gonum.org/v1/gonum@v0.14.0/lapack/testlapack/dgelq2.go (about) 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. 4 5 package testlapack 6 7 import ( 8 "testing" 9 10 "golang.org/x/exp/rand" 11 12 "gonum.org/v1/gonum/blas" 13 "gonum.org/v1/gonum/blas/blas64" 14 "gonum.org/v1/gonum/floats" 15 ) 16 17 type Dgelq2er interface { 18 Dgelq2(m, n int, a []float64, lda int, tau, work []float64) 19 } 20 21 func Dgelq2Test(t *testing.T, impl Dgelq2er) { 22 const tol = 1e-14 23 24 rnd := rand.New(rand.NewSource(1)) 25 for c, test := range []struct { 26 m, n, lda int 27 }{ 28 {1, 1, 0}, 29 {2, 2, 0}, 30 {3, 2, 0}, 31 {2, 3, 0}, 32 {1, 12, 0}, 33 {2, 6, 0}, 34 {3, 4, 0}, 35 {4, 3, 0}, 36 {6, 2, 0}, 37 {1, 12, 0}, 38 {1, 1, 20}, 39 {2, 2, 20}, 40 {3, 2, 20}, 41 {2, 3, 20}, 42 {1, 12, 20}, 43 {2, 6, 20}, 44 {3, 4, 20}, 45 {4, 3, 20}, 46 {6, 2, 20}, 47 {1, 12, 20}, 48 } { 49 n := test.n 50 m := test.m 51 lda := test.lda 52 if lda == 0 { 53 lda = test.n 54 } 55 k := min(m, n) 56 tau := make([]float64, k) 57 for i := range tau { 58 tau[i] = rnd.Float64() 59 } 60 work := make([]float64, m) 61 for i := range work { 62 work[i] = rnd.Float64() 63 } 64 a := make([]float64, m*lda) 65 for i := 0; i < m*lda; i++ { 66 a[i] = rnd.Float64() 67 } 68 aCopy := make([]float64, len(a)) 69 copy(aCopy, a) 70 impl.Dgelq2(m, n, a, lda, tau, work) 71 72 Q := constructQ("LQ", m, n, a, lda, tau) 73 74 // Check that Q is orthogonal. 75 if resid := residualOrthogonal(Q, false); resid > tol { 76 t.Errorf("Case %v: Q not orthogonal; resid=%v, want<=%v", c, resid, tol) 77 } 78 79 L := blas64.General{ 80 Rows: m, 81 Cols: n, 82 Stride: n, 83 Data: make([]float64, m*n), 84 } 85 for i := 0; i < m; i++ { 86 for j := 0; j <= min(i, n-1); j++ { 87 L.Data[i*L.Stride+j] = a[i*lda+j] 88 } 89 } 90 91 ans := blas64.General{ 92 Rows: m, 93 Cols: n, 94 Stride: lda, 95 Data: make([]float64, m*lda), 96 } 97 copy(ans.Data, aCopy) 98 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, L, Q, 0, ans) 99 if !floats.EqualApprox(aCopy, ans.Data, tol) { 100 t.Errorf("Case %v, LQ mismatch. Want %v, got %v.", c, aCopy, ans.Data) 101 } 102 } 103 }