nmoo.noises.uniform
Wrapper that generates a uniform noise.
1""" 2Wrapper that generates a uniform noise. 3""" 4__docformat__ = "google" 5 6from typing import Any, Dict, List, Tuple, Union 7 8import numpy as np 9from loguru import logger as logging 10from pymoo.core.problem import Problem 11 12from nmoo.wrapped_problem import WrappedProblem 13 14 15class UniformNoise(WrappedProblem): 16 """ 17 A wrapper that adds a uniform noise to a problem. 18 19 Assume that the output of the wrapped problem as an `F` numerical component 20 (as they almost always do) of dimension 2. The following creates a new 21 problem by adding a `U(-1, 1)` noise on all components of `F` (without any 22 covariance): 23 24 noisy_problem = nmoo.UniformNoise(problem, 1) 25 26 The following adds a `U(-1, 1)` noise on the first component of `F` but a 27 `U(-2, 2)` noise on the second: 28 29 noisy_problem = nmoo.UniformNoise(problem, [1, 2]) 30 31 For biased noises (i.e. with nonzero mean), the min and max values of every 32 distribution must be specified. For example the following adds a `U(-.1, 33 1)` noise on the first component of `F` but a `U(-.2, 2)` noise on the 34 second: 35 36 noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], [-.2, 2]]) 37 38 Note that mixed bound specifications such as 39 40 noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], 2]) 41 # instead of [[-.1, 1], [-2, 2]] 42 43 is not possible. 44 45 If you want to add noise to more outputs of the wrapped problem, a 46 parameter specification like `nmoo.noises.GaussianNoise` is also possible. 47 For example, assume that the problem has a `G` numerical component. To 48 apply a `U(-3, 3)` to all components of `G`, together with the noise above 49 for `F`, 50 51 noisy_problem = nmoo.UniformNoise( 52 problem, 53 { 54 "F": [[-.1, 1], [-.2, 2]], 55 "G": 3, 56 } 57 ) 58 59 """ 60 61 _generator: np.random.Generator 62 """Random number generator.""" 63 64 _parameters: Dict[str, List[Tuple[float, float]]] = {} 65 """Noise parameters.""" 66 67 def __init__( 68 self, 69 problem: Problem, 70 parameters: Union[ 71 float, 72 Tuple[float, float], 73 List[Tuple[float, float]], 74 Dict[ 75 str, 76 Union[ 77 float, 78 Tuple[float, float], 79 List[Tuple[float, float]], 80 ], 81 ], 82 ], 83 seed: Any = None, 84 *, 85 name: str = "uniform_noise", 86 **kwargs, 87 ): 88 """ 89 Args: 90 name (str): An optional name for this problem. This will be used 91 when creating history dump files. Defaults to `gaussian_noise`. 92 problem (pymoo `Problem`): A non-noisy pymoo problem (or 93 `nmoo.wrapped_problem.WrappedProblem`). 94 parameters: See the examples above. 95 seed: Seed for 96 [`numpy.random.default_rng`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng) 97 """ 98 super().__init__(problem, name=name, **kwargs) 99 if not isinstance(parameters, dict): 100 parameters = {"F": parameters} 101 try: 102 for k, v in parameters.items(): 103 if isinstance(v, (float, int)): 104 assert v >= 0 105 self._parameters[k] = [(-v, v)] 106 elif isinstance(v, (list, tuple)) and isinstance(v[0], list): 107 # v expected to be a list of min-max tuples 108 for w in v: 109 assert isinstance(w, (list, tuple)) 110 assert len(w) == 2 111 assert w[0] <= w[1] 112 self._parameters[k] = parameters[k] 113 else: 114 # v is expected to be a list of numbers 115 self._parameters[k] = [] 116 for a in v: 117 assert isinstance(a, (float, int)) 118 assert a >= 0 119 self._parameters[k].append((-a, a)) 120 except AssertionError as e: 121 raise ValueError("Invalid noise parameters") from e 122 self.reseed(seed) 123 124 # pylint: disable=duplicate-code 125 def _evaluate(self, x, out, *args, **kwargs): 126 """ 127 Calls the wrapped problems's `_evaluate` method and adds a uniform 128 noise. The history scheme is the same as in 129 `nmoo.noises.GaussianNoise._evaluate`. 130 """ 131 self._problem._evaluate(x, out, *args, **kwargs) 132 noises: Dict[str, np.ndarray] = {} 133 for k, v in self._parameters.items(): 134 try: 135 noises[k] = np.stack( 136 [ 137 self._generator.uniform(*b, size=out[k].shape[0]) 138 for b in v 139 ], 140 axis=-1, 141 ) 142 out[k] += noises[k] 143 except KeyError: 144 logging.error( 145 "Noise parameter key {} is not present in objective " 146 "function output keys. No noise will be applied. " 147 "Objective function keys: {}.", 148 k, 149 str(list(out.keys())), 150 ) 151 self.add_to_history_x_out( 152 x, out, **{k + "_noise": v for k, v in noises.items()} 153 ) 154 155 def reseed(self, seed: Any) -> None: 156 self._generator = np.random.default_rng(seed) 157 if isinstance(self._problem, WrappedProblem): 158 self._problem.reseed(seed)
16class UniformNoise(WrappedProblem): 17 """ 18 A wrapper that adds a uniform noise to a problem. 19 20 Assume that the output of the wrapped problem as an `F` numerical component 21 (as they almost always do) of dimension 2. The following creates a new 22 problem by adding a `U(-1, 1)` noise on all components of `F` (without any 23 covariance): 24 25 noisy_problem = nmoo.UniformNoise(problem, 1) 26 27 The following adds a `U(-1, 1)` noise on the first component of `F` but a 28 `U(-2, 2)` noise on the second: 29 30 noisy_problem = nmoo.UniformNoise(problem, [1, 2]) 31 32 For biased noises (i.e. with nonzero mean), the min and max values of every 33 distribution must be specified. For example the following adds a `U(-.1, 34 1)` noise on the first component of `F` but a `U(-.2, 2)` noise on the 35 second: 36 37 noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], [-.2, 2]]) 38 39 Note that mixed bound specifications such as 40 41 noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], 2]) 42 # instead of [[-.1, 1], [-2, 2]] 43 44 is not possible. 45 46 If you want to add noise to more outputs of the wrapped problem, a 47 parameter specification like `nmoo.noises.GaussianNoise` is also possible. 48 For example, assume that the problem has a `G` numerical component. To 49 apply a `U(-3, 3)` to all components of `G`, together with the noise above 50 for `F`, 51 52 noisy_problem = nmoo.UniformNoise( 53 problem, 54 { 55 "F": [[-.1, 1], [-.2, 2]], 56 "G": 3, 57 } 58 ) 59 60 """ 61 62 _generator: np.random.Generator 63 """Random number generator.""" 64 65 _parameters: Dict[str, List[Tuple[float, float]]] = {} 66 """Noise parameters.""" 67 68 def __init__( 69 self, 70 problem: Problem, 71 parameters: Union[ 72 float, 73 Tuple[float, float], 74 List[Tuple[float, float]], 75 Dict[ 76 str, 77 Union[ 78 float, 79 Tuple[float, float], 80 List[Tuple[float, float]], 81 ], 82 ], 83 ], 84 seed: Any = None, 85 *, 86 name: str = "uniform_noise", 87 **kwargs, 88 ): 89 """ 90 Args: 91 name (str): An optional name for this problem. This will be used 92 when creating history dump files. Defaults to `gaussian_noise`. 93 problem (pymoo `Problem`): A non-noisy pymoo problem (or 94 `nmoo.wrapped_problem.WrappedProblem`). 95 parameters: See the examples above. 96 seed: Seed for 97 [`numpy.random.default_rng`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng) 98 """ 99 super().__init__(problem, name=name, **kwargs) 100 if not isinstance(parameters, dict): 101 parameters = {"F": parameters} 102 try: 103 for k, v in parameters.items(): 104 if isinstance(v, (float, int)): 105 assert v >= 0 106 self._parameters[k] = [(-v, v)] 107 elif isinstance(v, (list, tuple)) and isinstance(v[0], list): 108 # v expected to be a list of min-max tuples 109 for w in v: 110 assert isinstance(w, (list, tuple)) 111 assert len(w) == 2 112 assert w[0] <= w[1] 113 self._parameters[k] = parameters[k] 114 else: 115 # v is expected to be a list of numbers 116 self._parameters[k] = [] 117 for a in v: 118 assert isinstance(a, (float, int)) 119 assert a >= 0 120 self._parameters[k].append((-a, a)) 121 except AssertionError as e: 122 raise ValueError("Invalid noise parameters") from e 123 self.reseed(seed) 124 125 # pylint: disable=duplicate-code 126 def _evaluate(self, x, out, *args, **kwargs): 127 """ 128 Calls the wrapped problems's `_evaluate` method and adds a uniform 129 noise. The history scheme is the same as in 130 `nmoo.noises.GaussianNoise._evaluate`. 131 """ 132 self._problem._evaluate(x, out, *args, **kwargs) 133 noises: Dict[str, np.ndarray] = {} 134 for k, v in self._parameters.items(): 135 try: 136 noises[k] = np.stack( 137 [ 138 self._generator.uniform(*b, size=out[k].shape[0]) 139 for b in v 140 ], 141 axis=-1, 142 ) 143 out[k] += noises[k] 144 except KeyError: 145 logging.error( 146 "Noise parameter key {} is not present in objective " 147 "function output keys. No noise will be applied. " 148 "Objective function keys: {}.", 149 k, 150 str(list(out.keys())), 151 ) 152 self.add_to_history_x_out( 153 x, out, **{k + "_noise": v for k, v in noises.items()} 154 ) 155 156 def reseed(self, seed: Any) -> None: 157 self._generator = np.random.default_rng(seed) 158 if isinstance(self._problem, WrappedProblem): 159 self._problem.reseed(seed)
A wrapper that adds a uniform noise to a problem.
Assume that the output of the wrapped problem as an F
numerical component
(as they almost always do) of dimension 2. The following creates a new
problem by adding a U(-1, 1)
noise on all components of F
(without any
covariance):
noisy_problem = nmoo.UniformNoise(problem, 1)
The following adds a U(-1, 1)
noise on the first component of F
but a
U(-2, 2)
noise on the second:
noisy_problem = nmoo.UniformNoise(problem, [1, 2])
For biased noises (i.e. with nonzero mean), the min and max values of every
distribution must be specified. For example the following adds a U(-.1,
1)
noise on the first component of F
but a U(-.2, 2)
noise on the
second:
noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], [-.2, 2]])
Note that mixed bound specifications such as
noisy_problem = nmoo.UniformNoise(problem, [[-.1, 1], 2])
# instead of [[-.1, 1], [-2, 2]]
is not possible.
If you want to add noise to more outputs of the wrapped problem, a
parameter specification like nmoo.noises.GaussianNoise
is also possible.
For example, assume that the problem has a G
numerical component. To
apply a U(-3, 3)
to all components of G
, together with the noise above
for F
,
noisy_problem = nmoo.UniformNoise(
problem,
{
"F": [[-.1, 1], [-.2, 2]],
"G": 3,
}
)
68 def __init__( 69 self, 70 problem: Problem, 71 parameters: Union[ 72 float, 73 Tuple[float, float], 74 List[Tuple[float, float]], 75 Dict[ 76 str, 77 Union[ 78 float, 79 Tuple[float, float], 80 List[Tuple[float, float]], 81 ], 82 ], 83 ], 84 seed: Any = None, 85 *, 86 name: str = "uniform_noise", 87 **kwargs, 88 ): 89 """ 90 Args: 91 name (str): An optional name for this problem. This will be used 92 when creating history dump files. Defaults to `gaussian_noise`. 93 problem (pymoo `Problem`): A non-noisy pymoo problem (or 94 `nmoo.wrapped_problem.WrappedProblem`). 95 parameters: See the examples above. 96 seed: Seed for 97 [`numpy.random.default_rng`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng) 98 """ 99 super().__init__(problem, name=name, **kwargs) 100 if not isinstance(parameters, dict): 101 parameters = {"F": parameters} 102 try: 103 for k, v in parameters.items(): 104 if isinstance(v, (float, int)): 105 assert v >= 0 106 self._parameters[k] = [(-v, v)] 107 elif isinstance(v, (list, tuple)) and isinstance(v[0], list): 108 # v expected to be a list of min-max tuples 109 for w in v: 110 assert isinstance(w, (list, tuple)) 111 assert len(w) == 2 112 assert w[0] <= w[1] 113 self._parameters[k] = parameters[k] 114 else: 115 # v is expected to be a list of numbers 116 self._parameters[k] = [] 117 for a in v: 118 assert isinstance(a, (float, int)) 119 assert a >= 0 120 self._parameters[k].append((-a, a)) 121 except AssertionError as e: 122 raise ValueError("Invalid noise parameters") from e 123 self.reseed(seed)
Arguments:
- name (str): An optional name for this problem. This will be used
when creating history dump files. Defaults to
gaussian_noise
. - problem (pymoo
Problem
): A non-noisy pymoo problem (ornmoo.wrapped_problem.WrappedProblem
). - parameters: See the examples above.
- seed: Seed for
numpy.random.default_rng
156 def reseed(self, seed: Any) -> None: 157 self._generator = np.random.default_rng(seed) 158 if isinstance(self._problem, WrappedProblem): 159 self._problem.reseed(seed)
Recursively resets the internal random state of the problem. See the numpy documentation for details about acceptable seeds.
Inherited Members
- nmoo.wrapped_problem.WrappedProblem
- add_to_history
- add_to_history_x_out
- all_layers
- depth
- dump_all_histories
- dump_history
- ground_problem
- innermost_wrapper
- start_new_run
- pymoo.core.problem.Problem
- evaluate
- do
- nadir_point
- ideal_point
- pareto_front
- pareto_set
- has_bounds
- has_constraints
- bounds
- name
- calc_constraint_violation