gonum.org/v1/gonum@v0.14.0/lapack/gonum/dorml2.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 // Dorml2 multiplies a general matrix C by an orthogonal matrix from an LQ factorization 10 // determined by Dgelqf. 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 side 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 will 21 // 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 // Dorml2 is an internal routine. It is exported for testing purposes. 27 func (impl Implementation) Dorml2(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 switch { 30 case !left && side != blas.Right: 31 panic(badSide) 32 case trans != blas.Trans && trans != blas.NoTrans: 33 panic(badTrans) 34 case m < 0: 35 panic(mLT0) 36 case n < 0: 37 panic(nLT0) 38 case k < 0: 39 panic(kLT0) 40 case left && k > m: 41 panic(kGTM) 42 case !left && k > n: 43 panic(kGTN) 44 case left && lda < max(1, m): 45 panic(badLdA) 46 case !left && lda < max(1, n): 47 panic(badLdA) 48 } 49 50 // Quick return if possible. 51 if m == 0 || n == 0 || k == 0 { 52 return 53 } 54 55 switch { 56 case left && len(a) < (k-1)*lda+m: 57 panic(shortA) 58 case !left && len(a) < (k-1)*lda+n: 59 panic(shortA) 60 case len(tau) < k: 61 panic(shortTau) 62 case len(c) < (m-1)*ldc+n: 63 panic(shortC) 64 case left && len(work) < n: 65 panic(shortWork) 66 case !left && len(work) < m: 67 panic(shortWork) 68 } 69 70 notrans := trans == blas.NoTrans 71 switch { 72 case left && notrans: 73 for i := 0; i < k; i++ { 74 aii := a[i*lda+i] 75 a[i*lda+i] = 1 76 impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work) 77 a[i*lda+i] = aii 78 } 79 80 case left && !notrans: 81 for i := k - 1; i >= 0; i-- { 82 aii := a[i*lda+i] 83 a[i*lda+i] = 1 84 impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work) 85 a[i*lda+i] = aii 86 } 87 88 case !left && notrans: 89 for i := k - 1; i >= 0; i-- { 90 aii := a[i*lda+i] 91 a[i*lda+i] = 1 92 impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work) 93 a[i*lda+i] = aii 94 } 95 96 case !left && !notrans: 97 for i := 0; i < k; i++ { 98 aii := a[i*lda+i] 99 a[i*lda+i] = 1 100 impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work) 101 a[i*lda+i] = aii 102 } 103 } 104 }