basic_dsp_vector/vector_types/real/
real_to_complex.rs

1use super::super::{
2    Buffer, Domain, DspVec, ErrorReason, InsertZerosOps, InsertZerosOpsBuffered, MetaData,
3    RealNumberSpace, RededicateForceOps, ToComplexResult, ToSliceMut, TransRes,
4};
5use crate::numbers::*;
6
7/// Defines transformations from real to complex number space.
8///
9/// # Failures
10/// All operations in this trait set `self.len()` to `0` if the type isn't in
11/// the real number space.
12pub trait RealToComplexTransformsOps<T>: ToComplexResult
13where
14    T: RealNumber,
15{
16    /// Converts the real vector into a complex vector.
17    ///
18    /// # Example
19    ///
20    /// ```
21    /// use basic_dsp_vector::*;
22    /// # use num_complex::Complex;
23    /// let vector = vec!(1.0, 2.0).to_real_time_vec();
24    /// let result = vector.to_complex().expect("Ignoring error handling in examples");
25    /// assert_eq!([Complex::new(1.0, 0.0), Complex::new(2.0, 0.0)], result[..]);
26    /// ```
27    fn to_complex(self) -> TransRes<Self::ComplexResult>;
28}
29
30/// Defines transformations from real to complex number space.
31///
32/// # Failures
33/// All operations in this trait set `self.len()` to `0` if the type isn't
34/// in the real number space.
35pub trait RealToComplexTransformsOpsBuffered<S, T>: ToComplexResult
36where
37    S: ToSliceMut<T>,
38    T: RealNumber,
39{
40    /// Converts the real vector into a complex vector. The buffer allows
41    /// this operation to succeed even if the storage type doesn't allow resizing.
42    ///
43    /// # Example
44    ///
45    /// ```
46    /// use basic_dsp_vector::*;
47    /// # use num_complex::Complex;
48    /// let vector = vec!(1.0, 2.0).to_real_time_vec();
49    /// let mut buffer = SingleBuffer::new();
50    /// let result = vector.to_complex_b(&mut buffer);
51    /// assert_eq!([Complex::new(1.0, 0.0), Complex::new(2.0, 0.0)], result[..]);
52    /// ```
53    fn to_complex_b<B>(self, buffer: &mut B) -> Self::ComplexResult
54    where
55        B: for<'a> Buffer<'a, S, T>;
56}
57
58impl<S, T, N, D> RealToComplexTransformsOps<T> for DspVec<S, T, N, D>
59where
60    DspVec<S, T, N, D>: ToComplexResult + InsertZerosOps<T>,
61    <DspVec<S, T, N, D> as ToComplexResult>::ComplexResult: RededicateForceOps<DspVec<S, T, N, D>>,
62    S: ToSliceMut<T>,
63    T: RealNumber,
64    N: RealNumberSpace,
65    D: Domain,
66{
67    fn to_complex(mut self) -> TransRes<Self::ComplexResult> {
68        if self.is_complex() {
69            self.number_space.to_complex();
70            return Err((
71                ErrorReason::InputMustBeReal,
72                Self::ComplexResult::rededicate_from_force(self),
73            ));
74        }
75
76        let result = self.zero_interleave(2);
77        let domain = self.domain();
78        match result {
79            Err(reason) => Err((
80                reason,
81                Self::ComplexResult::rededicate_with_runtime_data(self, true, domain),
82            )),
83            Ok(()) => Ok(Self::ComplexResult::rededicate_with_runtime_data(
84                self, true, domain,
85            )),
86        }
87    }
88}
89
90impl<S, T, N, D> RealToComplexTransformsOpsBuffered<S, T> for DspVec<S, T, N, D>
91where
92    DspVec<S, T, N, D>: ToComplexResult + InsertZerosOpsBuffered<S, T>,
93    <DspVec<S, T, N, D> as ToComplexResult>::ComplexResult: RededicateForceOps<DspVec<S, T, N, D>>,
94    S: ToSliceMut<T>,
95    T: RealNumber,
96    N: RealNumberSpace,
97    D: Domain,
98{
99    fn to_complex_b<B>(mut self, buffer: &mut B) -> Self::ComplexResult
100    where
101        B: for<'a> Buffer<'a, S, T>,
102    {
103        if self.is_complex() {
104            self.number_space.to_complex();
105            self.mark_vector_as_invalid();
106            return Self::ComplexResult::rededicate_from_force(self);
107        }
108        self.zero_interleave_b(buffer, 2);
109        self.number_space.to_complex();
110        Self::ComplexResult::rededicate_from_force(self)
111    }
112}