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.
7 import "gonum.org/v1/gonum/lapack"
9 // Dorgbr generates one of the matrices Q or P^T computed by Dgebrd
10 // computed from the decomposition Dgebrd. See Dgebd2 for the description of
13 // If vect == lapack.ApplyQ, then a is assumed to have been an m×k matrix and
14 // Q is of order m. If m >= k, then Dorgbr returns the first n columns of Q
15 // where m >= n >= k. If m < k, then Dorgbr returns Q as an m×m matrix.
17 // If vect == lapack.ApplyP, then A is assumed to have been a k×n matrix, and
18 // P^T is of order n. If k < n, then Dorgbr returns the first m rows of P^T,
19 // where n >= m >= k. If k >= n, then Dorgbr returns P^T as an n×n matrix.
21 // Dorgbr is an internal routine. It is exported for testing purposes.
22 func (impl Implementation) Dorgbr(vect lapack.DecompUpdate, m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
24 wantq := vect == lapack.ApplyQ
26 if m < n || n < min(m, k) || m < min(m, k) {
30 if n < m || m < min(n, k) || n < min(n, k) {
36 checkMatrix(m, k, a, lda)
38 checkMatrix(m, m, a, lda)
42 checkMatrix(k, n, a, lda)
44 checkMatrix(n, n, a, lda)
50 impl.Dorgqr(m, n, k, a, lda, tau, work, -1)
52 impl.Dorgqr(m-1, m-1, m-1, a[lda+1:], lda, tau, work, -1)
56 impl.Dorglq(m, n, k, a, lda, tau, work, -1)
58 impl.Dorglq(n-1, n-1, n-1, a[lda+1:], lda, tau, work, -1)
61 lworkopt := int(work[0])
62 lworkopt = max(lworkopt, mn)
64 work[0] = float64(lworkopt)
67 if len(work) < lwork {
78 // Form Q, determined by a call to Dgebrd to reduce an m×k matrix.
80 impl.Dorgqr(m, n, k, a, lda, tau, work, lwork)
82 // Shift the vectors which define the elementary reflectors one
83 // column to the right, and set the first row and column of Q to
84 // those of the unit matrix.
85 for j := m - 1; j >= 1; j-- {
87 for i := j + 1; i < m; i++ {
88 a[i*lda+j] = a[i*lda+j-1]
92 for i := 1; i < m; i++ {
96 // Form Q[1:m-1, 1:m-1]
97 impl.Dorgqr(m-1, m-1, m-1, a[lda+1:], lda, tau, work, lwork)
101 // Form P^T, determined by a call to Dgebrd to reduce a k×n matrix.
103 impl.Dorglq(m, n, k, a, lda, tau, work, lwork)
105 // Shift the vectors which define the elementary reflectors one
106 // row downward, and set the first row and column of P^T to
107 // those of the unit matrix.
109 for i := 1; i < n; i++ {
112 for j := 1; j < n; j++ {
113 for i := j - 1; i >= 1; i-- {
114 a[i*lda+j] = a[(i-1)*lda+j]
119 impl.Dorglq(n-1, n-1, n-1, a[lda+1:], lda, tau, work, lwork)
123 work[0] = float64(lworkopt)