github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/testlapack/dormlq.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 "math/rand" 9 "testing" 10 11 "github.com/gonum/blas" 12 "github.com/gonum/floats" 13 ) 14 15 type Dormlqer interface { 16 Dorml2er 17 Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) 18 } 19 20 func DormlqTest(t *testing.T, impl Dormlqer) { 21 rnd := rand.New(rand.NewSource(1)) 22 for _, side := range []blas.Side{blas.Left, blas.Right} { 23 for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { 24 for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { 25 for _, test := range []struct { 26 common, adim, cdim, lda, ldc int 27 }{ 28 {0, 0, 0, 0, 0}, 29 {6, 7, 8, 0, 0}, 30 {6, 8, 7, 0, 0}, 31 {7, 6, 8, 0, 0}, 32 {7, 8, 6, 0, 0}, 33 {8, 6, 7, 0, 0}, 34 {8, 7, 6, 0, 0}, 35 {100, 200, 300, 0, 0}, 36 {100, 300, 200, 0, 0}, 37 {200, 100, 300, 0, 0}, 38 {200, 300, 100, 0, 0}, 39 {300, 100, 200, 0, 0}, 40 {300, 200, 100, 0, 0}, 41 {100, 200, 300, 400, 500}, 42 {100, 300, 200, 400, 500}, 43 {200, 100, 300, 400, 500}, 44 {200, 300, 100, 400, 500}, 45 {300, 100, 200, 400, 500}, 46 {300, 200, 100, 400, 500}, 47 {100, 200, 300, 500, 400}, 48 {100, 300, 200, 500, 400}, 49 {200, 100, 300, 500, 400}, 50 {200, 300, 100, 500, 400}, 51 {300, 100, 200, 500, 400}, 52 {300, 200, 100, 500, 400}, 53 } { 54 var ma, na, mc, nc int 55 if side == blas.Left { 56 ma = test.adim 57 na = test.common 58 mc = test.common 59 nc = test.cdim 60 } else { 61 ma = test.adim 62 na = test.common 63 mc = test.cdim 64 nc = test.common 65 } 66 // Generate a random matrix 67 lda := test.lda 68 if lda == 0 { 69 lda = na 70 } 71 a := make([]float64, ma*lda) 72 for i := range a { 73 a[i] = rnd.Float64() 74 } 75 // Compute random C matrix 76 ldc := test.ldc 77 if ldc == 0 { 78 ldc = nc 79 } 80 c := make([]float64, mc*ldc) 81 for i := range c { 82 c[i] = rnd.Float64() 83 } 84 85 // Compute LQ 86 k := min(ma, na) 87 tau := make([]float64, k) 88 work := make([]float64, 1) 89 impl.Dgelqf(ma, na, a, lda, tau, work, -1) 90 work = make([]float64, int(work[0])) 91 impl.Dgelqf(ma, na, a, lda, tau, work, len(work)) 92 93 cCopy := make([]float64, len(c)) 94 copy(cCopy, c) 95 ans := make([]float64, len(c)) 96 copy(ans, cCopy) 97 98 var nw int 99 if side == blas.Left { 100 nw = nc 101 } else { 102 nw = mc 103 } 104 work = make([]float64, max(1, nw)) 105 impl.Dorml2(side, trans, mc, nc, k, a, lda, tau, ans, ldc, work) 106 107 var lwork int 108 switch wl { 109 case minimumWork: 110 lwork = nw 111 case optimumWork: 112 impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1) 113 lwork = int(work[0]) 114 case mediumWork: 115 work := make([]float64, 1) 116 impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1) 117 lwork = (int(work[0]) + nw) / 2 118 } 119 lwork = max(1, lwork) 120 work = make([]float64, lwork) 121 122 impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, lwork) 123 if !floats.EqualApprox(c, ans, 1e-13) { 124 t.Errorf("Dormqr and Dorm2r results mismatch") 125 } 126 } 127 } 128 } 129 } 130 }