Files
PINA/pina/problem/inverse_problem.py
Dario Coscia 42ab1a666b Formatting
* Adding black as dev dependency
* Formatting pina code
* Formatting tests
2025-03-19 17:46:36 +01:00

83 lines
2.9 KiB
Python

"""Module for the ParametricProblem class"""
import torch
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.operator 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))
"""
def __init__(self):
super().__init__()
# storing unknown_parameters for optimization
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)
@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