OSDN Git Service

fix commands
[bytom/shuttle.git] / vendor / github.com / bytom / vendor / gonum.org / v1 / gonum / blas / gonum / level1double.go
diff --git a/vendor/github.com/bytom/vendor/gonum.org/v1/gonum/blas/gonum/level1double.go b/vendor/github.com/bytom/vendor/gonum.org/v1/gonum/blas/gonum/level1double.go
new file mode 100644 (file)
index 0000000..d24483a
--- /dev/null
@@ -0,0 +1,595 @@
+// 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"
+
+       "gonum.org/v1/gonum/blas"
+       "gonum.org/v1/gonum/internal/asm/f64"
+)
+
+var _ blas.Float64Level1 = Implementation{}
+
+// Dnrm2 computes the Euclidean norm of a vector,
+//  sqrt(\sum_i x[i] * x[i]).
+// This function returns 0 if incX is negative.
+func (Implementation) Dnrm2(n int, x []float64, incX int) float64 {
+       if incX < 1 {
+               if incX == 0 {
+                       panic(zeroIncX)
+               }
+               return 0
+       }
+       if incX > 0 && (n-1)*incX >= len(x) {
+               panic(badX)
+       }
+       if n < 2 {
+               if n == 1 {
+                       return math.Abs(x[0])
+               }
+               if n == 0 {
+                       return 0
+               }
+               if n < 1 {
+                       panic(negativeN)
+               }
+       }
+       var (
+               scale      float64 = 0
+               sumSquares float64 = 1
+       )
+       if incX == 1 {
+               x = x[:n]
+               for _, v := range x {
+                       if v == 0 {
+                               continue
+                       }
+                       absxi := math.Abs(v)
+                       if math.IsNaN(absxi) {
+                               return math.NaN()
+                       }
+                       if scale < absxi {
+                               sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
+                               scale = absxi
+                       } else {
+                               sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
+                       }
+               }
+               if math.IsInf(scale, 1) {
+                       return math.Inf(1)
+               }
+               return scale * math.Sqrt(sumSquares)
+       }
+       for ix := 0; ix < n*incX; ix += incX {
+               val := x[ix]
+               if val == 0 {
+                       continue
+               }
+               absxi := math.Abs(val)
+               if math.IsNaN(absxi) {
+                       return math.NaN()
+               }
+               if scale < absxi {
+                       sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
+                       scale = absxi
+               } else {
+                       sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
+               }
+       }
+       if math.IsInf(scale, 1) {
+               return math.Inf(1)
+       }
+       return scale * math.Sqrt(sumSquares)
+}
+
+// Dasum computes the sum of the absolute values of the elements of x.
+//  \sum_i |x[i]|
+// Dasum returns 0 if incX is negative.
+func (Implementation) Dasum(n int, x []float64, incX int) float64 {
+       var sum float64
+       if n < 0 {
+               panic(negativeN)
+       }
+       if incX < 1 {
+               if incX == 0 {
+                       panic(zeroIncX)
+               }
+               return 0
+       }
+       if incX > 0 && (n-1)*incX >= len(x) {
+               panic(badX)
+       }
+       if incX == 1 {
+               x = x[:n]
+               for _, v := range x {
+                       sum += math.Abs(v)
+               }
+               return sum
+       }
+       for i := 0; i < n; i++ {
+               sum += math.Abs(x[i*incX])
+       }
+       return sum
+}
+
+// Idamax returns the index of an element of x with the largest absolute value.
+// If there are multiple such indices the earliest is returned.
+// Idamax returns -1 if n == 0.
+func (Implementation) Idamax(n int, x []float64, incX int) int {
+       if incX < 1 {
+               if incX == 0 {
+                       panic(zeroIncX)
+               }
+               return -1
+       }
+       if incX > 0 && (n-1)*incX >= len(x) {
+               panic(badX)
+       }
+       if n < 2 {
+               if n == 1 {
+                       return 0
+               }
+               if n == 0 {
+                       return -1 // Netlib returns invalid index when n == 0
+               }
+               if n < 1 {
+                       panic(negativeN)
+               }
+       }
+       idx := 0
+       max := math.Abs(x[0])
+       if incX == 1 {
+               for i, v := range x[:n] {
+                       absV := math.Abs(v)
+                       if absV > max {
+                               max = absV
+                               idx = i
+                       }
+               }
+               return idx
+       }
+       ix := incX
+       for i := 1; i < n; i++ {
+               v := x[ix]
+               absV := math.Abs(v)
+               if absV > max {
+                       max = absV
+                       idx = i
+               }
+               ix += incX
+       }
+       return idx
+}
+
+// Dswap exchanges the elements of two vectors.
+//  x[i], y[i] = y[i], x[i] for all i
+func (Implementation) Dswap(n int, x []float64, incX int, y []float64, incY int) {
+       if incX == 0 {
+               panic(zeroIncX)
+       }
+       if incY == 0 {
+               panic(zeroIncY)
+       }
+       if n < 1 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
+               panic(badX)
+       }
+       if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
+               panic(badY)
+       }
+       if incX == 1 && incY == 1 {
+               x = x[:n]
+               for i, v := range x {
+                       x[i], y[i] = y[i], v
+               }
+               return
+       }
+       var ix, iy int
+       if incX < 0 {
+               ix = (-n + 1) * incX
+       }
+       if incY < 0 {
+               iy = (-n + 1) * incY
+       }
+       for i := 0; i < n; i++ {
+               x[ix], y[iy] = y[iy], x[ix]
+               ix += incX
+               iy += incY
+       }
+}
+
+// Dcopy copies the elements of x into the elements of y.
+//  y[i] = x[i] for all i
+func (Implementation) Dcopy(n int, x []float64, incX int, y []float64, incY int) {
+       if incX == 0 {
+               panic(zeroIncX)
+       }
+       if incY == 0 {
+               panic(zeroIncY)
+       }
+       if n < 1 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
+               panic(badX)
+       }
+       if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
+               panic(badY)
+       }
+       if incX == 1 && incY == 1 {
+               copy(y[:n], x[:n])
+               return
+       }
+       var ix, iy int
+       if incX < 0 {
+               ix = (-n + 1) * incX
+       }
+       if incY < 0 {
+               iy = (-n + 1) * incY
+       }
+       for i := 0; i < n; i++ {
+               y[iy] = x[ix]
+               ix += incX
+               iy += incY
+       }
+}
+
+// Daxpy adds alpha times x to y
+//  y[i] += alpha * x[i] for all i
+func (Implementation) Daxpy(n int, alpha float64, x []float64, incX int, y []float64, incY int) {
+       if incX == 0 {
+               panic(zeroIncX)
+       }
+       if incY == 0 {
+               panic(zeroIncY)
+       }
+       if n < 1 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
+               panic(badX)
+       }
+       if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
+               panic(badY)
+       }
+       if alpha == 0 {
+               return
+       }
+       if incX == 1 && incY == 1 {
+               f64.AxpyUnitary(alpha, x[:n], y[:n])
+               return
+       }
+       var ix, iy int
+       if incX < 0 {
+               ix = (-n + 1) * incX
+       }
+       if incY < 0 {
+               iy = (-n + 1) * incY
+       }
+       f64.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
+}
+
+// Drotg computes the plane rotation
+//   _    _      _ _       _ _
+//  |  c s |    | a |     | r |
+//  | -s c |  * | b |   = | 0 |
+//   ‾    ‾      ‾ ‾       ‾ ‾
+// where
+//  r = ±√(a^2 + b^2)
+//  c = a/r, the cosine of the plane rotation
+//  s = b/r, the sine of the plane rotation
+//
+// NOTE: There is a discrepancy between the refence implementation and the BLAS
+// technical manual regarding the sign for r when a or b are zero.
+// Drotg agrees with the definition in the manual and other
+// common BLAS implementations.
+func (Implementation) Drotg(a, b float64) (c, s, r, z float64) {
+       if b == 0 && a == 0 {
+               return 1, 0, a, 0
+       }
+       absA := math.Abs(a)
+       absB := math.Abs(b)
+       aGTb := absA > absB
+       r = math.Hypot(a, b)
+       if aGTb {
+               r = math.Copysign(r, a)
+       } else {
+               r = math.Copysign(r, b)
+       }
+       c = a / r
+       s = b / r
+       if aGTb {
+               z = s
+       } else if c != 0 { // r == 0 case handled above
+               z = 1 / c
+       } else {
+               z = 1
+       }
+       return
+}
+
+// Drotmg computes the modified Givens rotation. See
+// http://www.netlib.org/lapack/explore-html/df/deb/drotmg_8f.html
+// for more details.
+func (Implementation) Drotmg(d1, d2, x1, y1 float64) (p blas.DrotmParams, rd1, rd2, rx1 float64) {
+       var p1, p2, q1, q2, u float64
+
+       const (
+               gam    = 4096.0
+               gamsq  = 16777216.0
+               rgamsq = 5.9604645e-8
+       )
+
+       if d1 < 0 {
+               p.Flag = blas.Rescaling
+               return
+       }
+
+       p2 = d2 * y1
+       if p2 == 0 {
+               p.Flag = blas.Identity
+               rd1 = d1
+               rd2 = d2
+               rx1 = x1
+               return
+       }
+       p1 = d1 * x1
+       q2 = p2 * y1
+       q1 = p1 * x1
+
+       absQ1 := math.Abs(q1)
+       absQ2 := math.Abs(q2)
+
+       if absQ1 < absQ2 && q2 < 0 {
+               p.Flag = blas.Rescaling
+               return
+       }
+
+       if d1 == 0 {
+               p.Flag = blas.Diagonal
+               p.H[0] = p1 / p2
+               p.H[3] = x1 / y1
+               u = 1 + p.H[0]*p.H[3]
+               rd1, rd2 = d2/u, d1/u
+               rx1 = y1 / u
+               return
+       }
+
+       // Now we know that d1 != 0, and d2 != 0. If d2 == 0, it would be caught
+       // when p2 == 0, and if d1 == 0, then it is caught above
+
+       if absQ1 > absQ2 {
+               p.H[1] = -y1 / x1
+               p.H[2] = p2 / p1
+               u = 1 - p.H[2]*p.H[1]
+               rd1 = d1
+               rd2 = d2
+               rx1 = x1
+               p.Flag = blas.OffDiagonal
+               // u must be greater than zero because |q1| > |q2|, so check from netlib
+               // is unnecessary
+               // This is left in for ease of comparison with complex routines
+               //if u > 0 {
+               rd1 /= u
+               rd2 /= u
+               rx1 *= u
+               //}
+       } else {
+               p.Flag = blas.Diagonal
+               p.H[0] = p1 / p2
+               p.H[3] = x1 / y1
+               u = 1 + p.H[0]*p.H[3]
+               rd1 = d2 / u
+               rd2 = d1 / u
+               rx1 = y1 * u
+       }
+
+       for rd1 <= rgamsq || rd1 >= gamsq {
+               if p.Flag == blas.OffDiagonal {
+                       p.H[0] = 1
+                       p.H[3] = 1
+                       p.Flag = blas.Rescaling
+               } else if p.Flag == blas.Diagonal {
+                       p.H[1] = -1
+                       p.H[2] = 1
+                       p.Flag = blas.Rescaling
+               }
+               if rd1 <= rgamsq {
+                       rd1 *= gam * gam
+                       rx1 /= gam
+                       p.H[0] /= gam
+                       p.H[2] /= gam
+               } else {
+                       rd1 /= gam * gam
+                       rx1 *= gam
+                       p.H[0] *= gam
+                       p.H[2] *= gam
+               }
+       }
+
+       for math.Abs(rd2) <= rgamsq || math.Abs(rd2) >= gamsq {
+               if p.Flag == blas.OffDiagonal {
+                       p.H[0] = 1
+                       p.H[3] = 1
+                       p.Flag = blas.Rescaling
+               } else if p.Flag == blas.Diagonal {
+                       p.H[1] = -1
+                       p.H[2] = 1
+                       p.Flag = blas.Rescaling
+               }
+               if math.Abs(rd2) <= rgamsq {
+                       rd2 *= gam * gam
+                       p.H[1] /= gam
+                       p.H[3] /= gam
+               } else {
+                       rd2 /= gam * gam
+                       p.H[1] *= gam
+                       p.H[3] *= gam
+               }
+       }
+       return
+}
+
+// Drot applies a plane transformation.
+//  x[i] = c * x[i] + s * y[i]
+//  y[i] = c * y[i] - s * x[i]
+func (Implementation) Drot(n int, x []float64, incX int, y []float64, incY int, c float64, s float64) {
+       if incX == 0 {
+               panic(zeroIncX)
+       }
+       if incY == 0 {
+               panic(zeroIncY)
+       }
+       if n < 1 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
+               panic(badX)
+       }
+       if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
+               panic(badY)
+       }
+       if incX == 1 && incY == 1 {
+               x = x[:n]
+               for i, vx := range x {
+                       vy := y[i]
+                       x[i], y[i] = c*vx+s*vy, c*vy-s*vx
+               }
+               return
+       }
+       var ix, iy int
+       if incX < 0 {
+               ix = (-n + 1) * incX
+       }
+       if incY < 0 {
+               iy = (-n + 1) * incY
+       }
+       for i := 0; i < n; i++ {
+               vx := x[ix]
+               vy := y[iy]
+               x[ix], y[iy] = c*vx+s*vy, c*vy-s*vx
+               ix += incX
+               iy += incY
+       }
+}
+
+// Drotm applies the modified Givens rotation to the 2×n matrix.
+func (Implementation) Drotm(n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) {
+       if incX == 0 {
+               panic(zeroIncX)
+       }
+       if incY == 0 {
+               panic(zeroIncY)
+       }
+       if n <= 0 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
+               panic(badX)
+       }
+       if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
+               panic(badY)
+       }
+
+       var h11, h12, h21, h22 float64
+       var ix, iy int
+       switch p.Flag {
+       case blas.Identity:
+               return
+       case blas.Rescaling:
+               h11 = p.H[0]
+               h12 = p.H[2]
+               h21 = p.H[1]
+               h22 = p.H[3]
+       case blas.OffDiagonal:
+               h11 = 1
+               h12 = p.H[2]
+               h21 = p.H[1]
+               h22 = 1
+       case blas.Diagonal:
+               h11 = p.H[0]
+               h12 = 1
+               h21 = -1
+               h22 = p.H[3]
+       }
+       if incX < 0 {
+               ix = (-n + 1) * incX
+       }
+       if incY < 0 {
+               iy = (-n + 1) * incY
+       }
+       if incX == 1 && incY == 1 {
+               x = x[:n]
+               for i, vx := range x {
+                       vy := y[i]
+                       x[i], y[i] = vx*h11+vy*h12, vx*h21+vy*h22
+               }
+               return
+       }
+       for i := 0; i < n; i++ {
+               vx := x[ix]
+               vy := y[iy]
+               x[ix], y[iy] = vx*h11+vy*h12, vx*h21+vy*h22
+               ix += incX
+               iy += incY
+       }
+}
+
+// Dscal scales x by alpha.
+//  x[i] *= alpha
+// Dscal has no effect if incX < 0.
+func (Implementation) Dscal(n int, alpha float64, x []float64, incX int) {
+       if incX < 1 {
+               if incX == 0 {
+                       panic(zeroIncX)
+               }
+               return
+       }
+       if (n-1)*incX >= len(x) {
+               panic(badX)
+       }
+       if n < 1 {
+               if n == 0 {
+                       return
+               }
+               panic(negativeN)
+       }
+       if alpha == 0 {
+               if incX == 1 {
+                       x = x[:n]
+                       for i := range x {
+                               x[i] = 0
+                       }
+                       return
+               }
+               for ix := 0; ix < n*incX; ix += incX {
+                       x[ix] = 0
+               }
+               return
+       }
+       if incX == 1 {
+               f64.ScalUnitary(alpha, x[:n])
+               return
+       }
+       f64.ScalInc(alpha, x, uintptr(n), uintptr(incX))
+}