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