github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/dlasr.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 (
     8  	"github.com/gonum/blas"
     9  	"github.com/gonum/lapack"
    10  )
    11  
    12  // Dlasr applies a sequence of plane rotations to the m×n matrix A. This series
    13  // of plane rotations is implicitly represented by a matrix P. P is multiplied
    14  // by a depending on the value of side -- A = P * A if side == lapack.Left,
    15  // A = A * P^T if side == lapack.Right.
    16  //
    17  //The exact value of P depends on the value of pivot, but in all cases P is
    18  // implicitly represented by a series of 2×2 rotation matrices. The entries of
    19  // rotation matrix k are defined by s[k] and c[k]
    20  //  R(k) = [ c[k] s[k]]
    21  //         [-s[k] s[k]]
    22  // If direct == lapack.Forward, the rotation matrices are applied as
    23  // P = P(z-1) * ... * P(2) * P(1), while if direct == lapack.Backward they are
    24  // applied as P = P(1) * P(2) * ... * P(n).
    25  //
    26  // pivot defines the mapping of the elements in R(k) to P(k).
    27  // If pivot == lapack.Variable, the rotation is performed for the (k, k+1) plane.
    28  //  P(k) = [1                    ]
    29  //         [    ...              ]
    30  //         [     1               ]
    31  //         [       c[k] s[k]     ]
    32  //         [      -s[k] c[k]     ]
    33  //         [                 1   ]
    34  //         [                ...  ]
    35  //         [                    1]
    36  // if pivot == lapack.Top, the rotation is performed for the (1, k+1) plane,
    37  //  P(k) = [c[k]        s[k]     ]
    38  //         [    1                ]
    39  //         [     ...             ]
    40  //         [         1           ]
    41  //         [-s[k]       c[k]     ]
    42  //         [                 1   ]
    43  //         [                ...  ]
    44  //         [                    1]
    45  // and if pivot == lapack.Bottom, the rotation is performed for the (k, z) plane.
    46  //  P(k) = [1                    ]
    47  //         [  ...                ]
    48  //         [      1              ]
    49  //         [        c[k]     s[k]]
    50  //         [           1         ]
    51  //         [            ...      ]
    52  //         [              1      ]
    53  //         [       -s[k]     c[k]]
    54  // s and c have length m - 1 if side == blas.Left, and n - 1 if side == blas.Right.
    55  //
    56  // Dlasr is an internal routine. It is exported for testing purposes.
    57  func (impl Implementation) Dlasr(side blas.Side, pivot lapack.Pivot, direct lapack.Direct, m, n int, c, s, a []float64, lda int) {
    58  	checkMatrix(m, n, a, lda)
    59  	if side != blas.Left && side != blas.Right {
    60  		panic(badSide)
    61  	}
    62  	if pivot != lapack.Variable && pivot != lapack.Top && pivot != lapack.Bottom {
    63  		panic(badPivot)
    64  	}
    65  	if direct != lapack.Forward && direct != lapack.Backward {
    66  		panic(badDirect)
    67  	}
    68  	if side == blas.Left {
    69  		if len(c) < m-1 {
    70  			panic(badSlice)
    71  		}
    72  		if len(s) < m-1 {
    73  			panic(badSlice)
    74  		}
    75  	} else {
    76  		if len(c) < n-1 {
    77  			panic(badSlice)
    78  		}
    79  		if len(s) < n-1 {
    80  			panic(badSlice)
    81  		}
    82  	}
    83  	if m == 0 || n == 0 {
    84  		return
    85  	}
    86  	if side == blas.Left {
    87  		if pivot == lapack.Variable {
    88  			if direct == lapack.Forward {
    89  				for j := 0; j < m-1; j++ {
    90  					ctmp := c[j]
    91  					stmp := s[j]
    92  					if ctmp != 1 || stmp != 0 {
    93  						for i := 0; i < n; i++ {
    94  							tmp2 := a[j*lda+i]
    95  							tmp := a[(j+1)*lda+i]
    96  							a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2
    97  							a[j*lda+i] = stmp*tmp + ctmp*tmp2
    98  						}
    99  					}
   100  				}
   101  				return
   102  			}
   103  			for j := m - 2; j >= 0; j-- {
   104  				ctmp := c[j]
   105  				stmp := s[j]
   106  				if ctmp != 1 || stmp != 0 {
   107  					for i := 0; i < n; i++ {
   108  						tmp2 := a[j*lda+i]
   109  						tmp := a[(j+1)*lda+i]
   110  						a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2
   111  						a[j*lda+i] = stmp*tmp + ctmp*tmp2
   112  					}
   113  				}
   114  			}
   115  			return
   116  		} else if pivot == lapack.Top {
   117  			if direct == lapack.Forward {
   118  				for j := 1; j < m; j++ {
   119  					ctmp := c[j-1]
   120  					stmp := s[j-1]
   121  					if ctmp != 1 || stmp != 0 {
   122  						for i := 0; i < n; i++ {
   123  							tmp := a[j*lda+i]
   124  							tmp2 := a[i]
   125  							a[j*lda+i] = ctmp*tmp - stmp*tmp2
   126  							a[i] = stmp*tmp + ctmp*tmp2
   127  						}
   128  					}
   129  				}
   130  				return
   131  			}
   132  			for j := m - 1; j >= 1; j-- {
   133  				ctmp := c[j-1]
   134  				stmp := s[j-1]
   135  				if ctmp != 1 || stmp != 0 {
   136  					for i := 0; i < n; i++ {
   137  						ctmp := c[j-1]
   138  						stmp := s[j-1]
   139  						if ctmp != 1 || stmp != 0 {
   140  							for i := 0; i < n; i++ {
   141  								tmp := a[j*lda+i]
   142  								tmp2 := a[i]
   143  								a[j*lda+i] = ctmp*tmp - stmp*tmp2
   144  								a[i] = stmp*tmp + ctmp*tmp2
   145  							}
   146  						}
   147  					}
   148  				}
   149  			}
   150  			return
   151  		}
   152  		if direct == lapack.Forward {
   153  			for j := 0; j < m-1; j++ {
   154  				ctmp := c[j]
   155  				stmp := s[j]
   156  				if ctmp != 1 || stmp != 0 {
   157  					for i := 0; i < n; i++ {
   158  						tmp := a[j*lda+i]
   159  						tmp2 := a[(m-1)*lda+i]
   160  						a[j*lda+i] = stmp*tmp2 + ctmp*tmp
   161  						a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp
   162  					}
   163  				}
   164  			}
   165  			return
   166  		}
   167  		for j := m - 2; j >= 0; j-- {
   168  			ctmp := c[j]
   169  			stmp := s[j]
   170  			if ctmp != 1 || stmp != 0 {
   171  				for i := 0; i < n; i++ {
   172  					tmp := a[j*lda+i]
   173  					tmp2 := a[(m-1)*lda+i]
   174  					a[j*lda+i] = stmp*tmp2 + ctmp*tmp
   175  					a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp
   176  				}
   177  			}
   178  		}
   179  		return
   180  	}
   181  	if pivot == lapack.Variable {
   182  		if direct == lapack.Forward {
   183  			for j := 0; j < n-1; j++ {
   184  				ctmp := c[j]
   185  				stmp := s[j]
   186  				if ctmp != 1 || stmp != 0 {
   187  					for i := 0; i < m; i++ {
   188  						tmp := a[i*lda+j+1]
   189  						tmp2 := a[i*lda+j]
   190  						a[i*lda+j+1] = ctmp*tmp - stmp*tmp2
   191  						a[i*lda+j] = stmp*tmp + ctmp*tmp2
   192  					}
   193  				}
   194  			}
   195  			return
   196  		}
   197  		for j := n - 2; j >= 0; j-- {
   198  			ctmp := c[j]
   199  			stmp := s[j]
   200  			if ctmp != 1 || stmp != 0 {
   201  				for i := 0; i < m; i++ {
   202  					tmp := a[i*lda+j+1]
   203  					tmp2 := a[i*lda+j]
   204  					a[i*lda+j+1] = ctmp*tmp - stmp*tmp2
   205  					a[i*lda+j] = stmp*tmp + ctmp*tmp2
   206  				}
   207  			}
   208  		}
   209  		return
   210  	} else if pivot == lapack.Top {
   211  		if direct == lapack.Forward {
   212  			for j := 1; j < n; j++ {
   213  				ctmp := c[j-1]
   214  				stmp := s[j-1]
   215  				if ctmp != 1 || stmp != 0 {
   216  					for i := 0; i < m; i++ {
   217  						tmp := a[i*lda+j]
   218  						tmp2 := a[i*lda]
   219  						a[i*lda+j] = ctmp*tmp - stmp*tmp2
   220  						a[i*lda] = stmp*tmp + ctmp*tmp2
   221  					}
   222  				}
   223  			}
   224  			return
   225  		}
   226  		for j := n - 1; j >= 1; j-- {
   227  			ctmp := c[j-1]
   228  			stmp := s[j-1]
   229  			if ctmp != 1 || stmp != 0 {
   230  				for i := 0; i < m; i++ {
   231  					tmp := a[i*lda+j]
   232  					tmp2 := a[i*lda]
   233  					a[i*lda+j] = ctmp*tmp - stmp*tmp2
   234  					a[i*lda] = stmp*tmp + ctmp*tmp2
   235  				}
   236  			}
   237  		}
   238  		return
   239  	}
   240  	if direct == lapack.Forward {
   241  		for j := 0; j < n-1; j++ {
   242  			ctmp := c[j]
   243  			stmp := s[j]
   244  			if ctmp != 1 || stmp != 0 {
   245  				for i := 0; i < m; i++ {
   246  					tmp := a[i*lda+j]
   247  					tmp2 := a[i*lda+n-1]
   248  					a[i*lda+j] = stmp*tmp2 + ctmp*tmp
   249  					a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp
   250  				}
   251  
   252  			}
   253  		}
   254  		return
   255  	}
   256  	for j := n - 2; j >= 0; j-- {
   257  		ctmp := c[j]
   258  		stmp := s[j]
   259  		if ctmp != 1 || stmp != 0 {
   260  			for i := 0; i < m; i++ {
   261  				tmp := a[i*lda+j]
   262  				tmp2 := a[i*lda+n-1]
   263  				a[i*lda+j] = stmp*tmp2 + ctmp*tmp
   264  				a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp
   265  			}
   266  		}
   267  	}
   268  }