mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 07:37:03 +08:00
blas64: add length field N to Vector
blas64: add length field N to Vector Alongside, fix the implementation of mat.VecDense and mat.Diagonal, as well as other changes needed to fix this change. Fixes #736.
This commit is contained in:
@@ -28,8 +28,9 @@ func Implementation() blas.Float64 {
|
||||
|
||||
// Vector represents a vector with an associated element increment.
|
||||
type Vector struct {
|
||||
Data []float64
|
||||
N int
|
||||
Inc int
|
||||
Data []float64
|
||||
}
|
||||
|
||||
// General represents a matrix using the conventional storage scheme.
|
||||
@@ -98,34 +99,40 @@ type SymmetricPacked struct {
|
||||
|
||||
// Level 1
|
||||
|
||||
const negInc = "blas64: negative vector increment"
|
||||
const (
|
||||
negInc = "blas64: negative vector increment"
|
||||
badLength = "blas64: vector length mismatch"
|
||||
)
|
||||
|
||||
// Dot computes the dot product of the two vectors:
|
||||
// \sum_i x[i]*y[i].
|
||||
func Dot(n int, x, y Vector) float64 {
|
||||
return blas64.Ddot(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Dot(x, y Vector) float64 {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
return blas64.Ddot(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Nrm2 computes the Euclidean norm of the vector x:
|
||||
// sqrt(\sum_i x[i]*x[i]).
|
||||
//
|
||||
// Nrm2 will panic if the vector increment is negative.
|
||||
func Nrm2(n int, x Vector) float64 {
|
||||
func Nrm2(x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Dnrm2(n, x.Data, x.Inc)
|
||||
return blas64.Dnrm2(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Asum computes the sum of the absolute values of the elements of x:
|
||||
// \sum_i |x[i]|.
|
||||
//
|
||||
// Asum will panic if the vector increment is negative.
|
||||
func Asum(n int, x Vector) float64 {
|
||||
func Asum(x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Dasum(n, x.Data, x.Inc)
|
||||
return blas64.Dasum(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Iamax returns the index of an element of x with the largest absolute value.
|
||||
@@ -133,29 +140,39 @@ func Asum(n int, x Vector) float64 {
|
||||
// Iamax returns -1 if n == 0.
|
||||
//
|
||||
// Iamax will panic if the vector increment is negative.
|
||||
func Iamax(n int, x Vector) int {
|
||||
func Iamax(x Vector) int {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Idamax(n, x.Data, x.Inc)
|
||||
return blas64.Idamax(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Swap exchanges the elements of the two vectors:
|
||||
// x[i], y[i] = y[i], x[i] for all i.
|
||||
func Swap(n int, x, y Vector) {
|
||||
blas64.Dswap(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Swap(x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Dswap(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Copy copies the elements of x into the elements of y:
|
||||
// y[i] = x[i] for all i.
|
||||
func Copy(n int, x, y Vector) {
|
||||
blas64.Dcopy(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
// Copy requires that the lengths of x and y match and will panic otherwise.
|
||||
func Copy(x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Dcopy(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Axpy adds x scaled by alpha to y:
|
||||
// y[i] += alpha*x[i] for all i.
|
||||
func Axpy(n int, alpha float64, x, y Vector) {
|
||||
blas64.Daxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Axpy(alpha float64, x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Daxpy(x.N, alpha, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Rotg computes the parameters of a Givens plane rotation so that
|
||||
@@ -185,25 +202,31 @@ func Rotmg(d1, d2, b1, b2 float64) (p blas.DrotmParams, rd1, rd2, rb1 float64) {
|
||||
// and y:
|
||||
// x[i] = c*x[i] + s*y[i],
|
||||
// y[i] = -s*x[i] + c*y[i], for all i.
|
||||
func Rot(n int, x, y Vector, c, s float64) {
|
||||
blas64.Drot(n, x.Data, x.Inc, y.Data, y.Inc, c, s)
|
||||
func Rot(x, y Vector, c, s float64) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Drot(x.N, x.Data, x.Inc, y.Data, y.Inc, c, s)
|
||||
}
|
||||
|
||||
// Rotm applies the modified Givens rotation to n points represented by the
|
||||
// vectors x and y.
|
||||
func Rotm(n int, x, y Vector, p blas.DrotmParams) {
|
||||
blas64.Drotm(n, x.Data, x.Inc, y.Data, y.Inc, p)
|
||||
func Rotm(x, y Vector, p blas.DrotmParams) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Drotm(x.N, x.Data, x.Inc, y.Data, y.Inc, p)
|
||||
}
|
||||
|
||||
// Scal scales the vector x by alpha:
|
||||
// x[i] *= alpha for all i.
|
||||
//
|
||||
// Scal will panic if the vector increment is negative.
|
||||
func Scal(n int, alpha float64, x Vector) {
|
||||
func Scal(alpha float64, x Vector) {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
blas64.Dscal(n, alpha, x.Data, x.Inc)
|
||||
blas64.Dscal(x.N, alpha, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Level 2
|
||||
|
@@ -72,15 +72,13 @@ func testDgebak(t *testing.T, impl Dgebaker, job lapack.BalanceJob, side lapack.
|
||||
// Make up some random permutations.
|
||||
for i := n - 1; i > ihi; i-- {
|
||||
scale[i] = float64(rnd.Intn(i + 1))
|
||||
blas64.Swap(n,
|
||||
blas64.Vector{Data: p.Data[i:], Inc: p.Stride},
|
||||
blas64.Vector{Data: p.Data[int(scale[i]):], Inc: p.Stride})
|
||||
blas64.Swap(blas64.Vector{N: n, Data: p.Data[i:], Inc: p.Stride},
|
||||
blas64.Vector{N: n, Data: p.Data[int(scale[i]):], Inc: p.Stride})
|
||||
}
|
||||
for i := 0; i < ilo; i++ {
|
||||
scale[i] = float64(i + rnd.Intn(ihi-i+1))
|
||||
blas64.Swap(n,
|
||||
blas64.Vector{Data: p.Data[i:], Inc: p.Stride},
|
||||
blas64.Vector{Data: p.Data[int(scale[i]):], Inc: p.Stride})
|
||||
blas64.Swap(blas64.Vector{N: n, Data: p.Data[i:], Inc: p.Stride},
|
||||
blas64.Vector{N: n, Data: p.Data[int(scale[i]):], Inc: p.Stride})
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -144,14 +144,12 @@ func testDgebal(t *testing.T, impl Dgebaler, job lapack.BalanceJob, a blas64.Gen
|
||||
// Create the permutation matrix P.
|
||||
p := eye(n, n)
|
||||
for j := n - 1; j > ihi; j-- {
|
||||
blas64.Swap(n,
|
||||
blas64.Vector{Data: p.Data[j:], Inc: p.Stride},
|
||||
blas64.Vector{Data: p.Data[int(scale[j]):], Inc: p.Stride})
|
||||
blas64.Swap(blas64.Vector{N: n, Data: p.Data[j:], Inc: p.Stride},
|
||||
blas64.Vector{N: n, Data: p.Data[int(scale[j]):], Inc: p.Stride})
|
||||
}
|
||||
for j := 0; j < ilo; j++ {
|
||||
blas64.Swap(n,
|
||||
blas64.Vector{Data: p.Data[j:], Inc: p.Stride},
|
||||
blas64.Vector{Data: p.Data[int(scale[j]):], Inc: p.Stride})
|
||||
blas64.Swap(blas64.Vector{N: n, Data: p.Data[j:], Inc: p.Stride},
|
||||
blas64.Vector{N: n, Data: p.Data[int(scale[j]):], Inc: p.Stride})
|
||||
}
|
||||
// Compute P^T*A*P and store into want.
|
||||
ap := zeros(n, n, n)
|
||||
|
@@ -170,7 +170,8 @@ func checkPLU(t *testing.T, ok bool, m, n, lda int, ipiv []int, factorized, orig
|
||||
}
|
||||
for i := len(ipiv) - 1; i >= 0; i-- {
|
||||
v := ipiv[i]
|
||||
blas64.Swap(m, blas64.Vector{Inc: 1, Data: p[i*ldp:]}, blas64.Vector{Inc: 1, Data: p[v*ldp:]})
|
||||
blas64.Swap(blas64.Vector{N: m, Inc: 1, Data: p[i*ldp:]},
|
||||
blas64.Vector{N: m, Inc: 1, Data: p[v*ldp:]})
|
||||
}
|
||||
P := blas64.General{
|
||||
Rows: m,
|
||||
|
@@ -49,7 +49,7 @@ func DlangeTest(t *testing.T, impl Dlanger) {
|
||||
norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work)
|
||||
var ans float64
|
||||
for i := 0; i < m; i++ {
|
||||
idx := blas64.Iamax(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]})
|
||||
idx := blas64.Iamax(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]})
|
||||
ans = math.Max(ans, math.Abs(a[i*lda+idx]))
|
||||
}
|
||||
// Should be strictly equal because there is no floating point summation error.
|
||||
@@ -61,7 +61,7 @@ func DlangeTest(t *testing.T, impl Dlanger) {
|
||||
norm = impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work)
|
||||
ans = 0
|
||||
for i := 0; i < n; i++ {
|
||||
sum := blas64.Asum(m, blas64.Vector{Inc: lda, Data: aCopy[i:]})
|
||||
sum := blas64.Asum(blas64.Vector{N: m, Inc: lda, Data: aCopy[i:]})
|
||||
ans = math.Max(ans, sum)
|
||||
}
|
||||
if math.Abs(norm-ans) > 1e-14 {
|
||||
@@ -72,7 +72,7 @@ func DlangeTest(t *testing.T, impl Dlanger) {
|
||||
norm = impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work)
|
||||
ans = 0
|
||||
for i := 0; i < m; i++ {
|
||||
sum := blas64.Asum(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]})
|
||||
sum := blas64.Asum(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]})
|
||||
ans = math.Max(ans, sum)
|
||||
}
|
||||
if math.Abs(norm-ans) > 1e-14 {
|
||||
@@ -83,7 +83,7 @@ func DlangeTest(t *testing.T, impl Dlanger) {
|
||||
norm = impl.Dlange(lapack.Frobenius, m, n, a, lda, work)
|
||||
ans = 0
|
||||
for i := 0; i < m; i++ {
|
||||
sum := blas64.Nrm2(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]})
|
||||
sum := blas64.Nrm2(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]})
|
||||
ans += sum * sum
|
||||
}
|
||||
ans = math.Sqrt(ans)
|
||||
|
@@ -828,7 +828,7 @@ func isOrthogonal(q blas64.General) bool {
|
||||
// an orthonormal basis of the Euclidean space R^n.
|
||||
const tol = 1e-13
|
||||
for i := 0; i < n; i++ {
|
||||
nrm := blas64.Nrm2(n, blas64.Vector{Data: q.Data[i*q.Stride:], Inc: 1})
|
||||
nrm := blas64.Nrm2(blas64.Vector{N: n, Data: q.Data[i*q.Stride:], Inc: 1})
|
||||
if math.IsNaN(nrm) {
|
||||
return false
|
||||
}
|
||||
@@ -836,10 +836,8 @@ func isOrthogonal(q blas64.General) bool {
|
||||
return false
|
||||
}
|
||||
for j := i + 1; j < n; j++ {
|
||||
dot := blas64.Dot(n,
|
||||
blas64.Vector{Data: q.Data[i*q.Stride:], Inc: 1},
|
||||
blas64.Vector{Data: q.Data[j*q.Stride:], Inc: 1},
|
||||
)
|
||||
dot := blas64.Dot(blas64.Vector{N: n, Data: q.Data[i*q.Stride:], Inc: 1},
|
||||
blas64.Vector{N: n, Data: q.Data[j*q.Stride:], Inc: 1})
|
||||
if math.IsNaN(dot) {
|
||||
return false
|
||||
}
|
||||
@@ -860,7 +858,7 @@ func hasOrthonormalColumns(q blas64.General) bool {
|
||||
ldq := q.Stride
|
||||
const tol = 1e-13
|
||||
for i := 0; i < n; i++ {
|
||||
nrm := blas64.Nrm2(m, blas64.Vector{Data: q.Data[i:], Inc: ldq})
|
||||
nrm := blas64.Nrm2(blas64.Vector{N: m, Data: q.Data[i:], Inc: ldq})
|
||||
if math.IsNaN(nrm) {
|
||||
return false
|
||||
}
|
||||
@@ -868,10 +866,8 @@ func hasOrthonormalColumns(q blas64.General) bool {
|
||||
return false
|
||||
}
|
||||
for j := i + 1; j < n; j++ {
|
||||
dot := blas64.Dot(m,
|
||||
blas64.Vector{Data: q.Data[i:], Inc: ldq},
|
||||
blas64.Vector{Data: q.Data[j:], Inc: ldq},
|
||||
)
|
||||
dot := blas64.Dot(blas64.Vector{N: m, Data: q.Data[i:], Inc: ldq},
|
||||
blas64.Vector{N: m, Data: q.Data[j:], Inc: ldq})
|
||||
if math.IsNaN(dot) {
|
||||
return false
|
||||
}
|
||||
|
@@ -193,10 +193,10 @@ func (b *BandDense) DiagView() Diagonal {
|
||||
n := min(b.mat.Rows, b.mat.Cols)
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: b.mat.Stride,
|
||||
Data: b.mat.Data[b.mat.KL : (n-1)*b.mat.Stride+b.mat.KL+1],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -478,12 +478,12 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
tmp.CopyVec(x)
|
||||
xmat = tmp.RawVector()
|
||||
}
|
||||
blas64.Copy(n, xmat, blas64.Vector{Data: work, Inc: 1})
|
||||
blas64.Copy(xmat, blas64.Vector{N: n, Data: work, Inc: 1})
|
||||
|
||||
if alpha > 0 {
|
||||
// Compute rank-1 update.
|
||||
if alpha != 1 {
|
||||
blas64.Scal(n, math.Sqrt(alpha), blas64.Vector{Data: work, Inc: 1})
|
||||
blas64.Scal(math.Sqrt(alpha), blas64.Vector{N: n, Data: work, Inc: 1})
|
||||
}
|
||||
umat := c.chol.mat
|
||||
stride := umat.Stride
|
||||
@@ -503,9 +503,9 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
// Multiply the extended factorization matrix by
|
||||
// the Givens matrix from the left. Only
|
||||
// the i-th row and x are modified.
|
||||
blas64.Rot(n-i-1,
|
||||
blas64.Vector{Data: umat.Data[i*stride+i+1 : i*stride+n], Inc: 1},
|
||||
blas64.Vector{Data: work[i+1 : n], Inc: 1},
|
||||
blas64.Rot(
|
||||
blas64.Vector{N: n - i - 1, Data: umat.Data[i*stride+i+1 : i*stride+n], Inc: 1},
|
||||
blas64.Vector{N: n - i - 1, Data: work[i+1 : n], Inc: 1},
|
||||
c, s)
|
||||
}
|
||||
}
|
||||
@@ -516,7 +516,7 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
// Compute rank-1 downdate.
|
||||
alpha = math.Sqrt(-alpha)
|
||||
if alpha != 1 {
|
||||
blas64.Scal(n, alpha, blas64.Vector{Data: work, Inc: 1})
|
||||
blas64.Scal(alpha, blas64.Vector{N: n, Data: work, Inc: 1})
|
||||
}
|
||||
// Solve U^T * p = x storing the result into work.
|
||||
ok = lapack64.Trtrs(blas.Trans, c.chol.RawTriangular(), blas64.General{
|
||||
@@ -530,7 +530,7 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
// the factorization is valid.
|
||||
panic(badCholesky)
|
||||
}
|
||||
norm := blas64.Nrm2(n, blas64.Vector{Data: work, Inc: 1})
|
||||
norm := blas64.Nrm2(blas64.Vector{N: n, Data: work, Inc: 1})
|
||||
if norm >= 1 {
|
||||
// The updated matrix is not positive definite.
|
||||
return false
|
||||
@@ -557,9 +557,9 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
// Apply Givens matrices to U.
|
||||
// TODO(vladimir-ch): Use workspace to avoid modifying the
|
||||
// receiver in case an invalid factorization is created.
|
||||
blas64.Rot(n-i,
|
||||
blas64.Vector{Data: work[i:n], Inc: 1},
|
||||
blas64.Vector{Data: umat.Data[i*stride+i : i*stride+n], Inc: 1},
|
||||
blas64.Rot(
|
||||
blas64.Vector{N: n - i, Data: work[i:n], Inc: 1},
|
||||
blas64.Vector{N: n - i, Data: umat.Data[i*stride+i : i*stride+n], Inc: 1},
|
||||
cos[i], sin[i])
|
||||
if umat.Data[i*stride+i] == 0 {
|
||||
// The matrix is singular (may rarely happen due to
|
||||
@@ -570,7 +570,7 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
|
||||
// that on the i-th row the diagonal is negative,
|
||||
// multiply U from the left by an identity matrix that
|
||||
// has -1 on the i-th row.
|
||||
blas64.Scal(n-i, -1, blas64.Vector{Data: umat.Data[i*stride+i : i*stride+n], Inc: 1})
|
||||
blas64.Scal(-1, blas64.Vector{N: n - i, Data: umat.Data[i*stride+i : i*stride+n], Inc: 1})
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
|
35
mat/dense.go
35
mat/dense.go
@@ -236,9 +236,9 @@ func (m *Dense) SetCol(j int, src []float64) {
|
||||
panic(ErrColLength)
|
||||
}
|
||||
|
||||
blas64.Copy(m.mat.Rows,
|
||||
blas64.Vector{Inc: 1, Data: src},
|
||||
blas64.Vector{Inc: m.mat.Stride, Data: m.mat.Data[j:]},
|
||||
blas64.Copy(
|
||||
blas64.Vector{N: m.mat.Rows, Inc: 1, Data: src},
|
||||
blas64.Vector{N: m.mat.Rows, Inc: m.mat.Stride, Data: m.mat.Data[j:]},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -283,10 +283,10 @@ func (m *Dense) DiagView() Diagonal {
|
||||
n := min(m.mat.Rows, m.mat.Cols)
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: m.mat.Stride + 1,
|
||||
Data: m.mat.Data[:(n-1)*m.mat.Stride+n],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,9 +399,8 @@ func (m *Dense) Clone(a Matrix) {
|
||||
mat.Data = make([]float64, r*c)
|
||||
if trans {
|
||||
for i := 0; i < r; i++ {
|
||||
blas64.Copy(c,
|
||||
blas64.Vector{Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
|
||||
blas64.Vector{Inc: 1, Data: mat.Data[i*c : (i+1)*c]})
|
||||
blas64.Copy(blas64.Vector{N: c, Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
|
||||
blas64.Vector{N: c, Inc: 1, Data: mat.Data[i*c : (i+1)*c]})
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < r; i++ {
|
||||
@@ -410,10 +409,9 @@ func (m *Dense) Clone(a Matrix) {
|
||||
}
|
||||
case *VecDense:
|
||||
amat := aU.mat
|
||||
mat.Data = make([]float64, aU.n)
|
||||
blas64.Copy(aU.n,
|
||||
blas64.Vector{Inc: amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{Inc: 1, Data: mat.Data})
|
||||
mat.Data = make([]float64, aU.mat.N)
|
||||
blas64.Copy(blas64.Vector{N: aU.mat.N, Inc: amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{N: aU.mat.N, Inc: 1, Data: mat.Data})
|
||||
default:
|
||||
mat.Data = make([]float64, r*c)
|
||||
w := *m
|
||||
@@ -456,9 +454,8 @@ func (m *Dense) Copy(a Matrix) (r, c int) {
|
||||
m.checkOverlap(amat)
|
||||
}
|
||||
for i := 0; i < r; i++ {
|
||||
blas64.Copy(c,
|
||||
blas64.Vector{Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
|
||||
blas64.Vector{Inc: 1, Data: m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]})
|
||||
blas64.Copy(blas64.Vector{N: c, Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
|
||||
blas64.Vector{N: c, Inc: 1, Data: m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]})
|
||||
}
|
||||
} else {
|
||||
switch o := offset(m.mat.Data, amat.Data); {
|
||||
@@ -493,13 +490,11 @@ func (m *Dense) Copy(a Matrix) (r, c int) {
|
||||
}
|
||||
switch o := offset(m.mat.Data, amat.Data); {
|
||||
case o < 0:
|
||||
blas64.Copy(n,
|
||||
blas64.Vector{Inc: -amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{Inc: -stride, Data: m.mat.Data})
|
||||
blas64.Copy(blas64.Vector{N: n, Inc: -amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{N: n, Inc: -stride, Data: m.mat.Data})
|
||||
case o > 0:
|
||||
blas64.Copy(n,
|
||||
blas64.Vector{Inc: amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{Inc: stride, Data: m.mat.Data})
|
||||
blas64.Copy(blas64.Vector{N: n, Inc: amat.Inc, Data: amat.Data},
|
||||
blas64.Vector{N: n, Inc: stride, Data: m.mat.Data})
|
||||
default:
|
||||
// Nothing to do.
|
||||
}
|
||||
|
@@ -504,12 +504,13 @@ func (m *Dense) Exp(a Matrix) {
|
||||
a1.Copy(a)
|
||||
v := getWorkspace(r, r, true)
|
||||
vraw := v.RawMatrix()
|
||||
vvec := blas64.Vector{Inc: 1, Data: vraw.Data}
|
||||
n := r * r
|
||||
vvec := blas64.Vector{N: n, Inc: 1, Data: vraw.Data}
|
||||
defer putWorkspace(v)
|
||||
|
||||
u := getWorkspace(r, r, true)
|
||||
uraw := u.RawMatrix()
|
||||
uvec := blas64.Vector{Inc: 1, Data: uraw.Data}
|
||||
uvec := blas64.Vector{N: n, Inc: 1, Data: uraw.Data}
|
||||
defer putWorkspace(u)
|
||||
|
||||
a2 := getWorkspace(r, r, false)
|
||||
@@ -525,7 +526,7 @@ func (m *Dense) Exp(a Matrix) {
|
||||
// this is not as horrible as it looks.
|
||||
p := getWorkspace(r, r, true)
|
||||
praw := p.RawMatrix()
|
||||
pvec := blas64.Vector{Inc: 1, Data: praw.Data}
|
||||
pvec := blas64.Vector{N: n, Inc: 1, Data: praw.Data}
|
||||
defer putWorkspace(p)
|
||||
|
||||
for k := 0; k < r; k++ {
|
||||
@@ -537,8 +538,8 @@ func (m *Dense) Exp(a Matrix) {
|
||||
a2.Mul(a1, a1)
|
||||
for j := 0; j <= i; j++ {
|
||||
p.Mul(p, a2)
|
||||
blas64.Axpy(r*r, t.b[2*j+2], pvec, vvec)
|
||||
blas64.Axpy(r*r, t.b[2*j+3], pvec, uvec)
|
||||
blas64.Axpy(t.b[2*j+2], pvec, vvec)
|
||||
blas64.Axpy(t.b[2*j+3], pvec, uvec)
|
||||
}
|
||||
u.Mul(a1, u)
|
||||
|
||||
@@ -573,43 +574,43 @@ func (m *Dense) Exp(a Matrix) {
|
||||
i.set(j, j, 1)
|
||||
}
|
||||
iraw := i.RawMatrix()
|
||||
ivec := blas64.Vector{Inc: 1, Data: iraw.Data}
|
||||
ivec := blas64.Vector{N: n, Inc: 1, Data: iraw.Data}
|
||||
defer putWorkspace(i)
|
||||
|
||||
a2raw := a2.RawMatrix()
|
||||
a2vec := blas64.Vector{Inc: 1, Data: a2raw.Data}
|
||||
a2vec := blas64.Vector{N: n, Inc: 1, Data: a2raw.Data}
|
||||
|
||||
a4 := getWorkspace(r, r, false)
|
||||
a4raw := a4.RawMatrix()
|
||||
a4vec := blas64.Vector{Inc: 1, Data: a4raw.Data}
|
||||
a4vec := blas64.Vector{N: n, Inc: 1, Data: a4raw.Data}
|
||||
defer putWorkspace(a4)
|
||||
a4.Mul(a2, a2)
|
||||
|
||||
a6 := getWorkspace(r, r, false)
|
||||
a6raw := a6.RawMatrix()
|
||||
a6vec := blas64.Vector{Inc: 1, Data: a6raw.Data}
|
||||
a6vec := blas64.Vector{N: n, Inc: 1, Data: a6raw.Data}
|
||||
defer putWorkspace(a6)
|
||||
a6.Mul(a2, a4)
|
||||
|
||||
// V = A_6(b_12*A_6 + b_10*A_4 + b_8*A_2) + b_6*A_6 + b_4*A_4 + b_2*A_2 +b_0*I
|
||||
blas64.Axpy(r*r, b[12], a6vec, vvec)
|
||||
blas64.Axpy(r*r, b[10], a4vec, vvec)
|
||||
blas64.Axpy(r*r, b[8], a2vec, vvec)
|
||||
blas64.Axpy(b[12], a6vec, vvec)
|
||||
blas64.Axpy(b[10], a4vec, vvec)
|
||||
blas64.Axpy(b[8], a2vec, vvec)
|
||||
v.Mul(v, a6)
|
||||
blas64.Axpy(r*r, b[6], a6vec, vvec)
|
||||
blas64.Axpy(r*r, b[4], a4vec, vvec)
|
||||
blas64.Axpy(r*r, b[2], a2vec, vvec)
|
||||
blas64.Axpy(r*r, b[0], ivec, vvec)
|
||||
blas64.Axpy(b[6], a6vec, vvec)
|
||||
blas64.Axpy(b[4], a4vec, vvec)
|
||||
blas64.Axpy(b[2], a2vec, vvec)
|
||||
blas64.Axpy(b[0], ivec, vvec)
|
||||
|
||||
// U = A(A_6(b_13*A_6 + b_11*A_4 + b_9*A_2) + b_7*A_6 + b_5*A_4 + b_2*A_3 +b_1*I)
|
||||
blas64.Axpy(r*r, b[13], a6vec, uvec)
|
||||
blas64.Axpy(r*r, b[11], a4vec, uvec)
|
||||
blas64.Axpy(r*r, b[9], a2vec, uvec)
|
||||
blas64.Axpy(b[13], a6vec, uvec)
|
||||
blas64.Axpy(b[11], a4vec, uvec)
|
||||
blas64.Axpy(b[9], a2vec, uvec)
|
||||
u.Mul(u, a6)
|
||||
blas64.Axpy(r*r, b[7], a6vec, uvec)
|
||||
blas64.Axpy(r*r, b[5], a4vec, uvec)
|
||||
blas64.Axpy(r*r, b[3], a2vec, uvec)
|
||||
blas64.Axpy(r*r, b[1], ivec, uvec)
|
||||
blas64.Axpy(b[7], a6vec, uvec)
|
||||
blas64.Axpy(b[5], a4vec, uvec)
|
||||
blas64.Axpy(b[3], a2vec, uvec)
|
||||
blas64.Axpy(b[1], ivec, uvec)
|
||||
u.Mul(u, a1)
|
||||
|
||||
// Use i as a workspace here and
|
||||
@@ -783,14 +784,14 @@ func (m *Dense) RankOne(a Matrix, alpha float64, x, y Vector) {
|
||||
xU, _ := untranspose(x)
|
||||
if rv, ok := xU.(RawVectorer); ok {
|
||||
xmat = rv.RawVector()
|
||||
m.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral())
|
||||
m.checkOverlap((&VecDense{mat: xmat}).asGeneral())
|
||||
} else {
|
||||
fast = false
|
||||
}
|
||||
yU, _ := untranspose(y)
|
||||
if rv, ok := yU.(RawVectorer); ok {
|
||||
ymat = rv.RawVector()
|
||||
m.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral())
|
||||
m.checkOverlap((&VecDense{mat: ymat}).asGeneral())
|
||||
} else {
|
||||
fast = false
|
||||
}
|
||||
@@ -856,7 +857,7 @@ func (m *Dense) Outer(alpha float64, x, y Vector) {
|
||||
xU, _ := untranspose(x)
|
||||
if rv, ok := xU.(RawVectorer); ok {
|
||||
xmat = rv.RawVector()
|
||||
m.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral())
|
||||
m.checkOverlap((&VecDense{mat: xmat}).asGeneral())
|
||||
|
||||
} else {
|
||||
fast = false
|
||||
@@ -864,7 +865,7 @@ func (m *Dense) Outer(alpha float64, x, y Vector) {
|
||||
yU, _ := untranspose(y)
|
||||
if rv, ok := yU.(RawVectorer); ok {
|
||||
ymat = rv.RawVector()
|
||||
m.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral())
|
||||
m.checkOverlap((&VecDense{mat: ymat}).asGeneral())
|
||||
} else {
|
||||
fast = false
|
||||
}
|
||||
|
@@ -71,7 +71,6 @@ type MutableDiagonal interface {
|
||||
// DiagDense represents a diagonal matrix in dense storage format.
|
||||
type DiagDense struct {
|
||||
mat blas64.Vector
|
||||
n int
|
||||
}
|
||||
|
||||
// NewDiagonal creates a new Diagonal matrix with n rows and n columns.
|
||||
@@ -91,19 +90,18 @@ func NewDiagonal(n int, data []float64) *DiagDense {
|
||||
panic(ErrShape)
|
||||
}
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{Data: data, Inc: 1},
|
||||
n: n,
|
||||
mat: blas64.Vector{N: n, Data: data, Inc: 1},
|
||||
}
|
||||
}
|
||||
|
||||
// Diag returns the dimension of the receiver.
|
||||
func (d *DiagDense) Diag() int {
|
||||
return d.n
|
||||
return d.mat.N
|
||||
}
|
||||
|
||||
// Dims returns the dimensions of the matrix.
|
||||
func (d *DiagDense) Dims() (r, c int) {
|
||||
return d.n, d.n
|
||||
return d.mat.N, d.mat.N
|
||||
}
|
||||
|
||||
// T returns the transpose of the matrix.
|
||||
@@ -137,25 +135,25 @@ func (d *DiagDense) Bandwidth() (kl, ku int) {
|
||||
|
||||
// Symmetric implements the Symmetric interface.
|
||||
func (d *DiagDense) Symmetric() int {
|
||||
return d.n
|
||||
return d.mat.N
|
||||
}
|
||||
|
||||
// SymBand returns the number of rows/columns in the matrix, and the size of
|
||||
// the bandwidth.
|
||||
func (d *DiagDense) SymBand() (n, k int) {
|
||||
return d.n, 0
|
||||
return d.mat.N, 0
|
||||
}
|
||||
|
||||
// Triangle implements the Triangular interface.
|
||||
func (d *DiagDense) Triangle() (int, TriKind) {
|
||||
return d.n, Upper
|
||||
return d.mat.N, Upper
|
||||
}
|
||||
|
||||
// TriBand returns the number of rows/columns in the matrix, the
|
||||
// size of the bandwidth, and the orientation. Note that Diagonal matrices are
|
||||
// Upper by default.
|
||||
func (d *DiagDense) TriBand() (n, k int, kind TriKind) {
|
||||
return d.n, 0, Upper
|
||||
return d.mat.N, 0, Upper
|
||||
}
|
||||
|
||||
// Reset zeros the length of the matrix so that it can be reused as the
|
||||
@@ -166,7 +164,7 @@ func (d *DiagDense) Reset() {
|
||||
// No change of Inc or n to 0 may be
|
||||
// made unless both are set to 0.
|
||||
d.mat.Inc = 0
|
||||
d.n = 0
|
||||
d.mat.N = 0
|
||||
d.mat.Data = d.mat.Data[:0]
|
||||
}
|
||||
|
||||
@@ -188,24 +186,28 @@ func (d *DiagDense) DiagFrom(m Matrix) {
|
||||
case RawBander:
|
||||
mat := r.RawBand()
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride,
|
||||
Data: mat.Data[mat.KL : (n-1)*mat.Stride+mat.KL+1],
|
||||
}
|
||||
case RawMatrixer:
|
||||
mat := r.RawMatrix()
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride + 1,
|
||||
Data: mat.Data[:(n-1)*mat.Stride+n],
|
||||
}
|
||||
case RawSymBander:
|
||||
mat := r.RawSymBand()
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride,
|
||||
Data: mat.Data[:(n-1)*mat.Stride+1],
|
||||
}
|
||||
case RawSymmetricer:
|
||||
mat := r.RawSymmetric()
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride + 1,
|
||||
Data: mat.Data[:(n-1)*mat.Stride+n],
|
||||
}
|
||||
@@ -216,6 +218,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
|
||||
data = data[mat.K:]
|
||||
}
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride,
|
||||
Data: data[:(n-1)*mat.Stride+1],
|
||||
}
|
||||
@@ -228,6 +231,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
|
||||
return
|
||||
}
|
||||
vec = blas64.Vector{
|
||||
N: n,
|
||||
Inc: mat.Stride + 1,
|
||||
Data: mat.Data[:(n-1)*mat.Stride+n],
|
||||
}
|
||||
@@ -240,7 +244,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
|
||||
}
|
||||
return
|
||||
}
|
||||
blas64.Copy(n, vec, d.mat)
|
||||
blas64.Copy(vec, d.mat)
|
||||
}
|
||||
|
||||
// RawBand returns the underlying data used by the receiver represented
|
||||
@@ -249,8 +253,8 @@ func (d *DiagDense) DiagFrom(m Matrix) {
|
||||
// in returned blas64.Band.
|
||||
func (d *DiagDense) RawBand() blas64.Band {
|
||||
return blas64.Band{
|
||||
Rows: d.n,
|
||||
Cols: d.n,
|
||||
Rows: d.mat.N,
|
||||
Cols: d.mat.N,
|
||||
KL: 0,
|
||||
KU: 0,
|
||||
Stride: d.mat.Inc,
|
||||
@@ -264,7 +268,7 @@ func (d *DiagDense) RawBand() blas64.Band {
|
||||
// in returned blas64.Band.
|
||||
func (d *DiagDense) RawSymBand() blas64.SymmetricBand {
|
||||
return blas64.SymmetricBand{
|
||||
N: d.n,
|
||||
N: d.mat.N,
|
||||
K: 0,
|
||||
Stride: d.mat.Inc,
|
||||
Uplo: blas.Upper,
|
||||
@@ -283,10 +287,10 @@ func (d *DiagDense) reuseAs(r int) {
|
||||
Inc: 1,
|
||||
Data: use(d.mat.Data, r),
|
||||
}
|
||||
d.n = r
|
||||
d.mat.N = r
|
||||
return
|
||||
}
|
||||
if r != d.n {
|
||||
if r != d.mat.N {
|
||||
panic(ErrShape)
|
||||
}
|
||||
}
|
||||
|
@@ -23,8 +23,7 @@ func TestNewDiagonal(t *testing.T) {
|
||||
data: []float64{1, 2, 3, 4, 5, 6},
|
||||
n: 6,
|
||||
mat: &DiagDense{
|
||||
mat: blas64.Vector{Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
|
||||
n: 6,
|
||||
mat: blas64.Vector{N: 6, Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
|
||||
},
|
||||
dense: NewDense(6, 6, []float64{
|
||||
1, 0, 0, 0, 0, 0,
|
||||
@@ -64,8 +63,7 @@ func TestDiagonalStride(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
diag: &DiagDense{
|
||||
mat: blas64.Vector{Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
|
||||
n: 6,
|
||||
mat: blas64.Vector{N: 6, Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
|
||||
},
|
||||
dense: NewDense(6, 6, []float64{
|
||||
1, 0, 0, 0, 0, 0,
|
||||
@@ -78,7 +76,7 @@ func TestDiagonalStride(t *testing.T) {
|
||||
},
|
||||
{
|
||||
diag: &DiagDense{
|
||||
mat: blas64.Vector{Inc: 2, Data: []float64{
|
||||
mat: blas64.Vector{N: 6, Inc: 2, Data: []float64{
|
||||
1, 0,
|
||||
2, 0,
|
||||
3, 0,
|
||||
@@ -86,7 +84,6 @@ func TestDiagonalStride(t *testing.T) {
|
||||
5, 0,
|
||||
6,
|
||||
}},
|
||||
n: 6,
|
||||
},
|
||||
dense: NewDense(6, 6, []float64{
|
||||
1, 0, 0, 0, 0, 0,
|
||||
@@ -99,7 +96,7 @@ func TestDiagonalStride(t *testing.T) {
|
||||
},
|
||||
{
|
||||
diag: &DiagDense{
|
||||
mat: blas64.Vector{Inc: 5, Data: []float64{
|
||||
mat: blas64.Vector{N: 6, Inc: 5, Data: []float64{
|
||||
1, 0, 0, 0, 0,
|
||||
2, 0, 0, 0, 0,
|
||||
3, 0, 0, 0, 0,
|
||||
@@ -107,7 +104,6 @@ func TestDiagonalStride(t *testing.T) {
|
||||
5, 0, 0, 0, 0,
|
||||
6,
|
||||
}},
|
||||
n: 6,
|
||||
},
|
||||
dense: NewDense(6, 6, []float64{
|
||||
1, 0, 0, 0, 0, 0,
|
||||
|
@@ -105,7 +105,7 @@ func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) {
|
||||
var cv VecDense
|
||||
for j := 0; j < c; j++ {
|
||||
cv.ColViewOf(v, j)
|
||||
cv.ScaleVec(1/blas64.Nrm2(c, cv.mat), &cv)
|
||||
cv.ScaleVec(1/blas64.Nrm2(cv.mat), &cv)
|
||||
}
|
||||
|
||||
b := make([]Dense, len(m))
|
||||
@@ -183,7 +183,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
|
||||
panic("hogsvd: invalid index")
|
||||
}
|
||||
|
||||
r, c := gsvd.b[n].Dims()
|
||||
_, c := gsvd.b[n].Dims()
|
||||
if s == nil {
|
||||
s = make([]float64, c)
|
||||
} else if len(s) != c {
|
||||
@@ -192,7 +192,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
|
||||
var v VecDense
|
||||
for j := 0; j < c; j++ {
|
||||
v.ColViewOf(&gsvd.b[n], j)
|
||||
s[j] = blas64.Nrm2(r, v.mat)
|
||||
s[j] = blas64.Nrm2(v.mat)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@@ -54,7 +54,7 @@ func (v *VecDense) AtVec(i int) float64 {
|
||||
}
|
||||
|
||||
func (v *VecDense) at(i int) float64 {
|
||||
if uint(i) >= uint(v.n) {
|
||||
if uint(i) >= uint(v.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
return v.mat.Data[i*v.mat.Inc]
|
||||
@@ -67,7 +67,7 @@ func (v *VecDense) SetVec(i int, val float64) {
|
||||
}
|
||||
|
||||
func (v *VecDense) setVec(i int, val float64) {
|
||||
if uint(i) >= uint(v.n) {
|
||||
if uint(i) >= uint(v.mat.N) {
|
||||
panic(ErrVectorAccess)
|
||||
}
|
||||
v.mat.Data[i*v.mat.Inc] = val
|
||||
@@ -292,10 +292,10 @@ func (d *DiagDense) At(i, j int) float64 {
|
||||
}
|
||||
|
||||
func (d *DiagDense) at(i, j int) float64 {
|
||||
if uint(i) >= uint(d.n) {
|
||||
if uint(i) >= uint(d.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
if uint(j) >= uint(d.n) {
|
||||
if uint(j) >= uint(d.mat.N) {
|
||||
panic(ErrColAccess)
|
||||
}
|
||||
if i != j {
|
||||
@@ -311,7 +311,7 @@ func (d *DiagDense) SetDiag(i int, v float64) {
|
||||
}
|
||||
|
||||
func (d *DiagDense) setDiag(i int, v float64) {
|
||||
if uint(i) >= uint(d.n) {
|
||||
if uint(i) >= uint(d.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
d.mat.Data[i*d.mat.Inc] = v
|
||||
|
@@ -41,7 +41,7 @@ func (m *Dense) set(i, j int, v float64) {
|
||||
// At returns the element at row i.
|
||||
// It panics if i is out of bounds or if j is not zero.
|
||||
func (v *VecDense) At(i, j int) float64 {
|
||||
if uint(i) >= uint(v.n) {
|
||||
if uint(i) >= uint(v.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
if j != 0 {
|
||||
@@ -53,7 +53,7 @@ func (v *VecDense) At(i, j int) float64 {
|
||||
// AtVec returns the element at row i.
|
||||
// It panics if i is out of bounds.
|
||||
func (v *VecDense) AtVec(i int) float64 {
|
||||
if uint(i) >= uint(v.n) {
|
||||
if uint(i) >= uint(v.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
return v.at(i)
|
||||
@@ -66,7 +66,7 @@ func (v *VecDense) at(i int) float64 {
|
||||
// SetVec sets the element at row i to the value val.
|
||||
// It panics if i is out of bounds.
|
||||
func (v *VecDense) SetVec(i int, val float64) {
|
||||
if uint(i) >= uint(v.n) {
|
||||
if uint(i) >= uint(v.mat.N) {
|
||||
panic(ErrVectorAccess)
|
||||
}
|
||||
v.setVec(i, val)
|
||||
@@ -299,10 +299,10 @@ func (t *TriBandDense) setTriBand(i, j int, v float64) {
|
||||
|
||||
// At returns the element at row i, column j.
|
||||
func (d *DiagDense) At(i, j int) float64 {
|
||||
if uint(i) >= uint(d.n) {
|
||||
if uint(i) >= uint(d.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
if uint(j) >= uint(d.n) {
|
||||
if uint(j) >= uint(d.mat.N) {
|
||||
panic(ErrColAccess)
|
||||
}
|
||||
return d.at(i, j)
|
||||
@@ -318,7 +318,7 @@ func (d *DiagDense) at(i, j int) float64 {
|
||||
// SetDiag sets the element at row i, column i to the value v.
|
||||
// It panics if the location is outside the appropriate region of the matrix.
|
||||
func (d *DiagDense) SetDiag(i int, v float64) {
|
||||
if uint(i) >= uint(d.n) {
|
||||
if uint(i) >= uint(d.mat.N) {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
d.setDiag(i, v)
|
||||
|
@@ -130,8 +130,8 @@ func TestInnerSym(t *testing.T) {
|
||||
|
||||
func makeVecDenseInc(inc int, f []float64) *VecDense {
|
||||
v := &VecDense{
|
||||
n: len(f),
|
||||
mat: blas64.Vector{
|
||||
N: len(f),
|
||||
Inc: inc,
|
||||
Data: make([]float64, (len(f)-1)*inc+1),
|
||||
},
|
||||
|
10
mat/io.go
10
mat/io.go
@@ -259,7 +259,7 @@ func (m *Dense) UnmarshalBinaryFrom(r io.Reader) (int, error) {
|
||||
// 32 - 39 0 (int64)
|
||||
// 40 - .. vector's data elements (float64)
|
||||
func (v VecDense) MarshalBinary() ([]byte, error) {
|
||||
bufLen := int64(headerSize) + int64(v.n)*int64(sizeFloat64)
|
||||
bufLen := int64(headerSize) + int64(v.mat.N)*int64(sizeFloat64)
|
||||
if bufLen <= 0 {
|
||||
// bufLen is too big and has wrapped around.
|
||||
return nil, errTooBig
|
||||
@@ -267,7 +267,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
|
||||
|
||||
header := storage{
|
||||
Form: 'G', Packing: 'F', Uplo: 'A',
|
||||
Rows: int64(v.n), Cols: 1,
|
||||
Rows: int64(v.mat.N), Cols: 1,
|
||||
Version: version,
|
||||
}
|
||||
buf := make([]byte, bufLen)
|
||||
@@ -277,7 +277,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
|
||||
}
|
||||
|
||||
p := headerSize
|
||||
for i := 0; i < v.n; i++ {
|
||||
for i := 0; i < v.mat.N; i++ {
|
||||
binary.LittleEndian.PutUint64(buf[p:p+sizeFloat64], math.Float64bits(v.at(i)))
|
||||
p += sizeFloat64
|
||||
}
|
||||
@@ -292,7 +292,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
|
||||
func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) {
|
||||
header := storage{
|
||||
Form: 'G', Packing: 'F', Uplo: 'A',
|
||||
Rows: int64(v.n), Cols: 1,
|
||||
Rows: int64(v.mat.N), Cols: 1,
|
||||
Version: version,
|
||||
}
|
||||
n, err := header.marshalBinaryTo(w)
|
||||
@@ -301,7 +301,7 @@ func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) {
|
||||
}
|
||||
|
||||
var buf [8]byte
|
||||
for i := 0; i < v.n; i++ {
|
||||
for i := 0; i < v.mat.N; i++ {
|
||||
binary.LittleEndian.PutUint64(buf[:], math.Float64bits(v.at(i)))
|
||||
nn, err := w.Write(buf[:])
|
||||
n += nn
|
||||
|
@@ -343,10 +343,10 @@ var vectorData = []struct {
|
||||
raw: []byte("\x01\x00\x00\x00GFA\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x18@"),
|
||||
want: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: []float64{0, 1, 2, 3, 4, 5, 6},
|
||||
Inc: 3,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
eq: Equal,
|
||||
},
|
||||
|
@@ -373,10 +373,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
||||
}
|
||||
mat := &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: length,
|
||||
Inc: inc,
|
||||
Data: make([]float64, inc*(length-1)+1),
|
||||
},
|
||||
n: length,
|
||||
}
|
||||
for i := 0; i < length; i++ {
|
||||
mat.SetVec(i, rand.NormFloat64())
|
||||
@@ -522,10 +522,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
||||
}
|
||||
mat := &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: inc,
|
||||
Data: make([]float64, inc*(n-1)+1),
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
mat.SetDiag(i, rand.Float64())
|
||||
@@ -633,10 +633,10 @@ func makeCopyOf(a Matrix) Matrix {
|
||||
case *VecDense:
|
||||
m := &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: t.mat.N,
|
||||
Inc: t.mat.Inc,
|
||||
Data: make([]float64, t.mat.Inc*(t.n-1)+1),
|
||||
Data: make([]float64, t.mat.Inc*(t.mat.N-1)+1),
|
||||
},
|
||||
n: t.n,
|
||||
}
|
||||
copy(m.mat.Data, t.mat.Data)
|
||||
return m
|
||||
@@ -655,8 +655,7 @@ func makeCopyOf(a Matrix) Matrix {
|
||||
diag = (*DiagDense)(s)
|
||||
}
|
||||
d := &DiagDense{
|
||||
mat: blas64.Vector{Inc: diag.mat.Inc, Data: make([]float64, len(diag.mat.Data))},
|
||||
n: diag.n,
|
||||
mat: blas64.Vector{N: diag.mat.N, Inc: diag.mat.Inc, Data: make([]float64, len(diag.mat.Data))},
|
||||
}
|
||||
copy(d.mat.Data, diag.mat.Data)
|
||||
return returnAs(d, t)
|
||||
|
@@ -223,7 +223,7 @@ func (lq *LQ) SolveVec(x *VecDense, trans bool, b Vector) error {
|
||||
if x != b {
|
||||
x.checkOverlap(bmat)
|
||||
}
|
||||
b := VecDense{mat: bmat, n: b.Len()}
|
||||
b := VecDense{mat: bmat}
|
||||
bm = b.asDense()
|
||||
}
|
||||
if trans {
|
||||
|
@@ -233,9 +233,8 @@ func Col(dst []float64, j int, a Matrix) []float64 {
|
||||
copy(dst, m.Data[j*m.Stride:j*m.Stride+m.Cols])
|
||||
return dst
|
||||
}
|
||||
blas64.Copy(r,
|
||||
blas64.Vector{Inc: m.Stride, Data: m.Data[j:]},
|
||||
blas64.Vector{Inc: 1, Data: dst},
|
||||
blas64.Copy(blas64.Vector{N: r, Inc: m.Stride, Data: m.Data[j:]},
|
||||
blas64.Vector{N: r, Inc: 1, Data: dst},
|
||||
)
|
||||
return dst
|
||||
}
|
||||
@@ -264,9 +263,8 @@ func Row(dst []float64, i int, a Matrix) []float64 {
|
||||
if rm, ok := aU.(RawMatrixer); ok {
|
||||
m := rm.RawMatrix()
|
||||
if aTrans {
|
||||
blas64.Copy(c,
|
||||
blas64.Vector{Inc: m.Stride, Data: m.Data[i:]},
|
||||
blas64.Vector{Inc: 1, Data: dst},
|
||||
blas64.Copy(blas64.Vector{N: c, Inc: m.Stride, Data: m.Data[i:]},
|
||||
blas64.Vector{N: c, Inc: 1, Data: dst},
|
||||
)
|
||||
return dst
|
||||
}
|
||||
@@ -345,7 +343,7 @@ func Dot(a, b Vector) float64 {
|
||||
}
|
||||
if arv, ok := a.(RawVectorer); ok {
|
||||
if brv, ok := b.(RawVectorer); ok {
|
||||
return blas64.Dot(la, arv.RawVector(), brv.RawVector())
|
||||
return blas64.Dot(arv.RawVector(), brv.RawVector())
|
||||
}
|
||||
}
|
||||
var sum float64
|
||||
@@ -408,7 +406,7 @@ func Equal(a, b Matrix) bool {
|
||||
if rb, ok := bU.(*VecDense); ok {
|
||||
// If the raw vectors are the same length they must either both be
|
||||
// transposed or both not transposed (or have length 1).
|
||||
for i := 0; i < ra.n; i++ {
|
||||
for i := 0; i < ra.mat.N; i++ {
|
||||
if ra.mat.Data[i*ra.mat.Inc] != rb.mat.Data[i*rb.mat.Inc] {
|
||||
return false
|
||||
}
|
||||
@@ -480,7 +478,7 @@ func EqualApprox(a, b Matrix, epsilon float64) bool {
|
||||
if rb, ok := bU.(*VecDense); ok {
|
||||
// If the raw vectors are the same length they must either both be
|
||||
// transposed or both not transposed (or have length 1).
|
||||
for i := 0; i < ra.n; i++ {
|
||||
for i := 0; i < ra.mat.N; i++ {
|
||||
if !floats.EqualWithinAbsOrRel(ra.mat.Data[i*ra.mat.Inc], rb.mat.Data[i*rb.mat.Inc], epsilon, epsilon) {
|
||||
return false
|
||||
}
|
||||
@@ -706,17 +704,17 @@ func Norm(a Matrix, norm float64) float64 {
|
||||
panic("unreachable")
|
||||
case 1:
|
||||
if aTrans {
|
||||
imax := blas64.Iamax(rma.n, rv)
|
||||
imax := blas64.Iamax(rv)
|
||||
return math.Abs(rma.At(imax, 0))
|
||||
}
|
||||
return blas64.Asum(rma.n, rv)
|
||||
return blas64.Asum(rv)
|
||||
case 2:
|
||||
return blas64.Nrm2(rma.n, rv)
|
||||
return blas64.Nrm2(rv)
|
||||
case math.Inf(1):
|
||||
if aTrans {
|
||||
return blas64.Asum(rma.n, rv)
|
||||
return blas64.Asum(rv)
|
||||
}
|
||||
imax := blas64.Iamax(rma.n, rv)
|
||||
imax := blas64.Iamax(rv)
|
||||
return math.Abs(rma.At(imax, 0))
|
||||
}
|
||||
}
|
||||
|
@@ -186,7 +186,7 @@ func getWorkspaceVec(n int, clear bool) *VecDense {
|
||||
if clear {
|
||||
zero(v.mat.Data)
|
||||
}
|
||||
v.n = n
|
||||
v.mat.N = n
|
||||
return v
|
||||
}
|
||||
|
||||
|
@@ -220,7 +220,7 @@ func (qr *QR) SolveVec(x *VecDense, trans bool, b Vector) error {
|
||||
if x != b {
|
||||
x.checkOverlap(bmat)
|
||||
}
|
||||
b := VecDense{mat: bmat, n: b.Len()}
|
||||
b := VecDense{mat: bmat}
|
||||
bm = b.asDense()
|
||||
}
|
||||
if trans {
|
||||
|
@@ -56,10 +56,8 @@ func isOrthonormal(q *Dense, tol float64) bool {
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
for j := i; j < m; j++ {
|
||||
dot := blas64.Dot(m,
|
||||
blas64.Vector{Inc: 1, Data: q.mat.Data[i*q.mat.Stride:]},
|
||||
blas64.Vector{Inc: 1, Data: q.mat.Data[j*q.mat.Stride:]},
|
||||
)
|
||||
dot := blas64.Dot(blas64.Vector{N: m, Inc: 1, Data: q.mat.Data[i*q.mat.Stride:]},
|
||||
blas64.Vector{N: m, Inc: 1, Data: q.mat.Data[j*q.mat.Stride:]})
|
||||
// Dot product should be 1 if i == j and 0 otherwise.
|
||||
if i == j && math.Abs(dot-1) > tol {
|
||||
return false
|
||||
|
@@ -128,7 +128,7 @@ func (v *VecDense) SolveVec(a Matrix, b Vector) error {
|
||||
// and bm as overlapping but not identical.
|
||||
bm := m
|
||||
if v != b {
|
||||
b := VecDense{mat: bmat, n: b.Len()}
|
||||
b := VecDense{mat: bmat}
|
||||
bm = b.asDense()
|
||||
}
|
||||
return m.Solve(a, bm)
|
||||
|
@@ -150,10 +150,10 @@ func (s *SymBandDense) DiagView() Diagonal {
|
||||
n := s.mat.N
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: s.mat.Stride,
|
||||
Data: s.mat.Data[:(n-1)*s.mat.Stride+1],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -183,10 +183,10 @@ func (s *SymDense) DiagView() Diagonal {
|
||||
n := s.mat.N
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: s.mat.Stride + 1,
|
||||
Data: s.mat.Data[:(n-1)*s.mat.Stride+n],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x Vector) {
|
||||
xU, _ := untranspose(x)
|
||||
if rv, ok := xU.(RawVectorer); ok {
|
||||
xmat := rv.RawVector()
|
||||
s.checkOverlap((&VecDense{mat: xmat, n: n}).asGeneral())
|
||||
s.checkOverlap((&VecDense{mat: xmat}).asGeneral())
|
||||
blas64.Syr(alpha, xmat, s.mat)
|
||||
return
|
||||
}
|
||||
@@ -387,14 +387,14 @@ func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y Vector) {
|
||||
xU, _ := untranspose(x)
|
||||
if rv, ok := xU.(RawVectorer); ok {
|
||||
xmat = rv.RawVector()
|
||||
s.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral())
|
||||
s.checkOverlap((&VecDense{mat: xmat}).asGeneral())
|
||||
} else {
|
||||
fast = false
|
||||
}
|
||||
yU, _ := untranspose(y)
|
||||
if rv, ok := yU.(RawVectorer); ok {
|
||||
ymat = rv.RawVector()
|
||||
s.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral())
|
||||
s.checkOverlap((&VecDense{mat: ymat}).asGeneral())
|
||||
} else {
|
||||
fast = false
|
||||
}
|
||||
|
@@ -304,10 +304,10 @@ func (t *TriDense) DiagView() Diagonal {
|
||||
n := t.mat.N
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: t.mat.Stride + 1,
|
||||
Data: t.mat.Data[:(n-1)*t.mat.Stride+n],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -318,9 +318,9 @@ func (t *TriBandDense) DiagView() Diagonal {
|
||||
}
|
||||
return &DiagDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: t.mat.Stride,
|
||||
Data: data[:(n-1)*t.mat.Stride+1],
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
@@ -76,7 +76,6 @@ func (t TransposeVec) UntransposeVec() Vector {
|
||||
// VecDense represents a column vector.
|
||||
type VecDense struct {
|
||||
mat blas64.Vector
|
||||
n int
|
||||
// A BLAS vector can have a negative increment, but allowing this
|
||||
// in the mat type complicates a lot of code, and doesn't gain anything.
|
||||
// VecDense must have positive increment in this package.
|
||||
@@ -102,10 +101,10 @@ func NewVecDense(n int, data []float64) *VecDense {
|
||||
}
|
||||
return &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: n,
|
||||
Inc: 1,
|
||||
Data: data,
|
||||
},
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +117,8 @@ func (v *VecDense) SliceVec(i, k int) Vector {
|
||||
panic(ErrIndexOutOfRange)
|
||||
}
|
||||
return &VecDense{
|
||||
n: k - i,
|
||||
mat: blas64.Vector{
|
||||
N: k - i,
|
||||
Inc: v.mat.Inc,
|
||||
Data: v.mat.Data[i*v.mat.Inc : (k-1)*v.mat.Inc+1],
|
||||
},
|
||||
@@ -132,7 +131,7 @@ func (v *VecDense) Dims() (r, c int) {
|
||||
if v.IsZero() {
|
||||
return 0, 0
|
||||
}
|
||||
return v.n, 1
|
||||
return v.mat.N, 1
|
||||
}
|
||||
|
||||
// Caps returns the number of rows and columns in the backing matrix. Columns is always 1
|
||||
@@ -146,7 +145,7 @@ func (v *VecDense) Caps() (r, c int) {
|
||||
|
||||
// Len returns the length of the vector.
|
||||
func (v *VecDense) Len() int {
|
||||
return v.n
|
||||
return v.mat.N
|
||||
}
|
||||
|
||||
// Cap returns the capacity of the vector.
|
||||
@@ -172,10 +171,10 @@ func (v *VecDense) TVec() Vector {
|
||||
//
|
||||
// See the Reseter interface for more information.
|
||||
func (v *VecDense) Reset() {
|
||||
// No change of Inc or n to 0 may be
|
||||
// No change of Inc or N to 0 may be
|
||||
// made unless both are set to 0.
|
||||
v.mat.Inc = 0
|
||||
v.n = 0
|
||||
v.mat.N = 0
|
||||
v.mat.Data = v.mat.Data[:0]
|
||||
}
|
||||
|
||||
@@ -185,13 +184,14 @@ func (v *VecDense) CloneVec(a Vector) {
|
||||
if v == a {
|
||||
return
|
||||
}
|
||||
v.n = a.Len()
|
||||
n := a.Len()
|
||||
v.mat = blas64.Vector{
|
||||
N: n,
|
||||
Inc: 1,
|
||||
Data: use(v.mat.Data, v.n),
|
||||
Data: use(v.mat.Data, n),
|
||||
}
|
||||
if r, ok := a.(RawVectorer); ok {
|
||||
blas64.Copy(v.n, r.RawVector(), v.mat)
|
||||
blas64.Copy(r.RawVector(), v.mat)
|
||||
return
|
||||
}
|
||||
for i := 0; i < a.Len(); i++ {
|
||||
@@ -219,7 +219,7 @@ func (v *VecDense) CopyVec(a Vector) int {
|
||||
return n
|
||||
}
|
||||
if r, ok := a.(RawVectorer); ok {
|
||||
blas64.Copy(n, r.RawVector(), v.mat)
|
||||
blas64.Copy(r.RawVector(), v.mat)
|
||||
return n
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
@@ -308,7 +308,7 @@ func (v *VecDense) AddScaledVec(a Vector, alpha float64, b Vector) {
|
||||
}
|
||||
v.CopyVec(a)
|
||||
case v == a && v == b: // v <- v + alpha * v = (alpha + 1) * v
|
||||
blas64.Scal(ar, alpha+1, v.mat)
|
||||
blas64.Scal(alpha+1, v.mat)
|
||||
case !fast: // v <- a + alpha * b without blas64 support.
|
||||
for i := 0; i < ar; i++ {
|
||||
v.setVec(i, a.AtVec(i)+alpha*b.AtVec(i))
|
||||
@@ -645,13 +645,13 @@ func (v *VecDense) reuseAs(r int) {
|
||||
}
|
||||
if v.IsZero() {
|
||||
v.mat = blas64.Vector{
|
||||
N: r,
|
||||
Inc: 1,
|
||||
Data: use(v.mat.Data, r),
|
||||
}
|
||||
v.n = r
|
||||
return
|
||||
}
|
||||
if r != v.n {
|
||||
if r != v.mat.N {
|
||||
panic(ErrShape)
|
||||
}
|
||||
}
|
||||
@@ -681,7 +681,7 @@ func (v *VecDense) isolatedWorkspace(a Vector) (n *VecDense, restore func()) {
|
||||
func (v *VecDense) asDense() *Dense {
|
||||
return &Dense{
|
||||
mat: v.asGeneral(),
|
||||
capRows: v.n,
|
||||
capRows: v.mat.N,
|
||||
capCols: 1,
|
||||
}
|
||||
}
|
||||
@@ -690,7 +690,7 @@ func (v *VecDense) asDense() *Dense {
|
||||
// same underlying data.
|
||||
func (v *VecDense) asGeneral() blas64.General {
|
||||
return blas64.General{
|
||||
Rows: v.n,
|
||||
Rows: v.mat.N,
|
||||
Cols: 1,
|
||||
Stride: v.mat.Inc,
|
||||
Data: v.mat.Data,
|
||||
@@ -706,13 +706,13 @@ func (v *VecDense) ColViewOf(m RawMatrixer, j int) {
|
||||
if j >= rm.Cols || j < 0 {
|
||||
panic(ErrColAccess)
|
||||
}
|
||||
if !v.IsZero() && v.n != rm.Rows {
|
||||
if !v.IsZero() && v.mat.N != rm.Rows {
|
||||
panic(ErrShape)
|
||||
}
|
||||
|
||||
v.mat.Inc = rm.Stride
|
||||
v.mat.Data = rm.Data[j : (rm.Rows-1)*rm.Stride+j+1]
|
||||
v.n = rm.Rows
|
||||
v.mat.N = rm.Rows
|
||||
}
|
||||
|
||||
// RowViewOf reflects the row i of the RawMatrixer m, into the receiver
|
||||
@@ -724,11 +724,11 @@ func (v *VecDense) RowViewOf(m RawMatrixer, i int) {
|
||||
if i >= rm.Rows || i < 0 {
|
||||
panic(ErrRowAccess)
|
||||
}
|
||||
if !v.IsZero() && v.n != rm.Cols {
|
||||
if !v.IsZero() && v.mat.N != rm.Cols {
|
||||
panic(ErrShape)
|
||||
}
|
||||
|
||||
v.mat.Inc = 1
|
||||
v.mat.Data = rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols]
|
||||
v.n = rm.Cols
|
||||
v.mat.N = rm.Cols
|
||||
}
|
||||
|
@@ -24,10 +24,10 @@ func TestNewVecDense(t *testing.T) {
|
||||
data: []float64{4, 5, 6},
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: []float64{4, 5, 6},
|
||||
Inc: 1,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -35,10 +35,10 @@ func TestNewVecDense(t *testing.T) {
|
||||
data: nil,
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: []float64{0, 0, 0},
|
||||
Inc: 1,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
},
|
||||
} {
|
||||
@@ -65,50 +65,50 @@ func TestCap(t *testing.T) {
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: make([]float64, 7, 10),
|
||||
Inc: 3,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 4,
|
||||
Data: make([]float64, 10),
|
||||
Inc: 3,
|
||||
},
|
||||
n: 4,
|
||||
},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 4,
|
||||
Data: make([]float64, 11),
|
||||
Inc: 3,
|
||||
},
|
||||
n: 4,
|
||||
},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 4,
|
||||
Data: make([]float64, 12),
|
||||
Inc: 3,
|
||||
},
|
||||
n: 4,
|
||||
},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 4,
|
||||
Data: make([]float64, 13),
|
||||
Inc: 3,
|
||||
},
|
||||
n: 4,
|
||||
},
|
||||
want: 5,
|
||||
},
|
||||
@@ -127,24 +127,24 @@ func TestVecDenseAtSet(t *testing.T) {
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: []float64{0, 1, 2},
|
||||
Inc: 1,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
vector: &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: 3,
|
||||
Data: []float64{0, 10, 10, 1, 10, 10, 2},
|
||||
Inc: 3,
|
||||
},
|
||||
n: 3,
|
||||
},
|
||||
},
|
||||
} {
|
||||
v := test.vector
|
||||
n := test.vector.n
|
||||
n := test.vector.mat.N
|
||||
|
||||
for _, row := range []int{-1, n} {
|
||||
panicked, message := panics(func() { v.At(row, 0) })
|
||||
@@ -523,9 +523,9 @@ func randVecDense(size, inc int, rho float64, rnd func() float64) *VecDense {
|
||||
}
|
||||
return &VecDense{
|
||||
mat: blas64.Vector{
|
||||
N: size,
|
||||
Inc: inc,
|
||||
Data: data,
|
||||
},
|
||||
n: size,
|
||||
}
|
||||
}
|
||||
|
@@ -81,9 +81,7 @@ func TorgersonScaling(dst *mat.Dense, eigdst []float64, dis mat.Symmetric) (k in
|
||||
func reverse(values []float64, vectors blas64.General) {
|
||||
for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 {
|
||||
values[i], values[j] = values[j], values[i]
|
||||
blas64.Swap(vectors.Rows,
|
||||
blas64.Vector{Inc: vectors.Stride, Data: vectors.Data[i:]},
|
||||
blas64.Vector{Inc: vectors.Stride, Data: vectors.Data[j:]},
|
||||
)
|
||||
blas64.Swap(blas64.Vector{N: vectors.Rows, Inc: vectors.Stride, Data: vectors.Data[i:]},
|
||||
blas64.Vector{N: vectors.Rows, Inc: vectors.Stride, Data: vectors.Data[j:]})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user