gonum.org/v1/gonum@v0.14.0/lapack/gonum/dgehd2.go (about) 1 // Copyright ©2016 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 // Dgehd2 reduces a block of a general n×n matrix A to upper Hessenberg form H 10 // by an orthogonal similarity transformation Qᵀ * A * Q = H. 11 // 12 // The matrix Q is represented as a product of (ihi-ilo) elementary 13 // reflectors 14 // 15 // Q = H_{ilo} H_{ilo+1} ... H_{ihi-1}. 16 // 17 // Each H_i has the form 18 // 19 // H_i = I - tau[i] * v * vᵀ 20 // 21 // where v is a real vector with v[0:i+1] = 0, v[i+1] = 1 and v[ihi+1:n] = 0. 22 // v[i+2:ihi+1] is stored on exit in A[i+2:ihi+1,i]. 23 // 24 // On entry, a contains the n×n general matrix to be reduced. On return, the 25 // upper triangle and the first subdiagonal of A are overwritten with the upper 26 // Hessenberg matrix H, and the elements below the first subdiagonal, with the 27 // slice tau, represent the orthogonal matrix Q as a product of elementary 28 // reflectors. 29 // 30 // The contents of A are illustrated by the following example, with n = 7, ilo = 31 // 1 and ihi = 5. 32 // On entry, 33 // 34 // [ a a a a a a a ] 35 // [ a a a a a a ] 36 // [ a a a a a a ] 37 // [ a a a a a a ] 38 // [ a a a a a a ] 39 // [ a a a a a a ] 40 // [ a ] 41 // 42 // on return, 43 // 44 // [ a a h h h h a ] 45 // [ a h h h h a ] 46 // [ h h h h h h ] 47 // [ v1 h h h h h ] 48 // [ v1 v2 h h h h ] 49 // [ v1 v2 v3 h h h ] 50 // [ a ] 51 // 52 // where a denotes an element of the original matrix A, h denotes a 53 // modified element of the upper Hessenberg matrix H, and vi denotes an 54 // element of the vector defining H_i. 55 // 56 // ilo and ihi determine the block of A that will be reduced to upper Hessenberg 57 // form. It must hold that 0 <= ilo <= ihi <= max(0, n-1), otherwise Dgehd2 will 58 // panic. 59 // 60 // On return, tau will contain the scalar factors of the elementary reflectors. 61 // It must have length equal to n-1, otherwise Dgehd2 will panic. 62 // 63 // work must have length at least n, otherwise Dgehd2 will panic. 64 // 65 // Dgehd2 is an internal routine. It is exported for testing purposes. 66 func (impl Implementation) Dgehd2(n, ilo, ihi int, a []float64, lda int, tau, work []float64) { 67 switch { 68 case n < 0: 69 panic(nLT0) 70 case ilo < 0 || max(0, n-1) < ilo: 71 panic(badIlo) 72 case ihi < min(ilo, n-1) || n <= ihi: 73 panic(badIhi) 74 case lda < max(1, n): 75 panic(badLdA) 76 } 77 78 // Quick return if possible. 79 if n == 0 { 80 return 81 } 82 83 switch { 84 case len(a) < (n-1)*lda+n: 85 panic(shortA) 86 case len(tau) != n-1: 87 panic(badLenTau) 88 case len(work) < n: 89 panic(shortWork) 90 } 91 92 for i := ilo; i < ihi; i++ { 93 // Compute elementary reflector H_i to annihilate A[i+2:ihi+1,i]. 94 var aii float64 95 aii, tau[i] = impl.Dlarfg(ihi-i, a[(i+1)*lda+i], a[min(i+2, n-1)*lda+i:], lda) 96 a[(i+1)*lda+i] = 1 97 98 // Apply H_i to A[0:ihi+1,i+1:ihi+1] from the right. 99 impl.Dlarf(blas.Right, ihi+1, ihi-i, a[(i+1)*lda+i:], lda, tau[i], a[i+1:], lda, work) 100 101 // Apply H_i to A[i+1:ihi+1,i+1:n] from the left. 102 impl.Dlarf(blas.Left, ihi-i, n-i-1, a[(i+1)*lda+i:], lda, tau[i], a[(i+1)*lda+i+1:], lda, work) 103 a[(i+1)*lda+i] = aii 104 } 105 }