Skip to content

Commit

Permalink
Merge pull request #76 from odegym/v0.3.0
Browse files Browse the repository at this point in the history
V0.3.0
  • Loading branch information
shuheng-liu authored Dec 26, 2020
2 parents f1cb40a + 6ae0014 commit 718f226
Show file tree
Hide file tree
Showing 15 changed files with 2,832 additions and 1,819 deletions.
14 changes: 14 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ API Reference
:inherited-members:
:members:

`neurodiffeq.solvers`
------------------------------------------------------
.. automodule:: neurodiffeq.solvers
:show-inheritance:
:inherited-members:
:members:

`neurodiffeq.monitors`
------------------------------------------------------
.. automodule:: neurodiffeq.monitors
:show-inheritance:
:inherited-members:
:members:

`neurodiffeq.ode`
------------------------------------------------------
.. automodule:: neurodiffeq.ode
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
pygments_style = 'sphinx'


# Mock Modules
Expand Down
4 changes: 2 additions & 2 deletions neurodiffeq/_version_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ def _rename_kwargs(func_name, kwargs, aliases):
for alias, new in aliases.items():
if alias in kwargs:
if new in kwargs:
raise KeyError(f'{func_name} received both {alias} (deprecated) and {new} (recommended)')
warnings.warn(f'The argument {alias} is deprecated; use {new} instead for {func_name}.', FutureWarning)
raise KeyError(f'{func_name} received both `{alias}` (deprecated) and `{new}` (recommended)')
warnings.warn(f'The argument `{alias}` is deprecated; use `{new}` instead for {func_name}.', FutureWarning)
kwargs[new] = kwargs.pop(alias)
97 changes: 71 additions & 26 deletions neurodiffeq/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,18 @@ def parameterize(self, output_tensor, *input_tensors):
r"""Re-parameterizes each column in output_tensor individually, using its corresponding sub-condition.
This is useful when solving differential equations with a single, multi-output network.
:param output_tensor: Output of the neural network. Number of units (.shape[1]) must equal number of sub-conditions.
:param output_tensor:
Output of the neural network.
Number of units (.shape[1]) must equal number of sub-conditions.
:type output_tensor: `torch.Tensor`
:param input_tensors: Inputs to the neural network; i.e., sampled coordinates; i.e., independent variables.
:param input_tensors:
Inputs to the neural network;
i.e., sampled coordinates;
i.e., independent variables.
:type input_tensors: `torch.Tensor`
:return: The column-wise re-parameterized network output, concatenated across columns so that it's still one tensor.
:return:
The column-wise re-parameterized network output,
concatenated across columns so that it's still one tensor.
:rtype: `torch.Tensor`
"""
if output_tensor.shape[1] != len(self.conditions):
Expand Down Expand Up @@ -165,7 +172,10 @@ class IVP(BaseCondition):
:type t_0: float
:param u_0: The initial value of :math:`u`. :math:`u(t_0)=u_0`.
:type u_0: float
:param u_0_prime: The initial derivative of :math:`u` w.r.t. :math:`t`. :math:`\displaystyle\frac{\partial u}{\partial t}\bigg|_{t = t_0} = u_0'`, defaults to None.
:param u_0_prime:
The initial derivative of :math:`u` w.r.t. :math:`t`.
:math:`\displaystyle\frac{\partial u}{\partial t}\bigg|_{t = t_0} = u_0'`.
Defaults to None.
:type u_0_prime: float, optional
"""

Expand Down Expand Up @@ -293,9 +303,9 @@ def parameterize(self, output_tensor, x, y):
:param output_tensor: Output of the neural network.
:type output_tensor: `torch.Tensor`
:param x: :math:`x`-coordinates of inputs to the neural network; i.e., the sampled :math:`x`-coordinates
:param x: :math:`x`-coordinates of inputs to the neural network; i.e., the sampled :math:`x`-coordinates.
:type x: `torch.Tensor`
:param y: :math:`y`-coordinates of inputs to the neural network; i.e., the sampled :math:`y`-coordinates
:param y: :math:`y`-coordinates of inputs to the neural network; i.e., the sampled :math:`y`-coordinates.
:type y: `torch.Tensor`
:return: The re-parameterized output of the network.
:rtype: `torch.Tensor`
Expand Down Expand Up @@ -522,13 +532,22 @@ class DirichletBVPSpherical(BaseCondition):
- :math:`u(r_0,\theta,\phi)=f(\theta,\phi)`
- :math:`u(r_1,\theta,\phi)=g(\theta,\phi)`
:param r_0: The radius of the interior boundary. When :math:`r_0 = 0`, the interior boundary collapses to a single point (center of the ball).
:param r_0:
The radius of the interior boundary.
When :math:`r_0 = 0`, the interior boundary collapses to a single point (center of the ball).
:type r_0: float
:param f: The value of :math:`u` on the interior boundary. :math:`u(r_0, \theta, \phi)=f(\theta, \phi)`.
:param f:
The value of :math:`u` on the interior boundary.
:math:`u(r_0, \theta, \phi)=f(\theta, \phi)`.
:type f: callable
:param r_1: The radius of the exterior boundary; if set to None, `g` must also be None.
:param r_1:
The radius of the exterior boundary.
If set to None, `g` must also be None.
:type r_1: float or None
:param g: The value of :math:`u` on the exterior boundary. :math:`u(r_1, \theta, \phi)=g(\theta, \phi)`. If set to None, `r_1` must also be set to None.
:param g:
The value of :math:`u` on the exterior boundary.
:math:`u(r_1, \theta, \phi)=g(\theta, \phi)`.
If set to None, `r_1` must also be set to None.
:type g: callable or None
"""

