matrix: rename matrix to mat, and merge with mat64 and cmat128.

This merges the three packages, matrix, mat64, and cmat128. It then renames this big package to mat. It fixes the import statements and corresponding code
This commit is contained in:
Brendan Tracey
2017-06-13 10:26:10 -06:00
parent 2b81cf67bf
commit 3fa9374bd4
60 changed files with 426 additions and 621 deletions

View File

@@ -4,7 +4,7 @@
//+build cblas //+build cblas
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"

View File

@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the CholeskyDecomposition class from Jama 1.0.3. // Based on the CholeskyDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"math" "math"
@@ -11,7 +11,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
const ( const (
@@ -48,8 +47,8 @@ func (c *Cholesky) updateCond(norm float64) {
// the condition number somewhat. // the condition number somewhat.
// The norm of the original factorized matrix cannot be stored because of // The norm of the original factorized matrix cannot be stored because of
// update possibilities. // update possibilities.
unorm := lapack64.Lantr(matrix.CondNorm, c.chol.mat, work) unorm := lapack64.Lantr(CondNorm, c.chol.mat, work)
lnorm := lapack64.Lantr(matrix.CondNormTrans, c.chol.mat, work) lnorm := lapack64.Lantr(CondNormTrans, c.chol.mat, work)
norm = unorm * lnorm norm = unorm * lnorm
} }
sym := c.chol.asSymBlas() sym := c.chol.asSymBlas()
@@ -65,15 +64,15 @@ func (c *Cholesky) updateCond(norm float64) {
func (c *Cholesky) Factorize(a Symmetric) (ok bool) { func (c *Cholesky) Factorize(a Symmetric) (ok bool) {
n := a.Symmetric() n := a.Symmetric()
if c.isZero() { if c.isZero() {
c.chol = NewTriDense(n, matrix.Upper, nil) c.chol = NewTriDense(n, Upper, nil)
} else { } 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) copySymIntoTriangle(c.chol, a)
sym := c.chol.asSymBlas() sym := c.chol.asSymBlas()
work := getFloats(c.chol.mat.N, false) work := getFloats(c.chol.mat.N, false)
norm := lapack64.Lansy(matrix.CondNorm, sym, work) norm := lapack64.Lansy(CondNorm, sym, work)
putFloats(work) putFloats(work)
_, ok = lapack64.Potrf(sym) _, ok = lapack64.Potrf(sym)
if ok { if ok {
@@ -98,13 +97,13 @@ func (c *Cholesky) Reset() {
// not stored inside, the receiver. // not stored inside, the receiver.
func (c *Cholesky) SetFromU(t *TriDense) { func (c *Cholesky) SetFromU(t *TriDense) {
n, kind := t.Triangle() n, kind := t.Triangle()
if kind != matrix.Upper { if kind != Upper {
panic("cholesky: matrix must be upper triangular") panic("cholesky: matrix must be upper triangular")
} }
if c.isZero() { if c.isZero() {
c.chol = NewTriDense(n, matrix.Upper, nil) c.chol = NewTriDense(n, Upper, nil)
} else { } 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.chol.Copy(t)
c.updateCond(-1) c.updateCond(-1)
@@ -119,9 +118,9 @@ func (c *Cholesky) Clone(chol *Cholesky) {
} }
n := chol.Size() n := chol.Size()
if c.isZero() { if c.isZero() {
c.chol = NewTriDense(n, matrix.Upper, nil) c.chol = NewTriDense(n, Upper, nil)
} else { } 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.chol.Copy(chol.chol)
c.cond = chol.cond c.cond = chol.cond
@@ -164,7 +163,7 @@ func (m *Dense) SolveCholesky(chol *Cholesky, b Matrix) error {
n := chol.chol.mat.N n := chol.chol.mat.N
bm, bn := b.Dims() bm, bn := b.Dims()
if n != bm { if n != bm {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(bm, bn) 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.Trans, 1, chol.chol.mat, m.mat)
blas64.Trsm(blas.Left, blas.NoTrans, 1, chol.chol.mat, m.mat) blas64.Trsm(blas.Left, blas.NoTrans, 1, chol.chol.mat, m.mat)
if chol.cond > matrix.ConditionTolerance { if chol.cond > ConditionTolerance {
return matrix.Condition(chol.cond) return Condition(chol.cond)
} }
return nil return nil
} }
@@ -188,7 +187,7 @@ func (m *Dense) solveTwoChol(a, b *Cholesky) error {
} }
bn := b.chol.mat.N bn := b.chol.mat.N
if a.chol.mat.N != bn { if a.chol.mat.N != bn {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAsZeroed(bn, bn) 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.Trans, 1, a.chol.mat, m.mat)
blas64.Trsm(blas.Left, blas.NoTrans, 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) blas64.Trmm(blas.Right, blas.NoTrans, 1, b.chol.mat, m.mat)
if a.cond > matrix.ConditionTolerance { if a.cond > ConditionTolerance {
return matrix.Condition(a.cond) return Condition(a.cond)
} }
return nil return nil
} }
@@ -211,7 +210,7 @@ func (v *Vector) SolveCholeskyVec(chol *Cholesky, b *Vector) error {
n := chol.chol.mat.N n := chol.chol.mat.N
vn := b.Len() vn := b.Len()
if vn != n { if vn != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != b { if v != b {
v.checkOverlap(b.mat) 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.Trans, chol.chol.mat, v.mat)
blas64.Trsv(blas.NoTrans, chol.chol.mat, v.mat) blas64.Trsv(blas.NoTrans, chol.chol.mat, v.mat)
if chol.cond > matrix.ConditionTolerance { if chol.cond > ConditionTolerance {
return matrix.Condition(chol.cond) return Condition(chol.cond)
} }
return nil return nil
@@ -237,7 +236,7 @@ func (t *TriDense) UFromCholesky(chol *Cholesky) {
panic(badCholesky) panic(badCholesky)
} }
n := chol.chol.mat.N n := chol.chol.mat.N
t.reuseAs(n, matrix.Upper) t.reuseAs(n, Upper)
t.Copy(chol.chol) t.Copy(chol.chol)
} }
@@ -249,7 +248,7 @@ func (t *TriDense) LFromCholesky(chol *Cholesky) {
panic(badCholesky) panic(badCholesky)
} }
n := chol.chol.mat.N n := chol.chol.mat.N
t.reuseAs(n, matrix.Lower) t.reuseAs(n, Lower)
t.Copy(chol.chol.TTri()) t.Copy(chol.chol.TTri())
} }
@@ -307,13 +306,13 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x *Vector) (ok bool
} }
n := orig.Size() n := orig.Size()
if x.Len() != n { if x.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if orig != c { if orig != c {
if c.isZero() { if c.isZero() {
c.chol = NewTriDense(n, matrix.Upper, nil) c.chol = NewTriDense(n, Upper, nil)
} else if c.chol.mat.N != n { } else if c.chol.mat.N != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
c.chol.Copy(orig.chol) c.chol.Copy(orig.chol)
} }

View File

@@ -2,29 +2,29 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64_test package mat_test
import ( import (
"fmt" "fmt"
"gonum.org/v1/gonum/matrix/mat64" "gonum.org/v1/gonum/mat"
) )
func ExampleCholesky() { func ExampleCholesky() {
// Construct a symmetric positive definite matrix. // Construct a symmetric positive definite matrix.
tmp := mat64.NewDense(4, 4, []float64{ tmp := mat.NewDense(4, 4, []float64{
2, 6, 8, -4, 2, 6, 8, -4,
1, 8, 7, -2, 1, 8, 7, -2,
2, 2, 1, 7, 2, 2, 1, 7,
8, -2, -2, 1, 8, -2, -2, 1,
}) })
var a mat64.SymDense var a mat.SymDense
a.SymOuterK(1, tmp) 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. // Compute the cholesky factorization.
var chol mat64.Cholesky var chol mat.Cholesky
if ok := chol.Factorize(&a); !ok { if ok := chol.Factorize(&a); !ok {
fmt.Println("a matrix is not positive semi-definite.") 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()) fmt.Printf("\nThe determinant of a is %0.4g\n\n", chol.Det())
// Use the factorization to solve the system of equations a * x = b. // Use the factorization to solve the system of equations a * x = b.
b := mat64.NewVector(4, []float64{1, 2, 3, 4}) b := mat.NewVector(4, []float64{1, 2, 3, 4})
var x mat64.Vector var x mat.Vector
if err := x.SolveCholeskyVec(&chol, b); err != nil { if err := x.SolveCholeskyVec(&chol, b); err != nil {
fmt.Println("Matrix is near singular: ", err) fmt.Println("Matrix is near singular: ", err)
} }
fmt.Println("Solve a * x = b") 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. // Extract the factorization and check that it equals the original matrix.
var t mat64.TriDense var t mat.TriDense
t.LFromCholesky(&chol) t.LFromCholesky(&chol)
var test mat64.Dense var test mat.Dense
test.Mul(&t, t.T()) test.Mul(&t, t.T())
fmt.Println() 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: // Output:
// a = ⎡120 114 -4 -16⎤ // a = ⎡120 114 -4 -16⎤
@@ -70,35 +70,35 @@ func ExampleCholesky() {
} }
func ExampleCholeskySymRankOne() { func ExampleCholeskySymRankOne() {
a := mat64.NewSymDense(4, []float64{ a := mat.NewSymDense(4, []float64{
1, 1, 1, 1, 1, 1, 1, 1,
0, 2, 3, 4, 0, 2, 3, 4,
0, 0, 6, 10, 0, 0, 6, 10,
0, 0, 0, 20, 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. // Compute the Cholesky factorization.
var chol mat64.Cholesky var chol mat.Cholesky
if ok := chol.Factorize(a); !ok { if ok := chol.Factorize(a); !ok {
fmt.Println("matrix a is not positive definite.") fmt.Println("matrix a is not positive definite.")
} }
x := mat64.NewVector(4, []float64{0, 0, 0, 1}) x := mat.NewVector(4, []float64{0, 0, 0, 1})
fmt.Printf("\nx = %0.4v\n", mat64.Formatted(x, mat64.Prefix(" "))) fmt.Printf("\nx = %0.4v\n", mat.Formatted(x, mat.Prefix(" ")))
// Rank-1 update the factorization. // Rank-1 update the factorization.
chol.SymRankOne(&chol, 1, x) chol.SymRankOne(&chol, 1, x)
// Rank-1 update the matrix a. // Rank-1 update the matrix a.
a.SymRankOne(a, 1, x) a.SymRankOne(a, 1, x)
var au mat64.SymDense var au mat.SymDense
au.FromCholesky(&chol) au.FromCholesky(&chol)
// Print the matrix that was updated directly. // 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. // 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: // Output:
// A = ⎡ 1 1 1 1⎤ // A = ⎡ 1 1 1 1⎤

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
@@ -10,7 +10,6 @@ import (
"testing" "testing"
"gonum.org/v1/gonum/blas/testblas" "gonum.org/v1/gonum/blas/testblas"
"gonum.org/v1/gonum/matrix"
) )
func TestCholesky(t *testing.T) { func TestCholesky(t *testing.T) {
@@ -269,7 +268,7 @@ func TestCloneCholesky(t *testing.T) {
// Corrupt chol2 and try again // Corrupt chol2 and try again
chol2.cond = math.NaN() chol2.cond = math.NaN()
chol2.chol = NewTriDense(2, matrix.Upper, nil) chol2.chol = NewTriDense(2, Upper, nil)
chol2.Clone(&chol) chol2.Clone(&chol)
if chol.cond != chol2.cond { if chol.cond != chol2.cond {
t.Errorf("condition number mismatch from non-zero") t.Errorf("condition number mismatch from non-zero")

View File

@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package cmat128 package mat
// Matrix is the basic matrix interface type. // CMatrix is the basic matrix interface type for complex matrices.
type Matrix interface { type CMatrix interface {
// Dims returns the dimensions of a Matrix. // Dims returns the dimensions of a Matrix.
Dims() (r, c int) Dims() (r, c int)
@@ -17,11 +17,11 @@ type Matrix interface {
// returns a copy of the underlying data is implementation dependent. // returns a copy of the underlying data is implementation dependent.
// This method may be implemented using the Conjugate type, which // This method may be implemented using the Conjugate type, which
// provides an implicit matrix conjugate transpose. // provides an implicit matrix conjugate transpose.
H() Matrix H() CMatrix
} }
var ( var (
_ Matrix = Conjugate{} _ CMatrix = Conjugate{}
_ Unconjugator = Conjugate{} _ Unconjugator = Conjugate{}
) )
@@ -29,13 +29,13 @@ var (
// It implements the Matrix interface, returning values from the conjugate // It implements the Matrix interface, returning values from the conjugate
// transpose of the matrix within. // transpose of the matrix within.
type Conjugate struct { type Conjugate struct {
Matrix Matrix CMatrix CMatrix
} }
// At returns the value of the element at row i and column j of the transposed // 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. // matrix, that is, row j and column i of the Matrix field.
func (t Conjugate) At(i, j int) complex128 { 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)) 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 // is the number of columns in the Matrix field, and the number of columns is
// the number of rows in the Matrix field. // the number of rows in the Matrix field.
func (t Conjugate) Dims() (r, c int) { func (t Conjugate) Dims() (r, c int) {
c, r = t.Matrix.Dims() c, r = t.CMatrix.Dims()
return r, c return r, c
} }
// H performs an implicit conjugate transpose by returning the Matrix field. // H performs an implicit conjugate transpose by returning the Matrix field.
func (t Conjugate) H() Matrix { func (t Conjugate) H() CMatrix {
return t.Matrix return t.CMatrix
} }
// Unconjugate returns the Matrix field. // Unconjugate returns the Matrix field.
func (t Conjugate) Unconjugate() Matrix { func (t Conjugate) Unconjugate() CMatrix {
return t.Matrix return t.CMatrix
} }
// Unconjugator is a type that can undo an implicit conjugate transpose. // 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 // Unconjugate returns the underlying Matrix stored for the implicit
// conjugate transpose. // conjugate transpose.
Unconjugate() Matrix Unconjugate() CMatrix
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package matrix package mat
// TriKind represents the triangularity of the matrix. // TriKind represents the triangularity of the matrix.
type TriKind bool type TriKind bool

View File

@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
var ( var (
@@ -45,7 +44,7 @@ type Dense struct {
// element in the data slice is the {i, j}-th element in the matrix. // element in the data slice is the {i, j}-th element in the matrix.
func NewDense(r, c int, data []float64) *Dense { func NewDense(r, c int, data []float64) *Dense {
if data != nil && r*c != len(data) { if data != nil && r*c != len(data) {
panic(matrix.ErrShape) panic(ErrShape)
} }
if data == nil { if data == nil {
data = make([]float64, r*c) data = make([]float64, r*c)
@@ -83,7 +82,7 @@ func (m *Dense) reuseAs(r, c int) {
return return
} }
if r != m.mat.Rows || c != m.mat.Cols { 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 return
} }
if r != m.mat.Rows || c != m.mat.Cols { if r != m.mat.Rows || c != m.mat.Cols {
panic(matrix.ErrShape) panic(ErrShape)
} }
for i := 0; i < r; i++ { for i := 0; i < r; i++ {
zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]) 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. // See ColViewer for more information.
func (m *Dense) ColView(j int) *Vector { func (m *Dense) ColView(j int) *Vector {
if j >= m.mat.Cols || j < 0 { if j >= m.mat.Cols || j < 0 {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return &Vector{ return &Vector{
mat: blas64.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. // in src. len(src) must equal the number of rows in the receiver.
func (m *Dense) SetCol(j int, src []float64) { func (m *Dense) SetCol(j int, src []float64) {
if j >= m.mat.Cols || j < 0 { if j >= m.mat.Cols || j < 0 {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
if len(src) != m.mat.Rows { if len(src) != m.mat.Rows {
panic(matrix.ErrColLength) panic(ErrColLength)
} }
blas64.Copy(m.mat.Rows, 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. // in src. len(src) must equal the number of columns in the receiver.
func (m *Dense) SetRow(i int, src []float64) { func (m *Dense) SetRow(i int, src []float64) {
if i >= m.mat.Rows || i < 0 { if i >= m.mat.Rows || i < 0 {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if len(src) != m.mat.Cols { if len(src) != m.mat.Cols {
panic(matrix.ErrRowLength) panic(ErrRowLength)
} }
copy(m.rawRowView(i), src) copy(m.rawRowView(i), src)
@@ -252,7 +251,7 @@ func (m *Dense) SetRow(i int, src []float64) {
// See RowViewer for more information. // See RowViewer for more information.
func (m *Dense) RowView(i int) *Vector { func (m *Dense) RowView(i int) *Vector {
if i >= m.mat.Rows || i < 0 { if i >= m.mat.Rows || i < 0 {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
return &Vector{ return &Vector{
mat: blas64.Vector{ mat: blas64.Vector{
@@ -267,7 +266,7 @@ func (m *Dense) RowView(i int) *Vector {
// receiver. // receiver.
func (m *Dense) RawRowView(i int) []float64 { func (m *Dense) RawRowView(i int) []float64 {
if i >= m.mat.Rows || i < 0 { if i >= m.mat.Rows || i < 0 {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
return m.rawRowView(i) 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 { func (m *Dense) Slice(i, k, j, l int) Matrix {
mr, mc := m.Dims() mr, mc := m.Dims()
if i < 0 || mr <= i || j < 0 || mc <= j || k <= i || mr < k || l <= j || mc < l { 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 := *m
t.mat.Data = t.mat.Data[i*t.mat.Stride+j : (k-1)*t.mat.Stride+l] 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. // during the call to Grow.
func (m *Dense) Grow(r, c int) Matrix { func (m *Dense) Grow(r, c int) Matrix {
if r < 0 || c < 0 { if r < 0 || c < 0 {
panic(matrix.ErrIndexOutOfRange) panic(ErrIndexOutOfRange)
} }
if r == 0 && c == 0 { if r == 0 && c == 0 {
return m return m
@@ -514,7 +513,7 @@ func (m *Dense) Stack(a, b Matrix) {
ar, ac := a.Dims() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ac != bc || m == a || m == b { if ac != bc || m == a || m == b {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(ar+br, ac) m.reuseAs(ar+br, ac)
@@ -532,7 +531,7 @@ func (m *Dense) Augment(a, b Matrix) {
ar, ac := a.Dims() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br || m == a || m == b { if ar != br || m == a || m == b {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(ar, ac+bc) m.reuseAs(ar, ac+bc)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
@@ -10,7 +10,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "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 // 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() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br || ac != bc { if ar != br || ac != bc {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -66,7 +65,7 @@ func (m *Dense) Sub(a, b Matrix) {
ar, ac := a.Dims() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br || ac != bc { if ar != br || ac != bc {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -114,7 +113,7 @@ func (m *Dense) MulElem(a, b Matrix) {
ar, ac := a.Dims() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br || ac != bc { if ar != br || ac != bc {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -162,7 +161,7 @@ func (m *Dense) DivElem(a, b Matrix) {
ar, ac := a.Dims() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br || ac != bc { if ar != br || ac != bc {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -211,7 +210,7 @@ func (m *Dense) Inverse(a Matrix) error {
// TODO(btracey): Special case for RawTriangular, etc. // TODO(btracey): Special case for RawTriangular, etc.
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrSquare) panic(ErrSquare)
} }
m.reuseAs(a.Dims()) m.reuseAs(a.Dims())
aU, aTrans := untranspose(a) aU, aTrans := untranspose(a)
@@ -234,7 +233,7 @@ func (m *Dense) Inverse(a Matrix) error {
defer putInts(ipiv) defer putInts(ipiv)
ok := lapack64.Getrf(m.mat, ipiv) ok := lapack64.Getrf(m.mat, ipiv)
if !ok { 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. work := getFloats(4*r, false) // must be at least 4*r for cond.
lapack64.Getri(m.mat, ipiv, work, -1) lapack64.Getri(m.mat, ipiv, work, -1)
@@ -247,14 +246,14 @@ func (m *Dense) Inverse(a Matrix) error {
} }
defer putFloats(work) defer putFloats(work)
lapack64.Getri(m.mat, ipiv, work, len(work)) lapack64.Getri(m.mat, ipiv, work, len(work))
norm := lapack64.Lange(matrix.CondNorm, m.mat, work) norm := lapack64.Lange(CondNorm, m.mat, work)
rcond := lapack64.Gecon(matrix.CondNorm, m.mat, norm, work, ipiv) // reuse ipiv rcond := lapack64.Gecon(CondNorm, m.mat, norm, work, ipiv) // reuse ipiv
if rcond == 0 { if rcond == 0 {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
cond := 1 / rcond cond := 1 / rcond
if cond > matrix.ConditionTolerance { if cond > ConditionTolerance {
return matrix.Condition(cond) return Condition(cond)
} }
return nil return nil
} }
@@ -266,7 +265,7 @@ func (m *Dense) Mul(a, b Matrix) {
br, bc := b.Dims() br, bc := b.Dims()
if ac != br { if ac != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, aTrans := untranspose(a) aU, aTrans := untranspose(a)
@@ -452,7 +451,7 @@ func strictCopy(m *Dense, a Matrix) {
if r != m.mat.Rows || c != m.mat.Cols { if r != m.mat.Rows || c != m.mat.Cols {
// Panic with a string since this // Panic with a string since this
// is not a user-facing panic. // 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) { func (m *Dense) Exp(a Matrix) {
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
var w *Dense var w *Dense
@@ -530,7 +529,7 @@ func (m *Dense) Pow(a Matrix, n int) {
} }
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(r, c) 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) { func (m *Dense) RankOne(a Matrix, alpha float64, x, y *Vector) {
ar, ac := a.Dims() ar, ac := a.Dims()
if x.Len() != ar { if x.Len() != ar {
panic(matrix.ErrShape) panic(ErrShape)
} }
if y.Len() != ac { if y.Len() != ac {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.checkOverlap(x.asGeneral()) m.checkOverlap(x.asGeneral())
@@ -707,7 +706,7 @@ func (m *Dense) Outer(alpha float64, x, y *Vector) {
m.capRows = r m.capRows = r
m.capCols = c m.capCols = c
} else if r != m.mat.Rows || c != m.mat.Cols { } else if r != m.mat.Rows || c != m.mat.Cols {
panic(matrix.ErrShape) panic(ErrShape)
} else { } else {
m.checkOverlap(x.asGeneral()) m.checkOverlap(x.asGeneral())
m.checkOverlap(y.asGeneral()) m.checkOverlap(y.asGeneral())

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"
@@ -13,7 +13,6 @@ import (
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
func asBasicMatrix(d *Dense) Matrix { return (*basicMatrix)(d) } func asBasicMatrix(d *Dense) Matrix { return (*basicMatrix)(d) }
@@ -188,13 +187,13 @@ func TestAtSet(t *testing.T) {
// Check access out of bounds fails // Check access out of bounds fails
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { m.At(row, 0) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { m.At(0, col) }) 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) 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 // Check Set out of bounds
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { m.Set(row, 0, 1.2) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { m.Set(0, col, 1.2) }) 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) 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} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { m.At(row, 0) }) 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) t.Errorf("expected panic for invalid row access rows=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { m.At(0, col) }) 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) 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) { func randDense(size int, rho float64, rnd func() float64) (*Dense, error) {
if size == 0 { if size == 0 {
return nil, matrix.ErrZeroLength return nil, ErrZeroLength
} }
d := &Dense{ d := &Dense{
mat: blas64.General{ mat: blas64.General{

View File

@@ -3,12 +3,11 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the EigenvalueDecomposition class from Jama 1.0.3. // Based on the EigenvalueDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
const ( const (
@@ -82,7 +81,7 @@ func (e *EigenSym) Values(dst []float64) []float64 {
dst = make([]float64, len(e.values)) dst = make([]float64, len(e.values))
} }
if len(dst) != len(e.values) { if len(dst) != len(e.values) {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
copy(dst, e.values) copy(dst, e.values)
return dst 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. // Copy a because it is modified during the Lapack call.
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
var sd Dense var sd Dense
sd.Clone(a) sd.Clone(a)
@@ -209,7 +208,7 @@ func (e *Eigen) Values(dst []complex128) []complex128 {
dst = make([]complex128, e.n) dst = make([]complex128, e.n)
} }
if len(dst) != e.n { if len(dst) != e.n {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
copy(dst, e.values) copy(dst, e.values)
return dst return dst

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package matrix package mat
import ( import (
"fmt" "fmt"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package matrix package mat
import "testing" import "testing"

View File

@@ -2,20 +2,20 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 // FAO is a dataset extracted from Food and Agriculture Organization of the
// United Nations "FAO Statistical Pocketbook: World Food and Agriculture 2015". // United Nations "FAO Statistical Pocketbook: World Food and Agriculture 2015".
// pp49-52. // pp49-52.
var FAO = struct { var FAO = struct {
Africa *mat64.Dense Africa *mat.Dense
Asia *mat64.Dense Asia *mat.Dense
LatinAmericaCaribbean *mat64.Dense LatinAmericaCaribbean *mat.Dense
Oceania *mat64.Dense Oceania *mat.Dense
}{ }{
Africa: mat64.NewDense(21, 3, []float64{ Africa: mat.NewDense(21, 3, []float64{
// 1990, 2000, 2014 // 1990, 2000, 2014
35.3, 38, 30.7, // Employment in agriculture (%) 35.3, 38, 30.7, // Employment in agriculture (%)
9.2, 20.3, 25.2, // Employment in agriculture, female (%) 9.2, 20.3, 25.2, // Employment in agriculture, female (%)
@@ -43,7 +43,7 @@ var FAO = struct {
72, 92, 119, // Fish 72, 92, 119, // Fish
}), }),
Asia: mat64.NewDense(21, 3, []float64{ Asia: mat.NewDense(21, 3, []float64{
// 1990, 2000, 2014 // 1990, 2000, 2014
30.9, 24.5, 27.6, // Employment in agriculture (%) 30.9, 24.5, 27.6, // Employment in agriculture (%)
40.9, 29.4, 31.1, // Employment in agriculture, female (%) 40.9, 29.4, 31.1, // Employment in agriculture, female (%)
@@ -71,7 +71,7 @@ var FAO = struct {
65, 90, 119, // Fish 65, 90, 119, // Fish
}), }),
LatinAmericaCaribbean: mat64.NewDense(14, 3, []float64{ LatinAmericaCaribbean: mat.NewDense(14, 3, []float64{
// 1990, 2000, 2014 // 1990, 2000, 2014
19.5, 14.2, 15.8, // Employment in agriculture (%) 19.5, 14.2, 15.8, // Employment in agriculture (%)
13.7, 6.2, 7.6, // Employment in agriculture, female (%) 13.7, 6.2, 7.6, // Employment in agriculture, female (%)
@@ -92,7 +92,7 @@ var FAO = struct {
82, 107, 71, // Fish 82, 107, 71, // Fish
}), }),
Oceania: mat64.NewDense(21, 3, []float64{ Oceania: mat.NewDense(21, 3, []float64{
// 1990, 2000, 2014 // 1990, 2000, 2014
6.2, 17.1, 3.8, // Employment in agriculture (%) 6.2, 17.1, 3.8, // Employment in agriculture (%)
4.5, 3.9, 4.4, // Employment in agriculture, female (%) 4.5, 3.9, 4.4, // Employment in agriculture, female (%)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"

View File

@@ -2,20 +2,20 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64_test package mat_test
import ( import (
"fmt" "fmt"
"gonum.org/v1/gonum/matrix/mat64" "gonum.org/v1/gonum/mat"
) )
func ExampleFormatted() { 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 // Create a matrix formatting value with a prefix and calculating each column
// width individually... // 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. // and then print with and without zero value elements.
fmt.Printf("with all values:\na = %v\n\n", fa) fmt.Printf("with all values:\na = %v\n\n", fa)
@@ -61,27 +61,27 @@ func ExampleExcerpt() {
// matrices and vectors. // matrices and vectors.
// The big matrix is too large to properly print... // 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++ { for i := 0; i < 100; i++ {
big.Set(i, i, 1) big.Set(i, i, 1)
} }
// so only print corner excerpts of the matrix. // so only print corner excerpts of the matrix.
fmt.Printf("excerpt big identity matrix: %v\n\n", 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, ... // The long vector is also too large, ...
long := mat64.NewVector(100, nil) long := mat.NewVector(100, nil)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
long.SetVec(i, float64(i)) long.SetVec(i, float64(i))
} }
// ... so print end excerpts of the vector, // ... so print end excerpts of the vector,
fmt.Printf("excerpt long column vector: %v\n\n", 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. // or its transpose.
fmt.Printf("excerpt long row vector: %v\n", 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: // Output:
// excerpt big identity matrix: Dims(100, 100) // excerpt big identity matrix: Dims(100, 100)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"
@@ -26,8 +26,8 @@ func TestFormat(t *testing.T) {
[]rp{ []rp{
{"%v", "⎡0 0 0⎤\n⎢0 0 0⎥\n⎣0 0 0⎦"}, {"%v", "⎡0 0 0⎤\n⎢0 0 0⎥\n⎣0 0 0⎦"},
{"% f", "⎡. . .⎤\n⎢. . .⎥\n⎣. . .⎦"}, {"% 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}"}, {"%#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(*mat64.Dense=Dims(3, 3))"}, {"%s", "%!s(*mat.Dense=Dims(3, 3))"},
}, },
}, },
{ {
@@ -35,7 +35,7 @@ func TestFormat(t *testing.T) {
[]rp{ []rp{
{"%v", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"}, {"%v", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"},
{"% f", "⎡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{ []rp{
{"%v", "⎡1 1 1⎤\n\t⎢1 1 1⎥\n\t⎣1 1 1⎦"}, {"%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⎦"}, {"% 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{ []rp{
{"%v", "⎡1 0 0⎤\n⎢0 1 0⎥\n⎣0 0 1⎦"}, {"%v", "⎡1 0 0⎤\n⎢0 1 0⎥\n⎣0 0 1⎦"},
{"% f", "⎡1 . .⎤\n⎢. 1 .⎥\n⎣. . 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{ []rp{
{"%v", "⎡1 2 3⎤\n⎣4 5 6⎦"}, {"%v", "⎡1 2 3⎤\n⎣4 5 6⎦"},
{"% f", "⎡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{ []rp{
{"%v", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"}, {"%v", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"},
{"% f", "⎡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⎦"}, {"%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⎦"}, {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"},
{"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, {"% 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⎦"}, {"%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⎦"}, {"%.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⎦"}, {"% 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⎦"}, {"%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⎦"}, {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"},
{"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, {"% 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}"},
}, },
}, },
{ {

View File

@@ -3,14 +3,13 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the SingularValueDecomposition class from Jama 1.0.3. // Based on the SingularValueDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
// GSVD is a type for creating and using the Generalized Singular Value Decomposition // 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" // variable×sample spaces to reduced and diagonalized "eigenvariable"×"eigensample"
// spaces. // spaces.
type GSVD struct { type GSVD struct {
kind matrix.GSVDKind kind GSVDKind
r, p, c, k, l int r, p, c, k, l int
s1, s2 []float64 s1, s2 []float64
@@ -50,24 +49,24 @@ type GSVD struct {
// //
// Factorize returns whether the decomposition succeeded. If the decomposition // Factorize returns whether the decomposition succeeded. If the decomposition
// failed, routines that require a successful factorization will panic. // 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() r, c := a.Dims()
gsvd.r, gsvd.c = r, c gsvd.r, gsvd.c = r, c
p, c := b.Dims() p, c := b.Dims()
gsvd.p = p gsvd.p = p
if gsvd.c != c { if gsvd.c != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
var jobU, jobV, jobQ lapack.GSVDJob var jobU, jobV, jobQ lapack.GSVDJob
switch { switch {
default: default:
panic("gsvd: bad input kind") panic("gsvd: bad input kind")
case kind == matrix.GSVDNone: case kind == GSVDNone:
jobU = lapack.GSVDNone jobU = lapack.GSVDNone
jobV = lapack.GSVDNone jobV = lapack.GSVDNone
jobQ = lapack.GSVDNone jobQ = lapack.GSVDNone
case (matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ)&kind != 0: case (GSVDU|GSVDV|GSVDQ)&kind != 0:
if matrix.GSVDU&kind != 0 { if GSVDU&kind != 0 {
jobU = lapack.GSVDU jobU = lapack.GSVDU
gsvd.u = blas64.General{ gsvd.u = blas64.General{
Rows: r, 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), Data: use(gsvd.u.Data, r*r),
} }
} }
if matrix.GSVDV&kind != 0 { if GSVDV&kind != 0 {
jobV = lapack.GSVDV jobV = lapack.GSVDV
gsvd.v = blas64.General{ gsvd.v = blas64.General{
Rows: p, 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), Data: use(gsvd.v.Data, p*p),
} }
} }
if matrix.GSVDQ&kind != 0 { if GSVDQ&kind != 0 {
jobQ = lapack.GSVDQ jobQ = lapack.GSVDQ
gsvd.q = blas64.General{ gsvd.q = blas64.General{
Rows: c, 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 // Kind returns the matrix.GSVDKind of the decomposition. If no decomposition has been
// computed, Kind returns 0. // computed, Kind returns 0.
func (gsvd *GSVD) Kind() matrix.GSVDKind { func (gsvd *GSVD) Kind() GSVDKind {
return gsvd.kind return gsvd.kind
} }
@@ -147,7 +146,7 @@ func (gsvd *GSVD) GeneralizedValues(v []float64) []float64 {
v = make([]float64, d-k) v = make([]float64, d-k)
} }
if len(v) != d-k { if len(v) != d-k {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
floats.DivTo(v, gsvd.s1[k:d], gsvd.s2[k:d]) floats.DivTo(v, gsvd.s1[k:d], gsvd.s2[k:d])
return v return v
@@ -172,7 +171,7 @@ func (gsvd *GSVD) ValuesA(s []float64) []float64 {
s = make([]float64, d-k) s = make([]float64, d-k)
} }
if len(s) != d-k { if len(s) != d-k {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
copy(s, gsvd.s1[k:min(r, c)]) copy(s, gsvd.s1[k:min(r, c)])
return s return s
@@ -197,7 +196,7 @@ func (gsvd *GSVD) ValuesB(s []float64) []float64 {
s = make([]float64, d-k) s = make([]float64, d-k)
} }
if len(s) != d-k { if len(s) != d-k {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
copy(s, gsvd.s2[k:d]) copy(s, gsvd.s2[k:d])
return s 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. // UTo will panic if the receiver does not contain a successful factorization.
func (gsvd *GSVD) UTo(dst *Dense) *Dense { func (gsvd *GSVD) UTo(dst *Dense) *Dense {
if gsvd.kind&matrix.GSVDU == 0 { if gsvd.kind&GSVDU == 0 {
panic("mat64: improper GSVD kind") panic("mat64: improper GSVD kind")
} }
r := gsvd.u.Rows 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. // VTo will panic if the receiver does not contain a successful factorization.
func (gsvd *GSVD) VTo(dst *Dense) *Dense { func (gsvd *GSVD) VTo(dst *Dense) *Dense {
if gsvd.kind&matrix.GSVDV == 0 { if gsvd.kind&GSVDV == 0 {
panic("mat64: improper GSVD kind") panic("mat64: improper GSVD kind")
} }
r := gsvd.v.Rows 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. // QTo will panic if the receiver does not contain a successful factorization.
func (gsvd *GSVD) QTo(dst *Dense) *Dense { func (gsvd *GSVD) QTo(dst *Dense) *Dense {
if gsvd.kind&matrix.GSVDQ == 0 { if gsvd.kind&GSVDQ == 0 {
panic("mat64: improper GSVD kind") panic("mat64: improper GSVD kind")
} }
r := gsvd.q.Rows r := gsvd.q.Rows

View File

@@ -2,15 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64_test package mat_test
import ( import (
"fmt" "fmt"
"log" "log"
"math" "math"
"gonum.org/v1/gonum/matrix" "gonum.org/v1/gonum/mat"
"gonum.org/v1/gonum/matrix/mat64"
) )
func ExampleGSVD() { func ExampleGSVD() {
@@ -19,8 +18,8 @@ func ExampleGSVD() {
// //
// See Lee et al. doi:10.1371/journal.pone.0030098 and // See Lee et al. doi:10.1371/journal.pone.0030098 and
// Alter at al. doi:10.1073/pnas.0530258100 for more details. // Alter at al. doi:10.1073/pnas.0530258100 for more details.
var gsvd mat64.GSVD var gsvd mat.GSVD
ok := gsvd.Factorize(FAO.Africa, FAO.LatinAmericaCaribbean, matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ) ok := gsvd.Factorize(FAO.Africa, FAO.LatinAmericaCaribbean, mat.GSVDU|mat.GSVDV|mat.GSVDQ)
if !ok { if !ok {
log.Fatal("GSVD factorization failed") log.Fatal("GSVD factorization failed")
} }
@@ -32,14 +31,14 @@ func ExampleGSVD() {
s2 := gsvd.ValuesB(nil) s2 := gsvd.ValuesB(nil)
fmt.Printf("Africa\n\ts1 = %.4f\n\n\tU = %.4f\n\n", 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", 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)) q.Mul(gsvd.ZeroRTo(nil), gsvd.QTo(nil))
fmt.Printf("\nCommon basis vectors\n\n\tQ^T = %.4f\n", 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. // Calculate the antisymmetric angular distances for each eigenvariable.
fmt.Println("\nSignificance:") fmt.Println("\nSignificance:")

View File

@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"
"testing" "testing"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
func TestGSVD(t *testing.T) { func TestGSVD(t *testing.T) {
@@ -49,7 +48,7 @@ func TestGSVD(t *testing.T) {
// Test Full decomposition. // Test Full decomposition.
var gsvd GSVD var gsvd GSVD
ok := gsvd.Factorize(a, b, matrix.GSVDU|matrix.GSVDV|matrix.GSVDQ) ok := gsvd.Factorize(a, b, GSVDU|GSVDV|GSVDQ)
if !ok { if !ok {
t.Errorf("GSVD factorization failed") t.Errorf("GSVD factorization failed")
} }
@@ -83,7 +82,7 @@ func TestGSVD(t *testing.T) {
} }
// Test None decomposition. // Test None decomposition.
ok = gsvd.Factorize(a, b, matrix.GSVDNone) ok = gsvd.Factorize(a, b, GSVDNone)
if !ok { if !ok {
t.Errorf("GSVD factorization failed") t.Errorf("GSVD factorization failed")
} }

View File

@@ -3,13 +3,12 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the SingularValueDecomposition class from Jama 1.0.3. // Based on the SingularValueDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"errors" "errors"
"gonum.org/v1/gonum/blas/blas64" "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 // 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 { for i, d := range m {
rd, cd := d.Dims() rd, cd := d.Dims()
if rd < cd { if rd < cd {
gsvd.err = matrix.ErrShape gsvd.err = ErrShape
return false return false
} }
if rd > r { if rd > r {
r = rd r = rd
} }
if cd != c { if cd != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
ts.Reset() ts.Reset()
ts.SymOuterK(1, d.T()) ts.SymOuterK(1, d.T())
@@ -187,7 +186,7 @@ func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
if s == nil { if s == nil {
s = make([]float64, c) s = make([]float64, c)
} else if len(s) != c { } else if len(s) != c {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
for j := 0; j < c; j++ { for j := 0; j < c; j++ {
s[j] = blas64.Nrm2(r, gsvd.b[n].ColView(j).mat) s[j] = blas64.Nrm2(r, gsvd.b[n].ColView(j).mat)

View File

@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64_test package mat_test
import ( import (
"fmt" "fmt"
"log" "log"
"gonum.org/v1/gonum/matrix/mat64" "gonum.org/v1/gonum/mat"
) )
func ExampleHOGSVD() { func ExampleHOGSVD() {
@@ -17,7 +17,7 @@ func ExampleHOGSVD() {
// //
// See Ponnapalli et al. doi:10.1371/journal.pone.0028072 and // See Ponnapalli et al. doi:10.1371/journal.pone.0028072 and
// Alter at al. doi:10.1073/pnas.0530258100 for more details. // 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) ok := gsvd.Factorize(FAO.Africa, FAO.Asia, FAO.LatinAmericaCaribbean, FAO.Oceania)
if !ok { if !ok {
log.Fatal("HOGSVD factorization failed: %v", gsvd.Err()) log.Fatal("HOGSVD factorization failed: %v", gsvd.Err())
@@ -27,12 +27,12 @@ func ExampleHOGSVD() {
u := gsvd.UTo(nil, i) u := gsvd.UTo(nil, i)
s := gsvd.Values(nil, i) s := gsvd.Values(nil, i)
fmt.Printf("%s\n\ts_%d = %.4f\n\n\tU_%[2]d = %.4[4]f\n", 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) v := gsvd.VTo(nil)
fmt.Printf("\nCommon basis vectors\n\n\tV^T = %.4f", 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: // Output:
// //

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"

View File

@@ -6,9 +6,7 @@
//+build bounds //+build bounds
package mat64 package mat
import "gonum.org/v1/gonum/matrix"
// At returns the element at row i, column j. // At returns the element at row i, column j.
func (m *Dense) At(i, j int) float64 { 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 { func (m *Dense) at(i, j int) float64 {
if uint(i) >= uint(m.mat.Rows) { if uint(i) >= uint(m.mat.Rows) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(m.mat.Cols) { if uint(j) >= uint(m.mat.Cols) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return m.mat.Data[i*m.mat.Stride+j] 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) { func (m *Dense) set(i, j int, v float64) {
if uint(i) >= uint(m.mat.Rows) { if uint(i) >= uint(m.mat.Rows) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(m.mat.Cols) { if uint(j) >= uint(m.mat.Cols) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
m.mat.Data[i*m.mat.Stride+j] = v 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. // It panics if i is out of bounds or if j is not zero.
func (v *Vector) At(i, j int) float64 { func (v *Vector) At(i, j int) float64 {
if j != 0 { if j != 0 {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return v.at(i) return v.at(i)
} }
func (v *Vector) at(i int) float64 { func (v *Vector) at(i int) float64 {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.n) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
return v.mat.Data[i*v.mat.Inc] 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) { func (v *Vector) setVec(i int, val float64) {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.n) {
panic(matrix.ErrVectorAccess) panic(ErrVectorAccess)
} }
v.mat.Data[i*v.mat.Inc] = val 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 { func (t *SymDense) at(i, j int) float64 {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
if i > j { if i > j {
i, j = j, i 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) { func (t *SymDense) set(i, j int, v float64) {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
if i > j { if i > j {
i, j = j, i i, j = j, i
@@ -112,10 +110,10 @@ func (t *TriDense) At(i, j int) float64 {
func (t *TriDense) at(i, j int) float64 { func (t *TriDense) at(i, j int) float64 {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
isUpper := t.isUpper() isUpper := t.isUpper()
if (isUpper && i > j) || (!isUpper && i < j) { 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) { func (t *TriDense) set(i, j int, v float64) {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
isUpper := t.isUpper() isUpper := t.isUpper()
if (isUpper && i > j) || (!isUpper && i < j) { if (isUpper && i > j) || (!isUpper && i < j) {
panic(matrix.ErrTriangleSet) panic(ErrTriangleSet)
} }
t.mat.Data[i*t.mat.Stride+j] = v t.mat.Data[i*t.mat.Stride+j] = v
} }

View File

@@ -6,17 +6,15 @@
//+build !bounds //+build !bounds
package mat64 package mat
import "gonum.org/v1/gonum/matrix"
// At returns the element at row i, column j. // At returns the element at row i, column j.
func (m *Dense) At(i, j int) float64 { func (m *Dense) At(i, j int) float64 {
if uint(i) >= uint(m.mat.Rows) { if uint(i) >= uint(m.mat.Rows) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(m.mat.Cols) { if uint(j) >= uint(m.mat.Cols) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return m.at(i, j) 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. // Set sets the element at row i, column j to the value v.
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) { if uint(i) >= uint(m.mat.Rows) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(m.mat.Cols) { if uint(j) >= uint(m.mat.Cols) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
m.set(i, j, v) 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. // It panics if i is out of bounds or if j is not zero.
func (v *Vector) At(i, j int) float64 { func (v *Vector) At(i, j int) float64 {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.n) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if j != 0 { if j != 0 {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return v.at(i) return v.at(i)
} }
@@ -60,7 +58,7 @@ func (v *Vector) at(i int) float64 {
// It panics if i is out of bounds. // It panics if i is out of bounds.
func (v *Vector) SetVec(i int, val float64) { func (v *Vector) SetVec(i int, val float64) {
if uint(i) >= uint(v.n) { if uint(i) >= uint(v.n) {
panic(matrix.ErrVectorAccess) panic(ErrVectorAccess)
} }
v.setVec(i, val) 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. // At returns the element at row i and column j.
func (s *SymDense) At(i, j int) float64 { func (s *SymDense) At(i, j int) float64 {
if uint(i) >= uint(s.mat.N) { if uint(i) >= uint(s.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(s.mat.N) { if uint(j) >= uint(s.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return s.at(i, j) 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. // SetSym sets the elements at (i,j) and (j,i) to the value v.
func (s *SymDense) SetSym(i, j int, v float64) { func (s *SymDense) SetSym(i, j int, v float64) {
if uint(i) >= uint(s.mat.N) { if uint(i) >= uint(s.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(s.mat.N) { if uint(j) >= uint(s.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
s.set(i, j, v) 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. // At returns the element at row i, column j.
func (t *TriDense) At(i, j int) float64 { func (t *TriDense) At(i, j int) float64 {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
return t.at(i, j) 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. // It panics if the location is outside the appropriate half of the matrix.
func (t *TriDense) SetTri(i, j int, v float64) { func (t *TriDense) SetTri(i, j int, v float64) {
if uint(i) >= uint(t.mat.N) { if uint(i) >= uint(t.mat.N) {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
if uint(j) >= uint(t.mat.N) { if uint(j) >= uint(t.mat.N) {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
isUpper := t.isUpper() isUpper := t.isUpper()
if (isUpper && i > j) || (!isUpper && i < j) { if (isUpper && i > j) || (!isUpper && i < j) {
panic(matrix.ErrTriangleSet) panic(ErrTriangleSet)
} }
t.set(i, j, v) t.set(i, j, v)
} }

View File

@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/internal/asm/f64" "gonum.org/v1/gonum/internal/asm/f64"
"gonum.org/v1/gonum/matrix"
) )
// Inner computes the generalized inner product // Inner computes the generalized inner product
@@ -19,10 +18,10 @@ import (
func Inner(x *Vector, A Matrix, y *Vector) float64 { func Inner(x *Vector, A Matrix, y *Vector) float64 {
m, n := A.Dims() m, n := A.Dims()
if x.Len() != m { if x.Len() != m {
panic(matrix.ErrShape) panic(ErrShape)
} }
if y.Len() != n { if y.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if m == 0 || n == 0 { if m == 0 || n == 0 {
return 0 return 0

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"encoding/binary" "encoding/binary"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"bytes" "bytes"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"
@@ -14,7 +14,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
// legalSizeSameRectangular returns whether the two matrices have the same rectangular shape. // 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 // This is necessary because we are making
// a triangle from the zero value, which // a triangle from the zero value, which
// always returns upper as true. // always returns upper as true.
var triKind matrix.TriKind var triKind TriKind
switch t := t.(type) { switch t := t.(type) {
case *TriDense: case *TriDense:
triKind = t.triKind() triKind = t.triKind()
@@ -310,7 +309,7 @@ func makeRandOf(a Matrix, m, n int) Matrix {
} }
mat := NewTriDense(n, triKind, nil) mat := NewTriDense(n, triKind, nil)
if triKind == matrix.Upper { if triKind == Upper {
for i := 0; i < m; i++ { for i := 0; i < m; i++ {
for j := i; j < n; j++ { for j := i; j < n; j++ {
mat.SetTri(i, j, rand.NormFloat64()) mat.SetTri(i, j, rand.NormFloat64())

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
@@ -10,7 +10,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "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. // 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) work := getFloats(3*m, false)
iwork := getInts(m, false) iwork := getInts(m, false)
l := lq.lq.asTriDense(m, blas.NonUnit, blas.Lower) 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 lq.cond = 1 / v
putFloats(work) putFloats(work)
putInts(iwork) putInts(iwork)
@@ -42,7 +41,7 @@ func (lq *LQ) updateCond() {
func (lq *LQ) Factorize(a Matrix) { func (lq *LQ) Factorize(a Matrix) {
m, n := a.Dims() m, n := a.Dims()
if m > n { if m > n {
panic(matrix.ErrShape) panic(ErrShape)
} }
k := min(m, n) k := min(m, n)
if lq.lq == nil { 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. // copy the result into m at the end.
if trans { if trans {
if c != br { if c != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(r, bc) m.reuseAs(r, bc)
} else { } else {
if r != br { if r != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(c, bc) 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) ok := lapack64.Trtrs(blas.Trans, t, x.mat)
if !ok { if !ok {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
} else { } else {
ok := lapack64.Trtrs(blas.NoTrans, t, x.mat) ok := lapack64.Trtrs(blas.NoTrans, t, x.mat)
if !ok { if !ok {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
for i := r; i < c; i++ { for i := r; i < c; i++ {
zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) 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 was set above to be the correct size for the result.
m.Copy(x) m.Copy(x)
putWorkspace(x) putWorkspace(x)
if lq.cond > matrix.ConditionTolerance { if lq.cond > ConditionTolerance {
return matrix.Condition(lq.cond) return Condition(lq.cond)
} }
return nil return nil
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
@@ -11,7 +11,6 @@ import (
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
const badSliceLength = "mat64: improper slice length" const badSliceLength = "mat64: improper slice length"
@@ -39,11 +38,11 @@ func (lu *LU) updateCond(norm float64) {
// update possibilities, e.g. RankOne. // update possibilities, e.g. RankOne.
u := lu.lu.asTriDense(n, blas.NonUnit, blas.Upper) u := lu.lu.asTriDense(n, blas.NonUnit, blas.Upper)
l := lu.lu.asTriDense(n, blas.Unit, blas.Lower) l := lu.lu.asTriDense(n, blas.Unit, blas.Lower)
unorm := lapack64.Lantr(matrix.CondNorm, u.mat, work) unorm := lapack64.Lantr(CondNorm, u.mat, work)
lnorm := lapack64.Lantr(matrix.CondNorm, l.mat, work) lnorm := lapack64.Lantr(CondNorm, l.mat, work)
norm = unorm * lnorm 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 lu.cond = 1 / v
} }
@@ -57,7 +56,7 @@ func (lu *LU) updateCond(norm float64) {
func (lu *LU) Factorize(a Matrix) { func (lu *LU) Factorize(a Matrix) {
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrSquare) panic(ErrSquare)
} }
if lu.lu == nil { if lu.lu == nil {
lu.lu = NewDense(r, r, nil) lu.lu = NewDense(r, r, nil)
@@ -71,7 +70,7 @@ func (lu *LU) Factorize(a Matrix) {
} }
lu.pivot = lu.pivot[:r] lu.pivot = lu.pivot[:r]
work := getFloats(r, false) work := getFloats(r, false)
anorm := lapack64.Lange(matrix.CondNorm, lu.lu.mat, work) anorm := lapack64.Lange(CondNorm, lu.lu.mat, work)
putFloats(work) putFloats(work)
lapack64.Getrf(lu.lu.mat, lu.pivot) lapack64.Getrf(lu.lu.mat, lu.pivot)
lu.updateCond(anorm) 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 // http://web.stanford.edu/group/SOL/dissertations/Linzhong-Deng-thesis.pdf
_, n := orig.lu.Dims() _, n := orig.lu.Dims()
if x.Len() != n { if x.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if y.Len() != n { if y.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if orig != lu { if orig != lu {
if lu.isZero() { if lu.isZero() {
@@ -169,7 +168,7 @@ func (lu *LU) RankOne(orig *LU, alpha float64, x, y *Vector) {
lu.lu.reuseAs(n, n) lu.lu.reuseAs(n, n)
} }
} else if len(lu.pivot) != n { } else if len(lu.pivot) != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
copy(lu.pivot, orig.pivot) copy(lu.pivot, orig.pivot)
lu.lu.Copy(orig.lu) 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 { func (lu *LU) LTo(dst *TriDense) *TriDense {
_, n := lu.lu.Dims() _, n := lu.lu.Dims()
if dst == nil { if dst == nil {
dst = NewTriDense(n, matrix.Lower, nil) dst = NewTriDense(n, Lower, nil)
} else { } else {
dst.reuseAs(n, matrix.Lower) dst.reuseAs(n, Lower)
} }
// Extract the lower triangular elements. // Extract the lower triangular elements.
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@@ -237,9 +236,9 @@ func (lu *LU) LTo(dst *TriDense) *TriDense {
func (lu *LU) UTo(dst *TriDense) *TriDense { func (lu *LU) UTo(dst *TriDense) *TriDense {
_, n := lu.lu.Dims() _, n := lu.lu.Dims()
if dst == nil { if dst == nil {
dst = NewTriDense(n, matrix.Upper, nil) dst = NewTriDense(n, Upper, nil)
} else { } else {
dst.reuseAs(n, matrix.Upper) dst.reuseAs(n, Upper)
} }
// Extract the upper triangular elements. // Extract the upper triangular elements.
for i := 0; i < n; i++ { 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]) zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+r])
v := swaps[i] v := swaps[i]
if v < 0 || v >= r { if v < 0 || v >= r {
panic(matrix.ErrRowAccess) panic(ErrRowAccess)
} }
m.mat.Data[i*m.mat.Stride+v] = 1 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() _, n := lu.lu.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if br != n { if br != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
// TODO(btracey): Should test the condition number instead of testing that // TODO(btracey): Should test the condition number instead of testing that
// the determinant is exactly zero. // the determinant is exactly zero.
if lu.Det() == 0 { if lu.Det() == 0 {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
m.reuseAs(n, bc) m.reuseAs(n, bc)
@@ -303,8 +302,8 @@ func (m *Dense) SolveLU(lu *LU, trans bool, b Matrix) error {
t = blas.Trans t = blas.Trans
} }
lapack64.Getrs(t, lu.lu.mat, m.mat, lu.pivot) lapack64.Getrs(t, lu.lu.mat, m.mat, lu.pivot)
if lu.cond > matrix.ConditionTolerance { if lu.cond > ConditionTolerance {
return matrix.Condition(lu.cond) return Condition(lu.cond)
} }
return nil return nil
} }
@@ -322,7 +321,7 @@ func (v *Vector) SolveLUVec(lu *LU, trans bool, b *Vector) error {
_, n := lu.lu.Dims() _, n := lu.lu.Dims()
bn := b.Len() bn := b.Len()
if bn != n { if bn != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != b { if v != b {
v.checkOverlap(b.mat) 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 // TODO(btracey): Should test the condition number instead of testing that
// the determinant is exactly zero. // the determinant is exactly zero.
if lu.Det() == 0 { if lu.Det() == 0 {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
v.reuseAs(n) v.reuseAs(n)
@@ -351,8 +350,8 @@ func (v *Vector) SolveLUVec(lu *LU, trans bool, b *Vector) error {
t = blas.Trans t = blas.Trans
} }
lapack64.Getrs(t, lu.lu.mat, vMat, lu.pivot) lapack64.Getrs(t, lu.lu.mat, vMat, lu.pivot)
if lu.cond > matrix.ConditionTolerance { if lu.cond > ConditionTolerance {
return matrix.Condition(lu.cond) return Condition(lu.cond)
} }
return nil return nil
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
@@ -12,7 +12,6 @@ import (
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
// Matrix is the basic matrix interface type. // Matrix is the basic matrix interface type.
@@ -196,13 +195,13 @@ type RawVectorer interface {
func Col(dst []float64, j int, a Matrix) []float64 { func Col(dst []float64, j int, a Matrix) []float64 {
r, c := a.Dims() r, c := a.Dims()
if j < 0 || j >= c { if j < 0 || j >= c {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
if dst == nil { if dst == nil {
dst = make([]float64, r) dst = make([]float64, r)
} else { } else {
if len(dst) != r { if len(dst) != r {
panic(matrix.ErrColLength) panic(ErrColLength)
} }
} }
aU, aTrans := untranspose(a) 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 { func Row(dst []float64, i int, a Matrix) []float64 {
r, c := a.Dims() r, c := a.Dims()
if i < 0 || i >= r { if i < 0 || i >= r {
panic(matrix.ErrColAccess) panic(ErrColAccess)
} }
if dst == nil { if dst == nil {
dst = make([]float64, c) dst = make([]float64, c)
} else { } else {
if len(dst) != c { if len(dst) != c {
panic(matrix.ErrRowLength) panic(ErrRowLength)
} }
} }
aU, aTrans := untranspose(a) aU, aTrans := untranspose(a)
@@ -270,7 +269,7 @@ func Row(dst []float64, i int, a Matrix) []float64 {
func Cond(a Matrix, norm float64) float64 { func Cond(a Matrix, norm float64) float64 {
m, n := a.Dims() m, n := a.Dims()
if m == 0 || n == 0 { if m == 0 || n == 0 {
panic(matrix.ErrShape) panic(ErrShape)
} }
var lnorm lapack.MatrixNorm var lnorm lapack.MatrixNorm
switch norm { switch norm {
@@ -280,7 +279,7 @@ func Cond(a Matrix, norm float64) float64 {
lnorm = lapack.MaxColumnSum lnorm = lapack.MaxColumnSum
case 2: case 2:
var svd SVD var svd SVD
ok := svd.Factorize(a, matrix.SVDNone) ok := svd.Factorize(a, SVDNone)
if !ok { if !ok {
return math.Inf(1) return math.Inf(1)
} }
@@ -360,7 +359,7 @@ func Dot(a, b *Vector) float64 {
la := a.Len() la := a.Len()
lb := b.Len() lb := b.Len()
if la != lb { if la != lb {
panic(matrix.ErrShape) panic(ErrShape)
} }
return blas64.Dot(la, a.mat, b.mat) 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 { func Max(a Matrix) float64 {
r, c := a.Dims() r, c := a.Dims()
if r == 0 || c == 0 { if r == 0 || c == 0 {
panic(matrix.ErrShape) panic(ErrShape)
} }
// Max(A) = Max(A^T) // Max(A) = Max(A^T)
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -598,7 +597,7 @@ func Max(a Matrix) float64 {
func Min(a Matrix) float64 { func Min(a Matrix) float64 {
r, c := a.Dims() r, c := a.Dims()
if r == 0 || c == 0 { if r == 0 || c == 0 {
panic(matrix.ErrShape) panic(ErrShape)
} }
// Min(A) = Min(A^T) // Min(A) = Min(A^T)
aU, _ := untranspose(a) aU, _ := untranspose(a)
@@ -680,7 +679,7 @@ func Min(a Matrix) float64 {
func Norm(a Matrix, norm float64) float64 { func Norm(a Matrix, norm float64) float64 {
r, c := a.Dims() r, c := a.Dims()
if r == 0 || c == 0 { if r == 0 || c == 0 {
panic(matrix.ErrShape) panic(ErrShape)
} }
aU, aTrans := untranspose(a) aU, aTrans := untranspose(a)
var work []float64 var work []float64
@@ -787,7 +786,7 @@ func normLapack(norm float64, aTrans bool) lapack.MatrixNorm {
} }
return n return n
default: default:
panic(matrix.ErrNormOrder) panic(ErrNormOrder)
} }
} }
@@ -820,7 +819,7 @@ func Sum(a Matrix) float64 {
func Trace(a Matrix) float64 { func Trace(a Matrix) float64 {
r, c := a.Dims() r, c := a.Dims()
if r != c { if r != c {
panic(matrix.ErrSquare) panic(ErrSquare)
} }
aU, _ := untranspose(a) aU, _ := untranspose(a)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"
@@ -13,7 +13,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
func panics(fn func()) (panicked bool, message string) { func panics(fn func()) (panicked bool, message string) {
@@ -335,7 +334,7 @@ func TestDet(t *testing.T) {
f = func(a Matrix) interface{} { f = func(a Matrix) interface{} {
ar, ac := a.Dims() ar, ac := a.Dims()
if !isWide(ar, ac) { if !isWide(ar, ac) {
panic(matrix.ErrShape) panic(ErrShape)
} }
var tmp Dense var tmp Dense
tmp.Mul(a, a.T()) tmp.Mul(a, a.T())
@@ -344,7 +343,7 @@ func TestDet(t *testing.T) {
denseComparison = func(a *Dense) interface{} { denseComparison = func(a *Dense) interface{} {
ar, ac := a.Dims() ar, ac := a.Dims()
if !isWide(ar, ac) { if !isWide(ar, ac) {
panic(matrix.ErrShape) panic(ErrShape)
} }
var tmp SymDense var tmp SymDense
tmp.SymOuterK(1, a) tmp.SymOuterK(1, a)
@@ -366,7 +365,7 @@ func TestDot(t *testing.T) {
ra, ca := a.Dims() ra, ca := a.Dims()
rb, cb := b.Dims() rb, cb := b.Dims()
if ra != rb || ca != cb { if ra != rb || ca != cb {
panic(matrix.ErrShape) panic(ErrShape)
} }
var sum float64 var sum float64
for i := 0; i < ra; i++ { for i := 0; i < ra; i++ {
@@ -481,9 +480,9 @@ func TestNormZero(t *testing.T) {
if !panicked { if !panicked {
t.Errorf("expected panic for Norm(&%T{}, %v)", a, norm) 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", t.Errorf("unexpected panic string for Norm(&%T{}, %v): got:%s want:%s",
a, norm, message, matrix.ErrShape.Error()) a, norm, message, ErrShape.Error())
} }
} }
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"
@@ -11,7 +11,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
// TODO: Need to add tests where one is overwritten. // TODO: Need to add tests where one is overwritten.
@@ -247,7 +246,7 @@ func (m *basicTriangular) T() Matrix {
return Transpose{m} return Transpose{m}
} }
func (m *basicTriangular) Triangle() (int, matrix.TriKind) { func (m *basicTriangular) Triangle() (int, TriKind) {
return (*TriDense)(m).Triangle() return (*TriDense)(m).Triangle()
} }

View File

@@ -4,7 +4,7 @@
//+build !appengine //+build !appengine
package mat64 package mat
import "unsafe" import "unsafe"

View File

@@ -4,7 +4,7 @@
//+build appengine //+build appengine
package mat64 package mat
import "reflect" import "reflect"

View File

@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"sync" "sync"
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
var tab64 = [64]byte{ var tab64 = [64]byte{
@@ -148,7 +147,7 @@ func putWorkspaceSym(s *SymDense) {
// getWorkspaceTri returns a *TriDense of size n and a cap that // getWorkspaceTri returns a *TriDense of size n and a cap that
// is less than 2*n. If clear is true, the data slice visible // is less than 2*n. If clear is true, the data slice visible
// through the Matrix interface is zeroed. // through the Matrix interface is zeroed.
func getWorkspaceTri(n int, kind matrix.TriKind, clear bool) *TriDense { func getWorkspaceTri(n int, kind TriKind, clear bool) *TriDense {
l := uint64(n) l := uint64(n)
l *= l l *= l
t := poolTri[bits(l)].Get().(*TriDense) 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.N = n
t.mat.Stride = n t.mat.Stride = n
if kind == matrix.Upper { if kind == Upper {
t.mat.Uplo = blas.Upper t.mat.Uplo = blas.Upper
} else if kind == matrix.Lower { } else if kind == Lower {
t.mat.Uplo = blas.Lower t.mat.Uplo = blas.Lower
} else { } else {
panic(matrix.ErrTriangle) panic(ErrTriangle)
} }
t.mat.Diag = blas.NonUnit t.mat.Diag = blas.NonUnit
t.cap = n t.cap = n

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"

View File

@@ -2,13 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import "fmt"
"fmt"
"gonum.org/v1/gonum/matrix"
)
// Product calculates the product of the given factors and places the result in // Product calculates the product of the given factors and places the result in
// the receiver. The order of multiplication operations is optimized to minimize // the receiver. The order of multiplication operations is optimized to minimize
@@ -31,7 +27,7 @@ func (m *Dense) Product(factors ...Matrix) {
switch len(factors) { switch len(factors) {
case 0: case 0:
if r != 0 || c != 0 { if r != 0 || c != 0 {
panic(matrix.ErrShape) panic(ErrShape)
} }
return return
case 1: 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. fr, fc := factors[0].Dims() // newMultiplier is only called with len(factors) > 2.
if !m.isZero() { if !m.isZero() {
if fr != r { if fr != r {
panic(matrix.ErrShape) panic(ErrShape)
} }
if _, lc := factors[len(factors)-1].Dims(); lc != c { 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() cr, cc := f.Dims()
dims[i+1] = cr dims[i+1] = cr
if pc != cr { if pc != cr {
panic(matrix.ErrShape) panic(ErrShape)
} }
pc = cc pc = cc
} }
@@ -150,7 +146,7 @@ func (p *multiplier) multiplySubchain(i, j int) (m Matrix, intermediate bool) {
if ac != br { if ac != br {
// Panic with a string since this // Panic with a string since this
// is not a user-facing panic. // is not a user-facing panic.
panic(matrix.ErrShape.Error()) panic(ErrShape.Error())
} }
if debugProductWalk { if debugProductWalk {

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"

View File

@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the QRDecomposition class from Jama 1.0.3. // Based on the QRDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"math" "math"
@@ -11,7 +11,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "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. // 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) work := getFloats(3*n, false)
iwork := getInts(n, false) iwork := getInts(n, false)
r := qr.qr.asTriDense(n, blas.NonUnit, blas.Upper) 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) putFloats(work)
putInts(iwork) putInts(iwork)
qr.cond = 1 / v qr.cond = 1 / v
@@ -43,7 +42,7 @@ func (qr *QR) updateCond() {
func (qr *QR) Factorize(a Matrix) { func (qr *QR) Factorize(a Matrix) {
m, n := a.Dims() m, n := a.Dims()
if m < n { if m < n {
panic(matrix.ErrShape) panic(ErrShape)
} }
k := min(m, n) k := min(m, n)
if qr.qr == nil { 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. // copy the result into m at the end.
if trans { if trans {
if c != br { if c != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(r, bc) m.reuseAs(r, bc)
} else { } else {
if r != br { if r != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(c, bc) m.reuseAs(c, bc)
} }
@@ -155,7 +154,7 @@ func (m *Dense) SolveQR(qr *QR, trans bool, b Matrix) error {
if trans { if trans {
ok := lapack64.Trtrs(blas.Trans, t, x.mat) ok := lapack64.Trtrs(blas.Trans, t, x.mat)
if !ok { if !ok {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
for i := c; i < r; i++ { for i := c; i < r; i++ {
zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) 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) ok := lapack64.Trtrs(blas.NoTrans, t, x.mat)
if !ok { 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 was set above to be the correct size for the result.
m.Copy(x) m.Copy(x)
putWorkspace(x) putWorkspace(x)
if qr.cond > matrix.ConditionTolerance { if qr.cond > ConditionTolerance {
return matrix.Condition(qr.cond) return Condition(qr.cond)
} }
return nil return nil
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"
@@ -10,7 +10,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
func TestDenseOverlaps(t *testing.T) { func TestDenseOverlaps(t *testing.T) {
@@ -94,7 +93,7 @@ func TestTriDenseOverlaps(t *testing.T) {
rnd := rand.New(rand.NewSource(1)) 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++ { for n := 1; n < 20; n++ {
data := make([]float64, n*n) data := make([]float64, n*n)
for i := range data { for i := range data {
@@ -120,7 +119,7 @@ func TestTriDenseOverlaps(t *testing.T) {
} else { } else {
views[k].n = 1 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( 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), m.Slice(views[k].i, views[k].i+views[k].n, views[k].j, views[k].j+views[k].n).(*Dense),
viewKind) viewKind)
@@ -172,21 +171,21 @@ func intervalsOverlap(a, b interval) bool {
return a.to > b.from && b.to > a.from 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 { switch parent {
case matrix.Upper: case Upper:
if i <= j { if i <= j {
return true return true
} }
if view == matrix.Upper { if view == Upper {
return i < j+n return i < j+n
} }
case matrix.Lower: case Lower:
if i >= j { if i >= j {
return true return true
} }
if view == matrix.Lower { if view == Lower {
return i+n > j return i+n > j
} }
} }
@@ -194,17 +193,17 @@ func overlapsParentTriangle(i, j, n int, parent, view matrix.TriKind) bool {
return false 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++ { for i := max(ai, bi); i < min(ai+an, bi+bn); i++ {
var a, b interval var a, b interval
if aKind == matrix.Upper { if aKind == Upper {
a = interval{from: aj - ai + i, to: aj + an} a = interval{from: aj - ai + i, to: aj + an}
} else { } else {
a = interval{from: aj, to: aj - ai + i + 1} 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} b = interval{from: bj - bi + i, to: bj + bn}
} else { } else {
b = interval{from: bj, to: bj - bi + i + 1} 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 return false
} }
func kindString(k matrix.TriKind) string { func kindString(k TriKind) string {
if k == matrix.Upper { if k == Upper {
return "U" return "U"
} }
return "L" return "L"
@@ -252,14 +251,14 @@ func TestIssue359(t *testing.T) {
// denseAsTriDense returns a triangular matrix derived from the // denseAsTriDense returns a triangular matrix derived from the
// square matrix m, with the orientation specified by kind. // 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() r, c := m.Dims()
if r != c { if r != c {
panic(matrix.ErrShape) panic(ErrShape)
} }
n := r n := r
uplo := blas.Lower uplo := blas.Lower
if kind == matrix.Upper { if kind == Upper {
uplo = blas.Upper uplo = blas.Upper
} }
return &TriDense{ return &TriDense{

View File

@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
// Solve finds a minimum-norm solution to a system of linear equations defined // 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() ar, ac := a.Dims()
br, bc := b.Dims() br, bc := b.Dims()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
m.reuseAs(ac, bc) m.reuseAs(ac, bc)
@@ -66,11 +65,11 @@ func (m *Dense) Solve(a, b Matrix) error {
blas64.Trsm(side, tA, 1, rm, m.mat) blas64.Trsm(side, tA, 1, rm, m.mat)
work := getFloats(3*rm.N, false) work := getFloats(3*rm.N, false)
iwork := getInts(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) putFloats(work)
putInts(iwork) putInts(iwork)
if cond > matrix.ConditionTolerance { if cond > ConditionTolerance {
return matrix.Condition(cond) return Condition(cond)
} }
return nil return nil
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"

View File

@@ -3,19 +3,18 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Based on the SingularValueDecomposition class from Jama 1.0.3. // Based on the SingularValueDecomposition class from Jama 1.0.3.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack" "gonum.org/v1/gonum/lapack"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
// SVD is a type for creating and using the Singular Value Decomposition (SVD) // SVD is a type for creating and using the Singular Value Decomposition (SVD)
// of a matrix. // of a matrix.
type SVD struct { type SVD struct {
kind matrix.SVDKind kind SVDKind
s []float64 s []float64
u blas64.General u blas64.General
@@ -40,16 +39,16 @@ type SVD struct {
// //
// Factorize returns whether the decomposition succeeded. If the decomposition // Factorize returns whether the decomposition succeeded. If the decomposition
// failed, routines that require a successful factorization will panic. // 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() m, n := a.Dims()
var jobU, jobVT lapack.SVDJob var jobU, jobVT lapack.SVDJob
switch kind { switch kind {
default: default:
panic("svd: bad input kind") panic("svd: bad input kind")
case matrix.SVDNone: case SVDNone:
jobU = lapack.SVDNone jobU = lapack.SVDNone
jobVT = lapack.SVDNone jobVT = lapack.SVDNone
case matrix.SVDFull: case SVDFull:
// TODO(btracey): This code should be modified to have the smaller // TODO(btracey): This code should be modified to have the smaller
// matrix written in-place into aCopy when the lapack/native/dgesvd // matrix written in-place into aCopy when the lapack/native/dgesvd
// implementation is complete. // implementation is complete.
@@ -67,7 +66,7 @@ func (svd *SVD) Factorize(a Matrix, kind matrix.SVDKind) (ok bool) {
} }
jobU = lapack.SVDAll jobU = lapack.SVDAll
jobVT = lapack.SVDAll jobVT = lapack.SVDAll
case matrix.SVDThin: case SVDThin:
// TODO(btracey): This code should be modified to have the larger // TODO(btracey): This code should be modified to have the larger
// matrix written in-place into aCopy when the lapack/native/dgesvd // matrix written in-place into aCopy when the lapack/native/dgesvd
// implementation is complete. // 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 // Kind returns the matrix.SVDKind of the decomposition. If no decomposition has been
// computed, Kind returns 0. // computed, Kind returns 0.
func (svd *SVD) Kind() matrix.SVDKind { func (svd *SVD) Kind() SVDKind {
return svd.kind return svd.kind
} }
@@ -133,7 +132,7 @@ func (svd *SVD) Values(s []float64) []float64 {
s = make([]float64, len(svd.s)) s = make([]float64, len(svd.s))
} }
if len(s) != len(svd.s) { if len(s) != len(svd.s) {
panic(matrix.ErrSliceLengthMismatch) panic(ErrSliceLengthMismatch)
} }
copy(s, svd.s) copy(s, svd.s)
return 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. // of size m×min(m,n) if svd.Kind() == SVDThin, and UTo panics otherwise.
func (svd *SVD) UTo(dst *Dense) *Dense { func (svd *SVD) UTo(dst *Dense) *Dense {
kind := svd.kind kind := svd.kind
if kind != matrix.SVDFull && kind != matrix.SVDThin { if kind != SVDFull && kind != SVDThin {
panic("mat64: improper SVD kind") panic("mat64: improper SVD kind")
} }
r := svd.u.Rows 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. // of size n×min(m,n) if svd.Kind() == SVDThin, and VTo panics otherwise.
func (svd *SVD) VTo(dst *Dense) *Dense { func (svd *SVD) VTo(dst *Dense) *Dense {
kind := svd.kind kind := svd.kind
if kind != matrix.SVDFull && kind != matrix.SVDThin { if kind != SVDFull && kind != SVDThin {
panic("mat64: improper SVD kind") panic("mat64: improper SVD kind")
} }
r := svd.vt.Rows r := svd.vt.Rows

View File

@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math/rand" "math/rand"
"testing" "testing"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
func TestSVD(t *testing.T) { func TestSVD(t *testing.T) {
@@ -63,7 +62,7 @@ func TestSVD(t *testing.T) {
}, },
} { } {
var svd SVD var svd SVD
ok := svd.Factorize(test.a, matrix.SVDThin) ok := svd.Factorize(test.a, SVDThin)
if !ok { if !ok {
t.Errorf("SVD failed") t.Errorf("SVD failed")
} }
@@ -111,7 +110,7 @@ func TestSVD(t *testing.T) {
// Test Full decomposition. // Test Full decomposition.
var svd SVD var svd SVD
ok := svd.Factorize(a, matrix.SVDFull) ok := svd.Factorize(a, SVDFull)
if !ok { if !ok {
t.Errorf("SVD factorization failed") t.Errorf("SVD factorization failed")
} }
@@ -130,7 +129,7 @@ func TestSVD(t *testing.T) {
} }
// Test Thin decomposition. // Test Thin decomposition.
ok = svd.Factorize(a, matrix.SVDThin) ok = svd.Factorize(a, SVDThin)
if !ok { if !ok {
t.Errorf("SVD factorization failed") t.Errorf("SVD factorization failed")
} }
@@ -152,7 +151,7 @@ func TestSVD(t *testing.T) {
} }
// Test None decomposition. // Test None decomposition.
ok = svd.Factorize(a, matrix.SVDNone) ok = svd.Factorize(a, SVDNone)
if !ok { if !ok {
t.Errorf("SVD factorization failed") t.Errorf("SVD factorization failed")
} }

View File

@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"math" "math"
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
var ( var (
@@ -64,7 +63,7 @@ func NewSymDense(n int, data []float64) *SymDense {
panic("mat64: negative dimension") panic("mat64: negative dimension")
} }
if data != nil && n*n != len(data) { if data != nil && n*n != len(data) {
panic(matrix.ErrShape) panic(ErrShape)
} }
if data == nil { if data == nil {
data = make([]float64, n*n) data = make([]float64, n*n)
@@ -147,7 +146,7 @@ func (s *SymDense) reuseAs(n int) {
panic(badSymTriangle) panic(badSymTriangle)
} }
if s.mat.N != n { 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) { func (s *SymDense) AddSym(a, b Symmetric) {
n := a.Symmetric() n := a.Symmetric()
if n != b.Symmetric() { if n != b.Symmetric() {
panic(matrix.ErrShape) panic(ErrShape)
} }
s.reuseAs(n) s.reuseAs(n)
@@ -227,7 +226,7 @@ func (s *SymDense) CopySym(a Symmetric) int {
func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *Vector) { func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *Vector) {
n := x.Len() n := x.Len()
if a.Symmetric() != n { if a.Symmetric() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
s.reuseAs(n) s.reuseAs(n)
if s != a { if s != a {
@@ -246,7 +245,7 @@ func (s *SymDense) SymRankK(a Symmetric, alpha float64, x Matrix) {
n := a.Symmetric() n := a.Symmetric()
r, _ := x.Dims() r, _ := x.Dims()
if r != n { if r != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
xMat, aTrans := untranspose(x) xMat, aTrans := untranspose(x)
var g blas64.General var g blas64.General
@@ -307,7 +306,7 @@ func (s *SymDense) SymOuterK(alpha float64, x Matrix) {
s.SymRankK(s, alpha, x) s.SymRankK(s, alpha, x)
} }
default: 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) { func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y *Vector) {
n := s.mat.N n := s.mat.N
if x.Len() != n { if x.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if y.Len() != n { if y.Len() != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
var w SymDense var w SymDense
if s == a { if s == a {
@@ -419,7 +418,7 @@ func (s *SymDense) ViewSquare(i, n int) Matrix {
func (s *SymDense) SliceSquare(i, k int) Matrix { func (s *SymDense) SliceSquare(i, k int) Matrix {
sz := s.Symmetric() sz := s.Symmetric()
if i < 0 || sz < i || k < i || sz < k { if i < 0 || sz < i || k < i || sz < k {
panic(matrix.ErrIndexOutOfRange) panic(ErrIndexOutOfRange)
} }
v := *s v := *s
v.mat.Data = s.mat.Data[i*s.mat.Stride+i : (k-1)*s.mat.Stride+k] 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. // not modified during the call to GrowSquare.
func (s *SymDense) GrowSquare(n int) Matrix { func (s *SymDense) GrowSquare(n int) Matrix {
if n < 0 { if n < 0 {
panic(matrix.ErrIndexOutOfRange) panic(ErrIndexOutOfRange)
} }
if n == 0 { if n == 0 {
return s return s
@@ -483,12 +482,12 @@ func (s *SymDense) PowPSD(a Symmetric, pow float64) error {
var eigen EigenSym var eigen EigenSym
ok := eigen.Factorize(a, true) ok := eigen.Factorize(a, true)
if !ok { if !ok {
return matrix.ErrFailedEigen return ErrFailedEigen
} }
values := eigen.Values(nil) values := eigen.Values(nil)
for i, v := range values { for i, v := range values {
if v <= 0 { if v <= 0 {
return matrix.ErrNotPSD return ErrNotPSD
} }
values[i] = math.Pow(v, pow) values[i] = math.Pow(v, pow)
} }

View File

@@ -1,14 +1,14 @@
package mat64_test package mat_test
import ( import (
"fmt" "fmt"
"gonum.org/v1/gonum/matrix/mat64" "gonum.org/v1/gonum/mat"
) )
func ExampleSymDense_SubsetSym() { func ExampleSymDense_SubsetSym() {
n := 5 n := 5
s := mat64.NewSymDense(5, nil) s := mat.NewSymDense(5, nil)
count := 1.0 count := 1.0
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
for j := i; j < n; j++ { for j := i; j < n; j++ {
@@ -17,18 +17,18 @@ func ExampleSymDense_SubsetSym() {
} }
} }
fmt.Println("Original matrix:") 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} // Take the subset {0, 2, 4}
var sub mat64.SymDense var sub mat.SymDense
sub.SubsetSym(s, []int{0, 2, 4}) sub.SubsetSym(s, []int{0, 2, 4})
fmt.Println("Subset {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} // Take the subset {0, 0, 4}
sub.SubsetSym(s, []int{0, 0, 4}) sub.SubsetSym(s, []int{0, 0, 4})
fmt.Println("Subset {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: // Output:
// Original matrix: // Original matrix:

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"fmt" "fmt"
@@ -14,7 +14,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/matrix"
) )
func TestNewSymmetric(t *testing.T) { func TestNewSymmetric(t *testing.T) {
@@ -61,7 +60,7 @@ func TestNewSymmetric(t *testing.T) {
} }
panicked, message := panics(func() { NewSymDense(3, []float64{1, 2}) }) 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") t.Error("expected panic for invalid data slice length")
} }
} }
@@ -81,13 +80,13 @@ func TestSymAtSet(t *testing.T) {
// Check At out of bounds // Check At out of bounds
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { sym.At(row, 0) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { sym.At(0, col) }) 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) 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 // Check Set out of bounds
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { sym.SetSym(row, 0, 1.2) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { sym.SetSym(0, col, 1.2) }) 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) t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col)
} }
} }

View File

@@ -1,4 +1,4 @@
package mat64 package mat
import ( import (
"math" "math"
@@ -6,7 +6,6 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/lapack/lapack64" "gonum.org/v1/gonum/lapack/lapack64"
"gonum.org/v1/gonum/matrix"
) )
var ( var (
@@ -29,7 +28,7 @@ type Triangular interface {
Matrix Matrix
// Triangular returns the number of rows/columns in the matrix and its // Triangular returns the number of rows/columns in the matrix and its
// orientation. // 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 // TTri is the equivalent of the T() method in the Matrix interface but
// guarantees the transpose is of triangular type. // 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. // 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() n, upper := t.Triangular.Triangle()
return n, !upper 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 // 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. // 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. // 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 { if n < 0 {
panic("mat64: negative dimension") panic("mat64: negative dimension")
} }
if data != nil && len(data) != n*n { if data != nil && len(data) != n*n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if data == nil { if data == nil {
data = make([]float64, n*n) data = make([]float64, n*n)
} }
uplo := blas.Lower uplo := blas.Lower
if kind == matrix.Upper { if kind == Upper {
uplo = blas.Upper uplo = blas.Upper
} }
return &TriDense{ return &TriDense{
@@ -131,16 +130,16 @@ func (t *TriDense) Dims() (r, c int) {
// Triangle returns the dimension of t and its orientation. The returned // Triangle returns the dimension of t and its orientation. The returned
// orientation is only valid when n is not zero. // orientation is only valid when n is not zero.
func (t *TriDense) Triangle() (n int, kind matrix.TriKind) { func (t *TriDense) Triangle() (n int, kind TriKind) {
return t.mat.N, matrix.TriKind(!t.isZero()) && t.triKind() return t.mat.N, TriKind(!t.isZero()) && t.triKind()
} }
func (t *TriDense) isUpper() bool { func (t *TriDense) isUpper() bool {
return isUpperUplo(t.mat.Uplo) return isUpperUplo(t.mat.Uplo)
} }
func (t *TriDense) triKind() matrix.TriKind { func (t *TriDense) triKind() TriKind {
return matrix.TriKind(isUpperUplo(t.mat.Uplo)) return TriKind(isUpperUplo(t.mat.Uplo))
} }
func isUpperUplo(u blas.Uplo) bool { 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 // 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 // orientation. If the receiver is non-zero, reuseAs checks that the receiver
// is the correct size and orientation. // 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 ul := blas.Lower
if kind == matrix.Upper { if kind == Upper {
ul = blas.Upper ul = blas.Upper
} }
if t.mat.N > t.cap { if t.mat.N > t.cap {
@@ -236,10 +235,10 @@ func (t *TriDense) reuseAs(n int, kind matrix.TriKind) {
return return
} }
if t.mat.N != n { if t.mat.N != n {
panic(matrix.ErrShape) panic(ErrShape)
} }
if t.mat.Uplo != ul { if t.mat.Uplo != ul {
panic(matrix.ErrTriangle) panic(ErrTriangle)
} }
} }
@@ -333,18 +332,18 @@ func (t *TriDense) InverseTri(a Triangular) error {
t.Copy(a) t.Copy(a)
work := getFloats(3*n, false) work := getFloats(3*n, false)
iwork := getInts(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) putFloats(work)
putInts(iwork) putInts(iwork)
if math.IsInf(cond, 1) { if math.IsInf(cond, 1) {
return matrix.Condition(cond) return Condition(cond)
} }
ok := lapack64.Trtri(t.mat) ok := lapack64.Trtri(t.mat)
if !ok { if !ok {
return matrix.Condition(math.Inf(1)) return Condition(math.Inf(1))
} }
if cond > matrix.ConditionTolerance { if cond > ConditionTolerance {
return matrix.Condition(cond) return Condition(cond)
} }
return nil return nil
} }
@@ -356,10 +355,10 @@ func (t *TriDense) MulTri(a, b Triangular) {
n, kind := a.Triangle() n, kind := a.Triangle()
nb, kindb := b.Triangle() nb, kindb := b.Triangle()
if n != nb { if n != nb {
panic(matrix.ErrShape) panic(ErrShape)
} }
if kind != kindb { if kind != kindb {
panic(matrix.ErrTriangle) panic(ErrTriangle)
} }
aU, _ := untransposeTri(a) aU, _ := untransposeTri(a)
@@ -375,7 +374,7 @@ func (t *TriDense) MulTri(a, b Triangular) {
} }
// TODO(btracey): Improve the set of fast-paths. // TODO(btracey): Improve the set of fast-paths.
if kind == matrix.Upper { if kind == Upper {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
for j := i; j < n; j++ { for j := i; j < n; j++ {
var v float64 var v float64

View File

@@ -1,4 +1,4 @@
package mat64 package mat
import ( import (
"math" "math"
@@ -8,14 +8,13 @@ import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
func TestNewTriangular(t *testing.T) { func TestNewTriangular(t *testing.T) {
for i, test := range []struct { for i, test := range []struct {
data []float64 data []float64
n int n int
kind matrix.TriKind kind TriKind
mat *TriDense mat *TriDense
}{ }{
{ {
@@ -25,7 +24,7 @@ func TestNewTriangular(t *testing.T) {
7, 8, 9, 7, 8, 9,
}, },
n: 3, n: 3,
kind: matrix.Upper, kind: Upper,
mat: &TriDense{ mat: &TriDense{
mat: blas64.Triangular{ mat: blas64.Triangular{
N: 3, 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}) }) 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) 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 // Check At out of bounds
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { tri.At(row, 0) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { tri.At(0, col) }) 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) 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 // Check Set out of bounds
for _, row := range []int{-1, rows, rows + 1} { for _, row := range []int{-1, rows, rows + 1} {
panicked, message := panics(func() { tri.SetTri(row, 0, 1.2) }) 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) t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
} }
} }
for _, col := range []int{-1, cols, cols + 1} { for _, col := range []int{-1, cols, cols + 1} {
panicked, message := panics(func() { tri.SetTri(0, col, 1.2) }) 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) 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 tri.mat.Uplo = st.uplo
panicked, message := panics(func() { tri.SetTri(st.row, st.col, 1.2) }) 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) t.Errorf("expected panic for %+v", st)
} }
} }
@@ -140,8 +139,8 @@ func TestTriDenseCopy(t *testing.T) {
size := rand.Intn(100) size := rand.Intn(100)
r, err := randDense(size, 0.9, rand.NormFloat64) r, err := randDense(size, 0.9, rand.NormFloat64)
if size == 0 { if size == 0 {
if err != matrix.ErrZeroLength { if err != ErrZeroLength {
t.Fatalf("expected error %v: got: %v", matrix.ErrZeroLength, err) t.Fatalf("expected error %v: got: %v", ErrZeroLength, err)
} }
continue continue
} }
@@ -190,8 +189,8 @@ func TestTriTriDenseCopy(t *testing.T) {
size := rand.Intn(100) size := rand.Intn(100)
r, err := randDense(size, 1, rand.NormFloat64) r, err := randDense(size, 1, rand.NormFloat64)
if size == 0 { if size == 0 {
if err != matrix.ErrZeroLength { if err != ErrZeroLength {
t.Fatalf("expected error %v: got: %v", matrix.ErrZeroLength, err) t.Fatalf("expected error %v: got: %v", ErrZeroLength, err)
} }
continue continue
} }
@@ -238,7 +237,7 @@ func TestTriTriDenseCopy(t *testing.T) {
} }
func TestTriInverse(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} { for _, n := range []int{1, 3, 5, 9} {
data := make([]float64, n*n) data := make([]float64, n*n)
for i := range data { for i := range data {
@@ -297,10 +296,10 @@ func TestTriMul(t *testing.T) {
return false return false
} }
_, kind := a.(Triangular).Triangle() _, kind := a.(Triangular).Triangle()
r := kind == matrix.Lower r := kind == Lower
return r return r
} }
receiver := NewTriDense(3, matrix.Lower, nil) receiver := NewTriDense(3, Lower, nil)
testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesLower, legalSizeTriMul, 1e-14) testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesLower, legalSizeTriMul, 1e-14)
legalTypesUpper := func(a, b Matrix) bool { legalTypesUpper := func(a, b Matrix) bool {
@@ -309,10 +308,10 @@ func TestTriMul(t *testing.T) {
return false return false
} }
_, kind := a.(Triangular).Triangle() _, kind := a.(Triangular).Triangle()
r := kind == matrix.Upper r := kind == Upper
return r return r
} }
receiver = NewTriDense(3, matrix.Upper, nil) receiver = NewTriDense(3, Upper, nil)
testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesUpper, legalSizeTriMul, 1e-14) testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesUpper, legalSizeTriMul, 1e-14)
} }
@@ -323,7 +322,7 @@ func TestCopySymIntoTriangle(t *testing.T) {
sUplo blas.Uplo sUplo blas.Uplo
s []float64 s []float64
tUplo matrix.TriKind tUplo TriKind
want []float64 want []float64
}{ }{
{ {
@@ -334,7 +333,7 @@ func TestCopySymIntoTriangle(t *testing.T) {
nan, 4, 5, nan, 4, 5,
nan, nan, 6, nan, nan, 6,
}, },
tUplo: matrix.Upper, tUplo: Upper,
want: []float64{ want: []float64{
1, 2, 3, 1, 2, 3,
0, 4, 5, 0, 4, 5,
@@ -349,7 +348,7 @@ func TestCopySymIntoTriangle(t *testing.T) {
2, 3, nan, 2, 3, nan,
4, 5, 6, 4, 5, 6,
}, },
tUplo: matrix.Upper, tUplo: Upper,
want: []float64{ want: []float64{
1, 2, 4, 1, 2, 4,
0, 3, 5, 0, 3, 5,
@@ -364,7 +363,7 @@ func TestCopySymIntoTriangle(t *testing.T) {
nan, 4, 5, nan, 4, 5,
nan, nan, 6, nan, nan, 6,
}, },
tUplo: matrix.Lower, tUplo: Lower,
want: []float64{ want: []float64{
1, 0, 0, 1, 0, 0,
2, 4, 0, 2, 4, 0,
@@ -379,7 +378,7 @@ func TestCopySymIntoTriangle(t *testing.T) {
2, 3, nan, 2, 3, nan,
4, 5, 6, 4, 5, 6,
}, },
tUplo: matrix.Lower, tUplo: Lower,
want: []float64{ want: []float64{
1, 0, 0, 1, 0, 0,
2, 3, 0, 2, 3, 0,

View File

@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mat64 package mat
import ( import (
"gonum.org/v1/gonum/blas" "gonum.org/v1/gonum/blas"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/internal/asm/f64" "gonum.org/v1/gonum/internal/asm/f64"
"gonum.org/v1/gonum/matrix"
) )
var ( var (
@@ -34,7 +33,7 @@ type Vector struct {
// will be reflected in data. If neither of these is true, NewVector will panic. // will be reflected in data. If neither of these is true, NewVector will panic.
func NewVector(n int, data []float64) *Vector { func NewVector(n int, data []float64) *Vector {
if len(data) != n && data != nil { if len(data) != n && data != nil {
panic(matrix.ErrShape) panic(ErrShape)
} }
if data == nil { if data == nil {
data = make([]float64, n) data = make([]float64, n)
@@ -64,7 +63,7 @@ func (v *Vector) ViewVec(i, n int) *Vector {
// of the receiver. // of the receiver.
func (v *Vector) SliceVec(i, k int) *Vector { func (v *Vector) SliceVec(i, k int) *Vector {
if i < 0 || k <= i || v.n < k { if i < 0 || k <= i || v.n < k {
panic(matrix.ErrIndexOutOfRange) panic(ErrIndexOutOfRange)
} }
return &Vector{ return &Vector{
n: k - i, n: k - i,
@@ -168,7 +167,7 @@ func (v *Vector) AddScaledVec(a *Vector, alpha float64, b *Vector) {
br := b.Len() br := b.Len()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != a { if v != a {
@@ -211,7 +210,7 @@ func (v *Vector) AddVec(a, b *Vector) {
br := b.Len() br := b.Len()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != a { if v != a {
@@ -239,7 +238,7 @@ func (v *Vector) SubVec(a, b *Vector) {
br := b.Len() br := b.Len()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != a { if v != a {
@@ -268,7 +267,7 @@ func (v *Vector) MulElemVec(a, b *Vector) {
br := b.Len() br := b.Len()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != a { if v != a {
@@ -293,7 +292,7 @@ func (v *Vector) DivElemVec(a, b *Vector) {
br := b.Len() br := b.Len()
if ar != br { if ar != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != a { if v != a {
@@ -317,7 +316,7 @@ func (v *Vector) MulVec(a Matrix, b *Vector) {
r, c := a.Dims() r, c := a.Dims()
br := b.Len() br := b.Len()
if c != br { if c != br {
panic(matrix.ErrShape) panic(ErrShape)
} }
if v != b { if v != b {
@@ -427,7 +426,7 @@ func (v *Vector) reuseAs(r int) {
return return
} }
if r != v.n { if r != v.n {
panic(matrix.ErrShape) panic(ErrShape)
} }
} }

View File

@@ -1,4 +1,4 @@
package mat64 package mat
import ( import (
"math/rand" "math/rand"
@@ -6,7 +6,6 @@ import (
"testing" "testing"
"gonum.org/v1/gonum/blas/blas64" "gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/matrix"
) )
func TestNewVector(t *testing.T) { func TestNewVector(t *testing.T) {
@@ -80,13 +79,13 @@ func TestVectorAtSet(t *testing.T) {
for _, row := range []int{-1, n} { for _, row := range []int{-1, n} {
panicked, message := panics(func() { v.At(row, 0) }) panicked, message := panics(func() { v.At(row, 0) })
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) t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
} }
} }
for _, col := range []int{-1, 1} { for _, col := range []int{-1, 1} {
panicked, message := panics(func() { v.At(0, col) }) 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) 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} { for _, row := range []int{-1, n} {
panicked, message := panics(func() { v.SetVec(row, 100) }) 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) t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
} }
} }

View File

@@ -1,158 +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 mat64 provides implementations of float64 matrix structures and
// linear algebra operations on them.
//
// Overview
//
// This section provides a quick overview of the mat64 package. The following
// sections provide more in depth commentary.
//
// 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
//
// 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 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.
//
// 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 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,
// 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
// through blas64, so if a cgo BLAS implementation is registered, the lapack64
// 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
// blas64.General, blas64.Gemm (general matrix multiplication) is called, while
// instead if b is a RawSymmetricer blas64.Symm is used (general-symmetric
// multiplication), and if b is a *Vector blas64.Gemv is used.
//
// 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 mat64 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
// mat64 API, and mat64 functions will detect and complain about those.
// There are many ways to make mistakes by excursion from the mat64 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 and lapack64 may be used to call the behavior directly.
//
// mat64 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.
//
// mat64 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
// if there is undetected overlap.
//
package mat64 // import "gonum.org/v1/gonum/matrix/mat64"