github.com/gopherd/gonum@v0.0.4/lapack/gonum/dlarfx.go (about) 1 // Copyright ©2016 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 "github.com/gopherd/gonum/blas" 8 9 // Dlarfx applies an elementary reflector H to a real m×n matrix C, from either 10 // the left or the right, with loop unrolling when the reflector has order less 11 // than 11. 12 // 13 // H is represented in the form 14 // H = I - tau * v * vᵀ, 15 // where tau is a real scalar and v is a real vector. If tau = 0, then H is 16 // taken to be the identity matrix. 17 // 18 // v must have length equal to m if side == blas.Left, and equal to n if side == 19 // blas.Right, otherwise Dlarfx will panic. 20 // 21 // c and ldc represent the m×n matrix C. On return, C is overwritten by the 22 // matrix H * C if side == blas.Left, or C * H if side == blas.Right. 23 // 24 // work must have length at least n if side == blas.Left, and at least m if side 25 // == blas.Right, otherwise Dlarfx will panic. work is not referenced if H has 26 // order < 11. 27 // 28 // Dlarfx is an internal routine. It is exported for testing purposes. 29 func (impl Implementation) Dlarfx(side blas.Side, m, n int, v []float64, tau float64, c []float64, ldc int, work []float64) { 30 switch { 31 case side != blas.Left && side != blas.Right: 32 panic(badSide) 33 case m < 0: 34 panic(mLT0) 35 case n < 0: 36 panic(nLT0) 37 case ldc < max(1, n): 38 panic(badLdC) 39 } 40 41 // Quick return if possible. 42 if m == 0 || n == 0 { 43 return 44 } 45 46 nh := m 47 lwork := n 48 if side == blas.Right { 49 nh = n 50 lwork = m 51 } 52 switch { 53 case len(v) < nh: 54 panic(shortV) 55 case len(c) < (m-1)*ldc+n: 56 panic(shortC) 57 case nh > 10 && len(work) < lwork: 58 panic(shortWork) 59 } 60 61 if tau == 0 { 62 return 63 } 64 65 if side == blas.Left { 66 // Form H * C, where H has order m. 67 switch m { 68 default: // Code for general m. 69 impl.Dlarf(side, m, n, v, 1, tau, c, ldc, work) 70 return 71 72 case 0: // No-op for zero size matrix. 73 return 74 75 case 1: // Special code for 1×1 Householder matrix. 76 t0 := 1 - tau*v[0]*v[0] 77 for j := 0; j < n; j++ { 78 c[j] *= t0 79 } 80 return 81 82 case 2: // Special code for 2×2 Householder matrix. 83 v0 := v[0] 84 t0 := tau * v0 85 v1 := v[1] 86 t1 := tau * v1 87 for j := 0; j < n; j++ { 88 sum := v0*c[j] + v1*c[ldc+j] 89 c[j] -= sum * t0 90 c[ldc+j] -= sum * t1 91 } 92 return 93 94 case 3: // Special code for 3×3 Householder matrix. 95 v0 := v[0] 96 t0 := tau * v0 97 v1 := v[1] 98 t1 := tau * v1 99 v2 := v[2] 100 t2 := tau * v2 101 for j := 0; j < n; j++ { 102 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] 103 c[j] -= sum * t0 104 c[ldc+j] -= sum * t1 105 c[2*ldc+j] -= sum * t2 106 } 107 return 108 109 case 4: // Special code for 4×4 Householder matrix. 110 v0 := v[0] 111 t0 := tau * v0 112 v1 := v[1] 113 t1 := tau * v1 114 v2 := v[2] 115 t2 := tau * v2 116 v3 := v[3] 117 t3 := tau * v3 118 for j := 0; j < n; j++ { 119 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] 120 c[j] -= sum * t0 121 c[ldc+j] -= sum * t1 122 c[2*ldc+j] -= sum * t2 123 c[3*ldc+j] -= sum * t3 124 } 125 return 126 127 case 5: // Special code for 5×5 Householder matrix. 128 v0 := v[0] 129 t0 := tau * v0 130 v1 := v[1] 131 t1 := tau * v1 132 v2 := v[2] 133 t2 := tau * v2 134 v3 := v[3] 135 t3 := tau * v3 136 v4 := v[4] 137 t4 := tau * v4 138 for j := 0; j < n; j++ { 139 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] 140 c[j] -= sum * t0 141 c[ldc+j] -= sum * t1 142 c[2*ldc+j] -= sum * t2 143 c[3*ldc+j] -= sum * t3 144 c[4*ldc+j] -= sum * t4 145 } 146 return 147 148 case 6: // Special code for 6×6 Householder matrix. 149 v0 := v[0] 150 t0 := tau * v0 151 v1 := v[1] 152 t1 := tau * v1 153 v2 := v[2] 154 t2 := tau * v2 155 v3 := v[3] 156 t3 := tau * v3 157 v4 := v[4] 158 t4 := tau * v4 159 v5 := v[5] 160 t5 := tau * v5 161 for j := 0; j < n; j++ { 162 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + 163 v5*c[5*ldc+j] 164 c[j] -= sum * t0 165 c[ldc+j] -= sum * t1 166 c[2*ldc+j] -= sum * t2 167 c[3*ldc+j] -= sum * t3 168 c[4*ldc+j] -= sum * t4 169 c[5*ldc+j] -= sum * t5 170 } 171 return 172 173 case 7: // Special code for 7×7 Householder matrix. 174 v0 := v[0] 175 t0 := tau * v0 176 v1 := v[1] 177 t1 := tau * v1 178 v2 := v[2] 179 t2 := tau * v2 180 v3 := v[3] 181 t3 := tau * v3 182 v4 := v[4] 183 t4 := tau * v4 184 v5 := v[5] 185 t5 := tau * v5 186 v6 := v[6] 187 t6 := tau * v6 188 for j := 0; j < n; j++ { 189 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + 190 v5*c[5*ldc+j] + v6*c[6*ldc+j] 191 c[j] -= sum * t0 192 c[ldc+j] -= sum * t1 193 c[2*ldc+j] -= sum * t2 194 c[3*ldc+j] -= sum * t3 195 c[4*ldc+j] -= sum * t4 196 c[5*ldc+j] -= sum * t5 197 c[6*ldc+j] -= sum * t6 198 } 199 return 200 201 case 8: // Special code for 8×8 Householder matrix. 202 v0 := v[0] 203 t0 := tau * v0 204 v1 := v[1] 205 t1 := tau * v1 206 v2 := v[2] 207 t2 := tau * v2 208 v3 := v[3] 209 t3 := tau * v3 210 v4 := v[4] 211 t4 := tau * v4 212 v5 := v[5] 213 t5 := tau * v5 214 v6 := v[6] 215 t6 := tau * v6 216 v7 := v[7] 217 t7 := tau * v7 218 for j := 0; j < n; j++ { 219 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + 220 v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] 221 c[j] -= sum * t0 222 c[ldc+j] -= sum * t1 223 c[2*ldc+j] -= sum * t2 224 c[3*ldc+j] -= sum * t3 225 c[4*ldc+j] -= sum * t4 226 c[5*ldc+j] -= sum * t5 227 c[6*ldc+j] -= sum * t6 228 c[7*ldc+j] -= sum * t7 229 } 230 return 231 232 case 9: // Special code for 9×9 Householder matrix. 233 v0 := v[0] 234 t0 := tau * v0 235 v1 := v[1] 236 t1 := tau * v1 237 v2 := v[2] 238 t2 := tau * v2 239 v3 := v[3] 240 t3 := tau * v3 241 v4 := v[4] 242 t4 := tau * v4 243 v5 := v[5] 244 t5 := tau * v5 245 v6 := v[6] 246 t6 := tau * v6 247 v7 := v[7] 248 t7 := tau * v7 249 v8 := v[8] 250 t8 := tau * v8 251 for j := 0; j < n; j++ { 252 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + 253 v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] + v8*c[8*ldc+j] 254 c[j] -= sum * t0 255 c[ldc+j] -= sum * t1 256 c[2*ldc+j] -= sum * t2 257 c[3*ldc+j] -= sum * t3 258 c[4*ldc+j] -= sum * t4 259 c[5*ldc+j] -= sum * t5 260 c[6*ldc+j] -= sum * t6 261 c[7*ldc+j] -= sum * t7 262 c[8*ldc+j] -= sum * t8 263 } 264 return 265 266 case 10: // Special code for 10×10 Householder matrix. 267 v0 := v[0] 268 t0 := tau * v0 269 v1 := v[1] 270 t1 := tau * v1 271 v2 := v[2] 272 t2 := tau * v2 273 v3 := v[3] 274 t3 := tau * v3 275 v4 := v[4] 276 t4 := tau * v4 277 v5 := v[5] 278 t5 := tau * v5 279 v6 := v[6] 280 t6 := tau * v6 281 v7 := v[7] 282 t7 := tau * v7 283 v8 := v[8] 284 t8 := tau * v8 285 v9 := v[9] 286 t9 := tau * v9 287 for j := 0; j < n; j++ { 288 sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + 289 v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] + v8*c[8*ldc+j] + v9*c[9*ldc+j] 290 c[j] -= sum * t0 291 c[ldc+j] -= sum * t1 292 c[2*ldc+j] -= sum * t2 293 c[3*ldc+j] -= sum * t3 294 c[4*ldc+j] -= sum * t4 295 c[5*ldc+j] -= sum * t5 296 c[6*ldc+j] -= sum * t6 297 c[7*ldc+j] -= sum * t7 298 c[8*ldc+j] -= sum * t8 299 c[9*ldc+j] -= sum * t9 300 } 301 return 302 } 303 } 304 305 // Form C * H, where H has order n. 306 switch n { 307 default: // Code for general n. 308 impl.Dlarf(side, m, n, v, 1, tau, c, ldc, work) 309 return 310 311 case 0: // No-op for zero size matrix. 312 return 313 314 case 1: // Special code for 1×1 Householder matrix. 315 t0 := 1 - tau*v[0]*v[0] 316 for j := 0; j < m; j++ { 317 c[j*ldc] *= t0 318 } 319 return 320 321 case 2: // Special code for 2×2 Householder matrix. 322 v0 := v[0] 323 t0 := tau * v0 324 v1 := v[1] 325 t1 := tau * v1 326 for j := 0; j < m; j++ { 327 cs := c[j*ldc:] 328 sum := v0*cs[0] + v1*cs[1] 329 cs[0] -= sum * t0 330 cs[1] -= sum * t1 331 } 332 return 333 334 case 3: // Special code for 3×3 Householder matrix. 335 v0 := v[0] 336 t0 := tau * v0 337 v1 := v[1] 338 t1 := tau * v1 339 v2 := v[2] 340 t2 := tau * v2 341 for j := 0; j < m; j++ { 342 cs := c[j*ldc:] 343 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] 344 cs[0] -= sum * t0 345 cs[1] -= sum * t1 346 cs[2] -= sum * t2 347 } 348 return 349 350 case 4: // Special code for 4×4 Householder matrix. 351 v0 := v[0] 352 t0 := tau * v0 353 v1 := v[1] 354 t1 := tau * v1 355 v2 := v[2] 356 t2 := tau * v2 357 v3 := v[3] 358 t3 := tau * v3 359 for j := 0; j < m; j++ { 360 cs := c[j*ldc:] 361 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] 362 cs[0] -= sum * t0 363 cs[1] -= sum * t1 364 cs[2] -= sum * t2 365 cs[3] -= sum * t3 366 } 367 return 368 369 case 5: // Special code for 5×5 Householder matrix. 370 v0 := v[0] 371 t0 := tau * v0 372 v1 := v[1] 373 t1 := tau * v1 374 v2 := v[2] 375 t2 := tau * v2 376 v3 := v[3] 377 t3 := tau * v3 378 v4 := v[4] 379 t4 := tau * v4 380 for j := 0; j < m; j++ { 381 cs := c[j*ldc:] 382 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] 383 cs[0] -= sum * t0 384 cs[1] -= sum * t1 385 cs[2] -= sum * t2 386 cs[3] -= sum * t3 387 cs[4] -= sum * t4 388 } 389 return 390 391 case 6: // Special code for 6×6 Householder matrix. 392 v0 := v[0] 393 t0 := tau * v0 394 v1 := v[1] 395 t1 := tau * v1 396 v2 := v[2] 397 t2 := tau * v2 398 v3 := v[3] 399 t3 := tau * v3 400 v4 := v[4] 401 t4 := tau * v4 402 v5 := v[5] 403 t5 := tau * v5 404 for j := 0; j < m; j++ { 405 cs := c[j*ldc:] 406 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + v5*cs[5] 407 cs[0] -= sum * t0 408 cs[1] -= sum * t1 409 cs[2] -= sum * t2 410 cs[3] -= sum * t3 411 cs[4] -= sum * t4 412 cs[5] -= sum * t5 413 } 414 return 415 416 case 7: // Special code for 7×7 Householder matrix. 417 v0 := v[0] 418 t0 := tau * v0 419 v1 := v[1] 420 t1 := tau * v1 421 v2 := v[2] 422 t2 := tau * v2 423 v3 := v[3] 424 t3 := tau * v3 425 v4 := v[4] 426 t4 := tau * v4 427 v5 := v[5] 428 t5 := tau * v5 429 v6 := v[6] 430 t6 := tau * v6 431 for j := 0; j < m; j++ { 432 cs := c[j*ldc:] 433 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + 434 v5*cs[5] + v6*cs[6] 435 cs[0] -= sum * t0 436 cs[1] -= sum * t1 437 cs[2] -= sum * t2 438 cs[3] -= sum * t3 439 cs[4] -= sum * t4 440 cs[5] -= sum * t5 441 cs[6] -= sum * t6 442 } 443 return 444 445 case 8: // Special code for 8×8 Householder matrix. 446 v0 := v[0] 447 t0 := tau * v0 448 v1 := v[1] 449 t1 := tau * v1 450 v2 := v[2] 451 t2 := tau * v2 452 v3 := v[3] 453 t3 := tau * v3 454 v4 := v[4] 455 t4 := tau * v4 456 v5 := v[5] 457 t5 := tau * v5 458 v6 := v[6] 459 t6 := tau * v6 460 v7 := v[7] 461 t7 := tau * v7 462 for j := 0; j < m; j++ { 463 cs := c[j*ldc:] 464 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + 465 v5*cs[5] + v6*cs[6] + v7*cs[7] 466 cs[0] -= sum * t0 467 cs[1] -= sum * t1 468 cs[2] -= sum * t2 469 cs[3] -= sum * t3 470 cs[4] -= sum * t4 471 cs[5] -= sum * t5 472 cs[6] -= sum * t6 473 cs[7] -= sum * t7 474 } 475 return 476 477 case 9: // Special code for 9×9 Householder matrix. 478 v0 := v[0] 479 t0 := tau * v0 480 v1 := v[1] 481 t1 := tau * v1 482 v2 := v[2] 483 t2 := tau * v2 484 v3 := v[3] 485 t3 := tau * v3 486 v4 := v[4] 487 t4 := tau * v4 488 v5 := v[5] 489 t5 := tau * v5 490 v6 := v[6] 491 t6 := tau * v6 492 v7 := v[7] 493 t7 := tau * v7 494 v8 := v[8] 495 t8 := tau * v8 496 for j := 0; j < m; j++ { 497 cs := c[j*ldc:] 498 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + 499 v5*cs[5] + v6*cs[6] + v7*cs[7] + v8*cs[8] 500 cs[0] -= sum * t0 501 cs[1] -= sum * t1 502 cs[2] -= sum * t2 503 cs[3] -= sum * t3 504 cs[4] -= sum * t4 505 cs[5] -= sum * t5 506 cs[6] -= sum * t6 507 cs[7] -= sum * t7 508 cs[8] -= sum * t8 509 } 510 return 511 512 case 10: // Special code for 10×10 Householder matrix. 513 v0 := v[0] 514 t0 := tau * v0 515 v1 := v[1] 516 t1 := tau * v1 517 v2 := v[2] 518 t2 := tau * v2 519 v3 := v[3] 520 t3 := tau * v3 521 v4 := v[4] 522 t4 := tau * v4 523 v5 := v[5] 524 t5 := tau * v5 525 v6 := v[6] 526 t6 := tau * v6 527 v7 := v[7] 528 t7 := tau * v7 529 v8 := v[8] 530 t8 := tau * v8 531 v9 := v[9] 532 t9 := tau * v9 533 for j := 0; j < m; j++ { 534 cs := c[j*ldc:] 535 sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + 536 v5*cs[5] + v6*cs[6] + v7*cs[7] + v8*cs[8] + v9*cs[9] 537 cs[0] -= sum * t0 538 cs[1] -= sum * t1 539 cs[2] -= sum * t2 540 cs[3] -= sum * t3 541 cs[4] -= sum * t4 542 cs[5] -= sum * t5 543 cs[6] -= sum * t6 544 cs[7] -= sum * t7 545 cs[8] -= sum * t8 546 cs[9] -= sum * t9 547 } 548 return 549 } 550 }