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:
Brendan Tracey
2018-12-10 08:36:04 +00:00
committed by GitHub
parent 6b862e40c9
commit 572d9101fe
32 changed files with 228 additions and 223 deletions

View File

@@ -28,8 +28,9 @@ func Implementation() blas.Float64 {
// Vector represents a vector with an associated element increment. // Vector represents a vector with an associated element increment.
type Vector struct { type Vector struct {
Data []float64 N int
Inc int Inc int
Data []float64
} }
// General represents a matrix using the conventional storage scheme. // General represents a matrix using the conventional storage scheme.
@@ -98,34 +99,40 @@ type SymmetricPacked struct {
// Level 1 // 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: // Dot computes the dot product of the two vectors:
// \sum_i x[i]*y[i]. // \sum_i x[i]*y[i].
func Dot(n int, x, y Vector) float64 { func Dot(x, y Vector) float64 {
return blas64.Ddot(n, x.Data, x.Inc, y.Data, y.Inc) 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: // Nrm2 computes the Euclidean norm of the vector x:
// sqrt(\sum_i x[i]*x[i]). // sqrt(\sum_i x[i]*x[i]).
// //
// Nrm2 will panic if the vector increment is negative. // 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 { if x.Inc < 0 {
panic(negInc) 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: // Asum computes the sum of the absolute values of the elements of x:
// \sum_i |x[i]|. // \sum_i |x[i]|.
// //
// Asum will panic if the vector increment is negative. // 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 { if x.Inc < 0 {
panic(negInc) 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. // 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 returns -1 if n == 0.
// //
// Iamax will panic if the vector increment is negative. // 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 { if x.Inc < 0 {
panic(negInc) 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: // Swap exchanges the elements of the two vectors:
// x[i], y[i] = y[i], x[i] for all i. // x[i], y[i] = y[i], x[i] for all i.
func Swap(n int, x, y Vector) { func Swap(x, y Vector) {
blas64.Dswap(n, x.Data, x.Inc, y.Data, y.Inc) 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: // Copy copies the elements of x into the elements of y:
// y[i] = x[i] for all i. // y[i] = x[i] for all i.
func Copy(n int, x, y Vector) { // Copy requires that the lengths of x and y match and will panic otherwise.
blas64.Dcopy(n, x.Data, x.Inc, y.Data, y.Inc) 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: // Axpy adds x scaled by alpha to y:
// y[i] += alpha*x[i] for all i. // y[i] += alpha*x[i] for all i.
func Axpy(n int, alpha float64, x, y Vector) { func Axpy(alpha float64, x, y Vector) {
blas64.Daxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc) 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 // 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: // and y:
// x[i] = c*x[i] + s*y[i], // x[i] = c*x[i] + s*y[i],
// y[i] = -s*x[i] + c*y[i], for all i. // y[i] = -s*x[i] + c*y[i], for all i.
func Rot(n int, x, y Vector, c, s float64) { func Rot(x, y Vector, c, s float64) {
blas64.Drot(n, x.Data, x.Inc, y.Data, y.Inc, c, s) 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 // Rotm applies the modified Givens rotation to n points represented by the
// vectors x and y. // vectors x and y.
func Rotm(n int, x, y Vector, p blas.DrotmParams) { func Rotm(x, y Vector, p blas.DrotmParams) {
blas64.Drotm(n, x.Data, x.Inc, y.Data, y.Inc, p) 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: // Scal scales the vector x by alpha:
// x[i] *= alpha for all i. // x[i] *= alpha for all i.
// //
// Scal will panic if the vector increment is negative. // 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 { if x.Inc < 0 {
panic(negInc) panic(negInc)
} }
blas64.Dscal(n, alpha, x.Data, x.Inc) blas64.Dscal(x.N, alpha, x.Data, x.Inc)
} }
// Level 2 // Level 2

View File

@@ -72,15 +72,13 @@ func testDgebak(t *testing.T, impl Dgebaker, job lapack.BalanceJob, side lapack.
// Make up some random permutations. // Make up some random permutations.
for i := n - 1; i > ihi; i-- { for i := n - 1; i > ihi; i-- {
scale[i] = float64(rnd.Intn(i + 1)) scale[i] = float64(rnd.Intn(i + 1))
blas64.Swap(n, blas64.Swap(blas64.Vector{N: n, Data: p.Data[i:], Inc: p.Stride},
blas64.Vector{Data: p.Data[i:], Inc: p.Stride}, blas64.Vector{N: n, Data: p.Data[int(scale[i]):], Inc: p.Stride})
blas64.Vector{Data: p.Data[int(scale[i]):], Inc: p.Stride})
} }
for i := 0; i < ilo; i++ { for i := 0; i < ilo; i++ {
scale[i] = float64(i + rnd.Intn(ihi-i+1)) scale[i] = float64(i + rnd.Intn(ihi-i+1))
blas64.Swap(n, blas64.Swap(blas64.Vector{N: n, Data: p.Data[i:], Inc: p.Stride},
blas64.Vector{Data: p.Data[i:], Inc: p.Stride}, blas64.Vector{N: n, Data: p.Data[int(scale[i]):], Inc: p.Stride})
blas64.Vector{Data: p.Data[int(scale[i]):], Inc: p.Stride})
} }
} }

View File

@@ -144,14 +144,12 @@ func testDgebal(t *testing.T, impl Dgebaler, job lapack.BalanceJob, a blas64.Gen
// Create the permutation matrix P. // Create the permutation matrix P.
p := eye(n, n) p := eye(n, n)
for j := n - 1; j > ihi; j-- { for j := n - 1; j > ihi; j-- {
blas64.Swap(n, blas64.Swap(blas64.Vector{N: n, Data: p.Data[j:], Inc: p.Stride},
blas64.Vector{Data: p.Data[j:], Inc: p.Stride}, blas64.Vector{N: n, Data: p.Data[int(scale[j]):], Inc: p.Stride})
blas64.Vector{Data: p.Data[int(scale[j]):], Inc: p.Stride})
} }
for j := 0; j < ilo; j++ { for j := 0; j < ilo; j++ {
blas64.Swap(n, blas64.Swap(blas64.Vector{N: n, Data: p.Data[j:], Inc: p.Stride},
blas64.Vector{Data: p.Data[j:], Inc: p.Stride}, blas64.Vector{N: n, Data: p.Data[int(scale[j]):], Inc: p.Stride})
blas64.Vector{Data: p.Data[int(scale[j]):], Inc: p.Stride})
} }
// Compute P^T*A*P and store into want. // Compute P^T*A*P and store into want.
ap := zeros(n, n, n) ap := zeros(n, n, n)

View File

@@ -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-- { for i := len(ipiv) - 1; i >= 0; i-- {
v := ipiv[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{ P := blas64.General{
Rows: m, Rows: m,

View File

@@ -49,7 +49,7 @@ func DlangeTest(t *testing.T, impl Dlanger) {
norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work) norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work)
var ans float64 var ans float64
for i := 0; i < m; i++ { 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])) ans = math.Max(ans, math.Abs(a[i*lda+idx]))
} }
// Should be strictly equal because there is no floating point summation error. // 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) norm = impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work)
ans = 0 ans = 0
for i := 0; i < n; i++ { 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) ans = math.Max(ans, sum)
} }
if math.Abs(norm-ans) > 1e-14 { 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) norm = impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work)
ans = 0 ans = 0
for i := 0; i < m; i++ { 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) ans = math.Max(ans, sum)
} }
if math.Abs(norm-ans) > 1e-14 { 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) norm = impl.Dlange(lapack.Frobenius, m, n, a, lda, work)
ans = 0 ans = 0
for i := 0; i < m; i++ { 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 += sum * sum
} }
ans = math.Sqrt(ans) ans = math.Sqrt(ans)

View File

@@ -828,7 +828,7 @@ func isOrthogonal(q blas64.General) bool {
// an orthonormal basis of the Euclidean space R^n. // an orthonormal basis of the Euclidean space R^n.
const tol = 1e-13 const tol = 1e-13
for i := 0; i < n; i++ { 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) { if math.IsNaN(nrm) {
return false return false
} }
@@ -836,10 +836,8 @@ func isOrthogonal(q blas64.General) bool {
return false return false
} }
for j := i + 1; j < n; j++ { for j := i + 1; j < n; j++ {
dot := blas64.Dot(n, dot := blas64.Dot(blas64.Vector{N: n, Data: q.Data[i*q.Stride:], Inc: 1},
blas64.Vector{Data: q.Data[i*q.Stride:], Inc: 1}, blas64.Vector{N: n, Data: q.Data[j*q.Stride:], Inc: 1})
blas64.Vector{Data: q.Data[j*q.Stride:], Inc: 1},
)
if math.IsNaN(dot) { if math.IsNaN(dot) {
return false return false
} }
@@ -860,7 +858,7 @@ func hasOrthonormalColumns(q blas64.General) bool {
ldq := q.Stride ldq := q.Stride
const tol = 1e-13 const tol = 1e-13
for i := 0; i < n; i++ { 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) { if math.IsNaN(nrm) {
return false return false
} }
@@ -868,10 +866,8 @@ func hasOrthonormalColumns(q blas64.General) bool {
return false return false
} }
for j := i + 1; j < n; j++ { for j := i + 1; j < n; j++ {
dot := blas64.Dot(m, dot := blas64.Dot(blas64.Vector{N: m, Data: q.Data[i:], Inc: ldq},
blas64.Vector{Data: q.Data[i:], Inc: ldq}, blas64.Vector{N: m, Data: q.Data[j:], Inc: ldq})
blas64.Vector{Data: q.Data[j:], Inc: ldq},
)
if math.IsNaN(dot) { if math.IsNaN(dot) {
return false return false
} }

View File

@@ -193,10 +193,10 @@ func (b *BandDense) DiagView() Diagonal {
n := min(b.mat.Rows, b.mat.Cols) n := min(b.mat.Rows, b.mat.Cols)
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: b.mat.Stride, Inc: b.mat.Stride,
Data: b.mat.Data[b.mat.KL : (n-1)*b.mat.Stride+b.mat.KL+1], Data: b.mat.Data[b.mat.KL : (n-1)*b.mat.Stride+b.mat.KL+1],
}, },
n: n,
} }
} }

View File

@@ -478,12 +478,12 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
tmp.CopyVec(x) tmp.CopyVec(x)
xmat = tmp.RawVector() 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 { if alpha > 0 {
// Compute rank-1 update. // Compute rank-1 update.
if alpha != 1 { 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 umat := c.chol.mat
stride := umat.Stride 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 // Multiply the extended factorization matrix by
// the Givens matrix from the left. Only // the Givens matrix from the left. Only
// the i-th row and x are modified. // the i-th row and x are modified.
blas64.Rot(n-i-1, blas64.Rot(
blas64.Vector{Data: umat.Data[i*stride+i+1 : i*stride+n], Inc: 1}, blas64.Vector{N: n - i - 1, Data: umat.Data[i*stride+i+1 : i*stride+n], Inc: 1},
blas64.Vector{Data: work[i+1 : n], Inc: 1}, blas64.Vector{N: n - i - 1, Data: work[i+1 : n], Inc: 1},
c, s) c, s)
} }
} }
@@ -516,7 +516,7 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
// Compute rank-1 downdate. // Compute rank-1 downdate.
alpha = math.Sqrt(-alpha) alpha = math.Sqrt(-alpha)
if alpha != 1 { 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. // Solve U^T * p = x storing the result into work.
ok = lapack64.Trtrs(blas.Trans, c.chol.RawTriangular(), blas64.General{ 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. // the factorization is valid.
panic(badCholesky) 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 { if norm >= 1 {
// The updated matrix is not positive definite. // The updated matrix is not positive definite.
return false return false
@@ -557,9 +557,9 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool)
// Apply Givens matrices to U. // Apply Givens matrices to U.
// TODO(vladimir-ch): Use workspace to avoid modifying the // TODO(vladimir-ch): Use workspace to avoid modifying the
// receiver in case an invalid factorization is created. // receiver in case an invalid factorization is created.
blas64.Rot(n-i, blas64.Rot(
blas64.Vector{Data: work[i:n], Inc: 1}, blas64.Vector{N: n - i, Data: work[i:n], Inc: 1},
blas64.Vector{Data: umat.Data[i*stride+i : i*stride+n], Inc: 1}, blas64.Vector{N: n - i, Data: umat.Data[i*stride+i : i*stride+n], Inc: 1},
cos[i], sin[i]) cos[i], sin[i])
if umat.Data[i*stride+i] == 0 { if umat.Data[i*stride+i] == 0 {
// The matrix is singular (may rarely happen due to // 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, // that on the i-th row the diagonal is negative,
// multiply U from the left by an identity matrix that // multiply U from the left by an identity matrix that
// has -1 on the i-th row. // 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 { if ok {

View File

@@ -236,9 +236,9 @@ func (m *Dense) SetCol(j int, src []float64) {
panic(ErrColLength) panic(ErrColLength)
} }
blas64.Copy(m.mat.Rows, blas64.Copy(
blas64.Vector{Inc: 1, Data: src}, blas64.Vector{N: m.mat.Rows, Inc: 1, Data: src},
blas64.Vector{Inc: m.mat.Stride, Data: m.mat.Data[j:]}, 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) n := min(m.mat.Rows, m.mat.Cols)
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: m.mat.Stride + 1, Inc: m.mat.Stride + 1,
Data: m.mat.Data[:(n-1)*m.mat.Stride+n], 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) mat.Data = make([]float64, r*c)
if trans { if trans {
for i := 0; i < r; i++ { for i := 0; i < r; i++ {
blas64.Copy(c, blas64.Copy(blas64.Vector{N: c, Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
blas64.Vector{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]})
blas64.Vector{Inc: 1, Data: mat.Data[i*c : (i+1)*c]})
} }
} else { } else {
for i := 0; i < r; i++ { for i := 0; i < r; i++ {
@@ -410,10 +409,9 @@ func (m *Dense) Clone(a Matrix) {
} }
case *VecDense: case *VecDense:
amat := aU.mat amat := aU.mat
mat.Data = make([]float64, aU.n) mat.Data = make([]float64, aU.mat.N)
blas64.Copy(aU.n, blas64.Copy(blas64.Vector{N: aU.mat.N, Inc: amat.Inc, Data: amat.Data},
blas64.Vector{Inc: amat.Inc, Data: amat.Data}, blas64.Vector{N: aU.mat.N, Inc: 1, Data: mat.Data})
blas64.Vector{Inc: 1, Data: mat.Data})
default: default:
mat.Data = make([]float64, r*c) mat.Data = make([]float64, r*c)
w := *m w := *m
@@ -456,9 +454,8 @@ func (m *Dense) Copy(a Matrix) (r, c int) {
m.checkOverlap(amat) m.checkOverlap(amat)
} }
for i := 0; i < r; i++ { for i := 0; i < r; i++ {
blas64.Copy(c, blas64.Copy(blas64.Vector{N: c, Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]},
blas64.Vector{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]})
blas64.Vector{Inc: 1, Data: m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]})
} }
} else { } else {
switch o := offset(m.mat.Data, amat.Data); { 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); { switch o := offset(m.mat.Data, amat.Data); {
case o < 0: case o < 0:
blas64.Copy(n, blas64.Copy(blas64.Vector{N: n, Inc: -amat.Inc, Data: amat.Data},
blas64.Vector{Inc: -amat.Inc, Data: amat.Data}, blas64.Vector{N: n, Inc: -stride, Data: m.mat.Data})
blas64.Vector{Inc: -stride, Data: m.mat.Data})
case o > 0: case o > 0:
blas64.Copy(n, blas64.Copy(blas64.Vector{N: n, Inc: amat.Inc, Data: amat.Data},
blas64.Vector{Inc: amat.Inc, Data: amat.Data}, blas64.Vector{N: n, Inc: stride, Data: m.mat.Data})
blas64.Vector{Inc: stride, Data: m.mat.Data})
default: default:
// Nothing to do. // Nothing to do.
} }

View File

@@ -504,12 +504,13 @@ func (m *Dense) Exp(a Matrix) {
a1.Copy(a) a1.Copy(a)
v := getWorkspace(r, r, true) v := getWorkspace(r, r, true)
vraw := v.RawMatrix() 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) defer putWorkspace(v)
u := getWorkspace(r, r, true) u := getWorkspace(r, r, true)
uraw := u.RawMatrix() uraw := u.RawMatrix()
uvec := blas64.Vector{Inc: 1, Data: uraw.Data} uvec := blas64.Vector{N: n, Inc: 1, Data: uraw.Data}
defer putWorkspace(u) defer putWorkspace(u)
a2 := getWorkspace(r, r, false) a2 := getWorkspace(r, r, false)
@@ -525,7 +526,7 @@ func (m *Dense) Exp(a Matrix) {
// this is not as horrible as it looks. // this is not as horrible as it looks.
p := getWorkspace(r, r, true) p := getWorkspace(r, r, true)
praw := p.RawMatrix() praw := p.RawMatrix()
pvec := blas64.Vector{Inc: 1, Data: praw.Data} pvec := blas64.Vector{N: n, Inc: 1, Data: praw.Data}
defer putWorkspace(p) defer putWorkspace(p)
for k := 0; k < r; k++ { for k := 0; k < r; k++ {
@@ -537,8 +538,8 @@ func (m *Dense) Exp(a Matrix) {
a2.Mul(a1, a1) a2.Mul(a1, a1)
for j := 0; j <= i; j++ { for j := 0; j <= i; j++ {
p.Mul(p, a2) p.Mul(p, a2)
blas64.Axpy(r*r, t.b[2*j+2], pvec, vvec) blas64.Axpy(t.b[2*j+2], pvec, vvec)
blas64.Axpy(r*r, t.b[2*j+3], pvec, uvec) blas64.Axpy(t.b[2*j+3], pvec, uvec)
} }
u.Mul(a1, u) u.Mul(a1, u)
@@ -573,43 +574,43 @@ func (m *Dense) Exp(a Matrix) {
i.set(j, j, 1) i.set(j, j, 1)
} }
iraw := i.RawMatrix() iraw := i.RawMatrix()
ivec := blas64.Vector{Inc: 1, Data: iraw.Data} ivec := blas64.Vector{N: n, Inc: 1, Data: iraw.Data}
defer putWorkspace(i) defer putWorkspace(i)
a2raw := a2.RawMatrix() 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) a4 := getWorkspace(r, r, false)
a4raw := a4.RawMatrix() a4raw := a4.RawMatrix()
a4vec := blas64.Vector{Inc: 1, Data: a4raw.Data} a4vec := blas64.Vector{N: n, Inc: 1, Data: a4raw.Data}
defer putWorkspace(a4) defer putWorkspace(a4)
a4.Mul(a2, a2) a4.Mul(a2, a2)
a6 := getWorkspace(r, r, false) a6 := getWorkspace(r, r, false)
a6raw := a6.RawMatrix() a6raw := a6.RawMatrix()
a6vec := blas64.Vector{Inc: 1, Data: a6raw.Data} a6vec := blas64.Vector{N: n, Inc: 1, Data: a6raw.Data}
defer putWorkspace(a6) defer putWorkspace(a6)
a6.Mul(a2, a4) 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 // 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(b[12], a6vec, vvec)
blas64.Axpy(r*r, b[10], a4vec, vvec) blas64.Axpy(b[10], a4vec, vvec)
blas64.Axpy(r*r, b[8], a2vec, vvec) blas64.Axpy(b[8], a2vec, vvec)
v.Mul(v, a6) v.Mul(v, a6)
blas64.Axpy(r*r, b[6], a6vec, vvec) blas64.Axpy(b[6], a6vec, vvec)
blas64.Axpy(r*r, b[4], a4vec, vvec) blas64.Axpy(b[4], a4vec, vvec)
blas64.Axpy(r*r, b[2], a2vec, vvec) blas64.Axpy(b[2], a2vec, vvec)
blas64.Axpy(r*r, b[0], ivec, 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) // 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(b[13], a6vec, uvec)
blas64.Axpy(r*r, b[11], a4vec, uvec) blas64.Axpy(b[11], a4vec, uvec)
blas64.Axpy(r*r, b[9], a2vec, uvec) blas64.Axpy(b[9], a2vec, uvec)
u.Mul(u, a6) u.Mul(u, a6)
blas64.Axpy(r*r, b[7], a6vec, uvec) blas64.Axpy(b[7], a6vec, uvec)
blas64.Axpy(r*r, b[5], a4vec, uvec) blas64.Axpy(b[5], a4vec, uvec)
blas64.Axpy(r*r, b[3], a2vec, uvec) blas64.Axpy(b[3], a2vec, uvec)
blas64.Axpy(r*r, b[1], ivec, uvec) blas64.Axpy(b[1], ivec, uvec)
u.Mul(u, a1) u.Mul(u, a1)
// Use i as a workspace here and // 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) xU, _ := untranspose(x)
if rv, ok := xU.(RawVectorer); ok { if rv, ok := xU.(RawVectorer); ok {
xmat = rv.RawVector() xmat = rv.RawVector()
m.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral()) m.checkOverlap((&VecDense{mat: xmat}).asGeneral())
} else { } else {
fast = false fast = false
} }
yU, _ := untranspose(y) yU, _ := untranspose(y)
if rv, ok := yU.(RawVectorer); ok { if rv, ok := yU.(RawVectorer); ok {
ymat = rv.RawVector() ymat = rv.RawVector()
m.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral()) m.checkOverlap((&VecDense{mat: ymat}).asGeneral())
} else { } else {
fast = false fast = false
} }
@@ -856,7 +857,7 @@ func (m *Dense) Outer(alpha float64, x, y Vector) {
xU, _ := untranspose(x) xU, _ := untranspose(x)
if rv, ok := xU.(RawVectorer); ok { if rv, ok := xU.(RawVectorer); ok {
xmat = rv.RawVector() xmat = rv.RawVector()
m.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral()) m.checkOverlap((&VecDense{mat: xmat}).asGeneral())
} else { } else {
fast = false fast = false
@@ -864,7 +865,7 @@ func (m *Dense) Outer(alpha float64, x, y Vector) {
yU, _ := untranspose(y) yU, _ := untranspose(y)
if rv, ok := yU.(RawVectorer); ok { if rv, ok := yU.(RawVectorer); ok {
ymat = rv.RawVector() ymat = rv.RawVector()
m.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral()) m.checkOverlap((&VecDense{mat: ymat}).asGeneral())
} else { } else {
fast = false fast = false
} }

View File

@@ -71,7 +71,6 @@ type MutableDiagonal interface {
// DiagDense represents a diagonal matrix in dense storage format. // DiagDense represents a diagonal matrix in dense storage format.
type DiagDense struct { type DiagDense struct {
mat blas64.Vector mat blas64.Vector
n int
} }
// NewDiagonal creates a new Diagonal matrix with n rows and n columns. // 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) panic(ErrShape)
} }
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{Data: data, Inc: 1}, mat: blas64.Vector{N: n, Data: data, Inc: 1},
n: n,
} }
} }
// Diag returns the dimension of the receiver. // Diag returns the dimension of the receiver.
func (d *DiagDense) Diag() int { func (d *DiagDense) Diag() int {
return d.n return d.mat.N
} }
// Dims returns the dimensions of the matrix. // Dims returns the dimensions of the matrix.
func (d *DiagDense) Dims() (r, c int) { 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. // T returns the transpose of the matrix.
@@ -137,25 +135,25 @@ func (d *DiagDense) Bandwidth() (kl, ku int) {
// Symmetric implements the Symmetric interface. // Symmetric implements the Symmetric interface.
func (d *DiagDense) Symmetric() int { 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 // SymBand returns the number of rows/columns in the matrix, and the size of
// the bandwidth. // the bandwidth.
func (d *DiagDense) SymBand() (n, k int) { func (d *DiagDense) SymBand() (n, k int) {
return d.n, 0 return d.mat.N, 0
} }
// Triangle implements the Triangular interface. // Triangle implements the Triangular interface.
func (d *DiagDense) Triangle() (int, TriKind) { 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 // TriBand returns the number of rows/columns in the matrix, the
// size of the bandwidth, and the orientation. Note that Diagonal matrices are // size of the bandwidth, and the orientation. Note that Diagonal matrices are
// Upper by default. // Upper by default.
func (d *DiagDense) TriBand() (n, k int, kind TriKind) { 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 // 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 // No change of Inc or n to 0 may be
// made unless both are set to 0. // made unless both are set to 0.
d.mat.Inc = 0 d.mat.Inc = 0
d.n = 0 d.mat.N = 0
d.mat.Data = d.mat.Data[:0] d.mat.Data = d.mat.Data[:0]
} }
@@ -188,24 +186,28 @@ func (d *DiagDense) DiagFrom(m Matrix) {
case RawBander: case RawBander:
mat := r.RawBand() mat := r.RawBand()
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride, Inc: mat.Stride,
Data: mat.Data[mat.KL : (n-1)*mat.Stride+mat.KL+1], Data: mat.Data[mat.KL : (n-1)*mat.Stride+mat.KL+1],
} }
case RawMatrixer: case RawMatrixer:
mat := r.RawMatrix() mat := r.RawMatrix()
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride + 1, Inc: mat.Stride + 1,
Data: mat.Data[:(n-1)*mat.Stride+n], Data: mat.Data[:(n-1)*mat.Stride+n],
} }
case RawSymBander: case RawSymBander:
mat := r.RawSymBand() mat := r.RawSymBand()
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride, Inc: mat.Stride,
Data: mat.Data[:(n-1)*mat.Stride+1], Data: mat.Data[:(n-1)*mat.Stride+1],
} }
case RawSymmetricer: case RawSymmetricer:
mat := r.RawSymmetric() mat := r.RawSymmetric()
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride + 1, Inc: mat.Stride + 1,
Data: mat.Data[:(n-1)*mat.Stride+n], Data: mat.Data[:(n-1)*mat.Stride+n],
} }
@@ -216,6 +218,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
data = data[mat.K:] data = data[mat.K:]
} }
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride, Inc: mat.Stride,
Data: data[:(n-1)*mat.Stride+1], Data: data[:(n-1)*mat.Stride+1],
} }
@@ -228,6 +231,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
return return
} }
vec = blas64.Vector{ vec = blas64.Vector{
N: n,
Inc: mat.Stride + 1, Inc: mat.Stride + 1,
Data: mat.Data[:(n-1)*mat.Stride+n], Data: mat.Data[:(n-1)*mat.Stride+n],
} }
@@ -240,7 +244,7 @@ func (d *DiagDense) DiagFrom(m Matrix) {
} }
return return
} }
blas64.Copy(n, vec, d.mat) blas64.Copy(vec, d.mat)
} }
// RawBand returns the underlying data used by the receiver represented // RawBand returns the underlying data used by the receiver represented
@@ -249,8 +253,8 @@ func (d *DiagDense) DiagFrom(m Matrix) {
// in returned blas64.Band. // in returned blas64.Band.
func (d *DiagDense) RawBand() blas64.Band { func (d *DiagDense) RawBand() blas64.Band {
return blas64.Band{ return blas64.Band{
Rows: d.n, Rows: d.mat.N,
Cols: d.n, Cols: d.mat.N,
KL: 0, KL: 0,
KU: 0, KU: 0,
Stride: d.mat.Inc, Stride: d.mat.Inc,
@@ -264,7 +268,7 @@ func (d *DiagDense) RawBand() blas64.Band {
// in returned blas64.Band. // in returned blas64.Band.
func (d *DiagDense) RawSymBand() blas64.SymmetricBand { func (d *DiagDense) RawSymBand() blas64.SymmetricBand {
return blas64.SymmetricBand{ return blas64.SymmetricBand{
N: d.n, N: d.mat.N,
K: 0, K: 0,
Stride: d.mat.Inc, Stride: d.mat.Inc,
Uplo: blas.Upper, Uplo: blas.Upper,
@@ -283,10 +287,10 @@ func (d *DiagDense) reuseAs(r int) {
Inc: 1, Inc: 1,
Data: use(d.mat.Data, r), Data: use(d.mat.Data, r),
} }
d.n = r d.mat.N = r
return return
} }
if r != d.n { if r != d.mat.N {
panic(ErrShape) panic(ErrShape)
} }
} }

View File

@@ -23,8 +23,7 @@ func TestNewDiagonal(t *testing.T) {
data: []float64{1, 2, 3, 4, 5, 6}, data: []float64{1, 2, 3, 4, 5, 6},
n: 6, n: 6,
mat: &DiagDense{ mat: &DiagDense{
mat: blas64.Vector{Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}}, mat: blas64.Vector{N: 6, Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
n: 6,
}, },
dense: NewDense(6, 6, []float64{ dense: NewDense(6, 6, []float64{
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
@@ -64,8 +63,7 @@ func TestDiagonalStride(t *testing.T) {
}{ }{
{ {
diag: &DiagDense{ diag: &DiagDense{
mat: blas64.Vector{Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}}, mat: blas64.Vector{N: 6, Inc: 1, Data: []float64{1, 2, 3, 4, 5, 6}},
n: 6,
}, },
dense: NewDense(6, 6, []float64{ dense: NewDense(6, 6, []float64{
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
@@ -78,7 +76,7 @@ func TestDiagonalStride(t *testing.T) {
}, },
{ {
diag: &DiagDense{ diag: &DiagDense{
mat: blas64.Vector{Inc: 2, Data: []float64{ mat: blas64.Vector{N: 6, Inc: 2, Data: []float64{
1, 0, 1, 0,
2, 0, 2, 0,
3, 0, 3, 0,
@@ -86,7 +84,6 @@ func TestDiagonalStride(t *testing.T) {
5, 0, 5, 0,
6, 6,
}}, }},
n: 6,
}, },
dense: NewDense(6, 6, []float64{ dense: NewDense(6, 6, []float64{
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
@@ -99,7 +96,7 @@ func TestDiagonalStride(t *testing.T) {
}, },
{ {
diag: &DiagDense{ diag: &DiagDense{
mat: blas64.Vector{Inc: 5, Data: []float64{ mat: blas64.Vector{N: 6, Inc: 5, Data: []float64{
1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
3, 0, 0, 0, 0, 3, 0, 0, 0, 0,
@@ -107,7 +104,6 @@ func TestDiagonalStride(t *testing.T) {
5, 0, 0, 0, 0, 5, 0, 0, 0, 0,
6, 6,
}}, }},
n: 6,
}, },
dense: NewDense(6, 6, []float64{ dense: NewDense(6, 6, []float64{
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,

View File

@@ -105,7 +105,7 @@ func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) {
var cv VecDense var cv VecDense
for j := 0; j < c; j++ { for j := 0; j < c; j++ {
cv.ColViewOf(v, 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)) b := make([]Dense, len(m))
@@ -183,7 +183,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
panic("hogsvd: invalid index") panic("hogsvd: invalid index")
} }
r, c := gsvd.b[n].Dims() _, c := gsvd.b[n].Dims()
if s == nil { if s == nil {
s = make([]float64, c) s = make([]float64, c)
} else if len(s) != c { } else if len(s) != c {
@@ -192,7 +192,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
var v VecDense var v VecDense
for j := 0; j < c; j++ { for j := 0; j < c; j++ {
v.ColViewOf(&gsvd.b[n], j) v.ColViewOf(&gsvd.b[n], j)
s[j] = blas64.Nrm2(r, v.mat) s[j] = blas64.Nrm2(v.mat)
} }
return s return s
} }

View File

@@ -54,7 +54,7 @@ func (v *VecDense) AtVec(i int) float64 {
} }
func (v *VecDense) at(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) panic(ErrRowAccess)
} }
return v.mat.Data[i*v.mat.Inc] 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) { func (v *VecDense) setVec(i int, val float64) {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.mat.N) {
panic(ErrVectorAccess) panic(ErrVectorAccess)
} }
v.mat.Data[i*v.mat.Inc] = val 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 { func (d *DiagDense) at(i, j int) float64 {
if uint(i) >= uint(d.n) { if uint(i) >= uint(d.mat.N) {
panic(ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(d.n) { if uint(j) >= uint(d.mat.N) {
panic(ErrColAccess) panic(ErrColAccess)
} }
if i != j { if i != j {
@@ -311,7 +311,7 @@ func (d *DiagDense) SetDiag(i int, v float64) {
} }
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) panic(ErrRowAccess)
} }
d.mat.Data[i*d.mat.Inc] = v d.mat.Data[i*d.mat.Inc] = v

View File

@@ -41,7 +41,7 @@ func (m *Dense) set(i, j int, v float64) {
// At returns the element at row i. // At returns the element at row i.
// It panics if i is out of bounds or if j is not zero. // It panics if i is out of bounds or if j is not zero.
func (v *VecDense) At(i, j int) float64 { func (v *VecDense) At(i, j int) float64 {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.mat.N) {
panic(ErrRowAccess) panic(ErrRowAccess)
} }
if j != 0 { if j != 0 {
@@ -53,7 +53,7 @@ func (v *VecDense) At(i, j int) float64 {
// AtVec returns the element at row i. // AtVec returns the element at row i.
// It panics if i is out of bounds. // It panics if i is out of bounds.
func (v *VecDense) AtVec(i int) float64 { func (v *VecDense) AtVec(i int) float64 {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.mat.N) {
panic(ErrRowAccess) panic(ErrRowAccess)
} }
return v.at(i) 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. // SetVec sets the element at row i to the value val.
// It panics if i is out of bounds. // It panics if i is out of bounds.
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) panic(ErrVectorAccess)
} }
v.setVec(i, val) 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. // At returns the element at row i, column j.
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) panic(ErrRowAccess)
} }
if uint(j) >= uint(d.n) { if uint(j) >= uint(d.mat.N) {
panic(ErrColAccess) panic(ErrColAccess)
} }
return d.at(i, j) 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. // 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. // It panics if the location is outside the appropriate region of the matrix.
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) panic(ErrRowAccess)
} }
d.setDiag(i, v) d.setDiag(i, v)

View File

@@ -130,8 +130,8 @@ func TestInnerSym(t *testing.T) {
func makeVecDenseInc(inc int, f []float64) *VecDense { func makeVecDenseInc(inc int, f []float64) *VecDense {
v := &VecDense{ v := &VecDense{
n: len(f),
mat: blas64.Vector{ mat: blas64.Vector{
N: len(f),
Inc: inc, Inc: inc,
Data: make([]float64, (len(f)-1)*inc+1), Data: make([]float64, (len(f)-1)*inc+1),
}, },

View File

@@ -259,7 +259,7 @@ func (m *Dense) UnmarshalBinaryFrom(r io.Reader) (int, error) {
// 32 - 39 0 (int64) // 32 - 39 0 (int64)
// 40 - .. vector's data elements (float64) // 40 - .. vector's data elements (float64)
func (v VecDense) MarshalBinary() ([]byte, error) { 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 { if bufLen <= 0 {
// bufLen is too big and has wrapped around. // bufLen is too big and has wrapped around.
return nil, errTooBig return nil, errTooBig
@@ -267,7 +267,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
header := storage{ header := storage{
Form: 'G', Packing: 'F', Uplo: 'A', Form: 'G', Packing: 'F', Uplo: 'A',
Rows: int64(v.n), Cols: 1, Rows: int64(v.mat.N), Cols: 1,
Version: version, Version: version,
} }
buf := make([]byte, bufLen) buf := make([]byte, bufLen)
@@ -277,7 +277,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
} }
p := headerSize 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))) binary.LittleEndian.PutUint64(buf[p:p+sizeFloat64], math.Float64bits(v.at(i)))
p += sizeFloat64 p += sizeFloat64
} }
@@ -292,7 +292,7 @@ func (v VecDense) MarshalBinary() ([]byte, error) {
func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) { func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) {
header := storage{ header := storage{
Form: 'G', Packing: 'F', Uplo: 'A', Form: 'G', Packing: 'F', Uplo: 'A',
Rows: int64(v.n), Cols: 1, Rows: int64(v.mat.N), Cols: 1,
Version: version, Version: version,
} }
n, err := header.marshalBinaryTo(w) n, err := header.marshalBinaryTo(w)
@@ -301,7 +301,7 @@ func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) {
} }
var buf [8]byte 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))) binary.LittleEndian.PutUint64(buf[:], math.Float64bits(v.at(i)))
nn, err := w.Write(buf[:]) nn, err := w.Write(buf[:])
n += nn n += nn

View File

@@ -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@"), 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{ want: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: []float64{0, 1, 2, 3, 4, 5, 6}, Data: []float64{0, 1, 2, 3, 4, 5, 6},
Inc: 3, Inc: 3,
}, },
n: 3,
}, },
eq: Equal, eq: Equal,
}, },

View File

@@ -373,10 +373,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
} }
mat := &VecDense{ mat := &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: length,
Inc: inc, Inc: inc,
Data: make([]float64, inc*(length-1)+1), Data: make([]float64, inc*(length-1)+1),
}, },
n: length,
} }
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
mat.SetVec(i, rand.NormFloat64()) mat.SetVec(i, rand.NormFloat64())
@@ -522,10 +522,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
} }
mat := &DiagDense{ mat := &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: inc, Inc: inc,
Data: make([]float64, inc*(n-1)+1), Data: make([]float64, inc*(n-1)+1),
}, },
n: n,
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
mat.SetDiag(i, rand.Float64()) mat.SetDiag(i, rand.Float64())
@@ -633,10 +633,10 @@ func makeCopyOf(a Matrix) Matrix {
case *VecDense: case *VecDense:
m := &VecDense{ m := &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: t.mat.N,
Inc: t.mat.Inc, 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) copy(m.mat.Data, t.mat.Data)
return m return m
@@ -655,8 +655,7 @@ func makeCopyOf(a Matrix) Matrix {
diag = (*DiagDense)(s) diag = (*DiagDense)(s)
} }
d := &DiagDense{ d := &DiagDense{
mat: blas64.Vector{Inc: diag.mat.Inc, Data: make([]float64, len(diag.mat.Data))}, mat: blas64.Vector{N: diag.mat.N, Inc: diag.mat.Inc, Data: make([]float64, len(diag.mat.Data))},
n: diag.n,
} }
copy(d.mat.Data, diag.mat.Data) copy(d.mat.Data, diag.mat.Data)
return returnAs(d, t) return returnAs(d, t)

View File

@@ -223,7 +223,7 @@ func (lq *LQ) SolveVec(x *VecDense, trans bool, b Vector) error {
if x != b { if x != b {
x.checkOverlap(bmat) x.checkOverlap(bmat)
} }
b := VecDense{mat: bmat, n: b.Len()} b := VecDense{mat: bmat}
bm = b.asDense() bm = b.asDense()
} }
if trans { if trans {

View File

@@ -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]) copy(dst, m.Data[j*m.Stride:j*m.Stride+m.Cols])
return dst return dst
} }
blas64.Copy(r, blas64.Copy(blas64.Vector{N: r, Inc: m.Stride, Data: m.Data[j:]},
blas64.Vector{Inc: m.Stride, Data: m.Data[j:]}, blas64.Vector{N: r, Inc: 1, Data: dst},
blas64.Vector{Inc: 1, Data: dst},
) )
return dst return dst
} }
@@ -264,9 +263,8 @@ func Row(dst []float64, i int, a Matrix) []float64 {
if rm, ok := aU.(RawMatrixer); ok { if rm, ok := aU.(RawMatrixer); ok {
m := rm.RawMatrix() m := rm.RawMatrix()
if aTrans { if aTrans {
blas64.Copy(c, blas64.Copy(blas64.Vector{N: c, Inc: m.Stride, Data: m.Data[i:]},
blas64.Vector{Inc: m.Stride, Data: m.Data[i:]}, blas64.Vector{N: c, Inc: 1, Data: dst},
blas64.Vector{Inc: 1, Data: dst},
) )
return dst return dst
} }
@@ -345,7 +343,7 @@ func Dot(a, b Vector) float64 {
} }
if arv, ok := a.(RawVectorer); ok { if arv, ok := a.(RawVectorer); ok {
if brv, ok := b.(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 var sum float64
@@ -408,7 +406,7 @@ func Equal(a, b Matrix) bool {
if rb, ok := bU.(*VecDense); ok { if rb, ok := bU.(*VecDense); ok {
// If the raw vectors are the same length they must either both be // If the raw vectors are the same length they must either both be
// transposed or both not transposed (or have length 1). // 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] { if ra.mat.Data[i*ra.mat.Inc] != rb.mat.Data[i*rb.mat.Inc] {
return false return false
} }
@@ -480,7 +478,7 @@ func EqualApprox(a, b Matrix, epsilon float64) bool {
if rb, ok := bU.(*VecDense); ok { if rb, ok := bU.(*VecDense); ok {
// If the raw vectors are the same length they must either both be // If the raw vectors are the same length they must either both be
// transposed or both not transposed (or have length 1). // 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) { if !floats.EqualWithinAbsOrRel(ra.mat.Data[i*ra.mat.Inc], rb.mat.Data[i*rb.mat.Inc], epsilon, epsilon) {
return false return false
} }
@@ -706,17 +704,17 @@ func Norm(a Matrix, norm float64) float64 {
panic("unreachable") panic("unreachable")
case 1: case 1:
if aTrans { if aTrans {
imax := blas64.Iamax(rma.n, rv) imax := blas64.Iamax(rv)
return math.Abs(rma.At(imax, 0)) return math.Abs(rma.At(imax, 0))
} }
return blas64.Asum(rma.n, rv) return blas64.Asum(rv)
case 2: case 2:
return blas64.Nrm2(rma.n, rv) return blas64.Nrm2(rv)
case math.Inf(1): case math.Inf(1):
if aTrans { 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)) return math.Abs(rma.At(imax, 0))
} }
} }

View File

@@ -186,7 +186,7 @@ func getWorkspaceVec(n int, clear bool) *VecDense {
if clear { if clear {
zero(v.mat.Data) zero(v.mat.Data)
} }
v.n = n v.mat.N = n
return v return v
} }

View File

@@ -220,7 +220,7 @@ func (qr *QR) SolveVec(x *VecDense, trans bool, b Vector) error {
if x != b { if x != b {
x.checkOverlap(bmat) x.checkOverlap(bmat)
} }
b := VecDense{mat: bmat, n: b.Len()} b := VecDense{mat: bmat}
bm = b.asDense() bm = b.asDense()
} }
if trans { if trans {

View File

@@ -56,10 +56,8 @@ func isOrthonormal(q *Dense, tol float64) bool {
} }
for i := 0; i < m; i++ { for i := 0; i < m; i++ {
for j := i; j < m; j++ { for j := i; j < m; j++ {
dot := blas64.Dot(m, dot := blas64.Dot(blas64.Vector{N: m, Inc: 1, Data: q.mat.Data[i*q.mat.Stride:]},
blas64.Vector{Inc: 1, Data: q.mat.Data[i*q.mat.Stride:]}, blas64.Vector{N: m, Inc: 1, Data: q.mat.Data[j*q.mat.Stride:]})
blas64.Vector{Inc: 1, Data: q.mat.Data[j*q.mat.Stride:]},
)
// Dot product should be 1 if i == j and 0 otherwise. // Dot product should be 1 if i == j and 0 otherwise.
if i == j && math.Abs(dot-1) > tol { if i == j && math.Abs(dot-1) > tol {
return false return false

View File

@@ -128,7 +128,7 @@ func (v *VecDense) SolveVec(a Matrix, b Vector) error {
// and bm as overlapping but not identical. // and bm as overlapping but not identical.
bm := m bm := m
if v != b { if v != b {
b := VecDense{mat: bmat, n: b.Len()} b := VecDense{mat: bmat}
bm = b.asDense() bm = b.asDense()
} }
return m.Solve(a, bm) return m.Solve(a, bm)

View File

@@ -150,10 +150,10 @@ func (s *SymBandDense) DiagView() Diagonal {
n := s.mat.N n := s.mat.N
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: s.mat.Stride, Inc: s.mat.Stride,
Data: s.mat.Data[:(n-1)*s.mat.Stride+1], Data: s.mat.Data[:(n-1)*s.mat.Stride+1],
}, },
n: n,
} }
} }

View File

@@ -183,10 +183,10 @@ func (s *SymDense) DiagView() Diagonal {
n := s.mat.N n := s.mat.N
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: s.mat.Stride + 1, Inc: s.mat.Stride + 1,
Data: s.mat.Data[:(n-1)*s.mat.Stride+n], 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) xU, _ := untranspose(x)
if rv, ok := xU.(RawVectorer); ok { if rv, ok := xU.(RawVectorer); ok {
xmat := rv.RawVector() xmat := rv.RawVector()
s.checkOverlap((&VecDense{mat: xmat, n: n}).asGeneral()) s.checkOverlap((&VecDense{mat: xmat}).asGeneral())
blas64.Syr(alpha, xmat, s.mat) blas64.Syr(alpha, xmat, s.mat)
return return
} }
@@ -387,14 +387,14 @@ func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y Vector) {
xU, _ := untranspose(x) xU, _ := untranspose(x)
if rv, ok := xU.(RawVectorer); ok { if rv, ok := xU.(RawVectorer); ok {
xmat = rv.RawVector() xmat = rv.RawVector()
s.checkOverlap((&VecDense{mat: xmat, n: x.Len()}).asGeneral()) s.checkOverlap((&VecDense{mat: xmat}).asGeneral())
} else { } else {
fast = false fast = false
} }
yU, _ := untranspose(y) yU, _ := untranspose(y)
if rv, ok := yU.(RawVectorer); ok { if rv, ok := yU.(RawVectorer); ok {
ymat = rv.RawVector() ymat = rv.RawVector()
s.checkOverlap((&VecDense{mat: ymat, n: y.Len()}).asGeneral()) s.checkOverlap((&VecDense{mat: ymat}).asGeneral())
} else { } else {
fast = false fast = false
} }

View File

@@ -304,10 +304,10 @@ func (t *TriDense) DiagView() Diagonal {
n := t.mat.N n := t.mat.N
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: t.mat.Stride + 1, Inc: t.mat.Stride + 1,
Data: t.mat.Data[:(n-1)*t.mat.Stride+n], Data: t.mat.Data[:(n-1)*t.mat.Stride+n],
}, },
n: n,
} }
} }

