1#![warn(clippy::pedantic)]
5#![warn(clippy::cargo)]
6#![warn(clippy::dbg_macro)]
8#![warn(clippy::print_stdout)]
9#![warn(clippy::print_stderr)]
10#![warn(clippy::undocumented_unsafe_blocks)]
11#![warn(clippy::unnecessary_safety_doc)]
12#![warn(clippy::unwrap_used)]
13
14pub use num;
15
16#[macro_export]
34macro_rules! complex {
35 () => {{
36 <$crate::num::Complex<_> as $crate::num::Zero>::zero()
37 }};
38 ($re:expr) => {{
39 $crate::num::Complex::new(
40 $re,
41 <$crate::num::Complex<_> as $crate::num::Zero>::zero().im,
42 )
43 }};
44 ($re:expr, $im: expr) => {{
45 $crate::num::Complex::new($re, $im)
46 }};
47}
48
49#[macro_export]
85macro_rules! poly {
86 () => {{
87 <$crate::Poly<_> as $crate::num::Zero>::zero()
88 }};
89 (($re:expr, $im:expr); $n:expr) => {{
90 $crate::Poly::from_complex_vec(vec![$crate::complex!($re, $im); $n])
91 }};
92 ($elem:expr; $n:expr) => {{
93 $crate::Poly::from_real_vec(vec![$elem; $n])
94 }};
95 ($(($re:expr, $im:expr)),+ $(,)?) => {{
96 $crate::Poly::from_complex_vec(vec![$($crate::complex!($re, $im)),*])
97 }};
98 ($($elems:expr),+ $(,)?) => {{
99 $crate::Poly::from_real_vec(vec![$($elems),*])
100 }};
101}
102
103mod scalar;
104pub use scalar::RealScalar;
105
106mod poly;
107pub use poly::{roots, Poly};
108
109pub(crate) mod util;
110pub use util::__testing;
111
112pub(crate) mod base;
113
114pub type Poly32 = Poly<f32>;
115pub type Poly64 = Poly<f64>;
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use num::{Complex, One, Zero};
121
122 #[test]
123 fn macro_complex() {
124 assert_eq!(complex!(), Complex::<f64>::zero());
125 assert_eq!(complex!(1.0, 2.0), Complex::<f64>::new(1.0, 2.0));
126 }
127
128 #[test]
129 fn macro_poly() {
130 assert_eq!(poly!(), Poly::<f64>::zero());
131 assert_eq!(poly!(1.0), Poly::<f64>::one());
132 assert_eq!(
133 poly!(1.0, 2.0, 3.0),
134 Poly::<f64>::new(&[
135 Complex::new(1.0, 0.0),
136 Complex::new(2.0, 0.0),
137 Complex::new(3.0, 0.0),
138 ])
139 );
140 assert_eq!(poly!((1.0, 0.0)), Poly::<f64>::one());
141 assert_eq!(
142 poly!((1.0, 1.0), (2.0, 2.0), (3.0, 3.0)),
143 Poly::<f64>::new(&[
144 Complex::new(1.0, 1.0),
145 Complex::new(2.0, 2.0),
146 Complex::new(3.0, 3.0)
147 ])
148 );
149 assert_eq!(
150 poly!(2.0; 3),
151 Poly::<f64>::new(&[
152 Complex::new(2.0, 0.0),
153 Complex::new(2.0, 0.0),
154 Complex::new(2.0, 0.0)
155 ])
156 );
157 assert_eq!(
158 poly!((1.0, -1.0); 3),
159 Poly::<f64>::new(&[
160 Complex::new(1.0, -1.0),
161 Complex::new(1.0, -1.0),
162 Complex::new(1.0, -1.0)
163 ])
164 );
165 }
166
167 #[test]
168 fn poly_new() {
169 Poly::new(&[Complex::new(2.0, -2.0)]);
171 }
172
173 #[test]
174 fn poly_from_complex_slice() {
175 let p = Poly::from_complex_slice(&[Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
176 let e = poly!((1.0, 2.0), (3.0, 4.0));
177 assert_eq!(p, e);
178 }
179
180 #[test]
183 fn poly_line() {
184 let p = Poly::<f64>::line(Complex::<f64>::new(1.0, 0.0), Complex::<f64>::new(2.0, 0.0));
185 let e = poly!(1.0, 2.0);
186 assert_eq!(p, e);
187 }
188
189 #[test]
190 fn poly_term() {
191 let p = Poly64::term(complex!(2.0), 2);
192 let e = poly!(0.0, 0.0, 2.0);
193 assert_eq!(p, e);
194 }
195
196 #[test]
197 fn poly_bessel() {
198 assert_eq!(Poly64::bessel(0).unwrap(), poly![1.0]);
199 assert_eq!(Poly64::bessel(1).unwrap(), poly![1.0, 1.0]);
200 assert_eq!(Poly64::bessel(2).unwrap(), poly![1.0, 3.0, 3.0]);
201 assert_eq!(Poly64::bessel(3).unwrap(), poly![1.0, 6.0, 15.0, 15.0]);
202 }
203
204 #[test]
205 fn poly_reverse_bessel() {
206 assert_eq!(Poly64::reverse_bessel(0).unwrap(), poly![1.0]);
207 assert_eq!(Poly64::reverse_bessel(1).unwrap(), poly![1.0, 1.0]);
208 assert_eq!(Poly64::reverse_bessel(2).unwrap(), poly![3.0, 3.0, 1.0]);
209 assert_eq!(
210 Poly64::reverse_bessel(3).unwrap(),
211 poly![15.0, 15.0, 6.0, 1.0]
212 );
213 }
214}