1 // Copyright ©2015 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
11 "golang.org/x/exp/rand"
13 "gonum.org/v1/gonum/blas"
14 "gonum.org/v1/gonum/blas/blas64"
15 "gonum.org/v1/gonum/floats"
18 type Dgeqr2er interface {
19 Dgeqr2(m, n int, a []float64, lda int, tau []float64, work []float64)
22 func Dgeqr2Test(t *testing.T, impl Dgeqr2er) {
23 rnd := rand.New(rand.NewSource(1))
24 for c, test := range []struct {
54 a := make([]float64, m*lda)
58 aCopy := make([]float64, len(a))
60 tau := make([]float64, k)
62 tau[i] = rnd.Float64()
64 work := make([]float64, n)
66 work[i] = rnd.Float64()
69 impl.Dgeqr2(m, n, a, lda, tau, work)
71 // Test that the QR factorization has completed successfully. Compute
72 // Q based on the vectors.
73 q := constructQ("QR", m, n, a, lda, tau)
75 // Check that q is orthonormal
76 for i := 0; i < m; i++ {
77 nrm := blas64.Nrm2(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]})
78 if math.Abs(nrm-1) > 1e-14 {
79 t.Errorf("Case %v, q not normal", c)
81 for j := 0; j < i; j++ {
82 dot := blas64.Dot(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]}, blas64.Vector{Inc: 1, Data: q.Data[j*m:]})
83 if math.Abs(dot) > 1e-14 {
84 t.Errorf("Case %v, q not orthogonal", c)
88 // Check that A = Q * R
93 Data: make([]float64, m*n),
95 for i := 0; i < m; i++ {
96 for j := i; j < n; j++ {
97 r.Data[i*n+j] = a[i*lda+j]
100 atmp := blas64.General{
104 Data: make([]float64, m*lda),
107 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, atmp)
108 if !floats.EqualApprox(atmp.Data, aCopy, 1e-14) {