Source code for cbadc.analog_signal.zero_order_hold

"""Sinusoidal signals."""

from typing import Iterable
from ._analog_signal import _AnalogSignal
from sympy import sin
from mpmath import mp
import numpy as np


[docs]class ZeroOrderHold(_AnalogSignal): """An analog continuous-time sinusoidal signal. Parameters ---------- amplitude : `float` The amplitude of the sinusoidal. frequency : `float` Frequency of the oscillation in [Hz]. phase : `float`, optional The phase, defaults to 0. offset : `float` The offset value. Attributes ---------- amplitude : `float` The amplitude. frequency : `float` The frequency in [Hz]. angularFrequency : `float` The frequency in [radians/second]. phase : `float` The phase. offset : `float`, `optional` The offset See also -------- cbadc.analog_signal.AnalogSignal Example ------- >>> from cbadc.analog_signal import Sinusoidal >>> import numpy as np >>> u = Sinusoidal(1, 123, np.pi/2, 0) >>> print(u.evaluate(0)) 1.0 """ _data: np.ndarray T: float t0: float _value: float def __init__(self, data: np.ndarray, T: float): super().__init__() self._data = data self.T = T self.piecewise_constant = True def __str__(self): return f"""Zero-order-hold signal with period {self.T}"""
[docs] def evaluate(self, t: float) -> float: """Evaluate the signal at time :math:`t`. Parameters ---------- t : `float` the time instance for evaluation. Returns ------- float The analog signal value """ return self._data[int(t / self.T) % self._data.shape[0]]
def __call__(self, data: np.ndarray): self._data = data return self
[docs]class BandLimitedSignal(_AnalogSignal): _data: np.ndarray T: float t0: float _value: float W: float def __init__( self, data: np.ndarray, T: float, alpha: float, number_of_samples: int ): super().__init__() self._data = data self._number_of_samples = number_of_samples self.T = T self.BW = 2 / T self.alpha = alpha def __str__(self): return f"""Zero-order-hold signal with period {self.T}""" def _impulse_response(self, t: float) -> float: return np.sinc(2 * self.BW * t)
[docs] def evaluate(self, t: float) -> float: """Evaluate the signal at time :math:`t`. Parameters ---------- t : `float` the time instance for evaluation. Returns ------- float The analog signal value """ index = int(t / self.T) % self._data.shape[0] res = self._data[index] for i in range(1, self._number_of_samples // 2): if index - i > 0: res += self._impulse_response(t - i * self.T) * self._data[index - i] if index + i < self._data.shape[0]: res += self._impulse_response(t + i * self.T) * self._data[index + i] return res
def __call__(self, data: np.ndarray): self._data = data return self
[docs]class RaisedCosine(_AnalogSignal): _data: np.ndarray T: float t0: float _value: float W: float def __init__( self, data: np.ndarray, T: float, alpha: float, number_of_samples: int ): super().__init__() self._data = data self._number_of_samples = number_of_samples self.T = T self.BW = 2 / T self.alpha = alpha def __str__(self): return f"""Zero-order-hold signal with period {self.T}""" def _impulse_response(self, t: float) -> float: return np.sinc(2 * self.BW * t) * ( np.cos(2 * np.pi * self.alpha * self.BW * t) / (1.0 - (4 * self.alpha * self.BW * t) ** 2) )
[docs] def evaluate(self, t: float) -> float: """Evaluate the signal at time :math:`t`. Parameters ---------- t : `float` the time instance for evaluation. Returns ------- float The analog signal value """ index = int(t / self.T) % self._data.shape[0] res = self._data[index] for i in range(1, self._number_of_samples // 2): if index - i > 0: res += self._impulse_response(t - i * self.T) * self._data[index - i] if index + i < self._data.shape[0]: res += self._impulse_response(t + i * self.T) * self._data[index + i] return res
def __call__(self, data: np.ndarray): self._data = data return self