feat(condition): implement an IVP condition, to replace ode.IVP
@@ -102,10 +102,42 @@ class NoCondition(BaseCondition):
return output_tensor
- :type net: `torch.nn.Module`
- :param coordinates: Inputs of the neural network.
- :type coordinates: tuple[`torch.Tensor`]
- :return: The re-parameterized output, where actually no condition is enforced.
+class IVP(BaseCondition):
+ r"""An initial value problem of one of the following forms:
+
+ - Dirichlet condition: :math:`x(t)\bigg|_{t = t_0} = x_0`.
+ - Neumann condition: :math:`\displaystyle\frac{\partial x}{\partial t}\bigg|_{t = t_0} = x_0'`.
+
+ :param t_0: The initial time.
+ :type t_0: float
+ :param x_0: The initial value of :math:`x`. :math:`x(t)\bigg|_{t = t_0} = x_0`.
+ :type x_0: float
+ :param x_0_prime: The initial derivative of :math:`x` w.r.t. :math:`t`. :math:`\displaystyle\frac{\partial x}{\partial t}\bigg|_{t = t_0} = x_0'`, defaults to None.
+ :type x_0_prime: float, optional
+ """
+
+ def __init__(self, t_0, x_0, x_0_prime=None):
+ super().__init__()
+ self.t_0, self.x_0, self.x_0_prime = t_0, x_0, x_0_prime
+
+ def parameterize(self, output_tensor, t):
+ r"""Re-parameterize outputs such that the Dirichlet/Neumann condition is satisfied.
+
+ - For Dirichlet condition, the re-parameterization is
+ :math:`\displaystyle x(t) = x_0 + \left(1 - e^{-(t-t_0)}\right) \mathrm{ANN}(t)`
+ where :math:`\mathrm{ANN}` is the neural network.
+ - For Neumann condition, the re-parameterization is
+ :math:`\displaystyle x(t) = x_0 + (t-t_0) x'_0 + \left(1 - e^{-(t-t_0)}\right)^2 \mathrm{ANN}(t)`
+ where :math:`\mathrm{ANN}` is the neural network.
+
+ :param output_tensor: Output of the neural network.
+ :type output_tensor: `torch.Tensor`
+ :param t: Input to the neural network; i.e., sampled time-points; i.e., independent variables.
+ :type t: `torch.Tensor`
+ :return: the re-parameterized output of the network
:rtype: `torch.Tensor`
"""
- return net(*coordinates)
+ if self.x_0_prime is None:
+ return self.x_0 + (1 - torch.exp(-t + self.t_0)) * output_tensor
+ else:
+ return self.x_0 + (t - self.t_0) * self.x_0_prime + ((1 - torch.exp(-t + self.t_0)) ** 2) * output_tensor
