Add test for Norm

Norm(±2) is, not surprisingly, difficult to pin down. The expected
values here agree with numpy well for Norm(2), less will with MATLAB
and the expectation for Norm(-2) is a fair amount (FWIW at this
magnitude) away from the numpy and MATLAB values which agree quite
well with each other.
This commit is contained in:
kortschak
2013-11-20 09:53:11 +10:30
parent 01d2d8774d
commit 172ec6bf55
2 changed files with 53 additions and 2 deletions

View File

@@ -263,7 +263,10 @@ func (m *Dense) Trace() float64 {
var inf = math.Inf(1) var inf = math.Inf(1)
const epsilon = 2.2204e-16 const (
epsilon = 2.2204e-16
small = math.SmallestNonzeroFloat64
)
// Norm(±2) depends on SVD, and so m must be tall or square. // Norm(±2) depends on SVD, and so m must be tall or square.
func (m *Dense) Norm(ord float64) float64 { func (m *Dense) Norm(ord float64) float64 {
@@ -315,7 +318,7 @@ func (m *Dense) Norm(ord float64) float64 {
} }
return math.Sqrt(n) return math.Sqrt(n)
case ord == 2, ord == -2: case ord == 2, ord == -2:
s := SVD(m, epsilon, math.SmallestNonzeroFloat64, false, false).Sigma s := SVD(m, epsilon, small, false, false).Sigma
if ord == 2 { if ord == 2 {
return s[0] return s[0]
} }

View File

@@ -610,6 +610,54 @@ func (s *S) TestTranspose(c *check.C) {
} }
} }
func (s *S) TestNorm(c *check.C) {
for i, test := range []struct {
a [][]float64
ord float64
norm float64
}{
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: 0,
norm: 25.495097567963924,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: 1,
norm: 30,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: -1,
norm: 22,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: 2,
norm: 25.46240743603639,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: -2,
norm: 9.013990486603544e-16,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: inf,
norm: 33,
},
{
a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}},
ord: -inf,
norm: 6,
},
} {
a, err := 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))
}
}
func identity(r, c int, v float64) float64 { return v } func identity(r, c int, v float64) float64 { return v }
func (s *S) TestApply(c *check.C) { func (s *S) TestApply(c *check.C) {