1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
use super::super::{
    Buffer, Domain, DspVec, ErrorReason, InsertZerosOps, InsertZerosOpsBuffered, MetaData,
    RealNumberSpace, RededicateForceOps, ToComplexResult, ToSliceMut, TransRes,
};
use crate::numbers::*;

/// Defines transformations from real to complex number space.
///
/// # Failures
/// All operations in this trait set `self.len()` to `0` if the type isn't in
/// the real number space.
pub trait RealToComplexTransformsOps<T>: ToComplexResult
where
    T: RealNumber,
{
    /// Converts the real vector into a complex vector.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let vector = vec!(1.0, 2.0).to_real_time_vec();
    /// let result = vector.to_complex().expect("Ignoring error handling in examples");
    /// assert_eq!([1.0, 0.0, 2.0, 0.0], result[..]);
    /// ```
    fn to_complex(self) -> TransRes<Self::ComplexResult>;
}

/// Defines transformations from real to complex number space.
///
/// # Failures
/// All operations in this trait set `self.len()` to `0` if the type isn't
/// in the real number space.
pub trait RealToComplexTransformsOpsBuffered<S, T>: ToComplexResult
where
    S: ToSliceMut<T>,
    T: RealNumber,
{
    /// Converts the real vector into a complex vector. The buffer allows
    /// this operation to succeed even if the storage type doesn't allow resizing.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let vector = vec!(1.0, 2.0).to_real_time_vec();
    /// let mut buffer = SingleBuffer::new();
    /// let result = vector.to_complex_b(&mut buffer);
    /// assert_eq!([1.0, 0.0, 2.0, 0.0], result[..]);
    /// ```
    fn to_complex_b<B>(self, buffer: &mut B) -> Self::ComplexResult
    where
        B: for<'a> Buffer<'a, S, T>;
}

impl<S, T, N, D> RealToComplexTransformsOps<T> for DspVec<S, T, N, D>
where
    DspVec<S, T, N, D>: ToComplexResult + InsertZerosOps<T>,
    <DspVec<S, T, N, D> as ToComplexResult>::ComplexResult: RededicateForceOps<DspVec<S, T, N, D>>,
    S: ToSliceMut<T>,
    T: RealNumber,
    N: RealNumberSpace,
    D: Domain,
{
    fn to_complex(mut self) -> TransRes<Self::ComplexResult> {
        if self.is_complex() {
            self.number_space.to_complex();
            return Err((
                ErrorReason::InputMustBeReal,
                Self::ComplexResult::rededicate_from_force(self),
            ));
        }

        let result = self.zero_interleave(2);
        let domain = self.domain();
        match result {
            Err(reason) => Err((
                reason,
                Self::ComplexResult::rededicate_with_runtime_data(self, true, domain),
            )),
            Ok(()) => Ok(Self::ComplexResult::rededicate_with_runtime_data(
                self, true, domain,
            )),
        }
    }
}

impl<S, T, N, D> RealToComplexTransformsOpsBuffered<S, T> for DspVec<S, T, N, D>
where
    DspVec<S, T, N, D>: ToComplexResult + InsertZerosOpsBuffered<S, T>,
    <DspVec<S, T, N, D> as ToComplexResult>::ComplexResult: RededicateForceOps<DspVec<S, T, N, D>>,
    S: ToSliceMut<T>,
    T: RealNumber,
    N: RealNumberSpace,
    D: Domain,
{
    fn to_complex_b<B>(mut self, buffer: &mut B) -> Self::ComplexResult
    where
        B: for<'a> Buffer<'a, S, T>,
    {
        if self.is_complex() {
            self.number_space.to_complex();
            self.mark_vector_as_invalid();
            return Self::ComplexResult::rededicate_from_force(self);
        }
        self.zero_interleave_b(buffer, 2);
        self.number_space.to_complex();
        Self::ComplexResult::rededicate_from_force(self)
    }
}