# This file is part of the pyMOR project (http://www.pymor.org).
# Copyright 2013-2019 pyMOR developers and contributors. All rights reserved.
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
from itertools import product
import numpy as np
from pymor.parameters.base import Parameter, ParameterType
from pymor.parameters.interfaces import ParameterSpaceInterface
from pymor.tools.random import get_random_state
[docs]class CubicParameterSpace(ParameterSpaceInterface):
"""Simple |ParameterSpace| where each summand is an n-cube.
Parameters
----------
parameter_type
The |ParameterType| of the space.
minimum
The minimum for each matrix entry of each |Parameter| component.
Must be `None` if `ranges` is specified.
maximum
The maximum for each matrix entry of each |Parameter| component.
Must be `None` if `ranges` is specified.
ranges
dict whose keys agree with `parameter_type` and whose values
are tuples (min, max) specifying the minimum and maximum of each
matrix entry of corresponding |Parameter| component.
Must be `None` if `minimum` and `maximum` are specified.
"""
def __init__(self, parameter_type, minimum=None, maximum=None, ranges=None):
assert ranges is None or (minimum is None and maximum is None), 'Must specify minimum, maximum or ranges'
assert ranges is not None or (minimum is not None and maximum is not None),\
'Must specify minimum, maximum or ranges'
assert minimum is None or minimum < maximum
if ranges is None:
ranges = {k: (minimum, maximum) for k in parameter_type}
parameter_type = ParameterType(parameter_type)
self.__auto_init(locals())
def parse_parameter(self, mu):
return Parameter.from_parameter_type(mu, self.parameter_type)
[docs] def contains(self, mu):
mu = self.parse_parameter(mu)
return all(np.all(self.ranges[k][0] <= mu[k]) and np.all(mu[k] <= self.ranges[k][1])
for k in self.parameter_type)
[docs] def sample_randomly(self, count=None, random_state=None, seed=None):
"""Randomly sample |Parameters| from the space.
Parameters
----------
count
`None` or number of random parameters (see below).
random_state
:class:`~numpy.random.RandomState` to use for sampling.
If `None`, a new random state is generated using `seed`
as random seed, or the :func:`default <pymor.tools.random.default_random_state>`
random state is used.
seed
If not `None`, a new radom state with this seed is used.
Returns
-------
If `count` is `None`, an inexhaustible iterator returning random
|Parameters|.
Otherwise a list of `count` random |Parameters|.
"""
assert not random_state or seed is None
ranges = self.ranges
random_state = get_random_state(random_state, seed)
get_param = lambda: Parameter(((k, random_state.uniform(ranges[k][0], ranges[k][1], shp))
for k, shp in self.parameter_type.items()))
if count is None:
def param_generator():
while True:
yield get_param()
return param_generator()
else:
return [get_param() for _ in range(count)]
[docs] def __str__(self):
rows = [(k, str(v), str(self.ranges[k])) for k, v in self.parameter_type.items()]
column_widths = [max(map(len, c)) for c in zip(*rows)]
return ('CubicParameterSpace\n'
+ '\n'.join(('key: {:' + str(column_widths[0] + 2)
+ '} shape: {:' + str(column_widths[1] + 2)
+ '} range: {}').format(c1 + ',', c2 + ',', c3) for (c1, c2, c3) in rows))