gonum.org/v1/gonum@v0.14.0/lapack/testlapack/dlarfb.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 "gonum.org/v1/gonum/lapack" 16 ) 17 18 type Dlarfber interface { 19 Dlarfter 20 Dlarfb(side blas.Side, trans blas.Transpose, direct lapack.Direct, 21 store lapack.StoreV, m, n, k int, v []float64, ldv int, t []float64, ldt int, 22 c []float64, ldc int, work []float64, ldwork int) 23 } 24 25 func DlarfbTest(t *testing.T, impl Dlarfber) { 26 rnd := rand.New(rand.NewSource(1)) 27 for _, store := range []lapack.StoreV{lapack.ColumnWise, lapack.RowWise} { 28 for _, direct := range []lapack.Direct{lapack.Forward, lapack.Backward} { 29 for _, side := range []blas.Side{blas.Left, blas.Right} { 30 for _, trans := range []blas.Transpose{blas.Trans, blas.NoTrans} { 31 for cas, test := range []struct { 32 ma, na, cdim, lda, ldt, ldc int 33 }{ 34 {6, 6, 6, 0, 0, 0}, 35 {6, 8, 10, 0, 0, 0}, 36 {6, 10, 8, 0, 0, 0}, 37 {8, 6, 10, 0, 0, 0}, 38 {8, 10, 6, 0, 0, 0}, 39 {10, 6, 8, 0, 0, 0}, 40 {10, 8, 6, 0, 0, 0}, 41 {6, 6, 6, 12, 15, 30}, 42 {6, 8, 10, 12, 15, 30}, 43 {6, 10, 8, 12, 15, 30}, 44 {8, 6, 10, 12, 15, 30}, 45 {8, 10, 6, 12, 15, 30}, 46 {10, 6, 8, 12, 15, 30}, 47 {10, 8, 6, 12, 15, 30}, 48 {6, 6, 6, 15, 12, 30}, 49 {6, 8, 10, 15, 12, 30}, 50 {6, 10, 8, 15, 12, 30}, 51 {8, 6, 10, 15, 12, 30}, 52 {8, 10, 6, 15, 12, 30}, 53 {10, 6, 8, 15, 12, 30}, 54 {10, 8, 6, 15, 12, 30}, 55 } { 56 // Generate a matrix for QR 57 ma := test.ma 58 na := test.na 59 lda := test.lda 60 if lda == 0 { 61 lda = na 62 } 63 a := make([]float64, ma*lda) 64 for i := 0; i < ma; i++ { 65 for j := 0; j < lda; j++ { 66 a[i*lda+j] = rnd.Float64() 67 } 68 } 69 k := min(ma, na) 70 71 // H is always ma x ma 72 var m, n, rowsWork int 73 switch { 74 default: 75 panic("not implemented") 76 case side == blas.Left: 77 m = test.ma 78 n = test.cdim 79 rowsWork = n 80 case side == blas.Right: 81 m = test.cdim 82 n = test.ma 83 rowsWork = m 84 } 85 86 // Use dgeqr2 to find the v vectors 87 tau := make([]float64, na) 88 work := make([]float64, na) 89 impl.Dgeqr2(ma, k, a, lda, tau, work) 90 91 // Correct the v vectors based on the direct and store 92 vMatTmp := extractVMat(ma, na, a, lda, lapack.Forward, lapack.ColumnWise) 93 vMat := constructVMat(vMatTmp, store, direct) 94 v := vMat.Data 95 ldv := vMat.Stride 96 97 // Use dlarft to find the t vector 98 ldt := test.ldt 99 if ldt == 0 { 100 ldt = k 101 } 102 tm := make([]float64, k*ldt) 103 104 impl.Dlarft(direct, store, ma, k, v, ldv, tau, tm, ldt) 105 106 // Generate c matrix 107 ldc := test.ldc 108 if ldc == 0 { 109 ldc = n 110 } 111 c := make([]float64, m*ldc) 112 for i := 0; i < m; i++ { 113 for j := 0; j < ldc; j++ { 114 c[i*ldc+j] = rnd.Float64() 115 } 116 } 117 cCopy := make([]float64, len(c)) 118 copy(cCopy, c) 119 120 ldwork := k 121 work = make([]float64, rowsWork*k) 122 123 // Call Dlarfb with this information 124 impl.Dlarfb(side, trans, direct, store, m, n, k, v, ldv, tm, ldt, c, ldc, work, ldwork) 125 126 h := constructH(tau, vMat, store, direct) 127 128 cMat := blas64.General{ 129 Rows: m, 130 Cols: n, 131 Stride: ldc, 132 Data: make([]float64, m*ldc), 133 } 134 copy(cMat.Data, cCopy) 135 ans := blas64.General{ 136 Rows: m, 137 Cols: n, 138 Stride: ldc, 139 Data: make([]float64, m*ldc), 140 } 141 copy(ans.Data, cMat.Data) 142 switch { 143 default: 144 panic("not implemented") 145 case side == blas.Left && trans == blas.NoTrans: 146 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, cMat, 0, ans) 147 case side == blas.Left && trans == blas.Trans: 148 blas64.Gemm(blas.Trans, blas.NoTrans, 1, h, cMat, 0, ans) 149 case side == blas.Right && trans == blas.NoTrans: 150 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMat, h, 0, ans) 151 case side == blas.Right && trans == blas.Trans: 152 blas64.Gemm(blas.NoTrans, blas.Trans, 1, cMat, h, 0, ans) 153 } 154 if !floats.EqualApprox(ans.Data, c, 1e-14) { 155 t.Errorf("Cas %v mismatch. Want %v, got %v.", cas, ans.Data, c) 156 } 157 } 158 } 159 } 160 } 161 } 162 }