OSDN Git Service

fix commands
[bytom/shuttle.git] / vendor / github.com / bytom / vendor / gonum.org / v1 / gonum / lapack / gonum / dlasq4.go
diff --git a/vendor/github.com/bytom/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq4.go b/vendor/github.com/bytom/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq4.go
new file mode 100644 (file)
index 0000000..1d581a2
--- /dev/null
@@ -0,0 +1,238 @@
+// Copyright ©2015 The Gonum Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gonum
+
+import "math"
+
+// Dlasq4 computes an approximation to the smallest eigenvalue using values of d
+// from the previous transform.
+// i0, n0, and n0in are zero-indexed.
+//
+// Dlasq4 is an internal routine. It is exported for testing purposes.
+func (impl Implementation) Dlasq4(i0, n0 int, z []float64, pp int, n0in int, dmin, dmin1, dmin2, dn, dn1, dn2, tau float64, ttype int, g float64) (tauOut float64, ttypeOut int, gOut float64) {
+       const (
+               cnst1 = 0.563
+               cnst2 = 1.01
+               cnst3 = 1.05
+
+               cnstthird = 0.333 // TODO(btracey): Fix?
+       )
+       // A negative dmin forces the shift to take that absolute value
+       // ttype records the type of shift.
+       if dmin <= 0 {
+               tau = -dmin
+               ttype = -1
+               return tau, ttype, g
+       }
+       nn := 4*(n0+1) + pp - 1 // -1 for zero indexing
+       s := math.NaN()         // Poison s so that failure to take a path below is obvious
+       if n0in == n0 {
+               // No eigenvalues deflated.
+               if dmin == dn || dmin == dn1 {
+                       b1 := math.Sqrt(z[nn-3]) * math.Sqrt(z[nn-5])
+                       b2 := math.Sqrt(z[nn-7]) * math.Sqrt(z[nn-9])
+                       a2 := z[nn-7] + z[nn-5]
+                       if dmin == dn && dmin1 == dn1 {
+                               gap2 := dmin2 - a2 - dmin2/4
+                               var gap1 float64
+                               if gap2 > 0 && gap2 > b2 {
+                                       gap1 = a2 - dn - (b2/gap2)*b2
+                               } else {
+                                       gap1 = a2 - dn - (b1 + b2)
+                               }
+                               if gap1 > 0 && gap1 > b1 {
+                                       s = math.Max(dn-(b1/gap1)*b1, 0.5*dmin)
+                                       ttype = -2
+                               } else {
+                                       s = 0
+                                       if dn > b1 {
+                                               s = dn - b1
+                                       }
+                                       if a2 > b1+b2 {
+                                               s = math.Min(s, a2-(b1+b2))
+                                       }
+                                       s = math.Max(s, cnstthird*dmin)
+                                       ttype = -3
+                               }
+                       } else {
+                               ttype = -4
+                               s = dmin / 4
+                               var gam float64
+                               var np int
+                               if dmin == dn {
+                                       gam = dn
+                                       a2 = 0
+                                       if z[nn-5] > z[nn-7] {
+                                               return tau, ttype, g
+                                       }
+                                       b2 = z[nn-5] / z[nn-7]
+                                       np = nn - 9
+                               } else {
+                                       np = nn - 2*pp
+                                       gam = dn1
+                                       if z[np-4] > z[np-2] {
+                                               return tau, ttype, g
+                                       }
+                                       a2 = z[np-4] / z[np-2]
+                                       if z[nn-9] > z[nn-11] {
+                                               return tau, ttype, g
+                                       }
+                                       b2 = z[nn-9] / z[nn-11]
+                                       np = nn - 13
+                               }
+                               // Approximate contribution to norm squared from i < nn-1.
+                               a2 += b2
+                               for i4loop := np + 1; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 {
+                                       i4 := i4loop - 1
+                                       if b2 == 0 {
+                                               break
+                                       }
+                                       b1 = b2
+                                       if z[i4] > z[i4-2] {
+                                               return tau, ttype, g
+                                       }
+                                       b2 *= z[i4] / z[i4-2]
+                                       a2 += b2
+                                       if 100*math.Max(b2, b1) < a2 || cnst1 < a2 {
+                                               break
+                                       }
+                               }
+                               a2 *= cnst3
+                               // Rayleigh quotient residual bound.
+                               if a2 < cnst1 {
+                                       s = gam * (1 - math.Sqrt(a2)) / (1 + a2)
+                               }
+                       }
+               } else if dmin == dn2 {
+                       ttype = -5
+                       s = dmin / 4
+                       // Compute contribution to norm squared from i > nn-2.
+                       np := nn - 2*pp
+                       b1 := z[np-2]
+                       b2 := z[np-6]
+                       gam := dn2
+                       if z[np-8] > b2 || z[np-4] > b1 {
+                               return tau, ttype, g
+                       }
+                       a2 := (z[np-8] / b2) * (1 + z[np-4]/b1)
+                       // Approximate contribution to norm squared from i < nn-2.
+                       if n0-i0 > 2 {
+                               b2 = z[nn-13] / z[nn-15]
+                               a2 += b2
+                               for i4loop := (nn + 1) - 17; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 {
+                                       i4 := i4loop - 1
+                                       if b2 == 0 {
+                                               break
+                                       }
+                                       b1 = b2
+                                       if z[i4] > z[i4-2] {
+                                               return tau, ttype, g
+                                       }
+                                       b2 *= z[i4] / z[i4-2]
+                                       a2 += b2
+                                       if 100*math.Max(b2, b1) < a2 || cnst1 < a2 {
+                                               break
+                                       }
+                               }
+                               a2 *= cnst3
+                       }
+                       if a2 < cnst1 {
+                               s = gam * (1 - math.Sqrt(a2)) / (1 + a2)
+                       }
+               } else {
+                       // Case 6, no information to guide us.
+                       if ttype == -6 {
+                               g += cnstthird * (1 - g)
+                       } else if ttype == -18 {
+                               g = cnstthird / 4
+                       } else {
+                               g = 1.0 / 4
+                       }
+                       s = g * dmin
+                       ttype = -6
+               }
+       } else if n0in == (n0 + 1) {
+               // One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
+               if dmin1 == dn1 && dmin2 == dn2 {
+                       ttype = -7
+                       s = cnstthird * dmin1
+                       if z[nn-5] > z[nn-7] {
+                               return tau, ttype, g
+                       }
+                       b1 := z[nn-5] / z[nn-7]
+                       b2 := b1
+                       if b2 != 0 {
+                               for i4loop := 4*(n0+1) - 9 + pp; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 {
+                                       i4 := i4loop - 1
+                                       a2 := b1
+                                       if z[i4] > z[i4-2] {
+                                               return tau, ttype, g
+                                       }
+                                       b1 *= z[i4] / z[i4-2]
+                                       b2 += b1
+                                       if 100*math.Max(b1, a2) < b2 {
+                                               break
+                                       }
+                               }
+                       }
+                       b2 = math.Sqrt(cnst3 * b2)
+                       a2 := dmin1 / (1 + b2*b2)
+                       gap2 := 0.5*dmin2 - a2
+                       if gap2 > 0 && gap2 > b2*a2 {
+                               s = math.Max(s, a2*(1-cnst2*a2*(b2/gap2)*b2))
+                       } else {
+                               s = math.Max(s, a2*(1-cnst2*b2))
+                               ttype = -8
+                       }
+               } else {
+                       s = dmin1 / 4
+                       if dmin1 == dn1 {
+                               s = 0.5 * dmin1
+                       }
+                       ttype = -9
+               }
+       } else if n0in == (n0 + 2) {
+               // Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
+               if dmin2 == dn2 && 2*z[nn-5] < z[nn-7] {
+                       ttype = -10
+                       s = cnstthird * dmin2
+                       if z[nn-5] > z[nn-7] {
+                               return tau, ttype, g
+                       }
+                       b1 := z[nn-5] / z[nn-7]
+                       b2 := b1
+                       if b2 != 0 {
+                               for i4loop := 4*(n0+1) - 9 + pp; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 {
+                                       i4 := i4loop - 1
+                                       if z[i4] > z[i4-2] {
+                                               return tau, ttype, g
+                                       }
+                                       b1 *= z[i4] / z[i4-2]
+                                       b2 += b1
+                                       if 100*b1 < b2 {
+                                               break
+                                       }
+                               }
+                       }
+                       b2 = math.Sqrt(cnst3 * b2)
+                       a2 := dmin2 / (1 + b2*b2)
+                       gap2 := z[nn-7] + z[nn-9] - math.Sqrt(z[nn-11])*math.Sqrt(z[nn-9]) - a2
+                       if gap2 > 0 && gap2 > b2*a2 {
+                               s = math.Max(s, a2*(1-cnst2*a2*(b2/gap2)*b2))
+                       } else {
+                               s = math.Max(s, a2*(1-cnst2*b2))
+                       }
+               } else {
+                       s = dmin2 / 4
+                       ttype = -11
+               }
+       } else if n0in > n0+2 {
+               // Case 12, more than two eigenvalues deflated. No information.
+               s = 0
+               ttype = -12
+       }
+       tau = s
+       return tau, ttype, g
+}