View File

@@ -318,9 +318,9 @@ func (t *TriBandDense) DiagView() Diagonal {
} }
return &DiagDense{ return &DiagDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: t.mat.Stride, Inc: t.mat.Stride,
Data: data[:(n-1)*t.mat.Stride+1], Data: data[:(n-1)*t.mat.Stride+1],
}, },
n: n,
} }
} }

View File

@@ -76,7 +76,6 @@ func (t TransposeVec) UntransposeVec() Vector {
// VecDense represents a column vector. // VecDense represents a column vector.
type VecDense struct { type VecDense struct {
mat blas64.Vector mat blas64.Vector
n int
// A BLAS vector can have a negative increment, but allowing this // 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. // in the mat type complicates a lot of code, and doesn't gain anything.
// VecDense must have positive increment in this package. // VecDense must have positive increment in this package.
@@ -102,10 +101,10 @@ func NewVecDense(n int, data []float64) *VecDense {
} }
return &VecDense{ return &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: n,
Inc: 1, Inc: 1,
Data: data, Data: data,
}, },
n: n,
} }
} }
@@ -118,8 +117,8 @@ func (v *VecDense) SliceVec(i, k int) Vector {
panic(ErrIndexOutOfRange) panic(ErrIndexOutOfRange)
} }
return &VecDense{ return &VecDense{
n: k - i,
mat: blas64.Vector{ mat: blas64.Vector{
N: k - i,
Inc: v.mat.Inc, Inc: v.mat.Inc,
Data: v.mat.Data[i*v.mat.Inc : (k-1)*v.mat.Inc+1], 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() { if v.IsZero() {
return 0, 0 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 // 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. // Len returns the length of the vector.
func (v *VecDense) Len() int { func (v *VecDense) Len() int {
return v.n return v.mat.N
} }
// Cap returns the capacity of the vector. // Cap returns the capacity of the vector.
@@ -172,10 +171,10 @@ func (v *VecDense) TVec() Vector {
// //
// See the Reseter interface for more information. // See the Reseter interface for more information.
func (v *VecDense) Reset() { 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. // made unless both are set to 0.
v.mat.Inc = 0 v.mat.Inc = 0
v.n = 0 v.mat.N = 0
v.mat.Data = v.mat.Data[:0] v.mat.Data = v.mat.Data[:0]
} }
@@ -185,13 +184,14 @@ func (v *VecDense) CloneVec(a Vector) {
if v == a { if v == a {
return return
} }
v.n = a.Len() n := a.Len()
v.mat = blas64.Vector{ v.mat = blas64.Vector{
N: n,
Inc: 1, Inc: 1,
Data: use(v.mat.Data, v.n), Data: use(v.mat.Data, n),
} }
if r, ok := a.(RawVectorer); ok { if r, ok := a.(RawVectorer); ok {
blas64.Copy(v.n, r.RawVector(), v.mat) blas64.Copy(r.RawVector(), v.mat)
return return
} }
for i := 0; i < a.Len(); i++ { for i := 0; i < a.Len(); i++ {
@@ -219,7 +219,7 @@ func (v *VecDense) CopyVec(a Vector) int {
return n return n
} }
if r, ok := a.(RawVectorer); ok { if r, ok := a.(RawVectorer); ok {
blas64.Copy(n, r.RawVector(), v.mat) blas64.Copy(r.RawVector(), v.mat)
return n return n
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@@ -308,7 +308,7 @@ func (v *VecDense) AddScaledVec(a Vector, alpha float64, b Vector) {
} }
v.CopyVec(a) v.CopyVec(a)
case v == a && v == b: // v <- v + alpha * v = (alpha + 1) * v 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. case !fast: // v <- a + alpha * b without blas64 support.
for i := 0; i < ar; i++ { for i := 0; i < ar; i++ {
v.setVec(i, a.AtVec(i)+alpha*b.AtVec(i)) v.setVec(i, a.AtVec(i)+alpha*b.AtVec(i))
@@ -645,13 +645,13 @@ func (v *VecDense) reuseAs(r int) {
} }
if v.IsZero() { if v.IsZero() {
v.mat = blas64.Vector{ v.mat = blas64.Vector{
N: r,
Inc: 1, Inc: 1,
Data: use(v.mat.Data, r), Data: use(v.mat.Data, r),
} }
v.n = r
return return
} }
if r != v.n { if r != v.mat.N {
panic(ErrShape) panic(ErrShape)
} }
} }
@@ -681,7 +681,7 @@ func (v *VecDense) isolatedWorkspace(a Vector) (n *VecDense, restore func()) {
func (v *VecDense) asDense() *Dense { func (v *VecDense) asDense() *Dense {
return &Dense{ return &Dense{
mat: v.asGeneral(), mat: v.asGeneral(),
capRows: v.n, capRows: v.mat.N,
capCols: 1, capCols: 1,
} }
} }
@@ -690,7 +690,7 @@ func (v *VecDense) asDense() *Dense {
// same underlying data. // same underlying data.
func (v *VecDense) asGeneral() blas64.General { func (v *VecDense) asGeneral() blas64.General {
return blas64.General{ return blas64.General{
Rows: v.n, Rows: v.mat.N,
Cols: 1, Cols: 1,
Stride: v.mat.Inc, Stride: v.mat.Inc,
Data: v.mat.Data, Data: v.mat.Data,
@@ -706,13 +706,13 @@ func (v *VecDense) ColViewOf(m RawMatrixer, j int) {
if j >= rm.Cols || j < 0 { if j >= rm.Cols || j < 0 {
panic(ErrColAccess) panic(ErrColAccess)
} }
if !v.IsZero() && v.n != rm.Rows { if !v.IsZero() && v.mat.N != rm.Rows {
panic(ErrShape) panic(ErrShape)
} }
v.mat.Inc = rm.Stride v.mat.Inc = rm.Stride
v.mat.Data = rm.Data[j : (rm.Rows-1)*rm.Stride+j+1] 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 // 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 { if i >= rm.Rows || i < 0 {
panic(ErrRowAccess) panic(ErrRowAccess)
} }
if !v.IsZero() && v.n != rm.Cols { if !v.IsZero() && v.mat.N != rm.Cols {
panic(ErrShape) panic(ErrShape)
} }
v.mat.Inc = 1 v.mat.Inc = 1
v.mat.Data = rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols] v.mat.Data = rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols]
v.n = rm.Cols v.mat.N = rm.Cols
} }

View File

@@ -24,10 +24,10 @@ func TestNewVecDense(t *testing.T) {
data: []float64{4, 5, 6}, data: []float64{4, 5, 6},
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: []float64{4, 5, 6}, Data: []float64{4, 5, 6},
Inc: 1, Inc: 1,
}, },
n: 3,
}, },
}, },
{ {
@@ -35,10 +35,10 @@ func TestNewVecDense(t *testing.T) {
data: nil, data: nil,
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: []float64{0, 0, 0}, Data: []float64{0, 0, 0},
Inc: 1, Inc: 1,
}, },
n: 3,
}, },
}, },
} { } {
@@ -65,50 +65,50 @@ func TestCap(t *testing.T) {
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: make([]float64, 7, 10), Data: make([]float64, 7, 10),
Inc: 3, Inc: 3,
}, },
n: 3,
}, },
want: 4, want: 4,
}, },
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 4,
Data: make([]float64, 10), Data: make([]float64, 10),
Inc: 3, Inc: 3,
}, },
n: 4,
}, },
want: 4, want: 4,
}, },
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 4,
Data: make([]float64, 11), Data: make([]float64, 11),
Inc: 3, Inc: 3,
}, },
n: 4,
}, },
want: 4, want: 4,
}, },
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 4,
Data: make([]float64, 12), Data: make([]float64, 12),
Inc: 3, Inc: 3,
}, },
n: 4,
}, },
want: 4, want: 4,
}, },
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 4,
Data: make([]float64, 13), Data: make([]float64, 13),
Inc: 3, Inc: 3,
}, },
n: 4,
}, },
want: 5, want: 5,
}, },
@@ -127,24 +127,24 @@ func TestVecDenseAtSet(t *testing.T) {
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: []float64{0, 1, 2}, Data: []float64{0, 1, 2},
Inc: 1, Inc: 1,
}, },
n: 3,
}, },
}, },
{ {
vector: &VecDense{ vector: &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: 3,
Data: []float64{0, 10, 10, 1, 10, 10, 2}, Data: []float64{0, 10, 10, 1, 10, 10, 2},
Inc: 3, Inc: 3,
}, },
n: 3,
}, },
}, },
} { } {
v := test.vector v := test.vector
n := test.vector.n n := test.vector.mat.N
for _, row := range []int{-1, n} { for _, row := range []int{-1, n} {
panicked, message := panics(func() { v.At(row, 0) }) 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{ return &VecDense{
mat: blas64.Vector{ mat: blas64.Vector{
N: size,
Inc: inc, Inc: inc,
Data: data, Data: data,
}, },
n: size,
} }
} }

View File

@@ -81,9 +81,7 @@ func TorgersonScaling(dst *mat.Dense, eigdst []float64, dis mat.Symmetric) (k in
func reverse(values []float64, vectors blas64.General) { func reverse(values []float64, vectors blas64.General) {
for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 {
values[i], values[j] = values[j], values[i] values[i], values[j] = values[j], values[i]
blas64.Swap(vectors.Rows, blas64.Swap(blas64.Vector{N: vectors.Rows, Inc: vectors.Stride, Data: vectors.Data[i:]},
blas64.Vector{Inc: vectors.Stride, Data: vectors.Data[i:]}, blas64.Vector{N: vectors.Rows, Inc: vectors.Stride, Data: vectors.Data[j:]})
blas64.Vector{Inc: vectors.Stride, Data: vectors.Data[j:]},
)
} }
} }