github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/dormr2.go (about)

     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 native
     6  
     7  import "github.com/gonum/blas"
     8  
     9  // Dormr2 multiplies a general matrix C by an orthogonal matrix from a RQ factorization
    10  // determined by Dgerqf.
    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 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
    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  // Dormr2 is an internal routine. It is exported for testing purposes.
    25  func (impl Implementation) Dormr2(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  		if k > m {
    37  			panic(kGTM)
    38  		}
    39  		checkMatrix(k, m, a, lda)
    40  		if len(work) < n {
    41  			panic(badWork)
    42  		}
    43  	} else {
    44  		if k > n {
    45  			panic(kGTN)
    46  		}
    47  		checkMatrix(k, n, a, lda)
    48  		if len(work) < m {
    49  			panic(badWork)
    50  		}
    51  	}
    52  	if len(tau) < k {
    53  		panic(badTau)
    54  	}
    55  	checkMatrix(m, n, c, ldc)
    56  
    57  	if m == 0 || n == 0 || k == 0 {
    58  		return
    59  	}
    60  	if left {
    61  		if notran {
    62  			for i := k - 1; i >= 0; i-- {
    63  				aii := a[i*lda+(m-k+i)]
    64  				a[i*lda+(m-k+i)] = 1
    65  				impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work)
    66  				a[i*lda+(m-k+i)] = aii
    67  			}
    68  			return
    69  		}
    70  		for i := 0; i < k; i++ {
    71  			aii := a[i*lda+(m-k+i)]
    72  			a[i*lda+(m-k+i)] = 1
    73  			impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work)
    74  			a[i*lda+(m-k+i)] = aii
    75  		}
    76  		return
    77  	}
    78  	if notran {
    79  		for i := 0; i < k; i++ {
    80  			aii := a[i*lda+(n-k+i)]
    81  			a[i*lda+(n-k+i)] = 1
    82  			impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work)
    83  			a[i*lda+(n-k+i)] = aii
    84  		}
    85  		return
    86  	}
    87  	for i := k - 1; i >= 0; i-- {
    88  		aii := a[i*lda+(n-k+i)]
    89  		a[i*lda+(n-k+i)] = 1
    90  		impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work)
    91  		a[i*lda+(n-k+i)] = aii
    92  	}
    93  }