mirror of
https://github.com/gonum/gonum.git
synced 2025-10-09 09:00:38 +08:00
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
// 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 mat64
|
|
|
|
import (
|
|
check "launchpad.net/gocheck"
|
|
"math"
|
|
|
|
"github.com/gonum/floats"
|
|
)
|
|
|
|
func isUpperTriangular(a *Dense) bool {
|
|
rows, cols := a.Dims()
|
|
for c := 0; c < cols-1; c++ {
|
|
for r := c + 1; r < rows; r++ {
|
|
if math.Abs(a.At(r, c)) > 1e-14 {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func isOrthogonal(a *Dense) bool {
|
|
rows, cols := a.Dims()
|
|
col1 := make([]float64, rows)
|
|
col2 := make([]float64, rows)
|
|
for i := 0; i < cols-1; i++ {
|
|
for j := i + 1; j < cols; j++ {
|
|
a.Col(col1, i)
|
|
a.Col(col2, j)
|
|
dot := floats.Dot(col1, col2)
|
|
if math.Abs(dot) > 1e-14 {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (s *S) TestQRD(c *check.C) {
|
|
for _, test := range []struct {
|
|
a [][]float64
|
|
name string
|
|
}{
|
|
{
|
|
name: "Square",
|
|
a: [][]float64{
|
|
{1.3, 2.4, 8.9},
|
|
{-2.6, 8.7, 9.1},
|
|
{5.6, 5.8, 2.1},
|
|
},
|
|
},
|
|
{
|
|
name: "Skinny",
|
|
a: [][]float64{
|
|
{1.3, 2.4, 8.9},
|
|
{-2.6, 8.7, 9.1},
|
|
{5.6, 5.8, 2.1},
|
|
{19.4, 5.2, -26.1},
|
|
},
|
|
},
|
|
} {
|
|
|
|
a := NewDense(flatten(test.a))
|
|
qf := QR(DenseCopyOf(a))
|
|
r := qf.R()
|
|
q := qf.Q()
|
|
|
|
rows, cols := a.Dims()
|
|
newA := NewDense(rows, cols, nil)
|
|
newA.Mul(q, r)
|
|
|
|
c.Check(isOrthogonal(q), check.Equals, true, check.Commentf("Test %v: Q not orthogonal", test.name))
|
|
c.Check(isUpperTriangular(r), check.Equals, true, check.Commentf("Test %v: R not upper triangular", test.name))
|
|
c.Check(a.EqualsApprox(newA, 1e-13), check.Equals, true, check.Commentf("Test %v: Q*R != A", test.name))
|
|
}
|
|
}
|