1use super::householder::{reflection, reflector};
8use super::properties::range_exponent;
9use super::{Matrix, Scalar};
10use crate::math::complex::{Complex, Float};
11
12mod deflate;
13mod hessenberg;
14mod multishift;
15mod vectors;
16
17pub(crate) use hessenberg::hessenberg;
18use multishift::multishift;
19pub(crate) use vectors::eigenvectors;
20
21#[derive(Clone, Debug)]
43pub struct Schur<T: Scalar> {
44 q: Matrix<T>,
46 t: Matrix<T>,
48 values: Vec<Complex<T::Real>>,
50}
51
52impl<T: Scalar> Matrix<T> {
53 #[track_caller]
62 pub fn schur(&self) -> Schur<T> {
63 assert!(self.is_square(), "the matrix is not square");
64 let (t, q, values) = schur(self, true, true);
65 Schur {
66 q: q.unwrap_or_default(),
67 t,
68 values,
69 }
70 }
71
72 #[track_caller]
80 pub fn eigenvalues(&self) -> Vec<Complex<T::Real>> {
81 assert!(self.is_square(), "the matrix is not square");
82 schur(self, false, false).2
83 }
84}
85
86impl<T: Scalar> Schur<T> {
87 pub fn q(&self) -> Matrix<T> {
89 self.q.clone()
90 }
91
92 pub fn t(&self) -> Matrix<T> {
94 self.t.clone()
95 }
96
97 pub fn eigenvalues(&self) -> &[Complex<T::Real>] {
100 &self.values
101 }
102}
103
104#[allow(clippy::type_complexity)]
107pub(crate) fn schur<T: Scalar>(
108 a: &Matrix<T>,
109 want_t: bool,
110 want_q: bool,
111) -> (Matrix<T>, Option<Matrix<T>>, Vec<Complex<T::Real>>) {
112 let n = a.rows();
113 if a.data.iter().any(|x| !x.is_finite()) {
114 let nan = T::from_parts(T::Real::NAN, T::Real::NAN);
115 let all = Matrix::from_fn(n, n, |_, _| nan);
116 let w = vec![Complex::new(T::Real::NAN, T::Real::NAN); n];
117 return (all.clone(), want_q.then_some(all), w);
118 }
119 let mut h = a.clone();
120 let k = range_exponent(&h.data);
124 if k != 0 {
125 let up = T::Real::TWO.powi(k);
126 for x in &mut h.data {
127 *x = x.scale(up);
128 }
129 }
130 let mut q = hessenberg(&mut h, want_q);
131 let mut w = vec![Complex::new(T::Real::ZERO, T::Real::ZERO); n];
132 let z = q.as_mut().map(|q| q.data.as_mut_slice());
133 let info = multishift(want_t, &mut h.data, n, z, &mut w, false);
134 w[..info].fill(Complex::new(T::Real::NAN, T::Real::NAN));
135 if want_t && info == 0 {
136 for j in 0..n {
138 let from = if T::IS_COMPLEX { j + 1 } else { j + 2 };
139 for i in from..n {
140 h.data[i + j * n] = T::zero();
141 }
142 }
143 }
144 if k != 0 {
145 let down = T::Real::TWO.powi(-k);
146 for x in &mut h.data {
147 *x = x.scale(down);
148 }
149 for w in &mut w {
150 *w = Complex::new(w.re * down, w.im * down);
151 }
152 }
153 (h, q, w)
154}
155
156fn small_qr<T: Scalar>(
162 h: &mut [T],
163 n: usize,
164 z: Option<&mut [T]>,
165 want_t: bool,
166 w: &mut [Complex<T::Real>],
167) -> usize {
168 if T::IS_COMPLEX {
169 return complex_qr(h, n, z, want_t, w);
170 }
171 let mut hr: Vec<T::Real> = h.iter().map(|x| x.re()).collect();
172 let mut zr: Option<Vec<T::Real>> = z.as_deref().map(|z| z.iter().map(|x| x.re()).collect());
173 let info = real_qr(&mut hr, n, zr.as_deref_mut(), want_t, w);
174 for (x, r) in h.iter_mut().zip(hr) {
175 *x = T::from_real(r);
176 }
177 if let (Some(z), Some(zr)) = (z, zr) {
178 for (x, r) in z.iter_mut().zip(zr) {
179 *x = T::from_real(r);
180 }
181 }
182 info
183}
184
185const EXCEPTIONAL: usize = 10;
187
188#[inline]
190fn rotate<R: Float>(x: &mut R, y: &mut R, c: R, s: R) {
191 let t = c * *x + s * *y;
192 *y = c * *y - s * *x;
193 *x = t;
194}
195
196fn real_qr<R: Float>(
201 h: &mut [R],
202 n: usize,
203 mut z: Option<&mut [R]>,
204 want_t: bool,
205 w: &mut [Complex<R>],
206) -> usize {
207 let at = |i: usize, j: usize| i + j * n;
208 if n == 0 {
209 return 0;
210 }
211 let ulp = R::EPSILON;
212 let smlnum = R::MIN_POSITIVE * (R::from_f64(n as f64) / ulp);
213 let max_its = 30 * n.max(10);
214 let mut kdefl = 0;
215 let mut i = n - 1;
217 loop {
218 let mut l = 0;
219 let mut converged = false;
220 for _ in 0..=max_its {
221 let mut k = i;
223 while k > l {
224 let sub = h[at(k, k - 1)].abs();
225 if sub <= smlnum {
226 break;
227 }
228 let mut tst = h[at(k - 1, k - 1)].abs() + h[at(k, k)].abs();
229 if tst == R::ZERO {
230 if k >= 2 {
231 tst += h[at(k - 1, k - 2)].abs();
232 }
233 if k + 1 < n {
234 tst += h[at(k + 1, k)].abs();
235 }
236 }
237 if sub <= ulp * tst {
239 let up = h[at(k - 1, k)].abs();
240 let (ab, ba) = (sub.max(up), sub.min(up));
241 let d = (h[at(k - 1, k - 1)] - h[at(k, k)]).abs();
242 let hk = h[at(k, k)].abs();
243 let (aa, bb) = (hk.max(d), hk.min(d));
244 let s = aa + ab;
245 if ba * (ab / s) <= smlnum.max(ulp * (bb * (aa / s))) {
246 break;
247 }
248 }
249 k -= 1;
250 }
251 l = k;
252 if l > 0 {
253 h[at(l, l - 1)] = R::ZERO;
254 }
255 if l + 1 >= i {
256 converged = true;
257 break;
258 }
259 kdefl += 1;
260 let (i1, i2) = if want_t { (0, n - 1) } else { (l, i) };
261 let (h11, h12, h21, h22) = if kdefl % (2 * EXCEPTIONAL) == 0 {
263 let s = h[at(i, i - 1)].abs() + h[at(i - 1, i - 2)].abs();
264 let h11 = R::from_f64(0.75) * s + h[at(i, i)];
265 (h11, R::from_f64(-0.4375) * s, s, h11)
266 } else if kdefl % EXCEPTIONAL == 0 {
267 let s = h[at(l + 1, l)].abs() + h[at(l + 2, l + 1)].abs();
268 let h11 = R::from_f64(0.75) * s + h[at(l, l)];
269 (h11, R::from_f64(-0.4375) * s, s, h11)
270 } else {
271 (
272 h[at(i - 1, i - 1)],
273 h[at(i - 1, i)],
274 h[at(i, i - 1)],
275 h[at(i, i)],
276 )
277 };
278 let s = h11.abs() + h12.abs() + h21.abs() + h22.abs();
279 let (rt1r, rt1i, rt2r, rt2i);
280 if s == R::ZERO {
281 (rt1r, rt1i, rt2r, rt2i) = (R::ZERO, R::ZERO, R::ZERO, R::ZERO);
282 } else {
283 let (h11, h12, h21, h22) = (h11 / s, h12 / s, h21 / s, h22 / s);
284 let tr = (h11 + h22) * R::HALF;
285 let det = (h11 - tr) * (h22 - tr) - h12 * h21;
286 let rtdisc = det.abs().sqrt();
287 if det >= R::ZERO {
288 rt1r = tr * s;
289 rt2r = rt1r;
290 rt1i = rtdisc * s;
291 rt2i = -rt1i;
292 } else {
293 let (a, b) = (tr + rtdisc, tr - rtdisc);
295 let r = if (a - h22).abs() <= (b - h22).abs() {
296 a * s
297 } else {
298 b * s
299 };
300 (rt1r, rt2r, rt1i, rt2i) = (r, r, R::ZERO, R::ZERO);
301 }
302 }
303 let mut m = i - 2;
305 let mut v = [R::ZERO; 3];
306 loop {
307 let h21s = h[at(m + 1, m)];
308 let s = (h[at(m, m)] - rt2r).abs() + rt2i.abs() + h21s.abs();
309 let h21s = h21s / s;
310 v[0] = h21s * h[at(m, m + 1)] + (h[at(m, m)] - rt1r) * ((h[at(m, m)] - rt2r) / s)
311 - rt1i * (rt2i / s);
312 v[1] = h21s * (h[at(m, m)] + h[at(m + 1, m + 1)] - rt1r - rt2r);
313 v[2] = h21s * h[at(m + 2, m + 1)];
314 let s = v[0].abs() + v[1].abs() + v[2].abs();
315 for x in &mut v {
316 *x /= s;
317 }
318 if m == l {
319 break;
320 }
321 let h00 = h[at(m, m - 1)].abs() * (v[1].abs() + v[2].abs());
322 let h01 = v[0].abs()
323 * (h[at(m - 1, m - 1)].abs() + h[at(m, m)].abs() + h[at(m + 1, m + 1)].abs());
324 if h00 <= ulp * h01 {
325 break;
326 }
327 m -= 1;
328 }
329 for k in m..i {
331 let nr = 3.min(i - k + 1);
332 if k > m {
333 for p in 0..nr {
334 v[p] = h[at(k + p, k - 1)];
335 }
336 }
337 let (t1, beta) = {
338 let (first, rest) = v.split_at_mut(1);
339 real_reflector(first[0], &mut rest[..nr - 1])
340 };
341 v[0] = beta;
342 if k > m {
343 h[at(k, k - 1)] = v[0];
344 h[at(k + 1, k - 1)] = R::ZERO;
345 if k + 2 < i + 1 {
346 h[at(k + 2, k - 1)] = R::ZERO;
347 }
348 } else if m > l {
349 h[at(k, k - 1)] = h[at(k, k - 1)] * (R::ONE - t1);
351 }
352 let v2 = v[1];
353 let t2 = t1 * v2;
354 if nr == 3 {
355 let v3 = v[2];
356 let t3 = t1 * v3;
357 for j in k..=i2 {
358 let sum = h[at(k, j)] + v2 * h[at(k + 1, j)] + v3 * h[at(k + 2, j)];
359 h[at(k, j)] -= sum * t1;
360 h[at(k + 1, j)] -= sum * t2;
361 h[at(k + 2, j)] -= sum * t3;
362 }
363 for j in i1..=(k + 3).min(i) {
364 let sum = h[at(j, k)] + v2 * h[at(j, k + 1)] + v3 * h[at(j, k + 2)];
365 h[at(j, k)] -= sum * t1;
366 h[at(j, k + 1)] -= sum * t2;
367 h[at(j, k + 2)] -= sum * t3;
368 }
369 if let Some(z) = z.as_deref_mut() {
370 for j in 0..n {
371 let sum = z[at(j, k)] + v2 * z[at(j, k + 1)] + v3 * z[at(j, k + 2)];
372 z[at(j, k)] -= sum * t1;
373 z[at(j, k + 1)] -= sum * t2;
374 z[at(j, k + 2)] -= sum * t3;
375 }
376 }
377 } else {
378 for j in k..=i2 {
379 let sum = h[at(k, j)] + v2 * h[at(k + 1, j)];
380 h[at(k, j)] -= sum * t1;
381 h[at(k + 1, j)] -= sum * t2;
382 }
383 for j in i1..=i {
384 let sum = h[at(j, k)] + v2 * h[at(j, k + 1)];
385 h[at(j, k)] -= sum * t1;
386 h[at(j, k + 1)] -= sum * t2;
387 }
388 if let Some(z) = z.as_deref_mut() {
389 for j in 0..n {
390 let sum = z[at(j, k)] + v2 * z[at(j, k + 1)];
391 z[at(j, k)] -= sum * t1;
392 z[at(j, k + 1)] -= sum * t2;
393 }
394 }
395 }
396 }
397 }
398 if !converged {
399 return i + 1;
400 }
401 if l == i {
402 w[i] = Complex::new(h[at(i, i)], R::ZERO);
403 } else {
404 let (a, b, c, d) = (
406 h[at(i - 1, i - 1)],
407 h[at(i - 1, i)],
408 h[at(i, i - 1)],
409 h[at(i, i)],
410 );
411 let s = standardize(a, b, c, d);
412 h[at(i - 1, i - 1)] = s.a;
413 h[at(i - 1, i)] = s.b;
414 h[at(i, i - 1)] = s.c;
415 h[at(i, i)] = s.d;
416 w[i - 1] = Complex::new(s.rt1r, s.rt1i);
417 w[i] = Complex::new(s.rt2r, s.rt2i);
418 if want_t {
419 for j in i + 1..n {
420 let (x, y) = (h[at(i - 1, j)], h[at(i, j)]);
421 let (mut x, mut y) = (x, y);
422 rotate(&mut x, &mut y, s.cs, s.sn);
423 h[at(i - 1, j)] = x;
424 h[at(i, j)] = y;
425 }
426 for j in 0..i - 1 {
427 let (mut x, mut y) = (h[at(j, i - 1)], h[at(j, i)]);
428 rotate(&mut x, &mut y, s.cs, s.sn);
429 h[at(j, i - 1)] = x;
430 h[at(j, i)] = y;
431 }
432 }
433 if let Some(z) = z.as_deref_mut() {
434 for j in 0..n {
435 let (mut x, mut y) = (z[at(j, i - 1)], z[at(j, i)]);
436 rotate(&mut x, &mut y, s.cs, s.sn);
437 z[at(j, i - 1)] = x;
438 z[at(j, i)] = y;
439 }
440 }
441 }
442 kdefl = 0;
443 if l == 0 {
444 break;
445 }
446 i = l - 1;
447 }
448 0
449}
450
451fn real_reflector<R: Float>(alpha: R, x: &mut [R]) -> (R, R) {
454 let big = x.iter().fold(alpha.abs(), |m, v| m.max(v.abs()));
455 if moderate(big) {
456 let squares = x.iter().fold(R::ZERO, |s, v| s + *v * *v);
457 if squares == R::ZERO {
458 return (R::ZERO, alpha);
459 }
460 let beta = -(alpha * alpha + squares).sqrt().copysign(alpha);
461 return (real_reflection(alpha, beta, x), beta);
462 }
463 let mut scale = R::ZERO;
464 for v in x.iter() {
465 scale = scale.max(v.abs());
466 }
467 if scale == R::ZERO {
468 return (R::ZERO, alpha);
469 }
470 let mut s = R::ZERO;
471 for v in x.iter() {
472 let t = *v / scale;
473 s += t * t;
474 }
475 let xnorm = s.sqrt() * scale;
476 let beta = -alpha.hypot(xnorm).copysign(alpha);
477 let small = R::MIN_POSITIVE / R::EPSILON;
480 if beta.abs() < small {
481 let up = R::ONE / small;
482 for v in x.iter_mut() {
483 *v *= up;
484 }
485 let (tau, beta) = real_reflector(alpha * up, x);
486 return (tau, beta * small);
487 }
488 (real_reflection(alpha, beta, x), beta)
489}
490
491fn real_reflection<R: Float>(alpha: R, beta: R, x: &mut [R]) -> R {
495 let d = alpha - beta;
496 if !d.is_finite() {
497 let r = R::ONE / (alpha * R::HALF - beta * R::HALF);
498 for v in x.iter_mut() {
499 *v = *v * r * R::HALF;
500 }
501 } else {
502 let r = R::ONE / d;
503 if r.is_finite() {
504 for v in x.iter_mut() {
505 *v *= r;
506 }
507 } else {
508 for v in x.iter_mut() {
509 *v /= d;
510 }
511 }
512 }
513 R::ONE - alpha / beta
514}
515
516struct Standard<R> {
518 a: R,
519 b: R,
520 c: R,
521 d: R,
522 rt1r: R,
523 rt1i: R,
524 rt2r: R,
525 rt2i: R,
526 cs: R,
527 sn: R,
528}
529
530fn standardize<R: Float>(mut a: R, mut b: R, mut c: R, mut d: R) -> Standard<R> {
534 let (mut cs, mut sn) = (R::ONE, R::ZERO);
535 let sign = |x: R, y: R| x.abs().copysign(y);
536 if c == R::ZERO {
537 } else if b == R::ZERO {
538 cs = R::ZERO;
540 sn = R::ONE;
541 core::mem::swap(&mut a, &mut d);
542 b = -c;
543 c = R::ZERO;
544 } else if a - d == R::ZERO && b.is_sign_negative() != c.is_sign_negative() {
545 } else {
546 let temp = a - d;
547 let mut p = temp * R::HALF;
548 let bcmax = b.abs().max(c.abs());
549 let bcmis = b.abs().min(c.abs()) * sign(R::ONE, b) * sign(R::ONE, c);
550 let scale = p.abs().max(bcmax);
551 let mut z = (p / scale) * p + (bcmax / scale) * bcmis;
552 if z >= R::from_f64(4.0) * R::EPSILON {
553 z = p + sign(scale.sqrt() * z.sqrt(), p);
555 a = d + z;
556 d -= (bcmax / z) * bcmis;
557 let tau = c.hypot(z);
558 cs = z / tau;
559 sn = c / tau;
560 b -= c;
561 c = R::ZERO;
562 } else {
563 let sigma = b + c;
565 let tau = sigma.hypot(temp);
566 cs = (R::HALF * (R::ONE + sigma.abs() / tau)).sqrt();
567 sn = -(temp * R::HALF / (tau * cs)) * sign(R::ONE, sigma);
568 let aa = a * cs + b * sn;
569 let bb = -a * sn + b * cs;
570 let cc = c * cs + d * sn;
571 let dd = -c * sn + d * cs;
572 a = aa * cs + cc * sn;
573 b = bb * cs + dd * sn;
574 c = -aa * sn + cc * cs;
575 d = -bb * sn + dd * cs;
576 let temp = R::HALF * (a + d);
577 a = temp;
578 d = temp;
579 if c != R::ZERO {
580 if b != R::ZERO {
581 if b.is_sign_negative() == c.is_sign_negative() {
582 let sab = b.abs().sqrt();
584 let sac = c.abs().sqrt();
585 p = sign(sab * sac, c);
586 let tau = R::ONE / (b + c).abs().sqrt();
587 a = temp + p;
588 d = temp - p;
589 b -= c;
590 c = R::ZERO;
591 let cs1 = sab * tau;
592 let sn1 = sac * tau;
593 let t = cs * cs1 - sn * sn1;
594 sn = cs * sn1 + sn * cs1;
595 cs = t;
596 }
597 } else {
598 b = -c;
599 c = R::ZERO;
600 let t = cs;
601 cs = -sn;
602 sn = t;
603 }
604 }
605 }
606 }
607 let (rt1i, rt2i) = if c == R::ZERO {
608 (R::ZERO, R::ZERO)
609 } else {
610 let r = b.abs().sqrt() * c.abs().sqrt();
611 (r, -r)
612 };
613 Standard {
614 a,
615 b,
616 c,
617 d,
618 rt1r: a,
619 rt1i,
620 rt2r: d,
621 rt2i,
622 cs,
623 sn,
624 }
625}
626
627#[inline]
629fn abs1<C: Scalar>(x: C) -> C::Real {
630 x.re().abs() + x.im().abs()
631}
632
633#[inline]
636fn moderate<R: Float>(big: R) -> bool {
637 let (low, high) = if R::MANTISSA_DIGITS > 24 {
638 (1e-130, 1e130)
639 } else {
640 (1e-15, 1e15)
641 };
642 R::from_f64(low) < big && big < R::from_f64(high)
643}
644
645#[inline]
648fn short_reflector<C: Scalar>(alpha: C, x: &mut [C]) -> (C, C) {
649 let zero = C::Real::ZERO;
650 let big = x
651 .iter()
652 .fold(alpha.re().abs().max(alpha.im().abs()), |m, v| {
653 m.max(v.re().abs()).max(v.im().abs())
654 });
655 if !moderate(big) {
656 return reflector(alpha, x);
657 }
658 let squares = x.iter().fold(zero, |s, v| s + v.abs2());
659 if squares == zero && alpha.im() == zero {
660 return (C::zero(), alpha);
661 }
662 reflection(alpha, (alpha.abs2() + squares).sqrt(), x)
663}
664
665fn complex_qr<C: Scalar>(
670 h: &mut [C],
671 n: usize,
672 mut z: Option<&mut [C]>,
673 want_t: bool,
674 w: &mut [Complex<C::Real>],
675) -> usize {
676 let at = |i: usize, j: usize| i + j * n;
677 let zero = C::Real::ZERO;
678 if n == 0 {
679 return 0;
680 }
681 for i in 1..n {
683 let x = h[at(i, i - 1)];
684 if x.im() != zero {
685 let a = x.abs();
686 let sc = x.conj().scale(C::Real::ONE / a);
687 h[at(i, i - 1)] = C::from_real(a);
688 let jhi = n - 1;
689 for j in i..=jhi {
690 h[at(i, j)] *= sc;
691 }
692 for j in 0..=(i + 1).min(jhi) {
693 h[at(j, i)] *= sc.conj();
694 }
695 if let Some(z) = z.as_deref_mut() {
696 for j in 0..n {
697 z[at(j, i)] *= sc.conj();
698 }
699 }
700 }
701 }
702 let ulp = C::Real::EPSILON;
703 let smlnum = C::Real::MIN_POSITIVE * (C::Real::from_f64(n as f64) / ulp);
704 let max_its = 30 * n.max(10);
705 let mut kdefl = 0;
706 let mut i = n - 1;
707 loop {
708 let mut l = 0;
709 let mut converged = false;
710 for _ in 0..=max_its {
711 let mut k = i;
712 while k > l {
713 let sub = abs1(h[at(k, k - 1)]);
714 if sub <= smlnum {
715 break;
716 }
717 let mut tst = abs1(h[at(k - 1, k - 1)]) + abs1(h[at(k, k)]);
718 if tst == zero {
719 if k >= 2 {
720 tst += h[at(k - 1, k - 2)].re().abs();
721 }
722 if k + 1 < n {
723 tst += h[at(k + 1, k)].re().abs();
724 }
725 }
726 if h[at(k, k - 1)].re().abs() <= ulp * tst {
727 let up = abs1(h[at(k - 1, k)]);
728 let (ab, ba) = (sub.max(up), sub.min(up));
729 let d = abs1(h[at(k - 1, k - 1)] - h[at(k, k)]);
730 let hk = abs1(h[at(k, k)]);
731 let (aa, bb) = (hk.max(d), hk.min(d));
732 let s = aa + ab;
733 if ba * (ab / s) <= smlnum.max(ulp * (bb * (aa / s))) {
734 break;
735 }
736 }
737 k -= 1;
738 }
739 l = k;
740 if l > 0 {
741 h[at(l, l - 1)] = C::zero();
742 }
743 if l >= i {
744 converged = true;
745 break;
746 }
747 kdefl += 1;
748 let (i1, i2) = if want_t { (0, n - 1) } else { (l, i) };
749 let t = if kdefl % (2 * EXCEPTIONAL) == 0 {
751 let s = C::Real::from_f64(0.75) * h[at(i, i - 1)].re().abs();
752 h[at(i, i)] + C::from_real(s)
753 } else if kdefl % EXCEPTIONAL == 0 {
754 let s = C::Real::from_f64(0.75) * h[at(l + 1, l)].re().abs();
755 h[at(l, l)] + C::from_real(s)
756 } else {
757 let mut t = h[at(i, i)];
758 let u = h[at(i - 1, i)].sqrt() * h[at(i, i - 1)].sqrt();
759 let s = abs1(u);
760 if s != zero {
761 let x = (h[at(i - 1, i - 1)] - t).scale(C::Real::HALF);
762 let sx = abs1(x);
763 let s = s.max(sx);
764 let (xs, us) = (x.scale(C::Real::ONE / s), u.scale(C::Real::ONE / s));
765 let mut y = (xs * xs + us * us).sqrt().scale(s);
766 if sx > zero {
767 let xr = x.scale(C::Real::ONE / sx);
768 if xr.re() * y.re() + xr.im() * y.im() < zero {
769 y = -y;
770 }
771 }
772 t -= u * (u / (x + y));
773 }
774 t
775 };
776 let mut m = i - 1;
778 let mut v: [C; 2];
779 loop {
780 let h11 = h[at(m, m)];
781 let h22 = h[at(m + 1, m + 1)];
782 let h11s = h11 - t;
783 let h21 = h[at(m + 1, m)].re();
784 let s = abs1(h11s) + h21.abs();
785 let (h11s, h21) = (h11s.scale(C::Real::ONE / s), h21 / s);
786 v = [h11s, C::from_real(h21)];
787 if m == l {
788 break;
789 }
790 let h10 = h[at(m, m - 1)].re();
791 if h10.abs() * h21.abs() <= ulp * (abs1(h11s) * (abs1(h11) + abs1(h22))) {
792 break;
793 }
794 m -= 1;
795 }
796 for k in m..i {
798 if k > m {
799 v = [h[at(k, k - 1)], h[at(k + 1, k - 1)]];
800 }
801 let (t1, beta) = {
802 let (first, rest) = v.split_at_mut(1);
803 short_reflector(first[0], rest)
804 };
805 v[0] = beta;
806 if k > m {
807 h[at(k, k - 1)] = v[0];
808 h[at(k + 1, k - 1)] = C::zero();
809 }
810 let v2 = v[1];
811 let t2 = (t1 * v2).re();
812 let (t1c, v2c) = (t1.conj(), v2.conj());
813 for col in h[k * n..(i2 + 1) * n].chunks_exact_mut(n) {
814 let [x, y] = &mut col[k..k + 2] else {
815 unreachable!()
816 };
817 let sum = t1c * *x + y.scale(t2);
818 *x -= sum;
819 *y -= sum * v2;
820 }
821 let turn = |a: &mut [C], rows: core::ops::Range<usize>| {
822 let (x, y) = a[k * n..].split_at_mut(n);
823 for (x, y) in x[rows.clone()].iter_mut().zip(&mut y[rows]) {
824 let sum = t1 * *x + y.scale(t2);
825 *x -= sum;
826 *y -= sum * v2c;
827 }
828 };
829 turn(h, i1..(k + 2).min(i) + 1);
830 if let Some(z) = z.as_deref_mut() {
831 turn(z, 0..n);
832 }
833 if k == m && m > l {
834 let mut temp = C::one() - t1;
836 temp = temp.scale(C::Real::ONE / temp.abs());
837 h[at(m + 1, m)] *= temp.conj();
838 if m + 2 <= i {
839 h[at(m + 2, m + 1)] *= temp;
840 }
841 for j in m..=i {
842 if j != m + 1 {
843 if i2 > j {
844 for c in j + 1..=i2 {
845 h[at(j, c)] *= temp;
846 }
847 }
848 for r in i1..j {
849 h[at(r, j)] *= temp.conj();
850 }
851 if let Some(z) = z.as_deref_mut() {
852 for r in 0..n {
853 z[at(r, j)] *= temp.conj();
854 }
855 }
856 }
857 }
858 }
859 }
860 let temp = h[at(i, i - 1)];
862 if temp.im() != zero {
863 let r = temp.abs();
864 h[at(i, i - 1)] = C::from_real(r);
865 let temp = temp.scale(C::Real::ONE / r);
866 if i2 > i {
867 for c in i + 1..=i2 {
868 h[at(i, c)] *= temp.conj();
869 }
870 }
871 for r in i1..i {
872 h[at(r, i)] *= temp;
873 }
874 if let Some(z) = z.as_deref_mut() {
875 for r in 0..n {
876 z[at(r, i)] *= temp;
877 }
878 }
879 }
880 }
881 if !converged {
882 return i + 1;
883 }
884 w[i] = h[at(i, i)].to_complex();
885 kdefl = 0;
886 if l == 0 {
887 break;
888 }
889 i = l - 1;
890 }
891 0
892}