Inverse problem implementation (#177)
* inverse problem implementation * add tutorial7 for inverse Poisson problem * fix doc in equation, equation_interface, system_equation --------- Co-authored-by: Dario Coscia <dariocoscia@dhcp-015.eduroam.sissa.it>
This commit is contained in:
committed by
Nicola Demo
parent
a9f14ac323
commit
0b7a307cf1
@@ -3,9 +3,11 @@ __all__ = [
|
||||
'SpatialProblem',
|
||||
'TimeDependentProblem',
|
||||
'ParametricProblem',
|
||||
'InverseProblem',
|
||||
]
|
||||
|
||||
from .abstract_problem import AbstractProblem
|
||||
from .spatial_problem import SpatialProblem
|
||||
from .timedep_problem import TimeDependentProblem
|
||||
from .parametric_problem import ParametricProblem
|
||||
from .inverse_problem import InverseProblem
|
||||
|
||||
@@ -109,6 +109,14 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
samples = condition.input_points
|
||||
self.input_pts[condition_name] = samples
|
||||
self._have_sampled_points[condition_name] = True
|
||||
if hasattr(self, 'unknown_parameter_domain'):
|
||||
# initialize the unknown parameters of the inverse problem given
|
||||
# the domain the user gives
|
||||
self.unknown_parameters = {}
|
||||
for i, var in enumerate(self.unknown_variables):
|
||||
range_var = self.unknown_parameter_domain.range_[var]
|
||||
tensor_var = torch.rand(1, requires_grad=True) * range_var[1] + range_var[0]
|
||||
self.unknown_parameters[var] = torch.nn.Parameter(tensor_var)
|
||||
|
||||
def discretise_domain(self,
|
||||
n,
|
||||
@@ -203,6 +211,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
self.input_variables):
|
||||
self._have_sampled_points[location] = True
|
||||
|
||||
|
||||
def add_points(self, new_points):
|
||||
"""
|
||||
Adding points to the already sampled points.
|
||||
@@ -237,7 +246,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
@property
|
||||
def have_sampled_points(self):
|
||||
"""
|
||||
Check if all points for
|
||||
Check if all points for
|
||||
``Location`` are sampled.
|
||||
"""
|
||||
return all(self._have_sampled_points.values())
|
||||
@@ -245,7 +254,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
@property
|
||||
def not_sampled_points(self):
|
||||
"""
|
||||
Check which points are
|
||||
Check which points are
|
||||
not sampled.
|
||||
"""
|
||||
# variables which are not sampled
|
||||
@@ -257,3 +266,4 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
if not is_sample:
|
||||
not_sampled.append(condition_name)
|
||||
return not_sampled
|
||||
|
||||
|
||||
71
pina/problem/inverse_problem.py
Normal file
71
pina/problem/inverse_problem.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Module for the ParametricProblem class"""
|
||||
from abc import abstractmethod
|
||||
|
||||
from .abstract_problem import AbstractProblem
|
||||
|
||||
|
||||
class InverseProblem(AbstractProblem):
|
||||
"""
|
||||
The class for the definition of inverse problems, i.e., problems
|
||||
with unknown parameters that have to be learned during the training process
|
||||
from given data.
|
||||
|
||||
Here's an example of a spatial inverse ODE problem, i.e., a spatial
|
||||
ODE problem with an unknown parameter `alpha` as coefficient of the
|
||||
derivative term.
|
||||
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem, InverseProblem
|
||||
>>> from pina.operators import grad
|
||||
>>> from pina.equation import ParametricEquation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
>>>
|
||||
>>> class InverseODE(SpatialProblem, InverseProblem):
|
||||
>>>
|
||||
>>> output_variables = ['u']
|
||||
>>> spatial_domain = CartesianDomain({'x': [0, 1]})
|
||||
>>> unknown_parameter_domain = CartesianDomain({'alpha': [1, 10]})
|
||||
>>>
|
||||
>>> def ode_equation(input_, output_, params_):
|
||||
>>> u_x = grad(output_, input_, components=['u'], d=['x'])
|
||||
>>> u = output_.extract(['u'])
|
||||
>>> return params_.extract(['alpha']) * u_x - u
|
||||
>>>
|
||||
>>> def solution_data(input_, output_):
|
||||
>>> x = input_.extract(['x'])
|
||||
>>> solution = torch.exp(x)
|
||||
>>> return output_ - solution
|
||||
>>>
|
||||
>>> conditions = {
|
||||
>>> 'x0': Condition(CartesianDomain({'x': 0}), FixedValue(1.0)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 1]}), ParametricEquation(ode_equation)),
|
||||
>>> 'data': Condition(CartesianDomain({'x': [0, 1]}), Equation(solution_data))
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def unknown_parameter_domain(self):
|
||||
"""
|
||||
The parameters' domain of the problem.
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
def unknown_variables(self):
|
||||
"""
|
||||
The parameters of the problem.
|
||||
"""
|
||||
return self.unknown_parameter_domain.variables
|
||||
|
||||
@property
|
||||
def unknown_parameters(self):
|
||||
"""
|
||||
The parameters of the problem.
|
||||
"""
|
||||
return self.__unknown_parameters
|
||||
|
||||
@unknown_parameters.setter
|
||||
def unknown_parameters(self, value):
|
||||
self.__unknown_parameters = value
|
||||
|
||||
@@ -14,7 +14,7 @@ class SpatialProblem(AbstractProblem):
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem
|
||||
>>> from pina.operators import grad
|
||||
>>> from pina.equations import Equation, FixedValue
|
||||
>>> from pina.equation import Equation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
@@ -33,7 +33,6 @@ class SpatialProblem(AbstractProblem):
|
||||
>>> conditions = {
|
||||
>>> 'x0': Condition(CartesianDomain({'x': 0, 'alpha':[1, 10]}), FixedValue(1.)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 1], 'alpha':[1, 10]}), Equation(ode_equation))}
|
||||
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@@ -14,7 +14,7 @@ class TimeDependentProblem(AbstractProblem):
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem, TimeDependentProblem
|
||||
>>> from pina.operators import grad, laplacian
|
||||
>>> from pina.equations import Equation, FixedValue
|
||||
>>> from pina.equation import Equation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
@@ -43,7 +43,6 @@ class TimeDependentProblem(AbstractProblem):
|
||||
>>> 'gamma1': Condition(CartesianDomain({'x':0, 't':[0, 1]}), FixedValue(0.)),
|
||||
>>> 'gamma2': Condition(CartesianDomain({'x':3, 't':[0, 1]}), FixedValue(0.)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 3], 't':[0, 1]}), Equation(wave_equation))}
|
||||
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
|
||||
Reference in New Issue
Block a user