OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / lapack / gonum / dorm2r.go
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 // Dorm2r multiplies a general matrix C by an orthogonal matrix from a QR factorization
10 // determined by Dgeqrf.
11 //  C = Q * C    if side == blas.Left and trans == blas.NoTrans
12 //  C = Q^T * C  if side == blas.Left and trans == blas.Trans
13 //  C = C * Q    if side == blas.Right and trans == blas.NoTrans
14 //  C = C * Q^T  if side == blas.Right and trans == blas.Trans
15 // If side == blas.Left, a is a matrix of size m×k, and if side == blas.Right
16 // a is of size n×k.
17 //
18 // tau contains the Householder factors and is of length at least k and this function
19 // will panic otherwise.
20 //
21 // work is temporary storage of length at least n if side == blas.Left
22 // and at least m if side == blas.Right and this function will panic otherwise.
23 //
24 // Dorm2r is an internal routine. It is exported for testing purposes.
25 func (impl Implementation) Dorm2r(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
26         if side != blas.Left && side != blas.Right {
27                 panic(badSide)
28         }
29         if trans != blas.Trans && trans != blas.NoTrans {
30                 panic(badTrans)
31         }
32
33         left := side == blas.Left
34         notran := trans == blas.NoTrans
35         if left {
36                 // Q is m x m
37                 checkMatrix(m, k, a, lda)
38                 if len(work) < n {
39                         panic(badWork)
40                 }
41         } else {
42                 // Q is n x n
43                 checkMatrix(n, k, a, lda)
44                 if len(work) < m {
45                         panic(badWork)
46                 }
47         }
48         checkMatrix(m, n, c, ldc)
49         if m == 0 || n == 0 || k == 0 {
50                 return
51         }
52         if len(tau) < k {
53                 panic(badTau)
54         }
55         if left {
56                 if notran {
57                         for i := k - 1; i >= 0; i-- {
58                                 aii := a[i*lda+i]
59                                 a[i*lda+i] = 1
60                                 impl.Dlarf(side, m-i, n, a[i*lda+i:], lda, tau[i], c[i*ldc:], ldc, work)
61                                 a[i*lda+i] = aii
62                         }
63                         return
64                 }
65                 for i := 0; i < k; i++ {
66                         aii := a[i*lda+i]
67                         a[i*lda+i] = 1
68                         impl.Dlarf(side, m-i, n, a[i*lda+i:], lda, tau[i], c[i*ldc:], ldc, work)
69                         a[i*lda+i] = aii
70                 }
71                 return
72         }
73         if notran {
74                 for i := 0; i < k; i++ {
75                         aii := a[i*lda+i]
76                         a[i*lda+i] = 1
77                         impl.Dlarf(side, m, n-i, a[i*lda+i:], lda, tau[i], c[i:], ldc, work)
78                         a[i*lda+i] = aii
79                 }
80                 return
81         }
82         for i := k - 1; i >= 0; i-- {
83                 aii := a[i*lda+i]
84                 a[i*lda+i] = 1
85                 impl.Dlarf(side, m, n-i, a[i*lda+i:], lda, tau[i], c[i:], ldc, work)
86                 a[i*lda+i] = aii
87         }
88 }