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.
from math import pi, sin
from numbers import Number
from typing import Sequence
from typing import Optional, Sequence
import numpy as np
class 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):
"""
Signal generator that adds two signals.
......
......@@ -4,9 +4,11 @@ import pytest
from b_asic.signal_generator import (
Constant,
Gaussian,
Impulse,
Sinusoid,
Step,
Uniform,
ZeroPad,
_AddGenerator,
_DivGenerator,
......@@ -97,6 +99,40 @@ def test_sinusoid():
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():
g = Impulse() + Impulse(2)
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