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 type Poly32 = Poly<f32>;
113pub type Poly64 = Poly<f64>;
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use num::{Complex, One, Zero};
119
120 #[test]
121 fn macro_complex() {
122 assert_eq!(complex!(), Complex::<f64>::zero());
123 assert_eq!(complex!(1.0, 2.0), Complex::<f64>::new(1.0, 2.0));
124 }
125
126 #[test]
127 fn macro_poly() {
128 assert_eq!(poly!(), Poly::<f64>::zero());
129 assert_eq!(poly!(1.0), Poly::<f64>::one());
130 assert_eq!(
131 poly!(1.0, 2.0, 3.0),
132 Poly::<f64>::new(&[
133 Complex::new(1.0, 0.0),
134 Complex::new(2.0, 0.0),
135 Complex::new(3.0, 0.0),
136 ])
137 );
138 assert_eq!(poly!((1.0, 0.0)), Poly::<f64>::one());
139 assert_eq!(
140 poly!((1.0, 1.0), (2.0, 2.0), (3.0, 3.0)),
141 Poly::<f64>::new(&[
142 Complex::new(1.0, 1.0),
143 Complex::new(2.0, 2.0),
144 Complex::new(3.0, 3.0)
145 ])
146 );
147 assert_eq!(
148 poly!(2.0; 3),
149 Poly::<f64>::new(&[
150 Complex::new(2.0, 0.0),
151 Complex::new(2.0, 0.0),
152 Complex::new(2.0, 0.0)
153 ])
154 );
155 assert_eq!(
156 poly!((1.0, -1.0); 3),
157 Poly::<f64>::new(&[
158 Complex::new(1.0, -1.0),
159 Complex::new(1.0, -1.0),
160 Complex::new(1.0, -1.0)
161 ])
162 );
163 }
164
165 #[test]
166 fn poly_new() {
167 Poly::new(&[Complex::new(2.0, -2.0)]);
169 }
170
171 #[test]
172 fn poly_from_complex_slice() {
173 let p = Poly::from_complex_slice(&[Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
174 let e = poly!((1.0, 2.0), (3.0, 4.0));
175 assert_eq!(p, e);
176 }
177
178 #[test]
181 fn poly_line() {
182 let p = Poly::<f64>::line(Complex::<f64>::new(1.0, 0.0), Complex::<f64>::new(2.0, 0.0));
183 let e = poly!(1.0, 2.0);
184 assert_eq!(p, e);
185 }
186
187 #[test]
188 fn poly_term() {
189 let p = Poly64::term(complex!(2.0), 2);
190 let e = poly!(0.0, 0.0, 2.0);
191 assert_eq!(p, e);
192 }
193
194 #[test]
195 fn poly_bessel() {
196 assert_eq!(Poly64::bessel(0).unwrap(), poly![1.0]);
197 assert_eq!(Poly64::bessel(1).unwrap(), poly![1.0, 1.0]);
198 assert_eq!(Poly64::bessel(2).unwrap(), poly![1.0, 3.0, 3.0]);
199 assert_eq!(Poly64::bessel(3).unwrap(), poly![1.0, 6.0, 15.0, 15.0]);
200 }
201
202 #[test]
203 fn poly_reverse_bessel() {
204 assert_eq!(Poly64::reverse_bessel(0).unwrap(), poly![1.0]);
205 assert_eq!(Poly64::reverse_bessel(1).unwrap(), poly![1.0, 1.0]);
206 assert_eq!(Poly64::reverse_bessel(2).unwrap(), poly![3.0, 3.0, 1.0]);
207 assert_eq!(
208 Poly64::reverse_bessel(3).unwrap(),
209 poly![15.0, 15.0, 6.0, 1.0]
210 );
211 }
212}