beginning of domain doc
This commit is contained in:
@@ -8,14 +8,19 @@ from ..utils import torch_lhs, chebyshev_roots
|
|||||||
|
|
||||||
|
|
||||||
class CartesianDomain(DomainInterface):
|
class CartesianDomain(DomainInterface):
|
||||||
"""PINA implementation of Hypercube domain."""
|
"""
|
||||||
|
Implementation of the hypercube domain.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, cartesian_dict):
|
def __init__(self, cartesian_dict):
|
||||||
"""
|
"""
|
||||||
:param cartesian_dict: A dictionary with dict-key a string representing
|
Initialize the :class:`~pina.domain.CartesianDomain` class.
|
||||||
the input variables for the pinn, and dict-value a list with
|
|
||||||
the domain extrema.
|
:param dict cartesian_dict: A dictionary where the keys are the
|
||||||
:type cartesian_dict: dict
|
variable names and the values are the domain extrema. The domain
|
||||||
|
extrema can be either a list with two elements or a single number.
|
||||||
|
If the domain extrema is a single number, the variable is fixed to
|
||||||
|
that value.
|
||||||
|
|
||||||
:Example:
|
:Example:
|
||||||
>>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
>>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||||
@@ -33,22 +38,31 @@ class CartesianDomain(DomainInterface):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def sample_modes(self):
|
def sample_modes(self):
|
||||||
|
"""
|
||||||
|
List of available sampling modes.
|
||||||
|
|
||||||
|
:return: List of available sampling modes.
|
||||||
|
:rtype: list[str]
|
||||||
|
"""
|
||||||
return ["random", "grid", "lh", "chebyshev", "latin"]
|
return ["random", "grid", "lh", "chebyshev", "latin"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def variables(self):
|
def variables(self):
|
||||||
"""Spatial variables.
|
"""
|
||||||
|
List of variables of the domain.
|
||||||
|
|
||||||
:return: Spatial variables defined in ``__init__()``
|
:return: List of variables of the domain.
|
||||||
:rtype: list[str]
|
:rtype: list[str]
|
||||||
"""
|
"""
|
||||||
return sorted(list(self.fixed_.keys()) + list(self.range_.keys()))
|
return sorted(list(self.fixed_.keys()) + list(self.range_.keys()))
|
||||||
|
|
||||||
def update(self, new_domain):
|
def update(self, new_domain):
|
||||||
"""Adding new dimensions on the ``CartesianDomain``
|
"""
|
||||||
|
Add new dimensions to an existing :class:`~pina.domain.CartesianDomain`
|
||||||
|
object.
|
||||||
|
|
||||||
:param CartesianDomain new_domain: A new ``CartesianDomain`` object
|
:param :class:`~pina.domain.CartesianDomain` new_domain: New domain to
|
||||||
to merge
|
be added to an existing :class:`~pina.domain.CartesianDomain` object.
|
||||||
|
|
||||||
:Example:
|
:Example:
|
||||||
>>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
>>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||||
@@ -63,24 +77,20 @@ class CartesianDomain(DomainInterface):
|
|||||||
self.range_.update(new_domain.range_)
|
self.range_.update(new_domain.range_)
|
||||||
|
|
||||||
def _sample_range(self, n, mode, bounds):
|
def _sample_range(self, n, mode, bounds):
|
||||||
"""Rescale the samples to the correct bounds
|
"""
|
||||||
|
Rescale the samples to fit within the specified bounds.
|
||||||
|
|
||||||
:param n: Number of points to sample, see Note below
|
:param int n: Number of points to sample.
|
||||||
for reference.
|
:param str mode: Sampling method. Default is ``random``.
|
||||||
:type n: int
|
:param torch.Tensor bounds: Bounds of the domain.
|
||||||
:param mode: Mode for sampling, defaults to ``random``.
|
:raises RuntimeError: Wrong bounds initialization.
|
||||||
Available modes include: random sampling, ``random``;
|
:raises ValueError: Invalid sampling mode.
|
||||||
latin hypercube sampling, ``latin`` or ``lh``;
|
|
||||||
chebyshev sampling, ``chebyshev``; grid sampling ``grid``.
|
|
||||||
:type mode: str
|
|
||||||
:param bounds: Bounds to rescale the samples.
|
|
||||||
:type bounds: torch.Tensor
|
|
||||||
:return: Rescaled sample points.
|
:return: Rescaled sample points.
|
||||||
:rtype: torch.Tensor
|
:rtype: torch.Tensor
|
||||||
"""
|
"""
|
||||||
dim = bounds.shape[0]
|
dim = bounds.shape[0]
|
||||||
if mode in ["chebyshev", "grid"] and dim != 1:
|
if mode in ["chebyshev", "grid"] and dim != 1:
|
||||||
raise RuntimeError("Something wrong in Cartesian...")
|
raise RuntimeError("Wrong bounds initialization")
|
||||||
|
|
||||||
if mode == "random":
|
if mode == "random":
|
||||||
pts = torch.rand(size=(n, dim))
|
pts = torch.rand(size=(n, dim))
|
||||||
@@ -88,7 +98,6 @@ class CartesianDomain(DomainInterface):
|
|||||||
pts = chebyshev_roots(n).mul(0.5).add(0.5).reshape(-1, 1)
|
pts = chebyshev_roots(n).mul(0.5).add(0.5).reshape(-1, 1)
|
||||||
elif mode == "grid":
|
elif mode == "grid":
|
||||||
pts = torch.linspace(0, 1, n).reshape(-1, 1)
|
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 = torch_lhs(n, dim)
|
||||||
else:
|
else:
|
||||||
@@ -97,36 +106,35 @@ class CartesianDomain(DomainInterface):
|
|||||||
return pts * (bounds[:, 1] - bounds[:, 0]) + bounds[:, 0]
|
return pts * (bounds[:, 1] - bounds[:, 0]) + bounds[:, 0]
|
||||||
|
|
||||||
def sample(self, n, mode="random", variables="all"):
|
def sample(self, n, mode="random", variables="all"):
|
||||||
"""Sample routine.
|
"""
|
||||||
|
Sampling routine.
|
||||||
|
|
||||||
:param n: Number of points to sample, see Note below
|
:param int n: Number of points to sample, see Note below for reference.
|
||||||
for reference.
|
:param str mode: Sampling method. Default is ``random``.
|
||||||
:type n: int
|
Available modes: random sampling, ``random``;
|
||||||
:param mode: Mode for sampling, defaults to ``random``.
|
latin hypercube sampling, ``latin`` or ``lh``;
|
||||||
Available modes include: random sampling, ``random``;
|
|
||||||
latin hypercube sampling, ``latin`` or ``lh``;
|
|
||||||
chebyshev sampling, ``chebyshev``; grid sampling ``grid``.
|
chebyshev sampling, ``chebyshev``; grid sampling ``grid``.
|
||||||
:type mode: str
|
:param variables: variables to be sampled. Default is ``all``.
|
||||||
:param variables: pinn variable to be sampled, defaults to ``all``.
|
|
||||||
:type variables: str | list[str]
|
:type variables: str | list[str]
|
||||||
:return: Returns ``LabelTensor`` of n sampled points.
|
:return: Sampled points.
|
||||||
:rtype: LabelTensor
|
:rtype: LabelTensor
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The total number of points sampled in case of multiple variables
|
When multiple variables are involved, the total number of sampled
|
||||||
is not ``n``, and it depends on the chosen ``mode``. If ``mode`` is
|
points may differ from ``n``, depending on the chosen ``mode``.
|
||||||
'grid' or ``chebyshev``, the points are sampled independentely
|
If ``mode`` is ``grid`` or ``chebyshev``, points are sampled
|
||||||
across the variables and the results crossed together, i.e. the
|
independently for each variable and then combined, resulting in a
|
||||||
final number of points is ``n`` to the power of the number of
|
total number of points equal to ``n`` raised to the power of the
|
||||||
variables. If 'mode' is 'random', ``lh`` or ``latin``, the variables
|
number of variables. If 'mode' is 'random', ``lh`` or ``latin``,
|
||||||
are sampled all together, and the final number of points
|
all variables are sampled together, and the total number of points
|
||||||
|
remains ``n``.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
The extrema values of Span are always sampled only for ``grid``
|
The extrema of CartesianDomain are only sampled when using the
|
||||||
mode.
|
``grid`` mode.
|
||||||
|
|
||||||
:Example:
|
:Example:
|
||||||
>>> spatial_domain = Span({'x': [0, 1], 'y': [0, 1]})
|
>>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||||
>>> spatial_domain.sample(n=4, mode='random')
|
>>> spatial_domain.sample(n=4, mode='random')
|
||||||
tensor([[0.0108, 0.7643],
|
tensor([[0.0108, 0.7643],
|
||||||
[0.4477, 0.8015],
|
[0.4477, 0.8015],
|
||||||
@@ -152,7 +160,16 @@ class CartesianDomain(DomainInterface):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def _1d_sampler(n, mode, variables):
|
def _1d_sampler(n, mode, variables):
|
||||||
"""Sample independentely the variables and cross the results"""
|
"""
|
||||||
|
Sample each variable independently.
|
||||||
|
|
||||||
|
:param int n: Number of points to sample.
|
||||||
|
:param str mode: Sampling method.
|
||||||
|
:param variables: variables to be sampled.
|
||||||
|
:type variables: str | list[str]
|
||||||
|
:return: Sampled points.
|
||||||
|
:rtype: list[LabelTensor]
|
||||||
|
"""
|
||||||
tmp = []
|
tmp = []
|
||||||
for variable in variables:
|
for variable in variables:
|
||||||
if variable in self.range_:
|
if variable in self.range_:
|
||||||
@@ -181,19 +198,15 @@ class CartesianDomain(DomainInterface):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _Nd_sampler(n, mode, variables):
|
def _Nd_sampler(n, mode, variables):
|
||||||
"""Sample all the variables together
|
"""
|
||||||
|
Sample all variables together.
|
||||||
|
|
||||||
:param n: Number of points to sample.
|
:param int n: Number of points to sample.
|
||||||
:type n: int
|
:param str mode: Sampling method.
|
||||||
:param mode: Mode for sampling, defaults to ``random``.
|
:param variables: variables to be sampled.
|
||||||
Available modes include: random sampling, ``random``;
|
:type variables: str | list[str]
|
||||||
latin hypercube sampling, ``latin`` or ``lh``;
|
:return: Sampled points.
|
||||||
chebyshev sampling, ``chebyshev``; grid sampling ``grid``.
|
:rtype: list[LabelTensor]
|
||||||
:type mode: str.
|
|
||||||
:param variables: pinn variable to be sampled, defaults to ``all``.
|
|
||||||
:type variables: str or list[str].
|
|
||||||
:return: Sample points.
|
|
||||||
:rtype: list[torch.Tensor]
|
|
||||||
"""
|
"""
|
||||||
pairs = [(k, v) for k, v in self.range_.items() if k in variables]
|
pairs = [(k, v) for k, v in self.range_.items() if k in variables]
|
||||||
keys, values = map(list, zip(*pairs))
|
keys, values = map(list, zip(*pairs))
|
||||||
@@ -215,13 +228,13 @@ class CartesianDomain(DomainInterface):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _single_points_sample(n, variables):
|
def _single_points_sample(n, variables):
|
||||||
"""Sample a single point in one dimension.
|
"""
|
||||||
|
Sample a single point in one dimension.
|
||||||
|
|
||||||
:param n: Number of points to sample.
|
:param int n: Number of points to sample.
|
||||||
:type n: int
|
:param variables: variables to be sampled.
|
||||||
:param variables: Variables to sample from.
|
:type variables: str | list[str]
|
||||||
:type variables: list[str]
|
:return: Sampled points.
|
||||||
:return: Sample points.
|
|
||||||
:rtype: list[torch.Tensor]
|
:rtype: list[torch.Tensor]
|
||||||
"""
|
"""
|
||||||
tmp = []
|
tmp = []
|
||||||
@@ -256,14 +269,13 @@ class CartesianDomain(DomainInterface):
|
|||||||
raise ValueError(f"mode={mode} is not valid.")
|
raise ValueError(f"mode={mode} is not valid.")
|
||||||
|
|
||||||
def is_inside(self, point, check_border=False):
|
def is_inside(self, point, check_border=False):
|
||||||
"""Check if a point is inside the ellipsoid.
|
"""
|
||||||
|
Check if a point is inside the hypercube.
|
||||||
|
|
||||||
:param point: Point to be checked
|
:param LabelTensor point: Point to be checked.
|
||||||
:type point: LabelTensor
|
:param bool check_border: Determines whether to check if the point lies
|
||||||
:param check_border: Check if the point is also on the frontier
|
on the boundary of the hypercube. Default is ``False``.
|
||||||
of the hypercube, default ``False``.
|
:return: ``True`` if the point is inside the domain, ``False`` otherwise.
|
||||||
:type check_border: bool
|
|
||||||
:return: Returning ``True`` if the point is inside, ``False`` otherwise.
|
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
is_inside = []
|
is_inside = []
|
||||||
|
|||||||
Reference in New Issue
Block a user