diff --git a/diff/fd/example_test.go b/diff/fd/example_test.go index 13a68fa0..adc9db0f 100644 --- a/diff/fd/example_test.go +++ b/diff/fd/example_test.go @@ -9,7 +9,7 @@ import ( "math" "gonum.org/v1/gonum/diff/fd" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleDerivative() { @@ -53,12 +53,12 @@ func ExampleJacobian() { dst[2] = 4*x[1]*x[1] - 2*x[2] dst[3] = x[2] * math.Sin(x[0]) } - jac := mat64.NewDense(4, 3, nil) + jac := mat.NewDense(4, 3, nil) fd.Jacobian(jac, f, []float64{1, 2, 3}, &fd.JacobianSettings{ Formula: fd.Central, Concurrent: true, }) - fmt.Printf("J ≈ %.6v\n", mat64.Formatted(jac, mat64.Prefix(" "))) + fmt.Printf("J ≈ %.6v\n", mat.Formatted(jac, mat.Prefix(" "))) // Output: // J ≈ ⎡ 1 0 0⎤ diff --git a/diff/fd/jacobian.go b/diff/fd/jacobian.go index ea42f233..a43c57d7 100644 --- a/diff/fd/jacobian.go +++ b/diff/fd/jacobian.go @@ -9,7 +9,7 @@ import ( "sync" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) type JacobianSettings struct { @@ -39,7 +39,7 @@ type JacobianSettings struct { // // dst must be non-nil, the number of its columns must equal the length of x, and // the derivative order of the formula must be 1, otherwise Jacobian will panic. -func Jacobian(dst *mat64.Dense, f func(y, x []float64), x []float64, settings *JacobianSettings) { +func Jacobian(dst *mat.Dense, f func(y, x []float64), x []float64, settings *JacobianSettings) { n := len(x) if n == 0 { panic("jacobian: x has zero length") @@ -93,7 +93,7 @@ func Jacobian(dst *mat64.Dense, f func(y, x []float64), x []float64, settings *J } } -func jacobianSerial(dst *mat64.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64) { +func jacobianSerial(dst *mat.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64) { m, n := dst.Dims() xcopy := make([]float64, n) y := make([]float64, m) @@ -122,7 +122,7 @@ func jacobianSerial(dst *mat64.Dense, f func([]float64, []float64), x, origin [] dst.Scale(1/step, dst) } -func jacobianConcurrent(dst *mat64.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64, nWorkers int) { +func jacobianConcurrent(dst *mat.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64, nWorkers int) { m, n := dst.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { @@ -138,7 +138,7 @@ func jacobianConcurrent(dst *mat64.Dense, f func([]float64, []float64), x, origi defer wg.Done() xcopy := make([]float64, n) y := make([]float64, m) - yVec := mat64.NewVector(m, y) + yVec := mat.NewVector(m, y) for job := range jobs { copy(xcopy, x) xcopy[job.j] += job.pt.Loc * step @@ -182,7 +182,7 @@ func jacobianConcurrent(dst *mat64.Dense, f func([]float64, []float64), x, origi // all columns of dst. Iterate again over all Formula points // because we don't forbid repeated locations. - originVec := mat64.NewVector(m, origin) + originVec := mat.NewVector(m, origin) for _, pt := range formula.Stencil { if pt.Loc != 0 { continue diff --git a/diff/fd/jacobian_test.go b/diff/fd/jacobian_test.go index 04dc5bfb..020f2c1b 100644 --- a/diff/fd/jacobian_test.go +++ b/diff/fd/jacobian_test.go @@ -10,13 +10,13 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func vecFunc13(y, x []float64) { y[0] = 5*x[0] + x[2]*math.Sin(x[1]) + 1 } -func vecFunc13Jac(jac *mat64.Dense, x []float64) { +func vecFunc13Jac(jac *mat.Dense, x []float64) { jac.Set(0, 0, 5) jac.Set(0, 1, x[2]*math.Cos(x[1])) jac.Set(0, 2, math.Sin(x[1])) @@ -26,7 +26,7 @@ func vecFunc22(y, x []float64) { y[0] = x[0]*x[0]*x[1] + 1 y[1] = 5*x[0] + math.Sin(x[1]) + 1 } -func vecFunc22Jac(jac *mat64.Dense, x []float64) { +func vecFunc22Jac(jac *mat.Dense, x []float64) { jac.Set(0, 0, 2*x[0]*x[1]) jac.Set(0, 1, x[0]*x[0]) jac.Set(1, 0, 5) @@ -39,7 +39,7 @@ func vecFunc43(y, x []float64) { y[2] = 4*x[1]*x[1] - 2*x[2] + 1 y[3] = x[2]*math.Sin(x[0]) + 1 } -func vecFunc43Jac(jac *mat64.Dense, x []float64) { +func vecFunc43Jac(jac *mat.Dense, x []float64) { jac.Set(0, 0, 1) jac.Set(0, 1, 0) jac.Set(0, 2, 0) @@ -61,7 +61,7 @@ func TestJacobian(t *testing.T) { for tc, test := range []struct { m, n int f func([]float64, []float64) - jac func(*mat64.Dense, []float64) + jac func(*mat.Dense, []float64) }{ { m: 1, @@ -88,15 +88,15 @@ func TestJacobian(t *testing.T) { xcopy := make([]float64, test.n) copy(xcopy, x) - want := mat64.NewDense(test.m, test.n, nil) + want := mat.NewDense(test.m, test.n, nil) test.jac(want, x) - got := mat64.NewDense(test.m, test.n, nil) + got := mat.NewDense(test.m, test.n, nil) fillNaNDense(got) Jacobian(got, test.f, x, nil) - if !mat64.EqualApprox(want, got, tol) { + if !mat.EqualApprox(want, got, tol) { t.Errorf("Case %d (default settings): unexpected Jacobian.\nwant: %v\ngot: %v", - tc, mat64.Formatted(want, mat64.Prefix(" ")), mat64.Formatted(got, mat64.Prefix(" "))) + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) } if !floats.Equal(x, xcopy) { t.Errorf("Case %d (default settings): x modified", tc) @@ -107,7 +107,7 @@ func TestJacobian(t *testing.T) { for tc, test := range []struct { m, n int f func([]float64, []float64) - jac func(*mat64.Dense, []float64) + jac func(*mat.Dense, []float64) tol float64 formula Formula }{ @@ -188,17 +188,17 @@ func TestJacobian(t *testing.T) { xcopy := make([]float64, test.n) copy(xcopy, x) - want := mat64.NewDense(test.m, test.n, nil) + want := mat.NewDense(test.m, test.n, nil) test.jac(want, x) - got := mat64.NewDense(test.m, test.n, nil) + got := mat.NewDense(test.m, test.n, nil) fillNaNDense(got) Jacobian(got, test.f, x, &JacobianSettings{ Formula: test.formula, }) - if !mat64.EqualApprox(want, got, test.tol) { + if !mat.EqualApprox(want, got, test.tol) { t.Errorf("Case %d: unexpected Jacobian.\nwant: %v\ngot: %v", - tc, mat64.Formatted(want, mat64.Prefix(" ")), mat64.Formatted(got, mat64.Prefix(" "))) + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) } if !floats.Equal(x, xcopy) { t.Errorf("Case %d: x modified", tc) @@ -209,9 +209,9 @@ func TestJacobian(t *testing.T) { Formula: test.formula, Concurrent: true, }) - if !mat64.EqualApprox(want, got, test.tol) { + if !mat.EqualApprox(want, got, test.tol) { t.Errorf("Case %d (concurrent): unexpected Jacobian.\nwant: %v\ngot: %v", - tc, mat64.Formatted(want, mat64.Prefix(" ")), mat64.Formatted(got, mat64.Prefix(" "))) + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) } if !floats.Equal(x, xcopy) { t.Errorf("Case %d (concurrent): x modified", tc) @@ -224,9 +224,9 @@ func TestJacobian(t *testing.T) { Formula: test.formula, OriginValue: origin, }) - if !mat64.EqualApprox(want, got, test.tol) { + if !mat.EqualApprox(want, got, test.tol) { t.Errorf("Case %d (origin): unexpected Jacobian.\nwant: %v\ngot: %v", - tc, mat64.Formatted(want, mat64.Prefix(" ")), mat64.Formatted(got, mat64.Prefix(" "))) + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) } if !floats.Equal(x, xcopy) { t.Errorf("Case %d (origin): x modified", tc) @@ -238,9 +238,9 @@ func TestJacobian(t *testing.T) { OriginValue: origin, Concurrent: true, }) - if !mat64.EqualApprox(want, got, test.tol) { + if !mat.EqualApprox(want, got, test.tol) { t.Errorf("Case %d (concurrent, origin): unexpected Jacobian.\nwant: %v\ngot: %v", - tc, mat64.Formatted(want, mat64.Prefix(" ")), mat64.Formatted(got, mat64.Prefix(" "))) + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) } if !floats.Equal(x, xcopy) { t.Errorf("Case %d (concurrent, origin): x modified", tc) @@ -258,7 +258,7 @@ func randomSlice(n int, bound float64) []float64 { } // fillNaNDense fills the matrix m with NaN values. -func fillNaNDense(m *mat64.Dense) { +func fillNaNDense(m *mat.Dense) { r, c := m.Dims() for i := 0; i < r; i++ { for j := 0; j < c; j++ { diff --git a/graph/network/page.go b/graph/network/page.go index 4036e20e..ceea2aa4 100644 --- a/graph/network/page.go +++ b/graph/network/page.go @@ -10,7 +10,7 @@ import ( "gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/graph" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // PageRank returns the PageRank weights for nodes of the directed graph g @@ -31,7 +31,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int]float64 { indexOf[n.ID()] = i } - m := mat64.NewDense(len(nodes), len(nodes), nil) + m := mat.NewDense(len(nodes), len(nodes), nil) dangling := damp / float64(len(nodes)) for j, u := range nodes { to := g.From(u) @@ -45,17 +45,17 @@ func PageRank(g graph.Directed, damp, tol float64) map[int]float64 { } } } - mat := m.RawMatrix().Data + matrix := m.RawMatrix().Data dt := (1 - damp) / float64(len(nodes)) - for i := range mat { - mat[i] += dt + for i := range matrix { + matrix[i] += dt } last := make([]float64, len(nodes)) for i := range last { last[i] = 1 } - lastV := mat64.NewVector(len(nodes), last) + lastV := mat.NewVector(len(nodes), last) vec := make([]float64, len(nodes)) var sum float64 @@ -68,7 +68,7 @@ func PageRank(g graph.Directed, damp, tol float64) map[int]float64 { for i := range vec { vec[i] *= f } - v := mat64.NewVector(len(nodes), vec) + v := mat.NewVector(len(nodes), vec) for { lastV, v = v, lastV @@ -122,7 +122,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int]float64 { for i := range last { last[i] = 1 } - lastV := mat64.NewVector(len(nodes), last) + lastV := mat.NewVector(len(nodes), last) vec := make([]float64, len(nodes)) var sum float64 @@ -135,7 +135,7 @@ func PageRankSparse(g graph.Directed, damp, tol float64) map[int]float64 { for i := range vec { vec[i] *= f } - v := mat64.NewVector(len(nodes), vec) + v := mat.NewVector(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 *mat64.Vector) { +func (m rowCompressedMatrix) mulVecUnitary(dst, src *mat.Vector) { 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 *mat64.Vector) float64 { +func (r compressedRow) dotUnitary(v *mat.Vector) 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 *mat64.Vector) float64 { +func onesDotUnitary(alpha float64, v *mat.Vector) float64 { var sum float64 for _, f := range v.RawVector().Data { sum += alpha * f diff --git a/graph/path/shortest.go b/graph/path/shortest.go index 8294abf2..883039f2 100644 --- a/graph/path/shortest.go +++ b/graph/path/shortest.go @@ -9,7 +9,7 @@ import ( "math/rand" "gonum.org/v1/gonum/graph" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // Shortest is a shortest-path tree created by the BellmanFordFrom or DijkstraFrom @@ -125,7 +125,7 @@ type AllShortest struct { // // dist contains the pairwise // distances between nodes. - dist *mat64.Dense + dist *mat.Dense // next contains the shortest-path // tree of the graph. The first index // is a linear mapping of from-dense-id @@ -159,7 +159,7 @@ func newAllShortest(nodes []graph.Node, forward bool) AllShortest { nodes: nodes, indexOf: indexOf, - dist: mat64.NewDense(len(nodes), len(nodes), dist), + dist: mat.NewDense(len(nodes), len(nodes), dist), next: make([][]int, len(nodes)*len(nodes)), forward: forward, } diff --git a/graph/simple/dense_directed_matrix.go b/graph/simple/dense_directed_matrix.go index a6d681d3..512fda57 100644 --- a/graph/simple/dense_directed_matrix.go +++ b/graph/simple/dense_directed_matrix.go @@ -9,7 +9,7 @@ import ( "gonum.org/v1/gonum/graph" "gonum.org/v1/gonum/graph/internal/ordered" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // DirectedMatrix represents a directed graph using an adjacency @@ -17,7 +17,7 @@ import ( // Edges are stored implicitly as an edge weight, so edges stored in // the graph are not recoverable. type DirectedMatrix struct { - mat *mat64.Dense + mat *mat.Dense nodes []graph.Node self float64 @@ -29,17 +29,17 @@ type DirectedMatrix struct { // specifies the cost of self connection, and absent specifies the weight // returned for absent edges. func NewDirectedMatrix(n int, init, self, absent float64) *DirectedMatrix { - mat := make([]float64, n*n) + matrix := make([]float64, n*n) if init != 0 { - for i := range mat { - mat[i] = init + for i := range matrix { + matrix[i] = init } } - for i := 0; i < len(mat); i += n + 1 { - mat[i] = self + for i := 0; i < len(matrix); i += n + 1 { + matrix[i] = self } return &DirectedMatrix{ - mat: mat64.NewDense(n, n, mat), + mat: mat.NewDense(n, n, matrix), self: self, absent: absent, } @@ -255,10 +255,10 @@ func (g *DirectedMatrix) Degree(n graph.Node) int { return deg } -// Matrix returns the mat64.Matrix representation of the graph. The orientation +// Matrix returns the mat.Matrix representation of the graph. The orientation // of the matrix is such that the matrix entry at G_{ij} is the weight of the edge // from node i to node j. -func (g *DirectedMatrix) Matrix() mat64.Matrix { +func (g *DirectedMatrix) Matrix() mat.Matrix { // Prevent alteration of dimensions of the returned matrix. m := *g.mat return &m diff --git a/graph/simple/dense_undirected_matrix.go b/graph/simple/dense_undirected_matrix.go index 6ef09ff6..ed4b7ce7 100644 --- a/graph/simple/dense_undirected_matrix.go +++ b/graph/simple/dense_undirected_matrix.go @@ -9,7 +9,7 @@ import ( "gonum.org/v1/gonum/graph" "gonum.org/v1/gonum/graph/internal/ordered" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // UndirectedMatrix represents an undirected graph using an adjacency @@ -17,7 +17,7 @@ import ( // Edges are stored implicitly as an edge weight, so edges stored in // the graph are not recoverable. type UndirectedMatrix struct { - mat *mat64.SymDense + mat *mat.SymDense nodes []graph.Node self float64 @@ -29,17 +29,17 @@ type UndirectedMatrix struct { // specifies the cost of self connection, and absent specifies the weight // returned for absent edges. func NewUndirectedMatrix(n int, init, self, absent float64) *UndirectedMatrix { - mat := make([]float64, n*n) + matrix := make([]float64, n*n) if init != 0 { - for i := range mat { - mat[i] = init + for i := range matrix { + matrix[i] = init } } - for i := 0; i < len(mat); i += n + 1 { - mat[i] = self + for i := 0; i < len(matrix); i += n + 1 { + matrix[i] = self } return &UndirectedMatrix{ - mat: mat64.NewSymDense(n, mat), + mat: mat.NewSymDense(n, matrix), self: self, absent: absent, } @@ -216,8 +216,8 @@ func (g *UndirectedMatrix) Degree(n graph.Node) int { return deg } -// Matrix returns the mat64.Matrix representation of the graph. -func (g *UndirectedMatrix) Matrix() mat64.Matrix { +// Matrix returns the mat.Matrix representation of the graph. +func (g *UndirectedMatrix) Matrix() mat.Matrix { // Prevent alteration of dimensions of the returned matrix. m := *g.mat return &m diff --git a/graph/undirect_test.go b/graph/undirect_test.go index 56acfa65..f5530608 100644 --- a/graph/undirect_test.go +++ b/graph/undirect_test.go @@ -10,7 +10,7 @@ import ( "gonum.org/v1/gonum/graph" "gonum.org/v1/gonum/graph/simple" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) var directedGraphs = []struct { @@ -19,7 +19,7 @@ var directedGraphs = []struct { absent float64 merge func(x, y float64, xe, ye graph.Edge) float64 - want mat64.Matrix + want mat.Matrix }{ { g: func() graph.DirectedBuilder { return simple.NewDirectedGraph(0, 0) }, @@ -28,7 +28,7 @@ var directedGraphs = []struct { {F: simple.Node(1), T: simple.Node(0), W: 1}, {F: simple.Node(1), T: simple.Node(2), W: 1}, }, - want: mat64.NewSymDense(3, []float64{ + want: mat.NewSymDense(3, []float64{ 0, (1. + 2.) / 2., 0, (1. + 2.) / 2., 0, 1. / 2., 0, 1. / 2., 0, @@ -43,7 +43,7 @@ var directedGraphs = []struct { }, absent: 1, merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Sqrt(x * y) }, - want: mat64.NewSymDense(3, []float64{ + want: mat.NewSymDense(3, []float64{ 0, math.Sqrt(1 * 2), 0, math.Sqrt(1 * 2), 0, math.Sqrt(1 * 1), 0, math.Sqrt(1 * 1), 0, @@ -57,7 +57,7 @@ var directedGraphs = []struct { {F: simple.Node(1), T: simple.Node(2), W: 1}, }, merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Min(x, y) }, - want: mat64.NewSymDense(3, []float64{ + want: mat.NewSymDense(3, []float64{ 0, math.Min(1, 2), 0, math.Min(1, 2), 0, math.Min(1, 0), 0, math.Min(1, 0), 0, @@ -79,7 +79,7 @@ var directedGraphs = []struct { } return math.Min(x, y) }, - want: mat64.NewSymDense(3, []float64{ + want: mat.NewSymDense(3, []float64{ 0, math.Min(1, 2), 0, math.Min(1, 2), 0, 1, 0, 1, 0, @@ -93,7 +93,7 @@ var directedGraphs = []struct { {F: simple.Node(1), T: simple.Node(2), W: 1}, }, merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Max(x, y) }, - want: mat64.NewSymDense(3, []float64{ + want: mat.NewSymDense(3, []float64{ 0, math.Max(1, 2), 0, math.Max(1, 2), 0, math.Max(1, 0), 0, math.Max(1, 0), 0, @@ -116,10 +116,10 @@ func TestUndirect(t *testing.T) { } } - if !mat64.Equal(dst.Matrix(), test.want) { + if !mat.Equal(dst.Matrix(), test.want) { t.Errorf("unexpected result:\ngot:\n%.4v\nwant:\n%.4v", - mat64.Formatted(dst.Matrix()), - mat64.Formatted(test.want), + mat.Formatted(dst.Matrix()), + mat.Formatted(test.want), ) } } diff --git a/matrix/README.md b/mat/README.md similarity index 100% rename from matrix/README.md rename to mat/README.md diff --git a/matrix/mat64/cblas_test.go b/mat/cblas_test.go similarity index 95% rename from matrix/mat64/cblas_test.go rename to mat/cblas_test.go index 222a5a32..7371e8ba 100644 --- a/matrix/mat64/cblas_test.go +++ b/mat/cblas_test.go @@ -4,7 +4,7 @@ //+build cblas -package mat64 +package mat import ( "gonum.org/v1/gonum/blas/blas64" diff --git a/matrix/mat64/cholesky.go b/mat/cholesky.go similarity index 92% rename from matrix/mat64/cholesky.go rename to mat/cholesky.go index dca84072..4cfd7e34 100644 --- a/matrix/mat64/cholesky.go +++ b/mat/cholesky.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Based on the CholeskyDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "math" @@ -11,7 +11,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) const ( @@ -48,8 +47,8 @@ func (c *Cholesky) updateCond(norm float64) { // the condition number somewhat. // The norm of the original factorized matrix cannot be stored because of // update possibilities. - unorm := lapack64.Lantr(matrix.CondNorm, c.chol.mat, work) - lnorm := lapack64.Lantr(matrix.CondNormTrans, c.chol.mat, work) + unorm := lapack64.Lantr(CondNorm, c.chol.mat, work) + lnorm := lapack64.Lantr(CondNormTrans, c.chol.mat, work) norm = unorm * lnorm } sym := c.chol.asSymBlas() @@ -65,15 +64,15 @@ func (c *Cholesky) updateCond(norm float64) { func (c *Cholesky) Factorize(a Symmetric) (ok bool) { n := a.Symmetric() if c.isZero() { - c.chol = NewTriDense(n, matrix.Upper, nil) + c.chol = NewTriDense(n, Upper, nil) } else { - c.chol = NewTriDense(n, matrix.Upper, use(c.chol.mat.Data, n*n)) + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) } copySymIntoTriangle(c.chol, a) sym := c.chol.asSymBlas() work := getFloats(c.chol.mat.N, false) - norm := lapack64.Lansy(matrix.CondNorm, sym, work) + norm := lapack64.Lansy(CondNorm, sym, work) putFloats(work) _, ok = lapack64.Potrf(sym) if ok { @@ -98,13 +97,13 @@ func (c *Cholesky) Reset() { // not stored inside, the receiver. func (c *Cholesky) SetFromU(t *TriDense) { n, kind := t.Triangle() - if kind != matrix.Upper { + if kind != Upper { panic("cholesky: matrix must be upper triangular") } if c.isZero() { - c.chol = NewTriDense(n, matrix.Upper, nil) + c.chol = NewTriDense(n, Upper, nil) } else { - c.chol = NewTriDense(n, matrix.Upper, use(c.chol.mat.Data, n*n)) + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) } c.chol.Copy(t) c.updateCond(-1) @@ -119,9 +118,9 @@ func (c *Cholesky) Clone(chol *Cholesky) { } n := chol.Size() if c.isZero() { - c.chol = NewTriDense(n, matrix.Upper, nil) + c.chol = NewTriDense(n, Upper, nil) } else { - c.chol = NewTriDense(n, matrix.Upper, use(c.chol.mat.Data, n*n)) + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) } c.chol.Copy(chol.chol) c.cond = chol.cond @@ -164,7 +163,7 @@ func (m *Dense) SolveCholesky(chol *Cholesky, b Matrix) error { n := chol.chol.mat.N bm, bn := b.Dims() if n != bm { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(bm, bn) @@ -173,8 +172,8 @@ func (m *Dense) SolveCholesky(chol *Cholesky, b Matrix) error { } blas64.Trsm(blas.Left, blas.Trans, 1, chol.chol.mat, m.mat) blas64.Trsm(blas.Left, blas.NoTrans, 1, chol.chol.mat, m.mat) - if chol.cond > matrix.ConditionTolerance { - return matrix.Condition(chol.cond) + if chol.cond > ConditionTolerance { + return Condition(chol.cond) } return nil } @@ -188,7 +187,7 @@ func (m *Dense) solveTwoChol(a, b *Cholesky) error { } bn := b.chol.mat.N if a.chol.mat.N != bn { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAsZeroed(bn, bn) @@ -196,8 +195,8 @@ func (m *Dense) solveTwoChol(a, b *Cholesky) error { blas64.Trsm(blas.Left, blas.Trans, 1, a.chol.mat, m.mat) blas64.Trsm(blas.Left, blas.NoTrans, 1, a.chol.mat, m.mat) blas64.Trmm(blas.Right, blas.NoTrans, 1, b.chol.mat, m.mat) - if a.cond > matrix.ConditionTolerance { - return matrix.Condition(a.cond) + if a.cond > ConditionTolerance { + return Condition(a.cond) } return nil } @@ -211,7 +210,7 @@ func (v *Vector) SolveCholeskyVec(chol *Cholesky, b *Vector) error { n := chol.chol.mat.N vn := b.Len() if vn != n { - panic(matrix.ErrShape) + panic(ErrShape) } if v != b { v.checkOverlap(b.mat) @@ -222,8 +221,8 @@ func (v *Vector) SolveCholeskyVec(chol *Cholesky, b *Vector) error { } blas64.Trsv(blas.Trans, chol.chol.mat, v.mat) blas64.Trsv(blas.NoTrans, chol.chol.mat, v.mat) - if chol.cond > matrix.ConditionTolerance { - return matrix.Condition(chol.cond) + if chol.cond > ConditionTolerance { + return Condition(chol.cond) } return nil @@ -237,7 +236,7 @@ func (t *TriDense) UFromCholesky(chol *Cholesky) { panic(badCholesky) } n := chol.chol.mat.N - t.reuseAs(n, matrix.Upper) + t.reuseAs(n, Upper) t.Copy(chol.chol) } @@ -249,7 +248,7 @@ func (t *TriDense) LFromCholesky(chol *Cholesky) { panic(badCholesky) } n := chol.chol.mat.N - t.reuseAs(n, matrix.Lower) + t.reuseAs(n, Lower) t.Copy(chol.chol.TTri()) } @@ -307,13 +306,13 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x *Vector) (ok bool } n := orig.Size() if x.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } if orig != c { if c.isZero() { - c.chol = NewTriDense(n, matrix.Upper, nil) + c.chol = NewTriDense(n, Upper, nil) } else if c.chol.mat.N != n { - panic(matrix.ErrShape) + panic(ErrShape) } c.chol.Copy(orig.chol) } diff --git a/matrix/mat64/cholesky_example_test.go b/mat/cholesky_example_test.go similarity index 71% rename from matrix/mat64/cholesky_example_test.go rename to mat/cholesky_example_test.go index 4249474b..7bbaf5af 100644 --- a/matrix/mat64/cholesky_example_test.go +++ b/mat/cholesky_example_test.go @@ -2,29 +2,29 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64_test +package mat_test import ( "fmt" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleCholesky() { // Construct a symmetric positive definite matrix. - tmp := mat64.NewDense(4, 4, []float64{ + tmp := mat.NewDense(4, 4, []float64{ 2, 6, 8, -4, 1, 8, 7, -2, 2, 2, 1, 7, 8, -2, -2, 1, }) - var a mat64.SymDense + var a mat.SymDense a.SymOuterK(1, tmp) - fmt.Printf("a = %0.4v\n", mat64.Formatted(&a, mat64.Prefix(" "))) + fmt.Printf("a = %0.4v\n", mat.Formatted(&a, mat.Prefix(" "))) // Compute the cholesky factorization. - var chol mat64.Cholesky + var chol mat.Cholesky if ok := chol.Factorize(&a); !ok { fmt.Println("a matrix is not positive semi-definite.") } @@ -33,21 +33,21 @@ 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 := mat64.NewVector(4, []float64{1, 2, 3, 4}) - var x mat64.Vector + b := mat.NewVector(4, []float64{1, 2, 3, 4}) + var x mat.Vector if err := x.SolveCholeskyVec(&chol, b); err != nil { fmt.Println("Matrix is near singular: ", err) } fmt.Println("Solve a * x = b") - fmt.Printf("x = %0.4v\n", mat64.Formatted(&x, mat64.Prefix(" "))) + fmt.Printf("x = %0.4v\n", mat.Formatted(&x, mat.Prefix(" "))) // Extract the factorization and check that it equals the original matrix. - var t mat64.TriDense + var t mat.TriDense t.LFromCholesky(&chol) - var test mat64.Dense + var test mat.Dense test.Mul(&t, t.T()) fmt.Println() - fmt.Printf("L * L^T = %0.4v\n", mat64.Formatted(&a, mat64.Prefix(" "))) + fmt.Printf("L * L^T = %0.4v\n", mat.Formatted(&a, mat.Prefix(" "))) // Output: // a = ⎡120 114 -4 -16⎤ @@ -70,35 +70,35 @@ func ExampleCholesky() { } func ExampleCholeskySymRankOne() { - a := mat64.NewSymDense(4, []float64{ + a := mat.NewSymDense(4, []float64{ 1, 1, 1, 1, 0, 2, 3, 4, 0, 0, 6, 10, 0, 0, 0, 20, }) - fmt.Printf("A = %0.4v\n", mat64.Formatted(a, mat64.Prefix(" "))) + fmt.Printf("A = %0.4v\n", mat.Formatted(a, mat.Prefix(" "))) // Compute the Cholesky factorization. - var chol mat64.Cholesky + var chol mat.Cholesky if ok := chol.Factorize(a); !ok { fmt.Println("matrix a is not positive definite.") } - x := mat64.NewVector(4, []float64{0, 0, 0, 1}) - fmt.Printf("\nx = %0.4v\n", mat64.Formatted(x, mat64.Prefix(" "))) + x := mat.NewVector(4, []float64{0, 0, 0, 1}) + fmt.Printf("\nx = %0.4v\n", mat.Formatted(x, mat.Prefix(" "))) // Rank-1 update the factorization. chol.SymRankOne(&chol, 1, x) // Rank-1 update the matrix a. a.SymRankOne(a, 1, x) - var au mat64.SymDense + var au mat.SymDense au.FromCholesky(&chol) // Print the matrix that was updated directly. - fmt.Printf("\nA' = %0.4v\n", mat64.Formatted(a, mat64.Prefix(" "))) + fmt.Printf("\nA' = %0.4v\n", mat.Formatted(a, mat.Prefix(" "))) // Print the matrix recovered from the factorization. - fmt.Printf("\nU'^T * U' = %0.4v\n", mat64.Formatted(&au, mat64.Prefix(" "))) + fmt.Printf("\nU'^T * U' = %0.4v\n", mat.Formatted(&au, mat.Prefix(" "))) // Output: // A = ⎡ 1 1 1 1⎤ diff --git a/matrix/mat64/cholesky_test.go b/mat/cholesky_test.go similarity index 99% rename from matrix/mat64/cholesky_test.go rename to mat/cholesky_test.go index 2d64e95b..8fbfd118 100644 --- a/matrix/mat64/cholesky_test.go +++ b/mat/cholesky_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" @@ -10,7 +10,6 @@ import ( "testing" "gonum.org/v1/gonum/blas/testblas" - "gonum.org/v1/gonum/matrix" ) func TestCholesky(t *testing.T) { @@ -269,7 +268,7 @@ func TestCloneCholesky(t *testing.T) { // Corrupt chol2 and try again chol2.cond = math.NaN() - chol2.chol = NewTriDense(2, matrix.Upper, nil) + chol2.chol = NewTriDense(2, Upper, nil) chol2.Clone(&chol) if chol.cond != chol2.cond { t.Errorf("condition number mismatch from non-zero") diff --git a/matrix/cmat128/matrix.go b/mat/cmatrix.go similarity index 85% rename from matrix/cmat128/matrix.go rename to mat/cmatrix.go index cfe5ec80..a2894237 100644 --- a/matrix/cmat128/matrix.go +++ b/mat/cmatrix.go @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package cmat128 +package mat -// Matrix is the basic matrix interface type. -type Matrix interface { +// CMatrix is the basic matrix interface type for complex matrices. +type CMatrix interface { // Dims returns the dimensions of a Matrix. Dims() (r, c int) @@ -17,11 +17,11 @@ type Matrix interface { // returns a copy of the underlying data is implementation dependent. // This method may be implemented using the Conjugate type, which // provides an implicit matrix conjugate transpose. - H() Matrix + H() CMatrix } var ( - _ Matrix = Conjugate{} + _ CMatrix = Conjugate{} _ Unconjugator = Conjugate{} ) @@ -29,13 +29,13 @@ var ( // It implements the Matrix interface, returning values from the conjugate // transpose of the matrix within. type Conjugate struct { - Matrix Matrix + CMatrix CMatrix } // At returns the value of the element at row i and column j of the transposed // matrix, that is, row j and column i of the Matrix field. func (t Conjugate) At(i, j int) complex128 { - z := t.Matrix.At(j, i) + z := t.CMatrix.At(j, i) return complex(real(z), -imag(z)) } @@ -43,18 +43,18 @@ func (t Conjugate) At(i, j int) complex128 { // is the number of columns in the Matrix field, and the number of columns is // the number of rows in the Matrix field. func (t Conjugate) Dims() (r, c int) { - c, r = t.Matrix.Dims() + c, r = t.CMatrix.Dims() return r, c } // H performs an implicit conjugate transpose by returning the Matrix field. -func (t Conjugate) H() Matrix { - return t.Matrix +func (t Conjugate) H() CMatrix { + return t.CMatrix } // Unconjugate returns the Matrix field. -func (t Conjugate) Unconjugate() Matrix { - return t.Matrix +func (t Conjugate) Unconjugate() CMatrix { + return t.CMatrix } // Unconjugator is a type that can undo an implicit conjugate transpose. @@ -67,5 +67,5 @@ type Unconjugator interface { // Unconjugate returns the underlying Matrix stored for the implicit // conjugate transpose. - Unconjugate() Matrix + Unconjugate() CMatrix } diff --git a/matrix/consts.go b/mat/consts.go similarity index 99% rename from matrix/consts.go rename to mat/consts.go index b288b272..a7025fff 100644 --- a/matrix/consts.go +++ b/mat/consts.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package matrix +package mat // TriKind represents the triangularity of the matrix. type TriKind bool diff --git a/matrix/mat64/dense.go b/mat/dense.go similarity index 96% rename from matrix/mat64/dense.go rename to mat/dense.go index b48d6a3b..ed0c653a 100644 --- a/matrix/mat64/dense.go +++ b/mat/dense.go @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) var ( @@ -45,7 +44,7 @@ type Dense struct { // element in the data slice is the {i, j}-th element in the matrix. func NewDense(r, c int, data []float64) *Dense { if data != nil && r*c != len(data) { - panic(matrix.ErrShape) + panic(ErrShape) } if data == nil { data = make([]float64, r*c) @@ -83,7 +82,7 @@ func (m *Dense) reuseAs(r, c int) { return } if r != m.mat.Rows || c != m.mat.Cols { - panic(matrix.ErrShape) + panic(ErrShape) } } @@ -109,7 +108,7 @@ func (m *Dense) reuseAsZeroed(r, c int) { return } if r != m.mat.Rows || c != m.mat.Cols { - panic(matrix.ErrShape) + panic(ErrShape) } for i := 0; i < r; i++ { zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]) @@ -206,7 +205,7 @@ func (m *Dense) T() Matrix { // See ColViewer for more information. func (m *Dense) ColView(j int) *Vector { if j >= m.mat.Cols || j < 0 { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return &Vector{ mat: blas64.Vector{ @@ -221,10 +220,10 @@ func (m *Dense) ColView(j int) *Vector { // in src. len(src) must equal the number of rows in the receiver. func (m *Dense) SetCol(j int, src []float64) { if j >= m.mat.Cols || j < 0 { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } if len(src) != m.mat.Rows { - panic(matrix.ErrColLength) + panic(ErrColLength) } blas64.Copy(m.mat.Rows, @@ -237,10 +236,10 @@ func (m *Dense) SetCol(j int, src []float64) { // in src. len(src) must equal the number of columns in the receiver. func (m *Dense) SetRow(i int, src []float64) { if i >= m.mat.Rows || i < 0 { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if len(src) != m.mat.Cols { - panic(matrix.ErrRowLength) + panic(ErrRowLength) } copy(m.rawRowView(i), src) @@ -252,7 +251,7 @@ func (m *Dense) SetRow(i int, src []float64) { // See RowViewer for more information. func (m *Dense) RowView(i int) *Vector { if i >= m.mat.Rows || i < 0 { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } return &Vector{ mat: blas64.Vector{ @@ -267,7 +266,7 @@ func (m *Dense) RowView(i int) *Vector { // receiver. func (m *Dense) RawRowView(i int) []float64 { if i >= m.mat.Rows || i < 0 { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } return m.rawRowView(i) } @@ -294,7 +293,7 @@ func (m *Dense) View(i, j, r, c int) Matrix { func (m *Dense) Slice(i, k, j, l int) Matrix { mr, mc := m.Dims() if i < 0 || mr <= i || j < 0 || mc <= j || k <= i || mr < k || l <= j || mc < l { - panic(matrix.ErrIndexOutOfRange) + panic(ErrIndexOutOfRange) } t := *m t.mat.Data = t.mat.Data[i*t.mat.Stride+j : (k-1)*t.mat.Stride+l] @@ -311,7 +310,7 @@ func (m *Dense) Slice(i, k, j, l int) Matrix { // during the call to Grow. func (m *Dense) Grow(r, c int) Matrix { if r < 0 || c < 0 { - panic(matrix.ErrIndexOutOfRange) + panic(ErrIndexOutOfRange) } if r == 0 && c == 0 { return m @@ -514,7 +513,7 @@ func (m *Dense) Stack(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ac != bc || m == a || m == b { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(ar+br, ac) @@ -532,7 +531,7 @@ func (m *Dense) Augment(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ar != br || m == a || m == b { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(ar, ac+bc) diff --git a/matrix/mat64/dense_arithmetic.go b/mat/dense_arithmetic.go similarity index 96% rename from matrix/mat64/dense_arithmetic.go rename to mat/dense_arithmetic.go index bc7945f3..0b0a8956 100644 --- a/matrix/mat64/dense_arithmetic.go +++ b/mat/dense_arithmetic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" @@ -10,7 +10,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // Add adds a and b element-wise, placing the result in the receiver. Add @@ -19,7 +18,7 @@ func (m *Dense) Add(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ar != br || ac != bc { - panic(matrix.ErrShape) + panic(ErrShape) } aU, _ := untranspose(a) @@ -66,7 +65,7 @@ func (m *Dense) Sub(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ar != br || ac != bc { - panic(matrix.ErrShape) + panic(ErrShape) } aU, _ := untranspose(a) @@ -114,7 +113,7 @@ func (m *Dense) MulElem(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ar != br || ac != bc { - panic(matrix.ErrShape) + panic(ErrShape) } aU, _ := untranspose(a) @@ -162,7 +161,7 @@ func (m *Dense) DivElem(a, b Matrix) { ar, ac := a.Dims() br, bc := b.Dims() if ar != br || ac != bc { - panic(matrix.ErrShape) + panic(ErrShape) } aU, _ := untranspose(a) @@ -211,7 +210,7 @@ func (m *Dense) Inverse(a Matrix) error { // TODO(btracey): Special case for RawTriangular, etc. r, c := a.Dims() if r != c { - panic(matrix.ErrSquare) + panic(ErrSquare) } m.reuseAs(a.Dims()) aU, aTrans := untranspose(a) @@ -234,7 +233,7 @@ func (m *Dense) Inverse(a Matrix) error { defer putInts(ipiv) ok := lapack64.Getrf(m.mat, ipiv) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } work := getFloats(4*r, false) // must be at least 4*r for cond. lapack64.Getri(m.mat, ipiv, work, -1) @@ -247,14 +246,14 @@ func (m *Dense) Inverse(a Matrix) error { } defer putFloats(work) lapack64.Getri(m.mat, ipiv, work, len(work)) - norm := lapack64.Lange(matrix.CondNorm, m.mat, work) - rcond := lapack64.Gecon(matrix.CondNorm, m.mat, norm, work, ipiv) // reuse ipiv + norm := lapack64.Lange(CondNorm, m.mat, work) + rcond := lapack64.Gecon(CondNorm, m.mat, norm, work, ipiv) // reuse ipiv if rcond == 0 { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } cond := 1 / rcond - if cond > matrix.ConditionTolerance { - return matrix.Condition(cond) + if cond > ConditionTolerance { + return Condition(cond) } return nil } @@ -266,7 +265,7 @@ func (m *Dense) Mul(a, b Matrix) { br, bc := b.Dims() if ac != br { - panic(matrix.ErrShape) + panic(ErrShape) } aU, aTrans := untranspose(a) @@ -452,7 +451,7 @@ func strictCopy(m *Dense, a Matrix) { if r != m.mat.Rows || c != m.mat.Cols { // Panic with a string since this // is not a user-facing panic. - panic(matrix.ErrShape.Error()) + panic(ErrShape.Error()) } } @@ -464,7 +463,7 @@ func strictCopy(m *Dense, a Matrix) { func (m *Dense) Exp(a Matrix) { r, c := a.Dims() if r != c { - panic(matrix.ErrShape) + panic(ErrShape) } var w *Dense @@ -530,7 +529,7 @@ func (m *Dense) Pow(a Matrix, n int) { } r, c := a.Dims() if r != c { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(r, c) @@ -657,10 +656,10 @@ func (m *Dense) Apply(fn func(i, j int, v float64) float64, a Matrix) { func (m *Dense) RankOne(a Matrix, alpha float64, x, y *Vector) { ar, ac := a.Dims() if x.Len() != ar { - panic(matrix.ErrShape) + panic(ErrShape) } if y.Len() != ac { - panic(matrix.ErrShape) + panic(ErrShape) } m.checkOverlap(x.asGeneral()) @@ -707,7 +706,7 @@ func (m *Dense) Outer(alpha float64, x, y *Vector) { m.capRows = r m.capCols = c } else if r != m.mat.Rows || c != m.mat.Cols { - panic(matrix.ErrShape) + panic(ErrShape) } else { m.checkOverlap(x.asGeneral()) m.checkOverlap(y.asGeneral()) diff --git a/matrix/mat64/dense_test.go b/mat/dense_test.go similarity index 99% rename from matrix/mat64/dense_test.go rename to mat/dense_test.go index 3e2303ea..2c680c0f 100644 --- a/matrix/mat64/dense_test.go +++ b/mat/dense_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" @@ -13,7 +13,6 @@ import ( "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) func asBasicMatrix(d *Dense) Matrix { return (*basicMatrix)(d) } @@ -188,13 +187,13 @@ func TestAtSet(t *testing.T) { // Check access out of bounds fails for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { m.At(row, 0) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { m.At(0, col) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } @@ -202,13 +201,13 @@ func TestAtSet(t *testing.T) { // Check Set out of bounds for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { m.Set(row, 0, 1.2) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { m.Set(0, col, 1.2) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } @@ -293,13 +292,13 @@ func TestRowColView(t *testing.T) { for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { m.At(row, 0) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access rows=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { m.At(0, col) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access cols=%d c=%d", cols, col) } } @@ -870,7 +869,7 @@ func TestMul(t *testing.T) { func randDense(size int, rho float64, rnd func() float64) (*Dense, error) { if size == 0 { - return nil, matrix.ErrZeroLength + return nil, ErrZeroLength } d := &Dense{ mat: blas64.General{ diff --git a/matrix/mat64/doc.go b/mat/doc.go similarity index 68% rename from matrix/mat64/doc.go rename to mat/doc.go index 833339a0..2001a7bd 100644 --- a/matrix/mat64/doc.go +++ b/mat/doc.go @@ -1,29 +1,26 @@ -// Generated by running -// go generate github.com/gonum/matrix -// DO NOT EDIT. - // Copyright ©2015 The gonum Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package mat64 provides implementations of float64 matrix structures and -// linear algebra operations on them. +// Package mat provides implementations of float64 and complex128 matrix +// structures and linear algebra operations on them. // // Overview // -// This section provides a quick overview of the mat64 package. The following +// This section provides a quick overview of the mat package. The following // sections provide more in depth commentary. // -// mat64 provides: +// mat provides: // - Interfaces for Matrix classes (Matrix, Symmetric, Triangular) // - Concrete implementations (Dense, SymDense, TriDense) // - Methods and functions for using matrix data (Add, Trace, SymRankOne) // - Types for constructing and using matrix factorizations (QR, LU) +// - The complementary types for complex matrices, CMatrix, CSymDense, etc. // // A matrix may be constructed through the corresponding New function. If no // backing array is provided the matrix will be initialized to all zeros. -// // Allocate a zeroed matrix of size 3×5 -// zero := mat64.NewDense(3, 5, nil) +// // Allocate a zeroed real matrix of size 3×5 +// zero := mat.NewDense(3, 5, nil) // If a backing data slice is provided, the matrix will have those elements. // Matrices are all stored in row-major format. // // Generate a 6×6 matrix of random values. @@ -32,7 +29,6 @@ // data[i] = rand.NormFloat64() // } // a := mat64.NewDense(6, 6, data) -// // Operations involving matrix data are implemented as functions when the values // of the matrix remain unchanged // tr := mat64.Trace(a) @@ -42,17 +38,17 @@ // Receivers must be the correct size for the matrix operations, otherwise the // operation will panic. As a special case for convenience, a zero-sized matrix // will be modified to have the correct size, allocating data if necessary. -// var c mat64.Dense // construct a new zero-sized matrix +// var c mat.Dense // construct a new zero-sized matrix // c.Mul(a, a) // c is automatically adjusted to be 6×6 // // The Matrix Interfaces // -// The Matrix interface is the common link between the concrete types. The Matrix -// interface is defined by three functions: Dims, which returns the dimensions -// of the Matrix, At, which returns the element in the specified location, and -// T for returning a Transpose (discussed later). All of the concrete types can -// perform these behaviors and so implement the interface. Methods and functions -// are designed to use this interface, so in particular the method +// The Matrix interface is the common link between the concrete types of real +// matrices, The Matrix interface is defined by three functions: Dims, which +// returns the dimensions of the Matrix, At, which returns the element in the +// specified location, and T for returning a Transpose (discussed later). All of +// the concrete types can perform these behaviors and so implement the interface. +// Methods and functions are designed to use this interface, so in particular the method // func (m *Dense) Mul(a, b Matrix) // constructs a *Dense from the result of a multiplication with any Matrix types, // not just *Dense. Where more restrictive requirements must be met, there are also the @@ -60,12 +56,17 @@ // func (s *SymDense) AddSym(a, b Symmetric) // the Symmetric interface guarantees a symmetric result. // -// Transposes +// The CMatrix interface plays the same role for complex matrices. The difference +// is that the CMatrix type has the H method instead T, for returning the conjugate +// transpose. // -// The T method is used for transposition. For example, c.Mul(a.T(), b) computes -// c = a^T * b. The mat64 types implement this method using an implicit transpose — -// see the Transpose type for more details. Note that some operations have a -// transpose as part of their definition, as in *SymDense.SymOuterK. +// (Conjugate) Transposes +// +// The T method is used for transposition on real matrices, and H is used for +// conjugate transposition on complex matrices. For example, c.Mul(a.T(), b) computes +// c = a^T * b. The mat types implement this method implicitly — +// see the Transpose and Conjugate types for more details. Note that some +// operations have a transpose as part of their definition, as in *SymDense.SymOuterK. // // Matrix Factorization // @@ -75,19 +76,20 @@ // var lu mat64.LU // lu.Factorize(a) // The elements of the factorization can be extracted through methods on the -// appropriate type, i.e. *TriDense.LFromLU and *TriDense.UFromLU. Alternatively, -// they can be used directly, as in *Dense.SolveLU. Some factorizations can be -// updated directly, without needing to update the original matrix and refactorize, +// factorized type, i.e. *LU.UTo. The factorization types can also be used directly, +// as in *Dense.SolveCholesky. Some factorizations can be updated directly, +// without needing to update the original matrix and refactorize, // as in *LU.RankOne. // // BLAS and LAPACK // // BLAS and LAPACK are the standard APIs for linear algebra routines. Many -// operations in mat64 are implemented using calls to the wrapper functions -// in gonum/blas/blas64 and gonum/lapack/lapack64. By default, blas64 and -// lapack64 call the native Go implementations of the routines. Alternatively, -// it is possible to use C-based implementations of the APIs through the respective -// cgo packages and "Use" functions. The Go implementation of LAPACK makes calls +// operations in mat are implemented using calls to the wrapper functions +// in gonum/blas/blas64 and gonum/lapack/lapack64 and their complex equivalents. +// By default, blas64 and lapack64 call the native Go implementations of the +// routines. Alternatively, it is possible to use C-based implementations of the +// APIs through the respective cgo packages and "Use" functions. The Go +// implementation of LAPACK (used by default) makes calls // through blas64, so if a cgo BLAS implementation is registered, the lapack64 // calls will be partially executed in Go and partially executed in C. // @@ -121,7 +123,7 @@ // // Element Aliasing // -// Most methods in mat64 modify receiver data. It is forbidden for the modified +// Most methods in mat modify receiver data. It is forbidden for the modified // data region of the receiver to overlap the used data area of the input // arguments. The exception to this rule is when the method receiver is equal to one // of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose. @@ -136,7 +138,7 @@ // your program, you are being clever. Don't be clever. If you must be clever, // blas64 and lapack64 may be used to call the behavior directly. // -// mat64 will use the following rules to detect overlap between the receiver and one +// mat will use the following rules to detect overlap between the receiver and one // of the inputs: // - the input implements one of the Raw methods, and // - the Raw type matches that of the receiver or @@ -150,9 +152,9 @@ // - there is pointer identity between the receiver and input values after // the value has been untransposed if necessary. // -// mat64 will not attempt to detect element overlap if the input does not implement a +// mat will not attempt to detect element overlap if the input does not implement a // Raw method, or if the Raw method differs from that of the receiver except when a -// conversion has occurred through a mat64 API function. Method behavior is undefined +// conversion has occurred through a mat API function. Method behavior is undefined // if there is undetected overlap. // -package mat64 // import "gonum.org/v1/gonum/matrix/mat64" +package mat // import "gonum.org/v1/gonum/mat" diff --git a/matrix/mat64/eigen.go b/mat/eigen.go similarity index 98% rename from matrix/mat64/eigen.go rename to mat/eigen.go index 08652864..45938233 100644 --- a/matrix/mat64/eigen.go +++ b/mat/eigen.go @@ -3,12 +3,11 @@ // license that can be found in the LICENSE file. // Based on the EigenvalueDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) const ( @@ -82,7 +81,7 @@ func (e *EigenSym) Values(dst []float64) []float64 { dst = make([]float64, len(e.values)) } if len(dst) != len(e.values) { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } copy(dst, e.values) return dst @@ -149,7 +148,7 @@ func (e *Eigen) Factorize(a Matrix, left, right bool) (ok bool) { // Copy a because it is modified during the Lapack call. r, c := a.Dims() if r != c { - panic(matrix.ErrShape) + panic(ErrShape) } var sd Dense sd.Clone(a) @@ -209,7 +208,7 @@ func (e *Eigen) Values(dst []complex128) []complex128 { dst = make([]complex128, e.n) } if len(dst) != e.n { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } copy(dst, e.values) return dst diff --git a/matrix/mat64/eigen_test.go b/mat/eigen_test.go similarity index 99% rename from matrix/mat64/eigen_test.go rename to mat/eigen_test.go index 83a3acdc..55234ebf 100644 --- a/matrix/mat64/eigen_test.go +++ b/mat/eigen_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" diff --git a/matrix/errors.go b/mat/errors.go similarity index 99% rename from matrix/errors.go rename to mat/errors.go index ea0f92c9..131307d6 100644 --- a/matrix/errors.go +++ b/mat/errors.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package matrix +package mat import ( "fmt" diff --git a/matrix/errors_test.go b/mat/errors_test.go similarity index 98% rename from matrix/errors_test.go rename to mat/errors_test.go index c144a2e6..7a1a7dd7 100644 --- a/matrix/errors_test.go +++ b/mat/errors_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package matrix +package mat import "testing" diff --git a/matrix/mat64/fao_data_test.go b/mat/fao_data_test.go similarity index 91% rename from matrix/mat64/fao_data_test.go rename to mat/fao_data_test.go index 1b01387f..e32e1676 100644 --- a/matrix/mat64/fao_data_test.go +++ b/mat/fao_data_test.go @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64_test +package mat_test -import "gonum.org/v1/gonum/matrix/mat64" +import "gonum.org/v1/gonum/mat" // FAO is a dataset extracted from Food and Agriculture Organization of the // United Nations "FAO Statistical Pocketbook: World Food and Agriculture 2015". // pp49-52. var FAO = struct { - Africa *mat64.Dense - Asia *mat64.Dense - LatinAmericaCaribbean *mat64.Dense - Oceania *mat64.Dense + Africa *mat.Dense + Asia *mat.Dense + LatinAmericaCaribbean *mat.Dense + Oceania *mat.Dense }{ - Africa: mat64.NewDense(21, 3, []float64{ + Africa: mat.NewDense(21, 3, []float64{ // 1990, 2000, 2014 35.3, 38, 30.7, // Employment in agriculture (%) 9.2, 20.3, 25.2, // Employment in agriculture, female (%) @@ -43,7 +43,7 @@ var FAO = struct { 72, 92, 119, // Fish }), - Asia: mat64.NewDense(21, 3, []float64{ + Asia: mat.NewDense(21, 3, []float64{ // 1990, 2000, 2014 30.9, 24.5, 27.6, // Employment in agriculture (%) 40.9, 29.4, 31.1, // Employment in agriculture, female (%) @@ -71,7 +71,7 @@ var FAO = struct { 65, 90, 119, // Fish }), - LatinAmericaCaribbean: mat64.NewDense(14, 3, []float64{ + LatinAmericaCaribbean: mat.NewDense(14, 3, []float64{ // 1990, 2000, 2014 19.5, 14.2, 15.8, // Employment in agriculture (%) 13.7, 6.2, 7.6, // Employment in agriculture, female (%) @@ -92,7 +92,7 @@ var FAO = struct { 82, 107, 71, // Fish }), - Oceania: mat64.NewDense(21, 3, []float64{ + Oceania: mat.NewDense(21, 3, []float64{ // 1990, 2000, 2014 6.2, 17.1, 3.8, // Employment in agriculture (%) 4.5, 3.9, 4.4, // Employment in agriculture, female (%) diff --git a/matrix/mat64/format.go b/mat/format.go similarity index 99% rename from matrix/mat64/format.go rename to mat/format.go index 5d01247d..8ab70ed3 100644 --- a/matrix/mat64/format.go +++ b/mat/format.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" diff --git a/matrix/mat64/format_example_test.go b/mat/format_example_test.go similarity index 84% rename from matrix/mat64/format_example_test.go rename to mat/format_example_test.go index dc31cbcd..02a5e085 100644 --- a/matrix/mat64/format_example_test.go +++ b/mat/format_example_test.go @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64_test +package mat_test import ( "fmt" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleFormatted() { - a := mat64.NewDense(3, 3, []float64{1, 2, 3, 0, 4, 5, 0, 0, 6}) + a := mat.NewDense(3, 3, []float64{1, 2, 3, 0, 4, 5, 0, 0, 6}) // Create a matrix formatting value with a prefix and calculating each column // width individually... - fa := mat64.Formatted(a, mat64.Prefix(" "), mat64.Squeeze()) + fa := mat.Formatted(a, mat.Prefix(" "), mat.Squeeze()) // and then print with and without zero value elements. fmt.Printf("with all values:\na = %v\n\n", fa) @@ -61,27 +61,27 @@ func ExampleExcerpt() { // matrices and vectors. // The big matrix is too large to properly print... - big := mat64.NewDense(100, 100, nil) + big := mat.NewDense(100, 100, nil) for i := 0; i < 100; i++ { big.Set(i, i, 1) } // so only print corner excerpts of the matrix. fmt.Printf("excerpt big identity matrix: %v\n\n", - mat64.Formatted(big, mat64.Prefix(" "), mat64.Excerpt(3))) + mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3))) // The long vector is also too large, ... - long := mat64.NewVector(100, nil) + long := mat.NewVector(100, nil) for i := 0; i < 100; i++ { long.SetVec(i, float64(i)) } // ... so print end excerpts of the vector, fmt.Printf("excerpt long column vector: %v\n\n", - mat64.Formatted(long, mat64.Prefix(" "), mat64.Excerpt(3))) + mat.Formatted(long, mat.Prefix(" "), mat.Excerpt(3))) // or its transpose. fmt.Printf("excerpt long row vector: %v\n", - mat64.Formatted(long.T(), mat64.Prefix(" "), mat64.Excerpt(3))) + mat.Formatted(long.T(), mat.Prefix(" "), mat.Excerpt(3))) // Output: // excerpt big identity matrix: Dims(100, 100) diff --git a/matrix/mat64/format_test.go b/mat/format_test.go similarity index 75% rename from matrix/mat64/format_test.go rename to mat/format_test.go index 6ddbcf6b..2b725571 100644 --- a/matrix/mat64/format_test.go +++ b/mat/format_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" @@ -26,8 +26,8 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡0 0 0⎤\n⎢0 0 0⎥\n⎣0 0 0⎦"}, {"% f", "⎡. . .⎤\n⎢. . .⎥\n⎣. . .⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{0, 0, 0, 0, 0, 0, 0, 0, 0}}, capRows:3, capCols:3}"}, - {"%s", "%!s(*mat64.Dense=Dims(3, 3))"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{0, 0, 0, 0, 0, 0, 0, 0, 0}}, capRows:3, capCols:3}"}, + {"%s", "%!s(*mat.Dense=Dims(3, 3))"}, }, }, { @@ -35,7 +35,7 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"}, {"% f", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, }, }, { @@ -43,7 +43,7 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡1 1 1⎤\n\t⎢1 1 1⎥\n\t⎣1 1 1⎦"}, {"% f", "⎡1 1 1⎤\n\t⎢1 1 1⎥\n\t⎣1 1 1⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, }, }, { @@ -51,7 +51,7 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡1 0 0⎤\n⎢0 1 0⎥\n⎣0 0 1⎦"}, {"% f", "⎡1 . .⎤\n⎢. 1 .⎥\n⎣. . 1⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 0, 0, 0, 1, 0, 0, 0, 1}}, capRows:3, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 0, 0, 0, 1, 0, 0, 0, 1}}, capRows:3, capCols:3}"}, }, }, { @@ -59,7 +59,7 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡1 2 3⎤\n⎣4 5 6⎦"}, {"% f", "⎡1 2 3⎤\n⎣4 5 6⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:2, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:2, capCols:3}"}, }, }, { @@ -67,7 +67,7 @@ func TestFormat(t *testing.T) { []rp{ {"%v", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"}, {"% f", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:3, capCols:2}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:3, capCols:2}"}, }, }, { @@ -80,7 +80,7 @@ func TestFormat(t *testing.T) { {"%v", "⎡ 0 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"}, {"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, }, }, { @@ -93,7 +93,7 @@ func TestFormat(t *testing.T) { {"%v", "⎡ 0 1⎤\n⎢1.4142135623730951 1.7320508075688772⎥\n⎣ 2 2.23606797749979⎦"}, {"%.2f", "⎡0.00 1.00⎤\n⎢1.41 1.73⎥\n⎣2.00 2.24⎦"}, {"% f", "⎡ . 1⎤\n⎢1.4142135623730951 1.7320508075688772⎥\n⎣ 2 2.23606797749979⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:3, capCols:2}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:3, capCols:2}"}, }, }, { @@ -106,7 +106,7 @@ func TestFormat(t *testing.T) { {"%v", "⎡ 0 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"}, {"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, - {"%#v", "&mat64.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, }, }, { diff --git a/matrix/mat64/gsvd.go b/mat/gsvd.go similarity index 94% rename from matrix/mat64/gsvd.go rename to mat/gsvd.go index d2db5734..0b9bce4e 100644 --- a/matrix/mat64/gsvd.go +++ b/mat/gsvd.go @@ -3,14 +3,13 @@ // license that can be found in the LICENSE file. // Based on the SingularValueDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // GSVD is a type for creating and using the Generalized Singular Value Decomposition @@ -20,7 +19,7 @@ import ( // variable×sample spaces to reduced and diagonalized "eigenvariable"×"eigensample" // spaces. type GSVD struct { - kind matrix.GSVDKind + kind GSVDKind r, p, c, k, l int s1, s2 []float64 @@ -50,24 +49,24 @@ type GSVD struct { // // Factorize returns whether the decomposition succeeded. If the decomposition // failed, routines that require a successful factorization will panic. -func (gsvd *GSVD) Factorize(a, b Matrix, kind matrix.GSVDKind) (ok bool) { +func (gsvd *GSVD) Factorize(a, b Matrix, kind GSVDKind) (ok bool) { r, c := a.Dims() gsvd.r, gsvd.c = r, c p, c := b.Dims() gsvd.p = p if gsvd.c != c { - panic(matrix.ErrShape) + panic(ErrShape) } var jobU, jobV, jobQ lapack.GSVDJob switch { default: panic("gsvd: bad input kind") - case kind == matrix.GSVDNone: + case kind == GSVDNone: jobU = lapack.GSVDNone jobV = lapack.GSVDNone jobQ = lapack.GSVDNone - case (matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ)&kind != 0: - if matrix.GSVDU&kind != 0 { + case (GSVDU|GSVDV|GSVDQ)&kind != 0: + if GSVDU&kind != 0 { jobU = lapack.GSVDU gsvd.u = blas64.General{ Rows: r, @@ -76,7 +75,7 @@ func (gsvd *GSVD) Factorize(a, b Matrix, kind matrix.GSVDKind) (ok bool) { Data: use(gsvd.u.Data, r*r), } } - if matrix.GSVDV&kind != 0 { + if GSVDV&kind != 0 { jobV = lapack.GSVDV gsvd.v = blas64.General{ Rows: p, @@ -85,7 +84,7 @@ func (gsvd *GSVD) Factorize(a, b Matrix, kind matrix.GSVDKind) (ok bool) { Data: use(gsvd.v.Data, p*p), } } - if matrix.GSVDQ&kind != 0 { + if GSVDQ&kind != 0 { jobQ = lapack.GSVDQ gsvd.q = blas64.General{ Rows: c, @@ -119,7 +118,7 @@ func (gsvd *GSVD) Factorize(a, b Matrix, kind matrix.GSVDKind) (ok bool) { // Kind returns the matrix.GSVDKind of the decomposition. If no decomposition has been // computed, Kind returns 0. -func (gsvd *GSVD) Kind() matrix.GSVDKind { +func (gsvd *GSVD) Kind() GSVDKind { return gsvd.kind } @@ -147,7 +146,7 @@ func (gsvd *GSVD) GeneralizedValues(v []float64) []float64 { v = make([]float64, d-k) } if len(v) != d-k { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } floats.DivTo(v, gsvd.s1[k:d], gsvd.s2[k:d]) return v @@ -172,7 +171,7 @@ func (gsvd *GSVD) ValuesA(s []float64) []float64 { s = make([]float64, d-k) } if len(s) != d-k { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } copy(s, gsvd.s1[k:min(r, c)]) return s @@ -197,7 +196,7 @@ func (gsvd *GSVD) ValuesB(s []float64) []float64 { s = make([]float64, d-k) } if len(s) != d-k { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } copy(s, gsvd.s2[k:d]) return s @@ -300,7 +299,7 @@ func (gsvd *GSVD) SigmaBTo(dst *Dense) *Dense { // // UTo will panic if the receiver does not contain a successful factorization. func (gsvd *GSVD) UTo(dst *Dense) *Dense { - if gsvd.kind&matrix.GSVDU == 0 { + if gsvd.kind&GSVDU == 0 { panic("mat64: improper GSVD kind") } r := gsvd.u.Rows @@ -326,7 +325,7 @@ func (gsvd *GSVD) UTo(dst *Dense) *Dense { // // VTo will panic if the receiver does not contain a successful factorization. func (gsvd *GSVD) VTo(dst *Dense) *Dense { - if gsvd.kind&matrix.GSVDV == 0 { + if gsvd.kind&GSVDV == 0 { panic("mat64: improper GSVD kind") } r := gsvd.v.Rows @@ -352,7 +351,7 @@ func (gsvd *GSVD) VTo(dst *Dense) *Dense { // // QTo will panic if the receiver does not contain a successful factorization. func (gsvd *GSVD) QTo(dst *Dense) *Dense { - if gsvd.kind&matrix.GSVDQ == 0 { + if gsvd.kind&GSVDQ == 0 { panic("mat64: improper GSVD kind") } r := gsvd.q.Rows diff --git a/matrix/mat64/gsvd_example_test.go b/mat/gsvd_example_test.go similarity index 86% rename from matrix/mat64/gsvd_example_test.go rename to mat/gsvd_example_test.go index 6d34f712..48898ccc 100644 --- a/matrix/mat64/gsvd_example_test.go +++ b/mat/gsvd_example_test.go @@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64_test +package mat_test import ( "fmt" "log" "math" - "gonum.org/v1/gonum/matrix" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleGSVD() { @@ -19,8 +18,8 @@ func ExampleGSVD() { // // See Lee et al. doi:10.1371/journal.pone.0030098 and // Alter at al. doi:10.1073/pnas.0530258100 for more details. - var gsvd mat64.GSVD - ok := gsvd.Factorize(FAO.Africa, FAO.LatinAmericaCaribbean, matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ) + var gsvd mat.GSVD + ok := gsvd.Factorize(FAO.Africa, FAO.LatinAmericaCaribbean, mat.GSVDU|mat.GSVDV|mat.GSVDQ) if !ok { log.Fatal("GSVD factorization failed") } @@ -32,14 +31,14 @@ func ExampleGSVD() { s2 := gsvd.ValuesB(nil) fmt.Printf("Africa\n\ts1 = %.4f\n\n\tU = %.4f\n\n", - s1, mat64.Formatted(u, mat64.Prefix("\t "), mat64.Excerpt(2))) + s1, mat.Formatted(u, mat.Prefix("\t "), mat.Excerpt(2))) fmt.Printf("Latin America/Caribbean\n\ts2 = %.4f\n\n\tV = %.4f\n", - s2, mat64.Formatted(v, mat64.Prefix("\t "), mat64.Excerpt(2))) + s2, mat.Formatted(v, mat.Prefix("\t "), mat.Excerpt(2))) - var q mat64.Dense + var q mat.Dense q.Mul(gsvd.ZeroRTo(nil), gsvd.QTo(nil)) fmt.Printf("\nCommon basis vectors\n\n\tQ^T = %.4f\n", - mat64.Formatted(q.T(), mat64.Prefix("\t "))) + mat.Formatted(q.T(), mat.Prefix("\t "))) // Calculate the antisymmetric angular distances for each eigenvariable. fmt.Println("\nSignificance:") diff --git a/matrix/mat64/gsvd_test.go b/mat/gsvd_test.go similarity index 94% rename from matrix/mat64/gsvd_test.go rename to mat/gsvd_test.go index e8b82083..6e8ef0f5 100644 --- a/matrix/mat64/gsvd_test.go +++ b/mat/gsvd_test.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) func TestGSVD(t *testing.T) { @@ -49,7 +48,7 @@ func TestGSVD(t *testing.T) { // Test Full decomposition. var gsvd GSVD - ok := gsvd.Factorize(a, b, matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ) + ok := gsvd.Factorize(a, b, GSVDU|GSVDV|GSVDQ) if !ok { t.Errorf("GSVD factorization failed") } @@ -83,7 +82,7 @@ func TestGSVD(t *testing.T) { } // Test None decomposition. - ok = gsvd.Factorize(a, b, matrix.GSVDNone) + ok = gsvd.Factorize(a, b, GSVDNone) if !ok { t.Errorf("GSVD factorization failed") } diff --git a/matrix/mat64/hogsvd.go b/mat/hogsvd.go similarity index 97% rename from matrix/mat64/hogsvd.go rename to mat/hogsvd.go index 9cd6ec4f..e90a3a7a 100644 --- a/matrix/mat64/hogsvd.go +++ b/mat/hogsvd.go @@ -3,13 +3,12 @@ // license that can be found in the LICENSE file. // Based on the SingularValueDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "errors" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) // HOGSVD is a type for creating and using the Higher Order Generalized Singular Value @@ -58,14 +57,14 @@ func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) { for i, d := range m { rd, cd := d.Dims() if rd < cd { - gsvd.err = matrix.ErrShape + gsvd.err = ErrShape return false } if rd > r { r = rd } if cd != c { - panic(matrix.ErrShape) + panic(ErrShape) } ts.Reset() ts.SymOuterK(1, d.T()) @@ -187,7 +186,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 { if s == nil { s = make([]float64, c) } else if len(s) != c { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } for j := 0; j < c; j++ { s[j] = blas64.Nrm2(r, gsvd.b[n].ColView(j).mat) diff --git a/matrix/mat64/hogsvd_example_test.go b/mat/hogsvd_example_test.go similarity index 96% rename from matrix/mat64/hogsvd_example_test.go rename to mat/hogsvd_example_test.go index dfb0821f..fd07e085 100644 --- a/matrix/mat64/hogsvd_example_test.go +++ b/mat/hogsvd_example_test.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64_test +package mat_test import ( "fmt" "log" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleHOGSVD() { @@ -17,7 +17,7 @@ func ExampleHOGSVD() { // // See Ponnapalli et al. doi:10.1371/journal.pone.0028072 and // Alter at al. doi:10.1073/pnas.0530258100 for more details. - var gsvd mat64.HOGSVD + var gsvd mat.HOGSVD ok := gsvd.Factorize(FAO.Africa, FAO.Asia, FAO.LatinAmericaCaribbean, FAO.Oceania) if !ok { log.Fatal("HOGSVD factorization failed: %v", gsvd.Err()) @@ -27,12 +27,12 @@ func ExampleHOGSVD() { u := gsvd.UTo(nil, i) s := gsvd.Values(nil, i) fmt.Printf("%s\n\ts_%d = %.4f\n\n\tU_%[2]d = %.4[4]f\n", - n, i, s, mat64.Formatted(u, mat64.Prefix("\t "))) + n, i, s, mat.Formatted(u, mat.Prefix("\t "))) } v := gsvd.VTo(nil) fmt.Printf("\nCommon basis vectors\n\n\tV^T = %.4f", - mat64.Formatted(v.T(), mat64.Prefix("\t "))) + mat.Formatted(v.T(), mat.Prefix("\t "))) // Output: // diff --git a/matrix/mat64/hogsvd_test.go b/mat/hogsvd_test.go similarity index 99% rename from matrix/mat64/hogsvd_test.go rename to mat/hogsvd_test.go index f6543944..5838b61b 100644 --- a/matrix/mat64/hogsvd_test.go +++ b/mat/hogsvd_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" diff --git a/matrix/mat64/index_bound_checks.go b/mat/index_bound_checks.go similarity index 84% rename from matrix/mat64/index_bound_checks.go rename to mat/index_bound_checks.go index 33726c9d..f4034460 100644 --- a/matrix/mat64/index_bound_checks.go +++ b/mat/index_bound_checks.go @@ -6,9 +6,7 @@ //+build bounds -package mat64 - -import "gonum.org/v1/gonum/matrix" +package mat // At returns the element at row i, column j. func (m *Dense) At(i, j int) float64 { @@ -17,10 +15,10 @@ func (m *Dense) At(i, j int) float64 { func (m *Dense) at(i, j int) float64 { if uint(i) >= uint(m.mat.Rows) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(m.mat.Cols) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return m.mat.Data[i*m.mat.Stride+j] } @@ -32,10 +30,10 @@ func (m *Dense) Set(i, j int, v float64) { func (m *Dense) set(i, j int, v float64) { if uint(i) >= uint(m.mat.Rows) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(m.mat.Cols) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } m.mat.Data[i*m.mat.Stride+j] = v } @@ -44,14 +42,14 @@ func (m *Dense) set(i, j int, v float64) { // It panics if i is out of bounds or if j is not zero. func (v *Vector) At(i, j int) float64 { if j != 0 { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return v.at(i) } func (v *Vector) at(i int) float64 { if uint(i) >= uint(v.n) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } return v.mat.Data[i*v.mat.Inc] } @@ -64,7 +62,7 @@ func (v *Vector) SetVec(i int, val float64) { func (v *Vector) setVec(i int, val float64) { if uint(i) >= uint(v.n) { - panic(matrix.ErrVectorAccess) + panic(ErrVectorAccess) } v.mat.Data[i*v.mat.Inc] = val } @@ -76,10 +74,10 @@ func (t *SymDense) At(i, j int) float64 { func (t *SymDense) at(i, j int) float64 { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } if i > j { i, j = j, i @@ -94,10 +92,10 @@ func (t *SymDense) SetSym(i, j int, v float64) { func (t *SymDense) set(i, j int, v float64) { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } if i > j { i, j = j, i @@ -112,10 +110,10 @@ func (t *TriDense) At(i, j int) float64 { func (t *TriDense) at(i, j int) float64 { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } isUpper := t.isUpper() if (isUpper && i > j) || (!isUpper && i < j) { @@ -132,14 +130,14 @@ func (t *TriDense) SetTri(i, j int, v float64) { func (t *TriDense) set(i, j int, v float64) { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } isUpper := t.isUpper() if (isUpper && i > j) || (!isUpper && i < j) { - panic(matrix.ErrTriangleSet) + panic(ErrTriangleSet) } t.mat.Data[i*t.mat.Stride+j] = v } diff --git a/matrix/mat64/index_no_bound_checks.go b/mat/index_no_bound_checks.go similarity index 83% rename from matrix/mat64/index_no_bound_checks.go rename to mat/index_no_bound_checks.go index 5e346fbf..5ea59031 100644 --- a/matrix/mat64/index_no_bound_checks.go +++ b/mat/index_no_bound_checks.go @@ -6,17 +6,15 @@ //+build !bounds -package mat64 - -import "gonum.org/v1/gonum/matrix" +package mat // At returns the element at row i, column j. func (m *Dense) At(i, j int) float64 { if uint(i) >= uint(m.mat.Rows) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(m.mat.Cols) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return m.at(i, j) } @@ -28,10 +26,10 @@ func (m *Dense) at(i, j int) float64 { // Set sets the element at row i, column j to the value v. func (m *Dense) Set(i, j int, v float64) { if uint(i) >= uint(m.mat.Rows) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(m.mat.Cols) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } m.set(i, j, v) } @@ -44,10 +42,10 @@ func (m *Dense) set(i, j int, v float64) { // It panics if i is out of bounds or if j is not zero. func (v *Vector) At(i, j int) float64 { if uint(i) >= uint(v.n) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if j != 0 { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return v.at(i) } @@ -60,7 +58,7 @@ func (v *Vector) at(i int) float64 { // It panics if i is out of bounds. func (v *Vector) SetVec(i int, val float64) { if uint(i) >= uint(v.n) { - panic(matrix.ErrVectorAccess) + panic(ErrVectorAccess) } v.setVec(i, val) } @@ -72,10 +70,10 @@ func (v *Vector) setVec(i int, val float64) { // At returns the element at row i and column j. func (s *SymDense) At(i, j int) float64 { if uint(i) >= uint(s.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(s.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return s.at(i, j) } @@ -90,10 +88,10 @@ func (s *SymDense) at(i, j int) float64 { // SetSym sets the elements at (i,j) and (j,i) to the value v. func (s *SymDense) SetSym(i, j int, v float64) { if uint(i) >= uint(s.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(s.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } s.set(i, j, v) } @@ -108,10 +106,10 @@ func (s *SymDense) set(i, j int, v float64) { // At returns the element at row i, column j. func (t *TriDense) At(i, j int) float64 { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } return t.at(i, j) } @@ -128,14 +126,14 @@ func (t *TriDense) at(i, j int) float64 { // It panics if the location is outside the appropriate half of the matrix. func (t *TriDense) SetTri(i, j int, v float64) { if uint(i) >= uint(t.mat.N) { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } if uint(j) >= uint(t.mat.N) { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } isUpper := t.isUpper() if (isUpper && i > j) || (!isUpper && i < j) { - panic(matrix.ErrTriangleSet) + panic(ErrTriangleSet) } t.set(i, j, v) } diff --git a/matrix/mat64/inner.go b/mat/inner.go similarity index 96% rename from matrix/mat64/inner.go rename to mat/inner.go index 085ce6a5..9318048c 100644 --- a/matrix/mat64/inner.go +++ b/mat/inner.go @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/internal/asm/f64" - "gonum.org/v1/gonum/matrix" ) // Inner computes the generalized inner product @@ -19,10 +18,10 @@ import ( func Inner(x *Vector, A Matrix, y *Vector) float64 { m, n := A.Dims() if x.Len() != m { - panic(matrix.ErrShape) + panic(ErrShape) } if y.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } if m == 0 || n == 0 { return 0 diff --git a/matrix/mat64/inner_test.go b/mat/inner_test.go similarity index 99% rename from matrix/mat64/inner_test.go rename to mat/inner_test.go index 19a2ebc9..7a8ce3f5 100644 --- a/matrix/mat64/inner_test.go +++ b/mat/inner_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" diff --git a/matrix/mat64/io.go b/mat/io.go similarity index 99% rename from matrix/mat64/io.go rename to mat/io.go index 903cdc7d..a6ba5034 100644 --- a/matrix/mat64/io.go +++ b/mat/io.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "encoding/binary" diff --git a/matrix/mat64/io_test.go b/mat/io_test.go similarity index 99% rename from matrix/mat64/io_test.go rename to mat/io_test.go index 5893b4c0..faec239b 100644 --- a/matrix/mat64/io_test.go +++ b/mat/io_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "bytes" diff --git a/matrix/mat64/list_test.go b/mat/list_test.go similarity index 99% rename from matrix/mat64/list_test.go rename to mat/list_test.go index 8f21b200..6336fe02 100644 --- a/matrix/mat64/list_test.go +++ b/mat/list_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" @@ -14,7 +14,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) // legalSizeSameRectangular returns whether the two matrices have the same rectangular shape. @@ -301,7 +300,7 @@ func makeRandOf(a Matrix, m, n int) Matrix { // This is necessary because we are making // a triangle from the zero value, which // always returns upper as true. - var triKind matrix.TriKind + var triKind TriKind switch t := t.(type) { case *TriDense: triKind = t.triKind() @@ -310,7 +309,7 @@ func makeRandOf(a Matrix, m, n int) Matrix { } mat := NewTriDense(n, triKind, nil) - if triKind == matrix.Upper { + if triKind == Upper { for i := 0; i < m; i++ { for j := i; j < n; j++ { mat.SetTri(i, j, rand.NormFloat64()) diff --git a/matrix/mat64/lq.go b/mat/lq.go similarity index 94% rename from matrix/mat64/lq.go rename to mat/lq.go index 30cf5d02..58b6b310 100644 --- a/matrix/mat64/lq.go +++ b/mat/lq.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" @@ -10,7 +10,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // LQ is a type for creating and using the LQ factorization of a matrix. @@ -27,7 +26,7 @@ func (lq *LQ) updateCond() { work := getFloats(3*m, false) iwork := getInts(m, false) l := lq.lq.asTriDense(m, blas.NonUnit, blas.Lower) - v := lapack64.Trcon(matrix.CondNorm, l.mat, work, iwork) + v := lapack64.Trcon(CondNorm, l.mat, work, iwork) lq.cond = 1 / v putFloats(work) putInts(iwork) @@ -42,7 +41,7 @@ func (lq *LQ) updateCond() { func (lq *LQ) Factorize(a Matrix) { m, n := a.Dims() if m > n { - panic(matrix.ErrShape) + panic(ErrShape) } k := min(m, n) if lq.lq == nil { @@ -141,12 +140,12 @@ func (m *Dense) SolveLQ(lq *LQ, trans bool, b Matrix) error { // copy the result into m at the end. if trans { if c != br { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(r, bc) } else { if r != br { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(c, bc) } @@ -164,12 +163,12 @@ func (m *Dense) SolveLQ(lq *LQ, trans bool, b Matrix) error { ok := lapack64.Trtrs(blas.Trans, t, x.mat) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } } else { ok := lapack64.Trtrs(blas.NoTrans, t, x.mat) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } for i := r; i < c; i++ { zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) @@ -183,8 +182,8 @@ func (m *Dense) SolveLQ(lq *LQ, trans bool, b Matrix) error { // M was set above to be the correct size for the result. m.Copy(x) putWorkspace(x) - if lq.cond > matrix.ConditionTolerance { - return matrix.Condition(lq.cond) + if lq.cond > ConditionTolerance { + return Condition(lq.cond) } return nil } diff --git a/matrix/mat64/lq_test.go b/mat/lq_test.go similarity index 99% rename from matrix/mat64/lq_test.go rename to mat/lq_test.go index 746283b4..a315a70d 100644 --- a/matrix/mat64/lq_test.go +++ b/mat/lq_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" diff --git a/matrix/mat64/lu.go b/mat/lu.go similarity index 91% rename from matrix/mat64/lu.go rename to mat/lu.go index 6db840f8..7416f735 100644 --- a/matrix/mat64/lu.go +++ b/mat/lu.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" @@ -11,7 +11,6 @@ import ( "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) const badSliceLength = "mat64: improper slice length" @@ -39,11 +38,11 @@ func (lu *LU) updateCond(norm float64) { // update possibilities, e.g. RankOne. u := lu.lu.asTriDense(n, blas.NonUnit, blas.Upper) l := lu.lu.asTriDense(n, blas.Unit, blas.Lower) - unorm := lapack64.Lantr(matrix.CondNorm, u.mat, work) - lnorm := lapack64.Lantr(matrix.CondNorm, l.mat, work) + unorm := lapack64.Lantr(CondNorm, u.mat, work) + lnorm := lapack64.Lantr(CondNorm, l.mat, work) norm = unorm * lnorm } - v := lapack64.Gecon(matrix.CondNorm, lu.lu.mat, norm, work, iwork) + v := lapack64.Gecon(CondNorm, lu.lu.mat, norm, work, iwork) lu.cond = 1 / v } @@ -57,7 +56,7 @@ func (lu *LU) updateCond(norm float64) { func (lu *LU) Factorize(a Matrix) { r, c := a.Dims() if r != c { - panic(matrix.ErrSquare) + panic(ErrSquare) } if lu.lu == nil { lu.lu = NewDense(r, r, nil) @@ -71,7 +70,7 @@ func (lu *LU) Factorize(a Matrix) { } lu.pivot = lu.pivot[:r] work := getFloats(r, false) - anorm := lapack64.Lange(matrix.CondNorm, lu.lu.mat, work) + anorm := lapack64.Lange(CondNorm, lu.lu.mat, work) putFloats(work) lapack64.Getrf(lu.lu.mat, lu.pivot) lu.updateCond(anorm) @@ -152,10 +151,10 @@ func (lu *LU) RankOne(orig *LU, alpha float64, x, y *Vector) { // http://web.stanford.edu/group/SOL/dissertations/Linzhong-Deng-thesis.pdf _, n := orig.lu.Dims() if x.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } if y.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } if orig != lu { if lu.isZero() { @@ -169,7 +168,7 @@ func (lu *LU) RankOne(orig *LU, alpha float64, x, y *Vector) { lu.lu.reuseAs(n, n) } } else if len(lu.pivot) != n { - panic(matrix.ErrShape) + panic(ErrShape) } copy(lu.pivot, orig.pivot) lu.lu.Copy(orig.lu) @@ -215,9 +214,9 @@ func (lu *LU) RankOne(orig *LU, alpha float64, x, y *Vector) { func (lu *LU) LTo(dst *TriDense) *TriDense { _, n := lu.lu.Dims() if dst == nil { - dst = NewTriDense(n, matrix.Lower, nil) + dst = NewTriDense(n, Lower, nil) } else { - dst.reuseAs(n, matrix.Lower) + dst.reuseAs(n, Lower) } // Extract the lower triangular elements. for i := 0; i < n; i++ { @@ -237,9 +236,9 @@ func (lu *LU) LTo(dst *TriDense) *TriDense { func (lu *LU) UTo(dst *TriDense) *TriDense { _, n := lu.lu.Dims() if dst == nil { - dst = NewTriDense(n, matrix.Upper, nil) + dst = NewTriDense(n, Upper, nil) } else { - dst.reuseAs(n, matrix.Upper) + dst.reuseAs(n, Upper) } // Extract the upper triangular elements. for i := 0; i < n; i++ { @@ -260,7 +259,7 @@ func (m *Dense) Permutation(r int, swaps []int) { zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+r]) v := swaps[i] if v < 0 || v >= r { - panic(matrix.ErrRowAccess) + panic(ErrRowAccess) } m.mat.Data[i*m.mat.Stride+v] = 1 } @@ -279,12 +278,12 @@ func (m *Dense) SolveLU(lu *LU, trans bool, b Matrix) error { _, n := lu.lu.Dims() br, bc := b.Dims() if br != n { - panic(matrix.ErrShape) + panic(ErrShape) } // TODO(btracey): Should test the condition number instead of testing that // the determinant is exactly zero. if lu.Det() == 0 { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } m.reuseAs(n, bc) @@ -303,8 +302,8 @@ func (m *Dense) SolveLU(lu *LU, trans bool, b Matrix) error { t = blas.Trans } lapack64.Getrs(t, lu.lu.mat, m.mat, lu.pivot) - if lu.cond > matrix.ConditionTolerance { - return matrix.Condition(lu.cond) + if lu.cond > ConditionTolerance { + return Condition(lu.cond) } return nil } @@ -322,7 +321,7 @@ func (v *Vector) SolveLUVec(lu *LU, trans bool, b *Vector) error { _, n := lu.lu.Dims() bn := b.Len() if bn != n { - panic(matrix.ErrShape) + panic(ErrShape) } if v != b { v.checkOverlap(b.mat) @@ -330,7 +329,7 @@ func (v *Vector) SolveLUVec(lu *LU, trans bool, b *Vector) error { // TODO(btracey): Should test the condition number instead of testing that // the determinant is exactly zero. if lu.Det() == 0 { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } v.reuseAs(n) @@ -351,8 +350,8 @@ func (v *Vector) SolveLUVec(lu *LU, trans bool, b *Vector) error { t = blas.Trans } lapack64.Getrs(t, lu.lu.mat, vMat, lu.pivot) - if lu.cond > matrix.ConditionTolerance { - return matrix.Condition(lu.cond) + if lu.cond > ConditionTolerance { + return Condition(lu.cond) } return nil } diff --git a/matrix/mat64/lu_test.go b/mat/lu_test.go similarity index 99% rename from matrix/mat64/lu_test.go rename to mat/lu_test.go index a2693d21..2b89f704 100644 --- a/matrix/mat64/lu_test.go +++ b/mat/lu_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" diff --git a/matrix/mat64/matrix.go b/mat/matrix.go similarity index 98% rename from matrix/mat64/matrix.go rename to mat/matrix.go index 0b5d3714..1d8f5ec6 100644 --- a/matrix/mat64/matrix.go +++ b/mat/matrix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" @@ -12,7 +12,6 @@ import ( "gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // Matrix is the basic matrix interface type. @@ -196,13 +195,13 @@ type RawVectorer interface { func Col(dst []float64, j int, a Matrix) []float64 { r, c := a.Dims() if j < 0 || j >= c { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } if dst == nil { dst = make([]float64, r) } else { if len(dst) != r { - panic(matrix.ErrColLength) + panic(ErrColLength) } } aU, aTrans := untranspose(a) @@ -230,13 +229,13 @@ func Col(dst []float64, j int, a Matrix) []float64 { func Row(dst []float64, i int, a Matrix) []float64 { r, c := a.Dims() if i < 0 || i >= r { - panic(matrix.ErrColAccess) + panic(ErrColAccess) } if dst == nil { dst = make([]float64, c) } else { if len(dst) != c { - panic(matrix.ErrRowLength) + panic(ErrRowLength) } } aU, aTrans := untranspose(a) @@ -270,7 +269,7 @@ func Row(dst []float64, i int, a Matrix) []float64 { func Cond(a Matrix, norm float64) float64 { m, n := a.Dims() if m == 0 || n == 0 { - panic(matrix.ErrShape) + panic(ErrShape) } var lnorm lapack.MatrixNorm switch norm { @@ -280,7 +279,7 @@ func Cond(a Matrix, norm float64) float64 { lnorm = lapack.MaxColumnSum case 2: var svd SVD - ok := svd.Factorize(a, matrix.SVDNone) + ok := svd.Factorize(a, SVDNone) if !ok { return math.Inf(1) } @@ -360,7 +359,7 @@ func Dot(a, b *Vector) float64 { la := a.Len() lb := b.Len() if la != lb { - panic(matrix.ErrShape) + panic(ErrShape) } return blas64.Dot(la, a.mat, b.mat) } @@ -523,7 +522,7 @@ func LogDet(a Matrix) (det float64, sign float64) { func Max(a Matrix) float64 { r, c := a.Dims() if r == 0 || c == 0 { - panic(matrix.ErrShape) + panic(ErrShape) } // Max(A) = Max(A^T) aU, _ := untranspose(a) @@ -598,7 +597,7 @@ func Max(a Matrix) float64 { func Min(a Matrix) float64 { r, c := a.Dims() if r == 0 || c == 0 { - panic(matrix.ErrShape) + panic(ErrShape) } // Min(A) = Min(A^T) aU, _ := untranspose(a) @@ -680,7 +679,7 @@ func Min(a Matrix) float64 { func Norm(a Matrix, norm float64) float64 { r, c := a.Dims() if r == 0 || c == 0 { - panic(matrix.ErrShape) + panic(ErrShape) } aU, aTrans := untranspose(a) var work []float64 @@ -787,7 +786,7 @@ func normLapack(norm float64, aTrans bool) lapack.MatrixNorm { } return n default: - panic(matrix.ErrNormOrder) + panic(ErrNormOrder) } } @@ -820,7 +819,7 @@ func Sum(a Matrix) float64 { func Trace(a Matrix) float64 { r, c := a.Dims() if r != c { - panic(matrix.ErrSquare) + panic(ErrSquare) } aU, _ := untranspose(a) diff --git a/matrix/mat64/matrix_test.go b/mat/matrix_test.go similarity index 98% rename from matrix/mat64/matrix_test.go rename to mat/matrix_test.go index 35ea4abf..b113e256 100644 --- a/matrix/mat64/matrix_test.go +++ b/mat/matrix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" @@ -13,7 +13,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) func panics(fn func()) (panicked bool, message string) { @@ -335,7 +334,7 @@ func TestDet(t *testing.T) { f = func(a Matrix) interface{} { ar, ac := a.Dims() if !isWide(ar, ac) { - panic(matrix.ErrShape) + panic(ErrShape) } var tmp Dense tmp.Mul(a, a.T()) @@ -344,7 +343,7 @@ func TestDet(t *testing.T) { denseComparison = func(a *Dense) interface{} { ar, ac := a.Dims() if !isWide(ar, ac) { - panic(matrix.ErrShape) + panic(ErrShape) } var tmp SymDense tmp.SymOuterK(1, a) @@ -366,7 +365,7 @@ func TestDot(t *testing.T) { ra, ca := a.Dims() rb, cb := b.Dims() if ra != rb || ca != cb { - panic(matrix.ErrShape) + panic(ErrShape) } var sum float64 for i := 0; i < ra; i++ { @@ -481,9 +480,9 @@ func TestNormZero(t *testing.T) { if !panicked { t.Errorf("expected panic for Norm(&%T{}, %v)", a, norm) } - if message != matrix.ErrShape.Error() { + if message != ErrShape.Error() { t.Errorf("unexpected panic string for Norm(&%T{}, %v): got:%s want:%s", - a, norm, message, matrix.ErrShape.Error()) + a, norm, message, ErrShape.Error()) } } } diff --git a/matrix/mat64/mul_test.go b/mat/mul_test.go similarity index 98% rename from matrix/mat64/mul_test.go rename to mat/mul_test.go index a73526e5..57ec17f2 100644 --- a/matrix/mat64/mul_test.go +++ b/mat/mul_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" @@ -11,7 +11,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) // TODO: Need to add tests where one is overwritten. @@ -247,7 +246,7 @@ func (m *basicTriangular) T() Matrix { return Transpose{m} } -func (m *basicTriangular) Triangle() (int, matrix.TriKind) { +func (m *basicTriangular) Triangle() (int, TriKind) { return (*TriDense)(m).Triangle() } diff --git a/matrix/mat64/offset.go b/mat/offset.go similarity index 97% rename from matrix/mat64/offset.go rename to mat/offset.go index 45707f15..01e7d34f 100644 --- a/matrix/mat64/offset.go +++ b/mat/offset.go @@ -4,7 +4,7 @@ //+build !appengine -package mat64 +package mat import "unsafe" diff --git a/matrix/mat64/offset_appengine.go b/mat/offset_appengine.go similarity index 98% rename from matrix/mat64/offset_appengine.go rename to mat/offset_appengine.go index 584ef8bb..a4e7b27a 100644 --- a/matrix/mat64/offset_appengine.go +++ b/mat/offset_appengine.go @@ -4,7 +4,7 @@ //+build appengine -package mat64 +package mat import "reflect" diff --git a/matrix/mat64/pool.go b/mat/pool.go similarity index 96% rename from matrix/mat64/pool.go rename to mat/pool.go index dc6ac17e..f081b0bb 100644 --- a/matrix/mat64/pool.go +++ b/mat/pool.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "sync" "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) var tab64 = [64]byte{ @@ -148,7 +147,7 @@ func putWorkspaceSym(s *SymDense) { // getWorkspaceTri returns a *TriDense of size 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 getWorkspaceTri(n int, kind matrix.TriKind, clear bool) *TriDense { +func getWorkspaceTri(n int, kind TriKind, clear bool) *TriDense { l := uint64(n) l *= l t := poolTri[bits(l)].Get().(*TriDense) @@ -158,12 +157,12 @@ func getWorkspaceTri(n int, kind matrix.TriKind, clear bool) *TriDense { } t.mat.N = n t.mat.Stride = n - if kind == matrix.Upper { + if kind == Upper { t.mat.Uplo = blas.Upper - } else if kind == matrix.Lower { + } else if kind == Lower { t.mat.Uplo = blas.Lower } else { - panic(matrix.ErrTriangle) + panic(ErrTriangle) } t.mat.Diag = blas.NonUnit t.cap = n diff --git a/matrix/mat64/pool_test.go b/mat/pool_test.go similarity index 99% rename from matrix/mat64/pool_test.go rename to mat/pool_test.go index 7f4a27d4..fcf831ad 100644 --- a/matrix/mat64/pool_test.go +++ b/mat/pool_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" diff --git a/matrix/mat64/product.go b/mat/product.go similarity index 95% rename from matrix/mat64/product.go rename to mat/product.go index f06d6ee5..dde0bff1 100644 --- a/matrix/mat64/product.go +++ b/mat/product.go @@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat -import ( - "fmt" - - "gonum.org/v1/gonum/matrix" -) +import "fmt" // Product calculates the product of the given factors and places the result in // the receiver. The order of multiplication operations is optimized to minimize @@ -31,7 +27,7 @@ func (m *Dense) Product(factors ...Matrix) { switch len(factors) { case 0: if r != 0 || c != 0 { - panic(matrix.ErrShape) + panic(ErrShape) } return case 1: @@ -77,10 +73,10 @@ func newMultiplier(m *Dense, factors []Matrix) *multiplier { fr, fc := factors[0].Dims() // newMultiplier is only called with len(factors) > 2. if !m.isZero() { if fr != r { - panic(matrix.ErrShape) + panic(ErrShape) } if _, lc := factors[len(factors)-1].Dims(); lc != c { - panic(matrix.ErrShape) + panic(ErrShape) } } @@ -92,7 +88,7 @@ func newMultiplier(m *Dense, factors []Matrix) *multiplier { cr, cc := f.Dims() dims[i+1] = cr if pc != cr { - panic(matrix.ErrShape) + panic(ErrShape) } pc = cc } @@ -150,7 +146,7 @@ func (p *multiplier) multiplySubchain(i, j int) (m Matrix, intermediate bool) { if ac != br { // Panic with a string since this // is not a user-facing panic. - panic(matrix.ErrShape.Error()) + panic(ErrShape.Error()) } if debugProductWalk { diff --git a/matrix/mat64/product_test.go b/mat/product_test.go similarity index 99% rename from matrix/mat64/product_test.go rename to mat/product_test.go index 4a101634..2ce0e575 100644 --- a/matrix/mat64/product_test.go +++ b/mat/product_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" diff --git a/matrix/mat64/qr.go b/mat/qr.go similarity index 94% rename from matrix/mat64/qr.go rename to mat/qr.go index 0dfdb6e3..6205a7e1 100644 --- a/matrix/mat64/qr.go +++ b/mat/qr.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Based on the QRDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "math" @@ -11,7 +11,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // QR is a type for creating and using the QR factorization of a matrix. @@ -28,7 +27,7 @@ func (qr *QR) updateCond() { work := getFloats(3*n, false) iwork := getInts(n, false) r := qr.qr.asTriDense(n, blas.NonUnit, blas.Upper) - v := lapack64.Trcon(matrix.CondNorm, r.mat, work, iwork) + v := lapack64.Trcon(CondNorm, r.mat, work, iwork) putFloats(work) putInts(iwork) qr.cond = 1 / v @@ -43,7 +42,7 @@ func (qr *QR) updateCond() { func (qr *QR) Factorize(a Matrix) { m, n := a.Dims() if m < n { - panic(matrix.ErrShape) + panic(ErrShape) } k := min(m, n) if qr.qr == nil { @@ -138,12 +137,12 @@ func (m *Dense) SolveQR(qr *QR, trans bool, b Matrix) error { // copy the result into m at the end. if trans { if c != br { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(r, bc) } else { if r != br { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(c, bc) } @@ -155,7 +154,7 @@ func (m *Dense) SolveQR(qr *QR, trans bool, b Matrix) error { if trans { ok := lapack64.Trtrs(blas.Trans, t, x.mat) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } for i := c; i < r; i++ { zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) @@ -174,14 +173,14 @@ func (m *Dense) SolveQR(qr *QR, trans bool, b Matrix) error { ok := lapack64.Trtrs(blas.NoTrans, t, x.mat) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } } // M was set above to be the correct size for the result. m.Copy(x) putWorkspace(x) - if qr.cond > matrix.ConditionTolerance { - return matrix.Condition(qr.cond) + if qr.cond > ConditionTolerance { + return Condition(qr.cond) } return nil } diff --git a/matrix/mat64/qr_test.go b/mat/qr_test.go similarity index 99% rename from matrix/mat64/qr_test.go rename to mat/qr_test.go index 6914c7e8..6ab44899 100644 --- a/matrix/mat64/qr_test.go +++ b/mat/qr_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" diff --git a/matrix/mat64/shadow.go b/mat/shadow.go similarity index 99% rename from matrix/mat64/shadow.go rename to mat/shadow.go index 8061f33f..30b6c2f5 100644 --- a/matrix/mat64/shadow.go +++ b/mat/shadow.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas" diff --git a/matrix/mat64/shadow_test.go b/mat/shadow_test.go similarity index 90% rename from matrix/mat64/shadow_test.go rename to mat/shadow_test.go index 7963ab85..564d9e66 100644 --- a/matrix/mat64/shadow_test.go +++ b/mat/shadow_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" @@ -10,7 +10,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) func TestDenseOverlaps(t *testing.T) { @@ -94,7 +93,7 @@ func TestTriDenseOverlaps(t *testing.T) { rnd := rand.New(rand.NewSource(1)) - for _, parentKind := range []matrix.TriKind{matrix.Upper, matrix.Lower} { + for _, parentKind := range []TriKind{Upper, Lower} { for n := 1; n < 20; n++ { data := make([]float64, n*n) for i := range data { @@ -120,7 +119,7 @@ func TestTriDenseOverlaps(t *testing.T) { } else { views[k].n = 1 } - viewKind := []matrix.TriKind{matrix.Upper, matrix.Lower}[rnd.Intn(2)] + viewKind := []TriKind{Upper, Lower}[rnd.Intn(2)] views[k].TriDense = denseAsTriDense( m.Slice(views[k].i, views[k].i+views[k].n, views[k].j, views[k].j+views[k].n).(*Dense), viewKind) @@ -172,21 +171,21 @@ func intervalsOverlap(a, b interval) bool { return a.to > b.from && b.to > a.from } -func overlapsParentTriangle(i, j, n int, parent, view matrix.TriKind) bool { +func overlapsParentTriangle(i, j, n int, parent, view TriKind) bool { switch parent { - case matrix.Upper: + case Upper: if i <= j { return true } - if view == matrix.Upper { + if view == Upper { return i < j+n } - case matrix.Lower: + case Lower: if i >= j { return true } - if view == matrix.Lower { + if view == Lower { return i+n > j } } @@ -194,17 +193,17 @@ func overlapsParentTriangle(i, j, n int, parent, view matrix.TriKind) bool { return false } -func overlapSiblingTriangles(ai, aj, an int, aKind matrix.TriKind, bi, bj, bn int, bKind matrix.TriKind) bool { +func overlapSiblingTriangles(ai, aj, an int, aKind TriKind, bi, bj, bn int, bKind TriKind) bool { for i := max(ai, bi); i < min(ai+an, bi+bn); i++ { var a, b interval - if aKind == matrix.Upper { + if aKind == Upper { a = interval{from: aj - ai + i, to: aj + an} } else { a = interval{from: aj, to: aj - ai + i + 1} } - if bKind == matrix.Upper { + if bKind == Upper { b = interval{from: bj - bi + i, to: bj + bn} } else { b = interval{from: bj, to: bj - bi + i + 1} @@ -217,8 +216,8 @@ func overlapSiblingTriangles(ai, aj, an int, aKind matrix.TriKind, bi, bj, bn in return false } -func kindString(k matrix.TriKind) string { - if k == matrix.Upper { +func kindString(k TriKind) string { + if k == Upper { return "U" } return "L" @@ -252,14 +251,14 @@ func TestIssue359(t *testing.T) { // denseAsTriDense returns a triangular matrix derived from the // square matrix m, with the orientation specified by kind. -func denseAsTriDense(m *Dense, kind matrix.TriKind) *TriDense { +func denseAsTriDense(m *Dense, kind TriKind) *TriDense { r, c := m.Dims() if r != c { - panic(matrix.ErrShape) + panic(ErrShape) } n := r uplo := blas.Lower - if kind == matrix.Upper { + if kind == Upper { uplo = blas.Upper } return &TriDense{ diff --git a/matrix/mat64/solve.go b/mat/solve.go similarity index 93% rename from matrix/mat64/solve.go rename to mat/solve.go index e30bada7..8b716189 100644 --- a/matrix/mat64/solve.go +++ b/mat/solve.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // Solve finds a minimum-norm solution to a system of linear equations defined @@ -23,7 +22,7 @@ func (m *Dense) Solve(a, b Matrix) error { ar, ac := a.Dims() br, bc := b.Dims() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } m.reuseAs(ac, bc) @@ -66,11 +65,11 @@ func (m *Dense) Solve(a, b Matrix) error { blas64.Trsm(side, tA, 1, rm, m.mat) work := getFloats(3*rm.N, false) iwork := getInts(rm.N, false) - cond := lapack64.Trcon(matrix.CondNorm, rm, work, iwork) + cond := lapack64.Trcon(CondNorm, rm, work, iwork) putFloats(work) putInts(iwork) - if cond > matrix.ConditionTolerance { - return matrix.Condition(cond) + if cond > ConditionTolerance { + return Condition(cond) } return nil } diff --git a/matrix/mat64/solve_test.go b/mat/solve_test.go similarity index 99% rename from matrix/mat64/solve_test.go rename to mat/solve_test.go index 7f013978..ed95ed1f 100644 --- a/matrix/mat64/solve_test.go +++ b/mat/solve_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" diff --git a/matrix/mat64/svd.go b/mat/svd.go similarity index 93% rename from matrix/mat64/svd.go rename to mat/svd.go index 0a4f2062..4955408f 100644 --- a/matrix/mat64/svd.go +++ b/mat/svd.go @@ -3,19 +3,18 @@ // license that can be found in the LICENSE file. // Based on the SingularValueDecomposition class from Jama 1.0.3. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) // SVD is a type for creating and using the Singular Value Decomposition (SVD) // of a matrix. type SVD struct { - kind matrix.SVDKind + kind SVDKind s []float64 u blas64.General @@ -40,16 +39,16 @@ type SVD struct { // // Factorize returns whether the decomposition succeeded. If the decomposition // failed, routines that require a successful factorization will panic. -func (svd *SVD) Factorize(a Matrix, kind matrix.SVDKind) (ok bool) { +func (svd *SVD) Factorize(a Matrix, kind SVDKind) (ok bool) { m, n := a.Dims() var jobU, jobVT lapack.SVDJob switch kind { default: panic("svd: bad input kind") - case matrix.SVDNone: + case SVDNone: jobU = lapack.SVDNone jobVT = lapack.SVDNone - case matrix.SVDFull: + case SVDFull: // TODO(btracey): This code should be modified to have the smaller // matrix written in-place into aCopy when the lapack/native/dgesvd // implementation is complete. @@ -67,7 +66,7 @@ func (svd *SVD) Factorize(a Matrix, kind matrix.SVDKind) (ok bool) { } jobU = lapack.SVDAll jobVT = lapack.SVDAll - case matrix.SVDThin: + case SVDThin: // TODO(btracey): This code should be modified to have the larger // matrix written in-place into aCopy when the lapack/native/dgesvd // implementation is complete. @@ -105,7 +104,7 @@ func (svd *SVD) Factorize(a Matrix, kind matrix.SVDKind) (ok bool) { // Kind returns the matrix.SVDKind of the decomposition. If no decomposition has been // computed, Kind returns 0. -func (svd *SVD) Kind() matrix.SVDKind { +func (svd *SVD) Kind() SVDKind { return svd.kind } @@ -133,7 +132,7 @@ func (svd *SVD) Values(s []float64) []float64 { s = make([]float64, len(svd.s)) } if len(s) != len(svd.s) { - panic(matrix.ErrSliceLengthMismatch) + panic(ErrSliceLengthMismatch) } copy(s, svd.s) return s @@ -144,7 +143,7 @@ func (svd *SVD) Values(s []float64) []float64 { // of size m×min(m,n) if svd.Kind() == SVDThin, and UTo panics otherwise. func (svd *SVD) UTo(dst *Dense) *Dense { kind := svd.kind - if kind != matrix.SVDFull && kind != matrix.SVDThin { + if kind != SVDFull && kind != SVDThin { panic("mat64: improper SVD kind") } r := svd.u.Rows @@ -170,7 +169,7 @@ func (svd *SVD) UTo(dst *Dense) *Dense { // of size n×min(m,n) if svd.Kind() == SVDThin, and VTo panics otherwise. func (svd *SVD) VTo(dst *Dense) *Dense { kind := svd.kind - if kind != matrix.SVDFull && kind != matrix.SVDThin { + if kind != SVDFull && kind != SVDThin { panic("mat64: improper SVD kind") } r := svd.vt.Rows diff --git a/matrix/mat64/svd_test.go b/mat/svd_test.go similarity index 95% rename from matrix/mat64/svd_test.go rename to mat/svd_test.go index 34e21a6f..54815c85 100644 --- a/matrix/mat64/svd_test.go +++ b/mat/svd_test.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math/rand" "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) func TestSVD(t *testing.T) { @@ -63,7 +62,7 @@ func TestSVD(t *testing.T) { }, } { var svd SVD - ok := svd.Factorize(test.a, matrix.SVDThin) + ok := svd.Factorize(test.a, SVDThin) if !ok { t.Errorf("SVD failed") } @@ -111,7 +110,7 @@ func TestSVD(t *testing.T) { // Test Full decomposition. var svd SVD - ok := svd.Factorize(a, matrix.SVDFull) + ok := svd.Factorize(a, SVDFull) if !ok { t.Errorf("SVD factorization failed") } @@ -130,7 +129,7 @@ func TestSVD(t *testing.T) { } // Test Thin decomposition. - ok = svd.Factorize(a, matrix.SVDThin) + ok = svd.Factorize(a, SVDThin) if !ok { t.Errorf("SVD factorization failed") } @@ -152,7 +151,7 @@ func TestSVD(t *testing.T) { } // Test None decomposition. - ok = svd.Factorize(a, matrix.SVDNone) + ok = svd.Factorize(a, SVDNone) if !ok { t.Errorf("SVD factorization failed") } diff --git a/matrix/mat64/symmetric.go b/mat/symmetric.go similarity index 97% rename from matrix/mat64/symmetric.go rename to mat/symmetric.go index 51b58401..82107db4 100644 --- a/matrix/mat64/symmetric.go +++ b/mat/symmetric.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "math" "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) var ( @@ -64,7 +63,7 @@ func NewSymDense(n int, data []float64) *SymDense { panic("mat64: negative dimension") } if data != nil && n*n != len(data) { - panic(matrix.ErrShape) + panic(ErrShape) } if data == nil { data = make([]float64, n*n) @@ -147,7 +146,7 @@ func (s *SymDense) reuseAs(n int) { panic(badSymTriangle) } if s.mat.N != n { - panic(matrix.ErrShape) + panic(ErrShape) } } @@ -163,7 +162,7 @@ func (s *SymDense) isolatedWorkspace(a Symmetric) (w *SymDense, restore func()) func (s *SymDense) AddSym(a, b Symmetric) { n := a.Symmetric() if n != b.Symmetric() { - panic(matrix.ErrShape) + panic(ErrShape) } s.reuseAs(n) @@ -227,7 +226,7 @@ func (s *SymDense) CopySym(a Symmetric) int { func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *Vector) { n := x.Len() if a.Symmetric() != n { - panic(matrix.ErrShape) + panic(ErrShape) } s.reuseAs(n) if s != a { @@ -246,7 +245,7 @@ func (s *SymDense) SymRankK(a Symmetric, alpha float64, x Matrix) { n := a.Symmetric() r, _ := x.Dims() if r != n { - panic(matrix.ErrShape) + panic(ErrShape) } xMat, aTrans := untranspose(x) var g blas64.General @@ -307,7 +306,7 @@ func (s *SymDense) SymOuterK(alpha float64, x Matrix) { s.SymRankK(s, alpha, x) } default: - panic(matrix.ErrShape) + panic(ErrShape) } } @@ -317,10 +316,10 @@ func (s *SymDense) SymOuterK(alpha float64, x Matrix) { func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y *Vector) { n := s.mat.N if x.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } if y.Len() != n { - panic(matrix.ErrShape) + panic(ErrShape) } var w SymDense if s == a { @@ -419,7 +418,7 @@ func (s *SymDense) ViewSquare(i, n int) Matrix { func (s *SymDense) SliceSquare(i, k int) Matrix { sz := s.Symmetric() if i < 0 || sz < i || k < i || sz < k { - panic(matrix.ErrIndexOutOfRange) + panic(ErrIndexOutOfRange) } v := *s v.mat.Data = s.mat.Data[i*s.mat.Stride+i : (k-1)*s.mat.Stride+k] @@ -434,7 +433,7 @@ func (s *SymDense) SliceSquare(i, k int) Matrix { // not modified during the call to GrowSquare. func (s *SymDense) GrowSquare(n int) Matrix { if n < 0 { - panic(matrix.ErrIndexOutOfRange) + panic(ErrIndexOutOfRange) } if n == 0 { return s @@ -483,12 +482,12 @@ func (s *SymDense) PowPSD(a Symmetric, pow float64) error { var eigen EigenSym ok := eigen.Factorize(a, true) if !ok { - return matrix.ErrFailedEigen + return ErrFailedEigen } values := eigen.Values(nil) for i, v := range values { if v <= 0 { - return matrix.ErrNotPSD + return ErrNotPSD } values[i] = math.Pow(v, pow) } diff --git a/matrix/mat64/symmetric_example_test.go b/mat/symmetric_example_test.go similarity index 75% rename from matrix/mat64/symmetric_example_test.go rename to mat/symmetric_example_test.go index f545da0a..c8b54eab 100644 --- a/matrix/mat64/symmetric_example_test.go +++ b/mat/symmetric_example_test.go @@ -1,14 +1,14 @@ -package mat64_test +package mat_test import ( "fmt" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func ExampleSymDense_SubsetSym() { n := 5 - s := mat64.NewSymDense(5, nil) + s := mat.NewSymDense(5, nil) count := 1.0 for i := 0; i < n; i++ { for j := i; j < n; j++ { @@ -17,18 +17,18 @@ func ExampleSymDense_SubsetSym() { } } fmt.Println("Original matrix:") - fmt.Printf("%0.4v\n\n", mat64.Formatted(s)) + fmt.Printf("%0.4v\n\n", mat.Formatted(s)) // Take the subset {0, 2, 4} - var sub mat64.SymDense + var sub mat.SymDense sub.SubsetSym(s, []int{0, 2, 4}) fmt.Println("Subset {0, 2, 4}") - fmt.Printf("%0.4v\n\n", mat64.Formatted(&sub)) + fmt.Printf("%0.4v\n\n", mat.Formatted(&sub)) // Take the subset {0, 0, 4} sub.SubsetSym(s, []int{0, 0, 4}) fmt.Println("Subset {0, 0, 4}") - fmt.Printf("%0.4v\n\n", mat64.Formatted(&sub)) + fmt.Printf("%0.4v\n\n", mat.Formatted(&sub)) // Output: // Original matrix: diff --git a/matrix/mat64/symmetric_test.go b/mat/symmetric_test.go similarity index 97% rename from matrix/mat64/symmetric_test.go rename to mat/symmetric_test.go index 06be63f0..e1d8b697 100644 --- a/matrix/mat64/symmetric_test.go +++ b/mat/symmetric_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "fmt" @@ -14,7 +14,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" ) func TestNewSymmetric(t *testing.T) { @@ -61,7 +60,7 @@ func TestNewSymmetric(t *testing.T) { } panicked, message := panics(func() { NewSymDense(3, []float64{1, 2}) }) - if !panicked || message != matrix.ErrShape.Error() { + if !panicked || message != ErrShape.Error() { t.Error("expected panic for invalid data slice length") } } @@ -81,13 +80,13 @@ func TestSymAtSet(t *testing.T) { // Check At out of bounds for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { sym.At(row, 0) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { sym.At(0, col) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } @@ -95,13 +94,13 @@ func TestSymAtSet(t *testing.T) { // Check Set out of bounds for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { sym.SetSym(row, 0, 1.2) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { sym.SetSym(0, col, 1.2) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } diff --git a/matrix/mat64/triangular.go b/mat/triangular.go similarity index 92% rename from matrix/mat64/triangular.go rename to mat/triangular.go index 394d5159..d8b84d29 100644 --- a/matrix/mat64/triangular.go +++ b/mat/triangular.go @@ -1,4 +1,4 @@ -package mat64 +package mat import ( "math" @@ -6,7 +6,6 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/lapack/lapack64" - "gonum.org/v1/gonum/matrix" ) var ( @@ -29,7 +28,7 @@ type Triangular interface { Matrix // Triangular returns the number of rows/columns in the matrix and its // orientation. - Triangle() (n int, kind matrix.TriKind) + Triangle() (n int, kind TriKind) // TTri is the equivalent of the T() method in the Matrix interface but // guarantees the transpose is of triangular type. @@ -72,7 +71,7 @@ func (t TransposeTri) T() Matrix { } // Triangle returns the number of rows/columns in the matrix and its orientation. -func (t TransposeTri) Triangle() (int, matrix.TriKind) { +func (t TransposeTri) Triangle() (int, TriKind) { n, upper := t.Triangular.Triangle() return n, !upper } @@ -99,18 +98,18 @@ func (t TransposeTri) UntransposeTri() Triangular { // The data must be arranged in row-major order, i.e. the (i*c + j)-th // element in the data slice is the {i, j}-th element in the matrix. // Only the values in the triangular portion corresponding to kind are used. -func NewTriDense(n int, kind matrix.TriKind, data []float64) *TriDense { +func NewTriDense(n int, kind TriKind, data []float64) *TriDense { if n < 0 { panic("mat64: negative dimension") } if data != nil && len(data) != n*n { - panic(matrix.ErrShape) + panic(ErrShape) } if data == nil { data = make([]float64, n*n) } uplo := blas.Lower - if kind == matrix.Upper { + if kind == Upper { uplo = blas.Upper } return &TriDense{ @@ -131,16 +130,16 @@ func (t *TriDense) Dims() (r, c int) { // Triangle returns the dimension of t and its orientation. The returned // orientation is only valid when n is not zero. -func (t *TriDense) Triangle() (n int, kind matrix.TriKind) { - return t.mat.N, matrix.TriKind(!t.isZero()) && t.triKind() +func (t *TriDense) Triangle() (n int, kind TriKind) { + return t.mat.N, TriKind(!t.isZero()) && t.triKind() } func (t *TriDense) isUpper() bool { return isUpperUplo(t.mat.Uplo) } -func (t *TriDense) triKind() matrix.TriKind { - return matrix.TriKind(isUpperUplo(t.mat.Uplo)) +func (t *TriDense) triKind() TriKind { + return TriKind(isUpperUplo(t.mat.Uplo)) } func isUpperUplo(u blas.Uplo) bool { @@ -216,9 +215,9 @@ func untransposeTri(a Triangular) (Triangular, bool) { // reuseAs resizes a zero receiver to an n×n triangular matrix with the given // orientation. If the receiver is non-zero, reuseAs checks that the receiver // is the correct size and orientation. -func (t *TriDense) reuseAs(n int, kind matrix.TriKind) { +func (t *TriDense) reuseAs(n int, kind TriKind) { ul := blas.Lower - if kind == matrix.Upper { + if kind == Upper { ul = blas.Upper } if t.mat.N > t.cap { @@ -236,10 +235,10 @@ func (t *TriDense) reuseAs(n int, kind matrix.TriKind) { return } if t.mat.N != n { - panic(matrix.ErrShape) + panic(ErrShape) } if t.mat.Uplo != ul { - panic(matrix.ErrTriangle) + panic(ErrTriangle) } } @@ -333,18 +332,18 @@ func (t *TriDense) InverseTri(a Triangular) error { t.Copy(a) work := getFloats(3*n, false) iwork := getInts(n, false) - cond := lapack64.Trcon(matrix.CondNorm, t.mat, work, iwork) + cond := lapack64.Trcon(CondNorm, t.mat, work, iwork) putFloats(work) putInts(iwork) if math.IsInf(cond, 1) { - return matrix.Condition(cond) + return Condition(cond) } ok := lapack64.Trtri(t.mat) if !ok { - return matrix.Condition(math.Inf(1)) + return Condition(math.Inf(1)) } - if cond > matrix.ConditionTolerance { - return matrix.Condition(cond) + if cond > ConditionTolerance { + return Condition(cond) } return nil } @@ -356,10 +355,10 @@ func (t *TriDense) MulTri(a, b Triangular) { n, kind := a.Triangle() nb, kindb := b.Triangle() if n != nb { - panic(matrix.ErrShape) + panic(ErrShape) } if kind != kindb { - panic(matrix.ErrTriangle) + panic(ErrTriangle) } aU, _ := untransposeTri(a) @@ -375,7 +374,7 @@ func (t *TriDense) MulTri(a, b Triangular) { } // TODO(btracey): Improve the set of fast-paths. - if kind == matrix.Upper { + if kind == Upper { for i := 0; i < n; i++ { for j := i; j < n; j++ { var v float64 diff --git a/matrix/mat64/triangular_test.go b/mat/triangular_test.go similarity index 89% rename from matrix/mat64/triangular_test.go rename to mat/triangular_test.go index bb1af94a..9067ead7 100644 --- a/matrix/mat64/triangular_test.go +++ b/mat/triangular_test.go @@ -1,4 +1,4 @@ -package mat64 +package mat import ( "math" @@ -8,14 +8,13 @@ import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) func TestNewTriangular(t *testing.T) { for i, test := range []struct { data []float64 n int - kind matrix.TriKind + kind TriKind mat *TriDense }{ { @@ -25,7 +24,7 @@ func TestNewTriangular(t *testing.T) { 7, 8, 9, }, n: 3, - kind: matrix.Upper, + kind: Upper, mat: &TriDense{ mat: blas64.Triangular{ N: 3, @@ -52,9 +51,9 @@ func TestNewTriangular(t *testing.T) { } } - for _, kind := range []matrix.TriKind{matrix.Lower, matrix.Upper} { + for _, kind := range []TriKind{Lower, Upper} { panicked, message := panics(func() { NewTriDense(3, kind, []float64{1, 2}) }) - if !panicked || message != matrix.ErrShape.Error() { + if !panicked || message != ErrShape.Error() { t.Errorf("expected panic for invalid data slice length for upper=%t", kind) } } @@ -77,13 +76,13 @@ func TestTriAtSet(t *testing.T) { // Check At out of bounds for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { tri.At(row, 0) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { tri.At(0, col) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } @@ -91,13 +90,13 @@ func TestTriAtSet(t *testing.T) { // Check Set out of bounds for _, row := range []int{-1, rows, rows + 1} { panicked, message := panics(func() { tri.SetTri(row, 0, 1.2) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) } } for _, col := range []int{-1, cols, cols + 1} { panicked, message := panics(func() { tri.SetTri(0, col, 1.2) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) } } @@ -111,7 +110,7 @@ func TestTriAtSet(t *testing.T) { } { tri.mat.Uplo = st.uplo panicked, message := panics(func() { tri.SetTri(st.row, st.col, 1.2) }) - if !panicked || message != matrix.ErrTriangleSet.Error() { + if !panicked || message != ErrTriangleSet.Error() { t.Errorf("expected panic for %+v", st) } } @@ -140,8 +139,8 @@ func TestTriDenseCopy(t *testing.T) { size := rand.Intn(100) r, err := randDense(size, 0.9, rand.NormFloat64) if size == 0 { - if err != matrix.ErrZeroLength { - t.Fatalf("expected error %v: got: %v", matrix.ErrZeroLength, err) + if err != ErrZeroLength { + t.Fatalf("expected error %v: got: %v", ErrZeroLength, err) } continue } @@ -190,8 +189,8 @@ func TestTriTriDenseCopy(t *testing.T) { size := rand.Intn(100) r, err := randDense(size, 1, rand.NormFloat64) if size == 0 { - if err != matrix.ErrZeroLength { - t.Fatalf("expected error %v: got: %v", matrix.ErrZeroLength, err) + if err != ErrZeroLength { + t.Fatalf("expected error %v: got: %v", ErrZeroLength, err) } continue } @@ -238,7 +237,7 @@ func TestTriTriDenseCopy(t *testing.T) { } func TestTriInverse(t *testing.T) { - for _, kind := range []matrix.TriKind{matrix.Upper, matrix.Lower} { + for _, kind := range []TriKind{Upper, Lower} { for _, n := range []int{1, 3, 5, 9} { data := make([]float64, n*n) for i := range data { @@ -297,10 +296,10 @@ func TestTriMul(t *testing.T) { return false } _, kind := a.(Triangular).Triangle() - r := kind == matrix.Lower + r := kind == Lower return r } - receiver := NewTriDense(3, matrix.Lower, nil) + receiver := NewTriDense(3, Lower, nil) testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesLower, legalSizeTriMul, 1e-14) legalTypesUpper := func(a, b Matrix) bool { @@ -309,10 +308,10 @@ func TestTriMul(t *testing.T) { return false } _, kind := a.(Triangular).Triangle() - r := kind == matrix.Upper + r := kind == Upper return r } - receiver = NewTriDense(3, matrix.Upper, nil) + receiver = NewTriDense(3, Upper, nil) testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesUpper, legalSizeTriMul, 1e-14) } @@ -323,7 +322,7 @@ func TestCopySymIntoTriangle(t *testing.T) { sUplo blas.Uplo s []float64 - tUplo matrix.TriKind + tUplo TriKind want []float64 }{ { @@ -334,7 +333,7 @@ func TestCopySymIntoTriangle(t *testing.T) { nan, 4, 5, nan, nan, 6, }, - tUplo: matrix.Upper, + tUplo: Upper, want: []float64{ 1, 2, 3, 0, 4, 5, @@ -349,7 +348,7 @@ func TestCopySymIntoTriangle(t *testing.T) { 2, 3, nan, 4, 5, 6, }, - tUplo: matrix.Upper, + tUplo: Upper, want: []float64{ 1, 2, 4, 0, 3, 5, @@ -364,7 +363,7 @@ func TestCopySymIntoTriangle(t *testing.T) { nan, 4, 5, nan, nan, 6, }, - tUplo: matrix.Lower, + tUplo: Lower, want: []float64{ 1, 0, 0, 2, 4, 0, @@ -379,7 +378,7 @@ func TestCopySymIntoTriangle(t *testing.T) { 2, 3, nan, 4, 5, 6, }, - tUplo: matrix.Lower, + tUplo: Lower, want: []float64{ 1, 0, 0, 2, 3, 0, diff --git a/matrix/mat64/vector.go b/mat/vector.go similarity index 97% rename from matrix/mat64/vector.go rename to mat/vector.go index e5fb6cba..59a1486d 100644 --- a/matrix/mat64/vector.go +++ b/mat/vector.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package mat64 +package mat import ( "gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/internal/asm/f64" - "gonum.org/v1/gonum/matrix" ) var ( @@ -34,7 +33,7 @@ type Vector struct { // will be reflected in data. If neither of these is true, NewVector will panic. func NewVector(n int, data []float64) *Vector { if len(data) != n && data != nil { - panic(matrix.ErrShape) + panic(ErrShape) } if data == nil { data = make([]float64, n) @@ -64,7 +63,7 @@ func (v *Vector) ViewVec(i, n int) *Vector { // of the receiver. func (v *Vector) SliceVec(i, k int) *Vector { if i < 0 || k <= i || v.n < k { - panic(matrix.ErrIndexOutOfRange) + panic(ErrIndexOutOfRange) } return &Vector{ n: k - i, @@ -168,7 +167,7 @@ func (v *Vector) AddScaledVec(a *Vector, alpha float64, b *Vector) { br := b.Len() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != a { @@ -211,7 +210,7 @@ func (v *Vector) AddVec(a, b *Vector) { br := b.Len() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != a { @@ -239,7 +238,7 @@ func (v *Vector) SubVec(a, b *Vector) { br := b.Len() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != a { @@ -268,7 +267,7 @@ func (v *Vector) MulElemVec(a, b *Vector) { br := b.Len() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != a { @@ -293,7 +292,7 @@ func (v *Vector) DivElemVec(a, b *Vector) { br := b.Len() if ar != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != a { @@ -317,7 +316,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) { r, c := a.Dims() br := b.Len() if c != br { - panic(matrix.ErrShape) + panic(ErrShape) } if v != b { @@ -427,7 +426,7 @@ func (v *Vector) reuseAs(r int) { return } if r != v.n { - panic(matrix.ErrShape) + panic(ErrShape) } } diff --git a/matrix/mat64/vector_test.go b/mat/vector_test.go similarity index 98% rename from matrix/mat64/vector_test.go rename to mat/vector_test.go index cc4c6f21..b0f8fe5a 100644 --- a/matrix/mat64/vector_test.go +++ b/mat/vector_test.go @@ -1,4 +1,4 @@ -package mat64 +package mat import ( "math/rand" @@ -6,7 +6,6 @@ import ( "testing" "gonum.org/v1/gonum/blas/blas64" - "gonum.org/v1/gonum/matrix" ) func TestNewVector(t *testing.T) { @@ -80,13 +79,13 @@ func TestVectorAtSet(t *testing.T) { for _, row := range []int{-1, n} { panicked, message := panics(func() { v.At(row, 0) }) - if !panicked || message != matrix.ErrRowAccess.Error() { + if !panicked || message != ErrRowAccess.Error() { t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row) } } for _, col := range []int{-1, 1} { panicked, message := panics(func() { v.At(0, col) }) - if !panicked || message != matrix.ErrColAccess.Error() { + if !panicked || message != ErrColAccess.Error() { t.Errorf("expected panic for invalid column access for test %d n=%d c=%d", i, n, col) } } @@ -99,7 +98,7 @@ func TestVectorAtSet(t *testing.T) { for _, row := range []int{-1, n} { panicked, message := panics(func() { v.SetVec(row, 100) }) - if !panicked || message != matrix.ErrVectorAccess.Error() { + if !panicked || message != ErrVectorAccess.Error() { t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row) } } diff --git a/matrix/cmat128/doc.go b/matrix/cmat128/doc.go deleted file mode 100644 index f780d6cd..00000000 --- a/matrix/cmat128/doc.go +++ /dev/null @@ -1,95 +0,0 @@ -// Generated by running -// go generate github.com/gonum/matrix -// DO NOT EDIT. - -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cmat128 provides implementations of complex128 matrix structures and -// linear algebra operations on them. -// -// Overview -// -// This section provides a quick overview of the cmat128 package. The following -// sections provide more in depth commentary. -// -// cmat128 provides: -// - Interfaces for a complex Matrix -// -// BLAS and LAPACK -// -// BLAS and LAPACK are the standard APIs for linear algebra routines. Many -// operations in cmat128 are implemented using calls to the wrapper functions -// in gonum/blas/cblas128 and gonum/lapack/clapack128. By default, cblas128 and -// clapack128 call the native Go implementations of the routines. Alternatively, -// it is possible to use C-based implementations of the APIs through the respective -// cgo packages and "Use" functions. The Go implementation of LAPACK makes calls -// through cblas128, so if a cgo BLAS implementation is registered, the clapack128 -// calls will be partially executed in Go and partially executed in C. -// -// Type Switching -// -// The Matrix abstraction enables efficiency as well as interoperability. Go's -// type reflection capabilities are used to choose the most efficient routine -// given the specific concrete types. For example, in -// c.Mul(a, b) -// if a and b both implement RawMatrixer, that is, they can be represented as a -// cblas128.General, cblas128.Gemm (general matrix multiplication) is called, while -// instead if b is a RawSymmetricer cblas128.Symm is used (general-symmetric -// multiplication), and if b is a *Vector cblas128.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 -// abstract matrix type may be copied into a concrete type of the corresponding -// value. If there are specific special cases that are needed, please submit a -// pull-request or file an issue. -// -// Invariants -// -// Matrix input arguments to functions are never directly modified. If an operation -// changes Matrix data, the mutated matrix will be the receiver of a function. -// -// For convenience, a matrix may be used as both a receiver and as an input, e.g. -// a.Pow(a, 6) -// v.SolveVec(a.T(), v) -// though in many cases this will cause an allocation (see Element Aliasing). -// An exception to this rule is Copy, which does not allow a.Copy(a.T()). -// -// Element Aliasing -// -// Most methods in cmat128 modify receiver data. It is forbidden for the modified -// data region of the receiver to overlap the used data area of the input -// arguments. The exception to this rule is when the method receiver is equal to one -// of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose. -// -// This prohibition is to help avoid subtle mistakes when the method needs to read -// from and write to the same data region. There are ways to make mistakes using the -// cmat128 API, and cmat128 functions will detect and complain about those. -// There are many ways to make mistakes by excursion from the cmat128 API via -// interaction with raw matrix values. -// -// If you need to read the rest of this section to understand the behavior of -// your program, you are being clever. Don't be clever. If you must be clever, -// cblas128 and clapack128 may be used to call the behavior directly. -// -// cmat128 will use the following rules to detect overlap between the receiver and one -// of the inputs: -// - the input implements one of the Raw methods, and -// - the Raw type matches that of the receiver or -// one is a RawMatrixer and the other is a RawVectorer, and -// - the address ranges of the backing data slices overlap, and -// - the strides differ or there is an overlap in the used data elements. -// If such an overlap is detected, the method will panic. -// -// The following cases will not panic: -// - the data slices do not overlap, -// - there is pointer identity between the receiver and input values after -// the value has been untransposed if necessary. -// -// cmat128 will not attempt to detect element overlap if the input does not implement a -// Raw method, or if the Raw method differs from that of the receiver except when a -// conversion has occurred through a cmat128 API function. Method behavior is undefined -// if there is undetected overlap. -// -package cmat128 // import "gonum.org/v1/gonum/matrix/cmat128" diff --git a/matrix/conv/conv.go b/matrix/conv/conv.go deleted file mode 100644 index d0f42609..00000000 --- a/matrix/conv/conv.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package conv provides matrix type interconversion utilities. -package conv // import "gonum.org/v1/gonum/matrix/conv" - -import ( - "gonum.org/v1/gonum/matrix" - "gonum.org/v1/gonum/matrix/cmat128" - "gonum.org/v1/gonum/matrix/mat64" -) - -// Complex is a complex matrix constructed from two real matrices. -type Complex struct { - // r and i are not exposed to ensure that - // their dimensions can not be altered by - // clients behind our back. - r, i mat64.Matrix - - // imagSign holds the sign of the imaginary - // part of the Complex. Valid values are 1 and -1. - imagSign float64 -} - -var ( - _ Realer = Complex{} - _ Imager = Complex{} -) - -// NewComplex returns a complex matrix constructed from r and i. At least one of -// r or i must be non-nil otherwise NewComplex will panic. If one of the inputs -// is nil, that part of the complex number will be zero when returned by At. -// If both are non-nil but differ in their sizes, NewComplex will panic. -func NewComplex(r, i mat64.Matrix) Complex { - if r == nil && i == nil { - panic("conv: no matrix") - } else if r != nil && i != nil { - rr, rc := r.Dims() - ir, ic := i.Dims() - if rr != ir || rc != ic { - panic(matrix.ErrShape) - } - } - return Complex{r: r, i: i, imagSign: 1} -} - -// Dims returns the number of rows and columns in the matrix. -func (m Complex) Dims() (r, c int) { - if m.r == nil { - return m.i.Dims() - } - return m.r.Dims() -} - -// At returns the element at row i, column j. -func (m Complex) At(i, j int) complex128 { - if m.i == nil { - return complex(m.r.At(i, j), 0) - } - if m.r == nil { - return complex(0, m.imagSign*m.i.At(i, j)) - } - return complex(m.r.At(i, j), m.imagSign*m.i.At(i, j)) -} - -// H performs an implicit transpose. -func (m Complex) H() cmat128.Matrix { - if m.i == nil { - return Complex{r: m.r.T()} - } - if m.r == nil { - return Complex{i: m.i.T(), imagSign: -m.imagSign} - } - return Complex{r: m.r.T(), i: m.i.T(), imagSign: -m.imagSign} -} - -// Real returns the real part of the receiver. -func (m Complex) Real() mat64.Matrix { return m.r } - -// Imag returns the imaginary part of the receiver. -func (m Complex) Imag() mat64.Matrix { return m.i } - -// Realer is a complex matrix that can return its real part. -type Realer interface { - Real() mat64.Matrix -} - -// Imager is a complex matrix that can return its imaginary part. -type Imager interface { - Imag() mat64.Matrix -} - -// Real is the real part of a complex matrix. -type Real struct { - matrix cmat128.Matrix -} - -// NewReal returns a mat64.Matrix representing the real part of m. If m is a Realer, -// the real part is returned. -func NewReal(m cmat128.Matrix) mat64.Matrix { - if m, ok := m.(Realer); ok { - return m.Real() - } - return Real{m} -} - -// Dims returns the number of rows and columns in the matrix. -func (m Real) Dims() (r, c int) { return m.matrix.Dims() } - -// At returns the element at row i, column j. -func (m Real) At(i, j int) float64 { return real(m.matrix.At(i, j)) } - -// T performs an implicit transpose. -func (m Real) T() mat64.Matrix { return Real{m.matrix.H()} } - -// Imag is the imaginary part of a complex matrix. -type Imag struct { - matrix cmat128.Matrix - - // conjSign holds the sign of the matrix. - // Valid values are 1 and -1. - conjSign float64 -} - -// NewImag returns a mat64.Matrix representing the imaginary part of m. If m is an Imager, -// the imaginary part is returned. -func NewImag(m cmat128.Matrix) mat64.Matrix { - if m, ok := m.(Imager); ok { - return m.Imag() - } - return Imag{matrix: m, conjSign: 1} -} - -// Dims returns the number of rows and columns in the matrix. -func (m Imag) Dims() (r, c int) { return m.matrix.Dims() } - -// At returns the element at row i, column j. -func (m Imag) At(i, j int) float64 { return m.conjSign * imag(m.matrix.At(i, j)) } - -// T performs an implicit transpose. -func (m Imag) T() mat64.Matrix { return Imag{matrix: m.matrix.H(), conjSign: -m.conjSign} } diff --git a/matrix/doc.go b/matrix/doc.go deleted file mode 100644 index 382a8b9b..00000000 --- a/matrix/doc.go +++ /dev/null @@ -1,103 +0,0 @@ -// Generated by running -// go generate github.com/gonum/matrix -// DO NOT EDIT. - -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package matrix provides common error handling mechanisms for matrix operations -// in mat64 and cmat128. -// -// Overview -// -// This section provides a quick overview of the matrix package. The following -// sections provide more in depth commentary. -// -// matrix provides: -// - Error type definitions -// - Error recovery mechanisms -// - Common constants used by mat64 and cmat128 -// -// Errors -// -// The mat64 and cmat128 matrix packages share a common set of errors -// provided by matrix via the matrix.Error type. -// -// Errors are either returned directly or used as the parameter of a panic -// depending on the class of error encountered. Returned errors indicate -// that a call was not able to complete successfully while panics generally -// indicate a programmer or unrecoverable error. -// -// Examples of each type are found in the mat64 Solve methods, which find -// x such that A*x = b. -// -// An error value is returned from the function or method when the operation -// can meaningfully fail. The Solve operation cannot complete if A is -// singular. However, determining the singularity of A is most easily -// discovered during the Solve procedure itself and is a valid result from -// the operation, so in this case an error is returned. -// -// A function will panic when the input parameters are inappropriate for -// the function. In Solve, for example, the number of rows of each input -// matrix must be equal because of the rules of matrix multiplication. -// Similarly, for solving A*x = b, a non-zero receiver must have the same -// number of rows as A has columns and must have the same number of columns -// as b. In all cases where a function will panic, conditions that would -// lead to a panic can easily be checked prior to a call. -// -// Error Recovery -// -// When a matrix.Error is the parameter of a panic, the panic can be -// recovered by a Maybe function, which will then return the error. -// Panics that are not of type matrix.Error are re-panicked by the -// Maybe functions. -// -// Invariants -// -// Matrix input arguments to functions are never directly modified. If an operation -// changes Matrix data, the mutated matrix will be the receiver of a function. -// -// For convenience, a matrix may be used as both a receiver and as an input, e.g. -// a.Pow(a, 6) -// v.SolveVec(a.T(), v) -// though in many cases this will cause an allocation (see Element Aliasing). -// An exception to this rule is Copy, which does not allow a.Copy(a.T()). -// -// Element Aliasing -// -// Most methods in the matrix packages modify receiver data. It is forbidden for the modified -// data region of the receiver to overlap the used data area of the input -// arguments. The exception to this rule is when the method receiver is equal to one -// of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose. -// -// This prohibition is to help avoid subtle mistakes when the method needs to read -// from and write to the same data region. There are ways to make mistakes using the -// matrix API, and matrix functions will detect and complain about those. -// There are many ways to make mistakes by excursion from the matrix API via -// interaction with raw matrix values. -// -// If you need to read the rest of this section to understand the behavior of -// your program, you are being clever. Don't be clever. If you must be clever, -// blas64/cblas128 and lapack64/clapack128 may be used to call the behavior directly. -// -// The matrix packages will use the following rules to detect overlap between the receiver and one -// of the inputs: -// - the input implements one of the Raw methods, and -// - the Raw type matches that of the receiver or -// one is a RawMatrixer and the other is a RawVectorer, and -// - the address ranges of the backing data slices overlap, and -// - the strides differ or there is an overlap in the used data elements. -// If such an overlap is detected, the method will panic. -// -// The following cases will not panic: -// - the data slices do not overlap, -// - there is pointer identity between the receiver and input values after -// the value has been untransposed if necessary. -// -// The matrix packages will not attempt to detect element overlap if the input does not implement a -// Raw method, or if the Raw method differs from that of the receiver except when a -// conversion has occurred through a matrix API function. Method behavior is undefined -// if there is undetected overlap. -// -package matrix // import "gonum.org/v1/gonum/matrix" diff --git a/matrix/gendoc.go b/matrix/gendoc.go deleted file mode 100644 index 25fd2e1e..00000000 --- a/matrix/gendoc.go +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//+build ignore - -// gendoc creates the matrix, mat64 and cmat128 package doc comments. -package main - -import ( - "fmt" - "log" - "os" - "path/filepath" - "strings" - "text/template" - "unicode/utf8" -) - -var docs = template.Must(template.New("docs").Funcs(funcs).Parse(`{{define "common"}}// Generated by running -// go generate github.com/gonum/matrix -// DO NOT EDIT. - -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package {{.Name}} provides {{.Provides}} -// -// Overview -// -// This section provides a quick overview of the {{.Name}} package. The following -// sections provide more in depth commentary. -// -{{.Overview}} -//{{end}} -{{define "interfaces"}}// The Matrix Interfaces -// -// The Matrix interface is the common link between the concrete types. The Matrix -// interface is defined by three functions: Dims, which returns the dimensions -// of the Matrix, At, which returns the element in the specified location, and -// T for returning a Transpose (discussed later). All of the concrete types can -// perform these behaviors and so implement the interface. Methods and functions -// are designed to use this interface, so in particular the method -// func (m *Dense) Mul(a, b Matrix) -// constructs a *Dense from the result of a multiplication with any Matrix types, -// not just *Dense. Where more restrictive requirements must be met, there are also the -// Symmetric and Triangular interfaces. For example, in -// func (s *SymDense) AddSym(a, b Symmetric) -// the Symmetric interface guarantees a symmetric result. -// -// Transposes -// -// The T method is used for transposition. For example, c.Mul(a.T(), b) computes -// c = a^T * b. The {{if .ExamplePackage}}{{.ExamplePackage}}{{else}}{{.Name}}{{end}} types implement this method using an implicit transpose — -// see the Transpose type for more details. Note that some operations have a -// transpose as part of their definition, as in *SymDense.SymOuterK. -//{{end}} -{{define "factorization"}}// Matrix Factorization -// -// Matrix factorizations, such as the LU decomposition, typically have their own -// specific data storage, and so are each implemented as a specific type. The -// factorization can be computed through a call to Factorize -// var lu {{if .ExamplePackage}}{{.ExamplePackage}}{{else}}{{.Name}}{{end}}.LU -// lu.Factorize(a) -// The elements of the factorization can be extracted through methods on the -// appropriate type, i.e. *TriDense.LFromLU and *TriDense.UFromLU. Alternatively, -// they can be used directly, as in *Dense.SolveLU. Some factorizations can be -// updated directly, without needing to update the original matrix and refactorize, -// as in *LU.RankOne. -//{{end}} -{{define "blas"}}// BLAS and LAPACK -// -// BLAS and LAPACK are the standard APIs for linear algebra routines. Many -// operations in {{if .Description}}{{.Description}}{{else}}{{.Name}}{{end}} are implemented using calls to the wrapper functions -// in gonum/blas/{{.BLAS|alts}} and gonum/lapack/{{.LAPACK|alts}}. By default, {{.BLAS|join "/"}} and -// {{.LAPACK|join "/"}} call the native Go implementations of the routines. Alternatively, -// it is possible to use C-based implementations of the APIs through the respective -// cgo packages and "Use" functions. The Go implementation of LAPACK makes calls -// through {{.BLAS|join "/"}}, so if a cgo BLAS implementation is registered, the {{.LAPACK|join "/"}} -// calls will be partially executed in Go and partially executed in C. -//{{end}} -{{define "switching"}}// Type Switching -// -// The Matrix abstraction enables efficiency as well as interoperability. Go's -// type reflection capabilities are used to choose the most efficient routine -// given the specific concrete types. For example, in -// c.Mul(a, b) -// if a and b both implement RawMatrixer, that is, they can be represented as a -// {{.BLAS|alts}}.General, {{.BLAS|alts}}.Gemm (general matrix multiplication) is called, while -// instead if b is a RawSymmetricer {{.BLAS|alts}}.Symm is used (general-symmetric -// multiplication), and if b is a *Vector {{.BLAS|alts}}.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 -// abstract matrix type may be copied into a concrete type of the corresponding -// value. If there are specific special cases that are needed, please submit a -// pull-request or file an issue. -//{{end}} -{{define "invariants"}}// Invariants -// -// Matrix input arguments to functions are never directly modified. If an operation -// changes Matrix data, the mutated matrix will be the receiver of a function. -// -// For convenience, a matrix may be used as both a receiver and as an input, e.g. -// a.Pow(a, 6) -// v.SolveVec(a.T(), v) -// though in many cases this will cause an allocation (see Element Aliasing). -// An exception to this rule is Copy, which does not allow a.Copy(a.T()). -//{{end}} -{{define "aliasing"}}// Element Aliasing -// -// Most methods in {{if .Description}}{{.Description}}{{else}}{{.Name}}{{end}} modify receiver data. It is forbidden for the modified -// data region of the receiver to overlap the used data area of the input -// arguments. The exception to this rule is when the method receiver is equal to one -// of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose. -// -// This prohibition is to help avoid subtle mistakes when the method needs to read -// from and write to the same data region. There are ways to make mistakes using the -// {{.Name}} API, and {{.Name}} functions will detect and complain about those. -// There are many ways to make mistakes by excursion from the {{.Name}} API via -// interaction with raw matrix values. -// -// If you need to read the rest of this section to understand the behavior of -// your program, you are being clever. Don't be clever. If you must be clever, -// {{.BLAS|join "/"}} and {{.LAPACK|join "/"}} may be used to call the behavior directly. -// -// {{if .Description}}{{.Description|sentence}}{{else}}{{.Name}}{{end}} will use the following rules to detect overlap between the receiver and one -// of the inputs: -// - the input implements one of the Raw methods, and -// - the Raw type matches that of the receiver or -// one is a RawMatrixer and the other is a RawVectorer, and -// - the address ranges of the backing data slices overlap, and -// - the strides differ or there is an overlap in the used data elements. -// If such an overlap is detected, the method will panic. -// -// The following cases will not panic: -// - the data slices do not overlap, -// - there is pointer identity between the receiver and input values after -// the value has been untransposed if necessary. -// -// {{if .Description}}{{.Description|sentence}}{{else}}{{.Name}}{{end}} will not attempt to detect element overlap if the input does not implement a -// Raw method, or if the Raw method differs from that of the receiver except when a -// conversion has occurred through a {{.Name}} API function. Method behavior is undefined -// if there is undetected overlap. -//{{end}}`)) - -type Package struct { - path string - - Name string - Provides string - Description string - ExamplePackage string - Overview string - - BLAS []string - LAPACK []string - - template string -} - -var pkgs = []Package{ - { - path: ".", - - Name: "matrix", - Description: "the matrix packages", - Provides: `common error handling mechanisms for matrix operations -// in mat64 and cmat128.`, - ExamplePackage: "mat64", - - Overview: `// matrix provides: -// - Error type definitions -// - Error recovery mechanisms -// - Common constants used by mat64 and cmat128 -// -// Errors -// -// The mat64 and cmat128 matrix packages share a common set of errors -// provided by matrix via the matrix.Error type. -// -// Errors are either returned directly or used as the parameter of a panic -// depending on the class of error encountered. Returned errors indicate -// that a call was not able to complete successfully while panics generally -// indicate a programmer or unrecoverable error. -// -// Examples of each type are found in the mat64 Solve methods, which find -// x such that A*x = b. -// -// An error value is returned from the function or method when the operation -// can meaningfully fail. The Solve operation cannot complete if A is -// singular. However, determining the singularity of A is most easily -// discovered during the Solve procedure itself and is a valid result from -// the operation, so in this case an error is returned. -// -// A function will panic when the input parameters are inappropriate for -// the function. In Solve, for example, the number of rows of each input -// matrix must be equal because of the rules of matrix multiplication. -// Similarly, for solving A*x = b, a non-zero receiver must have the same -// number of rows as A has columns and must have the same number of columns -// as b. In all cases where a function will panic, conditions that would -// lead to a panic can easily be checked prior to a call. -// -// Error Recovery -// -// When a matrix.Error is the parameter of a panic, the panic can be -// recovered by a Maybe function, which will then return the error. -// Panics that are not of type matrix.Error are re-panicked by the -// Maybe functions.`, - BLAS: []string{"blas64", "cblas128"}, - LAPACK: []string{"lapack64", "clapack128"}, - - template: `{{template "common" .}} -{{template "invariants" .}} -{{template "aliasing" .}} -package {{.Name}} // import "gonum.org/v1/gonum/{{.Name}}" -`, - }, - { - path: "mat64", - - Name: "mat64", - Provides: `implementations of float64 matrix structures and -// linear algebra operations on them.`, - - Overview: `// mat64 provides: -// - Interfaces for Matrix classes (Matrix, Symmetric, Triangular) -// - Concrete implementations (Dense, SymDense, TriDense) -// - Methods and functions for using matrix data (Add, Trace, SymRankOne) -// - Types for constructing and using matrix factorizations (QR, LU) -// -// A matrix may be constructed through the corresponding New function. If no -// backing array is provided the matrix will be initialized to all zeros. -// // Allocate a zeroed matrix of size 3×5 -// zero := mat64.NewDense(3, 5, nil) -// If a backing data slice is provided, the matrix will have those elements. -// Matrices are all stored in row-major format. -// // Generate a 6×6 matrix of random values. -// data := make([]float64, 36) -// for i := range data { -// data[i] = rand.NormFloat64() -// } -// a := mat64.NewDense(6, 6, data) -// -// Operations involving matrix data are implemented as functions when the values -// of the matrix remain unchanged -// tr := mat64.Trace(a) -// and are implemented as methods when the operation modifies the receiver. -// zero.Copy(a) -// -// Receivers must be the correct size for the matrix operations, otherwise the -// operation will panic. As a special case for convenience, a zero-sized matrix -// will be modified to have the correct size, allocating data if necessary. -// var c mat64.Dense // construct a new zero-sized matrix -// c.Mul(a, a) // c is automatically adjusted to be 6×6`, - - BLAS: []string{"blas64"}, - LAPACK: []string{"lapack64"}, - - template: `{{template "common" .}} -{{template "interfaces" .}} -{{template "factorization" .}} -{{template "blas" .}} -{{template "switching" .}} -{{template "invariants" .}} -{{template "aliasing" .}} -package {{.Name}} // import "gonum.org/v1/gonum/matrix/{{.Name}}" -`, - }, - { - path: "cmat128", - - Name: "cmat128", - Provides: `implementations of complex128 matrix structures and -// linear algebra operations on them.`, - - Overview: `// cmat128 provides: -// - Interfaces for a complex Matrix`, - - BLAS: []string{"cblas128"}, - LAPACK: []string{"clapack128"}, - - template: `{{template "common" . }} -{{template "blas" .}} -{{template "switching" .}} -{{template "invariants" .}} -{{template "aliasing" .}} -package {{.Name}} // import "gonum.org/v1/gonum/matrix/{{.Name}}" -`, - }, -} - -var funcs = template.FuncMap{ - "sentence": sentence, - "alts": alts, - "join": join, -} - -// sentence converts a string to sentence case where the string is the prefix of the sentence. -func sentence(s string) string { - if len(s) == 0 { - return "" - } - _, size := utf8.DecodeRune([]byte(s)) - return strings.ToUpper(s[:size]) + s[size:] -} - -// alts renders a []string as a glob alternatives list. -func alts(s []string) string { - switch len(s) { - case 0: - return "" - case 1: - return s[0] - default: - return fmt.Sprintf("{%s}", strings.Join(s, ",")) - } -} - -// join is strings.Join with the parameter order changed. -func join(sep string, s []string) string { - return strings.Join(s, sep) -} - -func main() { - for _, pkg := range pkgs { - t, err := template.Must(docs.Clone()).Parse(pkg.template) - if err != nil { - log.Fatalf("failed to parse template: %v", err) - } - file := filepath.Join(pkg.path, "doc.go") - f, err := os.Create(file) - if err != nil { - log.Fatalf("failed to create %q: %v", file, err) - } - err = t.Execute(f, pkg) - if err != nil { - log.Fatalf("failed to execute template: %v", err) - } - f.Close() - } -} diff --git a/matrix/generate.go b/matrix/generate.go deleted file mode 100644 index 068fb261..00000000 --- a/matrix/generate.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright ©2015 The gonum Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run gendoc.go - -package matrix diff --git a/optimize/bfgs.go b/optimize/bfgs.go index 5d320ac7..7f49e6d1 100644 --- a/optimize/bfgs.go +++ b/optimize/bfgs.go @@ -7,7 +7,7 @@ package optimize import ( "math" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // BFGS implements the Broyden–Fletcher–Goldfarb–Shanno optimization method. It @@ -24,13 +24,13 @@ type BFGS struct { ls *LinesearchMethod dim int - x mat64.Vector // Location of the last major iteration. - grad mat64.Vector // Gradient at the last major iteration. - s mat64.Vector // Difference between locations in this and the previous iteration. - y mat64.Vector // Difference between gradients in this and the previous iteration. - tmp mat64.Vector + 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 - invHess *mat64.SymDense + invHess *mat.SymDense first bool // Indicator of the first iteration. } @@ -57,8 +57,8 @@ func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) { b.dim = dim b.first = true - x := mat64.NewVector(dim, loc.X) - grad := mat64.NewVector(dim, loc.Gradient) + x := mat.NewVector(dim, loc.X) + grad := mat.NewVector(dim, loc.Gradient) b.x.CloneVec(x) b.grad.CloneVec(grad) @@ -67,18 +67,18 @@ func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) { b.tmp.Reset() if b.invHess == nil || cap(b.invHess.RawSymmetric().Data) < dim*dim { - b.invHess = mat64.NewSymDense(dim, nil) + b.invHess = mat.NewSymDense(dim, nil) } else { - b.invHess = mat64.NewSymDense(dim, b.invHess.RawSymmetric().Data[:dim*dim]) + b.invHess = mat.NewSymDense(dim, b.invHess.RawSymmetric().Data[:dim*dim]) } // The values of the inverse Hessian are initialized in the first call to // NextDirection. // Initial direction is just negative of the gradient because the Hessian // is an identity matrix. - d := mat64.NewVector(dim, dir) + d := mat.NewVector(dim, dir) d.ScaleVec(-1, grad) - return 1 / mat64.Norm(d, 2) + return 1 / mat.Norm(d, 2) } func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) { @@ -93,21 +93,21 @@ func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) { panic("bfgs: unexpected size mismatch") } - x := mat64.NewVector(dim, loc.X) - grad := mat64.NewVector(dim, loc.Gradient) + x := mat.NewVector(dim, loc.X) + grad := mat.NewVector(dim, loc.Gradient) // s = x_{k+1} - x_{k} b.s.SubVec(x, &b.x) // y = g_{k+1} - g_{k} b.y.SubVec(grad, &b.grad) - sDotY := mat64.Dot(&b.s, &b.y) + sDotY := mat.Dot(&b.s, &b.y) if b.first { // Rescale the initial Hessian. // From: Nocedal, J., Wright, S.: Numerical Optimization (2nd ed). // Springer (2006), page 143, eq. 6.20. - yDotY := mat64.Dot(&b.y, &b.y) + yDotY := mat.Dot(&b.y, &b.y) scale := sDotY / yDotY for i := 0; i < dim; i++ { for j := i; j < dim; j++ { @@ -130,7 +130,7 @@ func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) { // // Note that y_k^T B_k^-1 y_k is a scalar, and that the third term is a // rank-two update where B_k^-1 y_k is one vector and s_k is the other. - yBy := mat64.Inner(&b.y, b.invHess, &b.y) + yBy := mat.Inner(&b.y, b.invHess, &b.y) b.tmp.MulVec(b.invHess, &b.y) scale := (1 + yBy/sDotY) / sDotY b.invHess.SymRankOne(b.invHess, scale, &b.s) @@ -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 := mat64.NewVector(dim, dir) + d := mat.NewVector(dim, dir) d.MulVec(b.invHess, grad) d.ScaleVec(-1, d) diff --git a/optimize/convex/lp/convert.go b/optimize/convex/lp/convert.go index 5f2178c1..b7b3aff6 100644 --- a/optimize/convex/lp/convert.go +++ b/optimize/convex/lp/convert.go @@ -6,7 +6,7 @@ package lp import ( "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // TODO(btracey): Have some sort of preprocessing step for helping to fix A to make it @@ -27,7 +27,7 @@ import ( // s.t aNew * x = bNew // x >= 0 // If there are no constraints of the given type, the inputs may be nil. -func Convert(c []float64, g mat64.Matrix, h []float64, a mat64.Matrix, b []float64) (cNew []float64, aNew *mat64.Dense, bNew []float64) { +func Convert(c []float64, g mat.Matrix, h []float64, a mat.Matrix, b []float64) (cNew []float64, aNew *mat.Dense, bNew []float64) { nVar := len(c) nIneq := len(h) @@ -120,21 +120,21 @@ func Convert(c []float64, g mat64.Matrix, h []float64, a mat64.Matrix, b []float copy(bNew[nIneq:], b) // Construct aNew = [G, -G, I; A, -A, 0]. - aNew = mat64.NewDense(nNewEq, nNewVar, nil) + aNew = mat.NewDense(nNewEq, nNewVar, nil) if nIneq != 0 { - aView := (aNew.View(0, 0, nIneq, nVar)).(*mat64.Dense) + aView := (aNew.View(0, 0, nIneq, nVar)).(*mat.Dense) aView.Copy(g) - aView = (aNew.View(0, nVar, nIneq, nVar)).(*mat64.Dense) + aView = (aNew.View(0, nVar, nIneq, nVar)).(*mat.Dense) aView.Scale(-1, g) - aView = (aNew.View(0, 2*nVar, nIneq, nIneq)).(*mat64.Dense) + aView = (aNew.View(0, 2*nVar, nIneq, nIneq)).(*mat.Dense) for i := 0; i < nIneq; i++ { aView.Set(i, i, 1) } } if nEq != 0 { - aView := (aNew.View(nIneq, 0, nEq, nVar)).(*mat64.Dense) + aView := (aNew.View(nIneq, 0, nEq, nVar)).(*mat.Dense) aView.Copy(a) - aView = (aNew.View(nIneq, nVar, nEq, nVar)).(*mat64.Dense) + aView = (aNew.View(nIneq, nVar, nEq, nVar)).(*mat.Dense) aView.Scale(-1, a) } return cNew, aNew, bNew diff --git a/optimize/convex/lp/simplex.go b/optimize/convex/lp/simplex.go index ae843120..a2a372c8 100644 --- a/optimize/convex/lp/simplex.go +++ b/optimize/convex/lp/simplex.go @@ -11,7 +11,7 @@ import ( "math" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // TODO(btracey): Could have a solver structure with an abstract factorizer. With @@ -85,12 +85,12 @@ const ( // Strang, Gilbert. "Linear Algebra and Applications." Academic, New York (1976). // For a detailed video introduction, see lectures 11-13 of UC Math 352 // https://www.youtube.com/watch?v=ESzYPFkY3og&index=11&list=PLh464gFUoJWOmBYla3zbZbc4nv2AXez6X. -func Simplex(c []float64, A mat64.Matrix, b []float64, tol float64, initialBasic []int) (optF float64, optX []float64, err error) { +func Simplex(c []float64, A mat.Matrix, b []float64, tol float64, initialBasic []int) (optF float64, optX []float64, err error) { ans, x, _, err := simplex(initialBasic, c, A, b, tol) return ans, x, err } -func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol float64) (float64, []float64, []int, error) { +func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol float64) (float64, []float64, []int, error) { err := verifyInputs(initialBasic, c, A, b) if err != nil { if err == ErrUnbounded { @@ -123,7 +123,7 @@ func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol f // solution. var basicIdxs []int // The indices of the non-zero x values. - var ab *mat64.Dense // The subset of columns of A listed in basicIdxs. + var ab *mat.Dense // The subset of columns of A listed in basicIdxs. var xb []float64 // The non-zero elements of x. xb = ab^-1 b if initialBasic != nil { @@ -131,7 +131,7 @@ func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol f if len(initialBasic) != m { panic("lp: incorrect number of initial vectors") } - ab = mat64.NewDense(m, len(initialBasic), nil) + ab = mat.NewDense(m, len(initialBasic), nil) extractColumns(ab, A, initialBasic) xb = make([]float64, m) err = initializeFromBasic(xb, ab, b) @@ -175,11 +175,11 @@ func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol f for i, idx := range nonBasicIdx { cn[i] = c[idx] } - an := mat64.NewDense(m, len(nonBasicIdx), nil) + an := mat.NewDense(m, len(nonBasicIdx), nil) extractColumns(an, A, nonBasicIdx) - bVec := mat64.NewVector(len(b), b) - cbVec := mat64.NewVector(len(cb), cb) + bVec := mat.NewVector(len(b), b) + cbVec := mat.NewVector(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 mat64.Matrix, b []float64, tol f // of the rule in step 4 to avoid cycling. for { // Compute reduced costs -- r = cn - an^T ab^-T cb - var tmp mat64.Vector + var tmp mat.Vector err = tmp.SolveVec(ab.T(), cbVec) if err != nil { break } data := make([]float64, n-m) - tmp2 := mat64.NewVector(n-m, data) + tmp2 := mat.NewVector(n-m, data) tmp2.MulVec(an.T(), &tmp) floats.SubTo(r, cn, data) @@ -261,13 +261,13 @@ func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol f // Replace the constrained basicIdx with the newIdx. basicIdxs[replace], nonBasicIdx[minIdx] = nonBasicIdx[minIdx], basicIdxs[replace] cb[replace], cn[minIdx] = cn[minIdx], cb[replace] - tmpCol1 := mat64.Col(nil, replace, ab) - tmpCol2 := mat64.Col(nil, minIdx, an) + tmpCol1 := mat.Col(nil, replace, ab) + tmpCol2 := mat.Col(nil, minIdx, an) ab.SetCol(replace, tmpCol2) an.SetCol(minIdx, tmpCol1) // Compute the new xb. - xbVec := mat64.NewVector(len(xb), xb) + xbVec := mat.NewVector(len(xb), xb) err = xbVec.SolveVec(ab, bVec) if err != nil { break @@ -285,15 +285,15 @@ func simplex(initialBasic []int, c []float64, A mat64.Matrix, b []float64, tol f // computeMove computes how far can be moved replacing each index. The results // are stored into move. -func computeMove(move []float64, minIdx int, A mat64.Matrix, ab *mat64.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. - col := mat64.Col(nil, nonBasicIdx[minIdx], A) - aCol := mat64.NewVector(len(col), col) + col := mat.Col(nil, nonBasicIdx[minIdx], A) + aCol := mat.NewVector(len(col), col) // d = - Ab^-1 Ae nb, _ := ab.Dims() d := make([]float64, nb) - dVec := mat64.NewVector(nb, d) + dVec := mat.NewVector(nb, d) err := dVec.SolveVec(ab, aCol) if err != nil { return ErrLinSolve @@ -326,7 +326,7 @@ func computeMove(move []float64, minIdx int, A mat64.Matrix, ab *mat64.Dense, xb // replaceBland uses the Bland rule to find the indices to swap if the minimum // move is 0. The indices to be swapped are replace and minIdx (following the // nomenclature in the main routine). -func replaceBland(A mat64.Matrix, ab *mat64.Dense, xb []float64, basicIdxs, nonBasicIdx []int, r, move []float64) (replace, minIdx int, err error) { +func replaceBland(A mat.Matrix, ab *mat.Dense, xb []float64, basicIdxs, nonBasicIdx []int, r, move []float64) (replace, minIdx int, err error) { m, _ := A.Dims() // Use the traditional bland rule, except don't replace a constraint which // causes the new ab to be singular. @@ -353,10 +353,10 @@ func replaceBland(A mat64.Matrix, ab *mat64.Dense, xb []float64, basicIdxs, nonB } copy(biCopy, basicIdxs) biCopy[replace] = nonBasicIdx[minIdx] - abTmp := mat64.NewDense(m, len(biCopy), nil) + abTmp := mat.NewDense(m, len(biCopy), nil) extractColumns(abTmp, A, biCopy) // If the condition number is reasonable, use this index. - if mat64.Cond(abTmp, 1) < 1e16 { + if mat.Cond(abTmp, 1) < 1e16 { return replace, minIdx, nil } } @@ -364,7 +364,7 @@ func replaceBland(A mat64.Matrix, ab *mat64.Dense, xb []float64, basicIdxs, nonB return -1, -1, ErrBland } -func verifyInputs(initialBasic []int, c []float64, A mat64.Matrix, b []float64) error { +func verifyInputs(initialBasic []int, c []float64, A mat.Matrix, b []float64) error { m, n := A.Dims() if len(c) != n { panic("lp: c vector incorrect length") @@ -426,14 +426,14 @@ func verifyInputs(initialBasic []int, c []float64, A mat64.Matrix, b []float64) // // If the columns of A are not linearly independent or if the initial set is not // feasible, an error is returned. -func initializeFromBasic(xb []float64, ab *mat64.Dense, b []float64) error { +func initializeFromBasic(xb []float64, ab *mat.Dense, b []float64) error { m, _ := ab.Dims() if len(xb) != m { panic("simplex: bad xb length") } - xbMat := mat64.NewVector(m, xb) + xbMat := mat.NewVector(m, xb) - err := xbMat.SolveVec(ab, mat64.NewVector(m, b)) + err := xbMat.SolveVec(ab, mat.NewVector(m, b)) if err != nil { return errors.New("lp: subcolumns of A for supplied initial basic singular") } @@ -453,7 +453,7 @@ func initializeFromBasic(xb []float64, ab *mat64.Dense, b []float64) error { } // extractColumns copies the columns specified by cols into the columns of dst. -func extractColumns(dst *mat64.Dense, A mat64.Matrix, cols []int) { +func extractColumns(dst *mat.Dense, A mat.Matrix, cols []int) { r, c := dst.Dims() ra, _ := A.Dims() if ra != r { @@ -464,14 +464,14 @@ func extractColumns(dst *mat64.Dense, A mat64.Matrix, cols []int) { } col := make([]float64, r) for j, idx := range cols { - mat64.Col(col, idx, A) + mat.Col(col, idx, A) dst.SetCol(j, col) } } // findInitialBasic finds an initial basic solution, and returns the basic // indices, ab, and xb. -func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float64, error) { +func findInitialBasic(A mat.Matrix, b []float64) ([]int, *mat.Dense, []float64, error) { m, n := A.Dims() basicIdxs := findLinearlyIndependent(A) if len(basicIdxs) != m { @@ -480,7 +480,7 @@ func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float // It may be that this linearly independent basis is also a feasible set. If // so, the Phase I problem can be avoided. - ab := mat64.NewDense(m, len(basicIdxs), nil) + ab := mat.NewDense(m, len(basicIdxs), nil) extractColumns(ab, A, basicIdxs) xb := make([]float64, m) err := initializeFromBasic(xb, ab, b) @@ -519,7 +519,7 @@ func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float if i == minIdx { continue } - mat64.Col(col, v, A) + mat.Col(col, v, A) floats.Sub(aX1, col) } @@ -527,7 +527,7 @@ func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float // aNew = [A, a_{n+1}] // bNew = b // cNew = 1 for x_{n+1} - aNew := mat64.NewDense(m, n+1, nil) + aNew := mat.NewDense(m, n+1, nil) aNew.Copy(A) aNew.SetCol(n, aX1) basicIdxs[minIdx] = n // swap minIdx with n in the basic set. @@ -574,7 +574,7 @@ func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float } newBasic[addedIdx] = i if set { - mat64.Col(col, i, A) + mat.Col(col, i, A) ab.SetCol(addedIdx, col) } else { extractColumns(ab, A, newBasic) @@ -590,10 +590,10 @@ func findInitialBasic(A mat64.Matrix, b []float64) ([]int, *mat64.Dense, []float // findLinearlyIndependnt finds a set of linearly independent columns of A, and // returns the column indexes of the linearly independent columns. -func findLinearlyIndependent(A mat64.Matrix) []int { +func findLinearlyIndependent(A mat.Matrix) []int { m, n := A.Dims() idxs := make([]int, 0, m) - columns := mat64.NewDense(m, m, nil) + columns := mat.NewDense(m, m, nil) newCol := make([]float64, m) // Walk in reverse order because slack variables are typically the last columns // of A. @@ -601,7 +601,7 @@ func findLinearlyIndependent(A mat64.Matrix) []int { if len(idxs) == m { break } - mat64.Col(newCol, i, A) + mat.Col(newCol, i, A) columns.SetCol(len(idxs), newCol) if len(idxs) == 0 { // A column is linearly independent from the null set. @@ -609,7 +609,7 @@ func findLinearlyIndependent(A mat64.Matrix) []int { idxs = append(idxs, i) continue } - if mat64.Cond(columns.View(0, 0, m, len(idxs)+1), 1) > 1e12 { + if mat.Cond(columns.View(0, 0, m, len(idxs)+1), 1) > 1e12 { // Not linearly independent. continue } diff --git a/optimize/convex/lp/simplex_test.go b/optimize/convex/lp/simplex_test.go index 33d4359c..33f84551 100644 --- a/optimize/convex/lp/simplex_test.go +++ b/optimize/convex/lp/simplex_test.go @@ -10,7 +10,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) const convergenceTol = 1e-10 @@ -20,7 +20,7 @@ func TestSimplex(t *testing.T) { // during randomized testing. // TODO(btracey): Test specific problems with known solutions. for _, test := range []struct { - A mat64.Matrix + A mat.Matrix b []float64 c []float64 tol float64 @@ -28,7 +28,7 @@ func TestSimplex(t *testing.T) { }{ { // Basic feasible LP - A: mat64.NewDense(2, 4, []float64{ + A: mat.NewDense(2, 4, []float64{ -1, 2, 1, 0, 3, 1, 0, 1, }), @@ -39,56 +39,56 @@ func TestSimplex(t *testing.T) { }, { // Zero row that caused linear solver failure - A: mat64.NewDense(3, 5, []float64{0.09917822373225804, 0, 0, -0.2588175087223661, -0.5935518220870567, 1.301111422556007, 0.12220247487326946, 0, 0, -1.9194869979254463, 0, 0, 0, 0, -0.8588221231396473}), + A: mat.NewDense(3, 5, []float64{0.09917822373225804, 0, 0, -0.2588175087223661, -0.5935518220870567, 1.301111422556007, 0.12220247487326946, 0, 0, -1.9194869979254463, 0, 0, 0, 0, -0.8588221231396473}), b: []float64{0, 0, 0}, c: []float64{0, 0.598992624019304, 0, 0, 0}, }, { // Case that caused linear solver failure - A: mat64.NewDense(13, 26, []float64{-0.7001209024399848, -0.7027502615621812, -0, 0.7354444798695736, -0, 0.476457578966189, 0.7001209024399848, 0.7027502615621812, 0, -0.7354444798695736, 0, -0.476457578966189, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.8446087238391438, -0, -0, 0.7705609478497938, -0, -0, -2.7311218710244463, 0, 0, -0.7705609478497938, 0, 0, 2.7311218710244463, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, 0.8332519091897401, 0.7762132098737671, -0, -0, -0.052470638647269585, 0, -0.8332519091897401, -0.7762132098737671, 0, 0, 0.052470638647269585, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9898577208292023, 0.31653724289408824, -0, -0, 0.17797227766447388, 1.2702427184954932, -0.7998764021535656, -0.31653724289408824, 0, 0, -0.17797227766447388, -1.2702427184954932, 0.7998764021535656, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, 0.4206278126213235, -0.7253374879437113, 0, 0, 0, 0, -0.4206278126213235, 0.7253374879437113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0.7567988418466963, 0.3304567624749696, 0.8385927625193501, -0.0021606686026376387, -0, 0, 0.7567988418466963, -0.3304567624749696, -0.8385927625193501, 0.0021606686026376387, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2.230107839590404, -0.9897104202085316, -0, 0.24703471683023603, -0, -2.382860345431941, 0.6206871648345162, 0.9897104202085316, 0, -0.24703471683023603, 0, 2.382860345431941, -0.6206871648345162, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 1.4350469221322282, -0.9730343818431852, -0, 2.326429855201535, -0, -0.14347849887004038, -1.4350469221322282, 0.9730343818431852, 0, -2.326429855201535, 0, 0.14347849887004038, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.7943912888763849, -0.13735037357335078, -0.5101161104860161, -0, -0, -1.4790634590370297, 0.050911195996747316, 0.13735037357335078, 0.5101161104860161, 0, 0, 1.4790634590370297, -0.050911195996747316, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, -0, -0.2515400440591492, 0.2058339272568599, -0, -0, -1.314023802253438, 0, 0.2515400440591492, -0.2058339272568599, 0, 0, 1.314023802253438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0.08279503413614919, -0.16669071891829756, -0, -0.6208413721884664, -0, -0.6348258970402827, -0.08279503413614919, 0.16669071891829756, 0, 0.6208413721884664, 0, 0.6348258970402827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, -0, -0, 0.49634739711260845, -0, -0, -0, 0, 0, -0.49634739711260845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, -0.2797437186631715, -0.8356683570259136, 1.8970426594969672, -0.4095711945594497, 0.45831284820623924, -0.6109615338552246, 0.2797437186631715, 0.8356683570259136, -1.8970426594969672, 0.4095711945594497, -0.45831284820623924, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1}), + A: mat.NewDense(13, 26, []float64{-0.7001209024399848, -0.7027502615621812, -0, 0.7354444798695736, -0, 0.476457578966189, 0.7001209024399848, 0.7027502615621812, 0, -0.7354444798695736, 0, -0.476457578966189, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.8446087238391438, -0, -0, 0.7705609478497938, -0, -0, -2.7311218710244463, 0, 0, -0.7705609478497938, 0, 0, 2.7311218710244463, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, 0.8332519091897401, 0.7762132098737671, -0, -0, -0.052470638647269585, 0, -0.8332519091897401, -0.7762132098737671, 0, 0, 0.052470638647269585, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9898577208292023, 0.31653724289408824, -0, -0, 0.17797227766447388, 1.2702427184954932, -0.7998764021535656, -0.31653724289408824, 0, 0, -0.17797227766447388, -1.2702427184954932, 0.7998764021535656, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, 0.4206278126213235, -0.7253374879437113, 0, 0, 0, 0, -0.4206278126213235, 0.7253374879437113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0.7567988418466963, 0.3304567624749696, 0.8385927625193501, -0.0021606686026376387, -0, 0, 0.7567988418466963, -0.3304567624749696, -0.8385927625193501, 0.0021606686026376387, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2.230107839590404, -0.9897104202085316, -0, 0.24703471683023603, -0, -2.382860345431941, 0.6206871648345162, 0.9897104202085316, 0, -0.24703471683023603, 0, 2.382860345431941, -0.6206871648345162, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 1.4350469221322282, -0.9730343818431852, -0, 2.326429855201535, -0, -0.14347849887004038, -1.4350469221322282, 0.9730343818431852, 0, -2.326429855201535, 0, 0.14347849887004038, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.7943912888763849, -0.13735037357335078, -0.5101161104860161, -0, -0, -1.4790634590370297, 0.050911195996747316, 0.13735037357335078, 0.5101161104860161, 0, 0, 1.4790634590370297, -0.050911195996747316, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, -0, -0.2515400440591492, 0.2058339272568599, -0, -0, -1.314023802253438, 0, 0.2515400440591492, -0.2058339272568599, 0, 0, 1.314023802253438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0.08279503413614919, -0.16669071891829756, -0, -0.6208413721884664, -0, -0.6348258970402827, -0.08279503413614919, 0.16669071891829756, 0, 0.6208413721884664, 0, 0.6348258970402827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, -0, -0, 0.49634739711260845, -0, -0, -0, 0, 0, -0.49634739711260845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, -0.2797437186631715, -0.8356683570259136, 1.8970426594969672, -0.4095711945594497, 0.45831284820623924, -0.6109615338552246, 0.2797437186631715, 0.8356683570259136, -1.8970426594969672, 0.4095711945594497, -0.45831284820623924, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1}), b: []float64{-0.8446087238391436, 0, 1.9898577208292023, 0, 0, -2.230107839590404, 0, 0.20560871112361512, 0, 0, 0, 0, 0}, c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, }, { // Phase 1 of the above that panicked - A: mat64.NewDense(26, 52, []float64{0.7001209024399848, -0, -0, -0.31653724289408824, -0, -0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, -0, -0.08279503413614919, -0, 0.2797437186631715, -0.7001209024399848, 0, 0, 0.31653724289408824, 0, 0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, 0, 0.08279503413614919, 0, -0.2797437186631715, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7027502615621812, -0, -0.8332519091897401, -0, -0, 0.7567988418466963, -0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, -0, 0.8356683570259136, -0.7027502615621812, 0, 0.8332519091897401, 0, 0, -0.7567988418466963, 0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, 0, -0.8356683570259136, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.7705609478497938, -0.7762132098737671, -0, -0, -0.3304567624749696, -0.24703471683023603, -0, -0, -0.2058339272568599, -0, -0.49634739711260845, -1.8970426594969672, 0, 0.7705609478497938, 0.7762132098737671, 0, 0, 0.3304567624749696, 0.24703471683023603, 0, 0, 0.2058339272568599, 0, 0.49634739711260845, 1.8970426594969672, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7354444798695736, -0, -0, -0.17797227766447388, -0, -0.8385927625193501, -0, -2.326429855201535, -0, -0, 0.6208413721884664, -0, 0.4095711945594497, 0.7354444798695736, 0, 0, 0.17797227766447388, 0, 0.8385927625193501, 0, 2.326429855201535, 0, 0, -0.6208413721884664, 0, -0.4095711945594497, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, -0, 1.4790634590370297, -0, -0, -0, -0.45831284820623924, 0, 0, 0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, 0, -1.4790634590370297, 0, 0, 0, 0.45831284820623924, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, -0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, -0, 0.6109615338552246, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, 0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, 0, -0.6109615338552246, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7001209024399848, -0, -0, 0.31653724289408824, -0, -0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, -0, 0.08279503413614919, -0, -0.2797437186631715, 0.7001209024399848, 0, 0, -0.31653724289408824, 0, 0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, 0, -0.08279503413614919, 0, 0.2797437186631715, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7027502615621812, -0, 0.8332519091897401, -0, -0, -0.7567988418466963, -0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, -0, -0.8356683570259136, 0.7027502615621812, 0, -0.8332519091897401, 0, 0, 0.7567988418466963, 0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, 0, 0.8356683570259136, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0.7705609478497938, 0.7762132098737671, -0, -0, 0.3304567624749696, 0.24703471683023603, -0, -0, 0.2058339272568599, -0, 0.49634739711260845, 1.8970426594969672, 0, -0.7705609478497938, -0.7762132098737671, 0, 0, -0.3304567624749696, -0.24703471683023603, 0, 0, -0.2058339272568599, 0, -0.49634739711260845, -1.8970426594969672, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7354444798695736, -0, -0, 0.17797227766447388, -0, 0.8385927625193501, -0, 2.326429855201535, -0, -0, -0.6208413721884664, -0, -0.4095711945594497, -0.7354444798695736, 0, 0, -0.17797227766447388, 0, -0.8385927625193501, 0, -2.326429855201535, 0, 0, 0.6208413721884664, 0, 0.4095711945594497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, -0, -1.4790634590370297, -0, -0, -0, 0.45831284820623924, 0, 0, 0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, 0, 1.4790634590370297, 0, 0, 0, -0.45831284820623924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, -0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, -0, -0.6109615338552246, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, 0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, 0, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1.8446087238391438, 1, -0.9898577208292023, 1, 1, 2.230107839590404, 1, 0.7943912888763849, 1, 1, 1, 1, 1, -1.8446087238391438, -1, 0.9898577208292023, -1, -1, -2.230107839590404, -1, -0.7943912888763849, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + A: mat.NewDense(26, 52, []float64{0.7001209024399848, -0, -0, -0.31653724289408824, -0, -0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, -0, -0.08279503413614919, -0, 0.2797437186631715, -0.7001209024399848, 0, 0, 0.31653724289408824, 0, 0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, 0, 0.08279503413614919, 0, -0.2797437186631715, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7027502615621812, -0, -0.8332519091897401, -0, -0, 0.7567988418466963, -0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, -0, 0.8356683570259136, -0.7027502615621812, 0, 0.8332519091897401, 0, 0, -0.7567988418466963, 0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, 0, -0.8356683570259136, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.7705609478497938, -0.7762132098737671, -0, -0, -0.3304567624749696, -0.24703471683023603, -0, -0, -0.2058339272568599, -0, -0.49634739711260845, -1.8970426594969672, 0, 0.7705609478497938, 0.7762132098737671, 0, 0, 0.3304567624749696, 0.24703471683023603, 0, 0, 0.2058339272568599, 0, 0.49634739711260845, 1.8970426594969672, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7354444798695736, -0, -0, -0.17797227766447388, -0, -0.8385927625193501, -0, -2.326429855201535, -0, -0, 0.6208413721884664, -0, 0.4095711945594497, 0.7354444798695736, 0, 0, 0.17797227766447388, 0, 0.8385927625193501, 0, 2.326429855201535, 0, 0, -0.6208413721884664, 0, -0.4095711945594497, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, -0, 1.4790634590370297, -0, -0, -0, -0.45831284820623924, 0, 0, 0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, 0, -1.4790634590370297, 0, 0, 0, 0.45831284820623924, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, -0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, -0, 0.6109615338552246, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, 0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, 0, -0.6109615338552246, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7001209024399848, -0, -0, 0.31653724289408824, -0, -0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, -0, 0.08279503413614919, -0, -0.2797437186631715, 0.7001209024399848, 0, 0, -0.31653724289408824, 0, 0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, 0, -0.08279503413614919, 0, 0.2797437186631715, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7027502615621812, -0, 0.8332519091897401, -0, -0, -0.7567988418466963, -0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, -0, -0.8356683570259136, 0.7027502615621812, 0, -0.8332519091897401, 0, 0, 0.7567988418466963, 0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, 0, 0.8356683570259136, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0.7705609478497938, 0.7762132098737671, -0, -0, 0.3304567624749696, 0.24703471683023603, -0, -0, 0.2058339272568599, -0, 0.49634739711260845, 1.8970426594969672, 0, -0.7705609478497938, -0.7762132098737671, 0, 0, -0.3304567624749696, -0.24703471683023603, 0, 0, -0.2058339272568599, 0, -0.49634739711260845, -1.8970426594969672, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7354444798695736, -0, -0, 0.17797227766447388, -0, 0.8385927625193501, -0, 2.326429855201535, -0, -0, -0.6208413721884664, -0, -0.4095711945594497, -0.7354444798695736, 0, 0, -0.17797227766447388, 0, -0.8385927625193501, 0, -2.326429855201535, 0, 0, 0.6208413721884664, 0, 0.4095711945594497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, -0, -1.4790634590370297, -0, -0, -0, 0.45831284820623924, 0, 0, 0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, 0, 1.4790634590370297, 0, 0, 0, -0.45831284820623924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, -0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, -0, -0.6109615338552246, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, 0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, 0, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1.8446087238391438, 1, -0.9898577208292023, 1, 1, 2.230107839590404, 1, 0.7943912888763849, 1, 1, 1, 1, 1, -1.8446087238391438, -1, 0.9898577208292023, -1, -1, -2.230107839590404, -1, -0.7943912888763849, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), b: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, c: []float64{-0.8446087238391436, 0, 1.9898577208292023, 0, 0, -2.230107839590404, 0, 0.20560871112361512, 0, 0, 0, 0, 0, 0.8446087238391436, -0, -1.9898577208292023, -0, -0, 2.230107839590404, -0, -0.20560871112361512, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, { // Dense case that panicked. - A: mat64.NewDense(6, 15, []float64{0.3279477313560112, 0.04126296122557327, 0.24121743535067522, -0.8676933623438741, -0.3279477313560112, -0.04126296122557327, -0.24121743535067522, 0.8676933623438741, 1, 0, 0, 0, 0, 0, 1.3702148909442915, 0.43713186538468607, 0.8613818492485417, -0.9298615442657688, -0.037784779008231184, -0.43713186538468607, -0.8613818492485417, 0.9298615442657688, 0.037784779008231184, 0, 1, 0, 0, 0, 0, 0.3478112701177931, -0, 0.748352668598051, -0.4294796840343912, -0, 0, -0.748352668598051, 0.4294796840343912, 0, 0, 0, 1, 0, 0, 0, -1, -0, 1.1913912184457485, 1.732132186658447, 0.4026384828544584, 0, -1.1913912184457485, -1.732132186658447, -0.4026384828544584, 0, 0, 0, 1, 0, 0, -0.4598555419763902, -0, 1.2088959976921831, -0.7297794575275871, 1.9835614149566971, 0, -1.2088959976921831, 0.7297794575275871, -1.9835614149566971, 0, 0, 0, 0, 1, 0, 0.5986809560819324, 0.19738159369304414, -1.0647198575836367, -0, -0.7264943883762761, -0.19738159369304414, 1.0647198575836367, 0, 0.7264943883762761, 0, 0, 0, 0, 0, 1, 0.36269644970561576}), + A: mat.NewDense(6, 15, []float64{0.3279477313560112, 0.04126296122557327, 0.24121743535067522, -0.8676933623438741, -0.3279477313560112, -0.04126296122557327, -0.24121743535067522, 0.8676933623438741, 1, 0, 0, 0, 0, 0, 1.3702148909442915, 0.43713186538468607, 0.8613818492485417, -0.9298615442657688, -0.037784779008231184, -0.43713186538468607, -0.8613818492485417, 0.9298615442657688, 0.037784779008231184, 0, 1, 0, 0, 0, 0, 0.3478112701177931, -0, 0.748352668598051, -0.4294796840343912, -0, 0, -0.748352668598051, 0.4294796840343912, 0, 0, 0, 1, 0, 0, 0, -1, -0, 1.1913912184457485, 1.732132186658447, 0.4026384828544584, 0, -1.1913912184457485, -1.732132186658447, -0.4026384828544584, 0, 0, 0, 1, 0, 0, -0.4598555419763902, -0, 1.2088959976921831, -0.7297794575275871, 1.9835614149566971, 0, -1.2088959976921831, 0.7297794575275871, -1.9835614149566971, 0, 0, 0, 0, 1, 0, 0.5986809560819324, 0.19738159369304414, -1.0647198575836367, -0, -0.7264943883762761, -0.19738159369304414, 1.0647198575836367, 0, 0.7264943883762761, 0, 0, 0, 0, 0, 1, 0.36269644970561576}), b: []float64{2.3702148909442915, 1.3478112701177931, 0, -0.4598555419763902, 1.5986809560819324, 1.3626964497056158}, c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, }, { - A: mat64.NewDense(6, 11, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -0.719908817815329, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -1.142213296802784, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.5423586338987796, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0.6864090947259134, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0.4091621839837596, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1, -1.7416078575675549}), + A: mat.NewDense(6, 11, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -0.719908817815329, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -1.142213296802784, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.5423586338987796, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0.6864090947259134, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0.4091621839837596, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1, -1.7416078575675549}), b: []float64{0.28009118218467105, -0.14221329680278405, 0.4576413661012204, 0.3135909052740866, 1.4091621839837596, -1.7416078575675549}, c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, initialBasic: []int{10, 8, 7, 6, 5, 4}, }, { - A: mat64.NewDense(6, 10, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1}), + A: mat.NewDense(6, 10, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1}), b: []float64{0.28009118218467105, -0.14221329680278405, 0.4576413661012204, 0.3135909052740866, 1.4091621839837596, -1.7416078575675549}, c: []float64{-1.1951160054922971, -1.354633418345746, 1.1951160054922971, 1.354633418345746, 0, 0, 0, 0, 0, 0}, initialBasic: []int{0, 8, 7, 6, 5, 4}, }, { - A: mat64.NewDense(6, 14, []float64{-0.4398035705048233, -0, -1.1190414559968929, -0, 0.4398035705048233, 0, 1.1190414559968929, 0, 1, 0, 0, 0, 0, 0, -0, 0.45892918156139395, -0, -0, 0, -0.45892918156139395, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0.3163051515958635, -0, 0, 0, 0.3163051515958635, 0, 0, 0, 1, 0, 0, 0, -0, -0, -1.8226051692445888, -0.8154477101733032, 0, 0, 1.8226051692445888, 0.8154477101733032, 0, 0, 0, 1, 0, 0, -0, 1.0020104354806922, -2.80863692523519, -0.8493721031516384, 0, -1.0020104354806922, 2.80863692523519, 0.8493721031516384, 0, 0, 0, 0, 1, 0, -0.8292937871394104, -1.4615144665021647, -0, -0, 0.8292937871394104, 1.4615144665021647, 0, 0, 0, 0, 0, 0, 0, 1}), + A: mat.NewDense(6, 14, []float64{-0.4398035705048233, -0, -1.1190414559968929, -0, 0.4398035705048233, 0, 1.1190414559968929, 0, 1, 0, 0, 0, 0, 0, -0, 0.45892918156139395, -0, -0, 0, -0.45892918156139395, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0.3163051515958635, -0, 0, 0, 0.3163051515958635, 0, 0, 0, 1, 0, 0, 0, -0, -0, -1.8226051692445888, -0.8154477101733032, 0, 0, 1.8226051692445888, 0.8154477101733032, 0, 0, 0, 1, 0, 0, -0, 1.0020104354806922, -2.80863692523519, -0.8493721031516384, 0, -1.0020104354806922, 2.80863692523519, 0.8493721031516384, 0, 0, 0, 0, 1, 0, -0.8292937871394104, -1.4615144665021647, -0, -0, 0.8292937871394104, 1.4615144665021647, 0, 0, 0, 0, 0, 0, 0, 1}), b: []float64{0, -1.0154749704172474, 0, 0, 0, -1.5002324315812783}, c: []float64{1.0665389045026794, 0.097366273706136, 0, 2.7928153636989954, -1.0665389045026794, -0.097366273706136, -0, -2.7928153636989954, 0, 0, 0, 0, 0, 0}, initialBasic: []int{5, 12, 11, 10, 0, 8}, }, { // Bad Phase I setup. - A: mat64.NewDense(6, 7, []float64{1.4009742075419371, 0, 0.05737255493210325, -2.5954004393412915, 0, 1.561789236911904, 0, 0.17152506517602673, 0, 0, 0, 0, 0, -0.3458126550149948, 1.900744052464951, -0.32773164134097343, -0.9648201331251137, 0, 0, 0, 0, -1.3229549190526497, 0.0692227703722903, 0, 0, -0.1024297720479933, 0.4550740188869777, 0, 0.013599438965679167, 0, 0, 0, 0, 0, -0.1164365105021209, 0, 0, 0.4077091957443405, 1.5682816151954875, 0.8411734682369051, 0.22379142247562167, 1.2206581060250778}), + A: mat.NewDense(6, 7, []float64{1.4009742075419371, 0, 0.05737255493210325, -2.5954004393412915, 0, 1.561789236911904, 0, 0.17152506517602673, 0, 0, 0, 0, 0, -0.3458126550149948, 1.900744052464951, -0.32773164134097343, -0.9648201331251137, 0, 0, 0, 0, -1.3229549190526497, 0.0692227703722903, 0, 0, -0.1024297720479933, 0.4550740188869777, 0, 0.013599438965679167, 0, 0, 0, 0, 0, -0.1164365105021209, 0, 0, 0.4077091957443405, 1.5682816151954875, 0.8411734682369051, 0.22379142247562167, 1.2206581060250778}), b: []float64{0.3293809220378252, 0, -0.5688424847664554, 0, 0, 1.4832526082339592}, c: []float64{0.5246370956983506, -0.36608819899109946, 1.5854141981237713, 0.5170486527020665, 0, 1.4006819866163691, 0.7733814538809437}, }, { // The problem is feasible, but the PhaseI problem keeps the last // variable in the basis. - A: mat64.NewDense(2, 3, []float64{0.7171320440380402, 0, 0.22818288617480836, 0, -0.10030202006494793, -0.3282372661549324}), + A: mat.NewDense(2, 3, []float64{0.7171320440380402, 0, 0.22818288617480836, 0, -0.10030202006494793, -0.3282372661549324}), b: []float64{0.8913013436978257, 0}, c: []float64{0, 0, 1.16796158316812}, initialBasic: nil, @@ -98,7 +98,7 @@ func TestSimplex(t *testing.T) { // as infeasible. This is the dual. // Here, the phase I problem returns the value in the basis but equal // to epsilon and not 0. - A: mat64.NewDense(5, 11, []float64{0.48619717875196006, 0.5089083769874058, 1.4064796473022745, -0.48619717875196006, -0.5089083769874058, -1.4064796473022745, 1, 0, 0, 0, 0, 1.5169837857318682, -0, -0, -1.5169837857318682, 0, 0, 0, 1, 0, 0, 0, -1.3096160896447528, 0.12600426735917414, 0.296082394213142, 1.3096160896447528, -0.12600426735917414, -0.296082394213142, 0, 0, 1, 0, 0, -0, -0, 1.9870800277141467, 0, 0, -1.9870800277141467, 0, 0, 0, 1, 0, -0.3822356988571877, -0, -0.1793908926957139, 0.3822356988571877, 0, 0.1793908926957139, 0, 0, 0, 0, 1}), + A: mat.NewDense(5, 11, []float64{0.48619717875196006, 0.5089083769874058, 1.4064796473022745, -0.48619717875196006, -0.5089083769874058, -1.4064796473022745, 1, 0, 0, 0, 0, 1.5169837857318682, -0, -0, -1.5169837857318682, 0, 0, 0, 1, 0, 0, 0, -1.3096160896447528, 0.12600426735917414, 0.296082394213142, 1.3096160896447528, -0.12600426735917414, -0.296082394213142, 0, 0, 1, 0, 0, -0, -0, 1.9870800277141467, 0, 0, -1.9870800277141467, 0, 0, 0, 1, 0, -0.3822356988571877, -0, -0.1793908926957139, 0.3822356988571877, 0, 0.1793908926957139, 0, 0, 0, 0, 1}), b: []float64{0.6015865977347667, 0, -1.5648780993757594, 0, 0}, c: []float64{-0.642801659201449, -0.5412741400343285, -1.4634460998530177, 0.642801659201449, 0.5412741400343285, 1.4634460998530177, 0, 0, 0, 0, 0}, }, @@ -106,7 +106,7 @@ func TestSimplex(t *testing.T) { // Caused linear solve error. The error is because replacing the minimum // index in Bland causes the new basis to be singular. This // necessitates the ending loop in bland over possible moves. - A: mat64.NewDense(9, 23, []float64{-0.898219823758102, -0, -0, -0, 1.067555075209233, 1.581598470243863, -1.0656096883610071, 0.898219823758102, 0, 0, 0, -1.067555075209233, -1.581598470243863, 1.0656096883610071, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1.5657353278668433, 0.5798888118401012, -0, 0.14560553520321928, -0, -0, -0, 1.5657353278668433, -0.5798888118401012, 0, -0.14560553520321928, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1.5572250142582087, -0, -0, -0, -0, 0, 0, 1.5572250142582087, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.1266215512973428, -0, 1.0661059397023553, -0, 0, 0, 0, 1.1266215512973428, 0, -1.0661059397023553, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -2.060232129551813, 1.756900609902372, -0, -0, -0, -0, 0, 2.060232129551813, -1.756900609902372, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.0628806512935949, -0, -0, 0.3306985942820342, -0, 0.5013194822231914, -0, -1.0628806512935949, 0, 0, -0.3306985942820342, 0, -0.5013194822231914, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0.02053916418367785, 2.0967009672108627, -0, 1.276296057052031, -0, -0.8396554873675388, -0, 0.02053916418367785, -2.0967009672108627, 0, -1.276296057052031, 0, 0.8396554873675388, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1.5173172721095745, -0, -0, -0, -0, -0.7781977786718928, -0.08927683907374018, 1.5173172721095745, 0, 0, 0, 0, 0.7781977786718928, 0.08927683907374018, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, -0, -0, -0, -0, 0.39773149008355624, -0, 0, 0, 0, 0, 0, -0.39773149008355624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + A: mat.NewDense(9, 23, []float64{-0.898219823758102, -0, -0, -0, 1.067555075209233, 1.581598470243863, -1.0656096883610071, 0.898219823758102, 0, 0, 0, -1.067555075209233, -1.581598470243863, 1.0656096883610071, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1.5657353278668433, 0.5798888118401012, -0, 0.14560553520321928, -0, -0, -0, 1.5657353278668433, -0.5798888118401012, 0, -0.14560553520321928, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1.5572250142582087, -0, -0, -0, -0, 0, 0, 1.5572250142582087, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.1266215512973428, -0, 1.0661059397023553, -0, 0, 0, 0, 1.1266215512973428, 0, -1.0661059397023553, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -2.060232129551813, 1.756900609902372, -0, -0, -0, -0, 0, 2.060232129551813, -1.756900609902372, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.0628806512935949, -0, -0, 0.3306985942820342, -0, 0.5013194822231914, -0, -1.0628806512935949, 0, 0, -0.3306985942820342, 0, -0.5013194822231914, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0.02053916418367785, 2.0967009672108627, -0, 1.276296057052031, -0, -0.8396554873675388, -0, 0.02053916418367785, -2.0967009672108627, 0, -1.276296057052031, 0, 0.8396554873675388, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1.5173172721095745, -0, -0, -0, -0, -0.7781977786718928, -0.08927683907374018, 1.5173172721095745, 0, 0, 0, 0, 0.7781977786718928, 0.08927683907374018, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, -0, -0, -0, -0, 0.39773149008355624, -0, 0, 0, 0, 0, 0, -0.39773149008355624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), b: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, c: []float64{0.24547850255842107, -0.9373919913433648, 0, 0, 0, 0.2961224049153204, 0, -0.24547850255842107, 0.9373919913433648, -0, -0, -0, -0.2961224049153204, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, @@ -114,14 +114,14 @@ func TestSimplex(t *testing.T) { // Caused error because ALL of the possible replacements in Bland cause. // ab to be singular. This necessitates outer loop in bland over possible // moves. - A: mat64.NewDense(9, 23, []float64{0.6595219196440785, -0, -0, -1.8259394918781682, -0, -0, 0.005457361044175046, -0.6595219196440785, 0, 0, 1.8259394918781682, 0, 0, -0.005457361044175046, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.10352878714214864, -0, -0, -0, -0, 0.5945016966696087, 0, 0.10352878714214864, 0, 0, 0, 0, -0.5945016966696087, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0.31734882842876444, -0, -0, -0, -0, -0, -0.716633126367685, -0.31734882842876444, 0, 0, 0, 0, 0, 0.716633126367685, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0.7769812182932578, -0, -0.17370050158829553, 0.19405062263734607, -0, 1.1472330031002533, -0.6776631768730962, 0.7769812182932578, 0, 0.17370050158829553, -0.19405062263734607, 0, -1.1472330031002533, 0.6776631768730962, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0.8285611486611473, -0, -0, -0, -0, -0, 0, -0.8285611486611473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -2.088953453647358, 1.3286488791152795, -0, -0, -0, -0, 0.9147833235021142, 2.088953453647358, -1.3286488791152795, 0, 0, 0, 0, -0.9147833235021142, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, 0.6560365621262937, -0, -0, 0, 0, 0, 0, -0.6560365621262937, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0.8957188338098074, -0, -0, -0, -0, -0, -0, -0.8957188338098074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0.2761381891117365, -0, -0, -0, 1.1154921426237823, 0.06429872020552618, -0, 0.2761381891117365, 0, 0, 0, -1.1154921426237823, -0.06429872020552618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + A: mat.NewDense(9, 23, []float64{0.6595219196440785, -0, -0, -1.8259394918781682, -0, -0, 0.005457361044175046, -0.6595219196440785, 0, 0, 1.8259394918781682, 0, 0, -0.005457361044175046, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.10352878714214864, -0, -0, -0, -0, 0.5945016966696087, 0, 0.10352878714214864, 0, 0, 0, 0, -0.5945016966696087, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0.31734882842876444, -0, -0, -0, -0, -0, -0.716633126367685, -0.31734882842876444, 0, 0, 0, 0, 0, 0.716633126367685, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0.7769812182932578, -0, -0.17370050158829553, 0.19405062263734607, -0, 1.1472330031002533, -0.6776631768730962, 0.7769812182932578, 0, 0.17370050158829553, -0.19405062263734607, 0, -1.1472330031002533, 0.6776631768730962, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0.8285611486611473, -0, -0, -0, -0, -0, 0, -0.8285611486611473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -2.088953453647358, 1.3286488791152795, -0, -0, -0, -0, 0.9147833235021142, 2.088953453647358, -1.3286488791152795, 0, 0, 0, 0, -0.9147833235021142, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, 0.6560365621262937, -0, -0, 0, 0, 0, 0, -0.6560365621262937, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0.8957188338098074, -0, -0, -0, -0, -0, -0, -0.8957188338098074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0.2761381891117365, -0, -0, -0, 1.1154921426237823, 0.06429872020552618, -0, 0.2761381891117365, 0, 0, 0, -1.1154921426237823, -0.06429872020552618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), b: []float64{0, 0, 0, 0, 0.5046208538522362, 1.0859412982429362, -2.066283584195025, 0, -0.2604305274353169}, c: []float64{0, 0, 0, 0, 0, 0, -0.05793762969330718, -0, -0, -0, -0, -0, -0, 0.05793762969330718, 0, 0, 0, 0, 0, 0, 0, 0, 0}, initialBasic: []int{22, 11, 7, 19, 18, 17, 16, 15, 14}, }, { // Caused initial supplied basis of Phase I to be singular. - A: mat64.NewDense(7, 11, []float64{0, 0, 0, 0, 0, 0.6667874223914787, -0.04779440888372957, -0.810020924434026, 0, 1.4190243477163373, 0, 0, 1.0452496826112936, 1.1966134226828076, 0, 0, 0, 0, -0.676136041089015, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.123232807871834, 0.2795467733707712, 0.21997115467272987, 0, -0.1572003980840453, 0, 0, 0, 0, 0.5130196002804861, 0, -0.005957174211761673, 0.3262874931735277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.5582052881594286, 0, 0.3544026193217651, 0, -1.0761986709145068, 0, 0.2438593072108347, 0, 0, 0, 0, 1.387509848081664, 0, 0, 0.3958750570508226, 1.6281679612990678, 0, 0, -0.24638311667922103, 0, 0, 0, 0, 0, 0, -0.628850893994423}), + A: mat.NewDense(7, 11, []float64{0, 0, 0, 0, 0, 0.6667874223914787, -0.04779440888372957, -0.810020924434026, 0, 1.4190243477163373, 0, 0, 1.0452496826112936, 1.1966134226828076, 0, 0, 0, 0, -0.676136041089015, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.123232807871834, 0.2795467733707712, 0.21997115467272987, 0, -0.1572003980840453, 0, 0, 0, 0, 0.5130196002804861, 0, -0.005957174211761673, 0.3262874931735277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.5582052881594286, 0, 0.3544026193217651, 0, -1.0761986709145068, 0, 0.2438593072108347, 0, 0, 0, 0, 1.387509848081664, 0, 0, 0.3958750570508226, 1.6281679612990678, 0, 0, -0.24638311667922103, 0, 0, 0, 0, 0, 0, -0.628850893994423}), b: []float64{0.4135281763629115, 0, 0, 0, 0, 0, 0}, c: []float64{0.5586772876113472, 0, 0.14261332948424457, 0, -0.016394076753000086, -0.506087285562544, 0, 0.37619482505459145, 1.2943822852419233, 0.5887960293578207, 0}, }, @@ -153,7 +153,7 @@ func testRandomSimplex(t *testing.T, nTest int, pZero float64, maxN int, rnd *ra } return rnd.NormFloat64() } - a := mat64.NewDense(m, n, nil) + a := mat.NewDense(m, n, nil) for i := 0; i < m; i++ { for j := 0; j < n; j++ { a.Set(i, j, randValue()) @@ -173,13 +173,13 @@ func testRandomSimplex(t *testing.T, nTest int, pZero float64, maxN int, rnd *ra } } -func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat64.Matrix, b []float64, convergenceTol float64) error { +func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat.Matrix, b []float64, convergenceTol float64) error { 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 mat64.Vector - bCheck.MulVec(a, mat64.NewVector(len(primalX), primalX)) - if !mat64.EqualApprox(&bCheck, mat64.NewVector(len(b), b), 1e-10) { + var bCheck mat.Vector + bCheck.MulVec(a, mat.NewVector(len(primalX), primalX)) + if !mat.EqualApprox(&bCheck, mat.NewVector(len(b), b), 1e-10) { t.Errorf("No error in primal but solution infeasible") } } @@ -216,7 +216,7 @@ func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat64.Matrix, // minimize b^T * nu // subject to -A^T * nu <= c - negAT := &mat64.Dense{} + negAT := &mat.Dense{} negAT.Clone(a.T()) negAT.Scale(-1, negAT) cNew, aNew, bNew := Convert(b, negAT, c, nil, nil) @@ -224,9 +224,9 @@ func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat64.Matrix, dualOpt, dualX, _, errDual := simplex(nil, cNew, aNew, bNew, convergenceTol) if errDual == nil { // Check that the dual is feasible - var bCheck mat64.Vector - bCheck.MulVec(aNew, mat64.NewVector(len(dualX), dualX)) - if !mat64.EqualApprox(&bCheck, mat64.NewVector(len(bNew), bNew), 1e-10) { + var bCheck mat.Vector + bCheck.MulVec(aNew, mat.NewVector(len(dualX), dualX)) + if !mat.EqualApprox(&bCheck, mat.NewVector(len(bNew), bNew), 1e-10) { t.Errorf("No error in dual but solution infeasible") } } diff --git a/optimize/convex/lp/simplexexample_test.go b/optimize/convex/lp/simplexexample_test.go index ea8dc6c9..b0daa314 100644 --- a/optimize/convex/lp/simplexexample_test.go +++ b/optimize/convex/lp/simplexexample_test.go @@ -8,13 +8,13 @@ import ( "fmt" "log" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/optimize/convex/lp" ) func ExampleSimplex() { c := []float64{-1, -2, 0, 0} - A := mat64.NewDense(2, 4, []float64{-1, 2, 1, 0, 3, 1, 0, 1}) + A := mat.NewDense(2, 4, []float64{-1, 2, 1, 0, 3, 1, 0, 1}) b := []float64{4, 9} opt, x, err := lp.Simplex(c, A, b, 0, nil) diff --git a/optimize/functions/functions.go b/optimize/functions/functions.go index 279d0b62..37675592 100644 --- a/optimize/functions/functions.go +++ b/optimize/functions/functions.go @@ -8,7 +8,7 @@ import ( "math" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // Beale implements the Beale's function. @@ -56,7 +56,7 @@ func (Beale) Grad(grad, x []float64) { grad[1] = 2 * x[0] * (f1 + 2*f2*x[1] + 3*f3*x[1]*x[1]) } -func (Beale) Hess(hess mat64.MutableSymmetric, x []float64) { +func (Beale) Hess(hess mat.MutableSymmetric, x []float64) { if len(x) != 2 { panic("dimension of the problem must be 2") } @@ -558,7 +558,7 @@ func (BrownBadlyScaled) Grad(grad, x []float64) { grad[1] = 2*f2 + 2*f3*x[0] } -func (BrownBadlyScaled) Hess(hess mat64.MutableSymmetric, x []float64) { +func (BrownBadlyScaled) Hess(hess mat.MutableSymmetric, x []float64) { if len(x) != 2 { panic("dimension of the problem must be 2") } @@ -635,7 +635,7 @@ func (BrownAndDennis) Grad(grad, x []float64) { } } -func (BrownAndDennis) Hess(hess mat64.MutableSymmetric, x []float64) { +func (BrownAndDennis) Hess(hess mat.MutableSymmetric, x []float64) { if len(x) != 4 { panic("dimension of the problem must be 4") } @@ -1268,7 +1268,7 @@ func (PowellBadlyScaled) Grad(grad, x []float64) { grad[1] = 2 * (1e4*f1*x[0] - f2*math.Exp(-x[1])) } -func (PowellBadlyScaled) Hess(hess mat64.MutableSymmetric, x []float64) { +func (PowellBadlyScaled) Hess(hess mat.MutableSymmetric, x []float64) { if len(x) != 2 { panic("dimension of the problem must be 2") } @@ -1518,7 +1518,7 @@ func (Watson) Grad(grad, x []float64) { grad[1] += 2 * t } -func (Watson) Hess(hess mat64.MutableSymmetric, x []float64) { +func (Watson) Hess(hess mat.MutableSymmetric, x []float64) { dim := len(x) if dim != hess.Symmetric() { panic("incorrect size of the Hessian") @@ -1638,7 +1638,7 @@ func (Wood) Grad(grad, x []float64) { grad[3] = 2 * (90*f3 + 10*f5 - 0.1*f6) } -func (Wood) Hess(hess mat64.MutableSymmetric, x []float64) { +func (Wood) Hess(hess mat.MutableSymmetric, x []float64) { if len(x) != 4 { panic("dimension of the problem must be 4") } diff --git a/optimize/guessandcheck_test.go b/optimize/guessandcheck_test.go index 3b7fd910..d906f907 100644 --- a/optimize/guessandcheck_test.go +++ b/optimize/guessandcheck_test.go @@ -7,7 +7,7 @@ package optimize import ( "testing" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/optimize/functions" "gonum.org/v1/gonum/stat/distmv" ) @@ -18,7 +18,7 @@ func TestGuessAndCheck(t *testing.T) { Func: functions.ExtendedRosenbrock{}.Func, } mu := make([]float64, dim) - sigma := mat64.NewSymDense(dim, nil) + sigma := mat.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigma.SetSym(i, i, 1) } diff --git a/optimize/minimize.go b/optimize/minimize.go index 2b81694a..b5373e72 100644 --- a/optimize/minimize.go +++ b/optimize/minimize.go @@ -10,7 +10,7 @@ import ( "time" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // newLocation allocates a new locatian structure of the appropriate size. It @@ -26,7 +26,7 @@ func newLocation(dim int, method Needser) *Location { loc.Gradient = make([]float64, dim) } if method.Needs().Hessian { - loc.Hessian = mat64.NewSymDense(dim, nil) + loc.Hessian = mat.NewSymDense(dim, nil) } return loc } @@ -42,7 +42,7 @@ func copyLocation(dst, src *Location) { if src.Hessian != nil { if dst.Hessian == nil || dst.Hessian.Symmetric() != len(src.X) { - dst.Hessian = mat64.NewSymDense(len(src.X), nil) + dst.Hessian = mat.NewSymDense(len(src.X), nil) } dst.Hessian.CopySym(src.Hessian) } diff --git a/optimize/newton.go b/optimize/newton.go index f213067f..4cbc263f 100644 --- a/optimize/newton.go +++ b/optimize/newton.go @@ -7,7 +7,7 @@ package optimize import ( "math" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) const maxNewtonModifications = 20 @@ -48,8 +48,8 @@ type Newton struct { ls *LinesearchMethod - hess *mat64.SymDense // Storage for a copy of the Hessian matrix. - chol mat64.Cholesky // Storage for the Cholesky factorization. + hess *mat.SymDense // Storage for a copy of the Hessian matrix. + chol mat.Cholesky // Storage for the Cholesky factorization. tau float64 } @@ -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 := mat64.NewVector(dim, dir) - grad := mat64.NewVector(dim, loc.Gradient) + d := mat.NewVector(dim, dir) + grad := mat.NewVector(dim, loc.Gradient) n.hess.CopySym(loc.Hessian) // Find the smallest diagonal entry of the Hessian. diff --git a/optimize/types.go b/optimize/types.go index 4316f9cf..f6ecfc52 100644 --- a/optimize/types.go +++ b/optimize/types.go @@ -10,7 +10,7 @@ import ( "math" "time" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) const defaultGradientAbsTol = 1e-6 @@ -83,7 +83,7 @@ type Location struct { X []float64 F float64 Gradient []float64 - Hessian *mat64.SymDense + Hessian *mat.SymDense } // Result represents the answer of an optimization run. It contains the optimum @@ -131,7 +131,7 @@ type Problem struct { // Hess evaluates the Hessian at x and stores the result in-place in hess. // Hess must not modify x. - Hess func(hess mat64.MutableSymmetric, x []float64) + Hess func(hess mat.MutableSymmetric, x []float64) // Status reports the status of the objective function being optimized and any // error. This can be used to terminate early, for example when the function is @@ -161,10 +161,10 @@ func (p Problem) satisfies(method Needser) error { // // If Recorder is nil, no information will be recorded. type Settings struct { - UseInitialData bool // Use supplied information about the conditions at the initial x. - InitialValue float64 // Function value at the initial x. - InitialGradient []float64 // Gradient at the initial x. - InitialHessian *mat64.SymDense // Hessian at the initial x. + UseInitialData bool // Use supplied information about the conditions at the initial x. + InitialValue float64 // Function value at the initial x. + InitialGradient []float64 // Gradient at the initial x. + InitialHessian *mat.SymDense // Hessian at the initial x. // FunctionThreshold is the threshold for acceptably small values of the // objective function. FunctionThreshold status is returned if @@ -254,9 +254,9 @@ func resize(x []float64, dim int) []float64 { return x[:dim] } -func resizeSymDense(m *mat64.SymDense, dim int) *mat64.SymDense { +func resizeSymDense(m *mat.SymDense, dim int) *mat.SymDense { if m == nil || cap(m.RawSymmetric().Data) < dim*dim { - return mat64.NewSymDense(dim, nil) + return mat.NewSymDense(dim, nil) } - return mat64.NewSymDense(dim, m.RawSymmetric().Data[:dim*dim]) + return mat.NewSymDense(dim, m.RawSymmetric().Data[:dim*dim]) } diff --git a/optimize/unconstrained_test.go b/optimize/unconstrained_test.go index e45582e8..a8cb373f 100644 --- a/optimize/unconstrained_test.go +++ b/optimize/unconstrained_test.go @@ -10,7 +10,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/optimize/functions" ) @@ -1237,7 +1237,7 @@ func testLocal(t *testing.T, tests []unconstrainedTest, method Method) { test.p.Grad(settings.InitialGradient, test.x) } if method.Needs().Hessian { - settings.InitialHessian = mat64.NewSymDense(len(test.x), nil) + settings.InitialHessian = mat.NewSymDense(len(test.x), nil) test.p.Hess(settings.InitialHessian, test.x) } diff --git a/stat/boston_data_test.go b/stat/boston_data_test.go index 092bacae..e85a505f 100644 --- a/stat/boston_data_test.go +++ b/stat/boston_data_test.go @@ -4,7 +4,7 @@ package stat_test -import "gonum.org/v1/gonum/matrix/mat64" +import "gonum.org/v1/gonum/mat" // Boston Housing Data of Harrison and Rubinfeld (1978) // http://dx.doi.org/10.1016/0095-0696(78)90006-2 @@ -21,7 +21,7 @@ import "gonum.org/v1/gonum/matrix/mat64" // proportion of owner-occupied units built prior to 1940, // full-value property-tax rate per $10000, // median value of owner-occupied homes in $1000s. -var bostonData = mat64.NewDense(506, 11, []float64{ +var bostonData = mat.NewDense(506, 11, []float64{ 0.00632, 2.31000, 0.53800, 4.09000, 1.00000, 15.30000, 396.90000, 6.57500, 65.20000, 296.00000, 24.00000, 0.02731, 7.07000, 0.46900, 4.96710, 2.00000, 17.80000, 396.90000, 6.42100, 78.90000, 242.00000, 21.60000, 0.02729, 7.07000, 0.46900, 4.96710, 2.00000, 17.80000, 392.83000, 7.18500, 61.10000, 242.00000, 34.70000, diff --git a/stat/car_data_test.go b/stat/car_data_test.go index d8761a24..a3cdabb2 100644 --- a/stat/car_data_test.go +++ b/stat/car_data_test.go @@ -4,13 +4,13 @@ package stat_test -import "gonum.org/v1/gonum/matrix/mat64" +import "gonum.org/v1/gonum/mat" // ASA Car Exposition Data of Ramos and Donoho (1983) // http://lib.stat.cmu.edu/datasets/cars.desc // http://lib.stat.cmu.edu/datasets/cars.data // Columns are: displacement, horsepower, weight, acceleration, MPG. -var carData = mat64.NewDense(392, 5, []float64{ +var carData = mat.NewDense(392, 5, []float64{ 307.0, 130.0, 3504.0, 12.0, 18.0, 350.0, 165.0, 3693.0, 11.5, 15.0, 318.0, 150.0, 3436.0, 11.0, 18.0, diff --git a/stat/cca_example_test.go b/stat/cca_example_test.go index 3d311f02..eafc951d 100644 --- a/stat/cca_example_test.go +++ b/stat/cca_example_test.go @@ -9,13 +9,13 @@ import ( "log" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) // symView is a helper for getting a View of a SymDense. type symView struct { - sym *mat64.SymDense + sym *mat.SymDense i, j, r, c int } @@ -32,7 +32,7 @@ func (s symView) At(i, j int) float64 { return s.sym.At(s.i+i, s.j+j) } -func (s symView) T() mat64.Matrix { return mat64.Transpose{s} } +func (s symView) T() mat.Matrix { return mat.Transpose{s} } func ExampleCC() { // This example is directly analogous to Example 3.5 on page 87 of @@ -65,7 +65,7 @@ func ExampleCC() { ydata := bostonData.Slice(0, n, xd, xd+yd) // For comparison, calculate the correlation matrix for the original data. - var cor mat64.SymDense + var cor mat.SymDense stat.CorrelationMatrix(&cor, bostonData, nil) // Extract just those correlations that are between xdata and ydata. @@ -75,7 +75,7 @@ func ExampleCC() { // between the 5th variable of xdata (index of accessibility to radial // highways) and the 3rd variable of ydata (full-value property-tax rate per // $10000). - fmt.Printf("corRaw = %.4f", mat64.Formatted(corRaw, mat64.Prefix(" "))) + fmt.Printf("corRaw = %.4f", mat.Formatted(corRaw, mat.Prefix(" "))) // Calculate the canonical correlations. var cc stat.CC @@ -93,16 +93,16 @@ func ExampleCC() { // Canonical Correlation Matrix, or the correlations between the sphered // data. - var corSph mat64.Dense + var corSph mat.Dense corSph.Clone(pVecs) col := make([]float64, xd) for j := 0; j < yd; j++ { - mat64.Col(col, j, &corSph) + mat.Col(col, j, &corSph) floats.Scale(ccors[j], col) corSph.SetCol(j, col) } corSph.Product(&corSph, qVecs.T()) - fmt.Printf("\n\ncorSph = %.4f", mat64.Formatted(&corSph, mat64.Prefix(" "))) + fmt.Printf("\n\ncorSph = %.4f", mat.Formatted(&corSph, mat.Prefix(" "))) // Canonical Correlations. Note that the first canonical correlation is // 0.95, stronger than the greatest correlation in the original data, and @@ -110,13 +110,13 @@ func ExampleCC() { fmt.Printf("\n\nccors = %.4f", ccors) // Left and right eigenvectors of the canonical correlation matrix. - fmt.Printf("\n\npVecs = %.4f", mat64.Formatted(pVecs, mat64.Prefix(" "))) - fmt.Printf("\n\nqVecs = %.4f", mat64.Formatted(qVecs, mat64.Prefix(" "))) + fmt.Printf("\n\npVecs = %.4f", mat.Formatted(pVecs, mat.Prefix(" "))) + fmt.Printf("\n\nqVecs = %.4f", mat.Formatted(qVecs, mat.Prefix(" "))) // Canonical Correlation Transforms. These can be useful as they represent // the canonical variables as linear combinations of the original variables. - fmt.Printf("\n\nphiVs = %.4f", mat64.Formatted(phiVs, mat64.Prefix(" "))) - fmt.Printf("\n\npsiVs = %.4f", mat64.Formatted(psiVs, mat64.Prefix(" "))) + fmt.Printf("\n\nphiVs = %.4f", mat.Formatted(phiVs, mat.Prefix(" "))) + fmt.Printf("\n\npsiVs = %.4f", mat.Formatted(psiVs, mat.Prefix(" "))) // Output: // corRaw = ⎡-0.2192 0.3527 0.5828 -0.3883⎤ diff --git a/stat/cca_test.go b/stat/cca_test.go index 149f37da..4a6cc780 100644 --- a/stat/cca_test.go +++ b/stat/cca_test.go @@ -8,26 +8,26 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) func TestCanonicalCorrelations(t *testing.T) { tests: for i, test := range []struct { - xdata mat64.Matrix - ydata mat64.Matrix + xdata mat.Matrix + ydata mat.Matrix weights []float64 wantCorrs []float64 - wantpVecs *mat64.Dense - wantqVecs *mat64.Dense - wantphiVs *mat64.Dense - wantpsiVs *mat64.Dense + wantpVecs *mat.Dense + wantqVecs *mat.Dense + wantphiVs *mat.Dense + wantpsiVs *mat.Dense epsilon float64 }{ // Test results verified using R. { // Truncated iris data, Sepal vs Petal measurements. - xdata: mat64.NewDense(10, 2, []float64{ + xdata: mat.NewDense(10, 2, []float64{ 5.1, 3.5, 4.9, 3.0, 4.7, 3.2, @@ -39,7 +39,7 @@ tests: 4.4, 2.9, 4.9, 3.1, }), - ydata: mat64.NewDense(10, 2, []float64{ + ydata: mat.NewDense(10, 2, []float64{ 1.4, 0.2, 1.4, 0.2, 1.3, 0.2, @@ -52,19 +52,19 @@ tests: 1.5, 0.1, }), wantCorrs: []float64{0.7250624174504773, 0.5547679185730191}, - wantpVecs: mat64.NewDense(2, 2, []float64{ + wantpVecs: mat.NewDense(2, 2, []float64{ 0.0765914610875867, 0.9970625597666721, 0.9970625597666721, -0.0765914610875868, }), - wantqVecs: mat64.NewDense(2, 2, []float64{ + wantqVecs: mat.NewDense(2, 2, []float64{ 0.3075184850910837, 0.9515421069649439, 0.9515421069649439, -0.3075184850910837, }), - wantphiVs: mat64.NewDense(2, 2, []float64{ + wantphiVs: mat.NewDense(2, 2, []float64{ -1.9794877596804641, 5.2016325219025124, 4.5211829944066553, -2.7263663170835697, }), - wantpsiVs: mat64.NewDense(2, 2, []float64{ + wantpsiVs: mat.NewDense(2, 2, []float64{ -0.0613084818030103, 10.8514169865438941, 12.7209032660734298, -7.6793888180353775, }), @@ -79,21 +79,21 @@ tests: // Acceleration, MPG ydata: carData.Slice(0, 392, 3, 5), wantCorrs: []float64{0.8782187384352336, 0.6328187219216761}, - wantpVecs: mat64.NewDense(3, 2, []float64{ + wantpVecs: mat.NewDense(3, 2, []float64{ 0.3218296374829181, 0.3947540257657075, 0.4162807660635797, 0.7573719053303306, 0.8503740401982725, -0.5201509936144236, }), - wantqVecs: mat64.NewDense(2, 2, []float64{ + wantqVecs: mat.NewDense(2, 2, []float64{ -0.5161984172278830, -0.8564690269072364, -0.8564690269072364, 0.5161984172278830, }), - wantphiVs: mat64.NewDense(3, 2, []float64{ + wantphiVs: mat.NewDense(3, 2, []float64{ 0.0025033152994308, 0.0047795464118615, 0.0201923608080173, 0.0409150208725958, -0.0000247374128745, -0.0026766435161875, }), - wantpsiVs: mat64.NewDense(2, 2, []float64{ + wantpsiVs: mat.NewDense(2, 2, []float64{ -0.1666196759760772, -0.3637393866139658, -0.0915512109649727, 0.1077863777929168, }), @@ -116,7 +116,7 @@ tests: // Median value of owner-occupied homes in $1000s ydata: bostonData.Slice(0, 506, 7, 11), wantCorrs: []float64{0.9451239443886021, 0.6786622733370654, 0.5714338361583764, 0.2009739704710440}, - wantpVecs: mat64.NewDense(7, 4, []float64{ + wantpVecs: mat.NewDense(7, 4, []float64{ -0.2574391924541903, 0.0158477516621194, 0.2122169934631024, -0.0945733803894706, -0.4836594430018478, 0.3837101908138468, 0.1474448317415911, 0.6597324886718275, -0.0800776365873296, 0.3493556742809252, 0.3287336458109373, -0.2862040444334655, @@ -125,13 +125,13 @@ tests: -0.0990903250057199, 0.0503411215453873, 0.6384330631742202, 0.1022367136218303, 0.4260459963765036, 0.0323334351308141, -0.2289527516030810, 0.6419232947608805, }), - wantqVecs: mat64.NewDense(4, 4, []float64{ + wantqVecs: mat.NewDense(4, 4, []float64{ 0.0181660502363264, -0.1583489460479038, -0.0066723577642883, -0.9871935400650649, -0.2347699045986119, 0.9483314614936594, -0.1462420505631345, -0.1554470767919033, -0.9700704038477141, -0.2406071741000039, -0.0251838984227037, 0.0209134074358349, 0.0593000682318482, -0.1330460003097728, -0.9889057151969489, 0.0291161494720761, }), - wantphiVs: mat64.NewDense(7, 4, []float64{ + wantphiVs: mat.NewDense(7, 4, []float64{ -0.0027462234108197, 0.0093444513500898, 0.0489643932714296, -0.0154967189805819, -0.0428564455279537, -0.0241708702119420, 0.0360723472093996, 0.1838983230588095, -1.2248435648802380, 5.6030921364723980, 5.8094144583797025, -4.7926812190419676, @@ -140,7 +140,7 @@ tests: -0.0233270323101624, 0.1046330818178399, 0.3853045975077387, -0.0160927870102877, 0.0001293051387859, 0.0004540746921446, -0.0030296315865440, 0.0081895477974654, }), - wantpsiVs: mat64.NewDense(4, 4, []float64{ + wantpsiVs: mat.NewDense(4, 4, []float64{ 0.0301593362017375, -0.3002219289647127, 0.0878217377593682, -1.9583226531517062, -0.0065483104073892, 0.0392212086716247, -0.0117570776209991, -0.0061113064481860, -0.0052075523350125, -0.0045770200452960, -0.0022762313289592, 0.0008441873006821, @@ -151,8 +151,8 @@ tests: } { var cc stat.CC var corrs []float64 - var pVecs, qVecs *mat64.Dense - var phiVs, psiVs *mat64.Dense + var pVecs, qVecs *mat.Dense + var phiVs, psiVs *mat.Dense for j := 0; j < 2; j++ { err := cc.CanonicalCorrelations(test.xdata, test.ydata, test.weights) if err != nil { @@ -170,21 +170,21 @@ tests: t.Errorf("%d use %d: unexpected variance result got:%v, want:%v", i, j, corrs, test.wantCorrs) } - if !mat64.EqualApprox(pVecs, test.wantpVecs, test.epsilon) { + if !mat.EqualApprox(pVecs, test.wantpVecs, test.epsilon) { t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", - i, j, mat64.Formatted(pVecs), mat64.Formatted(test.wantpVecs)) + i, j, mat.Formatted(pVecs), mat.Formatted(test.wantpVecs)) } - if !mat64.EqualApprox(qVecs, test.wantqVecs, test.epsilon) { + if !mat.EqualApprox(qVecs, test.wantqVecs, test.epsilon) { t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", - i, j, mat64.Formatted(qVecs), mat64.Formatted(test.wantqVecs)) + i, j, mat.Formatted(qVecs), mat.Formatted(test.wantqVecs)) } - if !mat64.EqualApprox(phiVs, test.wantphiVs, test.epsilon) { + if !mat.EqualApprox(phiVs, test.wantphiVs, test.epsilon) { t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", - i, j, mat64.Formatted(phiVs), mat64.Formatted(test.wantphiVs)) + i, j, mat.Formatted(phiVs), mat.Formatted(test.wantphiVs)) } - if !mat64.EqualApprox(psiVs, test.wantpsiVs, test.epsilon) { + if !mat.EqualApprox(psiVs, test.wantpsiVs, test.epsilon) { t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", - i, j, mat64.Formatted(psiVs), mat64.Formatted(test.wantpsiVs)) + i, j, mat.Formatted(psiVs), mat.Formatted(test.wantpsiVs)) } } } diff --git a/stat/distmat/wishart.go b/stat/distmat/wishart.go index f384c30c..877ffaab 100644 --- a/stat/distmat/wishart.go +++ b/stat/distmat/wishart.go @@ -9,9 +9,8 @@ import ( "math/rand" "sync" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/mathext" - "gonum.org/v1/gonum/matrix" - "gonum.org/v1/gonum/matrix/mat64" "gonum.org/v1/gonum/stat/distuv" ) @@ -30,12 +29,12 @@ type Wishart struct { src *rand.Rand dim int - cholv mat64.Cholesky + cholv mat.Cholesky logdetv float64 - upper mat64.TriDense + upper mat.TriDense once sync.Once - v *mat64.SymDense // only stored if needed + v *mat.SymDense // only stored if needed } // NewWishart returns a new Wishart distribution with the given shape matrix and @@ -43,18 +42,18 @@ type Wishart struct { // successful. // // NewWishart panics if nu <= d - 1 where d is the order of v. -func NewWishart(v mat64.Symmetric, nu float64, src *rand.Rand) (*Wishart, bool) { +func NewWishart(v mat.Symmetric, nu float64, src *rand.Rand) (*Wishart, bool) { dim := v.Symmetric() if nu <= float64(dim-1) { panic("wishart: nu must be greater than dim-1") } - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(v) if !ok { return nil, false } - var u mat64.TriDense + var u mat.TriDense u.UFromCholesky(&chol) w := &Wishart{ @@ -73,9 +72,9 @@ func NewWishart(v mat64.Symmetric, nu float64, src *rand.Rand) (*Wishart, bool) // If x is nil, a new matrix is allocated and returned. If x is not nil, the // result is stored in-place into x and MeanSym will panic if the order of x // is not equal to the order of the receiver. -func (w *Wishart) MeanSym(x *mat64.SymDense) *mat64.SymDense { +func (w *Wishart) MeanSym(x *mat.SymDense) *mat.SymDense { if x == nil { - x = mat64.NewSymDense(w.dim, nil) + x = mat.NewSymDense(w.dim, nil) } d := x.Symmetric() if d != w.dim { @@ -89,7 +88,7 @@ func (w *Wishart) MeanSym(x *mat64.SymDense) *mat64.SymDense { // ProbSym returns the probability of the symmetric matrix x. If x is not positive // definite (the Cholesky decomposition fails), it has 0 probability. -func (w *Wishart) ProbSym(x mat64.Symmetric) float64 { +func (w *Wishart) ProbSym(x mat.Symmetric) float64 { return math.Exp(w.LogProbSym(x)) } @@ -97,12 +96,12 @@ func (w *Wishart) ProbSym(x mat64.Symmetric) float64 { // // LogProbSym returns -∞ if the input matrix is not positive definite (the Cholesky // decomposition fails). -func (w *Wishart) LogProbSym(x mat64.Symmetric) float64 { +func (w *Wishart) LogProbSym(x mat.Symmetric) float64 { dim := x.Symmetric() if dim != w.dim { panic(badDim) } - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(x) if !ok { return math.Inf(-1) @@ -112,7 +111,7 @@ func (w *Wishart) LogProbSym(x mat64.Symmetric) float64 { // LogProbSymChol returns the log of the probability of the input symmetric matrix // given its Cholesky decomposition. -func (w *Wishart) LogProbSymChol(cholX *mat64.Cholesky) float64 { +func (w *Wishart) LogProbSymChol(cholX *mat.Cholesky) float64 { dim := cholX.Size() if dim != w.dim { panic(badDim) @@ -120,7 +119,7 @@ func (w *Wishart) LogProbSymChol(cholX *mat64.Cholesky) float64 { return w.logProbSymChol(cholX) } -func (w *Wishart) logProbSymChol(cholX *mat64.Cholesky) float64 { +func (w *Wishart) logProbSymChol(cholX *mat.Cholesky) float64 { // The PDF is // p(X) = [|X|^((ν-d-1)/2) * exp(-tr(V^-1 * X)/2)] / [2^(ν*d/2) * |V|^(ν/2) * Γ_d(ν/2)] // The LogPDF is thus @@ -128,16 +127,16 @@ func (w *Wishart) logProbSymChol(cholX *mat64.Cholesky) float64 { logdetx := cholX.LogDet() // Compute tr(V^-1 * X), using the fact that X = U^T * U. - var u mat64.TriDense + var u mat.TriDense u.UFromCholesky(cholX) - var vinvx mat64.Dense + var vinvx mat.Dense err := vinvx.SolveCholesky(&w.cholv, u.T()) if err != nil { return math.Inf(-1) } vinvx.Mul(&vinvx, &u) - tr := mat64.Trace(&vinvx) + tr := mat.Trace(&vinvx) fnu := float64(w.nu) fdim := float64(w.dim) @@ -146,18 +145,18 @@ func (w *Wishart) logProbSymChol(cholX *mat64.Cholesky) float64 { } // RandSym generates a random symmetric matrix from the distribution. -func (w *Wishart) RandSym(x *mat64.SymDense) *mat64.SymDense { +func (w *Wishart) RandSym(x *mat.SymDense) *mat.SymDense { if x == nil { - x = &mat64.SymDense{} + x = &mat.SymDense{} } - var c mat64.Cholesky + var c mat.Cholesky w.RandChol(&c) x.FromCholesky(&c) return x } // RandChol generates the Cholesky decomposition of a random matrix from the distribution. -func (w *Wishart) RandChol(c *mat64.Cholesky) *mat64.Cholesky { +func (w *Wishart) RandChol(c *mat.Cholesky) *mat.Cholesky { // TODO(btracey): Modify the code if the underlying data from c is exposed // to avoid the dim^2 allocation here. @@ -179,7 +178,7 @@ func (w *Wishart) RandChol(c *mat64.Cholesky) *mat64.Cholesky { Source: w.src, } - t := mat64.NewTriDense(w.dim, matrix.Upper, nil) + t := mat.NewTriDense(w.dim, mat.Upper, nil) for i := 0; i < w.dim; i++ { v := distuv.ChiSquared{ K: w.nu - float64(i), @@ -195,7 +194,7 @@ func (w *Wishart) RandChol(c *mat64.Cholesky) *mat64.Cholesky { t.MulTri(t, &w.upper) if c == nil { - c = &mat64.Cholesky{} + c = &mat.Cholesky{} } c.SetFromU(t) return c @@ -204,7 +203,7 @@ func (w *Wishart) RandChol(c *mat64.Cholesky) *mat64.Cholesky { // setV computes and stores the covariance matrix of the distribution. func (w *Wishart) setV() { w.once.Do(func() { - w.v = mat64.NewSymDense(w.dim, nil) + w.v = mat.NewSymDense(w.dim, nil) w.v.FromCholesky(&w.cholv) }) } diff --git a/stat/distmat/wishart_test.go b/stat/distmat/wishart_test.go index 0245bf96..5943ecca 100644 --- a/stat/distmat/wishart_test.go +++ b/stat/distmat/wishart_test.go @@ -10,39 +10,39 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func TestWishart(t *testing.T) { for c, test := range []struct { - v *mat64.SymDense + v *mat.SymDense nu float64 - xs []*mat64.SymDense + xs []*mat.SymDense lps []float64 }{ // Logprob data compared with scipy. { - v: mat64.NewSymDense(2, []float64{1, 0, 0, 1}), + v: mat.NewSymDense(2, []float64{1, 0, 0, 1}), nu: 4, - xs: []*mat64.SymDense{ - mat64.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), + xs: []*mat.SymDense{ + mat.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), }, lps: []float64{-4.2357432031863409}, }, { - v: mat64.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), + v: mat.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), nu: 5, - xs: []*mat64.SymDense{ - mat64.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), - mat64.NewSymDense(2, []float64{0.3, -0.1, -0.1, 0.7}), + xs: []*mat.SymDense{ + mat.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), + mat.NewSymDense(2, []float64{0.3, -0.1, -0.1, 0.7}), }, lps: []float64{-4.2476495605333575, -4.9993285370378633}, }, { - v: mat64.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), + v: mat.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), nu: 5, - xs: []*mat64.SymDense{ - mat64.NewSymDense(3, []float64{1, 0.2, -0.3, 0.2, 0.6, -0.2, -0.3, -0.2, 6}), + xs: []*mat.SymDense{ + mat.NewSymDense(3, []float64{1, 0.2, -0.3, 0.2, 0.6, -0.2, -0.3, -0.2, 6}), }, lps: []float64{-11.010982249229421}, }, @@ -54,7 +54,7 @@ func TestWishart(t *testing.T) { for i, x := range test.xs { lp := w.LogProbSym(x) - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(x) if !ok { panic("bad test") @@ -80,25 +80,25 @@ func TestWishart(t *testing.T) { func TestWishartRand(t *testing.T) { for c, test := range []struct { - v *mat64.SymDense + v *mat.SymDense nu float64 samples int tol float64 }{ { - v: mat64.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), + v: mat.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), nu: 5, samples: 30000, tol: 3e-2, }, { - v: mat64.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), + v: mat.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), nu: 5, samples: 300000, tol: 3e-2, }, { - v: mat64.NewSymDense(4, []float64{ + v: mat.NewSymDense(4, []float64{ 0.8, 0.3, 0.1, -0.2, 0.3, 0.7, -0.1, 0.4, 0.1, -0.1, 7, 1, @@ -114,16 +114,16 @@ func TestWishartRand(t *testing.T) { if !ok { panic("bad test") } - mean := mat64.NewSymDense(dim, nil) - x := mat64.NewSymDense(dim, nil) + mean := mat.NewSymDense(dim, nil) + x := mat.NewSymDense(dim, nil) for i := 0; i < test.samples; i++ { w.RandSym(x) x.ScaleSym(1/float64(test.samples), x) mean.AddSym(mean, x) } trueMean := w.MeanSym(nil) - if !mat64.EqualApprox(trueMean, mean, test.tol) { - t.Errorf("Case %d: Mismatch between estimated and true mean. Got\n%0.4v\nWant\n%0.4v\n", c, mat64.Formatted(mean), mat64.Formatted(trueMean)) + if !mat.EqualApprox(trueMean, mean, test.tol) { + t.Errorf("Case %d: Mismatch between estimated and true mean. Got\n%0.4v\nWant\n%0.4v\n", c, mat.Formatted(mean), mat.Formatted(trueMean)) } } } diff --git a/stat/distmv/dirichlet.go b/stat/distmv/dirichlet.go index a13810c9..fbf2128f 100644 --- a/stat/distmv/dirichlet.go +++ b/stat/distmv/dirichlet.go @@ -9,7 +9,7 @@ import ( "math/rand" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat/distuv" ) @@ -61,11 +61,11 @@ func NewDirichlet(alpha []float64, src *rand.Rand) *Dirichlet { // covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] // If the input matrix is nil a new matrix is allocated, otherwise the result // is stored in-place into the input. -func (d *Dirichlet) CovarianceMatrix(cov *mat64.SymDense) *mat64.SymDense { +func (d *Dirichlet) CovarianceMatrix(cov *mat.SymDense) *mat.SymDense { if cov == nil { - cov = mat64.NewSymDense(d.Dim(), nil) + cov = mat.NewSymDense(d.Dim(), nil) } else if cov.Symmetric() == 0 { - *cov = *(cov.GrowSquare(d.dim).(*mat64.SymDense)) + *cov = *(cov.GrowSquare(d.dim).(*mat.SymDense)) } else if cov.Symmetric() != d.dim { panic("normal: input matrix size mismatch") } diff --git a/stat/distmv/dirichlet_test.go b/stat/distmv/dirichlet_test.go index 9542e193..b0c9464e 100644 --- a/stat/distmv/dirichlet_test.go +++ b/stat/distmv/dirichlet_test.go @@ -9,7 +9,7 @@ import ( "math/rand" "testing" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func TestDirichlet(t *testing.T) { @@ -64,7 +64,7 @@ func TestDirichlet(t *testing.T) { } { d := test.Dir dim := d.Dim() - x := mat64.NewDense(test.N, dim, nil) + x := mat.NewDense(test.N, dim, nil) generateSamples(x, d) checkMean(t, cas, x, d, 1e-3) checkCov(t, cas, x, d, 1e-3) diff --git a/stat/distmv/general_test.go b/stat/distmv/general_test.go index bcfa733f..05e65f7b 100644 --- a/stat/distmv/general_test.go +++ b/stat/distmv/general_test.go @@ -9,7 +9,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) @@ -37,7 +37,7 @@ func testProbability(t *testing.T, cases []probCase) { } } -func generateSamples(x *mat64.Dense, r Rander) { +func generateSamples(x *mat.Dense, r Rander) { n, _ := x.Dims() for i := 0; i < n; i++ { r.Rand(x.RawRowView(i)) @@ -48,7 +48,7 @@ type Meaner interface { Mean([]float64) []float64 } -func checkMean(t *testing.T, cas int, x *mat64.Dense, m Meaner, tol float64) { +func checkMean(t *testing.T, cas int, x *mat.Dense, m Meaner, tol float64) { mean := m.Mean(nil) // Check that the answer is identical when using nil or non-nil. @@ -63,7 +63,7 @@ func checkMean(t *testing.T, cas int, x *mat64.Dense, m Meaner, tol float64) { col := make([]float64, r) meanEst := make([]float64, len(mean)) for i := range meanEst { - meanEst[i] = stat.Mean(mat64.Col(col, i, x), nil) + meanEst[i] = stat.Mean(mat.Col(col, i, x), nil) } if !floats.EqualApprox(mean, meanEst, tol) { t.Errorf("Returned mean and sample mean mismatch. Case %v. Empirical %v, returned %v", cas, meanEst, mean) @@ -71,26 +71,26 @@ func checkMean(t *testing.T, cas int, x *mat64.Dense, m Meaner, tol float64) { } type Cover interface { - CovarianceMatrix(*mat64.SymDense) *mat64.SymDense + CovarianceMatrix(*mat.SymDense) *mat.SymDense } -func checkCov(t *testing.T, cas int, x *mat64.Dense, c Cover, tol float64) { +func checkCov(t *testing.T, cas int, x *mat.Dense, c Cover, tol float64) { cov := c.CovarianceMatrix(nil) n := cov.Symmetric() - cov2 := mat64.NewSymDense(n, nil) + cov2 := mat.NewSymDense(n, nil) c.CovarianceMatrix(cov2) - if !mat64.Equal(cov, cov2) { + if !mat.Equal(cov, cov2) { t.Errorf("Cov mismatch when providing nil and matrix. Case %v", cas) } - var cov3 mat64.SymDense + var cov3 mat.SymDense c.CovarianceMatrix(&cov3) - if !mat64.Equal(cov, &cov3) { + if !mat.Equal(cov, &cov3) { t.Errorf("Cov mismatch when providing zero matrix. Case %v", cas) } // Check that the covariance matrix matches the samples covEst := stat.CovarianceMatrix(nil, x, nil) - if !mat64.EqualApprox(covEst, cov, tol) { - t.Errorf("Return cov and sample cov mismatch. Cas %v.\nGot:\n%0.4v\nWant:\n%0.4v", cas, mat64.Formatted(cov), mat64.Formatted(covEst)) + if !mat.EqualApprox(covEst, cov, tol) { + t.Errorf("Return cov and sample cov mismatch. Cas %v.\nGot:\n%0.4v\nWant:\n%0.4v", cas, mat.Formatted(cov), mat.Formatted(covEst)) } } diff --git a/stat/distmv/normal.go b/stat/distmv/normal.go index 55a6df5f..93dddc13 100644 --- a/stat/distmv/normal.go +++ b/stat/distmv/normal.go @@ -9,7 +9,7 @@ import ( "math/rand" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" "gonum.org/v1/gonum/stat/distuv" ) @@ -26,10 +26,10 @@ var ( type Normal struct { mu []float64 - sigma mat64.SymDense + sigma mat.SymDense - chol mat64.Cholesky - lower mat64.TriDense + chol mat.Cholesky + lower mat.TriDense logSqrtDet float64 dim int @@ -39,7 +39,7 @@ type Normal struct { // NewNormal creates a new Normal with the given mean and covariance matrix. // NewNormal panics if len(mu) == 0, or if len(mu) != sigma.N. If the covariance // matrix is not positive-definite, the returned boolean is false. -func NewNormal(mu []float64, sigma mat64.Symmetric, src *rand.Rand) (*Normal, bool) { +func NewNormal(mu []float64, sigma mat.Symmetric, src *rand.Rand) (*Normal, bool) { if len(mu) == 0 { panic(badZeroDimension) } @@ -57,7 +57,7 @@ func NewNormal(mu []float64, sigma mat64.Symmetric, src *rand.Rand) (*Normal, bo if !ok { return nil, false } - n.sigma = *mat64.NewSymDense(dim, nil) + n.sigma = *mat.NewSymDense(dim, nil) n.sigma.CopySym(sigma) n.lower.LFromCholesky(&n.chol) n.logSqrtDet = 0.5 * n.chol.LogDet() @@ -67,7 +67,7 @@ func NewNormal(mu []float64, sigma mat64.Symmetric, src *rand.Rand) (*Normal, bo // NewNormalChol creates a new Normal distribution with the given mean and // covariance matrix represented by its Cholesky decomposition. NewNormalChol // panics if len(mu) is not equal to chol.Size(). -func NewNormalChol(mu []float64, chol *mat64.Cholesky, src *rand.Rand) *Normal { +func NewNormalChol(mu []float64, chol *mat.Cholesky, src *rand.Rand) *Normal { dim := len(mu) if dim != chol.Size() { panic(badSizeMismatch) @@ -89,7 +89,7 @@ func NewNormalChol(mu []float64, chol *mat64.Cholesky, src *rand.Rand) *Normal { // panics if len(mu) is not equal to prec.Symmetric(). If the precision matrix // is not positive-definite, NewNormalPrecision returns nil for norm and false // for ok. -func NewNormalPrecision(mu []float64, prec *mat64.SymDense, src *rand.Rand) (norm *Normal, ok bool) { +func NewNormalPrecision(mu []float64, prec *mat.SymDense, src *rand.Rand) (norm *Normal, ok bool) { if len(mu) == 0 { panic(badZeroDimension) } @@ -102,12 +102,12 @@ func NewNormalPrecision(mu []float64, prec *mat64.SymDense, src *rand.Rand) (nor // is much better, but this still loses precision. It is worth considering if // instead the precision matrix should be stored explicitly and used instead // of the Cholesky decomposition of the covariance matrix where appropriate. - var chol mat64.Cholesky + var chol mat.Cholesky ok = chol.Factorize(prec) if !ok { return nil, false } - var sigma mat64.SymDense + var sigma mat.SymDense sigma.InverseCholesky(&chol) return NewNormal(mu, &sigma, src) } @@ -154,9 +154,9 @@ func (n *Normal) ConditionNormal(observed []int, values []float64, src *rand.Ran // covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] // If the input matrix is nil a new matrix is allocated, otherwise the result // is stored in-place into the input. -func (n *Normal) CovarianceMatrix(s *mat64.SymDense) *mat64.SymDense { +func (n *Normal) CovarianceMatrix(s *mat.SymDense) *mat.SymDense { if s == nil { - s = mat64.NewSymDense(n.Dim(), nil) + s = mat.NewSymDense(n.Dim(), nil) } sn := s.Symmetric() if sn != n.Dim() { @@ -183,7 +183,7 @@ func (n *Normal) LogProb(x []float64) float64 { panic(badSizeMismatch) } c := -0.5*float64(dim)*logTwoPi - n.logSqrtDet - dst := stat.Mahalanobis(mat64.NewVector(dim, x), mat64.NewVector(dim, n.mu), &n.chol) + dst := stat.Mahalanobis(mat.NewVector(dim, x), mat.NewVector(dim, n.mu), &n.chol) return c - 0.5*dst*dst } @@ -199,7 +199,7 @@ func (n *Normal) MarginalNormal(vars []int, src *rand.Rand) (*Normal, bool) { for i, v := range vars { newMean[i] = n.mu[v] } - var s mat64.SymDense + var s mat.SymDense s.SubsetSym(&n.sigma, vars) return NewNormal(newMean, &s, src) } @@ -308,8 +308,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 := mat64.NewVector(n.dim, normal) - dstVec := mat64.NewVector(n.dim, dst) + srcVec := mat.NewVector(n.dim, normal) + dstVec := mat.NewVector(n.dim, dst) dstVec.MulVec(&n.lower, srcVec) floats.Add(dst, n.mu) return dst diff --git a/stat/distmv/normal_test.go b/stat/distmv/normal_test.go index a855077f..39e963d9 100644 --- a/stat/distmv/normal_test.go +++ b/stat/distmv/normal_test.go @@ -10,24 +10,24 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) type mvTest struct { Mu []float64 - Sigma *mat64.SymDense + Sigma *mat.SymDense Loc []float64 Logprob float64 Prob float64 } func TestNormProbs(t *testing.T) { - dist1, ok := NewNormal([]float64{0, 0}, mat64.NewSymDense(2, []float64{1, 0, 0, 1}), nil) + dist1, ok := NewNormal([]float64{0, 0}, mat.NewSymDense(2, []float64{1, 0, 0, 1}), nil) if !ok { t.Errorf("bad test") } - dist2, ok := NewNormal([]float64{6, 7}, mat64.NewSymDense(2, []float64{8, 2, 0, 4}), nil) + dist2, ok := NewNormal([]float64{6, 7}, mat.NewSymDense(2, []float64{8, 2, 0, 4}), nil) if !ok { t.Errorf("bad test") } @@ -53,14 +53,14 @@ func TestNormProbs(t *testing.T) { func TestNewNormalChol(t *testing.T) { for _, test := range []struct { mean []float64 - cov *mat64.SymDense + cov *mat.SymDense }{ { mean: []float64{2, 3}, - cov: mat64.NewSymDense(2, []float64{1, 0.1, 0.1, 1}), + cov: mat.NewSymDense(2, []float64{1, 0.1, 0.1, 1}), }, } { - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(test.cov) if !ok { panic("bad test") @@ -101,26 +101,26 @@ func TestNormRand(t *testing.T) { }, } { dim := len(test.mean) - cov := mat64.NewSymDense(dim, test.cov) + cov := mat.NewSymDense(dim, test.cov) n, ok := NewNormal(test.mean, cov, nil) if !ok { t.Errorf("bad covariance matrix") } nSamples := 1000000 - samps := mat64.NewDense(nSamples, dim, nil) + samps := mat.NewDense(nSamples, dim, nil) for i := 0; i < nSamples; i++ { n.Rand(samps.RawRowView(i)) } estMean := make([]float64, dim) for i := range estMean { - estMean[i] = stat.Mean(mat64.Col(nil, i, samps), nil) + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) } if !floats.EqualApprox(estMean, test.mean, 1e-2) { t.Errorf("Mean mismatch: want: %v, got %v", test.mean, estMean) } estCov := stat.CovarianceMatrix(nil, samps, nil) - if !mat64.EqualApprox(estCov, cov, 1e-2) { + if !mat.EqualApprox(estCov, cov, 1e-2) { t.Errorf("Cov mismatch: want: %v, got %v", cov, estCov) } } @@ -140,7 +140,7 @@ func TestNormalQuantile(t *testing.T) { }, } { dim := len(test.mean) - cov := mat64.NewSymDense(dim, test.cov) + cov := mat.NewSymDense(dim, test.cov) n, ok := NewNormal(test.mean, cov, nil) if !ok { t.Errorf("bad covariance matrix") @@ -148,7 +148,7 @@ func TestNormalQuantile(t *testing.T) { nSamples := 1000000 rnd := rand.New(rand.NewSource(1)) - samps := mat64.NewDense(nSamples, dim, nil) + samps := mat.NewDense(nSamples, dim, nil) tmp := make([]float64, dim) for i := 0; i < nSamples; i++ { for j := range tmp { @@ -158,13 +158,13 @@ func TestNormalQuantile(t *testing.T) { } estMean := make([]float64, dim) for i := range estMean { - estMean[i] = stat.Mean(mat64.Col(nil, i, samps), nil) + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) } if !floats.EqualApprox(estMean, test.mean, 1e-2) { t.Errorf("Mean mismatch: want: %v, got %v", test.mean, estMean) } estCov := stat.CovarianceMatrix(nil, samps, nil) - if !mat64.EqualApprox(estCov, cov, 1e-2) { + if !mat.EqualApprox(estCov, cov, 1e-2) { t.Errorf("Cov mismatch: want: %v, got %v", cov, estCov) } } @@ -174,57 +174,57 @@ func TestConditionNormal(t *testing.T) { // Uncorrelated values shouldn't influence the updated values. for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense observed []int values []float64 newMu []float64 - newSigma *mat64.SymDense + newSigma *mat.SymDense }{ { mu: []float64{2, 3}, - sigma: mat64.NewSymDense(2, []float64{2, 0, 0, 5}), + sigma: mat.NewSymDense(2, []float64{2, 0, 0, 5}), observed: []int{0}, values: []float64{10}, newMu: []float64{3}, - newSigma: mat64.NewSymDense(1, []float64{5}), + newSigma: mat.NewSymDense(1, []float64{5}), }, { mu: []float64{2, 3}, - sigma: mat64.NewSymDense(2, []float64{2, 0, 0, 5}), + sigma: mat.NewSymDense(2, []float64{2, 0, 0, 5}), observed: []int{1}, values: []float64{10}, newMu: []float64{2}, - newSigma: mat64.NewSymDense(1, []float64{2}), + newSigma: mat.NewSymDense(1, []float64{2}), }, { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), observed: []int{1}, values: []float64{10}, newMu: []float64{2, 4}, - newSigma: mat64.NewSymDense(2, []float64{2, 0, 0, 10}), + newSigma: mat.NewSymDense(2, []float64{2, 0, 0, 10}), }, { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), observed: []int{0, 1}, values: []float64{10, 15}, newMu: []float64{4}, - newSigma: mat64.NewSymDense(1, []float64{10}), + newSigma: mat.NewSymDense(1, []float64{10}), }, { mu: []float64{2, 3, 4, 5}, - sigma: mat64.NewSymDense(4, []float64{2, 0.5, 0, 0, 0.5, 5, 0, 0, 0, 0, 10, 2, 0, 0, 2, 3}), + sigma: mat.NewSymDense(4, []float64{2, 0.5, 0, 0, 0.5, 5, 0, 0, 0, 0, 10, 2, 0, 0, 2, 3}), observed: []int{0, 1}, values: []float64{10, 15}, newMu: []float64{4, 5}, - newSigma: mat64.NewSymDense(2, []float64{10, 2, 2, 3}), + newSigma: mat.NewSymDense(2, []float64{10, 2, 2, 3}), }, } { normal, ok := NewNormal(test.mu, test.sigma, nil) @@ -240,9 +240,9 @@ func TestConditionNormal(t *testing.T) { t.Errorf("Updated mean mismatch. Want %v, got %v.", test.newMu, newNormal.mu) } - var sigma mat64.SymDense + var sigma mat.SymDense sigma.FromCholesky(&newNormal.chol) - if !mat64.EqualApprox(test.newSigma, &sigma, 1e-12) { + if !mat.EqualApprox(test.newSigma, &sigma, 1e-12) { t.Errorf("Updated sigma mismatch\n.Want:\n% v\nGot:\n% v\n", test.newSigma, sigma) } } @@ -269,7 +269,7 @@ func TestConditionNormal(t *testing.T) { } { std := test.std rho := test.rho - sigma := mat64.NewSymDense(2, []float64{std[0] * std[0], std[0] * std[1] * rho, std[0] * std[1] * rho, std[1] * std[1]}) + sigma := mat.NewSymDense(2, []float64{std[0] * std[0], std[0] * std[1] * rho, std[0] * std[1] * rho, std[1] * std[1]}) normal, ok := NewNormal(test.mu, sigma, nil) if !ok { t.Fatalf("Bad test, original sigma not positive definite") @@ -278,7 +278,7 @@ func TestConditionNormal(t *testing.T) { if !ok { t.Fatalf("Bad test, update failed") } - var newSigma mat64.SymDense + var newSigma mat.SymDense newSigma.FromCholesky(&newNormal.chol) trueMean := test.mu[0] + rho*(std[0]/std[1])*(test.value-test.mu[1]) if math.Abs(trueMean-newNormal.mu[0]) > 1e-14 { @@ -293,7 +293,7 @@ func TestConditionNormal(t *testing.T) { // Test via sampling. for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense observed []int unobserved []int value []float64 @@ -301,7 +301,7 @@ func TestConditionNormal(t *testing.T) { // The indices in unobserved must be in ascending order for this test. { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), observed: []int{0}, unobserved: []int{1, 2}, @@ -309,7 +309,7 @@ func TestConditionNormal(t *testing.T) { }, { mu: []float64{2, 3, 4, 5}, - sigma: mat64.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), observed: []int{0, 3}, unobserved: []int{1, 2}, @@ -318,7 +318,7 @@ func TestConditionNormal(t *testing.T) { } { totalSamp := 4000000 var nSamp int - samples := mat64.NewDense(totalSamp, len(test.mu), nil) + samples := mat.NewDense(totalSamp, len(test.mu), nil) normal, ok := NewNormal(test.mu, test.sigma, nil) if !ok { t.Errorf("bad test") @@ -343,12 +343,12 @@ func TestConditionNormal(t *testing.T) { t.Errorf("bad test, not enough samples") continue } - samples = samples.View(0, 0, nSamp, len(test.mu)).(*mat64.Dense) + samples = samples.View(0, 0, nSamp, len(test.mu)).(*mat.Dense) // Compute mean and covariance matrix. estMean := make([]float64, len(test.mu)) for i := range estMean { - estMean[i] = stat.Mean(mat64.Col(nil, i, samples), nil) + estMean[i] = stat.Mean(mat.Col(nil, i, samples), nil) } estCov := stat.CovarianceMatrix(nil, samples, nil) @@ -363,7 +363,7 @@ func TestConditionNormal(t *testing.T) { subEstMean = append(subEstMean, estMean[v]) } - subEstCov := mat64.NewSymDense(len(test.unobserved), nil) + subEstCov := mat.NewSymDense(len(test.unobserved), nil) for i := 0; i < len(test.unobserved); i++ { for j := i; j < len(test.unobserved); j++ { subEstCov.SetSym(i, j, estCov.At(test.unobserved[i], test.unobserved[j])) @@ -375,9 +375,9 @@ func TestConditionNormal(t *testing.T) { t.Errorf("Mean mismatch. Want %v, got %v.", newNormal.mu[i], v) } } - var sigma mat64.SymDense + var sigma mat.SymDense sigma.FromCholesky(&newNormal.chol) - if !mat64.EqualApprox(&sigma, subEstCov, 1e-1) { + if !mat.EqualApprox(&sigma, subEstCov, 1e-1) { t.Errorf("Covariance mismatch. Want:\n%0.8v\nGot:\n%0.8v\n", subEstCov, sigma) } } @@ -386,11 +386,11 @@ func TestConditionNormal(t *testing.T) { func TestCovarianceMatrix(t *testing.T) { for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense }{ { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{1, 0.5, 3, 0.5, 8, -1, 3, -1, 15}), + sigma: mat.NewSymDense(3, []float64{1, 0.5, 3, 0.5, 8, -1, 3, -1, 15}), }, } { normal, ok := NewNormal(test.mu, test.sigma, nil) @@ -398,13 +398,13 @@ func TestCovarianceMatrix(t *testing.T) { t.Fatalf("Bad test, covariance matrix not positive definite") } cov := normal.CovarianceMatrix(nil) - if !mat64.EqualApprox(cov, test.sigma, 1e-14) { + if !mat.EqualApprox(cov, test.sigma, 1e-14) { t.Errorf("Covariance mismatch with nil input") } dim := test.sigma.Symmetric() - cov = mat64.NewSymDense(dim, nil) + cov = mat.NewSymDense(dim, nil) normal.CovarianceMatrix(cov) - if !mat64.EqualApprox(cov, test.sigma, 1e-14) { + if !mat.EqualApprox(cov, test.sigma, 1e-14) { t.Errorf("Covariance mismatch with supplied input") } } @@ -413,22 +413,22 @@ func TestCovarianceMatrix(t *testing.T) { func TestMarginal(t *testing.T) { for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense marginal []int }{ { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), marginal: []int{0}, }, { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), marginal: []int{0, 2}, }, { mu: []float64{2, 3, 4, 5}, - sigma: mat64.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), marginal: []int{0, 3}, }, @@ -443,13 +443,13 @@ func TestMarginal(t *testing.T) { } dim := normal.Dim() nSamples := 1000000 - samps := mat64.NewDense(nSamples, dim, nil) + samps := mat.NewDense(nSamples, dim, nil) for i := 0; i < nSamples; i++ { normal.Rand(samps.RawRowView(i)) } estMean := make([]float64, dim) for i := range estMean { - estMean[i] = stat.Mean(mat64.Col(nil, i, samps), nil) + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) } for i, v := range test.marginal { if math.Abs(marginal.mu[i]-estMean[v]) > 1e-2 { @@ -474,15 +474,15 @@ func TestMarginal(t *testing.T) { func TestMarginalSingle(t *testing.T) { for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense }{ { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), }, { mu: []float64{2, 3, 4, 5}, - sigma: mat64.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), }, } { normal, ok := NewNormal(test.mu, test.sigma, nil) @@ -513,9 +513,9 @@ func TestMarginalSingle(t *testing.T) { for i := range x { x[i] = rnd.Float64() } - mat := mat64.NewDense(dim, dim, x) - var sigma mat64.SymDense - sigma.SymOuterK(1, mat) + matrix := mat.NewDense(dim, dim, x) + var sigma mat.SymDense + sigma.SymOuterK(1, matrix) normal, ok := NewNormal(mu, &sigma, nil) if !ok { diff --git a/stat/distmv/normalbench_test.go b/stat/distmv/normalbench_test.go index 645f4f3e..a8890439 100644 --- a/stat/distmv/normalbench_test.go +++ b/stat/distmv/normalbench_test.go @@ -9,7 +9,7 @@ import ( "math/rand" "testing" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func BenchmarkMarginalNormal10(b *testing.B) { @@ -61,8 +61,8 @@ func randomNormal(sz int, rnd *rand.Rand) *Normal { for i := range data { data[i] = rnd.Float64() } - dM := mat64.NewDense(sz, sz, data) - var sigma mat64.SymDense + dM := mat.NewDense(sz, sz, data) + var sigma mat.SymDense sigma.SymOuterK(1, dM) normal, ok := NewNormal(mu, &sigma, nil) diff --git a/stat/distmv/statdist.go b/stat/distmv/statdist.go index 478fc88e..54fe420f 100644 --- a/stat/distmv/statdist.go +++ b/stat/distmv/statdist.go @@ -8,7 +8,7 @@ import ( "math" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) @@ -37,14 +37,14 @@ func (Bhattacharyya) DistNormal(l, r *Normal) float64 { panic(badSizeMismatch) } - var sigma mat64.SymDense + var sigma mat.SymDense sigma.AddSym(&l.sigma, &r.sigma) sigma.ScaleSym(0.5, &sigma) - var chol mat64.Cholesky + var chol mat.Cholesky chol.Factorize(&sigma) - mahalanobis := stat.Mahalanobis(mat64.NewVector(dim, l.mu), mat64.NewVector(dim, r.mu), &chol) + mahalanobis := stat.Mahalanobis(mat.NewVector(dim, l.mu), mat.NewVector(dim, r.mu), &chol) mahalanobisSq := mahalanobis * mahalanobis dl := l.chol.LogDet() @@ -154,21 +154,21 @@ func (KullbackLeibler) DistNormal(l, r *Normal) float64 { panic(badSizeMismatch) } - mahalanobis := stat.Mahalanobis(mat64.NewVector(dim, l.mu), mat64.NewVector(dim, r.mu), &r.chol) + mahalanobis := stat.Mahalanobis(mat.NewVector(dim, l.mu), mat.NewVector(dim, r.mu), &r.chol) mahalanobisSq := mahalanobis * mahalanobis // TODO(btracey): Optimize where there is a SolveCholeskySym // TODO(btracey): There may be a more efficient way to just compute the trace // Compute tr(Σ_r^-1*Σ_l) using the fact that Σ_l = U^T * U - var u mat64.TriDense + var u mat.TriDense u.UFromCholesky(&l.chol) - var m mat64.Dense + var m mat.Dense err := m.SolveCholesky(&r.chol, u.T()) if err != nil { return math.NaN() } m.Mul(&m, &u) - tr := mat64.Trace(&m) + tr := mat.Trace(&m) return r.logSqrtDet - l.logSqrtDet + 0.5*(mahalanobisSq+tr-float64(l.dim)) } @@ -233,20 +233,20 @@ func (Wasserstein) DistNormal(l, r *Normal) float64 { d = d * d // Compute Σ_l^(1/2) - var ssl mat64.SymDense + var ssl mat.SymDense ssl.PowPSD(&l.sigma, 0.5) // Compute Σ_l^(1/2)*Σ_r*Σ_l^(1/2) - var mean mat64.Dense + var mean mat.Dense mean.Mul(&ssl, &r.sigma) mean.Mul(&mean, &ssl) // Reinterpret as symdense, and take Σ^(1/2) - meanSym := mat64.NewSymDense(dim, mean.RawMatrix().Data) + meanSym := mat.NewSymDense(dim, mean.RawMatrix().Data) ssl.PowPSD(meanSym, 0.5) - tr := mat64.Trace(&r.sigma) - tl := mat64.Trace(&l.sigma) - tm := mat64.Trace(&ssl) + tr := mat.Trace(&r.sigma) + tl := mat.Trace(&l.sigma) + tm := mat.Trace(&ssl) return d + tl + tr - 2*tm } diff --git a/stat/distmv/statdist_test.go b/stat/distmv/statdist_test.go index bb2dbb32..c6790449 100644 --- a/stat/distmv/statdist_test.go +++ b/stat/distmv/statdist_test.go @@ -10,21 +10,21 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func TestBhattacharyyaNormal(t *testing.T) { for cas, test := range []struct { am, bm []float64 - ac, bc *mat64.SymDense + ac, bc *mat.SymDense samples int tol float64 }{ { am: []float64{2, 3}, - ac: mat64.NewSymDense(2, []float64{3, -1, -1, 2}), + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), bm: []float64{-1, 1}, - bc: mat64.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), samples: 100000, tol: 1e-2, }, @@ -105,15 +105,15 @@ func bhattacharyyaSample(dim, samples int, l RandLogProber, r LogProber) float64 func TestCrossEntropyNormal(t *testing.T) { for cas, test := range []struct { am, bm []float64 - ac, bc *mat64.SymDense + ac, bc *mat.SymDense samples int tol float64 }{ { am: []float64{2, 3}, - ac: mat64.NewSymDense(2, []float64{3, -1, -1, 2}), + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), bm: []float64{-1, 1}, - bc: mat64.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), samples: 100000, tol: 1e-2, }, @@ -144,15 +144,15 @@ func TestCrossEntropyNormal(t *testing.T) { func TestHellingerNormal(t *testing.T) { for cas, test := range []struct { am, bm []float64 - ac, bc *mat64.SymDense + ac, bc *mat.SymDense samples int tol float64 }{ { am: []float64{2, 3}, - ac: mat64.NewSymDense(2, []float64{3, -1, -1, 2}), + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), bm: []float64{-1, 1}, - bc: mat64.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), samples: 100000, tol: 5e-1, }, @@ -188,15 +188,15 @@ func TestHellingerNormal(t *testing.T) { func TestKullbackLeiblerNormal(t *testing.T) { for cas, test := range []struct { am, bm []float64 - ac, bc *mat64.SymDense + ac, bc *mat.SymDense samples int tol float64 }{ { am: []float64{2, 3}, - ac: mat64.NewSymDense(2, []float64{3, -1, -1, 2}), + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), bm: []float64{-1, 1}, - bc: mat64.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), samples: 10000, tol: 1e-2, }, diff --git a/stat/distmv/studentst.go b/stat/distmv/studentst.go index 0b8d50f3..5dc8287c 100644 --- a/stat/distmv/studentst.go +++ b/stat/distmv/studentst.go @@ -12,7 +12,7 @@ import ( "golang.org/x/tools/container/intsets" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat/distuv" ) @@ -35,10 +35,10 @@ type StudentsT struct { mu []float64 src *rand.Rand - sigma mat64.SymDense // only stored if needed + sigma mat.SymDense // only stored if needed - chol mat64.Cholesky - lower mat64.TriDense + chol mat.Cholesky + lower mat.TriDense logSqrtDet float64 dim int } @@ -48,7 +48,7 @@ type StudentsT struct { // // NewStudentsT panics if len(mu) == 0, or if len(mu) != sigma.Symmetric(). If // the covariance matrix is not positive-definite, nil is returned and ok is false. -func NewStudentsT(mu []float64, sigma mat64.Symmetric, nu float64, src *rand.Rand) (dist *StudentsT, ok bool) { +func NewStudentsT(mu []float64, sigma mat.Symmetric, nu float64, src *rand.Rand) (dist *StudentsT, ok bool) { if len(mu) == 0 { panic(badZeroDimension) } @@ -69,7 +69,7 @@ func NewStudentsT(mu []float64, sigma mat64.Symmetric, nu float64, src *rand.Ran if !ok { return nil, false } - s.sigma = *mat64.NewSymDense(dim, nil) + s.sigma = *mat.NewSymDense(dim, nil) s.sigma.CopySym(sigma) s.lower.LFromCholesky(&s.chol) s.logSqrtDet = 0.5 * s.chol.LogDet() @@ -113,7 +113,7 @@ func (s *StudentsT) ConditionStudentsT(observed []int, values []float64, src *ra // studentsTConditional updates a Student's T distribution based on the observed samples // (see documentation for the public function). The Gaussian conditional update // is treated as a special case when nu == math.Inf(1). -func studentsTConditional(observed []int, values []float64, nu float64, mu []float64, sigma mat64.Symmetric) (newNu float64, newMean []float64, newSigma *mat64.SymDense) { +func studentsTConditional(observed []int, values []float64, nu float64, mu []float64, sigma mat.Symmetric) (newNu float64, newMean []float64, newSigma *mat.SymDense) { dim := len(mu) ob := len(observed) @@ -133,11 +133,11 @@ func studentsTConditional(observed []int, values []float64, nu float64, mu []flo mu2[i] = values[i] - mu[v] } - var sigma11, sigma22 mat64.SymDense + var sigma11, sigma22 mat.SymDense sigma11.SubsetSym(sigma, unobserved) sigma22.SubsetSym(sigma, observed) - sigma21 := mat64.NewDense(ob, unob, nil) + sigma21 := mat.NewDense(ob, unob, nil) for i, r := range observed { for j, c := range unobserved { v := sigma.At(r, c) @@ -145,15 +145,15 @@ func studentsTConditional(observed []int, values []float64, nu float64, mu []flo } } - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(&sigma22) if !ok { return math.NaN(), nil, nil } // Compute mu_1 + sigma_{2,1}^T * sigma_{2,2}^-1 (v - mu_2). - v := mat64.NewVector(ob, mu2) - var tmp, tmp2 mat64.Vector + v := mat.NewVector(ob, mu2) + var tmp, tmp2 mat.Vector err := tmp.SolveCholeskyVec(&chol, v) if err != nil { return math.NaN(), nil, nil @@ -166,7 +166,7 @@ func studentsTConditional(observed []int, values []float64, nu float64, mu []flo // Compute tmp4 = sigma_{2,1}^T * sigma_{2,2}^-1 * sigma_{2,1}. // TODO(btracey): Should this be a method of SymDense? - var tmp3, tmp4 mat64.Dense + var tmp3, tmp4 mat.Dense err = tmp3.SolveCholesky(&chol, sigma21) if err != nil { return math.NaN(), nil, nil @@ -189,7 +189,7 @@ func studentsTConditional(observed []int, values []float64, nu float64, mu []flo } // Compute beta = (v - mu_2)^T * sigma_{2,2}^-1 * (v - mu_2)^T - beta := mat64.Dot(v, &tmp) + beta := mat.Dot(v, &tmp) // Scale the covariance matrix sigma11.ScaleSym((nu+beta)/(nu+float64(ob)), &sigma11) @@ -221,9 +221,9 @@ func findUnob(observed []int, dim int) (unobserved []int) { // covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] // If the input matrix is nil a new matrix is allocated, otherwise the result // is stored in-place into the input. -func (st *StudentsT) CovarianceMatrix(s *mat64.SymDense) *mat64.SymDense { +func (st *StudentsT) CovarianceMatrix(s *mat.SymDense) *mat.SymDense { if s == nil { - s = mat64.NewSymDense(st.dim, nil) + s = mat.NewSymDense(st.dim, nil) } sn := s.Symmetric() if sn != st.dim { @@ -256,12 +256,12 @@ func (s *StudentsT) LogProb(y []float64) float64 { copy(shift, y) floats.Sub(shift, s.mu) - x := mat64.NewVector(s.dim, shift) + x := mat.NewVector(s.dim, shift) - var tmp mat64.Vector + var tmp mat.Vector tmp.SolveCholeskyVec(&s.chol, x) - dot := mat64.Dot(&tmp, x) + dot := mat.Dot(&tmp, x) return t1 - ((nu+n)/2)*math.Log(1+dot/nu) } @@ -283,7 +283,7 @@ func (s *StudentsT) MarginalStudentsT(vars []int, src *rand.Rand) (dist *Student for i, v := range vars { newMean[i] = s.mu[v] } - var newSigma mat64.SymDense + var newSigma mat.SymDense newSigma.SubsetSym(&s.sigma, vars) return NewStudentsT(newMean, &newSigma, s.nu, src) } @@ -342,8 +342,8 @@ func (s *StudentsT) Rand(x []float64) []float64 { tmp[i] = s.src.NormFloat64() } } - xVec := mat64.NewVector(s.dim, x) - tmpVec := mat64.NewVector(s.dim, tmp) + xVec := mat.NewVector(s.dim, x) + tmpVec := mat.NewVector(s.dim, tmp) xVec.MulVec(&s.lower, tmpVec) u := distuv.ChiSquared{K: s.nu, Src: s.src}.Rand() diff --git a/stat/distmv/studentst_test.go b/stat/distmv/studentst_test.go index 28c749f1..c2f021e2 100644 --- a/stat/distmv/studentst_test.go +++ b/stat/distmv/studentst_test.go @@ -10,7 +10,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) @@ -19,7 +19,7 @@ func TestStudentTProbs(t *testing.T) { for _, test := range []struct { nu float64 mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense x [][]float64 probs []float64 @@ -27,7 +27,7 @@ func TestStudentTProbs(t *testing.T) { { nu: 3, mu: []float64{0, 0}, - sigma: mat64.NewSymDense(2, []float64{1, 0, 0, 1}), + sigma: mat.NewSymDense(2, []float64{1, 0, 0, 1}), x: [][]float64{ {0, 0}, @@ -46,7 +46,7 @@ func TestStudentTProbs(t *testing.T) { { nu: 4, mu: []float64{2, -3}, - sigma: mat64.NewSymDense(2, []float64{8, -1, -1, 5}), + sigma: mat.NewSymDense(2, []float64{8, -1, -1, 5}), x: [][]float64{ {0, 0}, @@ -87,25 +87,25 @@ func TestStudentsTRand(t *testing.T) { src := rand.New(rand.NewSource(1)) for _, test := range []struct { mean []float64 - cov *mat64.SymDense + cov *mat.SymDense nu float64 tolcov float64 }{ { mean: []float64{0, 0}, - cov: mat64.NewSymDense(2, []float64{1, 0, 0, 1}), + cov: mat.NewSymDense(2, []float64{1, 0, 0, 1}), nu: 3, tolcov: 1e-2, }, { mean: []float64{3, 4}, - cov: mat64.NewSymDense(2, []float64{5, 1.2, 1.2, 6}), + cov: mat.NewSymDense(2, []float64{5, 1.2, 1.2, 6}), nu: 8, tolcov: 1e-2, }, { mean: []float64{3, 4, -2}, - cov: mat64.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), + cov: mat.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), nu: 8, tolcov: 1e-2, }, @@ -116,13 +116,13 @@ func TestStudentsTRand(t *testing.T) { } nSamples := 10000000 dim := len(test.mean) - samps := mat64.NewDense(nSamples, dim, nil) + samps := mat.NewDense(nSamples, dim, nil) for i := 0; i < nSamples; i++ { s.Rand(samps.RawRowView(i)) } estMean := make([]float64, dim) for i := range estMean { - estMean[i] = stat.Mean(mat64.Col(nil, i, samps), nil) + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) } mean := s.Mean(nil) if !floats.EqualApprox(estMean, mean, 1e-2) { @@ -130,7 +130,7 @@ func TestStudentsTRand(t *testing.T) { } cov := s.CovarianceMatrix(nil) estCov := stat.CovarianceMatrix(nil, samps, nil) - if !mat64.EqualApprox(estCov, cov, test.tolcov) { + if !mat.EqualApprox(estCov, cov, test.tolcov) { t.Errorf("Cov mismatch: want: %v, got %v", cov, estCov) } } @@ -140,7 +140,7 @@ func TestStudentsTConditional(t *testing.T) { src := rand.New(rand.NewSource(1)) for _, test := range []struct { mean []float64 - cov *mat64.SymDense + cov *mat.SymDense nu float64 idx []int @@ -149,7 +149,7 @@ func TestStudentsTConditional(t *testing.T) { }{ { mean: []float64{3, 4, -2}, - cov: mat64.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), + cov: mat.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), nu: 8, idx: []int{0}, value: []float64{6}, @@ -182,11 +182,11 @@ func TestStudentsTConditional(t *testing.T) { muOb[i] = test.mean[v] } - var sig11, sig22 mat64.SymDense + var sig11, sig22 mat.SymDense sig11.SubsetSym(&s.sigma, unob) sig22.SubsetSym(&s.sigma, ob) - sig12 := mat64.NewDense(len(unob), len(ob), nil) + sig12 := mat.NewDense(len(unob), len(ob), nil) for i := range unob { for j := range ob { sig12.Set(i, j, s.sigma.At(unob[i], ob[j])) @@ -198,9 +198,9 @@ func TestStudentsTConditional(t *testing.T) { floats.Sub(shift, muOb) newMu := make([]float64, len(muUnob)) - newMuVec := mat64.NewVector(len(muUnob), newMu) - shiftVec := mat64.NewVector(len(shift), shift) - var tmp mat64.Vector + newMuVec := mat.NewVector(len(muUnob), newMu) + shiftVec := mat.NewVector(len(shift), shift) + var tmp mat.Vector tmp.SolveVec(&sig22, shiftVec) newMuVec.MulVec(sig12, &tmp) floats.Add(newMu, muUnob) @@ -209,16 +209,16 @@ func TestStudentsTConditional(t *testing.T) { t.Errorf("Mu mismatch. Got %v, want %v", sUp.mu, newMu) } - var tmp2 mat64.Dense + var tmp2 mat.Dense tmp2.Solve(&sig22, sig12.T()) - var tmp3 mat64.Dense + var tmp3 mat.Dense tmp3.Mul(sig12, &tmp2) tmp3.Sub(&sig11, &tmp3) - dot := mat64.Dot(shiftVec, &tmp) + dot := mat.Dot(shiftVec, &tmp) tmp3.Scale((test.nu+dot)/(test.nu+float64(len(ob))), &tmp3) - if !mat64.EqualApprox(&tmp3, &sUp.sigma, 1e-10) { + if !mat.EqualApprox(&tmp3, &sUp.sigma, 1e-10) { t.Errorf("Sigma mismatch") } } @@ -227,17 +227,17 @@ func TestStudentsTConditional(t *testing.T) { func TestStudentsTMarginalSingle(t *testing.T) { for _, test := range []struct { mu []float64 - sigma *mat64.SymDense + sigma *mat.SymDense nu float64 }{ { mu: []float64{2, 3, 4}, - sigma: mat64.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), nu: 5, }, { mu: []float64{2, 3, 4, 5}, - sigma: mat64.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), nu: 6, }, } { diff --git a/stat/pca_cca.go b/stat/pca_cca.go index 24b6772c..d059ef26 100644 --- a/stat/pca_cca.go +++ b/stat/pca_cca.go @@ -9,8 +9,7 @@ import ( "math" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // PC is a type for computing and extracting the principal components of a @@ -19,7 +18,7 @@ import ( type PC struct { n, d int weights []float64 - svd *mat64.SVD + svd *mat.SVD ok bool } @@ -34,7 +33,7 @@ type PC struct { // must match the number of observations or PrincipalComponents will panic. // // PrincipalComponents returns whether the analysis was successful. -func (c *PC) PrincipalComponents(a mat64.Matrix, weights []float64) (ok bool) { +func (c *PC) PrincipalComponents(a mat.Matrix, weights []float64) (ok bool) { c.n, c.d = a.Dims() if weights != nil && len(weights) != c.n { panic("stat: len(weights) != observations") @@ -51,15 +50,15 @@ func (c *PC) PrincipalComponents(a mat64.Matrix, weights []float64) (ok bool) { // analysis. The vectors are returned in the columns of a d×min(n, d) matrix. // If dst is not nil it must either be zero-sized or be a d×min(n, d) matrix. // dst will be used as the destination for the direction vector data. If dst -// is nil, a new mat64.Dense is allocated for the destination. -func (c *PC) Vectors(dst *mat64.Dense) *mat64.Dense { +// is nil, a new mat.Dense is allocated for the destination. +func (c *PC) Vectors(dst *mat.Dense) *mat.Dense { if !c.ok { panic("stat: use of unsuccessful principal components analysis") } if dst != nil { if d, n := dst.Dims(); (n != 0 || d != 0) && (d != c.d || n != min(c.n, c.d)) { - panic(matrix.ErrShape) + panic(mat.ErrShape) } } return c.svd.VTo(dst) @@ -110,7 +109,7 @@ type CC struct { // xd and yd are used for size checks. xd, yd int - x, y, c *mat64.SVD + x, y, c *mat.SVD ok bool } @@ -162,7 +161,7 @@ type CC struct { // or in Chapter 3 of // Koch, Inge. Analysis of multivariate and high-dimensional data. // Vol. 32. Cambridge University Press, 2013. ISBN: 9780521887939 -func (c *CC) CanonicalCorrelations(x, y mat64.Matrix, weights []float64) error { +func (c *CC) CanonicalCorrelations(x, y mat.Matrix, weights []float64) error { var yn int c.n, c.xd = x.Dims() yn, c.yd = y.Dims() @@ -188,12 +187,12 @@ func (c *CC) CanonicalCorrelations(x, y mat64.Matrix, weights []float64) error { yv := c.y.VTo(nil) // Calculate and factorise the canonical correlation matrix. - var ccor mat64.Dense + var ccor mat.Dense ccor.Product(xv, xu.T(), yu, yv.T()) if c.c == nil { - c.c = &mat64.SVD{} + c.c = &mat.SVD{} } - c.ok = c.c.Factorize(&ccor, matrix.SVDThin) + c.ok = c.c.Factorize(&ccor, mat.SVDThin) if !c.ok { return errors.New("stat: failed to factorize ccor") } @@ -220,15 +219,15 @@ func (c *CC) Corrs(dst []float64) []float64 { // If dst is not nil it must either be zero-sized or be an xd×yd matrix where xd // and yd are the number of variables in the input x and y matrices. dst will // be used as the destination for the vector data. If dst is nil, a new -// mat64.Dense is allocated for the destination. -func (c *CC) Left(dst *mat64.Dense, spheredSpace bool) *mat64.Dense { +// mat.Dense is allocated for the destination. +func (c *CC) Left(dst *mat.Dense, spheredSpace bool) *mat.Dense { if !c.ok || c.n < 2 { panic("stat: canonical correlations missing or invalid") } if dst != nil { if d, n := dst.Dims(); (n != 0 || d != 0) && (n != c.yd || d != c.xd) { - panic(matrix.ErrShape) + panic(mat.ErrShape) } } dst = c.c.UTo(dst) @@ -252,15 +251,15 @@ func (c *CC) Left(dst *mat64.Dense, spheredSpace bool) *mat64.Dense { // If dst is not nil it must either be zero-sized or be an yd×yd matrix where yd // is the number of variables in the input y matrix. dst will // be used as the destination for the vector data. If dst is nil, a new -// mat64.Dense is allocated for the destination. -func (c *CC) Right(dst *mat64.Dense, spheredSpace bool) *mat64.Dense { +// mat.Dense is allocated for the destination. +func (c *CC) Right(dst *mat.Dense, spheredSpace bool) *mat.Dense { if !c.ok || c.n < 2 { panic("stat: canonical correlations missing or invalid") } if dst != nil { if d, n := dst.Dims(); (n != 0 || d != 0) && (n != c.yd || d != c.yd) { - panic(matrix.ErrShape) + panic(mat.ErrShape) } } dst = c.c.VTo(dst) @@ -278,12 +277,12 @@ func (c *CC) Right(dst *mat64.Dense, spheredSpace bool) *mat64.Dense { return dst } -func svdFactorizeCentered(work *mat64.SVD, m mat64.Matrix, weights []float64) (svd *mat64.SVD, ok bool) { +func svdFactorizeCentered(work *mat.SVD, m mat.Matrix, weights []float64) (svd *mat.SVD, ok bool) { n, d := m.Dims() - centered := mat64.NewDense(n, d, nil) + centered := mat.NewDense(n, d, nil) col := make([]float64, n) for j := 0; j < d; j++ { - mat64.Col(col, j, m) + mat.Col(col, j, m) floats.AddConst(-Mean(col, weights), col) centered.SetCol(j, col) } @@ -291,15 +290,15 @@ func svdFactorizeCentered(work *mat64.SVD, m mat64.Matrix, weights []float64) (s floats.Scale(math.Sqrt(w), centered.RawRowView(i)) } if work == nil { - work = &mat64.SVD{} + work = &mat.SVD{} } - ok = work.Factorize(centered, matrix.SVDThin) + ok = work.Factorize(centered, mat.SVDThin) return work, ok } // scaleColsReciSqrt scales the columns of cols // by the reciprocal square-root of vals. -func scaleColsReciSqrt(cols *mat64.Dense, vals []float64) { +func scaleColsReciSqrt(cols *mat.Dense, vals []float64) { if cols == nil { panic("stat: input nil") } @@ -309,7 +308,7 @@ func scaleColsReciSqrt(cols *mat64.Dense, vals []float64) { } col := make([]float64, n) for j := 0; j < d; j++ { - mat64.Col(col, j, cols) + mat.Col(col, j, cols) floats.Scale(math.Sqrt(1/vals[j]), col) cols.SetCol(j, col) } diff --git a/stat/pca_example_test.go b/stat/pca_example_test.go index 33582362..45341317 100644 --- a/stat/pca_example_test.go +++ b/stat/pca_example_test.go @@ -7,7 +7,7 @@ package stat_test import ( "fmt" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" ) @@ -15,7 +15,7 @@ func ExamplePrincipalComponents() { // iris is a truncated sample of the Fisher's Iris dataset. n := 10 d := 4 - iris := mat64.NewDense(n, d, []float64{ + iris := mat.NewDense(n, d, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, @@ -39,10 +39,10 @@ func ExamplePrincipalComponents() { // Project the data onto the first 2 principal components. k := 2 - var proj mat64.Dense + var proj mat.Dense proj.Mul(iris, pc.Vectors(nil).Slice(0, d, 0, k)) - fmt.Printf("proj = %.4f", mat64.Formatted(&proj, mat64.Prefix(" "))) + fmt.Printf("proj = %.4f", mat.Formatted(&proj, mat.Prefix(" "))) // Output: // variances = [0.1666 0.0207 0.0079 0.0019] diff --git a/stat/pca_test.go b/stat/pca_test.go index e6b986ad..2cfa00c6 100644 --- a/stat/pca_test.go +++ b/stat/pca_test.go @@ -8,7 +8,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) var appengine bool @@ -19,20 +19,20 @@ func TestPrincipalComponents(t *testing.T) { } tests: for i, test := range []struct { - data mat64.Matrix + data mat.Matrix weights []float64 - wantVecs *mat64.Dense + wantVecs *mat.Dense wantVars []float64 epsilon float64 }{ // Test results verified using R. { - data: mat64.NewDense(3, 3, []float64{ + data: mat.NewDense(3, 3, []float64{ 1, 2, 3, 4, 5, 6, 7, 8, 9, }), - wantVecs: mat64.NewDense(3, 3, []float64{ + wantVecs: mat.NewDense(3, 3, []float64{ 0.5773502691896258, 0.8164965809277261, 0, 0.577350269189626, -0.4082482904638632, -0.7071067811865476, 0.5773502691896258, -0.4082482904638631, 0.7071067811865475, @@ -41,7 +41,7 @@ tests: epsilon: 1e-12, }, { // Truncated iris data. - data: mat64.NewDense(10, 4, []float64{ + data: mat.NewDense(10, 4, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, @@ -53,7 +53,7 @@ tests: 4.4, 2.9, 1.4, 0.2, 4.9, 3.1, 1.5, 0.1, }), - wantVecs: mat64.NewDense(4, 4, []float64{ + wantVecs: mat.NewDense(4, 4, []float64{ -0.6681110197952722, 0.7064764857539533, -0.14026590216895132, -0.18666578956412125, -0.7166344774801547, -0.6427036135482664, -0.135650285905254, 0.23444848208629923, -0.164411275166307, 0.11898477441068218, 0.9136367900709548, 0.35224901970831746, @@ -63,12 +63,12 @@ tests: epsilon: 1e-12, }, { // Truncated iris data to form wide matrix. - data: mat64.NewDense(3, 4, []float64{ + data: mat.NewDense(3, 4, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, }), - wantVecs: mat64.NewDense(4, 3, []float64{ + wantVecs: mat.NewDense(4, 3, []float64{ -0.5705187254552365, -0.7505979435049239, 0.08084520834544455, -0.8166537769529318, 0.5615147645527523, -0.032338083338177705, -0.08709186238359454, -0.3482870890450082, -0.22636658336724505, @@ -78,7 +78,7 @@ tests: epsilon: 1e-12, }, { // Truncated iris data transposed to check for operation on fat input. - data: mat64.NewDense(10, 4, []float64{ + data: mat.NewDense(10, 4, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, @@ -90,7 +90,7 @@ tests: 4.4, 2.9, 1.4, 0.2, 4.9, 3.1, 1.5, 0.1, }).T(), - wantVecs: mat64.NewDense(10, 4, []float64{ + wantVecs: mat.NewDense(10, 4, []float64{ -0.3366602459946619, -0.1373634006401213, 0.3465102523547623, -0.10290179303893479, -0.31381852053861975, 0.5197145790632827, 0.5567296129086686, -0.15923062170153618, -0.30857197637565165, -0.07670930360819002, 0.36159923003337235, 0.3342301027853355, @@ -106,7 +106,7 @@ tests: epsilon: 1e-12, }, { // Truncated iris data unitary weights. - data: mat64.NewDense(10, 4, []float64{ + data: mat.NewDense(10, 4, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, @@ -119,7 +119,7 @@ tests: 4.9, 3.1, 1.5, 0.1, }), weights: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - wantVecs: mat64.NewDense(4, 4, []float64{ + wantVecs: mat.NewDense(4, 4, []float64{ -0.6681110197952722, 0.7064764857539533, -0.14026590216895132, -0.18666578956412125, -0.7166344774801547, -0.6427036135482664, -0.135650285905254, 0.23444848208629923, -0.164411275166307, 0.11898477441068218, 0.9136367900709548, 0.35224901970831746, @@ -129,7 +129,7 @@ tests: epsilon: 1e-12, }, { // Truncated iris data non-unitary weights. - data: mat64.NewDense(10, 4, []float64{ + data: mat.NewDense(10, 4, []float64{ 5.1, 3.5, 1.4, 0.2, 4.9, 3.0, 1.4, 0.2, 4.7, 3.2, 1.3, 0.2, @@ -142,7 +142,7 @@ tests: 4.9, 3.1, 1.5, 0.1, }), weights: []float64{2, 3, 1, 1, 1, 1, 1, 1, 1, 2}, - wantVecs: mat64.NewDense(4, 4, []float64{ + wantVecs: mat.NewDense(4, 4, []float64{ -0.618936145422414, 0.763069301531647, 0.124857741232537, 0.138035623677211, -0.763958271606519, -0.603881770702898, 0.118267155321333, -0.194184052457746, -0.143552119754944, 0.090014599564871, -0.942209377020044, -0.289018426115945, @@ -153,7 +153,7 @@ tests: }, } { var pc PC - var vecs *mat64.Dense + var vecs *mat.Dense var vars []float64 for j := 0; j < 2; j++ { ok := pc.PrincipalComponents(test.data, test.weights) @@ -163,9 +163,9 @@ tests: t.Errorf("unexpected SVD failure for test %d use %d", i, j) continue tests } - if !mat64.EqualApprox(vecs, test.wantVecs, test.epsilon) { + if !mat.EqualApprox(vecs, test.wantVecs, test.epsilon) { t.Errorf("%d use %d: unexpected PCA result got:\n%v\nwant:\n%v", - i, j, mat64.Formatted(vecs), mat64.Formatted(test.wantVecs)) + i, j, mat.Formatted(vecs), mat.Formatted(test.wantVecs)) } if !approxEqual(vars, test.wantVars, test.epsilon) { t.Errorf("%d use %d: unexpected variance result got:%v, want:%v", diff --git a/stat/samplemv/metropolishastings.go b/stat/samplemv/metropolishastings.go index 9c4d09c6..450de23f 100644 --- a/stat/samplemv/metropolishastings.go +++ b/stat/samplemv/metropolishastings.go @@ -8,7 +8,7 @@ import ( "math" "math/rand" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat/distmv" ) @@ -57,7 +57,7 @@ type MetropolisHastingser struct { // // The number of columns in batch must equal len(m.Initial), otherwise Sample // will panic. -func (m MetropolisHastingser) Sample(batch *mat64.Dense) { +func (m MetropolisHastingser) Sample(batch *mat.Dense) { burnIn := m.BurnIn rate := m.Rate if rate == 0 { @@ -74,7 +74,7 @@ func (m MetropolisHastingser) Sample(batch *mat64.Dense) { // during the rate portion. tmp := batch if rate > r { - tmp = mat64.NewDense(rate, c, nil) + tmp = mat.NewDense(rate, c, nil) } rTmp, _ := tmp.Dims() @@ -84,7 +84,7 @@ func (m MetropolisHastingser) Sample(batch *mat64.Dense) { copy(initial, m.Initial) for remaining != 0 { newSamp := min(rTmp, remaining) - MetropolisHastings(tmp.View(0, 0, newSamp, c).(*mat64.Dense), initial, m.Target, m.Proposal, m.Src) + MetropolisHastings(tmp.View(0, 0, newSamp, c).(*mat.Dense), initial, m.Target, m.Proposal, m.Src) copy(initial, tmp.RawRowView(newSamp-1)) remaining -= newSamp } @@ -95,11 +95,11 @@ func (m MetropolisHastingser) Sample(batch *mat64.Dense) { } if rTmp <= r { - tmp = mat64.NewDense(rate, c, nil) + tmp = mat.NewDense(rate, c, nil) } // Take a single sample from the chain. - MetropolisHastings(batch.View(0, 0, 1, c).(*mat64.Dense), initial, m.Target, m.Proposal, m.Src) + MetropolisHastings(batch.View(0, 0, 1, c).(*mat.Dense), initial, m.Target, m.Proposal, m.Src) copy(initial, batch.RawRowView(0)) // For all of the other samples, first generate Rate samples and then actually @@ -139,7 +139,7 @@ func (m MetropolisHastingser) Sample(batch *mat64.Dense) { // are ignored in between each kept sample. This helps decorrelate // the samples from one another, but also reduces the number of available samples. // A sampling rate can be implemented with successive calls to MetropolisHastings. -func MetropolisHastings(batch *mat64.Dense, initial []float64, target distmv.LogProber, proposal MHProposal, src *rand.Rand) { +func MetropolisHastings(batch *mat.Dense, initial []float64, target distmv.LogProber, proposal MHProposal, src *rand.Rand) { f64 := rand.Float64 if src != nil { f64 = src.Float64 @@ -180,7 +180,7 @@ type ProposalNormal struct { // and the mean of the distribution changes. // // NewProposalNormal returns {nil, false} if the covariance matrix is not positive-definite. -func NewProposalNormal(sigma *mat64.SymDense, src *rand.Rand) (*ProposalNormal, bool) { +func NewProposalNormal(sigma *mat.SymDense, src *rand.Rand) (*ProposalNormal, bool) { mu := make([]float64, sigma.Symmetric()) normal, ok := distmv.NewNormal(mu, sigma, src) if !ok { diff --git a/stat/samplemv/sample_test.go b/stat/samplemv/sample_test.go index bb48ad11..b176f4d6 100644 --- a/stat/samplemv/sample_test.go +++ b/stat/samplemv/sample_test.go @@ -10,7 +10,7 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat" "gonum.org/v1/gonum/stat/distmv" ) @@ -28,7 +28,7 @@ func TestLatinHypercube(t *testing.T) { distmv.NewUniform([]distmv.Bound{{0, 3}, {-1, 5}, {-4, -1}}, nil), } { dim := dist.Dim() - batch := mat64.NewDense(nSamples, dim, nil) + batch := mat.NewDense(nSamples, dim, nil) LatinHypercube(batch, dist, nil) // Latin hypercube should have one entry per hyperrow. present := make([][]bool, nSamples) @@ -68,7 +68,7 @@ func TestImportance(t *testing.T) { } muImp := make([]float64, dim) - sigmaImp := mat64.NewSymDense(dim, nil) + sigmaImp := mat.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 3) } @@ -78,7 +78,7 @@ func TestImportance(t *testing.T) { } nSamples := 100000 - batch := mat64.NewDense(nSamples, dim, nil) + batch := mat.NewDense(nSamples, dim, nil) weights := make([]float64, nSamples) Importance(batch, weights, target, proposal) @@ -102,7 +102,7 @@ func TestRejection(t *testing.T) { mu := target.Mean(nil) muImp := make([]float64, dim) - sigmaImp := mat64.NewSymDense(dim, nil) + sigmaImp := mat.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 6) } @@ -112,7 +112,7 @@ func TestRejection(t *testing.T) { } nSamples := 1000 - batch := mat64.NewDense(nSamples, dim, nil) + batch := mat.NewDense(nSamples, dim, nil) weights := make([]float64, nSamples) _, ok = Rejection(batch, target, proposal, 1000, nil) if !ok { @@ -120,7 +120,7 @@ func TestRejection(t *testing.T) { } for i := 0; i < dim; i++ { - col := mat64.Col(nil, i, batch) + col := mat.Col(nil, i, batch) ev := stat.Mean(col, weights) if math.Abs(ev-mu[i]) > 1e-2 { t.Errorf("Mean mismatch: Want %v, got %v", mu[i], ev) @@ -136,7 +136,7 @@ func TestMetropolisHastings(t *testing.T) { t.Fatal("bad test, sigma not pos def") } - sigmaImp := mat64.NewSymDense(dim, nil) + sigmaImp := mat.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 0.25) } @@ -147,10 +147,10 @@ func TestMetropolisHastings(t *testing.T) { nSamples := 1000000 burnin := 5000 - batch := mat64.NewDense(nSamples, dim, nil) + batch := mat.NewDense(nSamples, dim, nil) initial := make([]float64, dim) MetropolisHastings(batch, initial, target, proposal, nil) - batch = batch.View(burnin, 0, nSamples-burnin, dim).(*mat64.Dense) + batch = batch.View(burnin, 0, nSamples-burnin, dim).(*mat.Dense) compareNormal(t, target, batch, nil) } @@ -161,8 +161,8 @@ func randomNormal(dim int) (*distmv.Normal, bool) { for i := range data { data[i] = rand.Float64() } - a := mat64.NewDense(dim, dim, data) - var sigma mat64.SymDense + a := mat.NewDense(dim, dim, data) + var sigma mat.SymDense sigma.SymOuterK(1, a) mu := make([]float64, dim) for i := range mu { @@ -171,7 +171,7 @@ func randomNormal(dim int) (*distmv.Normal, bool) { return distmv.NewNormal(mu, &sigma, nil) } -func compareNormal(t *testing.T, want *distmv.Normal, batch *mat64.Dense, weights []float64) { +func compareNormal(t *testing.T, want *distmv.Normal, batch *mat.Dense, weights []float64) { dim := want.Dim() mu := want.Mean(nil) sigma := want.CovarianceMatrix(nil) @@ -183,7 +183,7 @@ func compareNormal(t *testing.T, want *distmv.Normal, batch *mat64.Dense, weight } } for i := 0; i < dim; i++ { - col := mat64.Col(nil, i, batch) + col := mat.Col(nil, i, batch) ev := stat.Mean(col, weights) if math.Abs(ev-mu[i]) > 1e-2 { t.Errorf("Mean mismatch: Want %v, got %v", mu[i], ev) @@ -191,7 +191,7 @@ func compareNormal(t *testing.T, want *distmv.Normal, batch *mat64.Dense, weight } cov := stat.CovarianceMatrix(nil, batch, weights) - if !mat64.EqualApprox(cov, sigma, 1.5e-1) { + if !mat.EqualApprox(cov, sigma, 1.5e-1) { t.Errorf("Covariance matrix mismatch") } } @@ -222,7 +222,7 @@ func TestMetropolisHastingser(t *testing.T) { t.Fatal("bad test, sigma not pos def") } - sigmaImp := mat64.NewSymDense(dim, nil) + sigmaImp := mat.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 0.25) } @@ -245,7 +245,7 @@ func TestMetropolisHastingser(t *testing.T) { samples := test.samples burnin := test.burnin rate := test.rate - fullBatch := mat64.NewDense(1+burnin+rate*(samples-1), dim, nil) + fullBatch := mat.NewDense(1+burnin+rate*(samples-1), dim, nil) mh.Sample(fullBatch) mh = MetropolisHastingser{ Initial: initial, @@ -256,7 +256,7 @@ func TestMetropolisHastingser(t *testing.T) { Rate: rate, } rand.Seed(int64(seed)) - batch := mat64.NewDense(samples, dim, nil) + batch := mat.NewDense(samples, dim, nil) mh.Sample(batch) same := true @@ -271,8 +271,8 @@ func TestMetropolisHastingser(t *testing.T) { } if !same { - fmt.Printf("%v\n", mat64.Formatted(batch)) - fmt.Printf("%v\n", mat64.Formatted(fullBatch)) + fmt.Printf("%v\n", mat.Formatted(batch)) + fmt.Printf("%v\n", mat.Formatted(fullBatch)) t.Errorf("sampling mismatch: dim = %v, burnin = %v, rate = %v, samples = %v", dim, burnin, rate, samples) } diff --git a/stat/samplemv/samplemv.go b/stat/samplemv/samplemv.go index 0d253ee9..7c95d4b7 100644 --- a/stat/samplemv/samplemv.go +++ b/stat/samplemv/samplemv.go @@ -15,7 +15,7 @@ import ( "math" "math/rand" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/stat/distmv" ) @@ -43,7 +43,7 @@ func min(a, b int) int { // implementing type. The number of samples generated is equal to rows(batch), // and the samples are stored in-place into the input. type Sampler interface { - Sample(batch *mat64.Dense) + Sample(batch *mat.Dense) } // WeightedSampler generates a batch of samples and their relative weights @@ -52,7 +52,7 @@ type Sampler interface { // are stored in-place into the inputs. The length of weights must equal // rows(batch), otherwise SampleWeighted will panic. type WeightedSampler interface { - SampleWeighted(batch *mat64.Dense, weights []float64) + SampleWeighted(batch *mat.Dense, weights []float64) } // SampleUniformWeighted wraps a Sampler type to create a WeightedSampler where all @@ -64,7 +64,7 @@ type SampleUniformWeighted struct { // SampleWeighted generates rows(batch) samples from the embedded Sampler type // and sets all of the weights equal to 1. If rows(batch) and len(weights) // of weights are not equal, SampleWeighted will panic. -func (w SampleUniformWeighted) SampleWeighted(batch *mat64.Dense, weights []float64) { +func (w SampleUniformWeighted) SampleWeighted(batch *mat.Dense, weights []float64) { r, _ := batch.Dims() if r != len(weights) { panic(badLengthMismatch) @@ -84,7 +84,7 @@ type LatinHypercuber struct { // Sample generates rows(batch) samples using the LatinHypercube generation // procedure. -func (l LatinHypercuber) Sample(batch *mat64.Dense) { +func (l LatinHypercuber) Sample(batch *mat.Dense) { LatinHypercube(batch, l.Q, l.Src) } @@ -96,7 +96,7 @@ func (l LatinHypercuber) Sample(batch *mat64.Dense) { // spaced bins and guarantees that one sample is generated per bin. Within each bin, // the location is randomly sampled. The distmv.NewUnitUniform function can be used // for easy sampling from the unit hypercube. -func LatinHypercube(batch *mat64.Dense, q distmv.Quantiler, src *rand.Rand) { +func LatinHypercube(batch *mat.Dense, q distmv.Quantiler, src *rand.Rand) { r, c := batch.Dims() var f64 func() float64 var perm func(int) []int @@ -132,7 +132,7 @@ type Importancer struct { // SampleWeighted generates rows(batch) samples using the Importance sampling // generation procedure. -func (l Importancer) SampleWeighted(batch *mat64.Dense, weights []float64) { +func (l Importancer) SampleWeighted(batch *mat.Dense, weights []float64) { Importance(batch, weights, l.Target, l.Proposal) } @@ -150,7 +150,7 @@ func (l Importancer) SampleWeighted(batch *mat64.Dense, weights []float64) { // // If weights is nil, the weights are not stored. The length of weights must equal // the length of batch, otherwise Importance will panic. -func Importance(batch *mat64.Dense, weights []float64, target distmv.LogProber, proposal distmv.RandLogProber) { +func Importance(batch *mat.Dense, weights []float64, target distmv.LogProber, proposal distmv.RandLogProber) { r, _ := batch.Dims() if r != len(weights) { panic(badLengthMismatch) @@ -194,7 +194,7 @@ func (r *Rejectioner) Proposed() int { // Rejection sampling may fail if the constant is insufficiently high, as described // in the function comment for Rejection. If the generation fails, the samples // are set to math.NaN(), and a call to Err will return a non-nil value. -func (r *Rejectioner) Sample(batch *mat64.Dense) { +func (r *Rejectioner) Sample(batch *mat.Dense) { r.err = nil r.proposed = 0 proposed, ok := Rejection(batch, r.Target, r.Proposal, r.C, r.Src) @@ -225,7 +225,7 @@ func (r *Rejectioner) Sample(batch *mat64.Dense) { // a value that is proportional to the probability (logprob + constant). This is // useful for cases where the probability distribution is only known up to a normalization // constant. -func Rejection(batch *mat64.Dense, target distmv.LogProber, proposal distmv.RandLogProber, c float64, src *rand.Rand) (nProposed int, ok bool) { +func Rejection(batch *mat.Dense, target distmv.LogProber, proposal distmv.RandLogProber, c float64, src *rand.Rand) (nProposed int, ok bool) { if c < 1 { panic("rejection: acceptance constant must be greater than 1") } @@ -268,13 +268,13 @@ type IIDer struct { } // Sample generates a set of identically and independently distributed samples. -func (iid IIDer) Sample(batch *mat64.Dense) { +func (iid IIDer) Sample(batch *mat.Dense) { IID(batch, iid.Dist) } // IID generates a set of independently and identically distributed samples from // the input distribution. -func IID(batch *mat64.Dense, d distmv.Rander) { +func IID(batch *mat.Dense, d distmv.Rander) { r, _ := batch.Dims() for i := 0; i < r; i++ { d.Rand(batch.RawRowView(i)) diff --git a/stat/statmat.go b/stat/statmat.go index a0d9078c..06866a34 100644 --- a/stat/statmat.go +++ b/stat/statmat.go @@ -8,8 +8,7 @@ import ( "math" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) // CovarianceMatrix returns the covariance matrix (also known as the @@ -21,9 +20,9 @@ import ( // must not contain negative elements. // If cov is not nil it must either be zero-sized or have the same number of // columns as the input data matrix. cov will be used as the destination for -// the covariance data. If cov is nil, a new mat64.SymDense is allocated for +// the covariance data. If cov is nil, a new mat.SymDense is allocated for // the destination. -func CovarianceMatrix(cov *mat64.SymDense, x mat64.Matrix, weights []float64) *mat64.SymDense { +func CovarianceMatrix(cov *mat.SymDense, x mat.Matrix, weights []float64) *mat.SymDense { // This is the matrix version of the two-pass algorithm. It doesn't use the // additional floating point error correction that the Covariance function uses // to reduce the impact of rounding during centering. @@ -31,12 +30,12 @@ func CovarianceMatrix(cov *mat64.SymDense, x mat64.Matrix, weights []float64) *m r, c := x.Dims() if cov == nil { - cov = mat64.NewSymDense(c, nil) + cov = mat.NewSymDense(c, nil) } else if n := cov.Symmetric(); n != c && n != 0 { - panic(matrix.ErrShape) + panic(mat.ErrShape) } - var xt mat64.Dense + var xt mat.Dense xt.Clone(x.T()) // Subtract the mean of each of the columns. for i := 0; i < c; i++ { @@ -82,9 +81,9 @@ func CovarianceMatrix(cov *mat64.SymDense, x mat64.Matrix, weights []float64) *m // must not contain negative elements. // If corr is not nil it must either be zero-sized or have the same number of // columns as the input data matrix. corr will be used as the destination for -// the correlation data. If corr is nil, a new mat64.SymDense is allocated for +// the correlation data. If corr is nil, a new mat.SymDense is allocated for // the destination. -func CorrelationMatrix(corr *mat64.SymDense, x mat64.Matrix, weights []float64) *mat64.SymDense { +func CorrelationMatrix(corr *mat.SymDense, x mat.Matrix, weights []float64) *mat.SymDense { // This will panic if the sizes don't match, or if weights is the wrong size. corr = CovarianceMatrix(corr, x, weights) covToCorr(corr) @@ -92,7 +91,7 @@ func CorrelationMatrix(corr *mat64.SymDense, x mat64.Matrix, weights []float64) } // covToCorr converts a covariance matrix to a correlation matrix. -func covToCorr(c *mat64.SymDense) { +func covToCorr(c *mat.SymDense) { r := c.Symmetric() s := make([]float64, r) @@ -113,11 +112,11 @@ func covToCorr(c *mat64.SymDense) { // The input sigma should be vector of standard deviations corresponding // to the covariance. It will panic if len(sigma) is not equal to the // number of rows in the correlation matrix. -func corrToCov(c *mat64.SymDense, sigma []float64) { +func corrToCov(c *mat.SymDense, sigma []float64) { r, _ := c.Dims() if r != len(sigma) { - panic(matrix.ErrShape) + panic(mat.ErrShape) } for i, sx := range sigma { // Ensure that the diagonal has exactly sigma squared. @@ -135,13 +134,13 @@ func corrToCov(c *mat64.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 *mat64.Vector, chol *mat64.Cholesky) float64 { - var diff mat64.Vector +func Mahalanobis(x, y *mat.Vector, chol *mat.Cholesky) float64 { + var diff mat.Vector diff.SubVec(x, y) - var tmp mat64.Vector + var tmp mat.Vector err := tmp.SolveCholeskyVec(chol, &diff) if err != nil { return math.NaN() } - return math.Sqrt(mat64.Dot(&tmp, &diff)) + return math.Sqrt(mat.Dot(&tmp, &diff)) } diff --git a/stat/statmat_test.go b/stat/statmat_test.go index c0a523f6..4f0ddc8a 100644 --- a/stat/statmat_test.go +++ b/stat/statmat_test.go @@ -10,19 +10,19 @@ import ( "testing" "gonum.org/v1/gonum/floats" - "gonum.org/v1/gonum/matrix/mat64" + "gonum.org/v1/gonum/mat" ) func TestCovarianceMatrix(t *testing.T) { // An alternative way to test this is to call the Variance and // Covariance functions and ensure that the results are identical. for i, test := range []struct { - data *mat64.Dense + data *mat.Dense weights []float64 - ans *mat64.Dense + ans *mat.Dense }{ { - data: mat64.NewDense(5, 2, []float64{ + data: mat.NewDense(5, 2, []float64{ -2, -4, -1, 2, 0, 0, @@ -30,12 +30,12 @@ func TestCovarianceMatrix(t *testing.T) { 2, 4, }), weights: nil, - ans: mat64.NewDense(2, 2, []float64{ + ans: mat.NewDense(2, 2, []float64{ 2.5, 3, 3, 10, }), }, { - data: mat64.NewDense(3, 2, []float64{ + data: mat.NewDense(3, 2, []float64{ 1, 1, 2, 4, 3, 9, @@ -45,7 +45,7 @@ func TestCovarianceMatrix(t *testing.T) { 1.5, 1, }, - ans: mat64.NewDense(2, 2, []float64{ + ans: mat.NewDense(2, 2, []float64{ .8, 3.2, 3.2, 13.142857142857146, }), @@ -60,9 +60,9 @@ func TestCovarianceMatrix(t *testing.T) { if test.weights != nil { copy(w, test.weights) } - for _, cov := range []*mat64.SymDense{nil, {}} { + for _, cov := range []*mat.SymDense{nil, {}} { c := CovarianceMatrix(cov, test.data, test.weights) - if !mat64.Equal(c, test.ans) { + if !mat.Equal(c, test.ans) { t.Errorf("%d: expected cov %v, found %v", i, test.ans, c) } if !floats.Equal(d, r.Data) { @@ -76,8 +76,8 @@ func TestCovarianceMatrix(t *testing.T) { _, cols := c.Dims() for ci := 0; ci < cols; ci++ { for cj := 0; cj < cols; cj++ { - x := mat64.Col(nil, ci, test.data) - y := mat64.Col(nil, cj, test.data) + x := mat.Col(nil, ci, test.data) + y := mat.Col(nil, cj, test.data) cov := Covariance(x, y, test.weights) if math.Abs(cov-c.At(ci, cj)) > 1e-14 { t.Errorf("CovMat does not match at (%v, %v). Want %v, got %v.", ci, cj, cov, c.At(ci, cj)) @@ -87,38 +87,38 @@ func TestCovarianceMatrix(t *testing.T) { } } - if !Panics(func() { CovarianceMatrix(nil, mat64.NewDense(5, 2, nil), []float64{}) }) { + if !Panics(func() { CovarianceMatrix(nil, mat.NewDense(5, 2, nil), []float64{}) }) { t.Errorf("CovarianceMatrix did not panic with weight size mismatch") } - if !Panics(func() { CovarianceMatrix(mat64.NewSymDense(1, nil), mat64.NewDense(5, 2, nil), nil) }) { + if !Panics(func() { CovarianceMatrix(mat.NewSymDense(1, nil), mat.NewDense(5, 2, nil), nil) }) { t.Errorf("CovarianceMatrix did not panic with preallocation size mismatch") } - if !Panics(func() { CovarianceMatrix(nil, mat64.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { + if !Panics(func() { CovarianceMatrix(nil, mat.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { t.Errorf("CovarianceMatrix did not panic with negative weights") } } func TestCorrelationMatrix(t *testing.T) { for i, test := range []struct { - data *mat64.Dense + data *mat.Dense weights []float64 - ans *mat64.Dense + ans *mat.Dense }{ { - data: mat64.NewDense(3, 3, []float64{ + data: mat.NewDense(3, 3, []float64{ 1, 2, 3, 3, 4, 5, 5, 6, 7, }), weights: nil, - ans: mat64.NewDense(3, 3, []float64{ + ans: mat.NewDense(3, 3, []float64{ 1, 1, 1, 1, 1, 1, 1, 1, 1, }), }, { - data: mat64.NewDense(5, 2, []float64{ + data: mat.NewDense(5, 2, []float64{ -2, -4, -1, 2, 0, 0, @@ -126,12 +126,12 @@ func TestCorrelationMatrix(t *testing.T) { 2, 4, }), weights: nil, - ans: mat64.NewDense(2, 2, []float64{ + ans: mat.NewDense(2, 2, []float64{ 1, 0.6, 0.6, 1, }), }, { - data: mat64.NewDense(3, 2, []float64{ + data: mat.NewDense(3, 2, []float64{ 1, 1, 2, 4, 3, 9, @@ -141,7 +141,7 @@ func TestCorrelationMatrix(t *testing.T) { 1.5, 1, }, - ans: mat64.NewDense(2, 2, []float64{ + ans: mat.NewDense(2, 2, []float64{ 1, 0.9868703275903379, 0.9868703275903379, 1, }), @@ -156,9 +156,9 @@ func TestCorrelationMatrix(t *testing.T) { if test.weights != nil { copy(w, test.weights) } - for _, corr := range []*mat64.SymDense{nil, {}} { + for _, corr := range []*mat.SymDense{nil, {}} { c := CorrelationMatrix(corr, test.data, test.weights) - if !mat64.Equal(c, test.ans) { + if !mat.Equal(c, test.ans) { t.Errorf("%d: expected corr %v, found %v", i, test.ans, c) } if !floats.Equal(d, r.Data) { @@ -172,8 +172,8 @@ func TestCorrelationMatrix(t *testing.T) { _, cols := c.Dims() for ci := 0; ci < cols; ci++ { for cj := 0; cj < cols; cj++ { - x := mat64.Col(nil, ci, test.data) - y := mat64.Col(nil, cj, test.data) + x := mat.Col(nil, ci, test.data) + y := mat.Col(nil, cj, test.data) corr := Correlation(x, y, test.weights) if math.Abs(corr-c.At(ci, cj)) > 1e-14 { t.Errorf("CorrMat does not match at (%v, %v). Want %v, got %v.", ci, cj, corr, c.At(ci, cj)) @@ -183,13 +183,13 @@ func TestCorrelationMatrix(t *testing.T) { } } - if !Panics(func() { CorrelationMatrix(nil, mat64.NewDense(5, 2, nil), []float64{}) }) { + if !Panics(func() { CorrelationMatrix(nil, mat.NewDense(5, 2, nil), []float64{}) }) { t.Errorf("CorrelationMatrix did not panic with weight size mismatch") } - if !Panics(func() { CorrelationMatrix(mat64.NewSymDense(1, nil), mat64.NewDense(5, 2, nil), nil) }) { + if !Panics(func() { CorrelationMatrix(mat.NewSymDense(1, nil), mat.NewDense(5, 2, nil), nil) }) { t.Errorf("CorrelationMatrix did not panic with preallocation size mismatch") } - if !Panics(func() { CorrelationMatrix(nil, mat64.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { + if !Panics(func() { CorrelationMatrix(nil, mat.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { t.Errorf("CorrelationMatrix did not panic with negative weights") } } @@ -197,11 +197,11 @@ func TestCorrelationMatrix(t *testing.T) { func TestCorrCov(t *testing.T) { // test both Cov2Corr and Cov2Corr for i, test := range []struct { - data *mat64.Dense + data *mat.Dense weights []float64 }{ { - data: mat64.NewDense(3, 3, []float64{ + data: mat.NewDense(3, 3, []float64{ 1, 2, 3, 3, 4, 5, 5, 6, 7, @@ -209,7 +209,7 @@ func TestCorrCov(t *testing.T) { weights: nil, }, { - data: mat64.NewDense(5, 2, []float64{ + data: mat.NewDense(5, 2, []float64{ -2, -4, -1, 2, 0, 0, @@ -218,7 +218,7 @@ func TestCorrCov(t *testing.T) { }), weights: nil, }, { - data: mat64.NewDense(3, 2, []float64{ + data: mat.NewDense(3, 2, []float64{ 1, 1, 2, 4, 3, 9, @@ -241,22 +241,22 @@ func TestCorrCov(t *testing.T) { sigmas[i] = math.Sqrt(cov.At(i, i)) } - covFromCorr := mat64.NewSymDense(corr.Symmetric(), nil) + covFromCorr := mat.NewSymDense(corr.Symmetric(), nil) covFromCorr.CopySym(corr) corrToCov(covFromCorr, sigmas) - corrFromCov := mat64.NewSymDense(cov.Symmetric(), nil) + corrFromCov := mat.NewSymDense(cov.Symmetric(), nil) corrFromCov.CopySym(cov) covToCorr(corrFromCov) - if !mat64.EqualApprox(corr, corrFromCov, 1e-14) { + if !mat.EqualApprox(corr, corrFromCov, 1e-14) { t.Errorf("%d: corrToCov did not match direct Correlation calculation. Want: %v, got: %v. ", i, corr, corrFromCov) } - if !mat64.EqualApprox(cov, covFromCorr, 1e-14) { + if !mat.EqualApprox(cov, covFromCorr, 1e-14) { t.Errorf("%d: covToCorr did not match direct Covariance calculation. Want: %v, got: %v. ", i, cov, covFromCorr) } - if !Panics(func() { corrToCov(mat64.NewSymDense(2, nil), []float64{}) }) { + if !Panics(func() { corrToCov(mat.NewSymDense(2, nil), []float64{}) }) { t.Errorf("CorrelationMatrix did not panic with sigma size mismatch") } } @@ -265,14 +265,14 @@ func TestCorrCov(t *testing.T) { func TestMahalanobis(t *testing.T) { // Comparison with scipy. for cas, test := range []struct { - x, y *mat64.Vector - Sigma *mat64.SymDense + x, y *mat.Vector + Sigma *mat.SymDense ans float64 }{ { - x: mat64.NewVector(3, []float64{1, 2, 3}), - y: mat64.NewVector(3, []float64{0.8, 1.1, -1}), - Sigma: mat64.NewSymDense(3, + x: mat.NewVector(3, []float64{1, 2, 3}), + y: mat.NewVector(3, []float64{0.8, 1.1, -1}), + Sigma: mat.NewSymDense(3, []float64{ 0.8, 0.3, 0.1, 0.3, 0.7, -0.1, @@ -280,7 +280,7 @@ func TestMahalanobis(t *testing.T) { ans: 1.9251757377680914, }, } { - var chol mat64.Cholesky + var chol mat.Cholesky ok := chol.Factorize(test.Sigma) if !ok { panic("bad test") @@ -294,21 +294,21 @@ func TestMahalanobis(t *testing.T) { // benchmarks -func randMat(r, c int) mat64.Matrix { +func randMat(r, c int) mat.Matrix { x := make([]float64, r*c) for i := range x { x[i] = rand.Float64() } - return mat64.NewDense(r, c, x) + return mat.NewDense(r, c, x) } -func benchmarkCovarianceMatrix(b *testing.B, m mat64.Matrix) { +func benchmarkCovarianceMatrix(b *testing.B, m mat.Matrix) { b.ResetTimer() for i := 0; i < b.N; i++ { CovarianceMatrix(nil, m, nil) } } -func benchmarkCovarianceMatrixWeighted(b *testing.B, m mat64.Matrix) { +func benchmarkCovarianceMatrixWeighted(b *testing.B, m mat.Matrix) { r, _ := m.Dims() wts := make([]float64, r) for i := range wts { @@ -319,9 +319,9 @@ func benchmarkCovarianceMatrixWeighted(b *testing.B, m mat64.Matrix) { CovarianceMatrix(nil, m, wts) } } -func benchmarkCovarianceMatrixInPlace(b *testing.B, m mat64.Matrix) { +func benchmarkCovarianceMatrixInPlace(b *testing.B, m mat.Matrix) { _, c := m.Dims() - res := mat64.NewSymDense(c, nil) + res := mat.NewSymDense(c, nil) b.ResetTimer() for i := 0; i < b.N; i++ { CovarianceMatrix(res, m, nil) @@ -434,7 +434,7 @@ func BenchmarkCovToCorr(b *testing.B) { // generate a 10x10 covariance matrix m := randMat(small, small) c := CovarianceMatrix(nil, m, nil) - cc := mat64.NewSymDense(c.Symmetric(), nil) + cc := mat.NewSymDense(c.Symmetric(), nil) b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() @@ -448,7 +448,7 @@ func BenchmarkCorrToCov(b *testing.B) { // generate a 10x10 correlation matrix m := randMat(small, small) c := CorrelationMatrix(nil, m, nil) - cc := mat64.NewSymDense(c.Symmetric(), nil) + cc := mat.NewSymDense(c.Symmetric(), nil) sigma := make([]float64, small) for i := range sigma { sigma[i] = 2