mirror of
https://github.com/gonum/gonum.git
synced 2025-10-07 16:11:03 +08:00
mat: rename Vector->VecDense
This commit is contained in:
@@ -135,7 +135,7 @@ func jacobianConcurrent(dst *mat.Dense, f func([]float64, []float64), x, origin
|
|||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
xcopy := make([]float64, n)
|
xcopy := make([]float64, n)
|
||||||
y := make([]float64, m)
|
y := make([]float64, m)
|
||||||
yVec := mat.NewVector(m, y)
|
yVec := mat.NewVecDense(m, y)
|
||||||
for job := range jobs {
|
for job := range jobs {
|
||||||
copy(xcopy, x)
|
copy(xcopy, x)
|
||||||
xcopy[job.j] += job.pt.Loc * step
|
xcopy[job.j] += job.pt.Loc * step
|
||||||
@@ -179,7 +179,7 @@ func jacobianConcurrent(dst *mat.Dense, f func([]float64, []float64), x, origin
|
|||||||
// all columns of dst. Iterate again over all Formula points
|
// all columns of dst. Iterate again over all Formula points
|
||||||
// because we don't forbid repeated locations.
|
// because we don't forbid repeated locations.
|
||||||
|
|
||||||
originVec := mat.NewVector(m, origin)
|
originVec := mat.NewVecDense(m, origin)
|
||||||
for _, pt := range formula.Stencil {
|
for _, pt := range formula.Stencil {
|
||||||
if pt.Loc != 0 {
|
if pt.Loc != 0 {
|
||||||
continue
|
continue
|
||||||
|
@@ -55,7 +55,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int64]float64 {
|
|||||||
for i := range last {
|
for i := range last {
|
||||||
last[i] = 1
|
last[i] = 1
|
||||||
}
|
}
|
||||||
lastV := mat.NewVector(len(nodes), last)
|
lastV := mat.NewVecDense(len(nodes), last)
|
||||||
|
|
||||||
vec := make([]float64, len(nodes))
|
vec := make([]float64, len(nodes))
|
||||||
var sum float64
|
var sum float64
|
||||||
@@ -68,7 +68,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int64]float64 {
|
|||||||
for i := range vec {
|
for i := range vec {
|
||||||
vec[i] *= f
|
vec[i] *= f
|
||||||
}
|
}
|
||||||
v := mat.NewVector(len(nodes), vec)
|
v := mat.NewVecDense(len(nodes), vec)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
lastV, v = v, lastV
|
lastV, v = v, lastV
|
||||||
@@ -122,7 +122,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int64]float64 {
|
|||||||
for i := range last {
|
for i := range last {
|
||||||
last[i] = 1
|
last[i] = 1
|
||||||
}
|
}
|
||||||
lastV := mat.NewVector(len(nodes), last)
|
lastV := mat.NewVecDense(len(nodes), last)
|
||||||
|
|
||||||
vec := make([]float64, len(nodes))
|
vec := make([]float64, len(nodes))
|
||||||
var sum float64
|
var sum float64
|
||||||
@@ -135,7 +135,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int64]float64 {
|
|||||||
for i := range vec {
|
for i := range vec {
|
||||||
vec[i] *= f
|
vec[i] *= f
|
||||||
}
|
}
|
||||||
v := mat.NewVector(len(nodes), vec)
|
v := mat.NewVecDense(len(nodes), vec)
|
||||||
|
|
||||||
dt := (1 - damp) / float64(len(nodes))
|
dt := (1 - damp) / float64(len(nodes))
|
||||||
for {
|
for {
|
||||||
@@ -171,7 +171,7 @@ func (m rowCompressedMatrix) addTo(i, j int, v float64) { m[i].addTo(j, v) }
|
|||||||
// mulVecUnitary multiplies the receiver by the src vector, storing
|
// mulVecUnitary multiplies the receiver by the src vector, storing
|
||||||
// the result in dst. It assumes src and dst are the same length as m
|
// the result in dst. It assumes src and dst are the same length as m
|
||||||
// and that both have unitary vector increments.
|
// and that both have unitary vector increments.
|
||||||
func (m rowCompressedMatrix) mulVecUnitary(dst, src *mat.Vector) {
|
func (m rowCompressedMatrix) mulVecUnitary(dst, src *mat.VecDense) {
|
||||||
dMat := dst.RawVector().Data
|
dMat := dst.RawVector().Data
|
||||||
for i, r := range m {
|
for i, r := range m {
|
||||||
dMat[i] = r.dotUnitary(src)
|
dMat[i] = r.dotUnitary(src)
|
||||||
@@ -190,7 +190,7 @@ func (r *compressedRow) addTo(j int, v float64) {
|
|||||||
|
|
||||||
// dotUnitary performs a simplified scatter-based Ddot operations on
|
// dotUnitary performs a simplified scatter-based Ddot operations on
|
||||||
// v and the receiver. v must have have a unitary vector increment.
|
// v and the receiver. v must have have a unitary vector increment.
|
||||||
func (r compressedRow) dotUnitary(v *mat.Vector) float64 {
|
func (r compressedRow) dotUnitary(v *mat.VecDense) float64 {
|
||||||
var sum float64
|
var sum float64
|
||||||
vec := v.RawVector().Data
|
vec := v.RawVector().Data
|
||||||
for _, e := range r {
|
for _, e := range r {
|
||||||
@@ -208,7 +208,7 @@ type sparseElement struct {
|
|||||||
// onesDotUnitary performs the equivalent of a Ddot of v with
|
// onesDotUnitary performs the equivalent of a Ddot of v with
|
||||||
// a ones vector of equal length. v must have have a unitary
|
// a ones vector of equal length. v must have have a unitary
|
||||||
// vector increment.
|
// vector increment.
|
||||||
func onesDotUnitary(alpha float64, v *mat.Vector) float64 {
|
func onesDotUnitary(alpha float64, v *mat.VecDense) float64 {
|
||||||
var sum float64
|
var sum float64
|
||||||
for _, f := range v.RawVector().Data {
|
for _, f := range v.RawVector().Data {
|
||||||
sum += alpha * f
|
sum += alpha * f
|
||||||
|
@@ -207,7 +207,7 @@ func (m *Dense) solveTwoChol(a, b *Cholesky) error {
|
|||||||
|
|
||||||
// SolveVec finds the vector v that solves A * v = b where A is represented
|
// SolveVec finds the vector v that solves A * v = b where A is represented
|
||||||
// by the Cholesky decomposition, placing the result in v.
|
// by the Cholesky decomposition, placing the result in v.
|
||||||
func (c *Cholesky) SolveVec(v, b *Vector) error {
|
func (c *Cholesky) SolveVec(v, b *VecDense) error {
|
||||||
if !c.valid() {
|
if !c.valid() {
|
||||||
panic(badCholesky)
|
panic(badCholesky)
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ func (c *Cholesky) InverseTo(s *SymDense) error {
|
|||||||
//
|
//
|
||||||
// SymRankOne updates a Cholesky factorization in O(n²) time. The Cholesky
|
// SymRankOne updates a Cholesky factorization in O(n²) time. The Cholesky
|
||||||
// factorization computation from scratch is O(n³).
|
// factorization computation from scratch is O(n³).
|
||||||
func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x *Vector) (ok bool) {
|
func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x *VecDense) (ok bool) {
|
||||||
if !orig.valid() {
|
if !orig.valid() {
|
||||||
panic(badCholesky)
|
panic(badCholesky)
|
||||||
}
|
}
|
||||||
|
@@ -33,8 +33,8 @@ func ExampleCholesky() {
|
|||||||
fmt.Printf("\nThe determinant of a is %0.4g\n\n", chol.Det())
|
fmt.Printf("\nThe determinant of a is %0.4g\n\n", chol.Det())
|
||||||
|
|
||||||
// Use the factorization to solve the system of equations a * x = b.
|
// Use the factorization to solve the system of equations a * x = b.
|
||||||
b := mat.NewVector(4, []float64{1, 2, 3, 4})
|
b := mat.NewVecDense(4, []float64{1, 2, 3, 4})
|
||||||
var x mat.Vector
|
var x mat.VecDense
|
||||||
if err := chol.SolveVec(&x, b); err != nil {
|
if err := chol.SolveVec(&x, b); err != nil {
|
||||||
fmt.Println("Matrix is near singular: ", err)
|
fmt.Println("Matrix is near singular: ", err)
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ func ExampleCholesky_SymRankOne() {
|
|||||||
fmt.Println("matrix a is not positive definite.")
|
fmt.Println("matrix a is not positive definite.")
|
||||||
}
|
}
|
||||||
|
|
||||||
x := mat.NewVector(4, []float64{0, 0, 0, 1})
|
x := mat.NewVecDense(4, []float64{0, 0, 0, 1})
|
||||||
fmt.Printf("\nx = %0.4v\n", mat.Formatted(x, mat.Prefix(" ")))
|
fmt.Printf("\nx = %0.4v\n", mat.Formatted(x, mat.Prefix(" ")))
|
||||||
|
|
||||||
// Rank-1 update the factorization.
|
// Rank-1 update the factorization.
|
||||||
|
@@ -178,16 +178,16 @@ func TestSolveTwoChol(t *testing.T) {
|
|||||||
func TestCholeskySolveVec(t *testing.T) {
|
func TestCholeskySolveVec(t *testing.T) {
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
a *SymDense
|
a *SymDense
|
||||||
b *Vector
|
b *VecDense
|
||||||
ans *Vector
|
ans *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewSymDense(2, []float64{
|
a: NewSymDense(2, []float64{
|
||||||
1, 0,
|
1, 0,
|
||||||
0, 1,
|
0, 1,
|
||||||
}),
|
}),
|
||||||
b: NewVector(2, []float64{5, 6}),
|
b: NewVecDense(2, []float64{5, 6}),
|
||||||
ans: NewVector(2, []float64{5, 6}),
|
ans: NewVecDense(2, []float64{5, 6}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewSymDense(3, []float64{
|
a: NewSymDense(3, []float64{
|
||||||
@@ -195,8 +195,8 @@ func TestCholeskySolveVec(t *testing.T) {
|
|||||||
0, 83, 71,
|
0, 83, 71,
|
||||||
0, 0, 101,
|
0, 0, 101,
|
||||||
}),
|
}),
|
||||||
b: NewVector(3, []float64{5, 6, 7}),
|
b: NewVecDense(3, []float64{5, 6, 7}),
|
||||||
ans: NewVector(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
|
ans: NewVecDense(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var chol Cholesky
|
var chol Cholesky
|
||||||
@@ -205,13 +205,13 @@ func TestCholeskySolveVec(t *testing.T) {
|
|||||||
t.Fatal("unexpected Cholesky factorization failure: not positive definite")
|
t.Fatal("unexpected Cholesky factorization failure: not positive definite")
|
||||||
}
|
}
|
||||||
|
|
||||||
var x Vector
|
var x VecDense
|
||||||
chol.SolveVec(&x, test.b)
|
chol.SolveVec(&x, test.b)
|
||||||
if !EqualApprox(&x, test.ans, 1e-12) {
|
if !EqualApprox(&x, test.ans, 1e-12) {
|
||||||
t.Error("incorrect Cholesky solve solution")
|
t.Error("incorrect Cholesky solve solution")
|
||||||
}
|
}
|
||||||
|
|
||||||
var ans Vector
|
var ans VecDense
|
||||||
ans.MulVec(test.a, &x)
|
ans.MulVec(test.a, &x)
|
||||||
if !EqualApprox(&ans, test.b, 1e-12) {
|
if !EqualApprox(&ans, test.b, 1e-12) {
|
||||||
t.Error("incorrect Cholesky solve solution product")
|
t.Error("incorrect Cholesky solve solution product")
|
||||||
@@ -320,7 +320,7 @@ func TestCholeskySymRankOne(t *testing.T) {
|
|||||||
for i := range xdata {
|
for i := range xdata {
|
||||||
xdata[i] = rand.NormFloat64()
|
xdata[i] = rand.NormFloat64()
|
||||||
}
|
}
|
||||||
x := NewVector(n, xdata)
|
x := NewVecDense(n, xdata)
|
||||||
|
|
||||||
var chol Cholesky
|
var chol Cholesky
|
||||||
ok := chol.Factorize(&a)
|
ok := chol.Factorize(&a)
|
||||||
@@ -397,7 +397,7 @@ func TestCholeskySymRankOne(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
x := NewVector(len(test.x), test.x)
|
x := NewVecDense(len(test.x), test.x)
|
||||||
ok = chol.SymRankOne(&chol, test.alpha, x)
|
ok = chol.SymRankOne(&chol, test.alpha, x)
|
||||||
if !ok {
|
if !ok {
|
||||||
if test.wantOk {
|
if test.wantOk {
|
||||||
|
16
mat/dense.go
16
mat/dense.go
@@ -201,14 +201,14 @@ func (m *Dense) T() Matrix {
|
|||||||
return Transpose{m}
|
return Transpose{m}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColView returns a Vector reflecting the column j, backed by the matrix data.
|
// ColView returns a VecDense reflecting the column j, backed by the matrix data.
|
||||||
//
|
//
|
||||||
// See ColViewer for more information.
|
// See ColViewer for more information.
|
||||||
func (m *Dense) ColView(j int) *Vector {
|
func (m *Dense) ColView(j int) *VecDense {
|
||||||
if j >= m.mat.Cols || j < 0 {
|
if j >= m.mat.Cols || j < 0 {
|
||||||
panic(ErrColAccess)
|
panic(ErrColAccess)
|
||||||
}
|
}
|
||||||
return &Vector{
|
return &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: m.mat.Stride,
|
Inc: m.mat.Stride,
|
||||||
Data: m.mat.Data[j : (m.mat.Rows-1)*m.mat.Stride+j+1],
|
Data: m.mat.Data[j : (m.mat.Rows-1)*m.mat.Stride+j+1],
|
||||||
@@ -250,11 +250,11 @@ func (m *Dense) SetRow(i int, src []float64) {
|
|||||||
// backed by the matrix data.
|
// backed by the matrix data.
|
||||||
//
|
//
|
||||||
// See RowViewer for more information.
|
// See RowViewer for more information.
|
||||||
func (m *Dense) RowView(i int) *Vector {
|
func (m *Dense) RowView(i int) *VecDense {
|
||||||
if i >= m.mat.Rows || i < 0 {
|
if i >= m.mat.Rows || i < 0 {
|
||||||
panic(ErrRowAccess)
|
panic(ErrRowAccess)
|
||||||
}
|
}
|
||||||
return &Vector{
|
return &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
Data: m.rawRowView(i),
|
Data: m.rawRowView(i),
|
||||||
@@ -391,7 +391,7 @@ func (m *Dense) Clone(a Matrix) {
|
|||||||
copy(mat.Data[i*c:(i+1)*c], amat.Data[i*amat.Stride:i*amat.Stride+c])
|
copy(mat.Data[i*c:(i+1)*c], amat.Data[i*amat.Stride:i*amat.Stride+c])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
amat := aU.mat
|
amat := aU.mat
|
||||||
mat.Data = make([]float64, aU.n)
|
mat.Data = make([]float64, aU.n)
|
||||||
blas64.Copy(aU.n,
|
blas64.Copy(aU.n,
|
||||||
@@ -415,7 +415,7 @@ func (m *Dense) Clone(a Matrix) {
|
|||||||
// Copy makes a copy of elements of a into the receiver. It is similar to the
|
// Copy makes a copy of elements of a into the receiver. It is similar to the
|
||||||
// built-in copy; it copies as much as the overlap between the two matrices and
|
// built-in copy; it copies as much as the overlap between the two matrices and
|
||||||
// returns the number of rows and columns it copied. If a aliases the receiver
|
// returns the number of rows and columns it copied. If a aliases the receiver
|
||||||
// and is a transposed Dense or Vector, with a non-unitary increment, Copy will
|
// and is a transposed Dense or VecDense, with a non-unitary increment, Copy will
|
||||||
// panic.
|
// panic.
|
||||||
//
|
//
|
||||||
// See the Copier interface for more information.
|
// See the Copier interface for more information.
|
||||||
@@ -457,7 +457,7 @@ func (m *Dense) Copy(a Matrix) (r, c int) {
|
|||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
var n, stride int
|
var n, stride int
|
||||||
amat := aU.mat
|
amat := aU.mat
|
||||||
if trans {
|
if trans {
|
||||||
|
@@ -338,7 +338,7 @@ func (m *Dense) Mul(a, b Matrix) {
|
|||||||
blas64.Trmm(blas.Right, bT, 1, bmat, m.mat)
|
blas64.Trmm(blas.Right, bT, 1, bmat, m.mat)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if bU, ok := bU.(*Vector); ok {
|
if bU, ok := bU.(*VecDense); ok {
|
||||||
m.checkOverlap(bU.asGeneral())
|
m.checkOverlap(bU.asGeneral())
|
||||||
bvec := bU.RawVector()
|
bvec := bU.RawVector()
|
||||||
if bTrans {
|
if bTrans {
|
||||||
@@ -399,7 +399,7 @@ func (m *Dense) Mul(a, b Matrix) {
|
|||||||
blas64.Trmm(blas.Left, aT, 1, amat, m.mat)
|
blas64.Trmm(blas.Left, aT, 1, amat, m.mat)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if aU, ok := aU.(*Vector); ok {
|
if aU, ok := aU.(*VecDense); ok {
|
||||||
m.checkOverlap(aU.asGeneral())
|
m.checkOverlap(aU.asGeneral())
|
||||||
avec := aU.RawVector()
|
avec := aU.RawVector()
|
||||||
if aTrans {
|
if aTrans {
|
||||||
@@ -653,7 +653,7 @@ func (m *Dense) Apply(fn func(i, j int, v float64) float64, a Matrix) {
|
|||||||
// RankOne performs a rank-one update to the matrix a and stores the result
|
// RankOne performs a rank-one update to the matrix a and stores the result
|
||||||
// in the receiver. If a is zero, see Outer.
|
// in the receiver. If a is zero, see Outer.
|
||||||
// m = a + alpha * x * y'
|
// m = a + alpha * x * y'
|
||||||
func (m *Dense) RankOne(a Matrix, alpha float64, x, y *Vector) {
|
func (m *Dense) RankOne(a Matrix, alpha float64, x, y *VecDense) {
|
||||||
ar, ac := a.Dims()
|
ar, ac := a.Dims()
|
||||||
if x.Len() != ar {
|
if x.Len() != ar {
|
||||||
panic(ErrShape)
|
panic(ErrShape)
|
||||||
@@ -683,7 +683,7 @@ func (m *Dense) RankOne(a Matrix, alpha float64, x, y *Vector) {
|
|||||||
// in the receiver.
|
// in the receiver.
|
||||||
// m = alpha * x * y'
|
// m = alpha * x * y'
|
||||||
// In order to update an existing matrix, see RankOne.
|
// In order to update an existing matrix, see RankOne.
|
||||||
func (m *Dense) Outer(alpha float64, x, y *Vector) {
|
func (m *Dense) Outer(alpha float64, x, y *VecDense) {
|
||||||
r := x.Len()
|
r := x.Len()
|
||||||
c := y.Len()
|
c := y.Len()
|
||||||
|
|
||||||
|
@@ -1202,7 +1202,7 @@ func TestCopyDenseAlias(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCopyVectorAlias(t *testing.T) {
|
func TestCopyVecDenseAlias(t *testing.T) {
|
||||||
for _, horiz := range []bool{false, true} {
|
for _, horiz := range []bool{false, true} {
|
||||||
for do := 0; do < 2; do++ {
|
for do := 0; do < 2; do++ {
|
||||||
for di := 0; di < 3; di++ {
|
for di := 0; di < 3; di++ {
|
||||||
@@ -1212,7 +1212,7 @@ func TestCopyVectorAlias(t *testing.T) {
|
|||||||
4, 5, 6,
|
4, 5, 6,
|
||||||
7, 8, 9,
|
7, 8, 9,
|
||||||
})
|
})
|
||||||
var src *Vector
|
var src *VecDense
|
||||||
var want *Dense
|
var want *Dense
|
||||||
if horiz {
|
if horiz {
|
||||||
src = a.RowView(si)
|
src = a.RowView(si)
|
||||||
@@ -1549,12 +1549,12 @@ func TestRankOne(t *testing.T) {
|
|||||||
a := NewDense(flatten(test.m))
|
a := NewDense(flatten(test.m))
|
||||||
m := &Dense{}
|
m := &Dense{}
|
||||||
// Check with a new matrix
|
// Check with a new matrix
|
||||||
m.RankOne(a, test.alpha, NewVector(len(test.x), test.x), NewVector(len(test.y), test.y))
|
m.RankOne(a, test.alpha, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y))
|
||||||
if !Equal(m, want) {
|
if !Equal(m, want) {
|
||||||
t.Errorf("unexpected result for RankOne test %d iteration 0: got: %+v want: %+v", i, m, want)
|
t.Errorf("unexpected result for RankOne test %d iteration 0: got: %+v want: %+v", i, m, want)
|
||||||
}
|
}
|
||||||
// Check with the same matrix
|
// Check with the same matrix
|
||||||
a.RankOne(a, test.alpha, NewVector(len(test.x), test.x), NewVector(len(test.y), test.y))
|
a.RankOne(a, test.alpha, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y))
|
||||||
if !Equal(a, want) {
|
if !Equal(a, want) {
|
||||||
t.Errorf("unexpected result for Outer test %d iteration 1: got: %+v want: %+v", i, m, want)
|
t.Errorf("unexpected result for Outer test %d iteration 1: got: %+v want: %+v", i, m, want)
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1603,7 @@ func TestOuter(t *testing.T) {
|
|||||||
var m Dense
|
var m Dense
|
||||||
for j := 0; j < 2; j++ {
|
for j := 0; j < 2; j++ {
|
||||||
// Check with a new matrix - and then again.
|
// Check with a new matrix - and then again.
|
||||||
m.Outer(f, NewVector(len(test.x), test.x), NewVector(len(test.y), test.y))
|
m.Outer(f, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y))
|
||||||
if !Equal(&m, want) {
|
if !Equal(&m, want) {
|
||||||
t.Errorf("unexpected result for Outer test %d iteration %d scale %v: got: %+v want: %+v", i, j, f, m, want)
|
t.Errorf("unexpected result for Outer test %d iteration %d scale %v: got: %+v want: %+v", i, j, f, m, want)
|
||||||
}
|
}
|
||||||
|
@@ -115,7 +115,7 @@
|
|||||||
// if a and b both implement RawMatrixer, that is, they can be represented as a
|
// if a and b both implement RawMatrixer, that is, they can be represented as a
|
||||||
// blas64.General, blas64.Gemm (general matrix multiplication) is called, while
|
// blas64.General, blas64.Gemm (general matrix multiplication) is called, while
|
||||||
// instead if b is a RawSymmetricer blas64.Symm is used (general-symmetric
|
// instead if b is a RawSymmetricer blas64.Symm is used (general-symmetric
|
||||||
// multiplication), and if b is a *Vector blas64.Gemv is used.
|
// multiplication), and if b is a *VecDense blas64.Gemv is used.
|
||||||
//
|
//
|
||||||
// There are many possible type combinations and special cases. No specific guarantees
|
// There are many possible type combinations and special cases. No specific guarantees
|
||||||
// are made about the performance of any method, and in particular, note that an
|
// are made about the performance of any method, and in particular, note that an
|
||||||
|
@@ -141,7 +141,7 @@ func (e *Eigen) succFact() bool {
|
|||||||
// Factorize returns whether the decomposition succeeded. If the decomposition
|
// Factorize returns whether the decomposition succeeded. If the decomposition
|
||||||
// failed, methods that require a successful factorization will panic.
|
// failed, methods that require a successful factorization will panic.
|
||||||
func (e *Eigen) Factorize(a Matrix, left, right bool) (ok bool) {
|
func (e *Eigen) Factorize(a Matrix, left, right bool) (ok bool) {
|
||||||
// TODO(btracey): Change implementation to store Vectors as a *CMat when
|
// TODO(btracey): Change implementation to store VecDenses as a *CMat when
|
||||||
// #308 is resolved.
|
// #308 is resolved.
|
||||||
|
|
||||||
// Copy a because it is modified during the Lapack call.
|
// Copy a because it is modified during the Lapack call.
|
||||||
|
@@ -148,11 +148,11 @@ func TestSymEigen(t *testing.T) {
|
|||||||
|
|
||||||
// Check that the eigenvalues are actually eigenvalues.
|
// Check that the eigenvalues are actually eigenvalues.
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
v := NewVector(n, Col(nil, i, es.vectors))
|
v := NewVecDense(n, Col(nil, i, es.vectors))
|
||||||
var m Vector
|
var m VecDense
|
||||||
m.MulVec(s, v)
|
m.MulVec(s, v)
|
||||||
|
|
||||||
var scal Vector
|
var scal VecDense
|
||||||
scal.ScaleVec(es.values[i], v)
|
scal.ScaleVec(es.values[i], v)
|
||||||
|
|
||||||
if !EqualApprox(&m, &scal, 1e-8) {
|
if !EqualApprox(&m, &scal, 1e-8) {
|
||||||
|
@@ -71,7 +71,7 @@ func ExampleExcerpt() {
|
|||||||
mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3)))
|
mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3)))
|
||||||
|
|
||||||
// The long vector is also too large, ...
|
// The long vector is also too large, ...
|
||||||
long := mat.NewVector(100, nil)
|
long := mat.NewVecDense(100, nil)
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
long.SetVec(i, float64(i))
|
long.SetVec(i, float64(i))
|
||||||
}
|
}
|
||||||
|
@@ -40,14 +40,14 @@ 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 *Vector) At(i, j int) float64 {
|
func (v *VecDense) At(i, j int) float64 {
|
||||||
if j != 0 {
|
if j != 0 {
|
||||||
panic(ErrColAccess)
|
panic(ErrColAccess)
|
||||||
}
|
}
|
||||||
return v.at(i)
|
return v.at(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) at(i int) float64 {
|
func (v *VecDense) at(i int) float64 {
|
||||||
if uint(i) >= uint(v.n) {
|
if uint(i) >= uint(v.n) {
|
||||||
panic(ErrRowAccess)
|
panic(ErrRowAccess)
|
||||||
}
|
}
|
||||||
@@ -56,11 +56,11 @@ func (v *Vector) 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 *Vector) SetVec(i int, val float64) {
|
func (v *VecDense) SetVec(i int, val float64) {
|
||||||
v.setVec(i, val)
|
v.setVec(i, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) setVec(i int, val float64) {
|
func (v *VecDense) setVec(i int, val float64) {
|
||||||
if uint(i) >= uint(v.n) {
|
if uint(i) >= uint(v.n) {
|
||||||
panic(ErrVectorAccess)
|
panic(ErrVectorAccess)
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,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 *Vector) At(i, j int) float64 {
|
func (v *VecDense) At(i, j int) float64 {
|
||||||
if uint(i) >= uint(v.n) {
|
if uint(i) >= uint(v.n) {
|
||||||
panic(ErrRowAccess)
|
panic(ErrRowAccess)
|
||||||
}
|
}
|
||||||
@@ -50,20 +50,20 @@ func (v *Vector) At(i, j int) float64 {
|
|||||||
return v.at(i)
|
return v.at(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) at(i int) float64 {
|
func (v *VecDense) at(i int) float64 {
|
||||||
return v.mat.Data[i*v.mat.Inc]
|
return v.mat.Data[i*v.mat.Inc]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Vector) SetVec(i int, val float64) {
|
func (v *VecDense) SetVec(i int, val float64) {
|
||||||
if uint(i) >= uint(v.n) {
|
if uint(i) >= uint(v.n) {
|
||||||
panic(ErrVectorAccess)
|
panic(ErrVectorAccess)
|
||||||
}
|
}
|
||||||
v.setVec(i, val)
|
v.setVec(i, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) setVec(i int, val float64) {
|
func (v *VecDense) setVec(i int, val float64) {
|
||||||
v.mat.Data[i*v.mat.Inc] = val
|
v.mat.Data[i*v.mat.Inc] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ import (
|
|||||||
// A is symmetric positive definite, though the operation works for any matrix A.
|
// A is symmetric positive definite, though the operation works for any matrix A.
|
||||||
//
|
//
|
||||||
// Inner panics if x.Len != m or y.Len != n when A is an m x n matrix.
|
// Inner panics if x.Len != m or y.Len != n when A is an m x n matrix.
|
||||||
func Inner(x *Vector, A Matrix, y *Vector) float64 {
|
func Inner(x *VecDense, A Matrix, y *VecDense) float64 {
|
||||||
m, n := A.Dims()
|
m, n := A.Dims()
|
||||||
if x.Len() != m {
|
if x.Len() != m {
|
||||||
panic(ErrShape)
|
panic(ErrShape)
|
||||||
|
@@ -83,7 +83,7 @@ func TestInner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
want := cell.At(0, 0)
|
want := cell.At(0, 0)
|
||||||
got := Inner(makeVectorInc(inc.x, test.x), m, makeVectorInc(inc.y, test.y))
|
got := Inner(makeVecDenseInc(inc.x, test.x), m, makeVecDenseInc(inc.y, test.y))
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("Test %v: want %v, got %v", i, want, got)
|
t.Errorf("Test %v: want %v, got %v", i, want, got)
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ func TestInnerSym(t *testing.T) {
|
|||||||
data[j*n+i] = data[i*n+j]
|
data[j*n+i] = data[i*n+j]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x := makeVectorInc(inc.x, xData)
|
x := makeVecDenseInc(inc.x, xData)
|
||||||
y := makeVectorInc(inc.y, yData)
|
y := makeVecDenseInc(inc.y, yData)
|
||||||
m := NewDense(n, n, data)
|
m := NewDense(n, n, data)
|
||||||
ans := Inner(x, m, y)
|
ans := Inner(x, m, y)
|
||||||
sym := NewSymDense(n, data)
|
sym := NewSymDense(n, data)
|
||||||
@@ -128,8 +128,8 @@ func TestInnerSym(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeVectorInc(inc int, f []float64) *Vector {
|
func makeVecDenseInc(inc int, f []float64) *VecDense {
|
||||||
v := &Vector{
|
v := &VecDense{
|
||||||
n: len(f),
|
n: len(f),
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: inc,
|
Inc: inc,
|
||||||
@@ -151,9 +151,9 @@ func makeVectorInc(inc int, f []float64) *Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func benchmarkInner(b *testing.B, m, n int) {
|
func benchmarkInner(b *testing.B, m, n int) {
|
||||||
x := NewVector(m, nil)
|
x := NewVecDense(m, nil)
|
||||||
randomSlice(x.mat.Data)
|
randomSlice(x.mat.Data)
|
||||||
y := NewVector(n, nil)
|
y := NewVecDense(n, nil)
|
||||||
randomSlice(y.mat.Data)
|
randomSlice(y.mat.Data)
|
||||||
data := make([]float64, m*n)
|
data := make([]float64, m*n)
|
||||||
randomSlice(data)
|
randomSlice(data)
|
||||||
|
16
mat/io.go
16
mat/io.go
@@ -203,10 +203,10 @@ func (m *Dense) UnmarshalBinaryFrom(r io.Reader) (int, error) {
|
|||||||
|
|
||||||
// MarshalBinary encodes the receiver into a binary form and returns the result.
|
// MarshalBinary encodes the receiver into a binary form and returns the result.
|
||||||
//
|
//
|
||||||
// Vector is little-endian encoded as follows:
|
// VecDense is little-endian encoded as follows:
|
||||||
// 0 - 7 number of elements (int64)
|
// 0 - 7 number of elements (int64)
|
||||||
// 8 - .. vector's data elements (float64)
|
// 8 - .. vector's data elements (float64)
|
||||||
func (v Vector) MarshalBinary() ([]byte, error) {
|
func (v VecDense) MarshalBinary() ([]byte, error) {
|
||||||
bufLen := int64(sizeInt64) + int64(v.n)*int64(sizeFloat64)
|
bufLen := int64(sizeInt64) + int64(v.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.
|
||||||
@@ -230,7 +230,7 @@ func (v Vector) MarshalBinary() ([]byte, error) {
|
|||||||
// returns the number of bytes written and an error if any.
|
// returns the number of bytes written and an error if any.
|
||||||
//
|
//
|
||||||
// See MarshalBainry for the on-disk format.
|
// See MarshalBainry for the on-disk format.
|
||||||
func (v Vector) MarshalBinaryTo(w io.Writer) (int, error) {
|
func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) {
|
||||||
var (
|
var (
|
||||||
n int
|
n int
|
||||||
buf [8]byte
|
buf [8]byte
|
||||||
@@ -256,18 +256,18 @@ func (v Vector) MarshalBinaryTo(w io.Writer) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalBinary decodes the binary form into the receiver.
|
// UnmarshalBinary decodes the binary form into the receiver.
|
||||||
// It panics if the receiver is a non-zero Vector.
|
// It panics if the receiver is a non-zero VecDense.
|
||||||
//
|
//
|
||||||
// See MarshalBinary for the on-disk layout.
|
// See MarshalBinary for the on-disk layout.
|
||||||
//
|
//
|
||||||
// Limited checks on the validity of the binary input are performed:
|
// Limited checks on the validity of the binary input are performed:
|
||||||
// - matrix.ErrShape is returned if the number of rows is negative,
|
// - matrix.ErrShape is returned if the number of rows is negative,
|
||||||
// - an error is returned if the resulting Vector is too
|
// - an error is returned if the resulting VecDense is too
|
||||||
// big for the current architecture (e.g. a 16GB vector written by a
|
// big for the current architecture (e.g. a 16GB vector written by a
|
||||||
// 64b application and read back from a 32b application.)
|
// 64b application and read back from a 32b application.)
|
||||||
// UnmarshalBinary does not limit the size of the unmarshaled vector, and so
|
// UnmarshalBinary does not limit the size of the unmarshaled vector, and so
|
||||||
// it should not be used on untrusted data.
|
// it should not be used on untrusted data.
|
||||||
func (v *Vector) UnmarshalBinary(data []byte) error {
|
func (v *VecDense) UnmarshalBinary(data []byte) error {
|
||||||
if !v.IsZero() {
|
if !v.IsZero() {
|
||||||
panic("mat: unmarshal into non-zero vector")
|
panic("mat: unmarshal into non-zero vector")
|
||||||
}
|
}
|
||||||
@@ -296,11 +296,11 @@ func (v *Vector) UnmarshalBinary(data []byte) error {
|
|||||||
|
|
||||||
// UnmarshalBinaryFrom decodes the binary form into the receiver, from the
|
// UnmarshalBinaryFrom decodes the binary form into the receiver, from the
|
||||||
// io.Reader and returns the number of bytes read and an error if any.
|
// io.Reader and returns the number of bytes read and an error if any.
|
||||||
// It panics if the receiver is a non-zero Vector.
|
// It panics if the receiver is a non-zero VecDense.
|
||||||
//
|
//
|
||||||
// See MarshalBinary for the on-disk layout.
|
// See MarshalBinary for the on-disk layout.
|
||||||
// See UnmarshalBinary for the list of sanity checks performed on the input.
|
// See UnmarshalBinary for the list of sanity checks performed on the input.
|
||||||
func (v *Vector) UnmarshalBinaryFrom(r io.Reader) (int, error) {
|
func (v *VecDense) UnmarshalBinaryFrom(r io.Reader) (int, error) {
|
||||||
if !v.IsZero() {
|
if !v.IsZero() {
|
||||||
panic("mat: unmarshal into non-zero vector")
|
panic("mat: unmarshal into non-zero vector")
|
||||||
}
|
}
|
||||||
|
@@ -18,8 +18,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
_ encoding.BinaryMarshaler = (*Dense)(nil)
|
_ encoding.BinaryMarshaler = (*Dense)(nil)
|
||||||
_ encoding.BinaryUnmarshaler = (*Dense)(nil)
|
_ encoding.BinaryUnmarshaler = (*Dense)(nil)
|
||||||
_ encoding.BinaryMarshaler = (*Vector)(nil)
|
_ encoding.BinaryMarshaler = (*VecDense)(nil)
|
||||||
_ encoding.BinaryUnmarshaler = (*Vector)(nil)
|
_ encoding.BinaryUnmarshaler = (*VecDense)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
var denseData = []struct {
|
var denseData = []struct {
|
||||||
@@ -290,47 +290,47 @@ func TestDenseIORoundTrip(t *testing.T) {
|
|||||||
|
|
||||||
var vectorData = []struct {
|
var vectorData = []struct {
|
||||||
raw []byte
|
raw []byte
|
||||||
want *Vector
|
want *VecDense
|
||||||
eq func(got, want Matrix) bool
|
eq func(got, want Matrix) bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
|
raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||||
want: NewVector(0, []float64{}),
|
want: NewVecDense(0, []float64{}),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"),
|
raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"),
|
||||||
want: NewVector(4, []float64{1, 2, 3, 4}),
|
want: NewVecDense(4, []float64{1, 2, 3, 4}),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"),
|
raw: []byte("\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"),
|
||||||
want: NewVector(6, []float64{1, 2, 3, 4, 5, 6}),
|
want: NewVecDense(6, []float64{1, 2, 3, 4, 5, 6}),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
|
raw: []byte("\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
|
||||||
want: NewVector(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}),
|
want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@"),
|
raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@"),
|
||||||
want: NewVector(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 3),
|
want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 3),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x03\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\x10@"),
|
raw: []byte("\x03\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\x10@"),
|
||||||
want: NewVector(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(1, 4),
|
want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(1, 4),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @"),
|
raw: []byte("\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @"),
|
||||||
want: NewVector(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 8),
|
want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 8),
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x03\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("\x03\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: &Vector{
|
want: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: []float64{0, 1, 2, 3, 4, 5, 6},
|
Data: []float64{0, 1, 2, 3, 4, 5, 6},
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -341,7 +341,7 @@ var vectorData = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"),
|
raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"),
|
||||||
want: NewVector(4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}),
|
want: NewVecDense(4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}),
|
||||||
eq: func(got, want Matrix) bool {
|
eq: func(got, want Matrix) bool {
|
||||||
for _, v := range []bool{
|
for _, v := range []bool{
|
||||||
got.At(0, 0) == 0,
|
got.At(0, 0) == 0,
|
||||||
@@ -358,7 +358,7 @@ var vectorData = []struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorMarshal(t *testing.T) {
|
func TestVecDenseMarshal(t *testing.T) {
|
||||||
for i, test := range vectorData {
|
for i, test := range vectorData {
|
||||||
buf, err := test.want.MarshalBinary()
|
buf, err := test.want.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -383,7 +383,7 @@ func TestVectorMarshal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorMarshalTo(t *testing.T) {
|
func TestVecDenseMarshalTo(t *testing.T) {
|
||||||
for i, test := range vectorData {
|
for i, test := range vectorData {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
n, err := test.want.MarshalBinaryTo(buf)
|
n, err := test.want.MarshalBinaryTo(buf)
|
||||||
@@ -409,9 +409,9 @@ func TestVectorMarshalTo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorUnmarshal(t *testing.T) {
|
func TestVecDenseUnmarshal(t *testing.T) {
|
||||||
for i, test := range vectorData {
|
for i, test := range vectorData {
|
||||||
var v Vector
|
var v VecDense
|
||||||
err := v.UnmarshalBinary(test.raw)
|
err := v.UnmarshalBinary(test.raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error decoding test-%d: %v\n", i, err)
|
t.Errorf("error decoding test-%d: %v\n", i, err)
|
||||||
@@ -427,9 +427,9 @@ func TestVectorUnmarshal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorUnmarshalFrom(t *testing.T) {
|
func TestVecDenseUnmarshalFrom(t *testing.T) {
|
||||||
for i, test := range vectorData {
|
for i, test := range vectorData {
|
||||||
var v Vector
|
var v VecDense
|
||||||
buf := bytes.NewReader(test.raw)
|
buf := bytes.NewReader(test.raw)
|
||||||
n, err := v.UnmarshalBinaryFrom(buf)
|
n, err := v.UnmarshalBinaryFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -453,7 +453,7 @@ func TestVectorUnmarshalFrom(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorUnmarshalFromError(t *testing.T) {
|
func TestVecDenseUnmarshalFromError(t *testing.T) {
|
||||||
test := vectorData[1]
|
test := vectorData[1]
|
||||||
for i, tt := range []struct {
|
for i, tt := range []struct {
|
||||||
beg int
|
beg int
|
||||||
@@ -501,7 +501,7 @@ func TestVectorUnmarshalFromError(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
buf := bytes.NewReader(test.raw[tt.beg:tt.end])
|
buf := bytes.NewReader(test.raw[tt.beg:tt.end])
|
||||||
var v Vector
|
var v VecDense
|
||||||
_, err := v.UnmarshalBinaryFrom(buf)
|
_, err := v.UnmarshalBinaryFrom(buf)
|
||||||
if err != io.ErrUnexpectedEOF {
|
if err != io.ErrUnexpectedEOF {
|
||||||
t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF)
|
t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF)
|
||||||
@@ -509,14 +509,14 @@ func TestVectorUnmarshalFromError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorIORoundTrip(t *testing.T) {
|
func TestVecDenseIORoundTrip(t *testing.T) {
|
||||||
for i, test := range vectorData {
|
for i, test := range vectorData {
|
||||||
buf, err := test.want.MarshalBinary()
|
buf, err := test.want.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error encoding test #%d: %v\n", i, err)
|
t.Errorf("error encoding test #%d: %v\n", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var got Vector
|
var got VecDense
|
||||||
err = got.UnmarshalBinary(buf)
|
err = got.UnmarshalBinary(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error decoding test #%d: %v\n", i, err)
|
t.Errorf("error decoding test #%d: %v\n", i, err)
|
||||||
@@ -537,7 +537,7 @@ func TestVectorIORoundTrip(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var wgot Vector
|
var wgot VecDense
|
||||||
_, err = wgot.UnmarshalBinaryFrom(wbuf)
|
_, err = wgot.UnmarshalBinaryFrom(wbuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error decoding test #%d: %v\n", i, err)
|
t.Errorf("error decoding test #%d: %v\n", i, err)
|
||||||
@@ -647,17 +647,17 @@ func unmarshalBinaryFromBenchDense(b *testing.B, size int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkMarshalVector10(b *testing.B) { marshalBinaryBenchVector(b, 10) }
|
func BenchmarkMarshalVecDense10(b *testing.B) { marshalBinaryBenchVecDense(b, 10) }
|
||||||
func BenchmarkMarshalVector100(b *testing.B) { marshalBinaryBenchVector(b, 100) }
|
func BenchmarkMarshalVecDense100(b *testing.B) { marshalBinaryBenchVecDense(b, 100) }
|
||||||
func BenchmarkMarshalVector1000(b *testing.B) { marshalBinaryBenchVector(b, 1000) }
|
func BenchmarkMarshalVecDense1000(b *testing.B) { marshalBinaryBenchVecDense(b, 1000) }
|
||||||
func BenchmarkMarshalVector10000(b *testing.B) { marshalBinaryBenchVector(b, 10000) }
|
func BenchmarkMarshalVecDense10000(b *testing.B) { marshalBinaryBenchVecDense(b, 10000) }
|
||||||
|
|
||||||
func marshalBinaryBenchVector(b *testing.B, size int) {
|
func marshalBinaryBenchVecDense(b *testing.B, size int) {
|
||||||
data := make([]float64, size)
|
data := make([]float64, size)
|
||||||
for i := range data {
|
for i := range data {
|
||||||
data[i] = float64(i)
|
data[i] = float64(i)
|
||||||
}
|
}
|
||||||
vec := NewVector(size, data)
|
vec := NewVecDense(size, data)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
@@ -665,39 +665,39 @@ func marshalBinaryBenchVector(b *testing.B, size int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkUnmarshalVector10(b *testing.B) { unmarshalBinaryBenchVector(b, 10) }
|
func BenchmarkUnmarshalVecDense10(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10) }
|
||||||
func BenchmarkUnmarshalVector100(b *testing.B) { unmarshalBinaryBenchVector(b, 100) }
|
func BenchmarkUnmarshalVecDense100(b *testing.B) { unmarshalBinaryBenchVecDense(b, 100) }
|
||||||
func BenchmarkUnmarshalVector1000(b *testing.B) { unmarshalBinaryBenchVector(b, 1000) }
|
func BenchmarkUnmarshalVecDense1000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 1000) }
|
||||||
func BenchmarkUnmarshalVector10000(b *testing.B) { unmarshalBinaryBenchVector(b, 10000) }
|
func BenchmarkUnmarshalVecDense10000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10000) }
|
||||||
|
|
||||||
func unmarshalBinaryBenchVector(b *testing.B, size int) {
|
func unmarshalBinaryBenchVecDense(b *testing.B, size int) {
|
||||||
data := make([]float64, size)
|
data := make([]float64, size)
|
||||||
for i := range data {
|
for i := range data {
|
||||||
data[i] = float64(i)
|
data[i] = float64(i)
|
||||||
}
|
}
|
||||||
buf, err := NewVector(size, data).MarshalBinary()
|
buf, err := NewVecDense(size, data).MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
|
b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
|
||||||
}
|
}
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
var vec Vector
|
var vec VecDense
|
||||||
vec.UnmarshalBinary(buf)
|
vec.UnmarshalBinary(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkMarshalToVector10(b *testing.B) { marshalBinaryToBenchVector(b, 10) }
|
func BenchmarkMarshalToVecDense10(b *testing.B) { marshalBinaryToBenchVecDense(b, 10) }
|
||||||
func BenchmarkMarshalToVector100(b *testing.B) { marshalBinaryToBenchVector(b, 100) }
|
func BenchmarkMarshalToVecDense100(b *testing.B) { marshalBinaryToBenchVecDense(b, 100) }
|
||||||
func BenchmarkMarshalToVector1000(b *testing.B) { marshalBinaryToBenchVector(b, 1000) }
|
func BenchmarkMarshalToVecDense1000(b *testing.B) { marshalBinaryToBenchVecDense(b, 1000) }
|
||||||
func BenchmarkMarshalToVector10000(b *testing.B) { marshalBinaryToBenchVector(b, 10000) }
|
func BenchmarkMarshalToVecDense10000(b *testing.B) { marshalBinaryToBenchVecDense(b, 10000) }
|
||||||
|
|
||||||
func marshalBinaryToBenchVector(b *testing.B, size int) {
|
func marshalBinaryToBenchVecDense(b *testing.B, size int) {
|
||||||
data := make([]float64, size)
|
data := make([]float64, size)
|
||||||
for i := range data {
|
for i := range data {
|
||||||
data[i] = float64(i)
|
data[i] = float64(i)
|
||||||
}
|
}
|
||||||
vec := NewVector(size, data)
|
vec := NewVecDense(size, data)
|
||||||
w := ioutil.Discard
|
w := ioutil.Discard
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
@@ -706,17 +706,17 @@ func marshalBinaryToBenchVector(b *testing.B, size int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkUnmarshalFromVector10(b *testing.B) { unmarshalBinaryFromBenchVector(b, 10) }
|
func BenchmarkUnmarshalFromVecDense10(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10) }
|
||||||
func BenchmarkUnmarshalFromVector100(b *testing.B) { unmarshalBinaryFromBenchVector(b, 100) }
|
func BenchmarkUnmarshalFromVecDense100(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 100) }
|
||||||
func BenchmarkUnmarshalFromVector1000(b *testing.B) { unmarshalBinaryFromBenchVector(b, 1000) }
|
func BenchmarkUnmarshalFromVecDense1000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 1000) }
|
||||||
func BenchmarkUnmarshalFromVector10000(b *testing.B) { unmarshalBinaryFromBenchVector(b, 10000) }
|
func BenchmarkUnmarshalFromVecDense10000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10000) }
|
||||||
|
|
||||||
func unmarshalBinaryFromBenchVector(b *testing.B, size int) {
|
func unmarshalBinaryFromBenchVecDense(b *testing.B, size int) {
|
||||||
data := make([]float64, size)
|
data := make([]float64, size)
|
||||||
for i := range data {
|
for i := range data {
|
||||||
data[i] = float64(i)
|
data[i] = float64(i)
|
||||||
}
|
}
|
||||||
buf, err := NewVector(size, data).MarshalBinary()
|
buf, err := NewVecDense(size, data).MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
|
b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
|
||||||
}
|
}
|
||||||
@@ -724,7 +724,7 @@ func unmarshalBinaryFromBenchVector(b *testing.B, size int) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
var vec Vector
|
var vec VecDense
|
||||||
vec.UnmarshalBinaryFrom(r)
|
vec.UnmarshalBinaryFrom(r)
|
||||||
r.reset()
|
r.reset()
|
||||||
}
|
}
|
||||||
|
@@ -72,8 +72,8 @@ func isAnySize2(ar, ac, br, bc int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// isAnyVector returns true for any column vector sizes.
|
// isAnyVecDense returns true for any column vector sizes.
|
||||||
func isAnyVector(ar, ac int) bool {
|
func isAnyVecDense(ar, ac int) bool {
|
||||||
return ac == 1
|
return ac == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,27 +142,27 @@ func legalTypesSym(a, b Matrix) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// legalTypeVec returns whether v is a *Vector.
|
// legalTypeVec returns whether v is a *VecDense.
|
||||||
func legalTypeVec(v Matrix) bool {
|
func legalTypeVec(v Matrix) bool {
|
||||||
_, ok := v.(*Vector)
|
_, ok := v.(*VecDense)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// legalTypesVecVec returns whether both inputs are *Vector.
|
// legalTypesVecVec returns whether both inputs are *VecDense.
|
||||||
func legalTypesVecVec(a, b Matrix) bool {
|
func legalTypesVecVec(a, b Matrix) bool {
|
||||||
if _, ok := a.(*Vector); !ok {
|
if _, ok := a.(*VecDense); !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if _, ok := b.(*Vector); !ok {
|
if _, ok := b.(*VecDense); !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// legalTypesNotVecVec returns whether the first input is an arbitrary Matrix
|
// legalTypesNotVecVec returns whether the first input is an arbitrary Matrix
|
||||||
// and the second input is a *Vector.
|
// and the second input is a *VecDense.
|
||||||
func legalTypesNotVecVec(a, b Matrix) bool {
|
func legalTypesNotVecVec(a, b Matrix) bool {
|
||||||
_, ok := b.(*Vector)
|
_, ok := b.(*VecDense)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ func legalDims(a Matrix, m, n int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
if m < 0 || n < 0 {
|
if m < 0 || n < 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -258,9 +258,9 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rMatrix = returnAs(mat, t)
|
rMatrix = returnAs(mat, t)
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
if m == 0 && n == 0 {
|
if m == 0 && n == 0 {
|
||||||
return &Vector{}
|
return &VecDense{}
|
||||||
}
|
}
|
||||||
if n != 1 {
|
if n != 1 {
|
||||||
panic(fmt.Sprintf("bad vector size: m = %v, n = %v", m, n))
|
panic(fmt.Sprintf("bad vector size: m = %v, n = %v", m, n))
|
||||||
@@ -270,7 +270,7 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
|||||||
if t.mat.Inc != 0 {
|
if t.mat.Inc != 0 {
|
||||||
inc = t.mat.Inc
|
inc = t.mat.Inc
|
||||||
}
|
}
|
||||||
mat := &Vector{
|
mat := &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: inc,
|
Inc: inc,
|
||||||
Data: make([]float64, inc*(length-1)+1),
|
Data: make([]float64, inc*(length-1)+1),
|
||||||
@@ -363,8 +363,8 @@ func makeCopyOf(a Matrix) Matrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnAs(m, t)
|
return returnAs(m, t)
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
m := &Vector{
|
m := &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
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.n-1)+1),
|
||||||
@@ -492,7 +492,7 @@ func underlyingData(a Matrix) []float64 {
|
|||||||
return t.mat.Data
|
return t.mat.Data
|
||||||
case *TriDense:
|
case *TriDense:
|
||||||
return t.mat.Data
|
return t.mat.Data
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
return t.mat.Data
|
return t.mat.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,8 +505,8 @@ var testMatrices = []Matrix{
|
|||||||
&SymDense{},
|
&SymDense{},
|
||||||
NewTriDense(3, true, nil),
|
NewTriDense(3, true, nil),
|
||||||
NewTriDense(3, false, nil),
|
NewTriDense(3, false, nil),
|
||||||
NewVector(0, nil),
|
NewVecDense(0, nil),
|
||||||
&Vector{mat: blas64.Vector{Inc: 10}},
|
&VecDense{mat: blas64.Vector{Inc: 10}},
|
||||||
&basicMatrix{},
|
&basicMatrix{},
|
||||||
&basicSymmetric{},
|
&basicSymmetric{},
|
||||||
&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}},
|
&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}},
|
||||||
@@ -517,8 +517,8 @@ var testMatrices = []Matrix{
|
|||||||
TransposeTri{NewTriDense(3, true, nil)},
|
TransposeTri{NewTriDense(3, true, nil)},
|
||||||
Transpose{NewTriDense(3, false, nil)},
|
Transpose{NewTriDense(3, false, nil)},
|
||||||
TransposeTri{NewTriDense(3, false, nil)},
|
TransposeTri{NewTriDense(3, false, nil)},
|
||||||
Transpose{NewVector(0, nil)},
|
Transpose{NewVecDense(0, nil)},
|
||||||
Transpose{&Vector{mat: blas64.Vector{Inc: 10}}},
|
Transpose{&VecDense{mat: blas64.Vector{Inc: 10}}},
|
||||||
Transpose{&basicMatrix{}},
|
Transpose{&basicMatrix{}},
|
||||||
Transpose{&basicSymmetric{}},
|
Transpose{&basicSymmetric{}},
|
||||||
Transpose{&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}}},
|
Transpose{&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}}},
|
||||||
@@ -893,7 +893,7 @@ func testOneInput(t *testing.T,
|
|||||||
if !panicked {
|
if !panicked {
|
||||||
t.Errorf("Did not panic with wrong size: %s", errStr)
|
t.Errorf("Did not panic with wrong size: %s", errStr)
|
||||||
}
|
}
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
// Add to the column length.
|
// Add to the column length.
|
||||||
wrongSize := makeRandOf(receiver, rr+1, rc)
|
wrongSize := makeRandOf(receiver, rr+1, rc)
|
||||||
panicked, _ = panics(func() { method(wrongSize, a) })
|
panicked, _ = panics(func() { method(wrongSize, a) })
|
||||||
@@ -1054,7 +1054,7 @@ func testTwoInput(t *testing.T,
|
|||||||
if !panicked {
|
if !panicked {
|
||||||
t.Errorf("Did not panic with wrong size: %s", errStr)
|
t.Errorf("Did not panic with wrong size: %s", errStr)
|
||||||
}
|
}
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
// Add to the column length.
|
// Add to the column length.
|
||||||
wrongSize := makeRandOf(receiver, rr+1, rc)
|
wrongSize := makeRandOf(receiver, rr+1, rc)
|
||||||
panicked, _ = panics(func() { method(wrongSize, a, b) })
|
panicked, _ = panics(func() { method(wrongSize, a, b) })
|
||||||
|
@@ -190,13 +190,13 @@ func (lq *LQ) Solve(m *Dense, trans bool, b Matrix) error {
|
|||||||
|
|
||||||
// SolveVec finds a minimum-norm solution to a system of linear equations.
|
// SolveVec finds a minimum-norm solution to a system of linear equations.
|
||||||
// Please see LQ.Solve for the full documentation.
|
// Please see LQ.Solve for the full documentation.
|
||||||
func (lq *LQ) SolveVec(v *Vector, trans bool, b *Vector) error {
|
func (lq *LQ) SolveVec(v *VecDense, trans bool, b *VecDense) error {
|
||||||
if v != b {
|
if v != b {
|
||||||
v.checkOverlap(b.mat)
|
v.checkOverlap(b.mat)
|
||||||
}
|
}
|
||||||
r, c := lq.lq.Dims()
|
r, c := lq.lq.Dims()
|
||||||
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
||||||
// instead recast the Vectors as Dense and call the matrix code.
|
// instead recast the VecDenses as Dense and call the matrix code.
|
||||||
if trans {
|
if trans {
|
||||||
v.reuseAs(r)
|
v.reuseAs(r)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -123,11 +123,11 @@ func TestSolveLQVec(t *testing.T) {
|
|||||||
if trans {
|
if trans {
|
||||||
br = n
|
br = n
|
||||||
}
|
}
|
||||||
b := NewVector(br, nil)
|
b := NewVecDense(br, nil)
|
||||||
for i := 0; i < br; i++ {
|
for i := 0; i < br; i++ {
|
||||||
b.SetVec(i, rand.Float64())
|
b.SetVec(i, rand.Float64())
|
||||||
}
|
}
|
||||||
var x Vector
|
var x VecDense
|
||||||
lq := &LQ{}
|
lq := &LQ{}
|
||||||
lq.Factorize(a)
|
lq.Factorize(a)
|
||||||
lq.SolveVec(&x, trans, b)
|
lq.SolveVec(&x, trans, b)
|
||||||
@@ -170,8 +170,8 @@ func TestSolveLQCond(t *testing.T) {
|
|||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
|
|
||||||
bvec := NewVector(m, nil)
|
bvec := NewVecDense(m, nil)
|
||||||
var xvec Vector
|
var xvec VecDense
|
||||||
if err := lq.SolveVec(&xvec, false, bvec); err == nil {
|
if err := lq.SolveVec(&xvec, false, bvec); err == nil {
|
||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
|
@@ -145,7 +145,7 @@ func (lu *LU) Pivot(swaps []int) []int {
|
|||||||
// the original matrix A, storing the result into the receiver. That is, if in
|
// the original matrix A, storing the result into the receiver. That is, if in
|
||||||
// the original LU decomposition P * L * U = A, in the updated decomposition
|
// the original LU decomposition P * L * U = A, in the updated decomposition
|
||||||
// P * L * U = A + alpha * x * y^T.
|
// P * L * U = A + alpha * x * y^T.
|
||||||
func (lu *LU) RankOne(orig *LU, alpha float64, x, y *Vector) {
|
func (lu *LU) RankOne(orig *LU, alpha float64, x, y *VecDense) {
|
||||||
// RankOne uses algorithm a1 on page 28 of "Multiple-Rank Updates to Matrix
|
// RankOne uses algorithm a1 on page 28 of "Multiple-Rank Updates to Matrix
|
||||||
// Factorizations for Nonlinear Analysis and Circuit Design" by Linzhong Deng.
|
// Factorizations for Nonlinear Analysis and Circuit Design" by Linzhong Deng.
|
||||||
// http://web.stanford.edu/group/SOL/dissertations/Linzhong-Deng-thesis.pdf
|
// http://web.stanford.edu/group/SOL/dissertations/Linzhong-Deng-thesis.pdf
|
||||||
@@ -317,7 +317,7 @@ func (lu *LU) Solve(m *Dense, trans bool, b Matrix) error {
|
|||||||
//
|
//
|
||||||
// If A is singular or near-singular a Condition error is returned. Please see
|
// If A is singular or near-singular a Condition error is returned. Please see
|
||||||
// the documentation for Condition for more information.
|
// the documentation for Condition for more information.
|
||||||
func (lu *LU) SolveVec(v *Vector, trans bool, b *Vector) error {
|
func (lu *LU) SolveVec(v *VecDense, trans bool, b *VecDense) error {
|
||||||
_, n := lu.lu.Dims()
|
_, n := lu.lu.Dims()
|
||||||
bn := b.Len()
|
bn := b.Len()
|
||||||
if bn != n {
|
if bn != n {
|
||||||
|
@@ -62,8 +62,8 @@ func TestLURankOne(t *testing.T) {
|
|||||||
// Apply a rank one update. Ensure the update magnitude is larger than
|
// Apply a rank one update. Ensure the update magnitude is larger than
|
||||||
// the equal tolerance.
|
// the equal tolerance.
|
||||||
alpha := rand.Float64() + 1
|
alpha := rand.Float64() + 1
|
||||||
x := NewVector(n, nil)
|
x := NewVecDense(n, nil)
|
||||||
y := NewVector(n, nil)
|
y := NewVecDense(n, nil)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
x.setVec(i, rand.Float64()+1)
|
x.setVec(i, rand.Float64()+1)
|
||||||
y.setVec(i, rand.Float64()+1)
|
y.setVec(i, rand.Float64()+1)
|
||||||
@@ -153,8 +153,8 @@ func TestSolveLUCond(t *testing.T) {
|
|||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
|
|
||||||
bvec := NewVector(m, nil)
|
bvec := NewVecDense(m, nil)
|
||||||
var xvec Vector
|
var xvec VecDense
|
||||||
if err := lu.SolveVec(&xvec, false, bvec); err == nil {
|
if err := lu.SolveVec(&xvec, false, bvec); err == nil {
|
||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
@@ -169,17 +169,17 @@ func TestSolveLUVec(t *testing.T) {
|
|||||||
a.Set(i, j, rand.NormFloat64())
|
a.Set(i, j, rand.NormFloat64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b := NewVector(n, nil)
|
b := NewVecDense(n, nil)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
b.SetVec(i, rand.NormFloat64())
|
b.SetVec(i, rand.NormFloat64())
|
||||||
}
|
}
|
||||||
var lu LU
|
var lu LU
|
||||||
lu.Factorize(a)
|
lu.Factorize(a)
|
||||||
var x Vector
|
var x VecDense
|
||||||
if err := lu.SolveVec(&x, false, b); err != nil {
|
if err := lu.SolveVec(&x, false, b); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var got Vector
|
var got VecDense
|
||||||
got.MulVec(a, &x)
|
got.MulVec(a, &x)
|
||||||
if !EqualApprox(&got, b, 1e-12) {
|
if !EqualApprox(&got, b, 1e-12) {
|
||||||
t.Errorf("Solve mismatch n = %v.\nWant: %v\nGot: %v", n, b, got)
|
t.Errorf("Solve mismatch n = %v.\nWant: %v\nGot: %v", n, b, got)
|
||||||
|
@@ -98,10 +98,10 @@ type Mutable interface {
|
|||||||
Matrix
|
Matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RowViewer can return a Vector reflecting a row that is backed by the matrix
|
// A RowViewer can return a VecDense reflecting a row that is backed by the matrix
|
||||||
// data. The Vector returned will have length equal to the number of columns.
|
// data. The VecDense returned will have length equal to the number of columns.
|
||||||
type RowViewer interface {
|
type RowViewer interface {
|
||||||
RowView(i int) *Vector
|
RowView(i int) *VecDense
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RawRowViewer can return a slice of float64 reflecting a row that is backed by the matrix
|
// A RawRowViewer can return a slice of float64 reflecting a row that is backed by the matrix
|
||||||
@@ -110,10 +110,10 @@ type RawRowViewer interface {
|
|||||||
RawRowView(i int) []float64
|
RawRowView(i int) []float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// A ColViewer can return a Vector reflecting a column that is backed by the matrix
|
// A ColViewer can return a VecDense reflecting a column that is backed by the matrix
|
||||||
// data. The Vector returned will have length equal to the number of rows.
|
// data. The VecDense returned will have length equal to the number of rows.
|
||||||
type ColViewer interface {
|
type ColViewer interface {
|
||||||
ColView(j int) *Vector
|
ColView(j int) *VecDense
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RawColViewer can return a slice of float64 reflecting a column that is backed by the matrix
|
// A RawColViewer can return a slice of float64 reflecting a column that is backed by the matrix
|
||||||
@@ -370,7 +370,7 @@ func Det(a Matrix) float64 {
|
|||||||
|
|
||||||
// Dot returns the sum of the element-wise product of a and b.
|
// Dot returns the sum of the element-wise product of a and b.
|
||||||
// Dot panics if the matrix sizes are unequal.
|
// Dot panics if the matrix sizes are unequal.
|
||||||
func Dot(a, b *Vector) float64 {
|
func Dot(a, b *VecDense) float64 {
|
||||||
la := a.Len()
|
la := a.Len()
|
||||||
lb := b.Len()
|
lb := b.Len()
|
||||||
if la != lb {
|
if la != lb {
|
||||||
@@ -428,8 +428,8 @@ func Equal(a, b Matrix) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ra, ok := aU.(*Vector); ok {
|
if ra, ok := aU.(*VecDense); ok {
|
||||||
if rb, ok := bU.(*Vector); 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.n; i++ {
|
||||||
@@ -500,8 +500,8 @@ func EqualApprox(a, b Matrix, epsilon float64) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ra, ok := aU.(*Vector); ok {
|
if ra, ok := aU.(*VecDense); ok {
|
||||||
if rb, ok := bU.(*Vector); 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.n; i++ {
|
||||||
@@ -723,7 +723,7 @@ func Norm(a Matrix, norm float64) float64 {
|
|||||||
defer putFloats(work)
|
defer putFloats(work)
|
||||||
}
|
}
|
||||||
return lapack64.Lansy(n, rm, work)
|
return lapack64.Lansy(n, rm, work)
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
rv := rma.RawVector()
|
rv := rma.RawVector()
|
||||||
switch norm {
|
switch norm {
|
||||||
default:
|
default:
|
||||||
|
@@ -359,7 +359,7 @@ func TestDet(t *testing.T) {
|
|||||||
|
|
||||||
func TestDot(t *testing.T) {
|
func TestDot(t *testing.T) {
|
||||||
f := func(a, b Matrix) interface{} {
|
f := func(a, b Matrix) interface{} {
|
||||||
return Dot(a.(*Vector), b.(*Vector))
|
return Dot(a.(*VecDense), b.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(a, b *Dense) interface{} {
|
denseComparison := func(a, b *Dense) interface{} {
|
||||||
ra, ca := a.Dims()
|
ra, ca := a.Dims()
|
||||||
@@ -473,7 +473,7 @@ func TestNormZero(t *testing.T) {
|
|||||||
&SymDense{mat: blas64.Symmetric{Uplo: blas.Upper}},
|
&SymDense{mat: blas64.Symmetric{Uplo: blas.Upper}},
|
||||||
&TriDense{},
|
&TriDense{},
|
||||||
&TriDense{mat: blas64.Triangular{Uplo: blas.Upper, Diag: blas.NonUnit}},
|
&TriDense{mat: blas64.Triangular{Uplo: blas.Upper, Diag: blas.NonUnit}},
|
||||||
&Vector{},
|
&VecDense{},
|
||||||
} {
|
} {
|
||||||
for _, norm := range []float64{1, 2, math.Inf(1)} {
|
for _, norm := range []float64{1, 2, math.Inf(1)} {
|
||||||
panicked, message := panics(func() { Norm(a, norm) })
|
panicked, message := panics(func() { Norm(a, norm) })
|
||||||
|
14
mat/pool.go
14
mat/pool.go
@@ -51,7 +51,7 @@ var (
|
|||||||
// poolTri is the TriDense equivalent of pool.
|
// poolTri is the TriDense equivalent of pool.
|
||||||
poolTri [63]sync.Pool
|
poolTri [63]sync.Pool
|
||||||
|
|
||||||
// poolVec is the Vector equivalent of pool.
|
// poolVec is the VecDense equivalent of pool.
|
||||||
poolVec [63]sync.Pool
|
poolVec [63]sync.Pool
|
||||||
|
|
||||||
// poolFloats is the []float64 equivalent of pool.
|
// poolFloats is the []float64 equivalent of pool.
|
||||||
@@ -81,7 +81,7 @@ func init() {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
poolVec[i].New = func() interface{} {
|
poolVec[i].New = func() interface{} {
|
||||||
return &Vector{mat: blas64.Vector{
|
return &VecDense{mat: blas64.Vector{
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
Data: make([]float64, l),
|
Data: make([]float64, l),
|
||||||
}}
|
}}
|
||||||
@@ -176,12 +176,12 @@ func putWorkspaceTri(t *TriDense) {
|
|||||||
poolTri[bits(uint64(cap(t.mat.Data)))].Put(t)
|
poolTri[bits(uint64(cap(t.mat.Data)))].Put(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getWorkspaceVec returns a *Vector of length n and a cap that
|
// getWorkspaceVec returns a *VecDense of length n and a cap that
|
||||||
// is less than 2*n. If clear is true, the data slice visible
|
// is less than 2*n. If clear is true, the data slice visible
|
||||||
// through the Matrix interface is zeroed.
|
// through the Matrix interface is zeroed.
|
||||||
func getWorkspaceVec(n int, clear bool) *Vector {
|
func getWorkspaceVec(n int, clear bool) *VecDense {
|
||||||
l := uint64(n)
|
l := uint64(n)
|
||||||
v := poolVec[bits(l)].Get().(*Vector)
|
v := poolVec[bits(l)].Get().(*VecDense)
|
||||||
v.mat.Data = v.mat.Data[:l]
|
v.mat.Data = v.mat.Data[:l]
|
||||||
if clear {
|
if clear {
|
||||||
zero(v.mat.Data)
|
zero(v.mat.Data)
|
||||||
@@ -190,10 +190,10 @@ func getWorkspaceVec(n int, clear bool) *Vector {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// putWorkspaceVec replaces a used *Vector into the appropriate size
|
// putWorkspaceVec replaces a used *VecDense into the appropriate size
|
||||||
// workspace pool. putWorkspaceVec must not be called with a matrix
|
// workspace pool. putWorkspaceVec must not be called with a matrix
|
||||||
// where references to the underlying data slice have been kept.
|
// where references to the underlying data slice have been kept.
|
||||||
func putWorkspaceVec(v *Vector) {
|
func putWorkspaceVec(v *VecDense) {
|
||||||
poolVec[bits(uint64(cap(v.mat.Data)))].Put(v)
|
poolVec[bits(uint64(cap(v.mat.Data)))].Put(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -186,13 +186,13 @@ func (qr *QR) Solve(m *Dense, trans bool, b Matrix) error {
|
|||||||
|
|
||||||
// SolveVec finds a minimum-norm solution to a system of linear equations.
|
// SolveVec finds a minimum-norm solution to a system of linear equations.
|
||||||
// Please see QR.Solve for the full documentation.
|
// Please see QR.Solve for the full documentation.
|
||||||
func (qr *QR) SolveVec(v *Vector, trans bool, b *Vector) error {
|
func (qr *QR) SolveVec(v *VecDense, trans bool, b *VecDense) error {
|
||||||
if v != b {
|
if v != b {
|
||||||
v.checkOverlap(b.mat)
|
v.checkOverlap(b.mat)
|
||||||
}
|
}
|
||||||
r, c := qr.qr.Dims()
|
r, c := qr.qr.Dims()
|
||||||
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
||||||
// instead recast the Vectors as Dense and call the matrix code.
|
// instead recast the VecDenses as Dense and call the matrix code.
|
||||||
if trans {
|
if trans {
|
||||||
v.reuseAs(r)
|
v.reuseAs(r)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -149,11 +149,11 @@ func TestSolveQRVec(t *testing.T) {
|
|||||||
if trans {
|
if trans {
|
||||||
br = n
|
br = n
|
||||||
}
|
}
|
||||||
b := NewVector(br, nil)
|
b := NewVecDense(br, nil)
|
||||||
for i := 0; i < br; i++ {
|
for i := 0; i < br; i++ {
|
||||||
b.SetVec(i, rand.Float64())
|
b.SetVec(i, rand.Float64())
|
||||||
}
|
}
|
||||||
var x Vector
|
var x VecDense
|
||||||
var qr QR
|
var qr QR
|
||||||
qr.Factorize(a)
|
qr.Factorize(a)
|
||||||
qr.SolveVec(&x, trans, b)
|
qr.SolveVec(&x, trans, b)
|
||||||
@@ -196,8 +196,8 @@ func TestSolveQRCond(t *testing.T) {
|
|||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
|
|
||||||
bvec := NewVector(m, nil)
|
bvec := NewVecDense(m, nil)
|
||||||
var xvec Vector
|
var xvec VecDense
|
||||||
if err := qr.SolveVec(&xvec, false, bvec); err == nil {
|
if err := qr.SolveVec(&xvec, false, bvec); err == nil {
|
||||||
t.Error("No error for near-singular matrix in matrix solve.")
|
t.Error("No error for near-singular matrix in matrix solve.")
|
||||||
}
|
}
|
||||||
|
@@ -154,7 +154,7 @@ func (t *TriDense) checkOverlap(a blas64.Triangular) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) checkOverlap(a blas64.Vector) bool {
|
func (v *VecDense) checkOverlap(a blas64.Vector) bool {
|
||||||
mat := v.mat
|
mat := v.mat
|
||||||
if cap(mat.Data) == 0 || cap(a.Data) == 0 {
|
if cap(mat.Data) == 0 || cap(a.Data) == 0 {
|
||||||
return false
|
return false
|
||||||
|
@@ -107,13 +107,13 @@ func (m *Dense) Solve(a, b Matrix) error {
|
|||||||
// by the matrix a and the right-hand side vector b. If A is singular or
|
// by the matrix a and the right-hand side vector b. If A is singular or
|
||||||
// near-singular, a Condition error is returned. Please see the documentation for
|
// near-singular, a Condition error is returned. Please see the documentation for
|
||||||
// Dense.Solve for more information.
|
// Dense.Solve for more information.
|
||||||
func (v *Vector) SolveVec(a Matrix, b *Vector) error {
|
func (v *VecDense) SolveVec(a Matrix, b *VecDense) error {
|
||||||
if v != b {
|
if v != b {
|
||||||
v.checkOverlap(b.mat)
|
v.checkOverlap(b.mat)
|
||||||
}
|
}
|
||||||
_, c := a.Dims()
|
_, c := a.Dims()
|
||||||
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
// The Solve implementation is non-trivial, so rather than duplicate the code,
|
||||||
// instead recast the Vectors as Dense and call the matrix code.
|
// instead recast the VecDenses as Dense and call the matrix code.
|
||||||
v.reuseAs(c)
|
v.reuseAs(c)
|
||||||
m := v.asDense()
|
m := v.asDense()
|
||||||
// We conditionally create bm as m when b and v are identical
|
// We conditionally create bm as m when b and v are identical
|
||||||
|
@@ -263,11 +263,11 @@ func TestSolveVec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
br := m
|
br := m
|
||||||
b := NewVector(br, nil)
|
b := NewVecDense(br, nil)
|
||||||
for i := 0; i < br; i++ {
|
for i := 0; i < br; i++ {
|
||||||
b.SetVec(i, rand.Float64())
|
b.SetVec(i, rand.Float64())
|
||||||
}
|
}
|
||||||
var x Vector
|
var x VecDense
|
||||||
x.SolveVec(a, b)
|
x.SolveVec(a, b)
|
||||||
|
|
||||||
// Test that the normal equations hold.
|
// Test that the normal equations hold.
|
||||||
@@ -284,13 +284,13 @@ func TestSolveVec(t *testing.T) {
|
|||||||
// Use testTwoInput
|
// Use testTwoInput
|
||||||
method := func(receiver, a, b Matrix) {
|
method := func(receiver, a, b Matrix) {
|
||||||
type SolveVecer interface {
|
type SolveVecer interface {
|
||||||
SolveVec(a Matrix, b *Vector) error
|
SolveVec(a Matrix, b *VecDense) error
|
||||||
}
|
}
|
||||||
rd := receiver.(SolveVecer)
|
rd := receiver.(SolveVecer)
|
||||||
rd.SolveVec(a, b.(*Vector))
|
rd.SolveVec(a, b.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(receiver, a, b *Dense) {
|
denseComparison := func(receiver, a, b *Dense) {
|
||||||
receiver.Solve(a, b)
|
receiver.Solve(a, b)
|
||||||
}
|
}
|
||||||
testTwoInput(t, "SolveVec", &Vector{}, method, denseComparison, legalTypesNotVecVec, legalSizeSolve, 1e-12)
|
testTwoInput(t, "SolveVec", &VecDense{}, method, denseComparison, legalTypesNotVecVec, legalSizeSolve, 1e-12)
|
||||||
}
|
}
|
||||||
|
@@ -232,7 +232,7 @@ func (s *SymDense) CopySym(a Symmetric) int {
|
|||||||
// SymRankOne performs a symetric rank-one update to the matrix a and stores
|
// SymRankOne performs a symetric rank-one update to the matrix a and stores
|
||||||
// the result in the receiver
|
// the result in the receiver
|
||||||
// s = a + alpha * x * x'
|
// s = a + alpha * x * x'
|
||||||
func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *Vector) {
|
func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *VecDense) {
|
||||||
n := x.Len()
|
n := x.Len()
|
||||||
if a.Symmetric() != n {
|
if a.Symmetric() != n {
|
||||||
panic(ErrShape)
|
panic(ErrShape)
|
||||||
@@ -322,7 +322,7 @@ func (s *SymDense) SymOuterK(alpha float64, x Matrix) {
|
|||||||
// RankTwo performs a symmmetric rank-two update to the matrix a and stores
|
// RankTwo performs a symmmetric rank-two update to the matrix a and stores
|
||||||
// the result in the receiver
|
// the result in the receiver
|
||||||
// m = a + alpha * (x * y' + y * x')
|
// m = a + alpha * (x * y' + y * x')
|
||||||
func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y *Vector) {
|
func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y *VecDense) {
|
||||||
n := s.mat.N
|
n := s.mat.N
|
||||||
if x.Len() != n {
|
if x.Len() != n {
|
||||||
panic(ErrShape)
|
panic(ErrShape)
|
||||||
|
@@ -265,7 +265,7 @@ func TestSymRankOne(t *testing.T) {
|
|||||||
|
|
||||||
// Check with new receiver
|
// Check with new receiver
|
||||||
s := NewSymDense(n, nil)
|
s := NewSymDense(n, nil)
|
||||||
s.SymRankOne(a, alpha, NewVector(len(x), x))
|
s.SymRankOne(a, alpha, NewVecDense(len(x), x))
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
for j := i; j < n; j++ {
|
for j := i; j < n; j++ {
|
||||||
want := m.At(i, j)
|
want := m.At(i, j)
|
||||||
@@ -277,7 +277,7 @@ func TestSymRankOne(t *testing.T) {
|
|||||||
|
|
||||||
// Check with reused receiver
|
// Check with reused receiver
|
||||||
copy(s.mat.Data, a.mat.Data)
|
copy(s.mat.Data, a.mat.Data)
|
||||||
s.SymRankOne(s, alpha, NewVector(len(x), x))
|
s.SymRankOne(s, alpha, NewVecDense(len(x), x))
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
for j := i; j < n; j++ {
|
for j := i; j < n; j++ {
|
||||||
want := m.At(i, j)
|
want := m.At(i, j)
|
||||||
@@ -291,10 +291,10 @@ func TestSymRankOne(t *testing.T) {
|
|||||||
alpha := 3.0
|
alpha := 3.0
|
||||||
method := func(receiver, a, b Matrix) {
|
method := func(receiver, a, b Matrix) {
|
||||||
type SymRankOner interface {
|
type SymRankOner interface {
|
||||||
SymRankOne(a Symmetric, alpha float64, x *Vector)
|
SymRankOne(a Symmetric, alpha float64, x *VecDense)
|
||||||
}
|
}
|
||||||
rd := receiver.(SymRankOner)
|
rd := receiver.(SymRankOner)
|
||||||
rd.SymRankOne(a.(Symmetric), alpha, b.(*Vector))
|
rd.SymRankOne(a.(Symmetric), alpha, b.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(receiver, a, b *Dense) {
|
denseComparison := func(receiver, a, b *Dense) {
|
||||||
var tmp Dense
|
var tmp Dense
|
||||||
@@ -307,7 +307,7 @@ func TestSymRankOne(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, ok = b.(*Vector)
|
_, ok = b.(*VecDense)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
legalSize := func(ar, ac, br, bc int) bool {
|
legalSize := func(ar, ac, br, bc int) bool {
|
||||||
@@ -320,7 +320,7 @@ func TestSymRankOne(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue250SymRankOne(t *testing.T) {
|
func TestIssue250SymRankOne(t *testing.T) {
|
||||||
x := NewVector(5, []float64{1, 2, 3, 4, 5})
|
x := NewVecDense(5, []float64{1, 2, 3, 4, 5})
|
||||||
var s1, s2 SymDense
|
var s1, s2 SymDense
|
||||||
s1.SymRankOne(NewSymDense(5, nil), 1, x)
|
s1.SymRankOne(NewSymDense(5, nil), 1, x)
|
||||||
s2.SymRankOne(NewSymDense(5, nil), 1, x)
|
s2.SymRankOne(NewSymDense(5, nil), 1, x)
|
||||||
@@ -366,7 +366,7 @@ func TestRankTwo(t *testing.T) {
|
|||||||
|
|
||||||
// Check with new receiver
|
// Check with new receiver
|
||||||
s := NewSymDense(n, nil)
|
s := NewSymDense(n, nil)
|
||||||
s.RankTwo(a, alpha, NewVector(len(x), x), NewVector(len(y), y))
|
s.RankTwo(a, alpha, NewVecDense(len(x), x), NewVecDense(len(y), y))
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
for j := i; j < n; j++ {
|
for j := i; j < n; j++ {
|
||||||
if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) {
|
if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) {
|
||||||
@@ -377,7 +377,7 @@ func TestRankTwo(t *testing.T) {
|
|||||||
|
|
||||||
// Check with reused receiver
|
// Check with reused receiver
|
||||||
copy(s.mat.Data, a.mat.Data)
|
copy(s.mat.Data, a.mat.Data)
|
||||||
s.RankTwo(s, alpha, NewVector(len(x), x), NewVector(len(y), y))
|
s.RankTwo(s, alpha, NewVecDense(len(x), x), NewVecDense(len(y), y))
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
for j := i; j < n; j++ {
|
for j := i; j < n; j++ {
|
||||||
if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) {
|
if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) {
|
||||||
@@ -434,7 +434,7 @@ func TestSymOuterK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue250SymOuterK(t *testing.T) {
|
func TestIssue250SymOuterK(t *testing.T) {
|
||||||
x := NewVector(5, []float64{1, 2, 3, 4, 5})
|
x := NewVecDense(5, []float64{1, 2, 3, 4, 5})
|
||||||
var s1, s2 SymDense
|
var s1, s2 SymDense
|
||||||
s1.SymOuterK(1, x)
|
s1.SymOuterK(1, x)
|
||||||
s2.SymOuterK(1, x)
|
s2.SymOuterK(1, x)
|
||||||
|
@@ -11,34 +11,34 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
vector *Vector
|
vector *VecDense
|
||||||
|
|
||||||
_ Matrix = vector
|
_ Matrix = vector
|
||||||
|
|
||||||
_ Reseter = vector
|
_ Reseter = vector
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vector represents a column vector.
|
// VecDense represents a column vector.
|
||||||
type Vector struct {
|
type VecDense struct {
|
||||||
mat blas64.Vector
|
mat blas64.Vector
|
||||||
n int
|
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.
|
||||||
// Vector must have positive increment in this package.
|
// VecDense must have positive increment in this package.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVector creates a new Vector of length n. If data == nil,
|
// NewVecDense creates a new VecDense of length n. If data == nil,
|
||||||
// a new slice is allocated for the backing slice. If len(data) == n, data is
|
// a new slice is allocated for the backing slice. If len(data) == n, data is
|
||||||
// used as the backing slice, and changes to the elements of the returned Vector
|
// used as the backing slice, and changes to the elements of the returned VecDense
|
||||||
// will be reflected in data. If neither of these is true, NewVector will panic.
|
// will be reflected in data. If neither of these is true, NewVecDense will panic.
|
||||||
func NewVector(n int, data []float64) *Vector {
|
func NewVecDense(n int, data []float64) *VecDense {
|
||||||
if len(data) != n && data != nil {
|
if len(data) != n && data != nil {
|
||||||
panic(ErrShape)
|
panic(ErrShape)
|
||||||
}
|
}
|
||||||
if data == nil {
|
if data == nil {
|
||||||
data = make([]float64, n)
|
data = make([]float64, n)
|
||||||
}
|
}
|
||||||
return &Vector{
|
return &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -47,15 +47,15 @@ func NewVector(n int, data []float64) *Vector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SliceVec returns a new Vector that shares backing data with the receiver.
|
// SliceVec returns a new VecDense that shares backing data with the receiver.
|
||||||
// The returned matrix starts at i of the receiver and extends k-i elements.
|
// The returned matrix starts at i of the receiver and extends k-i elements.
|
||||||
// SliceVec panics with ErrIndexOutOfRange if the slice is outside the capacity
|
// SliceVec panics with ErrIndexOutOfRange if the slice is outside the capacity
|
||||||
// of the receiver.
|
// of the receiver.
|
||||||
func (v *Vector) SliceVec(i, k int) *Vector {
|
func (v *VecDense) SliceVec(i, k int) *VecDense {
|
||||||
if i < 0 || k <= i || v.Cap() < k {
|
if i < 0 || k <= i || v.Cap() < k {
|
||||||
panic(ErrIndexOutOfRange)
|
panic(ErrIndexOutOfRange)
|
||||||
}
|
}
|
||||||
return &Vector{
|
return &VecDense{
|
||||||
n: k - i,
|
n: k - i,
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: v.mat.Inc,
|
Inc: v.mat.Inc,
|
||||||
@@ -66,7 +66,7 @@ func (v *Vector) SliceVec(i, k int) *Vector {
|
|||||||
|
|
||||||
// Dims returns the number of rows and columns in the matrix. Columns is always 1
|
// Dims returns the number of rows and columns in the matrix. Columns is always 1
|
||||||
// for a non-Reset vector.
|
// for a non-Reset vector.
|
||||||
func (v *Vector) Dims() (r, c int) {
|
func (v *VecDense) Dims() (r, c int) {
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ func (v *Vector) Dims() (r, c int) {
|
|||||||
|
|
||||||
// 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
|
||||||
// for a non-Reset vector.
|
// for a non-Reset vector.
|
||||||
func (v *Vector) Caps() (r, c int) {
|
func (v *VecDense) Caps() (r, c int) {
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
@@ -83,12 +83,12 @@ func (v *Vector) Caps() (r, c int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the length of the vector.
|
// Len returns the length of the vector.
|
||||||
func (v *Vector) Len() int {
|
func (v *VecDense) Len() int {
|
||||||
return v.n
|
return v.n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cap returns the capacity of the vector.
|
// Cap returns the capacity of the vector.
|
||||||
func (v *Vector) Cap() int {
|
func (v *VecDense) Cap() int {
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ func (v *Vector) Cap() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// T performs an implicit transpose by returning the receiver inside a Transpose.
|
// T performs an implicit transpose by returning the receiver inside a Transpose.
|
||||||
func (v *Vector) T() Matrix {
|
func (v *VecDense) T() Matrix {
|
||||||
return Transpose{v}
|
return Transpose{v}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ func (v *Vector) T() Matrix {
|
|||||||
// receiver of a dimensionally restricted operation.
|
// receiver of a dimensionally restricted operation.
|
||||||
//
|
//
|
||||||
// See the Reseter interface for more information.
|
// See the Reseter interface for more information.
|
||||||
func (v *Vector) 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
|
||||||
@@ -114,7 +114,7 @@ func (v *Vector) Reset() {
|
|||||||
|
|
||||||
// CloneVec makes a copy of a into the receiver, overwriting the previous value
|
// CloneVec makes a copy of a into the receiver, overwriting the previous value
|
||||||
// of the receiver.
|
// of the receiver.
|
||||||
func (v *Vector) CloneVec(a *Vector) {
|
func (v *VecDense) CloneVec(a *VecDense) {
|
||||||
if v == a {
|
if v == a {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -126,14 +126,14 @@ func (v *Vector) CloneVec(a *Vector) {
|
|||||||
blas64.Copy(v.n, a.mat, v.mat)
|
blas64.Copy(v.n, a.mat, v.mat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) RawVector() blas64.Vector {
|
func (v *VecDense) RawVector() blas64.Vector {
|
||||||
return v.mat
|
return v.mat
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyVec makes a copy of elements of a into the receiver. It is similar to the
|
// CopyVec makes a copy of elements of a into the receiver. It is similar to the
|
||||||
// built-in copy; it copies as much as the overlap between the two vectors and
|
// built-in copy; it copies as much as the overlap between the two vectors and
|
||||||
// returns the number of elements it copied.
|
// returns the number of elements it copied.
|
||||||
func (v *Vector) CopyVec(a *Vector) int {
|
func (v *VecDense) CopyVec(a *VecDense) int {
|
||||||
n := min(v.Len(), a.Len())
|
n := min(v.Len(), a.Len())
|
||||||
if v != a {
|
if v != a {
|
||||||
blas64.Copy(n, a.mat, v.mat)
|
blas64.Copy(n, a.mat, v.mat)
|
||||||
@@ -142,7 +142,7 @@ func (v *Vector) CopyVec(a *Vector) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ScaleVec scales the vector a by alpha, placing the result in the receiver.
|
// ScaleVec scales the vector a by alpha, placing the result in the receiver.
|
||||||
func (v *Vector) ScaleVec(alpha float64, a *Vector) {
|
func (v *VecDense) ScaleVec(alpha float64, a *VecDense) {
|
||||||
n := a.Len()
|
n := a.Len()
|
||||||
if v != a {
|
if v != a {
|
||||||
v.reuseAs(n)
|
v.reuseAs(n)
|
||||||
@@ -162,7 +162,7 @@ func (v *Vector) ScaleVec(alpha float64, a *Vector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddScaledVec adds the vectors a and alpha*b, placing the result in the receiver.
|
// AddScaledVec adds the vectors a and alpha*b, placing the result in the receiver.
|
||||||
func (v *Vector) AddScaledVec(a *Vector, alpha float64, b *Vector) {
|
func (v *VecDense) AddScaledVec(a *VecDense, alpha float64, b *VecDense) {
|
||||||
if alpha == 1 {
|
if alpha == 1 {
|
||||||
v.AddVec(a, b)
|
v.AddVec(a, b)
|
||||||
return
|
return
|
||||||
@@ -214,7 +214,7 @@ func (v *Vector) AddScaledVec(a *Vector, alpha float64, b *Vector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddVec adds the vectors a and b, placing the result in the receiver.
|
// AddVec adds the vectors a and b, placing the result in the receiver.
|
||||||
func (v *Vector) AddVec(a, b *Vector) {
|
func (v *VecDense) AddVec(a, b *VecDense) {
|
||||||
ar := a.Len()
|
ar := a.Len()
|
||||||
br := b.Len()
|
br := b.Len()
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ func (v *Vector) AddVec(a, b *Vector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SubVec subtracts the vector b from a, placing the result in the receiver.
|
// SubVec subtracts the vector b from a, placing the result in the receiver.
|
||||||
func (v *Vector) SubVec(a, b *Vector) {
|
func (v *VecDense) SubVec(a, b *VecDense) {
|
||||||
ar := a.Len()
|
ar := a.Len()
|
||||||
br := b.Len()
|
br := b.Len()
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ func (v *Vector) SubVec(a, b *Vector) {
|
|||||||
|
|
||||||
// MulElemVec performs element-wise multiplication of a and b, placing the result
|
// MulElemVec performs element-wise multiplication of a and b, placing the result
|
||||||
// in the receiver.
|
// in the receiver.
|
||||||
func (v *Vector) MulElemVec(a, b *Vector) {
|
func (v *VecDense) MulElemVec(a, b *VecDense) {
|
||||||
ar := a.Len()
|
ar := a.Len()
|
||||||
br := b.Len()
|
br := b.Len()
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ func (v *Vector) MulElemVec(a, b *Vector) {
|
|||||||
|
|
||||||
// DivElemVec performs element-wise division of a by b, placing the result
|
// DivElemVec performs element-wise division of a by b, placing the result
|
||||||
// in the receiver.
|
// in the receiver.
|
||||||
func (v *Vector) DivElemVec(a, b *Vector) {
|
func (v *VecDense) DivElemVec(a, b *VecDense) {
|
||||||
ar := a.Len()
|
ar := a.Len()
|
||||||
br := b.Len()
|
br := b.Len()
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ func (v *Vector) DivElemVec(a, b *Vector) {
|
|||||||
|
|
||||||
// MulVec computes a * b. The result is stored into the receiver.
|
// MulVec computes a * b. The result is stored into the receiver.
|
||||||
// MulVec panics if the number of columns in a does not equal the number of rows in b.
|
// MulVec panics if the number of columns in a does not equal the number of rows in b.
|
||||||
func (v *Vector) MulVec(a Matrix, b *Vector) {
|
func (v *VecDense) MulVec(a Matrix, b *VecDense) {
|
||||||
r, c := a.Dims()
|
r, c := a.Dims()
|
||||||
br := b.Len()
|
br := b.Len()
|
||||||
if c != br {
|
if c != br {
|
||||||
@@ -337,7 +337,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
|
|||||||
v.reuseAs(r)
|
v.reuseAs(r)
|
||||||
var restore func()
|
var restore func()
|
||||||
if v == a {
|
if v == a {
|
||||||
v, restore = v.isolatedWorkspace(a.(*Vector))
|
v, restore = v.isolatedWorkspace(a.(*VecDense))
|
||||||
defer restore()
|
defer restore()
|
||||||
} else if v == b {
|
} else if v == b {
|
||||||
v, restore = v.isolatedWorkspace(b)
|
v, restore = v.isolatedWorkspace(b)
|
||||||
@@ -345,7 +345,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch a := a.(type) {
|
switch a := a.(type) {
|
||||||
case *Vector:
|
case *VecDense:
|
||||||
if v != a {
|
if v != a {
|
||||||
v.checkOverlap(a.mat)
|
v.checkOverlap(a.mat)
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
|
|||||||
|
|
||||||
// reuseAs resizes an empty vector to a r×1 vector,
|
// reuseAs resizes an empty vector to a r×1 vector,
|
||||||
// or checks that a non-empty matrix is r×1.
|
// or checks that a non-empty matrix is r×1.
|
||||||
func (v *Vector) reuseAs(r int) {
|
func (v *VecDense) reuseAs(r int) {
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
v.mat = blas64.Vector{
|
v.mat = blas64.Vector{
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
@@ -440,14 +440,14 @@ func (v *Vector) reuseAs(r int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsZero returns whether the receiver is zero-sized. Zero-sized vectors can be the
|
// IsZero returns whether the receiver is zero-sized. Zero-sized vectors can be the
|
||||||
// receiver for size-restricted operations. Vectors can be zeroed using Reset.
|
// receiver for size-restricted operations. VecDenses can be zeroed using Reset.
|
||||||
func (v *Vector) IsZero() bool {
|
func (v *VecDense) IsZero() bool {
|
||||||
// It must be the case that v.Dims() returns
|
// It must be the case that v.Dims() returns
|
||||||
// zeros in this case. See comment in Reset().
|
// zeros in this case. See comment in Reset().
|
||||||
return v.mat.Inc == 0
|
return v.mat.Inc == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) isolatedWorkspace(a *Vector) (n *Vector, restore func()) {
|
func (v *VecDense) isolatedWorkspace(a *VecDense) (n *VecDense, restore func()) {
|
||||||
l := a.Len()
|
l := a.Len()
|
||||||
n = getWorkspaceVec(l, false)
|
n = getWorkspaceVec(l, false)
|
||||||
return n, func() {
|
return n, func() {
|
||||||
@@ -458,7 +458,7 @@ func (v *Vector) isolatedWorkspace(a *Vector) (n *Vector, restore func()) {
|
|||||||
|
|
||||||
// asDense returns a Dense representation of the receiver with the same
|
// asDense returns a Dense representation of the receiver with the same
|
||||||
// underlying data.
|
// underlying data.
|
||||||
func (v *Vector) asDense() *Dense {
|
func (v *VecDense) asDense() *Dense {
|
||||||
return &Dense{
|
return &Dense{
|
||||||
mat: v.asGeneral(),
|
mat: v.asGeneral(),
|
||||||
capRows: v.n,
|
capRows: v.n,
|
||||||
@@ -468,7 +468,7 @@ func (v *Vector) asDense() *Dense {
|
|||||||
|
|
||||||
// asGeneral returns a blas64.General representation of the receiver with the
|
// asGeneral returns a blas64.General representation of the receiver with the
|
||||||
// same underlying data.
|
// same underlying data.
|
||||||
func (v *Vector) asGeneral() blas64.General {
|
func (v *VecDense) asGeneral() blas64.General {
|
||||||
return blas64.General{
|
return blas64.General{
|
||||||
Rows: v.n,
|
Rows: v.n,
|
||||||
Cols: 1,
|
Cols: 1,
|
||||||
|
@@ -12,16 +12,16 @@ import (
|
|||||||
"gonum.org/v1/gonum/blas/blas64"
|
"gonum.org/v1/gonum/blas/blas64"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewVector(t *testing.T) {
|
func TestNewVecDense(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
n int
|
n int
|
||||||
data []float64
|
data []float64
|
||||||
vector *Vector
|
vector *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
n: 3,
|
n: 3,
|
||||||
data: []float64{4, 5, 6},
|
data: []float64{4, 5, 6},
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: []float64{4, 5, 6},
|
Data: []float64{4, 5, 6},
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
@@ -32,7 +32,7 @@ func TestNewVector(t *testing.T) {
|
|||||||
{
|
{
|
||||||
n: 3,
|
n: 3,
|
||||||
data: nil,
|
data: nil,
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: []float64{0, 0, 0},
|
Data: []float64{0, 0, 0},
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
@@ -41,7 +41,7 @@ func TestNewVector(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
v := NewVector(test.n, test.data)
|
v := NewVecDense(test.n, test.data)
|
||||||
rows, cols := v.Dims()
|
rows, cols := v.Dims()
|
||||||
if rows != test.n {
|
if rows != test.n {
|
||||||
t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n)
|
t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n)
|
||||||
@@ -57,12 +57,12 @@ func TestNewVector(t *testing.T) {
|
|||||||
|
|
||||||
func TestCap(t *testing.T) {
|
func TestCap(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
vector *Vector
|
vector *VecDense
|
||||||
want int
|
want int
|
||||||
}{
|
}{
|
||||||
{vector: NewVector(3, nil), want: 3},
|
{vector: NewVecDense(3, nil), want: 3},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: make([]float64, 7, 10),
|
Data: make([]float64, 7, 10),
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -72,7 +72,7 @@ func TestCap(t *testing.T) {
|
|||||||
want: 4,
|
want: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: make([]float64, 10),
|
Data: make([]float64, 10),
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -82,7 +82,7 @@ func TestCap(t *testing.T) {
|
|||||||
want: 4,
|
want: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: make([]float64, 11),
|
Data: make([]float64, 11),
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -92,7 +92,7 @@ func TestCap(t *testing.T) {
|
|||||||
want: 4,
|
want: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: make([]float64, 12),
|
Data: make([]float64, 12),
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -102,7 +102,7 @@ func TestCap(t *testing.T) {
|
|||||||
want: 4,
|
want: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: make([]float64, 13),
|
Data: make([]float64, 13),
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -119,12 +119,12 @@ func TestCap(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorAtSet(t *testing.T) {
|
func TestVecDenseAtSet(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
vector *Vector
|
vector *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: []float64{0, 1, 2},
|
Data: []float64{0, 1, 2},
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
@@ -133,7 +133,7 @@ func TestVectorAtSet(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
vector: &Vector{
|
vector: &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Data: []float64{0, 10, 10, 1, 10, 10, 2},
|
Data: []float64{0, 10, 10, 1, 10, 10, 2},
|
||||||
Inc: 3,
|
Inc: 3,
|
||||||
@@ -180,13 +180,13 @@ func TestVectorAtSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorMul(t *testing.T) {
|
func TestVecDenseMul(t *testing.T) {
|
||||||
method := func(receiver, a, b Matrix) {
|
method := func(receiver, a, b Matrix) {
|
||||||
type mulVecer interface {
|
type mulVecer interface {
|
||||||
MulVec(a Matrix, b *Vector)
|
MulVec(a Matrix, b *VecDense)
|
||||||
}
|
}
|
||||||
rd := receiver.(mulVecer)
|
rd := receiver.(mulVecer)
|
||||||
rd.MulVec(a, b.(*Vector))
|
rd.MulVec(a, b.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(receiver, a, b *Dense) {
|
denseComparison := func(receiver, a, b *Dense) {
|
||||||
receiver.Mul(a, b)
|
receiver.Mul(a, b)
|
||||||
@@ -200,44 +200,44 @@ func TestVectorMul(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return legal
|
return legal
|
||||||
}
|
}
|
||||||
testTwoInput(t, "MulVec", &Vector{}, method, denseComparison, legalTypesNotVecVec, legalSizeMulVec, 1e-14)
|
testTwoInput(t, "MulVec", &VecDense{}, method, denseComparison, legalTypesNotVecVec, legalSizeMulVec, 1e-14)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorScale(t *testing.T) {
|
func TestVecDenseScale(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a *Vector
|
a *VecDense
|
||||||
alpha float64
|
alpha float64
|
||||||
want *Vector
|
want *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
want: NewVector(3, []float64{0, 0, 0}),
|
want: NewVecDense(3, []float64{0, 0, 0}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
alpha: 1,
|
alpha: 1,
|
||||||
want: NewVector(3, []float64{0, 1, 2}),
|
want: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
alpha: -2,
|
alpha: -2,
|
||||||
want: NewVector(3, []float64{0, -2, -4}),
|
want: NewVecDense(3, []float64{0, -2, -4}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
want: NewVector(3, []float64{0, 0, 0}),
|
want: NewVecDense(3, []float64{0, 0, 0}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
alpha: 1,
|
alpha: 1,
|
||||||
want: NewVector(3, []float64{0, 1, 2}),
|
want: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
alpha: -2,
|
alpha: -2,
|
||||||
want: NewVector(3, []float64{0, -2, -4}),
|
want: NewVecDense(3, []float64{0, -2, -4}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 3, []float64{
|
a: NewDense(3, 3, []float64{
|
||||||
@@ -246,10 +246,10 @@ func TestVectorScale(t *testing.T) {
|
|||||||
6, 7, 8,
|
6, 7, 8,
|
||||||
}).ColView(1),
|
}).ColView(1),
|
||||||
alpha: -2,
|
alpha: -2,
|
||||||
want: NewVector(3, []float64{-2, -8, -14}),
|
want: NewVecDense(3, []float64{-2, -8, -14}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var v Vector
|
var v VecDense
|
||||||
v.ScaleVec(test.alpha, test.a)
|
v.ScaleVec(test.alpha, test.a)
|
||||||
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
||||||
t.Errorf("test %d: unexpected result for v = alpha * a: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
t.Errorf("test %d: unexpected result for v = alpha * a: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
||||||
@@ -265,58 +265,58 @@ func TestVectorScale(t *testing.T) {
|
|||||||
for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
|
for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
|
||||||
method := func(receiver, a Matrix) {
|
method := func(receiver, a Matrix) {
|
||||||
type scaleVecer interface {
|
type scaleVecer interface {
|
||||||
ScaleVec(float64, *Vector)
|
ScaleVec(float64, *VecDense)
|
||||||
}
|
}
|
||||||
v := receiver.(scaleVecer)
|
v := receiver.(scaleVecer)
|
||||||
v.ScaleVec(alpha, a.(*Vector))
|
v.ScaleVec(alpha, a.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(receiver, a *Dense) {
|
denseComparison := func(receiver, a *Dense) {
|
||||||
receiver.Scale(alpha, a)
|
receiver.Scale(alpha, a)
|
||||||
}
|
}
|
||||||
testOneInput(t, "ScaleVec", &Vector{}, method, denseComparison, legalTypeVec, isAnyVector, 0)
|
testOneInput(t, "ScaleVec", &VecDense{}, method, denseComparison, legalTypeVec, isAnyVecDense, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorAddScaled(t *testing.T) {
|
func TestVecDenseAddScaled(t *testing.T) {
|
||||||
for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
|
for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
|
||||||
method := func(receiver, a, b Matrix) {
|
method := func(receiver, a, b Matrix) {
|
||||||
type addScaledVecer interface {
|
type addScaledVecer interface {
|
||||||
AddScaledVec(*Vector, float64, *Vector)
|
AddScaledVec(*VecDense, float64, *VecDense)
|
||||||
}
|
}
|
||||||
v := receiver.(addScaledVecer)
|
v := receiver.(addScaledVecer)
|
||||||
v.AddScaledVec(a.(*Vector), alpha, b.(*Vector))
|
v.AddScaledVec(a.(*VecDense), alpha, b.(*VecDense))
|
||||||
}
|
}
|
||||||
denseComparison := func(receiver, a, b *Dense) {
|
denseComparison := func(receiver, a, b *Dense) {
|
||||||
var sb Dense
|
var sb Dense
|
||||||
sb.Scale(alpha, b)
|
sb.Scale(alpha, b)
|
||||||
receiver.Add(a, &sb)
|
receiver.Add(a, &sb)
|
||||||
}
|
}
|
||||||
testTwoInput(t, "AddScaledVec", &Vector{}, method, denseComparison, legalTypesVecVec, legalSizeSameVec, 1e-14)
|
testTwoInput(t, "AddScaledVec", &VecDense{}, method, denseComparison, legalTypesVecVec, legalSizeSameVec, 1e-14)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorAdd(t *testing.T) {
|
func TestVecDenseAdd(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a, b *Vector
|
a, b *VecDense
|
||||||
want *Vector
|
want *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewVector(3, []float64{0, 2, 3}),
|
b: NewVecDense(3, []float64{0, 2, 3}),
|
||||||
want: NewVector(3, []float64{0, 3, 5}),
|
want: NewVecDense(3, []float64{0, 3, 5}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 3, 5}),
|
want: NewVecDense(3, []float64{0, 3, 5}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 3, 5}),
|
want: NewVecDense(3, []float64{0, 3, 5}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var v Vector
|
var v VecDense
|
||||||
v.AddVec(test.a, test.b)
|
v.AddVec(test.a, test.b)
|
||||||
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
||||||
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
||||||
@@ -324,28 +324,28 @@ func TestVectorAdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorSub(t *testing.T) {
|
func TestVecDenseSub(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a, b *Vector
|
a, b *VecDense
|
||||||
want *Vector
|
want *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewVector(3, []float64{0, 0.5, 1}),
|
b: NewVecDense(3, []float64{0, 0.5, 1}),
|
||||||
want: NewVector(3, []float64{0, 0.5, 1}),
|
want: NewVecDense(3, []float64{0, 0.5, 1}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 0.5, 1}),
|
want: NewVecDense(3, []float64{0, 0.5, 1}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 0.5, 1}),
|
want: NewVecDense(3, []float64{0, 0.5, 1}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var v Vector
|
var v VecDense
|
||||||
v.SubVec(test.a, test.b)
|
v.SubVec(test.a, test.b)
|
||||||
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
||||||
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
||||||
@@ -353,28 +353,28 @@ func TestVectorSub(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorMulElem(t *testing.T) {
|
func TestVecDenseMulElem(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a, b *Vector
|
a, b *VecDense
|
||||||
want *Vector
|
want *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewVector(3, []float64{0, 2, 3}),
|
b: NewVecDense(3, []float64{0, 2, 3}),
|
||||||
want: NewVector(3, []float64{0, 2, 6}),
|
want: NewVecDense(3, []float64{0, 2, 6}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0, 1, 2}),
|
a: NewVecDense(3, []float64{0, 1, 2}),
|
||||||
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 2, 6}),
|
want: NewVecDense(3, []float64{0, 2, 6}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
|
||||||
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
|
||||||
want: NewVector(3, []float64{0, 2, 6}),
|
want: NewVecDense(3, []float64{0, 2, 6}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var v Vector
|
var v VecDense
|
||||||
v.MulElemVec(test.a, test.b)
|
v.MulElemVec(test.a, test.b)
|
||||||
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
||||||
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
||||||
@@ -382,28 +382,28 @@ func TestVectorMulElem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectorDivElem(t *testing.T) {
|
func TestVecDenseDivElem(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a, b *Vector
|
a, b *VecDense
|
||||||
want *Vector
|
want *VecDense
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0.5, 1, 2}),
|
a: NewVecDense(3, []float64{0.5, 1, 2}),
|
||||||
b: NewVector(3, []float64{0.5, 0.5, 1}),
|
b: NewVecDense(3, []float64{0.5, 0.5, 1}),
|
||||||
want: NewVector(3, []float64{1, 2, 2}),
|
want: NewVecDense(3, []float64{1, 2, 2}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewVector(3, []float64{0.5, 1, 2}),
|
a: NewVecDense(3, []float64{0.5, 1, 2}),
|
||||||
b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
|
b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
|
||||||
want: NewVector(3, []float64{1, 2, 2}),
|
want: NewVecDense(3, []float64{1, 2, 2}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
a: NewDense(3, 1, []float64{0.5, 1, 2}).ColView(0),
|
a: NewDense(3, 1, []float64{0.5, 1, 2}).ColView(0),
|
||||||
b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
|
b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
|
||||||
want: NewVector(3, []float64{1, 2, 2}),
|
want: NewVecDense(3, []float64{1, 2, 2}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
var v Vector
|
var v VecDense
|
||||||
v.DivElemVec(test.a, test.b)
|
v.DivElemVec(test.a, test.b)
|
||||||
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
|
||||||
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
|
||||||
@@ -427,10 +427,10 @@ func BenchmarkAddScaledVec1000Inc20(b *testing.B) { addScaledVecBench(b, 1000,
|
|||||||
func BenchmarkAddScaledVec10000Inc20(b *testing.B) { addScaledVecBench(b, 10000, 20) }
|
func BenchmarkAddScaledVec10000Inc20(b *testing.B) { addScaledVecBench(b, 10000, 20) }
|
||||||
func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) }
|
func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) }
|
||||||
func addScaledVecBench(b *testing.B, size, inc int) {
|
func addScaledVecBench(b *testing.B, size, inc int) {
|
||||||
x := randVector(size, inc, 1, rand.NormFloat64)
|
x := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
y := randVector(size, inc, 1, rand.NormFloat64)
|
y := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
var v Vector
|
var v VecDense
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
v.AddScaledVec(y, 2, x)
|
v.AddScaledVec(y, 2, x)
|
||||||
}
|
}
|
||||||
@@ -452,9 +452,9 @@ func BenchmarkScaleVec1000Inc20(b *testing.B) { scaleVecBench(b, 1000, 20) }
|
|||||||
func BenchmarkScaleVec10000Inc20(b *testing.B) { scaleVecBench(b, 10000, 20) }
|
func BenchmarkScaleVec10000Inc20(b *testing.B) { scaleVecBench(b, 10000, 20) }
|
||||||
func BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) }
|
func BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) }
|
||||||
func scaleVecBench(b *testing.B, size, inc int) {
|
func scaleVecBench(b *testing.B, size, inc int) {
|
||||||
x := randVector(size, inc, 1, rand.NormFloat64)
|
x := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
var v Vector
|
var v VecDense
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
v.ScaleVec(2, x)
|
v.ScaleVec(2, x)
|
||||||
}
|
}
|
||||||
@@ -476,10 +476,10 @@ func BenchmarkAddVec1000Inc20(b *testing.B) { addVecBench(b, 1000, 20) }
|
|||||||
func BenchmarkAddVec10000Inc20(b *testing.B) { addVecBench(b, 10000, 20) }
|
func BenchmarkAddVec10000Inc20(b *testing.B) { addVecBench(b, 10000, 20) }
|
||||||
func BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) }
|
func BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) }
|
||||||
func addVecBench(b *testing.B, size, inc int) {
|
func addVecBench(b *testing.B, size, inc int) {
|
||||||
x := randVector(size, inc, 1, rand.NormFloat64)
|
x := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
y := randVector(size, inc, 1, rand.NormFloat64)
|
y := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
var v Vector
|
var v VecDense
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
v.AddVec(x, y)
|
v.AddVec(x, y)
|
||||||
}
|
}
|
||||||
@@ -501,16 +501,16 @@ func BenchmarkSubVec1000Inc20(b *testing.B) { subVecBench(b, 1000, 20) }
|
|||||||
func BenchmarkSubVec10000Inc20(b *testing.B) { subVecBench(b, 10000, 20) }
|
func BenchmarkSubVec10000Inc20(b *testing.B) { subVecBench(b, 10000, 20) }
|
||||||
func BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) }
|
func BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) }
|
||||||
func subVecBench(b *testing.B, size, inc int) {
|
func subVecBench(b *testing.B, size, inc int) {
|
||||||
x := randVector(size, inc, 1, rand.NormFloat64)
|
x := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
y := randVector(size, inc, 1, rand.NormFloat64)
|
y := randVecDense(size, inc, 1, rand.NormFloat64)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
var v Vector
|
var v VecDense
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
v.SubVec(x, y)
|
v.SubVec(x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func randVector(size, inc int, rho float64, rnd func() float64) *Vector {
|
func randVecDense(size, inc int, rho float64, rnd func() float64) *VecDense {
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
panic("bad vector size")
|
panic("bad vector size")
|
||||||
}
|
}
|
||||||
@@ -520,7 +520,7 @@ func randVector(size, inc int, rho float64, rnd func() float64) *Vector {
|
|||||||
data[i] = rnd()
|
data[i] = rnd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &Vector{
|
return &VecDense{
|
||||||
mat: blas64.Vector{
|
mat: blas64.Vector{
|
||||||
Inc: inc,
|
Inc: inc,
|
||||||
Data: data,
|
Data: data,
|
||||||
|
@@ -24,11 +24,11 @@ type BFGS struct {
|
|||||||
ls *LinesearchMethod
|
ls *LinesearchMethod
|
||||||
|
|
||||||
dim int
|
dim int
|
||||||
x mat.Vector // Location of the last major iteration.
|
x mat.VecDense // Location of the last major iteration.
|
||||||
grad mat.Vector // Gradient at the last major iteration.
|
grad mat.VecDense // Gradient at the last major iteration.
|
||||||
s mat.Vector // Difference between locations in this and the previous iteration.
|
s mat.VecDense // Difference between locations in this and the previous iteration.
|
||||||
y mat.Vector // Difference between gradients in this and the previous iteration.
|
y mat.VecDense // Difference between gradients in this and the previous iteration.
|
||||||
tmp mat.Vector
|
tmp mat.VecDense
|
||||||
|
|
||||||
invHess *mat.SymDense
|
invHess *mat.SymDense
|
||||||
|
|
||||||
@@ -57,8 +57,8 @@ func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) {
|
|||||||
b.dim = dim
|
b.dim = dim
|
||||||
b.first = true
|
b.first = true
|
||||||
|
|
||||||
x := mat.NewVector(dim, loc.X)
|
x := mat.NewVecDense(dim, loc.X)
|
||||||
grad := mat.NewVector(dim, loc.Gradient)
|
grad := mat.NewVecDense(dim, loc.Gradient)
|
||||||
b.x.CloneVec(x)
|
b.x.CloneVec(x)
|
||||||
b.grad.CloneVec(grad)
|
b.grad.CloneVec(grad)
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) {
|
|||||||
|
|
||||||
// Initial direction is just negative of the gradient because the Hessian
|
// Initial direction is just negative of the gradient because the Hessian
|
||||||
// is an identity matrix.
|
// is an identity matrix.
|
||||||
d := mat.NewVector(dim, dir)
|
d := mat.NewVecDense(dim, dir)
|
||||||
d.ScaleVec(-1, grad)
|
d.ScaleVec(-1, grad)
|
||||||
return 1 / mat.Norm(d, 2)
|
return 1 / mat.Norm(d, 2)
|
||||||
}
|
}
|
||||||
@@ -93,8 +93,8 @@ func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) {
|
|||||||
panic("bfgs: unexpected size mismatch")
|
panic("bfgs: unexpected size mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
x := mat.NewVector(dim, loc.X)
|
x := mat.NewVecDense(dim, loc.X)
|
||||||
grad := mat.NewVector(dim, loc.Gradient)
|
grad := mat.NewVecDense(dim, loc.Gradient)
|
||||||
|
|
||||||
// s = x_{k+1} - x_{k}
|
// s = x_{k+1} - x_{k}
|
||||||
b.s.SubVec(x, &b.x)
|
b.s.SubVec(x, &b.x)
|
||||||
@@ -142,7 +142,7 @@ func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) {
|
|||||||
b.grad.CopyVec(grad)
|
b.grad.CopyVec(grad)
|
||||||
|
|
||||||
// New direction is stored in dir.
|
// New direction is stored in dir.
|
||||||
d := mat.NewVector(dim, dir)
|
d := mat.NewVecDense(dim, dir)
|
||||||
d.MulVec(b.invHess, grad)
|
d.MulVec(b.invHess, grad)
|
||||||
d.ScaleVec(-1, d)
|
d.ScaleVec(-1, d)
|
||||||
|
|
||||||
|
@@ -178,8 +178,8 @@ func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol flo
|
|||||||
an := mat.NewDense(m, len(nonBasicIdx), nil)
|
an := mat.NewDense(m, len(nonBasicIdx), nil)
|
||||||
extractColumns(an, A, nonBasicIdx)
|
extractColumns(an, A, nonBasicIdx)
|
||||||
|
|
||||||
bVec := mat.NewVector(len(b), b)
|
bVec := mat.NewVecDense(len(b), b)
|
||||||
cbVec := mat.NewVector(len(cb), cb)
|
cbVec := mat.NewVecDense(len(cb), cb)
|
||||||
|
|
||||||
// Temporary data needed each iteration. (Described later)
|
// Temporary data needed each iteration. (Described later)
|
||||||
r := make([]float64, n-m)
|
r := make([]float64, n-m)
|
||||||
@@ -214,13 +214,13 @@ func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol flo
|
|||||||
// of the rule in step 4 to avoid cycling.
|
// of the rule in step 4 to avoid cycling.
|
||||||
for {
|
for {
|
||||||
// Compute reduced costs -- r = cn - an^T ab^-T cb
|
// Compute reduced costs -- r = cn - an^T ab^-T cb
|
||||||
var tmp mat.Vector
|
var tmp mat.VecDense
|
||||||
err = tmp.SolveVec(ab.T(), cbVec)
|
err = tmp.SolveVec(ab.T(), cbVec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
data := make([]float64, n-m)
|
data := make([]float64, n-m)
|
||||||
tmp2 := mat.NewVector(n-m, data)
|
tmp2 := mat.NewVecDense(n-m, data)
|
||||||
tmp2.MulVec(an.T(), &tmp)
|
tmp2.MulVec(an.T(), &tmp)
|
||||||
floats.SubTo(r, cn, data)
|
floats.SubTo(r, cn, data)
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol flo
|
|||||||
an.SetCol(minIdx, tmpCol1)
|
an.SetCol(minIdx, tmpCol1)
|
||||||
|
|
||||||
// Compute the new xb.
|
// Compute the new xb.
|
||||||
xbVec := mat.NewVector(len(xb), xb)
|
xbVec := mat.NewVecDense(len(xb), xb)
|
||||||
err = xbVec.SolveVec(ab, bVec)
|
err = xbVec.SolveVec(ab, bVec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
@@ -288,12 +288,12 @@ func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol flo
|
|||||||
func computeMove(move []float64, minIdx int, A mat.Matrix, ab *mat.Dense, xb []float64, nonBasicIdx []int) error {
|
func computeMove(move []float64, minIdx int, A mat.Matrix, ab *mat.Dense, xb []float64, nonBasicIdx []int) error {
|
||||||
// Find ae.
|
// Find ae.
|
||||||
col := mat.Col(nil, nonBasicIdx[minIdx], A)
|
col := mat.Col(nil, nonBasicIdx[minIdx], A)
|
||||||
aCol := mat.NewVector(len(col), col)
|
aCol := mat.NewVecDense(len(col), col)
|
||||||
|
|
||||||
// d = - Ab^-1 Ae
|
// d = - Ab^-1 Ae
|
||||||
nb, _ := ab.Dims()
|
nb, _ := ab.Dims()
|
||||||
d := make([]float64, nb)
|
d := make([]float64, nb)
|
||||||
dVec := mat.NewVector(nb, d)
|
dVec := mat.NewVecDense(nb, d)
|
||||||
err := dVec.SolveVec(ab, aCol)
|
err := dVec.SolveVec(ab, aCol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrLinSolve
|
return ErrLinSolve
|
||||||
@@ -431,9 +431,9 @@ func initializeFromBasic(xb []float64, ab *mat.Dense, b []float64) error {
|
|||||||
if len(xb) != m {
|
if len(xb) != m {
|
||||||
panic("simplex: bad xb length")
|
panic("simplex: bad xb length")
|
||||||
}
|
}
|
||||||
xbMat := mat.NewVector(m, xb)
|
xbMat := mat.NewVecDense(m, xb)
|
||||||
|
|
||||||
err := xbMat.SolveVec(ab, mat.NewVector(m, b))
|
err := xbMat.SolveVec(ab, mat.NewVecDense(m, b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("lp: subcolumns of A for supplied initial basic singular")
|
return errors.New("lp: subcolumns of A for supplied initial basic singular")
|
||||||
}
|
}
|
||||||
|
@@ -176,9 +176,9 @@ func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat.Matrix, b
|
|||||||
primalOpt, primalX, _, errPrimal := simplex(initialBasic, c, a, b, convergenceTol)
|
primalOpt, primalX, _, errPrimal := simplex(initialBasic, c, a, b, convergenceTol)
|
||||||
if errPrimal == nil {
|
if errPrimal == nil {
|
||||||
// No error solving the simplex, check that the solution is feasible.
|
// No error solving the simplex, check that the solution is feasible.
|
||||||
var bCheck mat.Vector
|
var bCheck mat.VecDense
|
||||||
bCheck.MulVec(a, mat.NewVector(len(primalX), primalX))
|
bCheck.MulVec(a, mat.NewVecDense(len(primalX), primalX))
|
||||||
if !mat.EqualApprox(&bCheck, mat.NewVector(len(b), b), 1e-10) {
|
if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(b), b), 1e-10) {
|
||||||
t.Errorf("No error in primal but solution infeasible")
|
t.Errorf("No error in primal but solution infeasible")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,9 +223,9 @@ func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat.Matrix, b
|
|||||||
dualOpt, dualX, _, errDual := simplex(nil, cNew, aNew, bNew, convergenceTol)
|
dualOpt, dualX, _, errDual := simplex(nil, cNew, aNew, bNew, convergenceTol)
|
||||||
if errDual == nil {
|
if errDual == nil {
|
||||||
// Check that the dual is feasible
|
// Check that the dual is feasible
|
||||||
var bCheck mat.Vector
|
var bCheck mat.VecDense
|
||||||
bCheck.MulVec(aNew, mat.NewVector(len(dualX), dualX))
|
bCheck.MulVec(aNew, mat.NewVecDense(len(dualX), dualX))
|
||||||
if !mat.EqualApprox(&bCheck, mat.NewVector(len(bNew), bNew), 1e-10) {
|
if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(bNew), bNew), 1e-10) {
|
||||||
t.Errorf("No error in dual but solution infeasible")
|
t.Errorf("No error in dual but solution infeasible")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -88,8 +88,8 @@ func (n *Newton) NextDirection(loc *Location, dir []float64) (stepSize float64)
|
|||||||
// the Identity) from Nocedal, Wright (2006), 2nd edition.
|
// the Identity) from Nocedal, Wright (2006), 2nd edition.
|
||||||
|
|
||||||
dim := len(loc.X)
|
dim := len(loc.X)
|
||||||
d := mat.NewVector(dim, dir)
|
d := mat.NewVecDense(dim, dir)
|
||||||
grad := mat.NewVector(dim, loc.Gradient)
|
grad := mat.NewVecDense(dim, loc.Gradient)
|
||||||
n.hess.CopySym(loc.Hessian)
|
n.hess.CopySym(loc.Hessian)
|
||||||
|
|
||||||
// Find the smallest diagonal entry of the Hessian.
|
// Find the smallest diagonal entry of the Hessian.
|
||||||
|
@@ -183,7 +183,7 @@ func (n *Normal) LogProb(x []float64) float64 {
|
|||||||
panic(badSizeMismatch)
|
panic(badSizeMismatch)
|
||||||
}
|
}
|
||||||
c := -0.5*float64(dim)*logTwoPi - n.logSqrtDet
|
c := -0.5*float64(dim)*logTwoPi - n.logSqrtDet
|
||||||
dst := stat.Mahalanobis(mat.NewVector(dim, x), mat.NewVector(dim, n.mu), &n.chol)
|
dst := stat.Mahalanobis(mat.NewVecDense(dim, x), mat.NewVecDense(dim, n.mu), &n.chol)
|
||||||
return c - 0.5*dst*dst
|
return c - 0.5*dst*dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ func (n *Normal) ScoreInput(score, x []float64) []float64 {
|
|||||||
copy(tmp, x)
|
copy(tmp, x)
|
||||||
floats.Sub(tmp, n.mu)
|
floats.Sub(tmp, n.mu)
|
||||||
|
|
||||||
n.chol.SolveVec(mat.NewVector(len(score), score), mat.NewVector(len(tmp), tmp))
|
n.chol.SolveVec(mat.NewVecDense(len(score), score), mat.NewVecDense(len(tmp), tmp))
|
||||||
floats.Scale(-1, score)
|
floats.Scale(-1, score)
|
||||||
return score
|
return score
|
||||||
}
|
}
|
||||||
@@ -337,8 +337,8 @@ func (n *Normal) TransformNormal(dst, normal []float64) []float64 {
|
|||||||
// transformNormal performs the same operation as TransformNormal except no
|
// transformNormal performs the same operation as TransformNormal except no
|
||||||
// safety checks are performed and both input slices must be non-nil.
|
// safety checks are performed and both input slices must be non-nil.
|
||||||
func (n *Normal) transformNormal(dst, normal []float64) []float64 {
|
func (n *Normal) transformNormal(dst, normal []float64) []float64 {
|
||||||
srcVec := mat.NewVector(n.dim, normal)
|
srcVec := mat.NewVecDense(n.dim, normal)
|
||||||
dstVec := mat.NewVector(n.dim, dst)
|
dstVec := mat.NewVecDense(n.dim, dst)
|
||||||
dstVec.MulVec(&n.lower, srcVec)
|
dstVec.MulVec(&n.lower, srcVec)
|
||||||
floats.Add(dst, n.mu)
|
floats.Add(dst, n.mu)
|
||||||
return dst
|
return dst
|
||||||
|
@@ -44,7 +44,7 @@ func (Bhattacharyya) DistNormal(l, r *Normal) float64 {
|
|||||||
var chol mat.Cholesky
|
var chol mat.Cholesky
|
||||||
chol.Factorize(&sigma)
|
chol.Factorize(&sigma)
|
||||||
|
|
||||||
mahalanobis := stat.Mahalanobis(mat.NewVector(dim, l.mu), mat.NewVector(dim, r.mu), &chol)
|
mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &chol)
|
||||||
mahalanobisSq := mahalanobis * mahalanobis
|
mahalanobisSq := mahalanobis * mahalanobis
|
||||||
|
|
||||||
dl := l.chol.LogDet()
|
dl := l.chol.LogDet()
|
||||||
@@ -153,7 +153,7 @@ func (KullbackLeibler) DistNormal(l, r *Normal) float64 {
|
|||||||
panic(badSizeMismatch)
|
panic(badSizeMismatch)
|
||||||
}
|
}
|
||||||
|
|
||||||
mahalanobis := stat.Mahalanobis(mat.NewVector(dim, l.mu), mat.NewVector(dim, r.mu), &r.chol)
|
mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &r.chol)
|
||||||
mahalanobisSq := mahalanobis * mahalanobis
|
mahalanobisSq := mahalanobis * mahalanobis
|
||||||
|
|
||||||
// TODO(btracey): Optimize where there is a SolveCholeskySym
|
// TODO(btracey): Optimize where there is a SolveCholeskySym
|
||||||
@@ -269,7 +269,7 @@ func (renyi Renyi) DistNormal(l, r *Normal) float64 {
|
|||||||
}
|
}
|
||||||
logDetA := chol.LogDet()
|
logDetA := chol.LogDet()
|
||||||
|
|
||||||
mahalanobis := stat.Mahalanobis(mat.NewVector(dim, l.mu), mat.NewVector(dim, r.mu), &chol)
|
mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &chol)
|
||||||
mahalanobisSq := mahalanobis * mahalanobis
|
mahalanobisSq := mahalanobis * mahalanobis
|
||||||
|
|
||||||
return (renyi.Alpha/2)*mahalanobisSq + 1/(2*(1-renyi.Alpha))*(logDetA-(1-renyi.Alpha)*logDetL-renyi.Alpha*logDetR)
|
return (renyi.Alpha/2)*mahalanobisSq + 1/(2*(1-renyi.Alpha))*(logDetA-(1-renyi.Alpha)*logDetL-renyi.Alpha*logDetR)
|
||||||
|
@@ -152,8 +152,8 @@ func studentsTConditional(observed []int, values []float64, nu float64, mu []flo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute mu_1 + sigma_{2,1}^T * sigma_{2,2}^-1 (v - mu_2).
|
// Compute mu_1 + sigma_{2,1}^T * sigma_{2,2}^-1 (v - mu_2).
|
||||||
v := mat.NewVector(ob, mu2)
|
v := mat.NewVecDense(ob, mu2)
|
||||||
var tmp, tmp2 mat.Vector
|
var tmp, tmp2 mat.VecDense
|
||||||
err := chol.SolveVec(&tmp, v)
|
err := chol.SolveVec(&tmp, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return math.NaN(), nil, nil
|
return math.NaN(), nil, nil
|
||||||
@@ -256,9 +256,9 @@ func (s *StudentsT) LogProb(y []float64) float64 {
|
|||||||
copy(shift, y)
|
copy(shift, y)
|
||||||
floats.Sub(shift, s.mu)
|
floats.Sub(shift, s.mu)
|
||||||
|
|
||||||
x := mat.NewVector(s.dim, shift)
|
x := mat.NewVecDense(s.dim, shift)
|
||||||
|
|
||||||
var tmp mat.Vector
|
var tmp mat.VecDense
|
||||||
s.chol.SolveVec(&tmp, x)
|
s.chol.SolveVec(&tmp, x)
|
||||||
|
|
||||||
dot := mat.Dot(&tmp, x)
|
dot := mat.Dot(&tmp, x)
|
||||||
@@ -342,8 +342,8 @@ func (s *StudentsT) Rand(x []float64) []float64 {
|
|||||||
tmp[i] = s.src.NormFloat64()
|
tmp[i] = s.src.NormFloat64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xVec := mat.NewVector(s.dim, x)
|
xVec := mat.NewVecDense(s.dim, x)
|
||||||
tmpVec := mat.NewVector(s.dim, tmp)
|
tmpVec := mat.NewVecDense(s.dim, tmp)
|
||||||
xVec.MulVec(&s.lower, tmpVec)
|
xVec.MulVec(&s.lower, tmpVec)
|
||||||
|
|
||||||
u := distuv.ChiSquared{K: s.nu, Src: s.src}.Rand()
|
u := distuv.ChiSquared{K: s.nu, Src: s.src}.Rand()
|
||||||
|
@@ -201,9 +201,9 @@ func TestStudentsTConditional(t *testing.T) {
|
|||||||
floats.Sub(shift, muOb)
|
floats.Sub(shift, muOb)
|
||||||
|
|
||||||
newMu := make([]float64, len(muUnob))
|
newMu := make([]float64, len(muUnob))
|
||||||
newMuVec := mat.NewVector(len(muUnob), newMu)
|
newMuVec := mat.NewVecDense(len(muUnob), newMu)
|
||||||
shiftVec := mat.NewVector(len(shift), shift)
|
shiftVec := mat.NewVecDense(len(shift), shift)
|
||||||
var tmp mat.Vector
|
var tmp mat.VecDense
|
||||||
tmp.SolveVec(&sig22, shiftVec)
|
tmp.SolveVec(&sig22, shiftVec)
|
||||||
newMuVec.MulVec(sig12, &tmp)
|
newMuVec.MulVec(sig12, &tmp)
|
||||||
floats.Add(newMu, muUnob)
|
floats.Add(newMu, muUnob)
|
||||||
|
@@ -134,10 +134,10 @@ func corrToCov(c *mat.SymDense, sigma []float64) {
|
|||||||
// Mahalanobis returns NaN if the linear solve fails.
|
// Mahalanobis returns NaN if the linear solve fails.
|
||||||
//
|
//
|
||||||
// See https://en.wikipedia.org/wiki/Mahalanobis_distance for more information.
|
// See https://en.wikipedia.org/wiki/Mahalanobis_distance for more information.
|
||||||
func Mahalanobis(x, y *mat.Vector, chol *mat.Cholesky) float64 {
|
func Mahalanobis(x, y *mat.VecDense, chol *mat.Cholesky) float64 {
|
||||||
var diff mat.Vector
|
var diff mat.VecDense
|
||||||
diff.SubVec(x, y)
|
diff.SubVec(x, y)
|
||||||
var tmp mat.Vector
|
var tmp mat.VecDense
|
||||||
err := chol.SolveVec(&tmp, &diff)
|
err := chol.SolveVec(&tmp, &diff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return math.NaN()
|
return math.NaN()
|
||||||
|
@@ -265,13 +265,13 @@ func TestCorrCov(t *testing.T) {
|
|||||||
func TestMahalanobis(t *testing.T) {
|
func TestMahalanobis(t *testing.T) {
|
||||||
// Comparison with scipy.
|
// Comparison with scipy.
|
||||||
for cas, test := range []struct {
|
for cas, test := range []struct {
|
||||||
x, y *mat.Vector
|
x, y *mat.VecDense
|
||||||
Sigma *mat.SymDense
|
Sigma *mat.SymDense
|
||||||
ans float64
|
ans float64
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
x: mat.NewVector(3, []float64{1, 2, 3}),
|
x: mat.NewVecDense(3, []float64{1, 2, 3}),
|
||||||
y: mat.NewVector(3, []float64{0.8, 1.1, -1}),
|
y: mat.NewVecDense(3, []float64{0.8, 1.1, -1}),
|
||||||
Sigma: mat.NewSymDense(3,
|
Sigma: mat.NewSymDense(3,
|
||||||
[]float64{
|
[]float64{
|
||||||
0.8, 0.3, 0.1,
|
0.8, 0.3, 0.1,
|
||||||
|
Reference in New Issue
Block a user