faer/linalg/evd/schur/
mod.rs1use super::*;
2pub(crate) mod complex_schur;
3pub(crate) mod real_schur;
4#[derive(Clone, Copy, Debug)]
5pub struct SchurParams {
6 pub recommended_shift_count: extern "C" fn(
9 matrix_dimension: usize,
10 active_block_dimension: usize,
11 ) -> usize,
12 pub recommended_deflation_window: extern "C" fn(
15 matrix_dimension: usize,
16 active_block_dimension: usize,
17 ) -> usize,
18 pub blocking_threshold: usize,
20 pub nibble_threshold: usize,
23 #[doc(hidden)]
24 pub non_exhaustive: NonExhaustive,
25}
26impl<T: ComplexField> Auto<T> for SchurParams {
27 fn auto() -> Self {
28 Self {
29 recommended_shift_count: default_recommended_shift_count,
30 recommended_deflation_window: default_recommended_deflation_window,
31 blocking_threshold: 75,
32 nibble_threshold: 50,
33 non_exhaustive: NonExhaustive(()),
34 }
35 }
36}
37pub fn multishift_qr_scratch<T: ComplexField>(
38 n: usize,
39 nh: usize,
40 want_t: bool,
41 want_z: bool,
42 parallelism: Par,
43 params: SchurParams,
44) -> StackReq {
45 let nsr = (params.recommended_shift_count)(n, nh);
46 let _ = want_t;
47 let _ = want_z;
48 if n <= 3 {
49 return StackReq::EMPTY;
50 }
51 let nw_max = (n - 3) / 3;
52 StackReq::any_of(&[
53 hessenberg::hessenberg_in_place_scratch::<T>(nw_max, 1, parallelism, Default::default()),
54 linalg::householder::apply_block_householder_sequence_transpose_on_the_left_in_place_scratch::<T>(nw_max, nw_max, nw_max),
55 linalg::householder::apply_block_householder_sequence_on_the_right_in_place_scratch::<T>(nw_max, nw_max, nw_max),
56 temp_mat_scratch::<T>(3, nsr),
57 ])
58}
59extern "C" fn default_recommended_shift_count(
60 dim: usize,
61 _active_block_dim: usize,
62) -> usize {
63 let n = dim;
64 if n < 30 {
65 2
66 } else if n < 60 {
67 4
68 } else if n < 150 {
69 12
70 } else if n < 590 {
71 32
72 } else if n < 3000 {
73 64
74 } else if n < 6000 {
75 128
76 } else {
77 256
78 }
79}
80extern "C" fn default_recommended_deflation_window(
81 dim: usize,
82 _active_block_dim: usize,
83) -> usize {
84 let n = dim;
85 if n < 30 {
86 2
87 } else if n < 60 {
88 4
89 } else if n < 150 {
90 10
91 } else if n < 590 {
92 #[cfg(feature = "std")]
93 {
94 (n as f64 / (n as f64).log2()) as usize
95 }
96 #[cfg(not(feature = "std"))]
97 {
98 libm::log2(n as f64 / (n as f64)) as usize
99 }
100 } else if n < 3000 {
101 96
102 } else if n < 6000 {
103 192
104 } else {
105 384
106 }
107}