Change NewDense signature and behaviour

This is an API breaking change.

NewDense now panics if len(mat) != r*c, unless mat == nil. When mat is
nil a new, correctly sized slice is allocated.
This commit is contained in:
kortschak
2014-01-08 09:56:39 +10:30
parent fadcd6dd7f
commit b10f3a00f3
13 changed files with 87 additions and 112 deletions

View File

@@ -21,7 +21,7 @@ func Cholesky(a *Dense) CholeskyFactor {
// Initialize. // Initialize.
m, n := a.Dims() m, n := a.Dims()
spd := m == n spd := m == n
l, _ := NewDense(n, n, make([]float64, n*n)) l := NewDense(n, n, nil)
// Main loop. // Main loop.
lRowj := make([]float64, n) lRowj := make([]float64, n)
@@ -59,7 +59,7 @@ func CholeskyR(a *Dense) (r *Dense, spd bool) {
// Initialize. // Initialize.
m, n := a.Dims() m, n := a.Dims()
spd = m == n spd = m == n
r, _ = NewDense(n, n, make([]float64, n*n)) r = NewDense(n, n, nil)
// Main loop. // Main loop.
for j := 0; j < n; j++ { for j := 0; j < n; j++ {

View File

@@ -14,11 +14,11 @@ func (s *S) TestCholesky(c *check.C) {
spd bool spd bool
}{ }{
{ {
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
4, 1, 1, 4, 1, 1,
1, 2, 3, 1, 2, 3,
1, 3, 6, 1, 3, 6,
})), }),
spd: true, spd: true,
}, },

View File

