dlaqr1.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. package gonum
  5. import "math"
  6. // Dlaqr1 sets v to a scalar multiple of the first column of the product
  7. // (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I)
  8. // where H is a 2×2 or 3×3 matrix, I is the identity matrix of the same size,
  9. // and i is the imaginary unit. Scaling is done to avoid overflows and most
  10. // underflows.
  11. //
  12. // n is the order of H and must be either 2 or 3. It must hold that either sr1 =
  13. // sr2 and si1 = -si2, or si1 = si2 = 0. The length of v must be equal to n. If
  14. // any of these conditions is not met, Dlaqr1 will panic.
  15. //
  16. // Dlaqr1 is an internal routine. It is exported for testing purposes.
  17. func (impl Implementation) Dlaqr1(n int, h []float64, ldh int, sr1, si1, sr2, si2 float64, v []float64) {
  18. switch {
  19. case n != 2 && n != 3:
  20. panic("lapack: n must be 2 or 3")
  21. case ldh < n:
  22. panic(badLdH)
  23. case len(h) < (n-1)*ldh+n:
  24. panic(shortH)
  25. case !((sr1 == sr2 && si1 == -si2) || (si1 == 0 && si2 == 0)):
  26. panic(badShifts)
  27. case len(v) != n:
  28. panic(shortV)
  29. }
  30. if n == 2 {
  31. s := math.Abs(h[0]-sr2) + math.Abs(si2) + math.Abs(h[ldh])
  32. if s == 0 {
  33. v[0] = 0
  34. v[1] = 0
  35. } else {
  36. h21s := h[ldh] / s
  37. v[0] = h21s*h[1] + (h[0]-sr1)*((h[0]-sr2)/s) - si1*(si2/s)
  38. v[1] = h21s * (h[0] + h[ldh+1] - sr1 - sr2)
  39. }
  40. return
  41. }
  42. s := math.Abs(h[0]-sr2) + math.Abs(si2) + math.Abs(h[ldh]) + math.Abs(h[2*ldh])
  43. if s == 0 {
  44. v[0] = 0
  45. v[1] = 0
  46. v[2] = 0
  47. } else {
  48. h21s := h[ldh] / s
  49. h31s := h[2*ldh] / s
  50. v[0] = (h[0]-sr1)*((h[0]-sr2)/s) - si1*(si2/s) + h[1]*h21s + h[2]*h31s
  51. v[1] = h21s*(h[0]+h[ldh+1]-sr1-sr2) + h[ldh+2]*h31s
  52. v[2] = h31s*(h[0]+h[2*ldh+2]-sr1-sr2) + h21s*h[2*ldh+1]
  53. }
  54. }