🎨 Format Python code with psf/black
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
__all__ = [
|
||||
'Location', 'CartesianDomain', 'EllipsoidDomain', 'Union', 'Intersection',
|
||||
'Exclusion', 'Difference', 'OperationInterface', 'SimplexDomain'
|
||||
"Location",
|
||||
"CartesianDomain",
|
||||
"EllipsoidDomain",
|
||||
"Union",
|
||||
"Intersection",
|
||||
"Exclusion",
|
||||
"Difference",
|
||||
"OperationInterface",
|
||||
"SimplexDomain",
|
||||
]
|
||||
|
||||
from .location import Location
|
||||
|
||||
@@ -72,17 +72,17 @@ class CartesianDomain(Location):
|
||||
:rtype: torch.Tensor
|
||||
"""
|
||||
dim = bounds.shape[0]
|
||||
if mode in ['chebyshev', 'grid'] and dim != 1:
|
||||
raise RuntimeError('Something wrong in Span...')
|
||||
if mode in ["chebyshev", "grid"] and dim != 1:
|
||||
raise RuntimeError("Something wrong in Span...")
|
||||
|
||||
if mode == 'random':
|
||||
if mode == "random":
|
||||
pts = torch.rand(size=(n, dim))
|
||||
elif mode == 'chebyshev':
|
||||
pts = chebyshev_roots(n).mul(.5).add(.5).reshape(-1, 1)
|
||||
elif mode == 'grid':
|
||||
elif mode == "chebyshev":
|
||||
pts = chebyshev_roots(n).mul(0.5).add(0.5).reshape(-1, 1)
|
||||
elif mode == "grid":
|
||||
pts = torch.linspace(0, 1, n).reshape(-1, 1)
|
||||
# elif mode == 'lh' or mode == 'latin':
|
||||
elif mode in ['lh', 'latin']:
|
||||
elif mode in ["lh", "latin"]:
|
||||
pts = torch_lhs(n, dim)
|
||||
|
||||
pts *= bounds[:, 1] - bounds[:, 0]
|
||||
@@ -90,7 +90,7 @@ class CartesianDomain(Location):
|
||||
|
||||
return pts
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""Sample routine.
|
||||
|
||||
:param n: Number of points to sample, see Note below
|
||||
@@ -145,7 +145,7 @@ class CartesianDomain(Location):
|
||||
"""
|
||||
|
||||
def _1d_sampler(n, mode, variables):
|
||||
""" Sample independentely the variables and cross the results"""
|
||||
"""Sample independentely the variables and cross the results"""
|
||||
tmp = []
|
||||
for variable in variables:
|
||||
if variable in self.range_.keys():
|
||||
@@ -158,17 +158,18 @@ class CartesianDomain(Location):
|
||||
|
||||
result = tmp[0]
|
||||
for i in tmp[1:]:
|
||||
result = result.append(i, mode='cross')
|
||||
result = result.append(i, mode="cross")
|
||||
|
||||
for variable in variables:
|
||||
if variable in self.fixed_.keys():
|
||||
value = self.fixed_[variable]
|
||||
pts_variable = torch.tensor([[value]
|
||||
]).repeat(result.shape[0], 1)
|
||||
pts_variable = torch.tensor([[value]]).repeat(
|
||||
result.shape[0], 1
|
||||
)
|
||||
pts_variable = pts_variable.as_subclass(LabelTensor)
|
||||
pts_variable.labels = [variable]
|
||||
|
||||
result = result.append(pts_variable, mode='std')
|
||||
result = result.append(pts_variable, mode="std")
|
||||
|
||||
return result
|
||||
|
||||
@@ -197,12 +198,13 @@ class CartesianDomain(Location):
|
||||
for variable in variables:
|
||||
if variable in self.fixed_.keys():
|
||||
value = self.fixed_[variable]
|
||||
pts_variable = torch.tensor([[value]
|
||||
]).repeat(result.shape[0], 1)
|
||||
pts_variable = torch.tensor([[value]]).repeat(
|
||||
result.shape[0], 1
|
||||
)
|
||||
pts_variable = pts_variable.as_subclass(LabelTensor)
|
||||
pts_variable.labels = [variable]
|
||||
|
||||
result = result.append(pts_variable, mode='std')
|
||||
result = result.append(pts_variable, mode="std")
|
||||
return result
|
||||
|
||||
def _single_points_sample(n, variables):
|
||||
@@ -226,22 +228,22 @@ class CartesianDomain(Location):
|
||||
|
||||
result = tmp[0]
|
||||
for i in tmp[1:]:
|
||||
result = result.append(i, mode='std')
|
||||
result = result.append(i, mode="std")
|
||||
|
||||
return result
|
||||
|
||||
if self.fixed_ and (not self.range_):
|
||||
return _single_points_sample(n, variables)
|
||||
|
||||
if variables == 'all':
|
||||
if variables == "all":
|
||||
variables = list(self.range_.keys()) + list(self.fixed_.keys())
|
||||
|
||||
if mode in ['grid', 'chebyshev']:
|
||||
if mode in ["grid", "chebyshev"]:
|
||||
return _1d_sampler(n, mode, variables)
|
||||
elif mode in ['random', 'lh', 'latin']:
|
||||
elif mode in ["random", "lh", "latin"]:
|
||||
return _Nd_sampler(n, mode, variables)
|
||||
else:
|
||||
raise ValueError(f'mode={mode} is not valid.')
|
||||
raise ValueError(f"mode={mode} is not valid.")
|
||||
|
||||
def is_inside(self, point, check_border=False):
|
||||
"""Check if a point is inside the ellipsoid.
|
||||
|
||||
@@ -20,7 +20,7 @@ class Difference(OperationInterface):
|
||||
the dimension of the geometry space.
|
||||
|
||||
:param list geometries: A list of geometries from ``pina.geometry``
|
||||
such as ``EllipsoidDomain`` or ``CartesianDomain``. The first
|
||||
such as ``EllipsoidDomain`` or ``CartesianDomain``. The first
|
||||
geometry in the list is the geometry from which points are
|
||||
sampled. The rest of the geometries are the geometries that
|
||||
are excluded from the first geometry to find the difference.
|
||||
@@ -39,7 +39,7 @@ class Difference(OperationInterface):
|
||||
Check if a point is inside the ``Difference`` domain.
|
||||
|
||||
:param point: Point to be checked.
|
||||
:type point: torch.Tensor
|
||||
:type point: torch.Tensor
|
||||
:param bool check_border: If ``True``, the border is considered inside.
|
||||
:return: ``True`` if the point is inside the Exclusion domain, ``False`` otherwise.
|
||||
:rtype: bool
|
||||
@@ -49,7 +49,7 @@ class Difference(OperationInterface):
|
||||
return False
|
||||
return self.geometries[0].is_inside(point, check_border)
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""
|
||||
Sample routine for ``Difference`` domain.
|
||||
|
||||
@@ -77,9 +77,10 @@ class Difference(OperationInterface):
|
||||
5
|
||||
|
||||
"""
|
||||
if mode != 'random':
|
||||
if mode != "random":
|
||||
raise NotImplementedError(
|
||||
f'{mode} is not a valid mode for sampling.')
|
||||
f"{mode} is not a valid mode for sampling."
|
||||
)
|
||||
|
||||
sampled = []
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class EllipsoidDomain(Location):
|
||||
|
||||
.. note::
|
||||
When ``sample_surface`` in the ``__init()__``
|
||||
is set to ``True``, then the method only checks
|
||||
is set to ``True``, then the method only checks
|
||||
points on the surface, and not inside the domain.
|
||||
|
||||
:param point: Point to be checked.
|
||||
@@ -103,7 +103,7 @@ class EllipsoidDomain(Location):
|
||||
# get axis ellipse as tensors
|
||||
list_dict_vals = list(self._axis.values())
|
||||
tmp = torch.tensor(list_dict_vals, dtype=torch.float)
|
||||
ax_sq = LabelTensor(tmp.reshape(1, -1)**2, self.variables)
|
||||
ax_sq = LabelTensor(tmp.reshape(1, -1) ** 2, self.variables)
|
||||
|
||||
# get centers ellipse as tensors
|
||||
list_dict_vals = list(self._centers.values())
|
||||
@@ -111,16 +111,18 @@ class EllipsoidDomain(Location):
|
||||
centers = LabelTensor(tmp.reshape(1, -1), self.variables)
|
||||
|
||||
if not all([i in ax_sq.labels for i in point.labels]):
|
||||
raise ValueError('point labels different from constructor'
|
||||
f' dictionary labels. Got {point.labels},'
|
||||
f' expected {ax_sq.labels}.')
|
||||
raise ValueError(
|
||||
"point labels different from constructor"
|
||||
f" dictionary labels. Got {point.labels},"
|
||||
f" expected {ax_sq.labels}."
|
||||
)
|
||||
|
||||
# point square + shift center
|
||||
point_sq = (point - centers).pow(2)
|
||||
point_sq.labels = point.labels
|
||||
|
||||
# calculate ellispoid equation
|
||||
eqn = torch.sum(point_sq.extract(ax_sq.labels) / ax_sq) - 1.
|
||||
eqn = torch.sum(point_sq.extract(ax_sq.labels) / ax_sq) - 1.0
|
||||
|
||||
# if we have sampled only the surface, we check that the
|
||||
# point is inside the surface border only
|
||||
@@ -160,8 +162,9 @@ class EllipsoidDomain(Location):
|
||||
dim = len(variables)
|
||||
|
||||
# get values center
|
||||
pairs_center = [(k, v) for k, v in self._centers.items()
|
||||
if k in variables]
|
||||
pairs_center = [
|
||||
(k, v) for k, v in self._centers.items() if k in variables
|
||||
]
|
||||
_, values_center = map(list, zip(*pairs_center))
|
||||
values_center = torch.tensor(values_center)
|
||||
|
||||
@@ -171,7 +174,7 @@ class EllipsoidDomain(Location):
|
||||
values_axis = torch.tensor(values_axis)
|
||||
|
||||
# Sample in the unit sphere
|
||||
if mode == 'random':
|
||||
if mode == "random":
|
||||
# 1. Sample n points from the surface of a unit sphere
|
||||
# 2. Scale each dimension using torch.rand()
|
||||
# (a random number between 0-1) so that it lies within
|
||||
@@ -192,7 +195,7 @@ class EllipsoidDomain(Location):
|
||||
|
||||
return pts
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""Sample routine.
|
||||
|
||||
:param int n: Number of points to sample in the shape.
|
||||
@@ -238,12 +241,13 @@ class EllipsoidDomain(Location):
|
||||
for variable in variables:
|
||||
if variable in self.fixed_.keys():
|
||||
value = self.fixed_[variable]
|
||||
pts_variable = torch.tensor([[value]
|
||||
]).repeat(result.shape[0], 1)
|
||||
pts_variable = torch.tensor([[value]]).repeat(
|
||||
result.shape[0], 1
|
||||
)
|
||||
pts_variable = pts_variable.as_subclass(LabelTensor)
|
||||
pts_variable.labels = [variable]
|
||||
|
||||
result = result.append(pts_variable, mode='std')
|
||||
result = result.append(pts_variable, mode="std")
|
||||
return result
|
||||
|
||||
def _single_points_sample(n, variables):
|
||||
@@ -267,17 +271,17 @@ class EllipsoidDomain(Location):
|
||||
|
||||
result = tmp[0]
|
||||
for i in tmp[1:]:
|
||||
result = result.append(i, mode='std')
|
||||
result = result.append(i, mode="std")
|
||||
|
||||
return result
|
||||
|
||||
if self.fixed_ and (not self.range_):
|
||||
return _single_points_sample(n, variables)
|
||||
|
||||
if variables == 'all':
|
||||
if variables == "all":
|
||||
variables = list(self.range_.keys()) + list(self.fixed_.keys())
|
||||
|
||||
if mode in ['random']:
|
||||
if mode in ["random"]:
|
||||
return _Nd_sampler(n, mode, variables)
|
||||
else:
|
||||
raise NotImplementedError(f'mode={mode} is not implemented.')
|
||||
raise NotImplementedError(f"mode={mode} is not implemented.")
|
||||
|
||||
@@ -37,7 +37,7 @@ class Exclusion(OperationInterface):
|
||||
Check if a point is inside the ``Exclusion`` domain.
|
||||
|
||||
:param point: Point to be checked.
|
||||
:type point: torch.Tensor
|
||||
:type point: torch.Tensor
|
||||
:param bool check_border: If ``True``, the border is considered inside.
|
||||
:return: ``True`` if the point is inside the Exclusion domain, ``False`` otherwise.
|
||||
:rtype: bool
|
||||
@@ -48,7 +48,7 @@ class Exclusion(OperationInterface):
|
||||
flag += 1
|
||||
return flag == 1
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""
|
||||
Sample routine for ``Exclusion`` domain.
|
||||
|
||||
@@ -76,9 +76,10 @@ class Exclusion(OperationInterface):
|
||||
5
|
||||
|
||||
"""
|
||||
if mode != 'random':
|
||||
if mode != "random":
|
||||
raise NotImplementedError(
|
||||
f'{mode} is not a valid mode for sampling.')
|
||||
f"{mode} is not a valid mode for sampling."
|
||||
)
|
||||
|
||||
sampled = []
|
||||
|
||||
@@ -104,4 +105,4 @@ class Exclusion(OperationInterface):
|
||||
sampled_points.append(sample)
|
||||
sampled += sampled_points
|
||||
|
||||
return LabelTensor(torch.cat(sampled), labels=self.variables)
|
||||
return LabelTensor(torch.cat(sampled), labels=self.variables)
|
||||
|
||||
@@ -20,7 +20,7 @@ class Intersection(OperationInterface):
|
||||
with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N`
|
||||
the dimension of the geometry space.
|
||||
|
||||
:param list geometries: A list of geometries from ``pina.geometry``
|
||||
:param list geometries: A list of geometries from ``pina.geometry``
|
||||
such as ``EllipsoidDomain`` or ``CartesianDomain``. The intersection
|
||||
will be taken between all the geometries in the list. The resulting
|
||||
geometry will be the intersection of all the geometries in the list.
|
||||
@@ -39,7 +39,7 @@ class Intersection(OperationInterface):
|
||||
Check if a point is inside the ``Intersection`` domain.
|
||||
|
||||
:param point: Point to be checked.
|
||||
:type point: torch.Tensor
|
||||
:type point: torch.Tensor
|
||||
:param bool check_border: If ``True``, the border is considered inside.
|
||||
:return: ``True`` if the point is inside the Intersection domain, ``False`` otherwise.
|
||||
:rtype: bool
|
||||
@@ -50,7 +50,7 @@ class Intersection(OperationInterface):
|
||||
flag += 1
|
||||
return flag == len(self.geometries)
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""
|
||||
Sample routine for ``Intersection`` domain.
|
||||
|
||||
@@ -78,9 +78,10 @@ class Intersection(OperationInterface):
|
||||
5
|
||||
|
||||
"""
|
||||
if mode != 'random':
|
||||
if mode != "random":
|
||||
raise NotImplementedError(
|
||||
f'{mode} is not a valid mode for sampling.')
|
||||
f"{mode} is not a valid mode for sampling."
|
||||
)
|
||||
|
||||
sampled = []
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class OperationInterface(Location, metaclass=ABCMeta):
|
||||
|
||||
@property
|
||||
def geometries(self):
|
||||
"""
|
||||
"""
|
||||
The geometries to perform set operation.
|
||||
"""
|
||||
return self._geometries
|
||||
@@ -40,15 +40,15 @@ class OperationInterface(Location, metaclass=ABCMeta):
|
||||
:rtype: list[str]
|
||||
"""
|
||||
return self.geometries[0].variables
|
||||
|
||||
@ abstractmethod
|
||||
|
||||
@abstractmethod
|
||||
def is_inside(self, point, check_border=False):
|
||||
"""
|
||||
Check if a point is inside the resulting domain after
|
||||
a set operation is applied.
|
||||
|
||||
:param point: Point to be checked.
|
||||
:type point: torch.Tensor
|
||||
:type point: torch.Tensor
|
||||
:param bool check_border: If ``True``, the border is considered inside.
|
||||
:return: ``True`` if the point is inside the Intersection domain, ``False`` otherwise.
|
||||
:rtype: bool
|
||||
@@ -64,4 +64,5 @@ class OperationInterface(Location, metaclass=ABCMeta):
|
||||
for geometry in geometries:
|
||||
if geometry.variables != geometries[0].variables:
|
||||
raise NotImplementedError(
|
||||
f'The geometries need to have same dimensions and labels.')
|
||||
f"The geometries need to have same dimensions and labels."
|
||||
)
|
||||
|
||||
@@ -94,7 +94,7 @@ class SimplexDomain(Location):
|
||||
# respective coord bounded by the lowest and highest values
|
||||
span_dict[coord] = [
|
||||
float(sorted_vertices[0][i]),
|
||||
float(sorted_vertices[-1][i])
|
||||
float(sorted_vertices[-1][i]),
|
||||
]
|
||||
|
||||
return CartesianDomain(span_dict)
|
||||
@@ -120,16 +120,19 @@ class SimplexDomain(Location):
|
||||
"""
|
||||
|
||||
if not all(label in self.variables for label in point.labels):
|
||||
raise ValueError("Point labels different from constructor"
|
||||
f" dictionary labels. Got {point.labels},"
|
||||
f" expected {self.variables}.")
|
||||
raise ValueError(
|
||||
"Point labels different from constructor"
|
||||
f" dictionary labels. Got {point.labels},"
|
||||
f" expected {self.variables}."
|
||||
)
|
||||
|
||||
point_shift = point - self._vertices_matrix[-1]
|
||||
point_shift = point_shift.tensor.reshape(-1, 1)
|
||||
|
||||
# compute barycentric coordinates
|
||||
lambda_ = torch.linalg.solve(self._vectors_shifted * 1.0,
|
||||
point_shift * 1.0)
|
||||
lambda_ = torch.linalg.solve(
|
||||
self._vectors_shifted * 1.0, point_shift * 1.0
|
||||
)
|
||||
lambda_1 = 1.0 - torch.sum(lambda_)
|
||||
lambdas = torch.vstack([lambda_, lambda_1])
|
||||
|
||||
@@ -137,8 +140,9 @@ class SimplexDomain(Location):
|
||||
if not check_border:
|
||||
return all(torch.gt(lambdas, 0.0)) and all(torch.lt(lambdas, 1.0))
|
||||
|
||||
return all(torch.ge(lambdas, 0)) and (any(torch.eq(lambdas, 0))
|
||||
or any(torch.eq(lambdas, 1)))
|
||||
return all(torch.ge(lambdas, 0)) and (
|
||||
any(torch.eq(lambdas, 0)) or any(torch.eq(lambdas, 1))
|
||||
)
|
||||
|
||||
def _sample_interior_randomly(self, n, variables):
|
||||
"""
|
||||
@@ -163,9 +167,9 @@ class SimplexDomain(Location):
|
||||
|
||||
sampled_points = []
|
||||
while len(sampled_points) < n:
|
||||
sampled_point = self._cartesian_bound.sample(n=1,
|
||||
mode="random",
|
||||
variables=variables)
|
||||
sampled_point = self._cartesian_bound.sample(
|
||||
n=1, mode="random", variables=variables
|
||||
)
|
||||
|
||||
if self.is_inside(sampled_point, self._sample_surface):
|
||||
sampled_points.append(sampled_point)
|
||||
@@ -196,9 +200,9 @@ class SimplexDomain(Location):
|
||||
# extract number of vertices
|
||||
number_of_vertices = self._vertices_matrix.shape[0]
|
||||
# extract idx lambda to set to zero randomly
|
||||
idx_lambda = torch.randint(low=0,
|
||||
high=number_of_vertices,
|
||||
size=(1, ))
|
||||
idx_lambda = torch.randint(
|
||||
low=0, high=number_of_vertices, size=(1,)
|
||||
)
|
||||
# build lambda vector
|
||||
# 1. sampling [1, 2)
|
||||
lambdas = torch.rand((number_of_vertices, 1))
|
||||
@@ -236,4 +240,4 @@ class SimplexDomain(Location):
|
||||
else:
|
||||
raise NotImplementedError(f"mode={mode} is not implemented.")
|
||||
|
||||
return LabelTensor(sample_pts, labels=self.variables)
|
||||
return LabelTensor(sample_pts, labels=self.variables)
|
||||
|
||||
@@ -20,7 +20,7 @@ class Union(OperationInterface):
|
||||
with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N`
|
||||
the dimension of the geometry space.
|
||||
|
||||
:param list geometries: A list of geometries from ``pina.geometry``
|
||||
:param list geometries: A list of geometries from ``pina.geometry``
|
||||
such as ``EllipsoidDomain`` or ``CartesianDomain``.
|
||||
|
||||
:Example:
|
||||
@@ -50,7 +50,7 @@ class Union(OperationInterface):
|
||||
return True
|
||||
return False
|
||||
|
||||
def sample(self, n, mode='random', variables='all'):
|
||||
def sample(self, n, mode="random", variables="all"):
|
||||
"""
|
||||
Sample routine for ``Union`` domain.
|
||||
|
||||
@@ -93,8 +93,10 @@ class Union(OperationInterface):
|
||||
# different than zero. Notice that len(geometries) is
|
||||
# always smaller than remaider.
|
||||
sampled_points.append(
|
||||
geometry.sample(num_points + int(i < remainder), mode,
|
||||
variables))
|
||||
geometry.sample(
|
||||
num_points + int(i < remainder), mode, variables
|
||||
)
|
||||
)
|
||||
# in case number of sampled points is smaller than the number of geometries
|
||||
if len(sampled_points) >= n:
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user