Skip to content
Snippets Groups Projects
Commit 9996e607 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Add random signal generators

parent aa3a5975
No related branches found
No related tags found
1 merge request!174Add random signal generators
Pipeline #89382 passed
...@@ -13,7 +13,9 @@ if you want more information. ...@@ -13,7 +13,9 @@ if you want more information.
from math import pi, sin from math import pi, sin
from numbers import Number from numbers import Number
from typing import Sequence from typing import Optional, Sequence
import numpy as np
class SignalGenerator: class SignalGenerator:
...@@ -187,6 +189,85 @@ class Sinusoid(SignalGenerator): ...@@ -187,6 +189,85 @@ class Sinusoid(SignalGenerator):
) )
class Gaussian(SignalGenerator):
"""
Signal generator with Gaussian noise.
See :class:`numpy.random.Generator.normal` for further details.
Parameters
----------
seed : int, optional
The seed of the random number generator.
scale : float, default: 1
The standard deviation of the noise.
loc : float, default: 0
The average value of the noise.
"""
def __init__(
self, seed: Optional[int] = None, loc: float = 0.0, scale: float = 1.0
) -> None:
self._rng = np.random.default_rng(seed)
self._seed = seed
self._loc = loc
self._scale = scale
def __call__(self, time: int) -> complex:
return self._rng.normal(self._loc, self._scale)
def __repr__(self):
ret_list = []
if self._seed is not None:
ret_list.append(f"seed={self._seed}")
if self._loc:
ret_list.append(f"loc={self._loc}")
if self._scale != 1.0:
ret_list.append(f"scale={self._scale}")
args = ", ".join(ret_list)
return f"Gaussian({args})"
class Uniform(SignalGenerator):
"""
Signal generator with uniform noise.
See :class:`numpy.random.Generator.normal` for further details.
Parameters
----------
seed : int, optional
The seed of the random number generator.
low : float, default: -1
The lower value of the uniform range.
high : float, default: 1
The upper value of the uniform range.
"""
def __init__(
self, seed: Optional[int] = None, low: float = -1.0, high: float = 1.0
) -> None:
self._rng = np.random.default_rng(seed)
self._seed = seed
self._low = low
self._high = high
def __call__(self, time: int) -> complex:
return self._rng.uniform(self._low, self._high)
def __repr__(self):
ret_list = []
if self._seed is not None:
ret_list.append(f"seed={self._seed}")
if self._low != -1.0:
ret_list.append(f"low={self._low}")
if self._high != 1.0:
ret_list.append(f"high={self._high}")
args = ", ".join(ret_list)
return f"Uniform({args})"
class _AddGenerator(SignalGenerator): class _AddGenerator(SignalGenerator):
""" """
Signal generator that adds two signals. Signal generator that adds two signals.
......
...@@ -4,9 +4,11 @@ import pytest ...@@ -4,9 +4,11 @@ import pytest
from b_asic.signal_generator import ( from b_asic.signal_generator import (
Constant, Constant,
Gaussian,
Impulse, Impulse,
Sinusoid, Sinusoid,
Step, Step,
Uniform,
ZeroPad, ZeroPad,
_AddGenerator, _AddGenerator,
_DivGenerator, _DivGenerator,
...@@ -97,6 +99,40 @@ def test_sinusoid(): ...@@ -97,6 +99,40 @@ def test_sinusoid():
assert str(g) == "Sinusoid(0.5, 0.25)" assert str(g) == "Sinusoid(0.5, 0.25)"
def test_gaussian():
g = Gaussian(1234)
assert g(0) == pytest.approx(-1.6038368053963015)
assert g(1) == pytest.approx(0.06409991400376411)
assert str(g) == "Gaussian(seed=1234)"
# Check same seed gives same sequence
g1 = Gaussian(12345)
g2 = Gaussian(12345)
for n in range(100):
assert g1(n) == g2(n)
assert str(Gaussian(1234, 1, 2)) == "Gaussian(seed=1234, loc=1, scale=2)"
def test_uniform():
g = Uniform(1234)
assert g(0) == pytest.approx(0.9533995333962844)
assert g(1) == pytest.approx(-0.23960852996076443)
assert str(g) == "Uniform(seed=1234)"
# Check same seed gives same sequence
g1 = Uniform(12345)
g2 = Uniform(12345)
for n in range(100):
assert g1(n) == g2(n)
assert str(Uniform(1234, 1, 2)) == "Uniform(seed=1234, low=1, high=2)"
def test_addition(): def test_addition():
g = Impulse() + Impulse(2) g = Impulse() + Impulse(2)
assert g(-1) == 0 assert g(-1) == 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment