github.com/gopherd/gonum@v0.0.4/lapack/gonum/dormr2.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 gonum 6 7 import "github.com/gopherd/gonum/blas" 8 9 // Dormr2 multiplies a general matrix C by an orthogonal matrix from a RQ factorization 10 // determined by Dgerqf. 11 // C = Q * C if side == blas.Left and trans == blas.NoTrans 12 // C = Qᵀ * C if side == blas.Left and trans == blas.Trans 13 // C = C * Q if side == blas.Right and trans == blas.NoTrans 14 // C = C * Qᵀ if side == blas.Right and trans == blas.Trans 15 // If side == blas.Left, a is a matrix of size k×m, and if side == blas.Right 16 // a is of size k×n. 17 // 18 // tau contains the Householder factors and is of length at least k and this function 19 // will panic otherwise. 20 // 21 // work is temporary storage of length at least n if side == blas.Left 22 // and at least m if side == blas.Right and this function will panic otherwise. 23 // 24 // Dormr2 is an internal routine. It is exported for testing purposes. 25 func (impl Implementation) Dormr2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) { 26 left := side == blas.Left 27 nq := n 28 nw := m 29 if left { 30 nq = m 31 nw = n 32 } 33 switch { 34 case !left && side != blas.Right: 35 panic(badSide) 36 case trans != blas.NoTrans && trans != blas.Trans: 37 panic(badTrans) 38 case m < 0: 39 panic(mLT0) 40 case n < 0: 41 panic(nLT0) 42 case k < 0: 43 panic(kLT0) 44 case left && k > m: 45 panic(kGTM) 46 case !left && k > n: 47 panic(kGTN) 48 case lda < max(1, nq): 49 panic(badLdA) 50 case ldc < max(1, n): 51 panic(badLdC) 52 } 53 54 // Quick return if possible. 55 if m == 0 || n == 0 || k == 0 { 56 return 57 } 58 59 switch { 60 case len(a) < (k-1)*lda+nq: 61 panic(shortA) 62 case len(tau) < k: 63 panic(shortTau) 64 case len(c) < (m-1)*ldc+n: 65 panic(shortC) 66 case len(work) < nw: 67 panic(shortWork) 68 } 69 70 if left { 71 if trans == blas.NoTrans { 72 for i := k - 1; i >= 0; i-- { 73 aii := a[i*lda+(m-k+i)] 74 a[i*lda+(m-k+i)] = 1 75 impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work) 76 a[i*lda+(m-k+i)] = aii 77 } 78 return 79 } 80 for i := 0; i < k; i++ { 81 aii := a[i*lda+(m-k+i)] 82 a[i*lda+(m-k+i)] = 1 83 impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work) 84 a[i*lda+(m-k+i)] = aii 85 } 86 return 87 } 88 if trans == blas.NoTrans { 89 for i := 0; i < k; i++ { 90 aii := a[i*lda+(n-k+i)] 91 a[i*lda+(n-k+i)] = 1 92 impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work) 93 a[i*lda+(n-k+i)] = aii 94 } 95 return 96 } 97 for i := k - 1; i >= 0; i-- { 98 aii := a[i*lda+(n-k+i)] 99 a[i*lda+(n-k+i)] = 1 100 impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work) 101 a[i*lda+(n-k+i)] = aii 102 } 103 }