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