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.
|
// 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
|
||||||
|
@@ -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})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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,
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
35
mat/dense.go
35
mat/dense.go
@@ -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.
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
@@ -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),
|
||||||
},
|
},
|
||||||
|
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)
|
// 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
|
||||||
|
@@ -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,
|
||||||
},
|
},
|
||||||
|
@@ -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)
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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:]},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user