Expand Down Expand Up @@ -585,14 +604,22 @@ class InfDirichletBVPSpherical(BaseCondition):
- :math:`\displaystyle u(r_0,\theta,\phi)=f(\theta,\phi)`,
- :math:`\lim_{r\to+\infty}u(r,\theta,\phi)=g(\theta,\phi)`.
:param r_0: The radius of the interior boundary. When :math:`r_0=0`, the interior boundary collapses to a single point (center of the ball).
:param r_0:
The radius of the interior boundary.
When :math:`r_0=0`, the interior boundary collapses to a single point (center of the ball).
:type r_0: float
:param f: The value of :math:`u` on the interior boundary. :math:`u(r_0,\theta,\phi)=f(\theta,\phi)`.
:param f:
The value of :math:`u` on the interior boundary.
:math:`u(r_0,\theta,\phi)=f(\theta,\phi)`.
:type f: callable
:param g: The value of :math:`u` at infinity. :math:`\lim_{r\to+\infty}u(r,\theta,\phi)=g(\theta,\phi)`.
:param g:
The value of :math:`u` at infinity.
:math:`\lim_{r\to+\infty}u(r,\theta,\phi)=g(\theta,\phi)`.
:type g: callable
:param order: The smallest :math:`k` such that :math:`\lim_{r\to+\infty}u(r,\theta,\phi)e^{-kr}=0`, defaults to 1.
:type order: int or float, optional
:param order:
The smallest :math:`k` such that :math:`\lim_{r\to+\infty}u(r,\theta,\phi)e^{-kr}=0`.
Defaults to 1.
:type order: int or float
"""

def __init__(self, r_0, f, g, order=1):
Expand Down Expand Up @@ -646,15 +673,24 @@ class DirichletBVPSphericalBasis(BaseCondition):
The boundary conditions are: :math:`\mathbf{R}(r_0)=\mathbf{R}_0` and :math:`\mathbf{R}(r_1)=\mathbf{R}_1`,
where :math:`\mathbf{R}` is a vector whose components are :math:`\big\{R_k\big\}_{k=1}^{K}`
:param r_0: The radius of the interior boundary. When r_0 = 0, the interior boundary is collapsed to a single point (center of the ball)
:param r_0:
The radius of the interior boundary.
When r_0 = 0, the interior boundary is collapsed to a single point (center of the ball).
:type r_0: float
:param R_0: The value of harmonic coefficients :math:`\mathbf{R}` on the interior boundary. :math:`\mathbf{R}(r_0)=\mathbf{R}_0`.
:param R_0:
The value of harmonic coefficients :math:`\mathbf{R}` on the interior boundary.
:math:`\mathbf{R}(r_0)=\mathbf{R}_0`.
:type R_0: `torch.Tensor`
:param r_1: The radius of the exterior boundary; if set to None, `R_1` must also be None
:param r_1:
The radius of the exterior boundary.
If set to None, `R_1` must also be None
:type r_1: float or None
:param R_1: The value of harmonic coefficients :math:`\mathbf{R}` on the exterior boundary. :math:`\mathbf{R}(r_1)=\mathbf{R}_1`.
:param R_1:
The value of harmonic coefficients :math:`\mathbf{R}` on the exterior boundary.
:math:`\mathbf{R}(r_1)=\mathbf{R}_1`.
:type R_1: `torch.Tensor`
:param max_degree: **[DEPRECATED]** highest degree when using spherical harmonics
:param max_degree:
**[DEPRECATED]** Highest degree when using spherical harmonics.
:type max_degree: int
"""

