Files
gonum/lapack/native/dgeqr2.go
2017-05-23 00:02:46 -06:00

60 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright ©2015 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package native
import "github.com/gonum/blas"
// Dgeqr2 computes a QR factorization of the m×n matrix A.
//
// In a QR factorization, Q is an m×m orthonormal matrix, and R is an
// upper triangular m×n matrix.
//
// A is modified to contain the information to construct Q and R.
// The upper triangle of a contains the matrix R. The lower triangular elements
// (not including the diagonal) contain the elementary reflectors. tau is modified
// to contain the reflector scales. tau must have length at least min(m,n), and
// this function will panic otherwise.
//
// The ith elementary reflector can be explicitly constructed by first extracting
// the
// v[j] = 0 j < i
// v[j] = 1 j == i
// v[j] = a[j*lda+i] j > i
// and computing H_i = I - tau[i] * v * v^T.
//
// The orthonormal matrix Q can be constructed from a product of these elementary
// reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n).
//
// work is temporary storage of length at least n and this function will panic otherwise.
//
// Dgeqr2 is an internal routine. It is exported for testing purposes.
func (impl Implementation) Dgeqr2(m, n int, a []float64, lda int, tau, work []float64) {
// TODO(btracey): This is oriented such that columns of a are eliminated.
// This likely could be re-arranged to take better advantage of row-major
// storage.
checkMatrix(m, n, a, lda)
if len(work) < n {
panic(badWork)
}
k := min(m, n)
if len(tau) < k {
panic(badTau)
}
for i := 0; i < k; i++ {
// Generate elementary reflector H_i.
a[i*lda+i], tau[i] = impl.Dlarfg(m-i, a[i*lda+i], a[min((i+1), m-1)*lda+i:], lda)
if i < n-1 {
aii := a[i*lda+i]
a[i*lda+i] = 1
impl.Dlarf(blas.Left, m-i, n-i-1,
a[i*lda+i:], lda,
tau[i],
a[i*lda+i+1:], lda,
work)
a[i*lda+i] = aii
}
}
}