komm.RaisedCosinePulse
Raised-cosine pulse. For a given roll-off factor $\alpha$ satisfying $0 \leq \alpha \leq 1$, it is a pulse with spectrum given by $$ \hat{p}(f) = \begin{cases} 1, & |f| \leq f_1, \\[1ex] \dfrac{1}{2} \left( 1 + \cos \left( \pi \dfrac{|f| - f_1}{f_2 - f_1}\right) \right), & f_1 \leq |f| \leq f_2, \\[1ex] 0, & \text{otherwise}. \end{cases} $$ where $f_1 = (1 - \alpha) / 2$ and $f_2 = (1 + \alpha) / 2$.
The waveform of the raised-cosine pulse is depicted below for $\alpha = 0.25$, and for $\alpha = 0.75$.
For more details, see Wikipedia: Raised-cosine filter and Wikipedia: Root-raised-cosine filter.
Notes
- For $\alpha = 0$ it reduces to the sinc pulse.
- For $\alpha = 1$ it becomes what is known as the full cosine roll-off pulse.
Parameters:
-
rolloff(float) –The roll-off factor $\alpha$ of the pulse. Must satisfy $0 \leq \alpha \leq 1$. The default value is
1.0.
waveform()
The waveform $p(t)$ of the pulse.
For the raised-cosine pulse, it is given by $$ p(t) = \sinc(t) \frac{\cos(\pi \alpha t)}{1 - (2 \alpha t)^2}. $$
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.waveform(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... ).round(3)
array([0. , 0.29 , 0.627, 0.897, 1. , 0.897, 0.627, 0.29 , 0. ])
spectrum()
The spectrum $\hat{p}(f)$ of the pulse.
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> np.abs(pulse.spectrum(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... ))
array([0. , 0. , 0.5, 1. , 1. , 1. , 0.5, 0. , 0. ])
energy()
The energy $E$ of the pulse.
For the raised-cosine pulse, it is given by $$ E = 1 - \frac{\alpha}{4}. $$
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.energy()
0.9375
autocorrelation()
The autocorrelation function $R(\tau)$ of the pulse.
For the raised-cosine pulse, it is given by $$ R(\tau) = \sinc(\tau) \frac{\cos(\pi \alpha \tau)}{1 - (2 \alpha \tau)^2} - \frac{\alpha}{4} \sinc(\alpha \tau) \frac{\cos(\pi \tau)}{1 - (\alpha \tau)^2}. $$
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.autocorrelation(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... ).round(3)
array([0.06 , 0.334, 0.627, 0.853, 0.938, 0.853, 0.627, 0.334, 0.06 ])
energy_spectral_density()
The energy spectral density $S(f)$ of the pulse.
For the raised-cosine pulse, it is given by $$ S(f) = \begin{cases} 1, & |f| \leq f_1, \\[1ex] \dfrac{1}{4} \left( 1 + \cos \left( \pi \dfrac{|f| - f_1}{f_2 - f_1}\right) \right)^2, & f_1 \leq |f| \leq f_2, \\[1ex] 0, & \text{otherwise}. \end{cases} $$
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.energy_spectral_density(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... )
array([0. , 0. , 0.25, 1. , 1. , 1. , 0.25, 0. , 0. ])
support tuple[float, float]
cached
property
The support of the pulse waveform $p(t)$, defined as the interval $[a, b]$ where $p(t)$ is non-zero.
For the raised-cosine pulse, the support is given by $(-\infty, \infty)$.
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.support
(-inf, inf)
taps()
Returns the FIR taps of the pulse.
Parameters:
-
samples_per_symbol(int) –The number of samples per symbol.
-
span(tuple[int, int] | None) –The time span to consider for the taps. This parameter is optional for pulses with finite support (defaults to $[0, 1]$), but required for pulses with infinite support.
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25)
>>> pulse.taps(samples_per_symbol=4, span=(-1, 1)).round(3)
array([0. , 0.29 , 0.627, 0.897, 1. , 0.897, 0.627, 0.29 , 0. ])
>>> pulse.taps(samples_per_symbol=4, span=(-16, 16)).shape
(129,)
root()
Returns the square-root version of the pulse, defined as the pulse whose spectrum is given by the square root of the spectrum of the original pulse. This method is only implemented for Nyquist pulses.
For the raised-cosine pulse, the square-root version is known as the root-raised-cosine (RRC) pulse, whose waveform is given by $$ p(t) = \frac{\sin ( 2 \pi f_1 t ) + 4 \alpha t \cos ( 2 \pi f_2 t )}{\pi t ( 1 - (4 \alpha t)^2 )}. $$
Examples:
>>> pulse = komm.RaisedCosinePulse(rolloff=0.25).root()
>>> pulse.waveform(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... ).round(3)
array([-0.064, 0.238, 0.622, 0.943, 1.068, 0.943, 0.622, 0.238,
-0.064])
>>> np.abs(pulse.spectrum(
... [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0],
... )).round(3)
array([0. , 0. , 0.707, 1. , 1. , 1. , 0.707, 0. , 0. ])