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