@@ -62,9 +62,12 @@ type Dense struct {
mat BlasMatrix mat BlasMatrix
} }
func NewDense(r, c int, mat []float64) (*Dense, error) { func NewDense(r, c int, mat []float64) *Dense {
if r*c != len(mat) { if mat != nil && r*c != len(mat) {
return nil, ErrShape panic(ErrShape)
}
if mat == nil {
mat = make([]float64, r*c)
} }
return &Dense{BlasMatrix{ return &Dense{BlasMatrix{
Order: BlasOrder, Order: BlasOrder,
@@ -72,7 +75,7 @@ func NewDense(r, c int, mat []float64) (*Dense, error) {
Cols: c, Cols: c,
Stride: c, Stride: c,
Data: mat, Data: mat,
}}, nil }}
} }
// DenseCopyOf returns a newly allocated copy of the elements of a. // DenseCopyOf returns a newly allocated copy of the elements of a.

View File

@@ -359,7 +359,7 @@ func orthes(a *Dense) (hess, v *Dense) {
} }
// Accumulate transformations (Algol's ortran). // Accumulate transformations (Algol's ortran).
v, _ = NewDense(n, n, make([]float64, n*n)) v = NewDense(n, n, nil)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
for j := 0; j < n; j++ { for j := 0; j < n; j++ {
if i == j { if i == j {
@@ -811,7 +811,7 @@ func (f EigenFactors) D() *Dense {
if n = len(d); n != len(e) { if n = len(d); n != len(e) {
panic(ErrSquare) panic(ErrSquare)
} }
dm, _ := NewDense(n, n, make([]float64, n*n)) dm := NewDense(n, n, nil)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
dm.Set(i, i, d[i]) dm.Set(i, i, d[i])
if e[i] > 0 { if e[i] > 0 {

View File

@@ -19,66 +19,66 @@ func (s *S) TestEigen(c *check.C) {
v *Dense v *Dense
}{ }{
{ {
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
1, 2, 1, 1, 2, 1,
6, -1, 0, 6, -1, 0,
-1, -2, -1, -1, -2, -1,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
d: []float64{3.0000000000000044, -4.000000000000003, -1.0980273383714707e-16}, d: []float64{3.0000000000000044, -4.000000000000003, -1.0980273383714707e-16},
e: []float64{0, 0, 0}, e: []float64{0, 0, 0},
v: mustDense(NewDense(3, 3, []float64{ v: NewDense(3, 3, []float64{
-0.48507125007266627, 0.41649656391752204, 0.11785113019775795, -0.48507125007266627, 0.41649656391752204, 0.11785113019775795,
-0.7276068751089995, -0.8329931278350428, 0.7071067811865481, -0.7276068751089995, -0.8329931278350428, 0.7071067811865481,
0.48507125007266627, -0.4164965639175216, -1.5320646925708532, 0.48507125007266627, -0.4164965639175216, -1.5320646925708532,
})), }),
}, },
{ {
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
1, 6, -1, 1, 6, -1,
6, -1, -2, 6, -1, -2,
-1, -2, -1, -1, -2, -1,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
d: []float64{-6.240753470718579, -1.3995889142010132, 6.640342384919599}, d: []float64{-6.240753470718579, -1.3995889142010132, 6.640342384919599},
e: []float64{0, 0, 0}, e: []float64{0, 0, 0},
v: mustDense(NewDense(3, 3, []float64{ v: NewDense(3, 3, []float64{
-0.6134279348516111, -0.31411097261113, -0.7245967607083111, -0.6134279348516111, -0.31411097261113, -0.7245967607083111,
0.7697297716508223, -0.03251534945303795, -0.6375412384185983, 0.7697297716508223, -0.03251534945303795, -0.6375412384185983,
0.17669818159240022, -0.9488293044247931, 0.2617263908869383, 0.17669818159240022, -0.9488293044247931, 0.2617263908869383,
})), }),
}, },
{ // Jama pvals { // Jama pvals
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
4, 1, 1, 4, 1, 1,
1, 2, 3, 1, 2, 3,
1, 3, 6, 1, 3, 6,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
}, },
{ // Jama evals { // Jama evals
a: mustDense(NewDense(4, 4, []float64{ a: NewDense(4, 4, []float64{
0, 1, 0, 0, 0, 1, 0, 0,
1, 0, 2e-7, 0, 1, 0, 2e-7, 0,
0, -2e-7, 0, 1, 0, -2e-7, 0, 1,
0, 0, 1, 0, 0, 0, 1, 0,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
}, },
{ // Jama badeigs { // Jama badeigs
a: mustDense(NewDense(5, 5, []float64{ a: NewDense(5, 5, []float64{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
0, 0, 0, 1, 0, 0, 0, 0, 1, 0,
1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
}, },

View File

@@ -173,7 +173,7 @@ func (f LUFactors) IsSingular() bool {
func (f LUFactors) L() *Dense { func (f LUFactors) L() *Dense {
lu := f.LU lu := f.LU
m, n := lu.Dims() m, n := lu.Dims()
l, _ := NewDense(m, n, make([]float64, m*n)) l := NewDense(m, n, nil)
for i := 0; i < m; i++ { for i := 0; i < m; i++ {
for j := 0; j < n; j++ { for j := 0; j < n; j++ {
if i > j { if i > j {
@@ -190,7 +190,7 @@ func (f LUFactors) L() *Dense {
func (f LUFactors) U() *Dense { func (f LUFactors) U() *Dense {
lu := f.LU lu := f.LU
m, n := lu.Dims() m, n := lu.Dims()
u, _ := NewDense(m, n, make([]float64, m*n)) u := NewDense(m, n, nil)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
for j := 0; j < n; j++ { for j := 0; j < n; j++ {
if i <= j { if i <= j {

View File

@@ -19,22 +19,22 @@ func (s *S) TestLUD(c *check.C) {
sign int sign int
}{ }{
{ // This is a hard coded equivalent of the approach used in the Jama LU test. { // This is a hard coded equivalent of the approach used in the Jama LU test.
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
0, 2, 3, 0, 2, 3,
4, 5, 6, 4, 5, 6,
7, 8, 9, 7, 8, 9,
})), }),
l: mustDense(NewDense(3, 3, []float64{ l: NewDense(3, 3, []float64{
1, 0, 0, 1, 0, 0,
0, 1, 0, 0, 1, 0,
0.5714285714285714, 0.2142857142857144, 1, 0.5714285714285714, 0.2142857142857144, 1,
})), }),
u: mustDense(NewDense(3, 3, []float64{ u: NewDense(3, 3, []float64{
7, 8, 9, 7, 8, 9,
0, 2, 3, 0, 2, 3,
0, 0, 0.2142857142857144, 0, 0, 0.2142857142857144,
})), }),
pivot: []int{ pivot: []int{
2, // 0 0 1 2, // 0 0 1
0, // 1 0 0 0, // 1 0 0
@@ -78,22 +78,22 @@ func (s *S) TestLUDGaussian(c *check.C) {
sign int sign int
}{ }{
{ // This is a hard coded equivalent of the approach used in the Jama LU test. { // This is a hard coded equivalent of the approach used in the Jama LU test.
a: mustDense(NewDense(3, 3, []float64{ a: NewDense(3, 3, []float64{
0, 2, 3, 0, 2, 3,
4, 5, 6, 4, 5, 6,
7, 8, 9, 7, 8, 9,
})), }),
l: mustDense(NewDense(3, 3, []float64{ l: NewDense(3, 3, []float64{
1, 0, 0, 1, 0, 0,
0, 1, 0, 0, 1, 0,
0.5714285714285714, 0.2142857142857144, 1, 0.5714285714285714, 0.2142857142857144, 1,
})), }),
u: mustDense(NewDense(3, 3, []float64{ u: NewDense(3, 3, []float64{
7, 8, 9, 7, 8, 9,
0, 2, 3, 0, 2, 3,
0, 0, 0.2142857142857144, 0, 0, 0.2142857142857144,
})), }),
pivot: []int{ pivot: []int{
2, // 0 0 1 2, // 0 0 1
0, // 1 0 0 0, // 1 0 0

View File

@@ -289,7 +289,7 @@ func Inverse(a Matrix) *Dense {
for i := 0; i < m*m; i += m + 1 { for i := 0; i < m*m; i += m + 1 {
d[i] = 1 d[i] = 1
} }
eye, _ := NewDense(m, m, d) eye := NewDense(m, m, d)
return Solve(a, eye) return Solve(a, eye)
} }

View File

@@ -46,19 +46,12 @@ func unflatten(r, c int, d []float64) [][]float64 {
return m return m
} }
func mustDense(m *Dense, err error) *Dense {
if err != nil {
panic(err)
}
return m
}
func eye() *Dense { func eye() *Dense {
return mustDense(NewDense(3, 3, []float64{ return NewDense(3, 3, []float64{
1, 0, 0, 1, 0, 0,
0, 1, 0, 0, 1, 0,
0, 0, 1, 0, 0, 1,
})) })
} }
func (s *S) TestMaybe(c *check.C) { func (s *S) TestMaybe(c *check.C) {
@@ -185,8 +178,7 @@ func (s *S) TestNewDense(c *check.C) {
}}, }},
}, },
} { } {
m, err := NewDense(test.rows, test.cols, test.a) m := NewDense(test.rows, test.cols, test.a)
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
rows, cols := m.Dims() rows, cols := m.Dims()
c.Check(rows, check.Equals, test.rows, check.Commentf("Test %d", i)) c.Check(rows, check.Equals, test.rows, check.Commentf("Test %d", i))
c.Check(cols, check.Equals, test.cols, check.Commentf("Test %d", i)) c.Check(cols, check.Equals, test.cols, check.Commentf("Test %d", i))
@@ -204,8 +196,7 @@ func (s *S) TestRowCol(c *check.C) {
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
} { } {
a, err := NewDense(flatten(af)) a := NewDense(flatten(af))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
for ri, row := range af { for ri, row := range af {
c.Check(a.Row(nil, ri), check.DeepEquals, row, check.Commentf("Test %d", i)) c.Check(a.Row(nil, ri), check.DeepEquals, row, check.Commentf("Test %d", i))
} }
@@ -220,14 +211,13 @@ func (s *S) TestRowCol(c *check.C) {
} }
func (s *S) TestSetRowColumn(c *check.C) { func (s *S) TestSetRowColumn(c *check.C) {
for i, as := range [][][]float64{ for _, as := range [][][]float64{
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
} { } {
for ri, row := range as { for ri, row := range as {
a, err := NewDense(flatten(as)) a := NewDense(flatten(as))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
t := &Dense{} t := &Dense{}
t.Clone(a) t.Clone(a)
a.SetRow(ri, make([]float64, a.mat.Cols)) a.SetRow(ri, make([]float64, a.mat.Cols))
@@ -236,8 +226,7 @@ func (s *S) TestSetRowColumn(c *check.C) {
} }
for ci := range as[0] { for ci := range as[0] {
a, err := NewDense(flatten(as)) a := NewDense(flatten(as))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
t := &Dense{} t := &Dense{}
t.Clone(a) t.Clone(a)
a.SetCol(ci, make([]float64, a.mat.Rows)) a.SetCol(ci, make([]float64, a.mat.Rows))
@@ -281,12 +270,9 @@ func (s *S) TestAdd(c *check.C) {
[][]float64{{2, 4, 6}, {8, 10, 12}}, [][]float64{{2, 4, 6}, {8, 10, 12}},
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) b := NewDense(flatten(test.b))
b, err := NewDense(flatten(test.b)) r := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
r, err := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
temp := &Dense{} temp := &Dense{}
temp.Add(a, b) temp.Add(a, b)
@@ -338,12 +324,9 @@ func (s *S) TestSub(c *check.C) {
[][]float64{{0, 0, 0}, {0, 0, 0}}, [][]float64{{0, 0, 0}, {0, 0, 0}},
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) b := NewDense(flatten(test.b))
b, err := NewDense(flatten(test.b)) r := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
r, err := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
temp := &Dense{} temp := &Dense{}
temp.Sub(a, b) temp.Sub(a, b)
@@ -395,12 +378,9 @@ func (s *S) TestMulElem(c *check.C) {
[][]float64{{1, 4, 9}, {16, 25, 36}}, [][]float64{{1, 4, 9}, {16, 25, 36}},
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) b := NewDense(flatten(test.b))
b, err := NewDense(flatten(test.b)) r := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
r, err := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
temp := &Dense{} temp := &Dense{}
temp.MulElem(a, b) temp.MulElem(a, b)
@@ -457,12 +437,9 @@ func (s *S) TestMul(c *check.C) {
[][]float64{{0, 2, 2}, {0, 2, 2}, {0, 2, 2}}, [][]float64{{0, 2, 2}, {0, 2, 2}, {0, 2, 2}},
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) b := NewDense(flatten(test.b))
b, err := NewDense(flatten(test.b)) r := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
r, err := NewDense(flatten(test.r))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
temp := &Dense{} temp := &Dense{}
temp.Mul(a, b) temp.Mul(a, b)
@@ -587,10 +564,8 @@ func (s *S) TestTranspose(c *check.C) {
[][]float64{{1, 4}, {2, 5}, {3, 6}}, [][]float64{{1, 4}, {2, 5}, {3, 6}},
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) t := NewDense(flatten(test.t))
t, err := NewDense(flatten(test.t))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
var r, rr Dense var r, rr Dense
@@ -652,8 +627,7 @@ func (s *S) TestNorm(c *check.C) {
norm: 6, norm: 6,
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
c.Check(a.Norm(test.ord), check.Equals, test.norm, check.Commentf("Test %d: %v norm = %f", i, test.a, test.norm)) c.Check(a.Norm(test.ord), check.Equals, test.norm, check.Commentf("Test %d: %v norm = %f", i, test.a, test.norm))
} }
} }
@@ -716,10 +690,8 @@ func (s *S) TestApply(c *check.C) {
}, },
}, },
} { } {
a, err := NewDense(flatten(test.a)) a := NewDense(flatten(test.a))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i)) t := NewDense(flatten(test.t))
t, err := NewDense(flatten(test.t))
c.Assert(err, check.Equals, nil, check.Commentf("Test %d", i))
var r Dense var r Dense

View File

@@ -80,7 +80,7 @@ func (f QRFactor) IsFullRank() bool {
func (f QRFactor) H() *Dense { func (f QRFactor) H() *Dense {
qr := f.QR qr := f.QR
m, n := qr.Dims() m, n := qr.Dims()
h, _ := NewDense(m, n, make([]float64, m*n)) h := NewDense(m, n, nil)
for i := 0; i < m; i++ { for i := 0; i < m; i++ {
for j := 0; j < n; j++ { for j := 0; j < n; j++ {
if i >= j { if i >= j {
@@ -95,7 +95,7 @@ func (f QRFactor) H() *Dense {
func (f QRFactor) R() *Dense { func (f QRFactor) R() *Dense {
qr, rDiag := f.QR, f.rDiag qr, rDiag := f.QR, f.rDiag
_, n := qr.Dims() _, n := qr.Dims()
r, _ := NewDense(n, n, make([]float64, n*n)) r := NewDense(n, n, nil)
for i, v := range rDiag[:n] { for i, v := range rDiag[:n] {
for j := 0; j < n; j++ { for j := 0; j < n; j++ {
if i < j { if i < j {
@@ -112,7 +112,7 @@ func (f QRFactor) R() *Dense {
func (f QRFactor) Q() *Dense { func (f QRFactor) Q() *Dense {
qr := f.QR qr := f.QR
m, n := qr.Dims() m, n := qr.Dims()
q, _ := NewDense(m, n, make([]float64, m*n)) q := NewDense(m, n, nil)
for k := n - 1; k >= 0; k-- { for k := n - 1; k >= 0; k-- {
// for i := 0; i < m; i++ { // for i := 0; i < m; i++ {

View File

@@ -13,7 +13,7 @@ func (s *S) TestQRD(c *check.C) {
a *Dense a *Dense
}{ }{
{ {
a: mustDense(NewDense(4, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12})), a: NewDense(4, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}),
}, },
} { } {
qf := QR(DenseCopyOf(t.a)) qf := QR(DenseCopyOf(t.a))

View File

@@ -40,10 +40,10 @@ func SVD(a *Dense, epsilon, small float64, wantu, wantv bool) SVDFactors {
nu := min(m, n) nu := min(m, n)
var u, v *Dense var u, v *Dense
if wantu { if wantu {
u, _ = NewDense(m, nu, make([]float64, m*nu)) u = NewDense(m, nu, nil)
} }
if wantv { if wantv {
v, _ = NewDense(n, n, make([]float64, n*n)) v = NewDense(n, n, nil)
} }
var ( var (
@@ -431,7 +431,7 @@ func SVD(a *Dense, epsilon, small float64, wantu, wantv bool) SVDFactors {
// S returns a newly allocated S matrix from the sigma values held by the // S returns a newly allocated S matrix from the sigma values held by the
// factorisation. // factorisation.
func (f SVDFactors) S() *Dense { func (f SVDFactors) S() *Dense {
s, _ := NewDense(len(f.Sigma), len(f.Sigma), make([]float64, len(f.Sigma)*len(f.Sigma))) s := NewDense(len(f.Sigma), len(f.Sigma), nil)
for i, v := range f.Sigma { for i, v := range f.Sigma {
s.Set(i, i, v) s.Set(i, i, v)
} }

View File

@@ -25,47 +25,47 @@ func (s *S) TestSVD(c *check.C) {
v *Dense v *Dense
}{ }{
{ {
a: mustDense(NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0})), a: NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0}),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
small: math.Pow(2, -966.0), small: math.Pow(2, -966.0),
wantu: true, wantu: true,
u: mustDense(NewDense(4, 2, []float64{ u: NewDense(4, 2, []float64{
0.8174155604703632, -0.5760484367663209, 0.8174155604703632, -0.5760484367663209,
0.5760484367663209, 0.8174155604703633, 0.5760484367663209, 0.8174155604703633,
0, 0, 0, 0,
0, 0, 0, 0,
})), }),
sigma: []float64{5.464985704219041, 0.365966190626258}, sigma: []float64{5.464985704219041, 0.365966190626258},
wantv: true, wantv: true,
v: mustDense(NewDense(2, 2, []float64{ v: NewDense(2, 2, []float64{
0.4045535848337571, -0.9145142956773044, 0.4045535848337571, -0.9145142956773044,
0.9145142956773044, 0.4045535848337571, 0.9145142956773044, 0.4045535848337571,
})), }),
}, },
{ {
a: mustDense(NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0})), a: NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0}),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
small: math.Pow(2, -966.0), small: math.Pow(2, -966.0),
wantu: true, wantu: true,
u: mustDense(NewDense(4, 2, []float64{ u: NewDense(4, 2, []float64{
0.8174155604703632, -0.5760484367663209, 0.8174155604703632, -0.5760484367663209,
0.5760484367663209, 0.8174155604703633, 0.5760484367663209, 0.8174155604703633,
0, 0, 0, 0,
0, 0, 0, 0,
})), }),
sigma: []float64{5.464985704219041, 0.365966190626258}, sigma: []float64{5.464985704219041, 0.365966190626258},
wantv: false, wantv: false,
}, },
{ {
a: mustDense(NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0})), a: NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0}),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
small: math.Pow(2, -966.0), small: math.Pow(2, -966.0),
@@ -75,13 +75,13 @@ func (s *S) TestSVD(c *check.C) {
sigma: []float64{5.464985704219041, 0.365966190626258}, sigma: []float64{5.464985704219041, 0.365966190626258},
wantv: true, wantv: true,
v: mustDense(NewDense(2, 2, []float64{ v: NewDense(2, 2, []float64{
0.4045535848337571, -0.9145142956773044, 0.4045535848337571, -0.9145142956773044,
0.9145142956773044, 0.4045535848337571, 0.9145142956773044, 0.4045535848337571,
})), }),
}, },
{ {
a: mustDense(NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0})), a: NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0}),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
small: math.Pow(2, -966.0), small: math.Pow(2, -966.0),
@@ -95,11 +95,11 @@ func (s *S) TestSVD(c *check.C) {
// forcing a to be a tall or square matrix. // forcing a to be a tall or square matrix.
// //
// This is a failing case to use to fix that bug. // This is a failing case to use to fix that bug.
a: mustDense(NewDense(3, 11, []float64{ a: NewDense(3, 11, []float64{
1, 1, 0, 1, 0, 0, 0, 0, 0, 11, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 11, 1,
1, 0, 0, 0, 0, 0, 1, 0, 0, 12, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 12, 2,
1, 1, 0, 0, 0, 0, 0, 0, 1, 13, 3, 1, 1, 0, 0, 0, 0, 0, 0, 1, 13, 3,
})), }),
epsilon: math.Pow(2, -52.0), epsilon: math.Pow(2, -52.0),
small: math.Pow(2, -966.0), small: math.Pow(2, -966.0),