sparse_ir_minipole/minipole/
con_map.rs1use num_complex::Complex;
8
9type C64 = Complex<f64>;
10
11pub trait ConMap {
14 fn z(&self, w: C64) -> C64;
16 fn w(&self, z: C64) -> C64;
18 fn dz(&self, w: C64) -> C64;
20}
21
22#[derive(Debug, Clone, Copy, PartialEq)]
25pub struct ConMapGeneric {
26 pub w_m: f64,
28 pub dw_h: f64,
30}
31
32impl ConMap for ConMapGeneric {
33 fn z(&self, w: C64) -> C64 {
34 if w == C64::new(0.0, 0.0) {
35 return C64::new(f64::INFINITY, 0.0);
36 }
37 (w - w.inv()) * (0.5 * self.dw_h) + C64::new(0.0, self.w_m)
38 }
39
40 fn w(&self, z: C64) -> C64 {
41 let x = (z - C64::new(0.0, self.w_m)) / self.dw_h;
42 let mut w = x - (x * x + 1.0).sqrt();
43 if w.norm() > 1.0 {
44 w = x * 2.0 - w;
45 }
46 w
47 }
48
49 fn dz(&self, w: C64) -> C64 {
50 if w == C64::new(0.0, 0.0) {
51 return C64::new(f64::INFINITY, 0.0);
52 }
53 (C64::new(1.0, 0.0) + (w * w).inv()) * (0.5 * self.dw_h)
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq)]
60pub struct ConMapGapless {
61 pub w_min: f64,
63}
64
65impl ConMap for ConMapGapless {
66 fn z(&self, w: C64) -> C64 {
67 if w == C64::new(1.0, 0.0) || w == C64::new(-1.0, 0.0) {
68 return C64::new(f64::INFINITY, 0.0);
69 }
70 w * (2.0 * self.w_min) / (C64::new(1.0, 0.0) - w * w)
71 }
72
73 fn w(&self, z: C64) -> C64 {
74 if z == C64::new(0.0, 0.0) {
75 return C64::new(0.0, 0.0);
76 }
77 let wm = self.w_min;
78 let mut w = ((z * z).inv() + 1.0 / (wm * wm)).sqrt() - z.inv();
79 w *= wm;
80 if w.norm() > 1.0 {
81 w = -w - z.inv() * (2.0 * wm);
82 }
83 w
84 }
85
86 fn dz(&self, w: C64) -> C64 {
87 if w == C64::new(1.0, 0.0) || w == C64::new(-1.0, 0.0) {
88 return C64::new(f64::INFINITY, 0.0);
89 }
90 let one = C64::new(1.0, 0.0);
91 let d = one - w * w;
92 (one + w * w) * (2.0 * self.w_min) / (d * d)
93 }
94}