github.com/gopherd/gonum@v0.0.4/lapack/gonum/dorg2r.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 ( 8 "github.com/gopherd/gonum/blas" 9 "github.com/gopherd/gonum/blas/blas64" 10 ) 11 12 // Dorg2r generates an m×n matrix Q with orthonormal columns defined by the 13 // product of elementary reflectors as computed by Dgeqrf. 14 // Q = H_0 * H_1 * ... * H_{k-1} 15 // len(tau) >= k, 0 <= k <= n, 0 <= n <= m, len(work) >= n. 16 // Dorg2r will panic if these conditions are not met. 17 // 18 // Dorg2r is an internal routine. It is exported for testing purposes. 19 func (impl Implementation) Dorg2r(m, n, k int, a []float64, lda int, tau []float64, work []float64) { 20 switch { 21 case m < 0: 22 panic(mLT0) 23 case n < 0: 24 panic(nLT0) 25 case n > m: 26 panic(nGTM) 27 case k < 0: 28 panic(kLT0) 29 case k > n: 30 panic(kGTN) 31 case lda < max(1, n): 32 panic(badLdA) 33 } 34 35 if n == 0 { 36 return 37 } 38 39 switch { 40 case len(a) < (m-1)*lda+n: 41 panic(shortA) 42 case len(tau) < k: 43 panic(shortTau) 44 case len(work) < n: 45 panic(shortWork) 46 } 47 48 bi := blas64.Implementation() 49 50 // Initialize columns k+1:n to columns of the unit matrix. 51 for l := 0; l < m; l++ { 52 for j := k; j < n; j++ { 53 a[l*lda+j] = 0 54 } 55 } 56 for j := k; j < n; j++ { 57 a[j*lda+j] = 1 58 } 59 for i := k - 1; i >= 0; i-- { 60 for i := range work { 61 work[i] = 0 62 } 63 if i < n-1 { 64 a[i*lda+i] = 1 65 impl.Dlarf(blas.Left, m-i, n-i-1, a[i*lda+i:], lda, tau[i], a[i*lda+i+1:], lda, work) 66 } 67 if i < m-1 { 68 bi.Dscal(m-i-1, -tau[i], a[(i+1)*lda+i:], lda) 69 } 70 a[i*lda+i] = 1 - tau[i] 71 for l := 0; l < i; l++ { 72 a[l*lda+i] = 0 73 } 74 } 75 }