gonum.org/v1/gonum@v0.14.0/lapack/testlapack/dlapmr.go (about) 1 // Copyright ©2022 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 "fmt" 9 "testing" 10 11 "golang.org/x/exp/rand" 12 "gonum.org/v1/gonum/blas" 13 "gonum.org/v1/gonum/blas/blas64" 14 ) 15 16 type Dlapmrer interface { 17 Dlapmr(forwrd bool, m, n int, x []float64, ldx int, k []int) 18 } 19 20 func DlapmrTest(t *testing.T, impl Dlapmrer) { 21 rnd := rand.New(rand.NewSource(1)) 22 for _, fwd := range []bool{true, false} { 23 for _, m := range []int{0, 1, 2, 3, 4, 5, 10} { 24 for _, n := range []int{0, 1, 4} { 25 for _, ldx := range []int{max(1, n), n + 3} { 26 dlapmrTest(t, impl, rnd, fwd, m, n, ldx) 27 } 28 } 29 } 30 } 31 } 32 33 func dlapmrTest(t *testing.T, impl Dlapmrer, rnd *rand.Rand, fwd bool, m, n, ldx int) { 34 name := fmt.Sprintf("forwrd=%v,m=%d,n=%d,ldx=%d", fwd, m, n, ldx) 35 36 bi := blas64.Implementation() 37 38 // Generate a random permutation and simultaneously apply it to the rows of the identity matrix. 39 k := make([]int, m) 40 for i := range k { 41 k[i] = i 42 } 43 p := eye(m, m) 44 for i := 0; i < m-1; i++ { 45 j := i + rnd.Intn(m-i) 46 k[i], k[j] = k[j], k[i] 47 bi.Dswap(m, p.Data[i*p.Stride:], 1, p.Data[j*p.Stride:], 1) 48 } 49 kCopy := make([]int, len(k)) 50 copy(kCopy, k) 51 52 // Generate a random matrix X. 53 x := randomGeneral(m, n, ldx, rnd) 54 55 // Applying the permutation k with Dlapmr is the same as multiplying X with P or Pᵀ from the left: 56 // - forward permutation: P * X 57 // - backward permutation: Pᵀ* X 58 trans := blas.NoTrans 59 if !fwd { 60 trans = blas.Trans 61 } 62 want := zeros(m, n, n) 63 bi.Dgemm(trans, blas.NoTrans, m, n, m, 1, p.Data, p.Stride, x.Data, x.Stride, 0, want.Data, want.Stride) 64 65 // Apply the permutation in k to X. 66 impl.Dlapmr(fwd, m, n, x.Data, x.Stride, k) 67 got := x 68 69 // Check that k hasn't been modified in Dlapmr. 70 var kmod bool 71 for i, ki := range k { 72 if ki != kCopy[i] { 73 kmod = true 74 break 75 } 76 } 77 if kmod { 78 t.Errorf("%s: unexpected modification of k", name) 79 } 80 81 // Check that Dlapmr yields the same result as multiplication with P. 82 if !equalGeneral(got, want) { 83 t.Errorf("%s: unexpected result", name) 84 } 85 }