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"
17 type Dgerq2er interface {
18 Dgerq2(m, n int, a []float64, lda int, tau []float64, work []float64)
21 func Dgerq2Test(t *testing.T, impl Dgerq2er) {
22 rnd := rand.New(rand.NewSource(1))
23 for c, test := range []struct {
53 a := make([]float64, m*lda)
57 aCopy := make([]float64, len(a))
59 tau := make([]float64, k)
61 tau[i] = rnd.Float64()
63 work := make([]float64, m)
65 work[i] = rnd.Float64()
68 impl.Dgerq2(m, n, a, lda, tau, work)
70 // Test that the RQ factorization has completed successfully. Compute
71 // Q based on the vectors.
72 q := constructQ("RQ", m, n, a, lda, tau)
74 // Check that q is orthonormal
75 for i := 0; i < q.Rows; i++ {
76 nrm := blas64.Nrm2(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]})
77 if math.IsNaN(nrm) || math.Abs(nrm-1) > 1e-14 {
78 t.Errorf("Case %v, q not normal", c)
80 for j := 0; j < i; j++ {
81 dot := blas64.Dot(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}, blas64.Vector{Inc: 1, Data: q.Data[j*q.Stride:]})
82 if math.IsNaN(dot) || math.Abs(dot) > 1e-14 {
83 t.Errorf("Case %v, q not orthogonal", c)
87 // Check that A = R * Q
92 Data: make([]float64, m*n),
94 for i := 0; i < m; i++ {
96 for j := max(0, i-off); j < n; j++ {
97 r.Data[i*r.Stride+j] = a[i*lda+j]
101 got := blas64.General{
105 Data: make([]float64, m*lda),
107 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, r, q, 0, got)
108 want := blas64.General{
114 if !equalApproxGeneral(got, want, 1e-14) {
115 t.Errorf("Case %d, R*Q != a\ngot: %+v\nwant:%+v", c, got, want)