1"""
2Module provides some helper functions regarding the implementation of uncertainty.
3"""
4import numpy as np
5from numpy.random import Generator
6from scipy.ndimage import gaussian_filter1d
7
8
[docs]
9def smoothing(pattern: np.ndarray, sigma: float = 10.) -> np.ndarray:
10 """
11 Smoothes a given pattern by applying a Gaussian filter.
12
13 Parameters
14 ----------
15 pattern : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
16 The original pattern
17 sigma : `float`, optional
18 Standard deviation for the Gaussian filter.
19
20 The default is 10.
21
22 Returns
23 -------
24 `numpy.ndarray`
25 The smoothed pattern.
26 """
27 return gaussian_filter1d(pattern, sigma=sigma)
28
29
[docs]
30def scale_to_range(pattern: np.ndarray, min_value: float, max_value: float) -> np.ndarray:
31 """
32 Scales a given pattern to an interval.
33
34 Parameters
35 ----------
36 pattern : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
37 The pattern to be scaled.
38 min_value : `float`
39 Lower bound of the pattern.
40 max_value : `float`
41 Upper bound of the pattern.
42
43 Returns
44 -------
45 `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
46 The scaled pattern.
47 """
48 if min_value is None or max_value is None:
49 return pattern
50
51 min_pattern_val = np.min(pattern)
52 max_pattern_val = np.max(pattern)
53
54 return [(x - min_pattern_val) / (max_pattern_val - min_pattern_val) * (max_value - min_value)
55 + min_value for x in pattern]
56
57
[docs]
58def generate_random_gaussian_noise(n_samples: int, np_rand_gen: Generator = np.random.default_rng()
59 ) -> np.ndarray:
60 """
61 Generates Gaussian noise using a random mean ([0,1]) and random standard deviation ([0,1]).
62
63 Parameters
64 ----------
65 n_samples : `int`
66 Number of random samples.
67 np_rand_generator : `numpy.random.Generator <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator>`_, optional
68 The random number generator that is going to be used.
69
70 The default is the default BitGenerator (PCG64) as constructed by
71 `numpy.random.default_rng() <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng>`_.
72
73 Returns
74 -------
75 `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
76 Gaussian noise.
77 """
78 return np_rand_gen.normal(np.random.rand(), np.random.rand(), size=n_samples)
79
80
[docs]
81def generate_deep_random_gaussian_noise(n_samples: int, mean: float = None,
82 np_rand_gen: Generator = np.random.default_rng()
83 ) -> np.ndarray:
84 """
85 Generates random Gaussian noise where the standard deviations (and mean) are changing over time.
86
87 Parameters
88 ----------
89 n_samples : `int`
90 Number of random samples.
91 mean : `float`, optional
92 Fixed mean at all points in time.
93 If None, random means are generated.
94
95 The default is None.
96 np_rand_generator : `numpy.random.Generator <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator>`_, optional
97 The random number generator that is going to be used.
98
99 The default is the default BitGenerator (PCG64) as constructed by
100 `numpy.random.default_rng() <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng>`_.
101
102 Returns
103 -------
104 `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
105 Random Gaussian noise.
106 """
107 noise = []
108
109 if mean is None:
110 mean = create_deep_random_pattern(n_samples, min_value=-1., max_value=1.,
111 np_rand_gen=np_rand_gen)
112 else:
113 mean = [mean] * n_samples
114 rand_std = create_deep_random_pattern(n_samples, np_rand_gen=np_rand_gen)
115 noise = np.array([np_rand_gen.normal(m, s) for m, s in zip(mean, rand_std)])
116
117 return noise
118
119
[docs]
120def create_deep_random_pattern(n_samples: int, min_value: float = 0., max_value: float = 1.,
121 init_value: float = None,
122 np_rand_gen: Generator = np.random.default_rng()) -> np.ndarray:
123 """
124 Generates a random pattern.
125
126 Parameters
127 ----------
128 n_samples : `int`
129 Number of random samples -- i.e. length of the pattern.
130 min_value : `float`, optional
131 Lower bound of the pattern.
132
133 The default is zero.
134 max_value : `float`, optional
135 Upper bound of the pattern.
136
137 The default is one.
138 init_value : `float`, optional
139 Value of the first sample in the pattern.
140 If None, a random value is used.
141
142 The default is None.
143 np_rand_generator : `numpy.random.Generator <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator>`_, optional
144 The random number generator that is going to be used.
145
146 The default is the default BitGenerator (PCG64) as constructed by
147 `numpy.random.default_rng() <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng>`_.
148
149 Returns
150 -------
151 `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
152 Random pattern.
153 """
154 pattern = []
155 start_value = init_value
156
157 while len(pattern) < n_samples:
158 if len(pattern) != 0:
159 start_value = pattern[-1]
160
161 pattern += _create_deep_random_pattern(start_value, min_value=min_value,
162 max_value=max_value, np_rand_gen=np_rand_gen)
163
164 pattern = pattern[:n_samples]
165
166 # Scaling to value range
167 pattern = scale_to_range(pattern, min_value, max_value)
168
169 return np.array(pattern)
170
171
172def _create_deep_random_pattern(start_value: float = None, min_length: int = 2, max_length: int = 5,
173 min_value: float = None, max_value: float = None,
174 np_rand_gen: Generator = np.random.default_rng()) -> np.ndarray:
175 """
176 Generates a random pattern of random length.
177
178 Parameters
179 ----------
180 start_value : `float`, optional
181 First value in the pattern.
182 If None, a random value is used.
183
184 The default is None.
185 min_length : `int`, optional
186 Minium length of the pattern.
187
188 The default is 2.
189 max_length : `int`
190 Maximum length of the pattern.
191
192 The default is 5.
193 min_value : `float`, optional
194 Lower bound of the pattern.
195
196 The default is zero.
197 max_value : `float`, optional
198 Upper bound of the pattern.
199
200 The default is one.
201 np_rand_generator : `numpy.random.Generator <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator>`_, optional
202 The random number generator that is going to be used.
203
204 The default is the default BitGenerator (PCG64) as constructed by
205 `numpy.random.default_rng() <https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng>`_.
206
207 Returns
208 -------
209 `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
210 Random pattern.
211 """
212 pattern = []
213
214 # Random parameters of pattern
215 if start_value is None:
216 start_value = np_rand_gen.random()
217 length = np_rand_gen.integers(low=min_length, high=max_length)
218 vec = np_rand_gen.choice([-.1, .1])
219
220 # Generate pattern
221 cur_value = start_value
222 pattern.append(start_value)
223
224 for _ in range(length):
225 cur_value = cur_value + np_rand_gen.random() * vec
226 pattern.append(cur_value)
227 if min_value is not None and max_value is not None:
228 if cur_value < min_value:
229 vec = .1
230 elif cur_value > max_value:
231 vec = -.1
232
233 return pattern