rust_poly/poly/
conversions.rs

1use itertools::Itertools;
2use num::Complex;
3
4use crate::{Poly, RealScalar};
5
6impl<T: RealScalar> Poly<T> {
7    #[must_use]
8    pub fn as_slice(&self) -> &[Complex<T>] {
9        self.0.as_slice()
10    }
11
12    pub fn as_mut_slice(&mut self) -> &mut [Complex<T>] {
13        self.0.as_mut_slice()
14    }
15
16    #[must_use]
17    pub fn as_ptr(&self) -> *const Complex<T> {
18        self.0.as_ptr()
19    }
20
21    pub fn as_mut_ptr(&mut self) -> *mut Complex<T> {
22        self.0.as_mut_ptr()
23    }
24
25    /// Iterate over coefficients, from the least significant
26    pub fn iter(&self) -> std::slice::Iter<'_, Complex<T>> {
27        self.0.as_slice().iter()
28    }
29
30    /// Iterate over coefficients, from the least significant
31    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Complex<T>> {
32        self.0.as_mut_slice().iter_mut()
33    }
34
35    #[must_use]
36    pub fn to_vec(&self) -> Vec<Complex<T>> {
37        Vec::from(self.as_slice())
38    }
39
40    /// The same as `Poly::new()`
41    pub fn from_complex_slice(value: &[Complex<T>]) -> Self {
42        Self::new(value)
43    }
44
45    #[allow(clippy::needless_pass_by_value)]
46    #[must_use]
47    pub fn from_complex_vec(value: Vec<Complex<T>>) -> Self {
48        Self::new(value.as_slice())
49    }
50
51    #[must_use]
52    pub fn from_real_slice(value: &[T]) -> Self {
53        Self::from_real_iterator(value.iter().cloned())
54    }
55
56    #[allow(clippy::needless_pass_by_value)]
57    #[must_use]
58    pub fn from_real_vec(value: Vec<T>) -> Self {
59        Self::from_real_slice(value.as_slice())
60    }
61
62    #[must_use]
63    pub fn from_real_iterator(coeffs: impl Iterator<Item = T>) -> Self {
64        let res = Self::from_complex_iterator(coeffs.map(|x| Complex::from(x)));
65        debug_assert!(res.is_normalized());
66        res
67    }
68
69    #[must_use]
70    pub fn from_complex_iterator(coeffs: impl Iterator<Item = Complex<T>>) -> Self {
71        Self(coeffs.collect_vec()).normalize()
72    }
73}
74
75impl<T: RealScalar> From<&[Complex<T>]> for Poly<T> {
76    fn from(value: &[Complex<T>]) -> Self {
77        Self::from_complex_slice(value)
78    }
79}
80
81impl<T: RealScalar> From<Vec<Complex<T>>> for Poly<T> {
82    fn from(value: Vec<Complex<T>>) -> Self {
83        Self::from_complex_vec(value)
84    }
85}
86
87// TODO: these are ambiguous and lead to making a `Poly<Complex<Complex<T>>>`
88//       but making a `Real` trait would preventing making blanket impls for
89//       numeric types.
90// impl<T: Scalar> From<&[T]> for Poly<T> {
91//     fn from(value: &[T]) -> Self {
92//         Self::from_real_slice(value)
93//     }
94// }
95
96// impl<T: Scalar> From<Vec<T>> for Poly<T> {
97//     fn from(value: Vec<T>) -> Self {
98//         Self::from_real_vec(value)
99//     }
100// }
101
102impl<T: RealScalar> From<Poly<T>> for *const Complex<T> {
103    fn from(val: Poly<T>) -> Self {
104        val.as_ptr()
105    }
106}
107
108impl<T: RealScalar> From<Poly<T>> for *mut Complex<T> {
109    fn from(mut val: Poly<T>) -> Self {
110        val.as_mut_ptr()
111    }
112}
113
114impl<T: RealScalar> From<Poly<T>> for Vec<Complex<T>> {
115    fn from(val: Poly<T>) -> Self {
116        val.to_vec()
117    }
118}
119
120impl<'a, T: RealScalar> IntoIterator for &'a Poly<T> {
121    type IntoIter = std::slice::Iter<'a, Complex<T>>;
122    type Item = &'a Complex<T>;
123    fn into_iter(self) -> Self::IntoIter {
124        self.iter()
125    }
126}
127
128impl<'a, T: RealScalar> IntoIterator for &'a mut Poly<T> {
129    type IntoIter = std::slice::IterMut<'a, Complex<T>>;
130    type Item = &'a mut Complex<T>;
131    fn into_iter(self) -> Self::IntoIter {
132        self.iter_mut()
133    }
134}