From 172ec6bf55793cadd1af62ced1fc23eb834c01fe Mon Sep 17 00:00:00 2001 From: kortschak Date: Wed, 20 Nov 2013 09:53:11 +1030 Subject: [PATCH] Add test for Norm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- mat64/dense.go | 7 +++++-- mat64/matrix_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/mat64/dense.go b/mat64/dense.go index 620cccff..7b45bee8 100644 --- a/mat64/dense.go +++ b/mat64/dense.go @@ -263,7 +263,10 @@ func (m *Dense) Trace() float64 { 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. func (m *Dense) Norm(ord float64) float64 { @@ -315,7 +318,7 @@ func (m *Dense) Norm(ord float64) float64 { } return math.Sqrt(n) 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 { return s[0] } diff --git a/mat64/matrix_test.go b/mat64/matrix_test.go index 4aa63add..b4d0a15d 100644 --- a/mat64/matrix_test.go +++ b/mat64/matrix_test.go @@ -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 (s *S) TestApply(c *check.C) {