gonum.org/v1/gonum@v0.14.0/lapack/testlapack/dgeqrf.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/floats" 13 ) 14 15 type Dgeqrfer interface { 16 Dgeqr2er 17 Dgeqrf(m, n int, a []float64, lda int, tau, work []float64, lwork int) 18 } 19 20 func DgeqrfTest(t *testing.T, impl Dgeqrfer) { 21 const tol = 1e-12 22 rnd := rand.New(rand.NewSource(1)) 23 for c, test := range []struct { 24 m, n, lda int 25 }{ 26 {10, 5, 0}, 27 {5, 10, 0}, 28 {10, 10, 0}, 29 {300, 5, 0}, 30 {3, 500, 0}, 31 {200, 200, 0}, 32 {300, 200, 0}, 33 {204, 300, 0}, 34 {1, 3000, 0}, 35 {3000, 1, 0}, 36 {10, 5, 20}, 37 {5, 10, 20}, 38 {10, 10, 20}, 39 {300, 5, 400}, 40 {3, 500, 600}, 41 {200, 200, 300}, 42 {300, 200, 300}, 43 {204, 300, 400}, 44 {1, 3000, 4000}, 45 {3000, 1, 4000}, 46 } { 47 m := test.m 48 n := test.n 49 lda := test.lda 50 if lda == 0 { 51 lda = test.n 52 } 53 54 // Allocate m×n matrix A and fill it with random numbers. 55 a := make([]float64, m*lda) 56 for i := range a { 57 a[i] = rnd.NormFloat64() 58 } 59 // Store a copy of A for later comparison. 60 aCopy := make([]float64, len(a)) 61 copy(aCopy, a) 62 63 // Allocate a slice for scalar factors of elementary reflectors 64 // and fill it with random numbers. 65 tau := make([]float64, n) 66 for i := 0; i < n; i++ { 67 tau[i] = rnd.Float64() 68 } 69 70 // Compute the expected result using unblocked QR algorithm and 71 // store it in want. 72 want := make([]float64, len(a)) 73 copy(want, a) 74 impl.Dgeqr2(m, n, want, lda, tau, make([]float64, n)) 75 76 for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { 77 copy(a, aCopy) 78 79 var lwork int 80 switch wl { 81 case minimumWork: 82 lwork = n 83 case mediumWork: 84 work := make([]float64, 1) 85 impl.Dgeqrf(m, n, a, lda, tau, work, -1) 86 lwork = int(work[0]) - 2*n 87 case optimumWork: 88 work := make([]float64, 1) 89 impl.Dgeqrf(m, n, a, lda, tau, work, -1) 90 lwork = int(work[0]) 91 } 92 work := make([]float64, lwork) 93 94 // Compute the QR factorization of A. 95 impl.Dgeqrf(m, n, a, lda, tau, work, len(work)) 96 // Compare the result with Dgeqr2. 97 if !floats.EqualApprox(want, a, tol) { 98 t.Errorf("Case %v, workspace %v, unexpected result.", c, wl) 99 } 100 } 101 } 102 }