github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/internal/testdata/dlaqr5test/main.go (about) 1 // Copyright ©2016 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 // This program generates test data for Dlaqr5. Test cases are stored in 6 // gzip-compressed JSON file testlapack/testdata/dlaqr5data.json.gz which is 7 // read during testing by testlapack/dlaqr5.go. 8 // 9 // This program uses cgo to call Fortran version of DLAQR5. Therefore, matrices 10 // passed to the Fortran routine are in column-major format but are written into 11 // the output file in row-major format. 12 package main 13 14 import ( 15 "compress/gzip" 16 "encoding/json" 17 "log" 18 "math/rand" 19 "os" 20 "path/filepath" 21 22 "github.com/gonum/lapack/internal/testdata/netlib" 23 ) 24 25 type Dlaqr5Test struct { 26 WantT bool 27 N int 28 NShifts int 29 KTop, KBot int 30 ShiftR, ShiftI []float64 31 H []float64 32 33 HWant []float64 34 ZWant []float64 35 } 36 37 func main() { 38 file, err := os.Create(filepath.FromSlash("../../../testlapack/testdata/dlaqr5data.json.gz")) 39 if err != nil { 40 log.Fatal(err) 41 } 42 defer file.Close() 43 w := gzip.NewWriter(file) 44 45 rnd := rand.New(rand.NewSource(1)) 46 47 var tests []Dlaqr5Test 48 for _, wantt := range []bool{true, false} { 49 for _, n := range []int{2, 3, 4, 5, 6, 7, 11} { 50 for k := 0; k <= min(5, n); k++ { 51 npairs := k 52 if npairs == 0 { 53 npairs = 2 * n 54 } 55 for ktop := 0; ktop < n-1; ktop++ { 56 for kbot := ktop + 1; kbot < n; kbot++ { 57 sr, si := shiftpairs(npairs, rnd) 58 nshfts := len(sr) 59 60 v := genrand(nshfts/2, 3, rnd) 61 u := genrand(3*nshfts-3, 3*nshfts-3, rnd) 62 wh := genrand(3*nshfts-3, n, rnd) 63 nh := n 64 wv := genrand(n, 3*nshfts-3, rnd) 65 nv := n 66 67 h := hessrand(n, rnd) 68 if ktop > 0 { 69 h[ktop+(ktop-1)*n] = 0 70 } 71 if kbot < n-1 { 72 h[kbot+1+kbot*n] = 0 73 } 74 hin := make([]float64, len(h)) 75 copy(hin, h) 76 z := eye(n) 77 78 netlib.Dlaqr5(wantt, true, 2, 79 n, ktop+1, kbot+1, 80 nshfts, sr, si, 81 h, n, 82 1, n, z, n, 83 v, 3, 84 u, 3*nshfts-3, 85 nh, wh, nh, 86 nv, wv, 3*nshfts-3) 87 88 tests = append(tests, Dlaqr5Test{ 89 WantT: wantt, 90 N: n, 91 NShifts: nshfts, 92 KTop: ktop, 93 KBot: kbot, 94 ShiftR: sr, 95 ShiftI: si, 96 H: rowMajor(n, n, hin), 97 HWant: rowMajor(n, n, h), 98 ZWant: rowMajor(n, n, z), 99 }) 100 } 101 } 102 } 103 } 104 } 105 json.NewEncoder(w).Encode(tests) 106 107 err = w.Close() 108 if err != nil { 109 log.Fatal(err) 110 } 111 } 112 113 // genrand returns a general r×c matrix with random entries. 114 func genrand(r, c int, rnd *rand.Rand) []float64 { 115 m := make([]float64, r*c) 116 for i := range m { 117 m[i] = rnd.NormFloat64() 118 } 119 return m 120 } 121 122 // eye returns an identity matrix of order n. 123 func eye(n int) []float64 { 124 m := make([]float64, n*n) 125 for i := 0; i < n*n; i += n + 1 { 126 m[i] = 1 127 } 128 return m 129 } 130 131 // hessrand returns a Hessenberg matrix of order n with random non-zero entries 132 // in column-major format. 133 func hessrand(n int, rnd *rand.Rand) []float64 { 134 h := make([]float64, n*n) 135 for j := 0; j < n; j++ { 136 for i := 0; i <= min(j+1, n-1); i++ { 137 h[i+j*n] = rnd.NormFloat64() 138 } 139 } 140 return h 141 } 142 143 // shiftpairs generates k real and complex conjugate shift pairs. That is, the 144 // length of sr and si is 2*k. 145 func shiftpairs(k int, rnd *rand.Rand) (sr, si []float64) { 146 sr = make([]float64, 2*k) 147 si = make([]float64, 2*k) 148 for i := 0; i < len(sr); { 149 if rnd.Float64() < 0.5 || i == len(sr)-1 { 150 sr[i] = rnd.NormFloat64() 151 i++ 152 continue 153 } 154 // Generate a complex conjugate pair. 155 r := rnd.NormFloat64() 156 c := rnd.NormFloat64() 157 sr[i] = r 158 si[i] = c 159 sr[i+1] = r 160 si[i+1] = -c 161 i += 2 162 } 163 return sr, si 164 } 165 166 // rowMajor returns the given r×c column-major matrix a in row-major format. 167 func rowMajor(r, c int, a []float64) []float64 { 168 if len(a) != r*c { 169 panic("testdata: slice length mismatch") 170 } 171 m := make([]float64, len(a)) 172 for i := 0; i < r; i++ { 173 for j := 0; j < c; j++ { 174 m[i*c+j] = a[i+j*r] 175 } 176 } 177 return m 178 } 179 180 func min(a, b int) int { 181 if a < b { 182 return a 183 } 184 return b 185 }