OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / mat / cholesky_test.go
diff --git a/vendor/gonum.org/v1/gonum/mat/cholesky_test.go b/vendor/gonum.org/v1/gonum/mat/cholesky_test.go
deleted file mode 100644 (file)
index 65eeed0..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-// Copyright ©2013 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 mat
-
-import (
-       "math"
-       "testing"
-
-       "golang.org/x/exp/rand"
-
-       "gonum.org/v1/gonum/blas/testblas"
-       "gonum.org/v1/gonum/floats"
-)
-
-func TestCholesky(t *testing.T) {
-       for _, test := range []struct {
-               a *SymDense
-
-               cond   float64
-               want   *TriDense
-               posdef bool
-       }{
-               {
-                       a: NewSymDense(3, []float64{
-                               4, 1, 1,
-                               0, 2, 3,
-                               0, 0, 6,
-                       }),
-                       cond: 37,
-                       want: NewTriDense(3, true, []float64{
-                               2, 0.5, 0.5,
-                               0, 1.3228756555322954, 2.0788046015507495,
-                               0, 0, 1.195228609334394,
-                       }),
-                       posdef: true,
-               },
-       } {
-               _, n := test.a.Dims()
-               for _, chol := range []*Cholesky{
-                       {},
-                       {chol: NewTriDense(n-1, true, nil)},
-                       {chol: NewTriDense(n, true, nil)},
-                       {chol: NewTriDense(n+1, true, nil)},
-               } {
-                       ok := chol.Factorize(test.a)
-                       if ok != test.posdef {
-                               t.Errorf("unexpected return from Cholesky factorization: got: ok=%t want: ok=%t", ok, test.posdef)
-                       }
-                       fc := DenseCopyOf(chol.chol)
-                       if !Equal(fc, test.want) {
-                               t.Error("incorrect Cholesky factorization")
-                       }
-                       if math.Abs(test.cond-chol.cond) > 1e-13 {
-                               t.Errorf("Condition number mismatch: Want %v, got %v", test.cond, chol.cond)
-                       }
-                       U := chol.UTo(nil)
-                       aCopy := DenseCopyOf(test.a)
-                       var a Dense
-                       a.Mul(U.TTri(), U)
-                       if !EqualApprox(&a, aCopy, 1e-14) {
-                               t.Error("unexpected Cholesky factor product")
-                       }
-
-                       L := chol.LTo(nil)
-                       a.Mul(L, L.TTri())
-                       if !EqualApprox(&a, aCopy, 1e-14) {
-                               t.Error("unexpected Cholesky factor product")
-                       }
-               }
-       }
-}
-
-func TestCholeskySolve(t *testing.T) {
-       for _, test := range []struct {
-               a   *SymDense
-               b   *Dense
-               ans *Dense
-       }{
-               {
-                       a: NewSymDense(2, []float64{
-                               1, 0,
-                               0, 1,
-                       }),
-                       b:   NewDense(2, 1, []float64{5, 6}),
-                       ans: NewDense(2, 1, []float64{5, 6}),
-               },
-               {
-                       a: NewSymDense(3, []float64{
-                               53, 59, 37,
-                               0, 83, 71,
-                               37, 71, 101,
-                       }),
-                       b:   NewDense(3, 1, []float64{5, 6, 7}),
-                       ans: NewDense(3, 1, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
-               },
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test.a)
-               if !ok {
-                       t.Fatal("unexpected Cholesky factorization failure: not positive definite")
-               }
-
-               var x Dense
-               chol.Solve(&x, test.b)
-               if !EqualApprox(&x, test.ans, 1e-12) {
-                       t.Error("incorrect Cholesky solve solution")
-               }
-
-               var ans Dense
-               ans.Mul(test.a, &x)
-               if !EqualApprox(&ans, test.b, 1e-12) {
-                       t.Error("incorrect Cholesky solve solution product")
-               }
-       }
-}
-
-func TestCholeskySolveChol(t *testing.T) {
-       for _, test := range []struct {
-               a, b *SymDense
-       }{
-               {
-                       a: NewSymDense(2, []float64{
-                               1, 0,
-                               0, 1,
-                       }),
-                       b: NewSymDense(2, []float64{
-                               1, 0,
-                               0, 1,
-                       }),
-               },
-               {
-                       a: NewSymDense(2, []float64{
-                               1, 0,
-                               0, 1,
-                       }),
-                       b: NewSymDense(2, []float64{
-                               2, 0,
-                               0, 2,
-                       }),
-               },
-               {
-                       a: NewSymDense(3, []float64{
-                               53, 59, 37,
-                               59, 83, 71,
-                               37, 71, 101,
-                       }),
-                       b: NewSymDense(3, []float64{
-                               2, -1, 0,
-                               -1, 2, -1,
-                               0, -1, 2,
-                       }),
-               },
-       } {
-               var chola, cholb Cholesky
-               ok := chola.Factorize(test.a)
-               if !ok {
-                       t.Fatal("unexpected Cholesky factorization failure for a: not positive definite")
-               }
-               ok = cholb.Factorize(test.b)
-               if !ok {
-                       t.Fatal("unexpected Cholesky factorization failure for b: not positive definite")
-               }
-
-               var x Dense
-               chola.SolveChol(&x, &cholb)
-
-               var ans Dense
-               ans.Mul(test.a, &x)
-               if !EqualApprox(&ans, test.b, 1e-12) {
-                       var y Dense
-                       y.Solve(test.a, test.b)
-                       t.Errorf("incorrect Cholesky solve solution product\ngot solution:\n%.4v\nwant solution\n%.4v",
-                               Formatted(&x), Formatted(&y))
-               }
-       }
-}
-
-func TestCholeskySolveVec(t *testing.T) {
-       for _, test := range []struct {
-               a   *SymDense
-               b   *VecDense
-               ans *VecDense
-       }{
-               {
-                       a: NewSymDense(2, []float64{
-                               1, 0,
-                               0, 1,
-                       }),
-                       b:   NewVecDense(2, []float64{5, 6}),
-                       ans: NewVecDense(2, []float64{5, 6}),
-               },
-               {
-                       a: NewSymDense(3, []float64{
-                               53, 59, 37,
-                               0, 83, 71,
-                               0, 0, 101,
-                       }),
-                       b:   NewVecDense(3, []float64{5, 6, 7}),
-                       ans: NewVecDense(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}),
-               },
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test.a)
-               if !ok {
-                       t.Fatal("unexpected Cholesky factorization failure: not positive definite")
-               }
-
-               var x VecDense
-               chol.SolveVec(&x, test.b)
-               if !EqualApprox(&x, test.ans, 1e-12) {
-                       t.Error("incorrect Cholesky solve solution")
-               }
-
-               var ans VecDense
-               ans.MulVec(test.a, &x)
-               if !EqualApprox(&ans, test.b, 1e-12) {
-                       t.Error("incorrect Cholesky solve solution product")
-               }
-       }
-}
-
-func TestCholeskyToSym(t *testing.T) {
-       for _, test := range []*SymDense{
-               NewSymDense(3, []float64{
-                       53, 59, 37,
-                       0, 83, 71,
-                       0, 0, 101,
-               }),
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test)
-               if !ok {
-                       t.Fatal("unexpected Cholesky factorization failure: not positive definite")
-               }
-               s := chol.ToSym(nil)
-
-               if !EqualApprox(s, test, 1e-12) {
-                       t.Errorf("Cholesky reconstruction not equal to original matrix.\nWant:\n% v\nGot:\n% v\n", Formatted(test), Formatted(s))
-               }
-       }
-}
-
-func TestCloneCholesky(t *testing.T) {
-       for _, test := range []*SymDense{
-               NewSymDense(3, []float64{
-                       53, 59, 37,
-                       0, 83, 71,
-                       0, 0, 101,
-               }),
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test)
-               if !ok {
-                       panic("bad test")
-               }
-               var chol2 Cholesky
-               chol2.Clone(&chol)
-
-               if chol.cond != chol2.cond {
-                       t.Errorf("condition number mismatch from zero")
-               }
-               if !Equal(chol.chol, chol2.chol) {
-                       t.Errorf("chol mismatch from zero")
-               }
-
-               // Corrupt chol2 and try again
-               chol2.cond = math.NaN()
-               chol2.chol = NewTriDense(2, Upper, nil)
-               chol2.Clone(&chol)
-               if chol.cond != chol2.cond {
-                       t.Errorf("condition number mismatch from non-zero")
-               }
-               if !Equal(chol.chol, chol2.chol) {
-                       t.Errorf("chol mismatch from non-zero")
-               }
-       }
-}
-
-func TestCholeskyInverseTo(t *testing.T) {
-       for _, n := range []int{1, 3, 5, 9} {
-               data := make([]float64, n*n)
-               for i := range data {
-                       data[i] = rand.NormFloat64()
-               }
-               var s SymDense
-               s.SymOuterK(1, NewDense(n, n, data))
-
-               var chol Cholesky
-               ok := chol.Factorize(&s)
-               if !ok {
-                       t.Errorf("Bad test, cholesky decomposition failed")
-               }
-
-               var sInv SymDense
-               chol.InverseTo(&sInv)
-
-               var ans Dense
-               ans.Mul(&sInv, &s)
-               if !equalApprox(eye(n), &ans, 1e-8, false) {
-                       var diff Dense
-                       diff.Sub(eye(n), &ans)
-                       t.Errorf("SymDense times Cholesky inverse not identity. Norm diff = %v", Norm(&diff, 2))
-               }
-       }
-}
-
-func TestCholeskySymRankOne(t *testing.T) {
-       rand.Seed(1)
-       for _, n := range []int{1, 2, 3, 4, 5, 7, 10, 20, 50, 100} {
-               for k := 0; k < 10; k++ {
-                       data := make([]float64, n*n)
-                       for i := range data {
-                               data[i] = rand.NormFloat64()
-                       }
-
-                       var a SymDense
-                       a.SymOuterK(1, NewDense(n, n, data))
-
-                       xdata := make([]float64, n)
-                       for i := range xdata {
-                               xdata[i] = rand.NormFloat64()
-                       }
-                       x := NewVecDense(n, xdata)
-
-                       var chol Cholesky
-                       ok := chol.Factorize(&a)
-                       if !ok {
-                               t.Errorf("Bad random test, Cholesky factorization failed")
-                               continue
-                       }
-
-                       alpha := rand.Float64()
-                       ok = chol.SymRankOne(&chol, alpha, x)
-                       if !ok {
-                               t.Errorf("n=%v, alpha=%v: unexpected failure", n, alpha)
-                               continue
-                       }
-                       a.SymRankOne(&a, alpha, x)
-
-                       var achol SymDense
-                       chol.ToSym(&achol)
-                       if !EqualApprox(&achol, &a, 1e-13) {
-                               t.Errorf("n=%v, alpha=%v: mismatch between updated matrix and from Cholesky:\nupdated:\n%v\nfrom Cholesky:\n%v",
-                                       n, alpha, Formatted(&a), Formatted(&achol))
-                       }
-               }
-       }
-
-       for i, test := range []struct {
-               a     *SymDense
-               alpha float64
-               x     []float64
-
-               wantOk bool
-       }{
-               {
-                       // Update (to positive definite matrix).
-                       a: NewSymDense(4, []float64{
-                               1, 1, 1, 1,
-                               0, 2, 3, 4,
-                               0, 0, 6, 10,
-                               0, 0, 0, 20,
-                       }),
-                       alpha:  1,
-                       x:      []float64{0, 0, 0, 1},
-                       wantOk: true,
-               },
-               {
-                       // Downdate to singular matrix.
-                       a: NewSymDense(4, []float64{
-                               1, 1, 1, 1,
-                               0, 2, 3, 4,
-                               0, 0, 6, 10,
-                               0, 0, 0, 20,
-                       }),
-                       alpha:  -1,
-                       x:      []float64{0, 0, 0, 1},
-                       wantOk: false,
-               },
-               {
-                       // Downdate to positive definite matrix.
-                       a: NewSymDense(4, []float64{
-                               1, 1, 1, 1,
-                               0, 2, 3, 4,
-                               0, 0, 6, 10,
-                               0, 0, 0, 20,
-                       }),
-                       alpha:  -1 / 2,
-                       x:      []float64{0, 0, 0, 1},
-                       wantOk: true,
-               },
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test.a)
-               if !ok {
-                       t.Errorf("Case %v: bad test, Cholesky factorization failed", i)
-                       continue
-               }
-
-               x := NewVecDense(len(test.x), test.x)
-               ok = chol.SymRankOne(&chol, test.alpha, x)
-               if !ok {
-                       if test.wantOk {
-                               t.Errorf("Case %v: unexpected failure from SymRankOne", i)
-                       }
-                       continue
-               }
-               if ok && !test.wantOk {
-                       t.Errorf("Case %v: expected a failure from SymRankOne", i)
-               }
-
-               a := test.a
-               a.SymRankOne(a, test.alpha, x)
-
-               var achol SymDense
-               chol.ToSym(&achol)
-               if !EqualApprox(&achol, a, 1e-13) {
-                       t.Errorf("Case %v: mismatch between updated matrix and from Cholesky:\nupdated:\n%v\nfrom Cholesky:\n%v",
-                               i, Formatted(a), Formatted(&achol))
-               }
-       }
-}
-
-func TestCholeskyExtendVecSym(t *testing.T) {
-       for cas, test := range []struct {
-               a *SymDense
-       }{
-               {
-                       a: NewSymDense(3, []float64{
-                               4, 1, 1,
-                               0, 2, 3,
-                               0, 0, 6,
-                       }),
-               },
-       } {
-               n := test.a.Symmetric()
-               as := test.a.SliceSquare(0, n-1).(*SymDense)
-
-               // Compute the full factorization to use later (do the full factorization
-               // first to ensure the matrix is positive definite).
-               var cholFull Cholesky
-               ok := cholFull.Factorize(test.a)
-               if !ok {
-                       panic("mat: bad test, matrix not positive definite")
-               }
-
-               var chol Cholesky
-               ok = chol.Factorize(as)
-               if !ok {
-                       panic("mat: bad test, subset is not positive definite")
-               }
-               row := NewVecDense(n, nil)
-               for i := 0; i < n; i++ {
-                       row.SetVec(i, test.a.At(n-1, i))
-               }
-
-               var cholNew Cholesky
-               ok = cholNew.ExtendVecSym(&chol, row)
-               if !ok {
-                       t.Errorf("cas %v: update not positive definite", cas)
-               }
-               a := cholNew.ToSym(nil)
-               if !EqualApprox(a, test.a, 1e-12) {
-                       t.Errorf("cas %v: mismatch", cas)
-               }
-
-               // test in-place
-               ok = chol.ExtendVecSym(&chol, row)
-               if !ok {
-                       t.Errorf("cas %v: in-place update not positive definite", cas)
-               }
-               if !equalChol(&chol, &cholNew) {
-                       t.Errorf("cas %v: Cholesky different in-place vs. new", cas)
-               }
-
-               // Test that the factorization is about right compared with the direct
-               // full factorization. Use a high tolerance on the condition number
-               // since the condition number with the updated rule is approximate.
-               if !equalApproxChol(&chol, &cholFull, 1e-12, 0.3) {
-                       t.Errorf("cas %v: updated Cholesky does not match full", cas)
-               }
-       }
-}
-
-func TestCholeskyScale(t *testing.T) {
-       for cas, test := range []struct {
-               a *SymDense
-               f float64
-       }{
-               {
-                       a: NewSymDense(3, []float64{
-                               4, 1, 1,
-                               0, 2, 3,
-                               0, 0, 6,
-                       }),
-                       f: 0.5,
-               },
-       } {
-               var chol Cholesky
-               ok := chol.Factorize(test.a)
-               if !ok {
-                       t.Errorf("Case %v: bad test, Cholesky factorization failed", cas)
-                       continue
-               }
-
-               // Compare the update to a new Cholesky to an update in-place.
-               var cholUpdate Cholesky
-               cholUpdate.Scale(test.f, &chol)
-               chol.Scale(test.f, &chol)
-               if !equalChol(&chol, &cholUpdate) {
-                       t.Errorf("Case %d: cholesky mismatch new receiver", cas)
-               }
-               var sym SymDense
-               chol.ToSym(&sym)
-               var comp SymDense
-               comp.ScaleSym(test.f, test.a)
-               if !EqualApprox(&comp, &sym, 1e-14) {
-                       t.Errorf("Case %d: cholesky reconstruction doesn't match scaled matrix", cas)
-               }
-
-               var cholTest Cholesky
-               cholTest.Factorize(&comp)
-               if !equalApproxChol(&cholTest, &chol, 1e-12, 1e-12) {
-                       t.Errorf("Case %d: cholesky mismatch with scaled matrix. %v, %v", cas, cholTest.cond, chol.cond)
-               }
-       }
-}
-
-// equalApproxChol checks that the two Cholesky decompositions are equal.
-func equalChol(a, b *Cholesky) bool {
-       return Equal(a.chol, b.chol) && a.cond == b.cond
-}
-
-// equalApproxChol checks that the two Cholesky decompositions are approximately
-// the same with the given tolerance on equality for the Triangular component and
-// condition.
-func equalApproxChol(a, b *Cholesky, matTol, condTol float64) bool {
-       if !EqualApprox(a.chol, b.chol, matTol) {
-               return false
-       }
-       return floats.EqualWithinAbsOrRel(a.cond, b.cond, condTol, condTol)
-}
-
-func BenchmarkCholeskySmall(b *testing.B) {
-       benchmarkCholesky(b, 2)
-}
-
-func BenchmarkCholeskyMedium(b *testing.B) {
-       benchmarkCholesky(b, testblas.MediumMat)
-}
-
-func BenchmarkCholeskyLarge(b *testing.B) {
-       benchmarkCholesky(b, testblas.LargeMat)
-}
-
-func benchmarkCholesky(b *testing.B, n int) {
-       base := make([]float64, n*n)
-       for i := range base {
-               base[i] = rand.Float64()
-       }
-       bm := NewDense(n, n, base)
-       bm.Mul(bm.T(), bm)
-       am := NewSymDense(n, bm.mat.Data)
-
-       var chol Cholesky
-       b.ResetTimer()
-       for i := 0; i < b.N; i++ {
-               ok := chol.Factorize(am)
-               if !ok {
-                       panic("not pos def")
-               }
-       }
-}