Expand Down Expand Up @@ -716,15 +752,24 @@ class InfDirichletBVPSphericalBasis(BaseCondition):
:math:`\lim_{r_0\to+\infty}\mathbf{R}(r)=\mathbf{R}_1`,
where :math:`\mathbf{R}` is a vector whose components are :math:`\big\{R_k\big\}_{k=1}^{K}`.
:param r_0: The radius of the interior boundary. When r_0 = 0, the interior boundary is collapsed to a single point (center of the ball)
:param r_0:
The radius of the interior boundary.
When r_0 = 0, the interior boundary is collapsed to a single point (center of the ball).
:type r_0: float
:param R_0: The value of harmonic coefficients :math:`R` on the interior boundary. :math:`R(r_0)=R_0`.
:param R_0:
The value of harmonic coefficients :math:`R` on the interior boundary.
:math:`R(r_0)=R_0`.
:type R_0: `torch.Tensor`
:param R_inf: The value of harmonic coefficients :math:`R` at infinity. :math:`\lim_{r\to+\infty}R(r)=R_\infty`.
:param R_inf:
The value of harmonic coefficients :math:`R` at infinity.
:math:`\lim_{r\to+\infty}R(r)=R_\infty`.
:type R_inf: `torch.Tensor`
:param order: The smallest :math:`k` that guarantees :math:`\lim_{r \to +\infty} R(r) e^{-k r} = \bf 0`, defaults to 1
:type order: int or float, optional
:param max_degree: **[DEPRECATED]** highest degree when using spherical harmonics
:param order:
The smallest :math:`k` that guarantees :math:`\lim_{r \to +\infty} R(r) e^{-k r} = \bf 0`.
Defaults to 1.
:type order: int or float
:param max_degree:
**[DEPRECATED]** Highest degree when using spherical harmonics.
:type max_degree: int
"""

Expand Down
8 changes: 4 additions & 4 deletions neurodiffeq/function_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,21 +278,21 @@ class HarmonicsLaplacian(BasisOperator):
:math:`\begin{aligned}
&\nabla^{2} R_{l, m}(r) Y_{l,m}(\theta, \phi)\\
&=\left(\nabla_{r}^{2}+\nabla_{\theta}^{2}+\nabla_{\phi}^{2}\right)\left(R_{l, m}(r) Y_{l, m}(\theta, \phi)\right)\\
&=Y_{l, m} \nabla_{r}^{2} R_{l, m}+R_{l, m}\left(\left(\nabla_{\theta}^{2}+\nabla_{\phi}^{2}\right) Y_{l, m}\right)\\
&=Y_{l, m} \nabla_{r}^{2} R_{l, m}+R_{l, m}\left(\left(\nabla_{\theta}^{2}+\nabla_{\phi}^{2}\right)Y_{l, m}\right)\\
&=Y_{l, m} \nabla_{r}^{2} R_{l, m}+R_{l, m} \frac{-l(l+1)}{r^{2}} Y_{l, m}\\
&=Y_{l, m}\left(\nabla_{r}^{2} R_{l, m}+\frac{-l(l+1)}{r^{2}} R_{l, m}\right)
\end{aligned}`
"""

def __init__(self, max_degree=4):
self.harmonics_fn = RealSphericalHarmonics(max_degree=max_degree)
laplacian_coefficients = [-l * (l + 1) for l in range(max_degree + 1) for m in range(-l, l + 1)]
self.laplacian_coefficients = torch.tensor(laplacian_coefficients).type(torch.float)
laplacian_coefficients = [-l * (l + 1) * 1.0 for l in range(max_degree + 1) for m in range(-l, l + 1)]
self.laplacian_coefficients = torch.tensor(laplacian_coefficients)

def __call__(self, R, r, theta, phi):
# We would hope to do `radial_component = diff(R * r, r, order=2) / r`
# But because of this issue https://github.com/odegym/neurodiffeq/issues/44#issuecomment-594998619,
# we have to separate columns in R, compute derivates, and manually concatenate them back together
# we have to separate columns in R, compute derivatives, and manually concatenate them back together
radial_component = torch.cat([diff(R[:, j:j+1] * r, r, order=2) for j in range(R.shape[1])], dim=1) / r

angular_component = self.laplacian_coefficients * R / r ** 2
Expand Down
Loading

0 comments on commit 718f226

Please sign in to comment.