mat: rename Vector->VecDense

This commit is contained in:
kortschak
2017-07-28 13:35:07 +09:30
committed by Dan Kortschak
parent c91540fef5
commit 862a4c5a4f
45 changed files with 383 additions and 383 deletions

View File

@@ -135,7 +135,7 @@ func jacobianConcurrent(dst *mat.Dense, f func([]float64, []float64), x, origin
defer wg.Done()
xcopy := make([]float64, n)
y := make([]float64, m)
yVec := mat.NewVector(m, y)
yVec := mat.NewVecDense(m, y)
for job := range jobs {
copy(xcopy, x)
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
// because we don't forbid repeated locations.
originVec := mat.NewVector(m, origin)
originVec := mat.NewVecDense(m, origin)
for _, pt := range formula.Stencil {
if pt.Loc != 0 {
continue

View File

@@ -55,7 +55,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int64]float64 {
for i := range last {
last[i] = 1
}
lastV := mat.NewVector(len(nodes), last)
lastV := mat.NewVecDense(len(nodes), last)
vec := make([]float64, len(nodes))
var sum float64
@@ -68,7 +68,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int64]float64 {
for i := range vec {
vec[i] *= f
}
v := mat.NewVector(len(nodes), vec)
v := mat.NewVecDense(len(nodes), vec)
for {
lastV, v = v, lastV
@@ -122,7 +122,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int64]float64 {
for i := range last {
last[i] = 1
}
lastV := mat.NewVector(len(nodes), last)
lastV := mat.NewVecDense(len(nodes), last)
vec := make([]float64, len(nodes))
var sum float64
@@ -135,7 +135,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int64]float64 {
for i := range vec {
vec[i] *= f
}
v := mat.NewVector(len(nodes), vec)
v := mat.NewVecDense(len(nodes), vec)
dt := (1 - damp) / float64(len(nodes))
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
// the result in dst. It assumes src and dst are the same length as m
// 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
for i, r := range m {
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
// 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
vec := v.RawVector().Data
for _, e := range r {
@@ -208,7 +208,7 @@ type sparseElement struct {
// onesDotUnitary performs the equivalent of a Ddot of v with
// a ones vector of equal length. v must have have a unitary
// vector increment.
func onesDotUnitary(alpha float64, v *mat.Vector) float64 {
func onesDotUnitary(alpha float64, v *mat.VecDense) float64 {
var sum float64
for _, f := range v.RawVector().Data {
sum += alpha * f

View File

@@ -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
// 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() {
panic(badCholesky)
}
@@ -322,7 +322,7 @@ func (c *Cholesky) InverseTo(s *SymDense) error {
//
// SymRankOne updates a Cholesky factorization in O(n²) time. The Cholesky
// 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() {
panic(badCholesky)
}

View File

@@ -33,8 +33,8 @@ func ExampleCholesky() {
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.
b := mat.NewVector(4, []float64{1, 2, 3, 4})
var x mat.Vector
b := mat.NewVecDense(4, []float64{1, 2, 3, 4})
var x mat.VecDense
if err := chol.SolveVec(&x, b); err != nil {
fmt.Println("Matrix is near singular: ", err)
}
@@ -83,7 +83,7 @@ func ExampleCholesky_SymRankOne() {
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(" ")))
// Rank-1 update the factorization.

View File

@@ -178,16 +178,16 @@ func TestSolveTwoChol(t *testing.T) {
func TestCholeskySolveVec(t *testing.T) {
for _, test := range []struct {
a *SymDense
b *Vector
ans *Vector
b *VecDense
ans *VecDense
}{
{
a: NewSymDense(2, []float64{
1, 0,
0, 1,
}),
b: NewVector(2, []float64{5, 6}),
ans: NewVector(2, []float64{5, 6}),
b: NewVecDense(2, []float64{5, 6}),
ans: NewVecDense(2, []float64{5, 6}),
},
{
a: NewSymDense(3, []float64{
@@ -195,8 +195,8 @@ func TestCholeskySolveVec(t *testing.T) {
0, 83, 71,
0, 0, 101,
}),
b: NewVector(3, []float64{5, 6, 7}),
ans: NewVector(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
b: NewVecDense(3, []float64{5, 6, 7}),
ans: NewVecDense(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
},
} {
var chol Cholesky
@@ -205,13 +205,13 @@ func TestCholeskySolveVec(t *testing.T) {
t.Fatal("unexpected Cholesky factorization failure: not positive definite")
}
var x Vector
var x VecDense
chol.SolveVec(&x, test.b)
if !EqualApprox(&x, test.ans, 1e-12) {
t.Error("incorrect Cholesky solve solution")
}
var ans Vector
var ans VecDense
ans.MulVec(test.a, &x)
if !EqualApprox(&ans, test.b, 1e-12) {
t.Error("incorrect Cholesky solve solution product")
@@ -320,7 +320,7 @@ func TestCholeskySymRankOne(t *testing.T) {
for i := range xdata {
xdata[i] = rand.NormFloat64()
}
x := NewVector(n, xdata)
x := NewVecDense(n, xdata)
var chol Cholesky
ok := chol.Factorize(&a)
@@ -397,7 +397,7 @@ func TestCholeskySymRankOne(t *testing.T) {
continue
}
x := NewVector(len(test.x), test.x)
x := NewVecDense(len(test.x), test.x)
ok = chol.SymRankOne(&chol, test.alpha, x)
if !ok {
if test.wantOk {

View File

@@ -201,14 +201,14 @@ func (m *Dense) T() Matrix {
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.
func (m *Dense) ColView(j int) *Vector {
func (m *Dense) ColView(j int) *VecDense {
if j >= m.mat.Cols || j < 0 {
panic(ErrColAccess)
}
return &Vector{
return &VecDense{
mat: blas64.Vector{
Inc: m.mat.Stride,
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.
//
// 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 {
panic(ErrRowAccess)
}
return &Vector{
return &VecDense{
mat: blas64.Vector{
Inc: 1,
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])
}
}
case *Vector:
case *VecDense:
amat := aU.mat
mat.Data = make([]float64, 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
// 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
// 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.
//
// See the Copier interface for more information.
@@ -457,7 +457,7 @@ func (m *Dense) Copy(a Matrix) (r, c int) {
// Nothing to do.
}
}
case *Vector:
case *VecDense:
var n, stride int
amat := aU.mat
if trans {

View File

@@ -338,7 +338,7 @@ func (m *Dense) Mul(a, b Matrix) {
blas64.Trmm(blas.Right, bT, 1, bmat, m.mat)
return
}
if bU, ok := bU.(*Vector); ok {
if bU, ok := bU.(*VecDense); ok {
m.checkOverlap(bU.asGeneral())
bvec := bU.RawVector()
if bTrans {
@@ -399,7 +399,7 @@ func (m *Dense) Mul(a, b Matrix) {
blas64.Trmm(blas.Left, aT, 1, amat, m.mat)
return
}
if aU, ok := aU.(*Vector); ok {
if aU, ok := aU.(*VecDense); ok {
m.checkOverlap(aU.asGeneral())
avec := aU.RawVector()
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
// in the receiver. If a is zero, see Outer.
// 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()
if x.Len() != ar {
panic(ErrShape)
@@ -683,7 +683,7 @@ func (m *Dense) RankOne(a Matrix, alpha float64, x, y *Vector) {
// in the receiver.
// m = alpha * x * y'
// 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()
c := y.Len()

View File

@@ -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 do := 0; do < 2; do++ {
for di := 0; di < 3; di++ {
@@ -1212,7 +1212,7 @@ func TestCopyVectorAlias(t *testing.T) {
4, 5, 6,
7, 8, 9,
})
var src *Vector
var src *VecDense
var want *Dense
if horiz {
src = a.RowView(si)
@@ -1549,12 +1549,12 @@ func TestRankOne(t *testing.T) {
a := NewDense(flatten(test.m))
m := &Dense{}
// 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) {
t.Errorf("unexpected result for RankOne test %d iteration 0: got: %+v want: %+v", i, m, want)
}
// 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) {
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
for j := 0; j < 2; j++ {
// 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) {
t.Errorf("unexpected result for Outer test %d iteration %d scale %v: got: %+v want: %+v", i, j, f, m, want)
}

View File

@@ -115,7 +115,7 @@
// 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
// 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
// are made about the performance of any method, and in particular, note that an

View File

@@ -141,7 +141,7 @@ func (e *Eigen) succFact() bool {
// Factorize returns whether the decomposition succeeded. If the decomposition
// failed, methods that require a successful factorization will panic.
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.
// Copy a because it is modified during the Lapack call.

View File

@@ -148,11 +148,11 @@ func TestSymEigen(t *testing.T) {
// Check that the eigenvalues are actually eigenvalues.
for i := 0; i < n; i++ {
v := NewVector(n, Col(nil, i, es.vectors))
var m Vector
v := NewVecDense(n, Col(nil, i, es.vectors))
var m VecDense
m.MulVec(s, v)
var scal Vector
var scal VecDense
scal.ScaleVec(es.values[i], v)
if !EqualApprox(&m, &scal, 1e-8) {

View File

@@ -71,7 +71,7 @@ func ExampleExcerpt() {
mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3)))
// The long vector is also too large, ...
long := mat.NewVector(100, nil)
long := mat.NewVecDense(100, nil)
for i := 0; i < 100; i++ {
long.SetVec(i, float64(i))
}

View File

@@ -40,14 +40,14 @@ func (m *Dense) set(i, j int, v float64) {
// At returns the element at row i.
// It panics if i is out of bounds or if j is not zero.
func (v *Vector) At(i, j int) float64 {
func (v *VecDense) At(i, j int) float64 {
if j != 0 {
panic(ErrColAccess)
}
return v.at(i)
}
func (v *Vector) at(i int) float64 {
func (v *VecDense) at(i int) float64 {
if uint(i) >= uint(v.n) {
panic(ErrRowAccess)
}
@@ -56,11 +56,11 @@ func (v *Vector) at(i int) float64 {
// SetVec sets the element at row i to the value val.
// It panics if i is out of bounds.
func (v *Vector) SetVec(i int, val float64) {
func (v *VecDense) SetVec(i int, val float64) {
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) {
panic(ErrVectorAccess)
}

View File

@@ -40,7 +40,7 @@ func (m *Dense) set(i, j int, v float64) {
// At returns the element at row i.
// It panics if i is out of bounds or if j is not zero.
func (v *Vector) At(i, j int) float64 {
func (v *VecDense) At(i, j int) float64 {
if uint(i) >= uint(v.n) {
panic(ErrRowAccess)
}
@@ -50,20 +50,20 @@ func (v *Vector) At(i, j int) float64 {
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]
}
// SetVec sets the element at row i to the value val.
// 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) {
panic(ErrVectorAccess)
}
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
}

View File

@@ -15,7 +15,7 @@ import (
// 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.
func Inner(x *Vector, A Matrix, y *Vector) float64 {
func Inner(x *VecDense, A Matrix, y *VecDense) float64 {
m, n := A.Dims()
if x.Len() != m {
panic(ErrShape)

View File

@@ -83,7 +83,7 @@ func TestInner(t *testing.T) {
}
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 {
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]
}
}
x := makeVectorInc(inc.x, xData)
y := makeVectorInc(inc.y, yData)
x := makeVecDenseInc(inc.x, xData)
y := makeVecDenseInc(inc.y, yData)
m := NewDense(n, n, data)
ans := Inner(x, m, y)
sym := NewSymDense(n, data)
@@ -128,8 +128,8 @@ func TestInnerSym(t *testing.T) {
}
}
func makeVectorInc(inc int, f []float64) *Vector {
v := &Vector{
func makeVecDenseInc(inc int, f []float64) *VecDense {
v := &VecDense{
n: len(f),
mat: blas64.Vector{
Inc: inc,
@@ -151,9 +151,9 @@ func makeVectorInc(inc int, f []float64) *Vector {
}
func benchmarkInner(b *testing.B, m, n int) {
x := NewVector(m, nil)
x := NewVecDense(m, nil)
randomSlice(x.mat.Data)
y := NewVector(n, nil)
y := NewVecDense(n, nil)
randomSlice(y.mat.Data)
data := make([]float64, m*n)
randomSlice(data)

View File

@@ -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.
//
// Vector is little-endian encoded as follows:
// VecDense is little-endian encoded as follows:
// 0 - 7 number of elements (int64)
// 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)
if bufLen <= 0 {
// 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.
//
// 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 (
n int
buf [8]byte
@@ -256,18 +256,18 @@ func (v Vector) MarshalBinaryTo(w io.Writer) (int, error) {
}
// 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.
//
// Limited checks on the validity of the binary input are performed:
// - 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
// 64b application and read back from a 32b application.)
// UnmarshalBinary does not limit the size of the unmarshaled vector, and so
// 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() {
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
// 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 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() {
panic("mat: unmarshal into non-zero vector")
}

View File

@@ -18,8 +18,8 @@ import (
var (
_ encoding.BinaryMarshaler = (*Dense)(nil)
_ encoding.BinaryUnmarshaler = (*Dense)(nil)
_ encoding.BinaryMarshaler = (*Vector)(nil)
_ encoding.BinaryUnmarshaler = (*Vector)(nil)
_ encoding.BinaryMarshaler = (*VecDense)(nil)
_ encoding.BinaryUnmarshaler = (*VecDense)(nil)
)
var denseData = []struct {
@@ -290,47 +290,47 @@ func TestDenseIORoundTrip(t *testing.T) {
var vectorData = []struct {
raw []byte
want *Vector
want *VecDense
eq func(got, want Matrix) bool
}{
{
raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
want: NewVector(0, []float64{}),
want: NewVecDense(0, []float64{}),
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@"),
want: NewVector(4, []float64{1, 2, 3, 4}),
want: NewVecDense(4, []float64{1, 2, 3, 4}),
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@"),
want: NewVector(6, []float64{1, 2, 3, 4, 5, 6}),
want: NewVecDense(6, []float64{1, 2, 3, 4, 5, 6}),
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\"@"),
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,
},
{
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,
},
{
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,
},
{
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,
},
{
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{
Data: []float64{0, 1, 2, 3, 4, 5, 6},
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"),
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 {
for _, v := range []bool{
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 {
buf, err := test.want.MarshalBinary()
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 {
buf := new(bytes.Buffer)
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 {
var v Vector
var v VecDense
err := v.UnmarshalBinary(test.raw)
if err != nil {
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 {
var v Vector
var v VecDense
buf := bytes.NewReader(test.raw)
n, err := v.UnmarshalBinaryFrom(buf)
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]
for i, tt := range []struct {
beg int
@@ -501,7 +501,7 @@ func TestVectorUnmarshalFromError(t *testing.T) {
},
} {
buf := bytes.NewReader(test.raw[tt.beg:tt.end])
var v Vector
var v VecDense
_, err := v.UnmarshalBinaryFrom(buf)
if 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 {
buf, err := test.want.MarshalBinary()
if err != nil {
t.Errorf("error encoding test #%d: %v\n", i, err)
}
var got Vector
var got VecDense
err = got.UnmarshalBinary(buf)
if err != nil {
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)
if err != nil {
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 BenchmarkMarshalVector100(b *testing.B) { marshalBinaryBenchVector(b, 100) }
func BenchmarkMarshalVector1000(b *testing.B) { marshalBinaryBenchVector(b, 1000) }
func BenchmarkMarshalVector10000(b *testing.B) { marshalBinaryBenchVector(b, 10000) }
func BenchmarkMarshalVecDense10(b *testing.B) { marshalBinaryBenchVecDense(b, 10) }
func BenchmarkMarshalVecDense100(b *testing.B) { marshalBinaryBenchVecDense(b, 100) }
func BenchmarkMarshalVecDense1000(b *testing.B) { marshalBinaryBenchVecDense(b, 1000) }
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)
for i := range data {
data[i] = float64(i)
}
vec := NewVector(size, data)
vec := NewVecDense(size, data)
b.ResetTimer()
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 BenchmarkUnmarshalVector100(b *testing.B) { unmarshalBinaryBenchVector(b, 100) }
func BenchmarkUnmarshalVector1000(b *testing.B) { unmarshalBinaryBenchVector(b, 1000) }
func BenchmarkUnmarshalVector10000(b *testing.B) { unmarshalBinaryBenchVector(b, 10000) }
func BenchmarkUnmarshalVecDense10(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10) }
func BenchmarkUnmarshalVecDense100(b *testing.B) { unmarshalBinaryBenchVecDense(b, 100) }
func BenchmarkUnmarshalVecDense1000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 1000) }
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)
for i := range data {
data[i] = float64(i)
}
buf, err := NewVector(size, data).MarshalBinary()
buf, err := NewVecDense(size, data).MarshalBinary()
if err != nil {
b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
var vec Vector
var vec VecDense
vec.UnmarshalBinary(buf)
}
}
func BenchmarkMarshalToVector10(b *testing.B) { marshalBinaryToBenchVector(b, 10) }
func BenchmarkMarshalToVector100(b *testing.B) { marshalBinaryToBenchVector(b, 100) }
func BenchmarkMarshalToVector1000(b *testing.B) { marshalBinaryToBenchVector(b, 1000) }
func BenchmarkMarshalToVector10000(b *testing.B) { marshalBinaryToBenchVector(b, 10000) }
func BenchmarkMarshalToVecDense10(b *testing.B) { marshalBinaryToBenchVecDense(b, 10) }
func BenchmarkMarshalToVecDense100(b *testing.B) { marshalBinaryToBenchVecDense(b, 100) }
func BenchmarkMarshalToVecDense1000(b *testing.B) { marshalBinaryToBenchVecDense(b, 1000) }
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)
for i := range data {
data[i] = float64(i)
}
vec := NewVector(size, data)
vec := NewVecDense(size, data)
w := ioutil.Discard
b.ResetTimer()
@@ -706,17 +706,17 @@ func marshalBinaryToBenchVector(b *testing.B, size int) {
}
}
func BenchmarkUnmarshalFromVector10(b *testing.B) { unmarshalBinaryFromBenchVector(b, 10) }
func BenchmarkUnmarshalFromVector100(b *testing.B) { unmarshalBinaryFromBenchVector(b, 100) }
func BenchmarkUnmarshalFromVector1000(b *testing.B) { unmarshalBinaryFromBenchVector(b, 1000) }
func BenchmarkUnmarshalFromVector10000(b *testing.B) { unmarshalBinaryFromBenchVector(b, 10000) }
func BenchmarkUnmarshalFromVecDense10(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10) }
func BenchmarkUnmarshalFromVecDense100(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 100) }
func BenchmarkUnmarshalFromVecDense1000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 1000) }
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)
for i := range data {
data[i] = float64(i)
}
buf, err := NewVector(size, data).MarshalBinary()
buf, err := NewVecDense(size, data).MarshalBinary()
if err != nil {
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()
for n := 0; n < b.N; n++ {
var vec Vector
var vec VecDense
vec.UnmarshalBinaryFrom(r)
r.reset()
}

View File

@@ -72,8 +72,8 @@ func isAnySize2(ar, ac, br, bc int) bool {
return true
}
// isAnyVector returns true for any column vector sizes.
func isAnyVector(ar, ac int) bool {
// isAnyVecDense returns true for any column vector sizes.
func isAnyVecDense(ar, ac int) bool {
return ac == 1
}
@@ -142,27 +142,27 @@ func legalTypesSym(a, b Matrix) bool {
return true
}
// legalTypeVec returns whether v is a *Vector.
// legalTypeVec returns whether v is a *VecDense.
func legalTypeVec(v Matrix) bool {
_, ok := v.(*Vector)
_, ok := v.(*VecDense)
return ok
}
// legalTypesVecVec returns whether both inputs are *Vector.
// legalTypesVecVec returns whether both inputs are *VecDense.
func legalTypesVecVec(a, b Matrix) bool {
if _, ok := a.(*Vector); !ok {
if _, ok := a.(*VecDense); !ok {
return false
}
if _, ok := b.(*Vector); !ok {
if _, ok := b.(*VecDense); !ok {
return false
}
return true
}
// 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 {
_, ok := b.(*Vector)
_, ok := b.(*VecDense)
return ok
}
@@ -183,7 +183,7 @@ func legalDims(a Matrix, m, n int) bool {
return false
}
return true
case *Vector:
case *VecDense:
if m < 0 || n < 0 {
return false
}
@@ -258,9 +258,9 @@ func makeRandOf(a Matrix, m, n int) Matrix {
}
}
rMatrix = returnAs(mat, t)
case *Vector:
case *VecDense:
if m == 0 && n == 0 {
return &Vector{}
return &VecDense{}
}
if n != 1 {
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 {
inc = t.mat.Inc
}
mat := &Vector{
mat := &VecDense{
mat: blas64.Vector{
Inc: inc,
Data: make([]float64, inc*(length-1)+1),
@@ -363,8 +363,8 @@ func makeCopyOf(a Matrix) Matrix {
}
}
return returnAs(m, t)
case *Vector:
m := &Vector{
case *VecDense:
m := &VecDense{
mat: blas64.Vector{
Inc: t.mat.Inc,
Data: make([]float64, t.mat.Inc*(t.n-1)+1),
@@ -492,7 +492,7 @@ func underlyingData(a Matrix) []float64 {
return t.mat.Data
case *TriDense:
return t.mat.Data
case *Vector:
case *VecDense:
return t.mat.Data
}
}
@@ -505,8 +505,8 @@ var testMatrices = []Matrix{
&SymDense{},
NewTriDense(3, true, nil),
NewTriDense(3, false, nil),
NewVector(0, nil),
&Vector{mat: blas64.Vector{Inc: 10}},
NewVecDense(0, nil),
&VecDense{mat: blas64.Vector{Inc: 10}},
&basicMatrix{},
&basicSymmetric{},
&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)},
Transpose{NewTriDense(3, false, nil)},
TransposeTri{NewTriDense(3, false, nil)},
Transpose{NewVector(0, nil)},
Transpose{&Vector{mat: blas64.Vector{Inc: 10}}},
Transpose{NewVecDense(0, nil)},
Transpose{&VecDense{mat: blas64.Vector{Inc: 10}}},
Transpose{&basicMatrix{}},
Transpose{&basicSymmetric{}},
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 {
t.Errorf("Did not panic with wrong size: %s", errStr)
}
case *Vector:
case *VecDense:
// Add to the column length.
wrongSize := makeRandOf(receiver, rr+1, rc)
panicked, _ = panics(func() { method(wrongSize, a) })
@@ -1054,7 +1054,7 @@ func testTwoInput(t *testing.T,
if !panicked {
t.Errorf("Did not panic with wrong size: %s", errStr)
}
case *Vector:
case *VecDense:
// Add to the column length.
wrongSize := makeRandOf(receiver, rr+1, rc)
panicked, _ = panics(func() { method(wrongSize, a, b) })

View File

@@ -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.
// 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 {
v.checkOverlap(b.mat)
}
r, c := lq.lq.Dims()
// 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 {
v.reuseAs(r)
} else {

View File

@@ -123,11 +123,11 @@ func TestSolveLQVec(t *testing.T) {
if trans {
br = n
}
b := NewVector(br, nil)
b := NewVecDense(br, nil)
for i := 0; i < br; i++ {
b.SetVec(i, rand.Float64())
}
var x Vector
var x VecDense
lq := &LQ{}
lq.Factorize(a)
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.")
}
bvec := NewVector(m, nil)
var xvec Vector
bvec := NewVecDense(m, nil)
var xvec VecDense
if err := lq.SolveVec(&xvec, false, bvec); err == nil {
t.Error("No error for near-singular matrix in matrix solve.")
}

View File

@@ -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 LU decomposition P * L * U = A, in the updated decomposition
// 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
// Factorizations for Nonlinear Analysis and Circuit Design" by Linzhong Deng.
// 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
// 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()
bn := b.Len()
if bn != n {

View File

@@ -62,8 +62,8 @@ func TestLURankOne(t *testing.T) {
// Apply a rank one update. Ensure the update magnitude is larger than
// the equal tolerance.
alpha := rand.Float64() + 1
x := NewVector(n, nil)
y := NewVector(n, nil)
x := NewVecDense(n, nil)
y := NewVecDense(n, nil)
for i := 0; i < n; i++ {
x.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.")
}
bvec := NewVector(m, nil)
var xvec Vector
bvec := NewVecDense(m, nil)
var xvec VecDense
if err := lu.SolveVec(&xvec, false, bvec); err == nil {
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())
}
}
b := NewVector(n, nil)
b := NewVecDense(n, nil)
for i := 0; i < n; i++ {
b.SetVec(i, rand.NormFloat64())
}
var lu LU
lu.Factorize(a)
var x Vector
var x VecDense
if err := lu.SolveVec(&x, false, b); err != nil {
continue
}
var got Vector
var got VecDense
got.MulVec(a, &x)
if !EqualApprox(&got, b, 1e-12) {
t.Errorf("Solve mismatch n = %v.\nWant: %v\nGot: %v", n, b, got)

View File

@@ -98,10 +98,10 @@ type Mutable interface {
Matrix
}
// A RowViewer can return a Vector reflecting a row that is backed by the matrix
// data. The Vector returned will have length equal to the number of columns.
// A RowViewer can return a VecDense reflecting a row that is backed by the matrix
// data. The VecDense returned will have length equal to the number of columns.
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
@@ -110,10 +110,10 @@ type RawRowViewer interface {
RawRowView(i int) []float64
}
// A ColViewer can return a Vector reflecting a column that is backed by the matrix
// data. The Vector returned will have length equal to the number of rows.
// A ColViewer can return a VecDense reflecting a column that is backed by the matrix
// data. The VecDense returned will have length equal to the number of rows.
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
@@ -370,7 +370,7 @@ func Det(a Matrix) float64 {
// Dot returns the sum of the element-wise product of a and b.
// Dot panics if the matrix sizes are unequal.
func Dot(a, b *Vector) float64 {
func Dot(a, b *VecDense) float64 {
la := a.Len()
lb := b.Len()
if la != lb {
@@ -428,8 +428,8 @@ func Equal(a, b Matrix) bool {
return true
}
}
if ra, ok := aU.(*Vector); ok {
if rb, ok := bU.(*Vector); ok {
if ra, ok := aU.(*VecDense); ok {
if rb, ok := bU.(*VecDense); ok {
// If the raw vectors are the same length they must either both be
// transposed or both not transposed (or have length 1).
for i := 0; i < ra.n; i++ {
@@ -500,8 +500,8 @@ func EqualApprox(a, b Matrix, epsilon float64) bool {
return true
}
}
if ra, ok := aU.(*Vector); ok {
if rb, ok := bU.(*Vector); ok {
if ra, ok := aU.(*VecDense); ok {
if rb, ok := bU.(*VecDense); ok {
// If the raw vectors are the same length they must either both be
// transposed or both not transposed (or have length 1).
for i := 0; i < ra.n; i++ {
@@ -723,7 +723,7 @@ func Norm(a Matrix, norm float64) float64 {
defer putFloats(work)
}
return lapack64.Lansy(n, rm, work)
case *Vector:
case *VecDense:
rv := rma.RawVector()
switch norm {
default:

View File

@@ -359,7 +359,7 @@ func TestDet(t *testing.T) {
func TestDot(t *testing.T) {
f := func(a, b Matrix) interface{} {
return Dot(a.(*Vector), b.(*Vector))
return Dot(a.(*VecDense), b.(*VecDense))
}
denseComparison := func(a, b *Dense) interface{} {
ra, ca := a.Dims()
@@ -473,7 +473,7 @@ func TestNormZero(t *testing.T) {
&SymDense{mat: blas64.Symmetric{Uplo: blas.Upper}},
&TriDense{},
&TriDense{mat: blas64.Triangular{Uplo: blas.Upper, Diag: blas.NonUnit}},
&Vector{},
&VecDense{},
} {
for _, norm := range []float64{1, 2, math.Inf(1)} {
panicked, message := panics(func() { Norm(a, norm) })

View File

@@ -51,7 +51,7 @@ var (
// poolTri is the TriDense equivalent of pool.
poolTri [63]sync.Pool
// poolVec is the Vector equivalent of pool.
// poolVec is the VecDense equivalent of pool.
poolVec [63]sync.Pool
// poolFloats is the []float64 equivalent of pool.
@@ -81,7 +81,7 @@ func init() {
}}
}
poolVec[i].New = func() interface{} {
return &Vector{mat: blas64.Vector{
return &VecDense{mat: blas64.Vector{
Inc: 1,
Data: make([]float64, l),
}}
@@ -176,12 +176,12 @@ func putWorkspaceTri(t *TriDense) {
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
// through the Matrix interface is zeroed.
func getWorkspaceVec(n int, clear bool) *Vector {
func getWorkspaceVec(n int, clear bool) *VecDense {
l := uint64(n)
v := poolVec[bits(l)].Get().(*Vector)
v := poolVec[bits(l)].Get().(*VecDense)
v.mat.Data = v.mat.Data[:l]
if clear {
zero(v.mat.Data)
@@ -190,10 +190,10 @@ func getWorkspaceVec(n int, clear bool) *Vector {
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
// 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)
}

View File

@@ -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.
// 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 {
v.checkOverlap(b.mat)
}
r, c := qr.qr.Dims()
// 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 {
v.reuseAs(r)
} else {

View File

@@ -149,11 +149,11 @@ func TestSolveQRVec(t *testing.T) {
if trans {
br = n
}
b := NewVector(br, nil)
b := NewVecDense(br, nil)
for i := 0; i < br; i++ {
b.SetVec(i, rand.Float64())
}
var x Vector
var x VecDense
var qr QR
qr.Factorize(a)
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.")
}
bvec := NewVector(m, nil)
var xvec Vector
bvec := NewVecDense(m, nil)
var xvec VecDense
if err := qr.SolveVec(&xvec, false, bvec); err == nil {
t.Error("No error for near-singular matrix in matrix solve.")
}

View File

@@ -154,7 +154,7 @@ func (t *TriDense) checkOverlap(a blas64.Triangular) bool {
return false
}
func (v *Vector) checkOverlap(a blas64.Vector) bool {
func (v *VecDense) checkOverlap(a blas64.Vector) bool {
mat := v.mat
if cap(mat.Data) == 0 || cap(a.Data) == 0 {
return false

View File

@@ -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
// near-singular, a Condition error is returned. Please see the documentation for
// 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 {
v.checkOverlap(b.mat)
}
_, c := a.Dims()
// 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)
m := v.asDense()
// We conditionally create bm as m when b and v are identical

View File

@@ -263,11 +263,11 @@ func TestSolveVec(t *testing.T) {
}
}
br := m
b := NewVector(br, nil)
b := NewVecDense(br, nil)
for i := 0; i < br; i++ {
b.SetVec(i, rand.Float64())
}
var x Vector
var x VecDense
x.SolveVec(a, b)
// Test that the normal equations hold.
@@ -284,13 +284,13 @@ func TestSolveVec(t *testing.T) {
// Use testTwoInput
method := func(receiver, a, b Matrix) {
type SolveVecer interface {
SolveVec(a Matrix, b *Vector) error
SolveVec(a Matrix, b *VecDense) error
}
rd := receiver.(SolveVecer)
rd.SolveVec(a, b.(*Vector))
rd.SolveVec(a, b.(*VecDense))
}
denseComparison := func(receiver, a, b *Dense) {
receiver.Solve(a, b)
}
testTwoInput(t, "SolveVec", &Vector{}, method, denseComparison, legalTypesNotVecVec, legalSizeSolve, 1e-12)
testTwoInput(t, "SolveVec", &VecDense{}, method, denseComparison, legalTypesNotVecVec, legalSizeSolve, 1e-12)
}

View File

@@ -232,7 +232,7 @@ func (s *SymDense) CopySym(a Symmetric) int {
// SymRankOne performs a symetric rank-one update to the matrix a and stores
// the result in the receiver
// 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()
if a.Symmetric() != n {
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
// the result in the receiver
// 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
if x.Len() != n {
panic(ErrShape)

View File

@@ -265,7 +265,7 @@ func TestSymRankOne(t *testing.T) {
// Check with new receiver
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 j := i; j < n; j++ {
want := m.At(i, j)
@@ -277,7 +277,7 @@ func TestSymRankOne(t *testing.T) {
// Check with reused receiver
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 j := i; j < n; j++ {
want := m.At(i, j)
@@ -291,10 +291,10 @@ func TestSymRankOne(t *testing.T) {
alpha := 3.0
method := func(receiver, a, b Matrix) {
type SymRankOner interface {
SymRankOne(a Symmetric, alpha float64, x *Vector)
SymRankOne(a Symmetric, alpha float64, x *VecDense)
}
rd := receiver.(SymRankOner)
rd.SymRankOne(a.(Symmetric), alpha, b.(*Vector))
rd.SymRankOne(a.(Symmetric), alpha, b.(*VecDense))
}
denseComparison := func(receiver, a, b *Dense) {
var tmp Dense
@@ -307,7 +307,7 @@ func TestSymRankOne(t *testing.T) {
if !ok {
return false
}
_, ok = b.(*Vector)
_, ok = b.(*VecDense)
return ok
}
legalSize := func(ar, ac, br, bc int) bool {
@@ -320,7 +320,7 @@ func TestSymRankOne(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
s1.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
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 j := i; j < n; j++ {
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
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 j := i; j < n; j++ {
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) {
x := NewVector(5, []float64{1, 2, 3, 4, 5})
x := NewVecDense(5, []float64{1, 2, 3, 4, 5})
var s1, s2 SymDense
s1.SymOuterK(1, x)
s2.SymOuterK(1, x)

View File

@@ -11,34 +11,34 @@ import (
)
var (
vector *Vector
vector *VecDense
_ Matrix = vector
_ Reseter = vector
)
// Vector represents a column vector.
type Vector struct {
// VecDense represents a column vector.
type VecDense struct {
mat blas64.Vector
n int
// A BLAS vector can have a negative increment, but allowing this
// in the mat type complicates a lot of code, and doesn't gain anything.
// 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
// used as the backing slice, and changes to the elements of the returned Vector
// will be reflected in data. If neither of these is true, NewVector will panic.
func NewVector(n int, data []float64) *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, NewVecDense will panic.
func NewVecDense(n int, data []float64) *VecDense {
if len(data) != n && data != nil {
panic(ErrShape)
}
if data == nil {
data = make([]float64, n)
}
return &Vector{
return &VecDense{
mat: blas64.Vector{
Inc: 1,
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.
// SliceVec panics with ErrIndexOutOfRange if the slice is outside the capacity
// 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 {
panic(ErrIndexOutOfRange)
}
return &Vector{
return &VecDense{
n: k - i,
mat: blas64.Vector{
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
// for a non-Reset vector.
func (v *Vector) Dims() (r, c int) {
func (v *VecDense) Dims() (r, c int) {
if v.IsZero() {
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
// for a non-Reset vector.
func (v *Vector) Caps() (r, c int) {
func (v *VecDense) Caps() (r, c int) {
if v.IsZero() {
return 0, 0
}
@@ -83,12 +83,12 @@ func (v *Vector) Caps() (r, c int) {
}
// Len returns the length of the vector.
func (v *Vector) Len() int {
func (v *VecDense) Len() int {
return v.n
}
// Cap returns the capacity of the vector.
func (v *Vector) Cap() int {
func (v *VecDense) Cap() int {
if v.IsZero() {
return 0
}
@@ -96,7 +96,7 @@ func (v *Vector) Cap() int {
}
// 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}
}
@@ -104,7 +104,7 @@ func (v *Vector) T() Matrix {
// receiver of a dimensionally restricted operation.
//
// 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
// made unless both are set to 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
// of the receiver.
func (v *Vector) CloneVec(a *Vector) {
func (v *VecDense) CloneVec(a *VecDense) {
if v == a {
return
}
@@ -126,14 +126,14 @@ func (v *Vector) CloneVec(a *Vector) {
blas64.Copy(v.n, a.mat, v.mat)
}
func (v *Vector) RawVector() blas64.Vector {
func (v *VecDense) RawVector() blas64.Vector {
return v.mat
}
// 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
// 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())
if v != a {
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.
func (v *Vector) ScaleVec(alpha float64, a *Vector) {
func (v *VecDense) ScaleVec(alpha float64, a *VecDense) {
n := a.Len()
if v != a {
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.
func (v *Vector) AddScaledVec(a *Vector, alpha float64, b *Vector) {
func (v *VecDense) AddScaledVec(a *VecDense, alpha float64, b *VecDense) {
if alpha == 1 {
v.AddVec(a, b)
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.
func (v *Vector) AddVec(a, b *Vector) {
func (v *VecDense) AddVec(a, b *VecDense) {
ar := a.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.
func (v *Vector) SubVec(a, b *Vector) {
func (v *VecDense) SubVec(a, b *VecDense) {
ar := a.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
// in the receiver.
func (v *Vector) MulElemVec(a, b *Vector) {
func (v *VecDense) MulElemVec(a, b *VecDense) {
ar := a.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
// in the receiver.
func (v *Vector) DivElemVec(a, b *Vector) {
func (v *VecDense) DivElemVec(a, b *VecDense) {
ar := a.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 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()
br := b.Len()
if c != br {
@@ -337,7 +337,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
v.reuseAs(r)
var restore func()
if v == a {
v, restore = v.isolatedWorkspace(a.(*Vector))
v, restore = v.isolatedWorkspace(a.(*VecDense))
defer restore()
} else if v == b {
v, restore = v.isolatedWorkspace(b)
@@ -345,7 +345,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
}
switch a := a.(type) {
case *Vector:
case *VecDense:
if v != a {
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,
// 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() {
v.mat = blas64.Vector{
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
// receiver for size-restricted operations. Vectors can be zeroed using Reset.
func (v *Vector) IsZero() bool {
// receiver for size-restricted operations. VecDenses can be zeroed using Reset.
func (v *VecDense) IsZero() bool {
// It must be the case that v.Dims() returns
// zeros in this case. See comment in Reset().
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()
n = getWorkspaceVec(l, false)
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
// underlying data.
func (v *Vector) asDense() *Dense {
func (v *VecDense) asDense() *Dense {
return &Dense{
mat: v.asGeneral(),
capRows: v.n,
@@ -468,7 +468,7 @@ func (v *Vector) asDense() *Dense {
// asGeneral returns a blas64.General representation of the receiver with the
// same underlying data.
func (v *Vector) asGeneral() blas64.General {
func (v *VecDense) asGeneral() blas64.General {
return blas64.General{
Rows: v.n,
Cols: 1,

View File

@@ -12,16 +12,16 @@ import (
"gonum.org/v1/gonum/blas/blas64"
)
func TestNewVector(t *testing.T) {
func TestNewVecDense(t *testing.T) {
for i, test := range []struct {
n int
data []float64
vector *Vector
vector *VecDense
}{
{
n: 3,
data: []float64{4, 5, 6},
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: []float64{4, 5, 6},
Inc: 1,
@@ -32,7 +32,7 @@ func TestNewVector(t *testing.T) {
{
n: 3,
data: nil,
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: []float64{0, 0, 0},
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()
if 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) {
for i, test := range []struct {
vector *Vector
vector *VecDense
want int
}{
{vector: NewVector(3, nil), want: 3},
{vector: NewVecDense(3, nil), want: 3},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: make([]float64, 7, 10),
Inc: 3,
@@ -72,7 +72,7 @@ func TestCap(t *testing.T) {
want: 4,
},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: make([]float64, 10),
Inc: 3,
@@ -82,7 +82,7 @@ func TestCap(t *testing.T) {
want: 4,
},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: make([]float64, 11),
Inc: 3,
@@ -92,7 +92,7 @@ func TestCap(t *testing.T) {
want: 4,
},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: make([]float64, 12),
Inc: 3,
@@ -102,7 +102,7 @@ func TestCap(t *testing.T) {
want: 4,
},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: make([]float64, 13),
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 {
vector *Vector
vector *VecDense
}{
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: []float64{0, 1, 2},
Inc: 1,
@@ -133,7 +133,7 @@ func TestVectorAtSet(t *testing.T) {
},
},
{
vector: &Vector{
vector: &VecDense{
mat: blas64.Vector{
Data: []float64{0, 10, 10, 1, 10, 10, 2},
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) {
type mulVecer interface {
MulVec(a Matrix, b *Vector)
MulVec(a Matrix, b *VecDense)
}
rd := receiver.(mulVecer)
rd.MulVec(a, b.(*Vector))
rd.MulVec(a, b.(*VecDense))
}
denseComparison := func(receiver, a, b *Dense) {
receiver.Mul(a, b)
@@ -200,44 +200,44 @@ func TestVectorMul(t *testing.T) {
}
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 {
a *Vector
a *VecDense
alpha float64
want *Vector
want *VecDense
}{
{
a: NewVector(3, []float64{0, 1, 2}),
a: NewVecDense(3, []float64{0, 1, 2}),
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,
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,
want: NewVector(3, []float64{0, -2, -4}),
want: NewVecDense(3, []float64{0, -2, -4}),
},
{
a: NewDense(3, 1, []float64{0, 1, 2}).ColView(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),
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),
alpha: -2,
want: NewVector(3, []float64{0, -2, -4}),
want: NewVecDense(3, []float64{0, -2, -4}),
},
{
a: NewDense(3, 3, []float64{
@@ -246,10 +246,10 @@ func TestVectorScale(t *testing.T) {
6, 7, 8,
}).ColView(1),
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)
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())
@@ -265,58 +265,58 @@ func TestVectorScale(t *testing.T) {
for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
method := func(receiver, a Matrix) {
type scaleVecer interface {
ScaleVec(float64, *Vector)
ScaleVec(float64, *VecDense)
}
v := receiver.(scaleVecer)
v.ScaleVec(alpha, a.(*Vector))
v.ScaleVec(alpha, a.(*VecDense))
}
denseComparison := func(receiver, a *Dense) {
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} {
method := func(receiver, a, b Matrix) {
type addScaledVecer interface {
AddScaledVec(*Vector, float64, *Vector)
AddScaledVec(*VecDense, float64, *VecDense)
}
v := receiver.(addScaledVecer)
v.AddScaledVec(a.(*Vector), alpha, b.(*Vector))
v.AddScaledVec(a.(*VecDense), alpha, b.(*VecDense))
}
denseComparison := func(receiver, a, b *Dense) {
var sb Dense
sb.Scale(alpha, b)
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 {
a, b *Vector
want *Vector
a, b *VecDense
want *VecDense
}{
{
a: NewVector(3, []float64{0, 1, 2}),
b: NewVector(3, []float64{0, 2, 3}),
want: NewVector(3, []float64{0, 3, 5}),
a: NewVecDense(3, []float64{0, 1, 2}),
b: NewVecDense(3, []float64{0, 2, 3}),
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),
want: NewVector(3, []float64{0, 3, 5}),
want: NewVecDense(3, []float64{0, 3, 5}),
},
{
a: NewDense(3, 1, []float64{0, 1, 2}).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)
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())
@@ -324,28 +324,28 @@ func TestVectorAdd(t *testing.T) {
}
}
func TestVectorSub(t *testing.T) {
func TestVecDenseSub(t *testing.T) {
for i, test := range []struct {
a, b *Vector
want *Vector
a, b *VecDense
want *VecDense
}{
{
a: NewVector(3, []float64{0, 1, 2}),
b: NewVector(3, []float64{0, 0.5, 1}),
want: NewVector(3, []float64{0, 0.5, 1}),
a: NewVecDense(3, []float64{0, 1, 2}),
b: NewVecDense(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),
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),
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)
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())
@@ -353,28 +353,28 @@ func TestVectorSub(t *testing.T) {
}
}
func TestVectorMulElem(t *testing.T) {
func TestVecDenseMulElem(t *testing.T) {
for i, test := range []struct {
a, b *Vector
want *Vector
a, b *VecDense
want *VecDense
}{
{
a: NewVector(3, []float64{0, 1, 2}),
b: NewVector(3, []float64{0, 2, 3}),
want: NewVector(3, []float64{0, 2, 6}),
a: NewVecDense(3, []float64{0, 1, 2}),
b: NewVecDense(3, []float64{0, 2, 3}),
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),
want: NewVector(3, []float64{0, 2, 6}),
want: NewVecDense(3, []float64{0, 2, 6}),
},
{
a: NewDense(3, 1, []float64{0, 1, 2}).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)
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())
@@ -382,28 +382,28 @@ func TestVectorMulElem(t *testing.T) {
}
}
func TestVectorDivElem(t *testing.T) {
func TestVecDenseDivElem(t *testing.T) {
for i, test := range []struct {
a, b *Vector
want *Vector
a, b *VecDense
want *VecDense
}{
{
a: NewVector(3, []float64{0.5, 1, 2}),
b: NewVector(3, []float64{0.5, 0.5, 1}),
want: NewVector(3, []float64{1, 2, 2}),
a: NewVecDense(3, []float64{0.5, 1, 2}),
b: NewVecDense(3, []float64{0.5, 0.5, 1}),
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),
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),
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)
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())
@@ -427,10 +427,10 @@ func BenchmarkAddScaledVec1000Inc20(b *testing.B) { addScaledVecBench(b, 1000,
func BenchmarkAddScaledVec10000Inc20(b *testing.B) { addScaledVecBench(b, 10000, 20) }
func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) }
func addScaledVecBench(b *testing.B, size, inc int) {
x := randVector(size, inc, 1, rand.NormFloat64)
y := randVector(size, inc, 1, rand.NormFloat64)
x := randVecDense(size, inc, 1, rand.NormFloat64)
y := randVecDense(size, inc, 1, rand.NormFloat64)
b.ResetTimer()
var v Vector
var v VecDense
for i := 0; i < b.N; i++ {
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 BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) }
func scaleVecBench(b *testing.B, size, inc int) {
x := randVector(size, inc, 1, rand.NormFloat64)
x := randVecDense(size, inc, 1, rand.NormFloat64)
b.ResetTimer()
var v Vector
var v VecDense
for i := 0; i < b.N; i++ {
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 BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) }
func addVecBench(b *testing.B, size, inc int) {
x := randVector(size, inc, 1, rand.NormFloat64)
y := randVector(size, inc, 1, rand.NormFloat64)
x := randVecDense(size, inc, 1, rand.NormFloat64)
y := randVecDense(size, inc, 1, rand.NormFloat64)
b.ResetTimer()
var v Vector
var v VecDense
for i := 0; i < b.N; i++ {
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 BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) }
func subVecBench(b *testing.B, size, inc int) {
x := randVector(size, inc, 1, rand.NormFloat64)
y := randVector(size, inc, 1, rand.NormFloat64)
x := randVecDense(size, inc, 1, rand.NormFloat64)
y := randVecDense(size, inc, 1, rand.NormFloat64)
b.ResetTimer()
var v Vector
var v VecDense
for i := 0; i < b.N; i++ {
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 {
panic("bad vector size")
}
@@ -520,7 +520,7 @@ func randVector(size, inc int, rho float64, rnd func() float64) *Vector {
data[i] = rnd()
}
}
return &Vector{
return &VecDense{
mat: blas64.Vector{
Inc: inc,
Data: data,

View File

@@ -24,11 +24,11 @@ type BFGS struct {
ls *LinesearchMethod
dim int
x mat.Vector // Location of the last major iteration.
grad mat.Vector // Gradient at the last major iteration.
s mat.Vector // Difference between locations in this and the previous iteration.
y mat.Vector // Difference between gradients in this and the previous iteration.
tmp mat.Vector
x mat.VecDense // Location of the last major iteration.
grad mat.VecDense // Gradient at the last major iteration.
s mat.VecDense // Difference between locations in this and the previous iteration.
y mat.VecDense // Difference between gradients in this and the previous iteration.
tmp mat.VecDense
invHess *mat.SymDense
@@ -57,8 +57,8 @@ func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) {
b.dim = dim
b.first = true
x := mat.NewVector(dim, loc.X)
grad := mat.NewVector(dim, loc.Gradient)
x := mat.NewVecDense(dim, loc.X)
grad := mat.NewVecDense(dim, loc.Gradient)
b.x.CloneVec(x)
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
// is an identity matrix.
d := mat.NewVector(dim, dir)
d := mat.NewVecDense(dim, dir)
d.ScaleVec(-1, grad)
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")
}
x := mat.NewVector(dim, loc.X)
grad := mat.NewVector(dim, loc.Gradient)
x := mat.NewVecDense(dim, loc.X)
grad := mat.NewVecDense(dim, loc.Gradient)
// s = x_{k+1} - x_{k}
b.s.SubVec(x, &b.x)
@@ -142,7 +142,7 @@ func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) {
b.grad.CopyVec(grad)
// New direction is stored in dir.
d := mat.NewVector(dim, dir)
d := mat.NewVecDense(dim, dir)
d.MulVec(b.invHess, grad)
d.ScaleVec(-1, d)

View File

@@ -178,8 +178,8 @@ func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol flo
an := mat.NewDense(m, len(nonBasicIdx), nil)
extractColumns(an, A, nonBasicIdx)
bVec := mat.NewVector(len(b), b)
cbVec := mat.NewVector(len(cb), cb)
bVec := mat.NewVecDense(len(b), b)
cbVec := mat.NewVecDense(len(cb), cb)
// Temporary data needed each iteration. (Described later)
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.
for {
// Compute reduced costs -- r = cn - an^T ab^-T cb
var tmp mat.Vector
var tmp mat.VecDense
err = tmp.SolveVec(ab.T(), cbVec)
if err != nil {
break
}
data := make([]float64, n-m)
tmp2 := mat.NewVector(n-m, data)
tmp2 := mat.NewVecDense(n-m, data)
tmp2.MulVec(an.T(), &tmp)
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)
// Compute the new xb.
xbVec := mat.NewVector(len(xb), xb)
xbVec := mat.NewVecDense(len(xb), xb)
err = xbVec.SolveVec(ab, bVec)
if err != nil {
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 {
// Find ae.
col := mat.Col(nil, nonBasicIdx[minIdx], A)
aCol := mat.NewVector(len(col), col)
aCol := mat.NewVecDense(len(col), col)
// d = - Ab^-1 Ae
nb, _ := ab.Dims()
d := make([]float64, nb)
dVec := mat.NewVector(nb, d)
dVec := mat.NewVecDense(nb, d)
err := dVec.SolveVec(ab, aCol)
if err != nil {
return ErrLinSolve
@@ -431,9 +431,9 @@ func initializeFromBasic(xb []float64, ab *mat.Dense, b []float64) error {
if len(xb) != m {
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 {
return errors.New("lp: subcolumns of A for supplied initial basic singular")
}

View File

@@ -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)
if errPrimal == nil {
// No error solving the simplex, check that the solution is feasible.
var bCheck mat.Vector
bCheck.MulVec(a, mat.NewVector(len(primalX), primalX))
if !mat.EqualApprox(&bCheck, mat.NewVector(len(b), b), 1e-10) {
var bCheck mat.VecDense
bCheck.MulVec(a, mat.NewVecDense(len(primalX), primalX))
if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(b), b), 1e-10) {
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)
if errDual == nil {
// Check that the dual is feasible
var bCheck mat.Vector
bCheck.MulVec(aNew, mat.NewVector(len(dualX), dualX))
if !mat.EqualApprox(&bCheck, mat.NewVector(len(bNew), bNew), 1e-10) {
var bCheck mat.VecDense
bCheck.MulVec(aNew, mat.NewVecDense(len(dualX), dualX))
if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(bNew), bNew), 1e-10) {
t.Errorf("No error in dual but solution infeasible")
}
}

View File

@@ -88,8 +88,8 @@ func (n *Newton) NextDirection(loc *Location, dir []float64) (stepSize float64)
// the Identity) from Nocedal, Wright (2006), 2nd edition.
dim := len(loc.X)
d := mat.NewVector(dim, dir)
grad := mat.NewVector(dim, loc.Gradient)
d := mat.NewVecDense(dim, dir)
grad := mat.NewVecDense(dim, loc.Gradient)
n.hess.CopySym(loc.Hessian)
// Find the smallest diagonal entry of the Hessian.

View File

@@ -183,7 +183,7 @@ func (n *Normal) LogProb(x []float64) float64 {
panic(badSizeMismatch)
}
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
}
@@ -301,7 +301,7 @@ func (n *Normal) ScoreInput(score, x []float64) []float64 {
copy(tmp, x)
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)
return score
}
@@ -337,8 +337,8 @@ func (n *Normal) TransformNormal(dst, normal []float64) []float64 {
// transformNormal performs the same operation as TransformNormal except no
// safety checks are performed and both input slices must be non-nil.
func (n *Normal) transformNormal(dst, normal []float64) []float64 {
srcVec := mat.NewVector(n.dim, normal)
dstVec := mat.NewVector(n.dim, dst)
srcVec := mat.NewVecDense(n.dim, normal)
dstVec := mat.NewVecDense(n.dim, dst)
dstVec.MulVec(&n.lower, srcVec)
floats.Add(dst, n.mu)
return dst

View File

@@ -44,7 +44,7 @@ func (Bhattacharyya) DistNormal(l, r *Normal) float64 {
var chol mat.Cholesky
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
dl := l.chol.LogDet()
@@ -153,7 +153,7 @@ func (KullbackLeibler) DistNormal(l, r *Normal) float64 {
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
// TODO(btracey): Optimize where there is a SolveCholeskySym
@@ -269,7 +269,7 @@ func (renyi Renyi) DistNormal(l, r *Normal) float64 {
}
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
return (renyi.Alpha/2)*mahalanobisSq + 1/(2*(1-renyi.Alpha))*(logDetA-(1-renyi.Alpha)*logDetL-renyi.Alpha*logDetR)

View File

@@ -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).
v := mat.NewVector(ob, mu2)
var tmp, tmp2 mat.Vector
v := mat.NewVecDense(ob, mu2)
var tmp, tmp2 mat.VecDense
err := chol.SolveVec(&tmp, v)
if err != nil {
return math.NaN(), nil, nil
@@ -256,9 +256,9 @@ func (s *StudentsT) LogProb(y []float64) float64 {
copy(shift, y)
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)
dot := mat.Dot(&tmp, x)
@@ -342,8 +342,8 @@ func (s *StudentsT) Rand(x []float64) []float64 {
tmp[i] = s.src.NormFloat64()
}
}
xVec := mat.NewVector(s.dim, x)
tmpVec := mat.NewVector(s.dim, tmp)
xVec := mat.NewVecDense(s.dim, x)
tmpVec := mat.NewVecDense(s.dim, tmp)
xVec.MulVec(&s.lower, tmpVec)
u := distuv.ChiSquared{K: s.nu, Src: s.src}.Rand()

View File

@@ -201,9 +201,9 @@ func TestStudentsTConditional(t *testing.T) {
floats.Sub(shift, muOb)
newMu := make([]float64, len(muUnob))
newMuVec := mat.NewVector(len(muUnob), newMu)
shiftVec := mat.NewVector(len(shift), shift)
var tmp mat.Vector
newMuVec := mat.NewVecDense(len(muUnob), newMu)
shiftVec := mat.NewVecDense(len(shift), shift)
var tmp mat.VecDense
tmp.SolveVec(&sig22, shiftVec)
newMuVec.MulVec(sig12, &tmp)
floats.Add(newMu, muUnob)

View File

@@ -134,10 +134,10 @@ func corrToCov(c *mat.SymDense, sigma []float64) {
// Mahalanobis returns NaN if the linear solve fails.
//
// See https://en.wikipedia.org/wiki/Mahalanobis_distance for more information.
func Mahalanobis(x, y *mat.Vector, chol *mat.Cholesky) float64 {
var diff mat.Vector
func Mahalanobis(x, y *mat.VecDense, chol *mat.Cholesky) float64 {
var diff mat.VecDense
diff.SubVec(x, y)
var tmp mat.Vector
var tmp mat.VecDense
err := chol.SolveVec(&tmp, &diff)
if err != nil {
return math.NaN()

View File

@@ -265,13 +265,13 @@ func TestCorrCov(t *testing.T) {
func TestMahalanobis(t *testing.T) {
// Comparison with scipy.
for cas, test := range []struct {
x, y *mat.Vector
x, y *mat.VecDense
Sigma *mat.SymDense
ans float64
}{
{
x: mat.NewVector(3, []float64{1, 2, 3}),
y: mat.NewVector(3, []float64{0.8, 1.1, -1}),
x: mat.NewVecDense(3, []float64{1, 2, 3}),
y: mat.NewVecDense(3, []float64{0.8, 1.1, -1}),
Sigma: mat.NewSymDense(3,
[]float64{
0.8, 0.3, 0.1,