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.
10 "golang.org/x/exp/rand"
12 "gonum.org/v1/gonum/blas"
13 "gonum.org/v1/gonum/blas/blas64"
14 "gonum.org/v1/gonum/floats"
17 type Dlarfer interface {
18 Dlarf(side blas.Side, m, n int, v []float64, incv int, tau float64, c []float64, ldc int, work []float64)
21 func DlarfTest(t *testing.T, impl Dlarfer) {
22 rnd := rand.New(rand.NewSource(1))
23 for i, test := range []struct {
95 // Construct a random matrix.
96 c := make([]float64, test.ldc*test.m)
97 for i := 0; i <= test.lastr; i++ {
98 for j := 0; j <= test.lastc; j++ {
99 c[i*test.ldc+j] = rnd.Float64()
102 cCopy := make([]float64, len(c))
104 cCopy2 := make([]float64, len(c))
107 // Test with side right.
108 sz := max(test.m, test.n) // so v works for both right and left side.
109 v := make([]float64, test.incv*sz+1)
110 // Fill with nonzero entries up until lastv.
111 for i := 0; i <= test.lastv; i++ {
112 v[i*test.incv] = rnd.Float64()
114 // Construct h explicitly to compare.
115 h := make([]float64, test.n*test.n)
116 for i := 0; i < test.n; i++ {
119 hMat := blas64.General{
125 vVec := blas64.Vector{
129 blas64.Ger(-test.tau, vVec, vVec, hMat)
131 // Apply multiplication (2nd copy is to avoid aliasing).
132 cMat := blas64.General{
138 cMat2 := blas64.General{
144 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMat2, hMat, 0, cMat)
146 // cMat now stores the true answer. Compare with the function call.
147 work := make([]float64, sz)
148 impl.Dlarf(blas.Right, test.m, test.n, v, test.incv, test.tau, c, test.ldc, work)
149 if !floats.EqualApprox(c, cMat.Data, 1e-14) {
150 t.Errorf("Dlarf mismatch right, case %v. Want %v, got %v", i, cMat.Data, c)
153 // Test on the left side.
157 h = make([]float64, test.m*test.m)
158 for i := 0; i < test.m; i++ {
161 hMat = blas64.General{
167 blas64.Ger(-test.tau, vVec, vVec, hMat)
168 blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hMat, cMat2, 0, cMat)
169 impl.Dlarf(blas.Left, test.m, test.n, v, test.incv, test.tau, c, test.ldc, work)
170 if !floats.EqualApprox(c, cMat.Data, 1e-14) {
171 t.Errorf("Dlarf mismatch left, case %v. Want %v, got %v", i, cMat.Data, c)