OSDN Git Service

test (#52)
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / lapack / gonum / dorml2.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 // Dorml2 multiplies a general matrix C by an orthogonal matrix from an LQ factorization
10 // determined by Dgelqf.
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 side k×m, and if side == blas.Right
16 // a is of size k×n.
17 //
18 // tau contains the Householder factors and is of length at least k and this function will
19 // 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 // Dorml2 is an internal routine. It is exported for testing purposes.
25 func (impl Implementation) Dorml2(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                 checkMatrix(k, m, a, lda)
37                 if len(work) < n {
38                         panic(badWork)
39                 }
40         } else {
41                 checkMatrix(k, n, a, lda)
42                 if len(work) < m {
43                         panic(badWork)
44                 }
45         }
46         checkMatrix(m, n, c, ldc)
47         if m == 0 || n == 0 || k == 0 {
48                 return
49         }
50         switch {
51         case left && notran:
52                 for i := 0; i < k; i++ {
53                         aii := a[i*lda+i]
54                         a[i*lda+i] = 1
55                         impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work)
56                         a[i*lda+i] = aii
57                 }
58
59         case left && !notran:
60                 for i := k - 1; i >= 0; i-- {
61                         aii := a[i*lda+i]
62                         a[i*lda+i] = 1
63                         impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work)
64                         a[i*lda+i] = aii
65                 }
66
67         case !left && notran:
68                 for i := k - 1; i >= 0; i-- {
69                         aii := a[i*lda+i]
70                         a[i*lda+i] = 1
71                         impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work)
72                         a[i*lda+i] = aii
73                 }
74
75         case !left && !notran:
76                 for i := 0; i < k; i++ {
77                         aii := a[i*lda+i]
78                         a[i*lda+i] = 1
79                         impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work)
80                         a[i*lda+i] = aii
81                 }
82         }
83 }