github.com/gopherd/gonum@v0.0.4/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 "github.com/gopherd/gonum/blas" 9 "github.com/gopherd/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 // 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 switch { 59 case side != blas.Left && side != blas.Right: 60 panic(badSide) 61 case pivot != lapack.Variable && pivot != lapack.Top && pivot != lapack.Bottom: 62 panic(badPivot) 63 case direct != lapack.Forward && direct != lapack.Backward: 64 panic(badDirect) 65 case m < 0: 66 panic(mLT0) 67 case n < 0: 68 panic(nLT0) 69 case lda < max(1, n): 70 panic(badLdA) 71 } 72 73 // Quick return if possible. 74 if m == 0 || n == 0 { 75 return 76 } 77 78 if side == blas.Left { 79 if len(c) < m-1 { 80 panic(shortC) 81 } 82 if len(s) < m-1 { 83 panic(shortS) 84 } 85 } else { 86 if len(c) < n-1 { 87 panic(shortC) 88 } 89 if len(s) < n-1 { 90 panic(shortS) 91 } 92 } 93 if len(a) < (m-1)*lda+n { 94 panic(shortA) 95 } 96 97 if side == blas.Left { 98 if pivot == lapack.Variable { 99 if direct == lapack.Forward { 100 for j := 0; j < m-1; j++ { 101 ctmp := c[j] 102 stmp := s[j] 103 if ctmp != 1 || stmp != 0 { 104 for i := 0; i < n; i++ { 105 tmp2 := a[j*lda+i] 106 tmp := a[(j+1)*lda+i] 107 a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2 108 a[j*lda+i] = stmp*tmp + ctmp*tmp2 109 } 110 } 111 } 112 return 113 } 114 for j := m - 2; j >= 0; j-- { 115 ctmp := c[j] 116 stmp := s[j] 117 if ctmp != 1 || stmp != 0 { 118 for i := 0; i < n; i++ { 119 tmp2 := a[j*lda+i] 120 tmp := a[(j+1)*lda+i] 121 a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2 122 a[j*lda+i] = stmp*tmp + ctmp*tmp2 123 } 124 } 125 } 126 return 127 } else if pivot == lapack.Top { 128 if direct == lapack.Forward { 129 for j := 1; j < m; j++ { 130 ctmp := c[j-1] 131 stmp := s[j-1] 132 if ctmp != 1 || stmp != 0 { 133 for i := 0; i < n; i++ { 134 tmp := a[j*lda+i] 135 tmp2 := a[i] 136 a[j*lda+i] = ctmp*tmp - stmp*tmp2 137 a[i] = stmp*tmp + ctmp*tmp2 138 } 139 } 140 } 141 return 142 } 143 for j := m - 1; j >= 1; j-- { 144 ctmp := c[j-1] 145 stmp := s[j-1] 146 if ctmp != 1 || stmp != 0 { 147 for i := 0; i < n; i++ { 148 ctmp := c[j-1] 149 stmp := s[j-1] 150 if ctmp != 1 || stmp != 0 { 151 for i := 0; i < n; i++ { 152 tmp := a[j*lda+i] 153 tmp2 := a[i] 154 a[j*lda+i] = ctmp*tmp - stmp*tmp2 155 a[i] = stmp*tmp + ctmp*tmp2 156 } 157 } 158 } 159 } 160 } 161 return 162 } 163 if direct == lapack.Forward { 164 for j := 0; j < m-1; j++ { 165 ctmp := c[j] 166 stmp := s[j] 167 if ctmp != 1 || stmp != 0 { 168 for i := 0; i < n; i++ { 169 tmp := a[j*lda+i] 170 tmp2 := a[(m-1)*lda+i] 171 a[j*lda+i] = stmp*tmp2 + ctmp*tmp 172 a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp 173 } 174 } 175 } 176 return 177 } 178 for j := m - 2; j >= 0; j-- { 179 ctmp := c[j] 180 stmp := s[j] 181 if ctmp != 1 || stmp != 0 { 182 for i := 0; i < n; i++ { 183 tmp := a[j*lda+i] 184 tmp2 := a[(m-1)*lda+i] 185 a[j*lda+i] = stmp*tmp2 + ctmp*tmp 186 a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp 187 } 188 } 189 } 190 return 191 } 192 if pivot == lapack.Variable { 193 if direct == lapack.Forward { 194 for j := 0; j < n-1; j++ { 195 ctmp := c[j] 196 stmp := s[j] 197 if ctmp != 1 || stmp != 0 { 198 for i := 0; i < m; i++ { 199 tmp := a[i*lda+j+1] 200 tmp2 := a[i*lda+j] 201 a[i*lda+j+1] = ctmp*tmp - stmp*tmp2 202 a[i*lda+j] = stmp*tmp + ctmp*tmp2 203 } 204 } 205 } 206 return 207 } 208 for j := n - 2; j >= 0; j-- { 209 ctmp := c[j] 210 stmp := s[j] 211 if ctmp != 1 || stmp != 0 { 212 for i := 0; i < m; i++ { 213 tmp := a[i*lda+j+1] 214 tmp2 := a[i*lda+j] 215 a[i*lda+j+1] = ctmp*tmp - stmp*tmp2 216 a[i*lda+j] = stmp*tmp + ctmp*tmp2 217 } 218 } 219 } 220 return 221 } else if pivot == lapack.Top { 222 if direct == lapack.Forward { 223 for j := 1; j < n; j++ { 224 ctmp := c[j-1] 225 stmp := s[j-1] 226 if ctmp != 1 || stmp != 0 { 227 for i := 0; i < m; i++ { 228 tmp := a[i*lda+j] 229 tmp2 := a[i*lda] 230 a[i*lda+j] = ctmp*tmp - stmp*tmp2 231 a[i*lda] = stmp*tmp + ctmp*tmp2 232 } 233 } 234 } 235 return 236 } 237 for j := n - 1; j >= 1; j-- { 238 ctmp := c[j-1] 239 stmp := s[j-1] 240 if ctmp != 1 || stmp != 0 { 241 for i := 0; i < m; i++ { 242 tmp := a[i*lda+j] 243 tmp2 := a[i*lda] 244 a[i*lda+j] = ctmp*tmp - stmp*tmp2 245 a[i*lda] = stmp*tmp + ctmp*tmp2 246 } 247 } 248 } 249 return 250 } 251 if direct == lapack.Forward { 252 for j := 0; j < n-1; j++ { 253 ctmp := c[j] 254 stmp := s[j] 255 if ctmp != 1 || stmp != 0 { 256 for i := 0; i < m; i++ { 257 tmp := a[i*lda+j] 258 tmp2 := a[i*lda+n-1] 259 a[i*lda+j] = stmp*tmp2 + ctmp*tmp 260 a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp 261 } 262 263 } 264 } 265 return 266 } 267 for j := n - 2; j >= 0; j-- { 268 ctmp := c[j] 269 stmp := s[j] 270 if ctmp != 1 || stmp != 0 { 271 for i := 0; i < m; i++ { 272 tmp := a[i*lda+j] 273 tmp2 := a[i*lda+n-1] 274 a[i*lda+j] = stmp*tmp2 + ctmp*tmp 275 a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp 276 } 277 } 278 } 279 }