From 8b7b61b3bd3b10bacf55b41bb1869e74decaa866 Mon Sep 17 00:00:00 2001 From: Dario Coscia <93731561+dario-coscia@users.noreply.github.com> Date: Wed, 8 Nov 2023 14:39:00 +0100 Subject: [PATCH] Documentation for v0.1 version (#199) * Adding Equations, solving typos * improve _code.rst * the team rst and restuctore index.rst * fixing errors --------- Co-authored-by: Dario Coscia --- docs/.nojekyll | 0 docs/index.html | 6 - docs/source/_cite.rst | 21 ++ docs/source/_rst/_code.rst | 130 +++++++--- docs/source/_rst/_tutorial.rst | 39 +++ docs/source/_rst/_tutorials.rst | 27 --- .../adaptive_refinment_callbacks.rst | 7 + .../_rst/callbacks/optimizer_callbacks.rst | 7 + .../_rst/callbacks/processing_callbacks.rst | 7 + docs/source/_rst/condition.rst | 3 - docs/source/_rst/equations.rst | 42 ++++ docs/source/_rst/geometry/cartesian.rst | 2 +- .../_rst/geometry/difference_domain.rst | 9 + docs/source/_rst/geometry/ellipsoid.rst | 2 +- .../source/_rst/geometry/exclusion_domain.rst | 9 + .../_rst/geometry/intersection_domain.rst | 9 + docs/source/_rst/geometry/location.rst | 3 +- .../_rst/geometry/operation_interface.rst | 9 + docs/source/_rst/geometry/simplex.rst | 2 +- docs/source/_rst/geometry/union_domain.rst | 9 + docs/source/_rst/label_tensor.rst | 1 - docs/source/_rst/layers/convolution.rst | 8 +- docs/source/_rst/layers/enhanced_linear.rst | 8 + docs/source/_rst/layers/fourier.rst | 16 ++ docs/source/_rst/layers/residual.rst | 7 + docs/source/_rst/layers/spectral.rst | 15 ++ docs/source/_rst/loss/loss_interface.rst | 3 +- docs/source/_rst/loss/lploss.rst | 4 +- docs/source/_rst/loss/powerloss.rst | 4 +- docs/source/_rst/models/deeponet.rst | 3 - docs/source/_rst/models/fnn.rst | 5 +- docs/source/_rst/models/fnn_residual.rst | 5 +- docs/source/_rst/models/fno.rst | 3 - docs/source/_rst/models/mionet.rst | 7 + docs/source/_rst/models/multifeedforward.rst | 5 +- docs/source/_rst/models/network.rst | 2 - .../{equations_operators => }/operators.rst | 6 +- docs/source/_rst/problem/abstractproblem.rst | 2 - .../source/_rst/problem/parametricproblem.rst | 3 +- docs/source/_rst/problem/spatialproblem.rst | 2 - docs/source/_rst/problem/timedepproblem.rst | 2 - docs/source/_rst/solvers/garom.rst | 7 + docs/source/_rst/solvers/pinn.rst | 5 +- docs/source/_rst/solvers/solver_interface.rst | 7 +- docs/source/_rst/solvers/supervised.rst | 7 + docs/source/_rst/trainer.rst | 8 + .../_rst/tutorials/tutorial1/tutorial.rst | 4 +- .../_rst/tutorials/tutorial2/tutorial.rst | 30 ++- .../_rst/tutorials/tutorial3/tutorial.rst | 15 +- .../_rst/tutorials/tutorial4/tutorial.rst | 48 ++-- docs/source/_team.rst | 24 ++ docs/source/conf.py | 61 +++-- docs/source/index.rst | 27 +-- docs/source/index_files/API_color.png | Bin 124005 -> 161741 bytes docs/source/index_files/foudings.png | Bin 0 -> 79867 bytes docs/source/index_files/pina_logo.png | Bin 52492 -> 91576 bytes .../index_files/university_dev_pina.png | Bin 0 -> 119229 bytes docs/sphinx_extensions/paramref_extension.py | 11 + pina/__init__.py | 16 +- pina/adaptive_functions/__init__.py | 1 - pina/adaptive_functions/adaptive_cos.py | 16 +- pina/adaptive_functions/adaptive_exp.py | 20 +- pina/adaptive_functions/adaptive_linear.py | 6 +- pina/adaptive_functions/adaptive_relu.py | 8 +- pina/adaptive_functions/adaptive_sin.py | 20 +- pina/adaptive_functions/adaptive_softplus.py | 6 +- pina/adaptive_functions/adaptive_square.py | 8 +- pina/adaptive_functions/adaptive_tanh.py | 22 +- pina/callbacks/__init__.py | 8 +- .../callbacks/adaptive_refinment_callbacks.py | 78 ++++-- pina/callbacks/optimizer_callbacks.py | 56 +++-- pina/callbacks/processing_callbacks.py | 51 +++- pina/condition.py | 22 +- pina/equation/equation.py | 7 +- pina/equation/equation_factory.py | 18 +- pina/equation/system_equation.py | 22 +- pina/geometry/__init__.py | 11 +- pina/geometry/cartesian.py | 91 +++---- pina/geometry/difference_domain.py | 53 ++-- pina/geometry/ellipsoid.py | 47 ++-- pina/geometry/exclusion_domain.py | 52 ++-- pina/geometry/intersection_domain.py | 51 ++-- pina/geometry/location.py | 7 +- pina/geometry/operation_interface.py | 37 +-- pina/geometry/simplex.py | 79 +++--- pina/geometry/union_domain.py | 56 +++-- pina/label_tensor.py | 48 ++-- pina/loss.py | 99 ++++---- pina/meta.py | 15 +- pina/model/deeponet.py | 162 +++++++------ pina/model/feed_forward.py | 115 +++++---- pina/model/fno.py | 54 +++-- pina/model/layers/convolution.py | 38 +-- pina/model/layers/convolution_2d.py | 227 +++++++++--------- pina/model/layers/fourier.py | 66 +++-- pina/model/layers/residual.py | 112 +++++---- pina/model/layers/spectral.py | 169 ++++++------- pina/model/layers/stride.py | 10 +- pina/model/layers/utils_convolution.py | 4 +- pina/model/multi_feed_forward.py | 3 +- pina/model/network.py | 24 +- pina/operators.py | 36 +-- pina/plotter.py | 94 +++++--- pina/problem/abstract_problem.py | 61 ++--- pina/problem/parametric_problem.py | 18 +- pina/problem/spatial_problem.py | 21 +- pina/problem/timedep_problem.py | 21 +- pina/solvers/__init__.py | 4 + pina/solvers/garom.py | 114 +++++---- pina/solvers/pinn.py | 61 ++--- pina/solvers/solver.py | 63 +++-- pina/solvers/supervised.py | 54 +++-- pina/trainer.py | 30 ++- pina/utils.py | 6 +- pina/writer.py | 7 +- .../test_adaptive_refinment_callbacks.py | 20 +- .../test_optimizer_callbacks.py | 33 ++- tests/test_condition.py | 10 +- tests/test_equations/test_equation.py | 11 +- tests/test_equations/test_systemequation.py | 11 +- tests/test_geometry/test_cartesian.py | 11 +- tests/test_geometry/test_difference.py | 80 +++++- tests/test_geometry/test_ellipsoid.py | 10 +- tests/test_geometry/test_exclusion.py | 80 +++++- tests/test_geometry/test_intersection.py | 80 +++++- tests/test_geometry/test_simplex.py | 72 +++--- tests/test_geometry/test_union.py | 88 +++++-- tests/test_label_tensor.py | 1 + tests/test_layers/test_conv.py | 79 +++--- tests/test_layers/test_fourier.py | 35 +-- tests/test_layers/test_residual.py | 69 +++++- tests/test_layers/test_spectral_conv.py | 11 +- tests/test_loss/test_lploss.py | 21 +- tests/test_loss/test_powerloss.py | 21 +- tests/test_model/test_deeponet.py | 33 +-- tests/test_model/test_fnn.py | 14 +- tests/test_model/test_fno.py | 57 +++-- tests/test_model/test_mionet.py | 43 +--- tests/test_model/test_residualfnn.py | 12 +- tests/test_operators.py | 21 +- tests/test_problem.py | 71 ++++-- tests/test_solvers/test_garom.py | 107 +++++---- tests/test_solvers/test_pinn.py | 83 ++++--- tests/test_utils.py | 10 +- 144 files changed, 2741 insertions(+), 1766 deletions(-) delete mode 100644 docs/.nojekyll delete mode 100644 docs/index.html create mode 100644 docs/source/_cite.rst create mode 100644 docs/source/_rst/_tutorial.rst delete mode 100644 docs/source/_rst/_tutorials.rst create mode 100644 docs/source/_rst/callbacks/adaptive_refinment_callbacks.rst create mode 100644 docs/source/_rst/callbacks/optimizer_callbacks.rst create mode 100644 docs/source/_rst/callbacks/processing_callbacks.rst create mode 100644 docs/source/_rst/equations.rst create mode 100644 docs/source/_rst/geometry/difference_domain.rst create mode 100644 docs/source/_rst/geometry/exclusion_domain.rst create mode 100644 docs/source/_rst/geometry/intersection_domain.rst create mode 100644 docs/source/_rst/geometry/operation_interface.rst create mode 100644 docs/source/_rst/geometry/union_domain.rst create mode 100644 docs/source/_rst/layers/enhanced_linear.rst create mode 100644 docs/source/_rst/layers/fourier.rst create mode 100644 docs/source/_rst/layers/residual.rst create mode 100644 docs/source/_rst/layers/spectral.rst create mode 100644 docs/source/_rst/models/mionet.rst rename docs/source/_rst/{equations_operators => }/operators.rst (56%) create mode 100644 docs/source/_rst/solvers/garom.rst create mode 100644 docs/source/_rst/solvers/supervised.rst create mode 100644 docs/source/_rst/trainer.rst create mode 100644 docs/source/_team.rst create mode 100644 docs/source/index_files/foudings.png create mode 100644 docs/source/index_files/university_dev_pina.png create mode 100644 docs/sphinx_extensions/paramref_extension.py diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index ebe8f9c..0000000 --- a/docs/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/docs/source/_cite.rst b/docs/source/_cite.rst new file mode 100644 index 0000000..71d5379 --- /dev/null +++ b/docs/source/_cite.rst @@ -0,0 +1,21 @@ +Cite PINA +============== + +If PINA has been significant in your research, and you would like to acknowledge the project in your academic publication, +we suggest citing the following paper: + +*Coscia, D., Ivagnes, A., Demo, N., & Rozza, G. (2023). Physics-Informed Neural networks for Advanced modeling. Journal of Open Source Software, 8(87), 5352.* + +Or in BibTex format + +.. code:: bash + + @article{coscia2023physics, + title={Physics-Informed Neural networks for Advanced modeling}, + author={Coscia, Dario and Ivagnes, Anna and Demo, Nicola and Rozza, Gianluigi}, + journal={Journal of Open Source Software}, + volume={8}, + number={87}, + pages={5352}, + year={2023} + } \ No newline at end of file diff --git a/docs/source/_rst/_code.rst b/docs/source/_rst/_code.rst index 33d8a08..bdbe70c 100644 --- a/docs/source/_rst/_code.rst +++ b/docs/source/_rst/_code.rst @@ -1,18 +1,85 @@ Code Documentation ================== Welcome to PINA documentation! Here you can find the modules of the package divided in different sections. +The high-level structure of the package is depicted in our API. + +.. figure:: ../index_files/API_color.png + :alt: PINA application program interface + :align: center + :width: 400 + + +The pipeline to solve differential equations with PINA follows just five steps: + + 1. Define the `Problem`_ the user aim to solve + 2. Generate data using built in `Geometries`_, or load high level simulation results as :doc:`LabelTensor ` + 3. Choose or build one or more `Models`_ to solve the problem + 4. Choose a solver across PINA available `Solvers`_, or build one using the :doc:`SolverInterface ` + 5. Train the model with the PINA :doc:`Trainer `, enhance the train with `Callbacks_` PINA Features -------- +-------------- .. toctree:: :titlesonly: LabelTensor Condition + Trainer Plotter + +Solvers +-------------- + +.. toctree:: + :titlesonly: + + SolverInterface + PINN + Supervised solver + GAROM + + +Models +------------ + +.. toctree:: + :titlesonly: + :maxdepth: 5 + + Network + FeedForward + MultiFeedForward + ResidualFeedForward + DeepONet + MIONet + FNO + +Layers +------------- + +.. toctree:: + :titlesonly: + + Residual layer + EnhancedLinear layer + Spectral convolution + Fourier layers + Continuous convolution + + +Equations and Operators +------------------------- + +.. toctree:: + :titlesonly: + + Equations + Differential Operators + + Problem -------- +-------------- .. toctree:: :titlesonly: @@ -22,40 +89,8 @@ Problem TimeDependentProblem ParametricProblem -Solvers -------- - -.. toctree:: - :titlesonly: - - SolverInterface - PINN - - -Models ------ - -.. toctree:: - :titlesonly: - - Network - FeedForward - MultiFeedForward - ResidualFeedForward - DeepONet - FNO - -Layers ------- - -.. toctree:: - :titlesonly: - - ContinuousConv - - Geometries ----------- +----------------- .. toctree:: :titlesonly: @@ -65,9 +100,30 @@ Geometries EllipsoidDomain SimplexDomain +Geometry set operations +------------------------ -Loss ------- +.. toctree:: + :titlesonly: + + OperationInterface + Union + Intersection + Difference + Exclusion + +Callbacks +-------------------- + +.. toctree:: + :titlesonly: + + Metric tracking + Optimizer callbacks + Adaptive Refinments + +Metrics and Losses +-------------------- .. toctree:: :titlesonly: diff --git a/docs/source/_rst/_tutorial.rst b/docs/source/_rst/_tutorial.rst new file mode 100644 index 0000000..f904f83 --- /dev/null +++ b/docs/source/_rst/_tutorial.rst @@ -0,0 +1,39 @@ +PINA Tutorials +============== + +In this folder we collect useful tutorials in order to understand the principles and the potential of **PINA**. + +Getting started with PINA +------------------------- +.. toctree:: + :maxdepth: 3 + :titlesonly: + + Introduction to PINA for Physics Informed Neural Networks training + Building custom geometries with PINA Location class + +Physics Informed Neural Networks +-------------------------------- +.. toctree:: + :maxdepth: 3 + :titlesonly: + + Two dimensional Poisson problem using Extra Features Learning + Two dimensional Wave problem with hard constraint + + +Neural Operator Learning +------------------------ +.. toctree:: + :maxdepth: 3 + :titlesonly: + + Two dimensional Darcy flow using the Fourier Neural Operator + +Supervised Learning +------------------- +.. toctree:: + :maxdepth: 3 + :titlesonly: + + Unstructured convolutional autoencoder via continuous convolution \ No newline at end of file diff --git a/docs/source/_rst/_tutorials.rst b/docs/source/_rst/_tutorials.rst deleted file mode 100644 index de5b475..0000000 --- a/docs/source/_rst/_tutorials.rst +++ /dev/null @@ -1,27 +0,0 @@ - -PINA Tutorials -============== - -In this folder we collect useful tutorials in order to understand the principles and the potential of **PINA**. - -.. toctree:: - :maxdepth: 3 - :hidden: - -Getting started with PINA -------------------------- - * :doc:`Introduction to PINA for Physics Informed Neural Networks training` - * :doc:`Building custom geometries with PINA Location class` - -Physics Informed Neural Networks --------------------------------- - * :doc:`Two dimensional Poisson problem using Extra Features Learning` - * :doc:`Two dimensional Wave problem with hard constraint` - -Neural Operator Learning ------------------------- - * :doc:`Two dimensional Darcy flow using the Fourier Neural Operator` - -Supervised Learning -------------------- - * :doc:`Unstructured convolutional autoencoder via continuous convolution` diff --git a/docs/source/_rst/callbacks/adaptive_refinment_callbacks.rst b/docs/source/_rst/callbacks/adaptive_refinment_callbacks.rst new file mode 100644 index 0000000..11b313e --- /dev/null +++ b/docs/source/_rst/callbacks/adaptive_refinment_callbacks.rst @@ -0,0 +1,7 @@ +Adaptive Refinments callbacks +=============================== + +.. currentmodule:: pina.callbacks.adaptive_refinment_callbacks +.. autoclass:: R3Refinement + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/callbacks/optimizer_callbacks.rst b/docs/source/_rst/callbacks/optimizer_callbacks.rst new file mode 100644 index 0000000..7ee418f --- /dev/null +++ b/docs/source/_rst/callbacks/optimizer_callbacks.rst @@ -0,0 +1,7 @@ +Optimizer callbacks +===================== + +.. currentmodule:: pina.callbacks.optimizer_callbacks +.. autoclass:: SwitchOptimizer + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/callbacks/processing_callbacks.rst b/docs/source/_rst/callbacks/processing_callbacks.rst new file mode 100644 index 0000000..e024a49 --- /dev/null +++ b/docs/source/_rst/callbacks/processing_callbacks.rst @@ -0,0 +1,7 @@ +Processing callbacks +======================= + +.. currentmodule:: pina.callbacks.processing_callbacks +.. autoclass:: MetricTracker + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/condition.rst b/docs/source/_rst/condition.rst index 8a554d1..088b966 100644 --- a/docs/source/_rst/condition.rst +++ b/docs/source/_rst/condition.rst @@ -2,9 +2,6 @@ Condition ========= .. currentmodule:: pina.condition -.. automodule:: pina.condition - .. autoclass:: Condition :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/equations.rst b/docs/source/_rst/equations.rst new file mode 100644 index 0000000..6826dde --- /dev/null +++ b/docs/source/_rst/equations.rst @@ -0,0 +1,42 @@ +Equations +========== +Equations are used in PINA to make easy the training. During problem definition +each `equation` passed to a `Condition` object must be an `Equation` or `SystemEquation`. +An `Equation` is simply a wrapper over callable python functions, while `SystemEquation` is +a wrapper arounf a list of callable python functions. We provide a wide rage of already implemented +equations to ease the code writing, such as `FixedValue`, `Laplace`, and many more. + + +.. currentmodule:: pina.equation.equation_interface +.. autoclass:: EquationInterface + :members: + :show-inheritance: + +.. currentmodule:: pina.equation.equation +.. autoclass:: Equation + :members: + :show-inheritance: + + +.. currentmodule:: pina.equation.system_equation +.. autoclass:: SystemEquation + :members: + :show-inheritance: + + +.. currentmodule:: pina.equation.equation_factory +.. autoclass:: FixedValue + :members: + :show-inheritance: + +.. autoclass:: FixedGradient + :members: + :show-inheritance: + +.. autoclass:: FixedFlux + :members: + :show-inheritance: + +.. autoclass:: Laplace + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/geometry/cartesian.rst b/docs/source/_rst/geometry/cartesian.rst index 8e97197..b57c02b 100644 --- a/docs/source/_rst/geometry/cartesian.rst +++ b/docs/source/_rst/geometry/cartesian.rst @@ -1,5 +1,5 @@ CartesianDomain -=========== +====================== .. currentmodule:: pina.geometry.cartesian .. automodule:: pina.geometry.cartesian diff --git a/docs/source/_rst/geometry/difference_domain.rst b/docs/source/_rst/geometry/difference_domain.rst new file mode 100644 index 0000000..fc0b293 --- /dev/null +++ b/docs/source/_rst/geometry/difference_domain.rst @@ -0,0 +1,9 @@ +Difference +====================== +.. currentmodule:: pina.geometry.difference_domain + +.. automodule:: pina.geometry.difference_domain + +.. autoclass:: Difference + :members: + :show-inheritance: diff --git a/docs/source/_rst/geometry/ellipsoid.rst b/docs/source/_rst/geometry/ellipsoid.rst index 25d606c..09af427 100644 --- a/docs/source/_rst/geometry/ellipsoid.rst +++ b/docs/source/_rst/geometry/ellipsoid.rst @@ -1,5 +1,5 @@ EllipsoidDomain -=========== +====================== .. currentmodule:: pina.geometry.ellipsoid .. automodule:: pina.geometry.ellipsoid diff --git a/docs/source/_rst/geometry/exclusion_domain.rst b/docs/source/_rst/geometry/exclusion_domain.rst new file mode 100644 index 0000000..a07aafc --- /dev/null +++ b/docs/source/_rst/geometry/exclusion_domain.rst @@ -0,0 +1,9 @@ +Exclusion +====================== +.. currentmodule:: pina.geometry.exclusion_domain + +.. automodule:: pina.geometry.exclusion_domain + +.. autoclass:: Exclusion + :members: + :show-inheritance: diff --git a/docs/source/_rst/geometry/intersection_domain.rst b/docs/source/_rst/geometry/intersection_domain.rst new file mode 100644 index 0000000..a3c1356 --- /dev/null +++ b/docs/source/_rst/geometry/intersection_domain.rst @@ -0,0 +1,9 @@ +Intersection +====================== +.. currentmodule:: pina.geometry.intersection_domain + +.. automodule:: pina.geometry.intersection_domain + +.. autoclass:: Intersection + :members: + :show-inheritance: diff --git a/docs/source/_rst/geometry/location.rst b/docs/source/_rst/geometry/location.rst index 3603a24..5d680a1 100644 --- a/docs/source/_rst/geometry/location.rst +++ b/docs/source/_rst/geometry/location.rst @@ -1,10 +1,9 @@ Location -========= +==================== .. currentmodule:: pina.geometry.location .. automodule:: pina.geometry.location .. autoclass:: Location :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/geometry/operation_interface.rst b/docs/source/_rst/geometry/operation_interface.rst new file mode 100644 index 0000000..00a2d84 --- /dev/null +++ b/docs/source/_rst/geometry/operation_interface.rst @@ -0,0 +1,9 @@ +OperationInterface +====================== +.. currentmodule:: pina.geometry.operation_interface + +.. automodule:: pina.geometry.operation_interface + +.. autoclass:: OperationInterface + :members: + :show-inheritance: diff --git a/docs/source/_rst/geometry/simplex.rst b/docs/source/_rst/geometry/simplex.rst index f0b96a7..b5a83e4 100644 --- a/docs/source/_rst/geometry/simplex.rst +++ b/docs/source/_rst/geometry/simplex.rst @@ -1,5 +1,5 @@ SimplexDomain -=========== +====================== .. currentmodule:: pina.geometry.simplex .. automodule:: pina.geometry.simplex diff --git a/docs/source/_rst/geometry/union_domain.rst b/docs/source/_rst/geometry/union_domain.rst new file mode 100644 index 0000000..ad172d7 --- /dev/null +++ b/docs/source/_rst/geometry/union_domain.rst @@ -0,0 +1,9 @@ +Union +====================== +.. currentmodule:: pina.geometry.union_domain + +.. automodule:: pina.geometry.union_domain + +.. autoclass:: Union + :members: + :show-inheritance: diff --git a/docs/source/_rst/label_tensor.rst b/docs/source/_rst/label_tensor.rst index 07a665e..9eb2273 100644 --- a/docs/source/_rst/label_tensor.rst +++ b/docs/source/_rst/label_tensor.rst @@ -2,7 +2,6 @@ LabelTensor =========== .. currentmodule:: pina.label_tensor -.. automodule:: pina.label_tensor .. autoclass:: LabelTensor :members: diff --git a/docs/source/_rst/layers/convolution.rst b/docs/source/_rst/layers/convolution.rst index fb60aa1..3089fea 100644 --- a/docs/source/_rst/layers/convolution.rst +++ b/docs/source/_rst/layers/convolution.rst @@ -1,12 +1,8 @@ -ContinuousConvBlock -=================== +Continuous convolution +========================= .. currentmodule:: pina.model.layers.convolution_2d -.. automodule:: pina.model.layers.convolution_2d - .. autoclass:: ContinuousConvBlock :members: - :private-members: - :undoc-members: :show-inheritance: :noindex: diff --git a/docs/source/_rst/layers/enhanced_linear.rst b/docs/source/_rst/layers/enhanced_linear.rst new file mode 100644 index 0000000..ba30960 --- /dev/null +++ b/docs/source/_rst/layers/enhanced_linear.rst @@ -0,0 +1,8 @@ +EnhancedLinear +================= +.. currentmodule:: pina.model.layers.residual + +.. autoclass:: EnhancedLinear + :members: + :show-inheritance: + :noindex: \ No newline at end of file diff --git a/docs/source/_rst/layers/fourier.rst b/docs/source/_rst/layers/fourier.rst new file mode 100644 index 0000000..1321700 --- /dev/null +++ b/docs/source/_rst/layers/fourier.rst @@ -0,0 +1,16 @@ +Fourier Layers +=================== +.. currentmodule:: pina.model.layers.fourier + + +.. autoclass:: FourierBlock1D + :members: + :show-inheritance: + +.. autoclass:: FourierBlock2D + :members: + :show-inheritance: + +.. autoclass:: FourierBlock3D + :members: + :show-inheritance: diff --git a/docs/source/_rst/layers/residual.rst b/docs/source/_rst/layers/residual.rst new file mode 100644 index 0000000..1af11e5 --- /dev/null +++ b/docs/source/_rst/layers/residual.rst @@ -0,0 +1,7 @@ +Residual layer +=================== +.. currentmodule:: pina.model.layers.residual + +.. autoclass:: ResidualBlock + :members: + :show-inheritance: diff --git a/docs/source/_rst/layers/spectral.rst b/docs/source/_rst/layers/spectral.rst new file mode 100644 index 0000000..5635ba2 --- /dev/null +++ b/docs/source/_rst/layers/spectral.rst @@ -0,0 +1,15 @@ +Spectral Convolution +====================== +.. currentmodule:: pina.model.layers.spectral + +.. autoclass:: SpectralConvBlock1D + :members: + :show-inheritance: + +.. autoclass:: SpectralConvBlock2D + :members: + :show-inheritance: + +.. autoclass:: SpectralConvBlock3D + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/loss/loss_interface.rst b/docs/source/_rst/loss/loss_interface.rst index d449a91..6d4827d 100644 --- a/docs/source/_rst/loss/loss_interface.rst +++ b/docs/source/_rst/loss/loss_interface.rst @@ -1,10 +1,9 @@ LpLoss -==== +=============== .. currentmodule:: pina.loss .. automodule:: pina.loss .. autoclass:: LossInterface :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/loss/lploss.rst b/docs/source/_rst/loss/lploss.rst index b83a13b..f95d187 100644 --- a/docs/source/_rst/loss/lploss.rst +++ b/docs/source/_rst/loss/lploss.rst @@ -1,10 +1,10 @@ LpLoss -==== +=============== .. currentmodule:: pina.loss .. automodule:: pina.loss + :no-index: .. autoclass:: LpLoss :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/loss/powerloss.rst b/docs/source/_rst/loss/powerloss.rst index e8f5c49..0b1a7d9 100644 --- a/docs/source/_rst/loss/powerloss.rst +++ b/docs/source/_rst/loss/powerloss.rst @@ -1,10 +1,10 @@ PowerLoss -========= +==================== .. currentmodule:: pina.loss .. automodule:: pina.loss + :no-index: .. autoclass:: PowerLoss :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/deeponet.rst b/docs/source/_rst/models/deeponet.rst index 94bd6e9..0ca0824 100644 --- a/docs/source/_rst/models/deeponet.rst +++ b/docs/source/_rst/models/deeponet.rst @@ -2,9 +2,6 @@ DeepONet =========== .. currentmodule:: pina.model.deeponet -.. automodule:: pina.model.deeponet - .. autoclass:: DeepONet :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/fnn.rst b/docs/source/_rst/models/fnn.rst index 98bec0c..2dea8e5 100644 --- a/docs/source/_rst/models/fnn.rst +++ b/docs/source/_rst/models/fnn.rst @@ -1,10 +1,7 @@ FeedForward -=========== +====================== .. currentmodule:: pina.model.feed_forward -.. automodule:: pina.model.feed_forward - .. autoclass:: FeedForward :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/fnn_residual.rst b/docs/source/_rst/models/fnn_residual.rst index 6f3aeaf..66d83a4 100644 --- a/docs/source/_rst/models/fnn_residual.rst +++ b/docs/source/_rst/models/fnn_residual.rst @@ -1,10 +1,7 @@ ResidualFeedForward -=========== +====================== .. currentmodule:: pina.model.feed_forward -.. automodule:: pina.model.feed_forward - .. autoclass:: ResidualFeedForward :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/fno.rst b/docs/source/_rst/models/fno.rst index 73e0713..3d102b3 100644 --- a/docs/source/_rst/models/fno.rst +++ b/docs/source/_rst/models/fno.rst @@ -2,9 +2,6 @@ FNO =========== .. currentmodule:: pina.model.fno -.. automodule:: pina.model.fno - .. autoclass:: FNO :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/mionet.rst b/docs/source/_rst/models/mionet.rst new file mode 100644 index 0000000..fe62817 --- /dev/null +++ b/docs/source/_rst/models/mionet.rst @@ -0,0 +1,7 @@ +MIONet +=========== +.. currentmodule:: pina.model.deeponet + +.. autoclass:: MIONet + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/multifeedforward.rst b/docs/source/_rst/models/multifeedforward.rst index faa9c33..aa79580 100644 --- a/docs/source/_rst/models/multifeedforward.rst +++ b/docs/source/_rst/models/multifeedforward.rst @@ -1,10 +1,7 @@ MultiFeedForward -================ +================== .. currentmodule:: pina.model.multi_feed_forward -.. automodule:: pina.model.multi_feed_forward - .. autoclass:: MultiFeedForward :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/models/network.rst b/docs/source/_rst/models/network.rst index e81143a..4df9e19 100644 --- a/docs/source/_rst/models/network.rst +++ b/docs/source/_rst/models/network.rst @@ -1,10 +1,8 @@ Network ================ -.. currentmodule:: pina.model.network .. automodule:: pina.model.network .. autoclass:: Network :members: - :private-members: :show-inheritance: diff --git a/docs/source/_rst/equations_operators/operators.rst b/docs/source/_rst/operators.rst similarity index 56% rename from docs/source/_rst/equations_operators/operators.rst rename to docs/source/_rst/operators.rst index 458dcf8..59f7c7a 100644 --- a/docs/source/_rst/equations_operators/operators.rst +++ b/docs/source/_rst/operators.rst @@ -1,10 +1,8 @@ Operators =========== + .. currentmodule:: pina.operators .. automodule:: pina.operators :members: - :private-members: - :undoc-members: - :show-inheritance: - :noindex: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/problem/abstractproblem.rst b/docs/source/_rst/problem/abstractproblem.rst index 770533e..143909e 100644 --- a/docs/source/_rst/problem/abstractproblem.rst +++ b/docs/source/_rst/problem/abstractproblem.rst @@ -6,6 +6,4 @@ AbstractProblem .. autoclass:: AbstractProblem :members: - :private-members: - :undoc-members: :show-inheritance: diff --git a/docs/source/_rst/problem/parametricproblem.rst b/docs/source/_rst/problem/parametricproblem.rst index 84eac3f..8f217fb 100644 --- a/docs/source/_rst/problem/parametricproblem.rst +++ b/docs/source/_rst/problem/parametricproblem.rst @@ -1,10 +1,9 @@ ParametricProblem -================= +==================== .. currentmodule:: pina.problem.parametric_problem .. automodule:: pina.problem.parametric_problem .. autoclass:: ParametricProblem :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/problem/spatialproblem.rst b/docs/source/_rst/problem/spatialproblem.rst index 74c1fba..90ec6ec 100644 --- a/docs/source/_rst/problem/spatialproblem.rst +++ b/docs/source/_rst/problem/spatialproblem.rst @@ -6,6 +6,4 @@ SpatialProblem .. autoclass:: SpatialProblem :members: - :private-members: - :undoc-members: :show-inheritance: diff --git a/docs/source/_rst/problem/timedepproblem.rst b/docs/source/_rst/problem/timedepproblem.rst index 2f81119..93b8cb5 100644 --- a/docs/source/_rst/problem/timedepproblem.rst +++ b/docs/source/_rst/problem/timedepproblem.rst @@ -6,6 +6,4 @@ TimeDependentProblem .. autoclass:: TimeDependentProblem :members: - :private-members: - :undoc-members: :show-inheritance: diff --git a/docs/source/_rst/solvers/garom.rst b/docs/source/_rst/solvers/garom.rst new file mode 100644 index 0000000..5fcd97f --- /dev/null +++ b/docs/source/_rst/solvers/garom.rst @@ -0,0 +1,7 @@ +GAROM +====== +.. currentmodule:: pina.solvers.garom + +.. autoclass:: GAROM + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/solvers/pinn.rst b/docs/source/_rst/solvers/pinn.rst index 602b827..3e9b2ef 100644 --- a/docs/source/_rst/solvers/pinn.rst +++ b/docs/source/_rst/solvers/pinn.rst @@ -1,10 +1,7 @@ PINN -==== +====== .. currentmodule:: pina.solvers.pinn -.. automodule:: pina.solvers.pinn - .. autoclass:: PINN :members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/solvers/solver_interface.rst b/docs/source/_rst/solvers/solver_interface.rst index 05e3b98..363e1db 100644 --- a/docs/source/_rst/solvers/solver_interface.rst +++ b/docs/source/_rst/solvers/solver_interface.rst @@ -1,10 +1,7 @@ SolverInterface -=========== +================= .. currentmodule:: pina.solvers.solver -.. automodule:: pina.solvers.solver - .. autoclass:: SolverInterface - :members: :show-inheritance: - :noindex: + :members: diff --git a/docs/source/_rst/solvers/supervised.rst b/docs/source/_rst/solvers/supervised.rst new file mode 100644 index 0000000..895759e --- /dev/null +++ b/docs/source/_rst/solvers/supervised.rst @@ -0,0 +1,7 @@ +SupervisedSolver +=================== +.. currentmodule:: pina.solvers.supervised + +.. autoclass:: SupervisedSolver + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/trainer.rst b/docs/source/_rst/trainer.rst new file mode 100644 index 0000000..2582b6d --- /dev/null +++ b/docs/source/_rst/trainer.rst @@ -0,0 +1,8 @@ +Trainer +=========== + +.. automodule:: pina.trainer + +.. autoclass:: Trainer + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/_rst/tutorials/tutorial1/tutorial.rst b/docs/source/_rst/tutorials/tutorial1/tutorial.rst index f78b2d7..c76b5c1 100644 --- a/docs/source/_rst/tutorials/tutorial1/tutorial.rst +++ b/docs/source/_rst/tutorials/tutorial1/tutorial.rst @@ -28,8 +28,8 @@ Build a PINA problem Problem definition in the **PINA** framework is done by building a python ``class``, which inherits from one or more problem classes (``SpatialProblem``, ``TimeDependentProblem``, ``ParametricProblem``, …) -depending on the nature of the problem. Below is an example: ### Simple -Ordinary Differential Equation Consider the following: +depending on the nature of the problem. Below is an example. Consider the following +simple Ordinary Differential Equation: .. math:: diff --git a/docs/source/_rst/tutorials/tutorial2/tutorial.rst b/docs/source/_rst/tutorials/tutorial2/tutorial.rst index 80d2d03..8a59771 100644 --- a/docs/source/_rst/tutorials/tutorial2/tutorial.rst +++ b/docs/source/_rst/tutorials/tutorial2/tutorial.rst @@ -31,12 +31,16 @@ The problem definition ---------------------- The two-dimensional Poisson problem is mathematically written as: -:raw-latex:`\begin{equation} -\begin{cases} -\Delta u = \sin{(\pi x)} \sin{(\pi y)} \text{ in } D, \\ -u = 0 \text{ on } \Gamma_1 \cup \Gamma_2 \cup \Gamma_3 \cup \Gamma_4, -\end{cases} -\end{equation}` where :math:`D` is a square domain :math:`[0,1]^2`, and + +.. math:: + \begin{equation} + \begin{cases} + \Delta u = \sin{(\pi x)} \sin{(\pi y)} \text{ in } D, \\ + u = 0 \text{ on } \Gamma_1 \cup \Gamma_2 \cup \Gamma_3 \cup \Gamma_4, + \end{cases} + \end{equation} + +where :math:`D` is a square domain :math:`[0,1]^2`, and :math:`\Gamma_i`, with :math:`i=1,...,4`, are the boundaries of the square. @@ -158,9 +162,10 @@ is now defined, with an additional input variable, named extra-feature, which coincides with the forcing term in the Laplace equation. The set of input variables to the neural network is: -:raw-latex:`\begin{equation} -[x, y, k(x, y)], \text{ with } k(x, y)=\sin{(\pi x)}\sin{(\pi y)}, -\end{equation}` +.. math:: + \begin{equation} + [x, y, k(x, y)], \text{ with } k(x, y)=\sin{(\pi x)}\sin{(\pi y)}, + \end{equation} where :math:`x` and :math:`y` are the spatial coordinates and :math:`k(x, y)` is the added feature. @@ -249,9 +254,10 @@ Another way to exploit the extra features is the addition of learnable parameter inside them. In this way, the added parameters are learned during the training phase of the neural network. In this case, we use: -:raw-latex:`\begin{equation} -k(x, \mathbf{y}) = \beta \sin{(\alpha x)} \sin{(\alpha y)}, -\end{equation}` +.. math:: + \begin{equation} + k(x, \mathbf{y}) = \beta \sin{(\alpha x)} \sin{(\alpha y)}, + \end{equation} where :math:`\alpha` and :math:`\beta` are the abovementioned parameters. Their implementation is quite trivial: by using the class diff --git a/docs/source/_rst/tutorials/tutorial3/tutorial.rst b/docs/source/_rst/tutorials/tutorial3/tutorial.rst index 2b16113..23288b9 100644 --- a/docs/source/_rst/tutorials/tutorial3/tutorial.rst +++ b/docs/source/_rst/tutorials/tutorial3/tutorial.rst @@ -25,13 +25,14 @@ The problem definition The problem is written in the following form: -:raw-latex:`\begin{equation} -\begin{cases} -\Delta u(x,y,t) = \frac{\partial^2}{\partial t^2} u(x,y,t) \quad \text{in } D, \\\\ -u(x, y, t=0) = \sin(\pi x)\sin(\pi y), \\\\ -u(x, y, t) = 0 \quad \text{on } \Gamma_1 \cup \Gamma_2 \cup \Gamma_3 \cup \Gamma_4, -\end{cases} -\end{equation}` +.. math:: + \begin{equation} + \begin{cases} + \Delta u(x,y,t) = \frac{\partial^2}{\partial t^2} u(x,y,t) \quad \text{in } D, \\\\ + u(x, y, t=0) = \sin(\pi x)\sin(\pi y), \\\\ + u(x, y, t) = 0 \quad \text{on } \Gamma_1 \cup \Gamma_2 \cup \Gamma_3 \cup \Gamma_4, + \end{cases} + \end{equation} where :math:`D` is a square domain :math:`[0,1]^2`, and :math:`\Gamma_i`, with :math:`i=1,...,4`, are the boundaries of the diff --git a/docs/source/_rst/tutorials/tutorial4/tutorial.rst b/docs/source/_rst/tutorials/tutorial4/tutorial.rst index d6cca05..f93c2fe 100644 --- a/docs/source/_rst/tutorials/tutorial4/tutorial.rst +++ b/docs/source/_rst/tutorials/tutorial4/tutorial.rst @@ -21,16 +21,15 @@ First of all we import the modules needed for the tutorial: import torchvision # for MNIST dataset from pina.model import FeedForward # for building AE and MNIST classification -The tutorial is structured as follow: \* `Continuous filter -background <#continuous-filter-background>`__: understand how the -convolutional filter works and how to use it. \* `Building a MNIST -Classifier <#building-a-mnist-classifier>`__: show how to build a simple -classifier using the MNIST dataset and how to combine a continuous -convolutional layer with a feedforward neural network. \* `Building a -Continuous Convolutional -Autoencoder <#building-a-continuous-convolutional-autoencoder>`__: show -how to use the continuous filter to work with unstructured data for -autoencoding and up-sampling. +The tutorial is structured as follow: + +* `Continuous filter background <#continuous-filter-background>`__: understand how the convolutional filter works and how to use it. +* `Building a MNIST Classifier <#building-a-mnist-classifier>`__: show how to build a simple + classifier using the MNIST dataset and how to combine a continuous + convolutional layer with a feedforward neural network. +* `Building a Continuous Convolutional Autoencoder <#building-a-continuous-convolutional-autoencoder>`__: show + show to use the continuous filter to work with unstructured data for + autoencoding and up-sampling. Continuous filter background ---------------------------- @@ -153,13 +152,16 @@ where to go. Here is an example for the :math:`[0,1]\times[0,5]` domain: "direction": [1, 1], } -This tells the filter: 1. ``domain``: square domain (the only -implemented) :math:`[0,1]\times[0,5]`. The minimum value is always zero, -while the maximum is specified by the user 2. ``start``: start position -of the filter, coordinate :math:`(0, 0)` 3. ``jump``: the jumps of the -centroid of the filter to the next position :math:`(0.1, 0.3)` 4. -``direction``: the directions of the jump, with ``1 = right``, -``0 = no jump``,\ ``-1 = left`` with respect to the current position +This tells the filter: + +1. ``domain``: square domain (the only implemented) :math:`[0,1]\times[0,5]`. The minimum value is always zero, + while the maximum is specified by the user +2. ``start``: start position + of the filter, coordinate :math:`(0, 0)` +3. ``jump``: the jumps of the + centroid of the filter to the next position :math:`(0.1, 0.3)` +4. ``direction``: the directions of the jump, with ``1 = right``, + ``0 = no jump``,\ ``-1 = left`` with respect to the current position **Note** @@ -170,9 +172,7 @@ Filter definition ~~~~~~~~~~~~~~~~~ Having defined all the previous blocks we are able to construct the -continuous filter. - -Suppose we would like to get an ouput with only one field, and let us +continuous filter. Suppose we would like to get an ouput with only one field, and let us fix the filter dimension to be :math:`[0.1, 0.1]`. .. code:: ipython3 @@ -192,13 +192,7 @@ fix the filter dimension to be :math:`[0.1, 0.1]`. output_numb_field=1, filter_dim=filter_dim, stride=stride) - - -.. parsed-literal:: - - /u/d/dcoscia/.local/lib/python3.9/site-packages/torch/functional.py:504: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:3483.) - return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined] - + That’s it! In just one line of code we have created the continuous convolutional filter. By default the ``pina.model.FeedForward`` neural diff --git a/docs/source/_team.rst b/docs/source/_team.rst new file mode 100644 index 0000000..1fa4212 --- /dev/null +++ b/docs/source/_team.rst @@ -0,0 +1,24 @@ +PINA Team +============== + +PINA is currently developed by `Dario Coscia `_, `Nicola Demo `_, and `Anna Ivagnes `_ +under the supervision of `Prof. Gianluigi Rozza `_ in the `SISSA MathLab `_ group. + +A significant part of PINA has been written either as a by-product for other projects people were funded for, or by people on university-funded positions. +There are probably many of such projects that have led to some development of PINA. We are very grateful for this support! +In particular, we acknowledge the following sources of support with great gratitude: + +* `H2020 ERC CoG 2015 AROMA-CFD project 681447 `_, P.I. Professor `Prof. Gianluigi Rozza `_ at `SISSA MathLab `_. +* `Next Generation EU `_ for ambiental and digital transitionfor, Italy. + +.. figure:: index_files/foudings.png + :align: center + :width: 400 + +We also acknowledge the contribuition of `Maria Strazzullo `_ in the early developments of the package. A special +thank goeas to all the students and researchers from different universities which contributed to the package. Finally we warmly thank all the +`contributors `_! + +.. figure:: index_files/university_dev_pina.png + :align: center + :width: 500 diff --git a/docs/source/conf.py b/docs/source/conf.py index 22df97e..7efb647 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,6 +22,8 @@ import sphinx_rtd_theme sys.path.insert(0, os.path.abspath('../..')) import pina +sys.path.insert(0, os.path.abspath('../sphinx_extensions')) # extension to remove paramref link from lightinig + # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -36,29 +38,45 @@ import pina # ones. extensions = [ 'sphinx.ext.autodoc', - #'sphinx.ext.autosummary', - #'sphinx.ext.coverage', - #'sphinx.ext.graphviz', - #'sphinx.ext.doctest', + 'sphinx.ext.autosummary', + 'sphinx.ext.doctest', + 'sphinx.ext.napoleon', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', - #'sphinx.ext.coverage', + 'sphinx.ext.coverage', 'sphinx.ext.viewcode', - #'sphinx.ext.ifconfig', 'sphinx.ext.mathjax', - 'sphinx.ext.autosectionlabel', + 'sphinx.ext.intersphinx', + 'paramref_extension', # this extension is made to remove paramref links from lightining doc + 'sphinx_copybutton', ] -#autosummary_generate = True intersphinx_mapping = { 'python': ('http://docs.python.org/3', None), - 'numpy': ('http://docs.scipy.org/doc/numpy/', None), - 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), + # 'numpy': ('http://docs.scipy.org/doc/numpy/', None), + # 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), 'matplotlib': ('http://matplotlib.sourceforge.net/', None), - 'torch': ('https://pytorch.org/docs/stable/', None), -} + 'torch': ('https://pytorch.org/docs/stable/', None), + 'pytorch_lightning': ("https://lightning.ai/docs/pytorch/stable/", None), + } nitpicky = True +nitpick_ignore = [ + ('py:meth', 'pytorch_lightning.core.module.LightningModule.log'), + ('py:meth', 'pytorch_lightning.core.module.LightningModule.log_dict'), + ('py:exc', 'MisconfigurationException'), + ('py:func', 'torch.inference_mode'), + ('py:func', 'torch.no_grad'), + ('py:class', 'torch.utils.data.DistributedSampler'), + ('py:class', 'CartesianDomain'), # TO FIX + ('py:class', 'pina.model.layers.convolution.BaseContinuousConv'), + ('py:class', 'Module'), + ('py:class', 'torch.nn.modules.loss._Loss'), # TO FIX + ('py:class', 'torch.optim.LRScheduler'), # TO FIX + + ] + + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -95,7 +113,7 @@ release = version # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -125,11 +143,7 @@ add_module_names = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -keep_warnings = False +# A list of ignored prefixes for module index sortins as "systems = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -167,7 +181,13 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # The name of an image file (relative to this directory) to place at the top # of the sidebar. -# html_logo = None +html_logo = "index_files/pina_logo.png" +html_theme_options = { + 'logo_only': True, + 'display_version': True, + 'prev_next_buttons_location': 'bottom', + +} # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -182,7 +202,7 @@ html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -html_extra_path = ['_tutorials'] +# html_extra_path = ['_tutorial'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -322,3 +342,4 @@ texinfo_documents = [ # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False +autodoc_member_order = 'bysource' \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index cac1ae5..8a242c5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,13 +1,6 @@ Welcome to PINA's documentation! =================================================== -.. figure:: index_files/pina_logo.png - :align: center - :width: 150 - -| - - Physics Informed Neural network for Advanced modeling (**PINA**) is an open-source Python library providing an intuitive interface for solving differential equations using PINNs, NOs or both together. @@ -29,7 +22,7 @@ with PINA follows just five steps: problem definition, model selection, data gen .. figure:: index_files/API_color.png :alt: PINA application program interface :align: center - :width: 500 + :width: 600 | @@ -54,12 +47,10 @@ terms), without the need of re-training. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Package Documentation: - + API <_rst/_code> - Contributing <_rst/_contributing> - License <_LICENSE.rst> .. the following is demo content intended to showcase some of the features you can invoke in reStructuredText .. this can be safely deleted or commented out @@ -67,8 +58,16 @@ terms), without the need of re-training. .. toctree:: :maxdepth: 1 - :numbered: :caption: Getting Started: Installation <_rst/_installation> - Tutorials <_rst/_tutorials> + Tutorials <_rst/_tutorial> + +.. toctree:: + :maxdepth: 1 + :caption: Community: + + Team & Foundings <_team.rst> + Contributing <_rst/_contributing> + License <_LICENSE.rst> + Cite PINA <_cite.rst> \ No newline at end of file diff --git a/docs/source/index_files/API_color.png b/docs/source/index_files/API_color.png index 97b25e7cc6368842df92000d3d318f1cb6d506cf..9e61695c6f250ceae68030d64630589e97491edd 100644 GIT binary patch literal 161741 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�ii>U7VLehZuT_poH!y0RAUg6n#K(IKa^iYK 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 DhNa20 literal 124005 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 Bh;#q| diff --git a/docs/source/index_files/foudings.png b/docs/source/index_files/foudings.png new file mode 100644 index 0000000000000000000000000000000000000000..65b9237fb2311017b4c575fbc53a0cd900e91621 GIT binary patch literal 79867 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%0A>PQu1 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 x = torch.randn(256) >>> x = a1(x) ''' - def __init__(self, alpha = None): + + def __init__(self, alpha=None): ''' Initialization. INPUT: @@ -31,16 +33,18 @@ class AdaptiveCos(torch.nn.Module): # initialize alpha if alpha == None: - self.alpha = Parameter(torch.tensor(1.0)) # create a tensor out of alpha + self.alpha = Parameter( + torch.tensor(1.0)) # create a tensor out of alpha else: - self.alpha = Parameter(torch.tensor(alpha)) # create a tensor out of alpha - self.alpha.requiresGrad = True # set requiresGrad to true! + self.alpha = Parameter( + torch.tensor(alpha)) # create a tensor out of alpha + self.alpha.requiresGrad = True # set requiresGrad to true! self.scale = Parameter(torch.tensor(1.0)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! self.translate = Parameter(torch.tensor(0.0)) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' diff --git a/pina/adaptive_functions/adaptive_exp.py b/pina/adaptive_functions/adaptive_exp.py index d9b1732..c65406f 100644 --- a/pina/adaptive_functions/adaptive_exp.py +++ b/pina/adaptive_functions/adaptive_exp.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveExp(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -18,6 +19,7 @@ class AdaptiveExp(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' + def __init__(self): ''' Initialization. @@ -28,14 +30,20 @@ class AdaptiveExp(torch.nn.Module): ''' super(AdaptiveExp, self).__init__() - self.scale = Parameter(torch.normal(torch.tensor(1.0), torch.tensor(0.1))) # create a tensor out of alpha - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale = Parameter( + torch.normal(torch.tensor(1.0), + torch.tensor(0.1))) # create a tensor out of alpha + self.scale.requiresGrad = True # set requiresGrad to true! - self.alpha = Parameter(torch.normal(torch.tensor(1.0), torch.tensor(0.1))) # create a tensor out of alpha - self.alpha.requiresGrad = True # set requiresGrad to true! + self.alpha = Parameter( + torch.normal(torch.tensor(1.0), + torch.tensor(0.1))) # create a tensor out of alpha + self.alpha.requiresGrad = True # set requiresGrad to true! - self.translate = Parameter(torch.normal(torch.tensor(0.0), torch.tensor(0.1))) # create a tensor out of alpha - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate = Parameter( + torch.normal(torch.tensor(0.0), + torch.tensor(0.1))) # create a tensor out of alpha + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' diff --git a/pina/adaptive_functions/adaptive_linear.py b/pina/adaptive_functions/adaptive_linear.py index f4b72e9..42968c9 100644 --- a/pina/adaptive_functions/adaptive_linear.py +++ b/pina/adaptive_functions/adaptive_linear.py @@ -2,6 +2,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveLinear(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -19,6 +20,7 @@ class AdaptiveLinear(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' + def __init__(self): ''' Initialization. @@ -30,10 +32,10 @@ class AdaptiveLinear(torch.nn.Module): super(AdaptiveLinear, self).__init__() self.scale = Parameter(torch.tensor(1.0)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! self.translate = Parameter(torch.tensor(0.0)) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' diff --git a/pina/adaptive_functions/adaptive_relu.py b/pina/adaptive_functions/adaptive_relu.py index 14cf133..0061462 100644 --- a/pina/adaptive_functions/adaptive_relu.py +++ b/pina/adaptive_functions/adaptive_relu.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveReLU(torch.nn.Module, Parameter): ''' Implementation of soft exponential activation. @@ -18,6 +19,7 @@ class AdaptiveReLU(torch.nn.Module, Parameter): >>> x = torch.randn(256) >>> x = a1(x) ''' + def __init__(self): ''' Initialization. @@ -29,10 +31,10 @@ class AdaptiveReLU(torch.nn.Module, Parameter): super(AdaptiveReLU, self).__init__() self.scale = Parameter(torch.rand(1)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! self.translate = Parameter(torch.rand(1)) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' @@ -40,4 +42,4 @@ class AdaptiveReLU(torch.nn.Module, Parameter): Applies the function to the input elementwise. ''' #x += self.translate - return torch.relu(x+self.translate)*self.scale + return torch.relu(x + self.translate) * self.scale diff --git a/pina/adaptive_functions/adaptive_sin.py b/pina/adaptive_functions/adaptive_sin.py index 80793c2..26a6ef3 100644 --- a/pina/adaptive_functions/adaptive_sin.py +++ b/pina/adaptive_functions/adaptive_sin.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveSin(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -18,7 +19,8 @@ class AdaptiveSin(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' - def __init__(self, alpha = None): + + def __init__(self, alpha=None): ''' Initialization. INPUT: @@ -29,14 +31,18 @@ class AdaptiveSin(torch.nn.Module): super(AdaptiveSin, self).__init__() # initialize alpha - self.alpha = Parameter(torch.normal(torch.tensor(1.0), torch.tensor(0.1))) # create a tensor out of alpha - self.alpha.requiresGrad = True # set requiresGrad to true! + self.alpha = Parameter( + torch.normal(torch.tensor(1.0), + torch.tensor(0.1))) # create a tensor out of alpha + self.alpha.requiresGrad = True # set requiresGrad to true! - self.scale = Parameter(torch.normal(torch.tensor(1.0), torch.tensor(0.1))) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale = Parameter( + torch.normal(torch.tensor(1.0), torch.tensor(0.1))) + self.scale.requiresGrad = True # set requiresGrad to true! - self.translate = Parameter(torch.normal(torch.tensor(0.0), torch.tensor(0.1))) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate = Parameter( + torch.normal(torch.tensor(0.0), torch.tensor(0.1))) + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' diff --git a/pina/adaptive_functions/adaptive_softplus.py b/pina/adaptive_functions/adaptive_softplus.py index c2069ff..d306832 100644 --- a/pina/adaptive_functions/adaptive_softplus.py +++ b/pina/adaptive_functions/adaptive_softplus.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveSoftplus(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -18,6 +19,7 @@ class AdaptiveSoftplus(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' + def __init__(self): ''' Initialization. @@ -31,7 +33,7 @@ class AdaptiveSoftplus(torch.nn.Module): self.soft = torch.nn.Softplus() self.scale = Parameter(torch.rand(1)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' @@ -39,4 +41,4 @@ class AdaptiveSoftplus(torch.nn.Module): Applies the function to the input elementwise. ''' #x += self.translate - return self.soft(x)*self.scale + return self.soft(x) * self.scale diff --git a/pina/adaptive_functions/adaptive_square.py b/pina/adaptive_functions/adaptive_square.py index 911673a..9b341a0 100644 --- a/pina/adaptive_functions/adaptive_square.py +++ b/pina/adaptive_functions/adaptive_square.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveSquare(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -18,7 +19,8 @@ class AdaptiveSquare(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' - def __init__(self, alpha = None): + + def __init__(self, alpha=None): ''' Initialization. INPUT: @@ -29,10 +31,10 @@ class AdaptiveSquare(torch.nn.Module): super(AdaptiveSquare, self).__init__() self.scale = Parameter(torch.tensor(1.0)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! self.translate = Parameter(torch.tensor(0.0)) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' diff --git a/pina/adaptive_functions/adaptive_tanh.py b/pina/adaptive_functions/adaptive_tanh.py index 5b6bede..3a2c719 100644 --- a/pina/adaptive_functions/adaptive_tanh.py +++ b/pina/adaptive_functions/adaptive_tanh.py @@ -1,6 +1,7 @@ import torch from torch.nn.parameter import Parameter + class AdaptiveTanh(torch.nn.Module): ''' Implementation of soft exponential activation. @@ -18,7 +19,8 @@ class AdaptiveTanh(torch.nn.Module): >>> x = torch.randn(256) >>> x = a1(x) ''' - def __init__(self, alpha = None): + + def __init__(self, alpha=None): ''' Initialization. INPUT: @@ -31,17 +33,19 @@ class AdaptiveTanh(torch.nn.Module): # initialize alpha if alpha == None: - self.alpha = Parameter(torch.tensor(1.0)) # create a tensor out of alpha + self.alpha = Parameter( + torch.tensor(1.0)) # create a tensor out of alpha else: - self.alpha = Parameter(torch.tensor(alpha)) # create a tensor out of alpha - - self.alpha.requiresGrad = True # set requiresGrad to true! + self.alpha = Parameter( + torch.tensor(alpha)) # create a tensor out of alpha + + self.alpha.requiresGrad = True # set requiresGrad to true! self.scale = Parameter(torch.tensor(1.0)) - self.scale.requiresGrad = True # set requiresGrad to true! + self.scale.requiresGrad = True # set requiresGrad to true! self.translate = Parameter(torch.tensor(0.0)) - self.translate.requiresGrad = True # set requiresGrad to true! + self.translate.requiresGrad = True # set requiresGrad to true! def forward(self, x): ''' @@ -49,4 +53,6 @@ class AdaptiveTanh(torch.nn.Module): Applies the function to the input elementwise. ''' x += self.translate - return self.scale * (torch.exp(self.alpha * x) - torch.exp(-self.alpha * x))/(torch.exp(self.alpha * x) + torch.exp(-self.alpha * x)) + return self.scale * (torch.exp(self.alpha * x) - torch.exp( + -self.alpha * x)) / (torch.exp(self.alpha * x) + + torch.exp(-self.alpha * x)) diff --git a/pina/callbacks/__init__.py b/pina/callbacks/__init__.py index e0beae9..c9ba520 100644 --- a/pina/callbacks/__init__.py +++ b/pina/callbacks/__init__.py @@ -1,9 +1,5 @@ -__all__ = [ - 'SwitchOptimizer', - 'R3Refinement', - 'MetricTracker' -] +__all__ = ['SwitchOptimizer', 'R3Refinement', 'MetricTracker'] from .optimizer_callbacks import SwitchOptimizer from .adaptive_refinment_callbacks import R3Refinement -from .processing_callbacks import MetricTracker \ No newline at end of file +from .processing_callbacks import MetricTracker diff --git a/pina/callbacks/adaptive_refinment_callbacks.py b/pina/callbacks/adaptive_refinment_callbacks.py index 1be904d..5ec149b 100644 --- a/pina/callbacks/adaptive_refinment_callbacks.py +++ b/pina/callbacks/adaptive_refinment_callbacks.py @@ -6,37 +6,37 @@ import torch from ..utils import check_consistency - class R3Refinement(Callback): - """ - PINA implementation of a R3 Refinement Callback. - .. seealso:: - - **Original reference**: Daw, Arka, et al. "Mitigating Propagation Failures - in Physics-informed Neural Networks using - Retain-Resample-Release (R3) Sampling." (2023). - DOI: `10.48550/arXiv.2207.02338 - < https://doi.org/10.48550/arXiv.2207.02338>`_ - """ def __init__(self, sample_every): """ - R3 routine for sampling new points based on - adpative search. The algorithm incrementally - accumulate collocation points in regions of - high PDE residuals, and release the one which - have low residual. Points are sampled uniformmaly - in all region where sampling is needed. + PINA Implementation of an R3 Refinement Callback. + + This callback implements the R3 (Retain-Resample-Release) routine for sampling new points based on adaptive search. + The algorithm incrementally accumulates collocation points in regions of high PDE residuals, and releases those + with low residuals. Points are sampled uniformly in all regions where sampling is needed. + + .. seealso:: + + Original Reference: Daw, Arka, et al. *Mitigating Propagation Failures in Physics-informed Neural Networks + using Retain-Resample-Release (R3) Sampling. (2023)*. + DOI: `10.48550/arXiv.2207.02338 + `_ :param int sample_every: Frequency for sampling. + + :raises ValueError: If `sample_every` is not an integer. + + Example: + >>> r3_callback = R3Refinement(sample_every=5) """ super().__init__() # sample every check_consistency(sample_every, int) self._sample_every = sample_every - + def _compute_residual(self, trainer): """ Computes the residuals for a PINN object. @@ -63,7 +63,7 @@ class R3Refinement(Callback): target = condition.equation.residual(pts, solver.forward(pts)) res_loss[location] = torch.abs(target).as_subclass(torch.Tensor) tot_loss.append(torch.abs(target)) - + return torch.vstack(tot_loss), res_loss def _r3_routine(self, trainer): @@ -79,7 +79,7 @@ class R3Refinement(Callback): # !!!!!! From now everything is performed on CPU !!!!!! # average loss - avg = (tot_loss.mean()).to('cpu') + avg = (tot_loss.mean()).to('cpu') # points to keep old_pts = {} @@ -97,16 +97,18 @@ class R3Refinement(Callback): tot_points += len(pts) # extract new points to sample uniformally for each location - n_points = (self._tot_pop_numb - tot_points ) // len(self._sampling_locations) - remainder = (self._tot_pop_numb - tot_points ) % len(self._sampling_locations) + n_points = (self._tot_pop_numb - tot_points) // len( + self._sampling_locations) + remainder = (self._tot_pop_numb - tot_points) % len( + self._sampling_locations) n_uniform_points = [n_points] * len(self._sampling_locations) n_uniform_points[-1] += remainder # sample new points for numb_pts, loc in zip(n_uniform_points, self._sampling_locations): trainer._model.problem.discretise_domain(numb_pts, - 'random', - locations=[loc]) + 'random', + locations=[loc]) # adding previous population points trainer._model.problem.add_points(old_pts) @@ -114,6 +116,18 @@ class R3Refinement(Callback): trainer._create_or_update_loader() def on_train_start(self, trainer, _): + """ + Callback function called at the start of training. + + This method extracts the locations for sampling from the problem conditions and calculates the total population. + + :param trainer: The trainer object managing the training process. + :type trainer: pytorch_lightning.Trainer + :param _: Placeholder argument (not used). + + :return: None + :rtype: None + """ # extract locations for sampling problem = trainer._model.problem locations = [] @@ -122,7 +136,7 @@ class R3Refinement(Callback): if hasattr(condition, 'location'): locations.append(condition_name) self._sampling_locations = locations - + # extract total population total_population = 0 for location in self._sampling_locations: @@ -131,5 +145,17 @@ class R3Refinement(Callback): self._tot_pop_numb = total_population def on_train_epoch_end(self, trainer, __): + """ + Callback function called at the end of each training epoch. + + This method triggers the R3 routine for refinement if the current epoch is a multiple of `_sample_every`. + + :param trainer: The trainer object managing the training process. + :type trainer: pytorch_lightning.Trainer + :param __: Placeholder argument (not used). + + :return: None + :rtype: None + """ if trainer.current_epoch % self._sample_every == 0: - self._r3_routine(trainer) \ No newline at end of file + self._r3_routine(trainer) diff --git a/pina/callbacks/optimizer_callbacks.py b/pina/callbacks/optimizer_callbacks.py index 0f375f1..276983e 100644 --- a/pina/callbacks/optimizer_callbacks.py +++ b/pina/callbacks/optimizer_callbacks.py @@ -6,22 +6,30 @@ from ..utils import check_consistency class SwitchOptimizer(Callback): - """ - PINA implementation of a Lightining Callback to switch - optimizer during training. The rouutine can be used to - try multiple optimizers during the training, without the - need to stop training. - """ + def __init__(self, new_optimizers, new_optimizers_kwargs, epoch_switch): """ - SwitchOptimizer is a routine for switching optimizer during training. + PINA Implementation of a Lightning Callback to switch optimizer during training. - :param torch.optim.Optimizer | list new_optimizers: The model optimizers to - switch to. It must be a list of :class:`torch.optim.Optimizer` or list of - :class:`torch.optim.Optimizer` for multiple model solvers. - :param dict| list new_optimizers: The model optimizers keyword arguments to - switch use. It must be a dict or list of dict for multiple optimizers. - :param int epoch_switch: Epoch for switching optimizer. + This callback allows for switching between different optimizers during training, enabling + the exploration of multiple optimization strategies without the need to stop training. + + :param new_optimizers: The model optimizers to switch to. Can be a single + :class:`torch.optim.Optimizer` or a list of them for multiple model solvers. + :type new_optimizers: torch.optim.Optimizer | list + :param new_optimizers_kwargs: The keyword arguments for the new optimizers. Can be a single dictionary + or a list of dictionaries corresponding to each optimizer. + :type new_optimizers_kwargs: dict | list + :param epoch_switch: The epoch at which to switch to the new optimizer. + :type epoch_switch: int + + :raises ValueError: If `epoch_switch` is less than 1 or if there is a mismatch in the number of + optimizers and their corresponding keyword argument dictionaries. + + Example: + >>> switch_callback = SwitchOptimizer(new_optimizers=[optimizer1, optimizer2], + >>> new_optimizers_kwargs=[{'lr': 0.001}, {'lr': 0.01}], + >>> epoch_switch=10) """ super().__init__() @@ -44,19 +52,29 @@ class SwitchOptimizer(Callback): ' arguments for each optimizers.' f' Got {len_optimizer} optimizers, and' f' {len_optimizer_kwargs} dicitionaries') - + # save new optimizers self._new_optimizers = new_optimizers self._new_optimizers_kwargs = new_optimizers_kwargs self._epoch_switch = epoch_switch def on_train_epoch_start(self, trainer, __): + """ + Callback function to switch optimizer at the start of each training epoch. + + :param trainer: The trainer object managing the training process. + :type trainer: pytorch_lightning.Trainer + :param _: Placeholder argument (not used). + + :return: None + :rtype: None + """ if trainer.current_epoch == self._epoch_switch: optims = [] for idx, (optim, optim_kwargs) in enumerate( - zip(self._new_optimizers, - self._new_optimizers_kwargs) - ): - optims.append(optim(trainer._model.models[idx].parameters(), **optim_kwargs)) + zip(self._new_optimizers, self._new_optimizers_kwargs)): + optims.append( + optim(trainer._model.models[idx].parameters(), + **optim_kwargs)) - trainer.optimizers = optims \ No newline at end of file + trainer.optimizers = optims diff --git a/pina/callbacks/processing_callbacks.py b/pina/callbacks/processing_callbacks.py index 74ccc44..791d540 100644 --- a/pina/callbacks/processing_callbacks.py +++ b/pina/callbacks/processing_callbacks.py @@ -6,20 +6,53 @@ import copy class MetricTracker(Callback): - """ - PINA implementation of a Lightining Callback to track relevant - metrics during training. - """ + def __init__(self): + """ + PINA Implementation of a Lightning Callback for Metric Tracking. + + This class provides functionality to track relevant metrics during the training process. + + :ivar _collection: A list to store collected metrics after each training epoch. + + :param trainer: The trainer object managing the training process. + :type trainer: pytorch_lightning.Trainer + + :return: A dictionary containing aggregated metric values. + :rtype: dict + + Example: + >>> tracker = MetricTracker() + >>> # ... Perform training ... + >>> metrics = tracker.metrics + """ self._collection = [] def on_train_epoch_end(self, trainer, __): - self._collection.append(copy.deepcopy(trainer.logged_metrics)) # track them + """ + Collect and track metrics at the end of each training epoch. + + :param trainer: The trainer object managing the training process. + :type trainer: pytorch_lightning.Trainer + :param _: Placeholder argument. + + :return: None + :rtype: None + """ + self._collection.append(copy.deepcopy( + trainer.logged_metrics)) # track them @property def metrics(self): - common_keys = set.intersection(*map(set, self._collection)) - v = {k: torch.stack([dic[k] for dic in self._collection]) for k in common_keys} - return v + """ + Aggregate collected metrics during training. - \ No newline at end of file + :return: A dictionary containing aggregated metric values. + :rtype: dict + """ + common_keys = set.intersection(*map(set, self._collection)) + v = { + k: torch.stack([dic[k] for dic in self._collection]) + for k in common_keys + } + return v diff --git a/pina/condition.py b/pina/condition.py index 0fa0cc4..6994701 100644 --- a/pina/condition.py +++ b/pina/condition.py @@ -3,15 +3,17 @@ from .label_tensor import LabelTensor from .geometry import Location from .equation.equation import Equation + def dummy(a): """Dummy function for testing purposes.""" return None + class Condition: """ - The class `Condition` is used to represent the constraints (physical + The class ``Condition`` is used to represent the constraints (physical equations, boundary conditions, etc.) that should be satisfied in the - problem at hand. Condition objects are used to formulate the PINA :obj:`pina.problem.abstract_problem.Abstract_Problem` object. + problem at hand. Condition objects are used to formulate the PINA :obj:`pina.problem.abstract_problem.AbstractProblem` object. Conditions can be specified in three ways: 1. By specifying the input and output points of the condition; in such a @@ -49,8 +51,7 @@ class Condition: """ __slots__ = [ - 'input_points', 'output_points', 'location', 'equation', - 'data_weight' + 'input_points', 'output_points', 'location', 'equation', 'data_weight' ] def _dictvalue_isinstance(self, dict_, key_, class_): @@ -67,13 +68,14 @@ class Condition: self.data_weight = kwargs.pop('data_weight', 1.0) if len(args) != 0: - raise ValueError('Condition takes only the following keyword arguments: {`input_points`, `output_points`, `location`, `function`, `data_weight`}.') + raise ValueError( + 'Condition takes only the following keyword arguments: {`input_points`, `output_points`, `location`, `function`, `data_weight`}.' + ) - if ( - sorted(kwargs.keys()) != sorted(['input_points', 'output_points']) and - sorted(kwargs.keys()) != sorted(['location', 'equation']) and - sorted(kwargs.keys()) != sorted(['input_points', 'equation']) - ): + if (sorted(kwargs.keys()) != sorted(['input_points', 'output_points']) + and sorted(kwargs.keys()) != sorted(['location', 'equation']) + and sorted(kwargs.keys()) != sorted( + ['input_points', 'equation'])): raise ValueError(f'Invalid keyword arguments {kwargs.keys()}.') if not self._dictvalue_isinstance(kwargs, 'input_points', LabelTensor): diff --git a/pina/equation/equation.py b/pina/equation/equation.py index 577d6ee..2934d37 100644 --- a/pina/equation/equation.py +++ b/pina/equation/equation.py @@ -1,6 +1,7 @@ -""" Module """ +""" Module for Equation. """ from .equation_interface import EquationInterface + class Equation(EquationInterface): def __init__(self, equation): @@ -11,7 +12,7 @@ class Equation(EquationInterface): :param equation: A ``torch`` callable equation to evaluate the residual. - :type equation: callable + :type equation: Callable """ if not callable(equation): raise ValueError('equation must be a callable function.' @@ -29,4 +30,4 @@ class Equation(EquationInterface): :return: The residual evaluation of the specified equation. :rtype: LabelTensor """ - return self.__equation(input_, output_) \ No newline at end of file + return self.__equation(input_, output_) diff --git a/pina/equation/equation_factory.py b/pina/equation/equation_factory.py index dc09869..4edbf53 100644 --- a/pina/equation/equation_factory.py +++ b/pina/equation/equation_factory.py @@ -4,7 +4,7 @@ from ..operators import grad, div, laplacian class FixedValue(Equation): - + def __init__(self, value, components=None): """ Fixed Value Equation class. This class can be @@ -18,10 +18,12 @@ class FixedValue(Equation): all the output variables are considered. Default is ``None``. """ + def equation(input_, output_): if components is None: return output_ - value - return output_.extract(components) - value + return output_.extract(components) - value + super().__init__(equation) @@ -43,9 +45,11 @@ class FixedGradient(Equation): which the gradient is calculated. d should be a subset of the input labels. If ``None``, all the input variables are considered. Default is ``None``. - """ + """ + def equation(input_, output_): return grad(output_, input_, components=components, d=d) - value + super().__init__(equation) @@ -67,9 +71,11 @@ class FixedFlux(Equation): which the flux is calculated. d should be a subset of the input labels. If ``None``, all the input variables are considered. Default is ``None``. - """ + """ + def equation(input_, output_): return div(output_, input_, components=components, d=d) - value + super().__init__(equation) @@ -90,7 +96,9 @@ class Laplace(Equation): which the flux is calculated. d should be a subset of the input labels. If ``None``, all the input variables are considered. Default is ``None``. - """ + """ + def equation(input_, output_): return laplacian(output_, input_, components=components, d=d) + super().__init__(equation) diff --git a/pina/equation/system_equation.py b/pina/equation/system_equation.py index df852dc..910005f 100644 --- a/pina/equation/system_equation.py +++ b/pina/equation/system_equation.py @@ -1,8 +1,9 @@ -""" Module """ +""" Module for SystemEquation. """ import torch from .equation import Equation from ..utils import check_consistency + class SystemEquation(Equation): def __init__(self, list_equation, reduction='mean'): @@ -14,7 +15,7 @@ class SystemEquation(Equation): A ``SystemEquation`` is specified by a list of equations. - :param callable equation: A ``torch`` callable equation to + :param Callable equation: A ``torch`` callable equation to evaluate the residual :param str reduction: Specifies the reduction to apply to the output: ``none`` | ``mean`` | ``sum`` | ``callable``. ``none``: no reduction @@ -28,7 +29,7 @@ class SystemEquation(Equation): # equations definition self.equations = [] - for _, equation in enumerate(list_equation): + for _, equation in enumerate(list_equation): self.equations.append(Equation(equation)) # possible reduction @@ -39,7 +40,8 @@ class SystemEquation(Equation): elif (reduction == 'none') or callable(reduction): self.reduction = reduction else: - raise NotImplementedError('Only mean and sum reductions implemented.') + raise NotImplementedError( + 'Only mean and sum reductions implemented.') def residual(self, input_, output_): """ @@ -52,12 +54,10 @@ class SystemEquation(Equation): aggregated by the ``reduction`` defined in the ``__init__``. :rtype: LabelTensor """ - residual = torch.hstack([ - equation.residual(input_, output_) - for equation in self.equations - ]) - + residual = torch.hstack( + [equation.residual(input_, output_) for equation in self.equations]) + if self.reduction == 'none': return residual - - return self.reduction(residual, dim=-1) \ No newline at end of file + + return self.reduction(residual, dim=-1) diff --git a/pina/geometry/__init__.py b/pina/geometry/__init__.py index 5d38b32..a936069 100644 --- a/pina/geometry/__init__.py +++ b/pina/geometry/__init__.py @@ -1,13 +1,6 @@ __all__ = [ - 'Location', - 'CartesianDomain', - 'EllipsoidDomain', - 'Union', - 'Intersection', - 'Exclusion', - 'Difference', - 'OperationInterface', - 'SimplexDomain' + 'Location', 'CartesianDomain', 'EllipsoidDomain', 'Union', 'Intersection', + 'Exclusion', 'Difference', 'OperationInterface', 'SimplexDomain' ] from .location import Location diff --git a/pina/geometry/cartesian.py b/pina/geometry/cartesian.py index 6c8f810..84f6554 100644 --- a/pina/geometry/cartesian.py +++ b/pina/geometry/cartesian.py @@ -8,12 +8,12 @@ from ..utils import torch_lhs, chebyshev_roots class CartesianDomain(Location): """PINA implementation of Hypercube domain.""" - def __init__(self, span_dict): + def __init__(self, cartesian_dict): """ - :param span_dict: A dictionary with dict-key a string representing + :param cartesian_dict: A dictionary with dict-key a string representing the input variables for the pinn, and dict-value a list with the domain extrema. - :type span_dict: dict + :type cartesian_dict: dict :Example: >>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) @@ -21,7 +21,7 @@ class CartesianDomain(Location): self.fixed_ = {} self.range_ = {} - for k, v in span_dict.items(): + for k, v in cartesian_dict.items(): if isinstance(v, (int, float)): self.fixed_[k] = v elif isinstance(v, (list, tuple)) and len(v) == 2: @@ -33,28 +33,27 @@ class CartesianDomain(Location): def variables(self): """Spatial variables. - :return: Spatial variables defined in '__init__()' + :return: Spatial variables defined in ``__init__()`` :rtype: list[str] """ return list(self.fixed_.keys()) + list(self.range_.keys()) - def update(self, new_span): - """Adding new dimensions on the span + def update(self, new_domain): + """Adding new dimensions on the ``CartesianDomain`` - :param new_span: A new span object to merge - :type new_span: Span + :param CartesianDomain new_domain: A new ``CartesianDomain`` object to merge :Example: - >>> spatial_domain = Span({'x': [0, 1], 'y': [0, 1]}) + >>> spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) >>> spatial_domain.variables ['x', 'y'] - >>> spatial_domain_2 = Span({'z': [3, 4], 'w': [0, 1]}) + >>> spatial_domain_2 = CartesianDomain({'z': [3, 4], 'w': [0, 1]}) >>> spatial_domain.update(spatial_domain_2) >>> spatial_domain.variables ['x', 'y', 'z', 'w'] """ - self.fixed_.update(new_span.fixed_) - self.range_.update(new_span.range_) + self.fixed_.update(new_domain.fixed_) + self.range_.update(new_domain.range_) def _sample_range(self, n, mode, bounds): """Rescale the samples to the correct bounds @@ -62,11 +61,11 @@ class CartesianDomain(Location): :param n: Number of points to sample, see Note below for reference. :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'; - latin hypercube sampling, 'latin' or 'lh'; - chebyshev sampling, 'chebyshev'; grid sampling 'grid'. - :type mode: str, optional + :param mode: Mode for sampling, defaults to ``random``. + Available modes include: random sampling, ``random``; + 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. @@ -97,25 +96,27 @@ class CartesianDomain(Location): :param n: Number of points to sample, see Note below for reference. :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'; - latin hypercube sampling, 'latin' or 'lh'; - chebyshev sampling, 'chebyshev'; grid sampling 'grid'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param mode: Mode for sampling, defaults to ``random``. + Available modes include: random sampling, ``random``; + latin hypercube sampling, ``latin`` or ``lh``; + chebyshev sampling, ``chebyshev``; grid sampling ``grid``. + :type mode: str + :param variables: pinn variable to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor .. note:: The total number of points sampled in case of multiple variables - is not 'n', and it depends on the chosen 'mode'. If 'mode' is - 'grid' or 'chebyshev', the points are sampled independentely + is not ``n``, and it depends on the chosen ``mode``. If ``mode`` is + 'grid' or ``chebyshev``, the points are sampled independentely across the variables and the results crossed together, i.e. the - final number of points is 'n' to the power of the number of - variables. If 'mode' is 'random', 'lh' or 'latin', the variables + final number of points is ``n`` to the power of the number of + variables. If 'mode' is 'random', ``lh`` or ``latin``, the variables are sampled all together, and the final number of points .. warning:: - The extrema values of Span are always sampled only for 'grid' mode. + The extrema values of Span are always sampled only for ``grid`` mode. :Example: >>> spatial_domain = Span({'x': [0, 1], 'y': [0, 1]}) @@ -142,6 +143,7 @@ class CartesianDomain(Location): [0.6667, 1.0000], [1.0000, 1.0000]]) """ + def _1d_sampler(n, mode, variables): """ Sample independentely the variables and cross the results""" tmp = [] @@ -161,8 +163,8 @@ class CartesianDomain(Location): for variable in variables: if variable in self.fixed_.keys(): value = self.fixed_[variable] - pts_variable = torch.tensor([[value]]).repeat( - result.shape[0], 1) + pts_variable = torch.tensor([[value] + ]).repeat(result.shape[0], 1) pts_variable = pts_variable.as_subclass(LabelTensor) pts_variable.labels = [variable] @@ -175,13 +177,13 @@ class CartesianDomain(Location): :param n: Number of points to sample. :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'; - latin hypercube sampling, 'latin' or 'lh'; - chebyshev sampling, 'chebyshev'; grid sampling 'grid'. - :type mode: str, optional. - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional. + :param mode: Mode for sampling, defaults to ``random``. + Available modes include: random sampling, ``random``; + latin hypercube sampling, ``latin`` or ``lh``; + chebyshev sampling, ``chebyshev``; grid sampling ``grid``. + :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] """ @@ -195,8 +197,8 @@ class CartesianDomain(Location): for variable in variables: if variable in self.fixed_.keys(): value = self.fixed_[variable] - pts_variable = torch.tensor([[value]]).repeat( - result.shape[0], 1) + pts_variable = torch.tensor([[value] + ]).repeat(result.shape[0], 1) pts_variable = pts_variable.as_subclass(LabelTensor) pts_variable.labels = [variable] @@ -241,16 +243,15 @@ class CartesianDomain(Location): else: raise ValueError(f'mode={mode} is not valid.') - def is_inside(self, point, check_border=False): """Check if a point is inside the ellipsoid. :param point: Point to be checked :type point: LabelTensor :param check_border: Check if the point is also on the frontier - of the hypercube, default False. + of the hypercube, default ``False``. :type check_border: bool - :return: Returning True if the point is inside, False otherwise. + :return: Returning ``True`` if the point is inside, ``False`` otherwise. :rtype: bool """ is_inside = [] @@ -268,7 +269,7 @@ class CartesianDomain(Location): check = bound[0] <= point.extract([variable]) <= bound[1] else: check = bound[0] < point.extract([variable]) < bound[1] - + is_inside.append(check) return all(is_inside) diff --git a/pina/geometry/difference_domain.py b/pina/geometry/difference_domain.py index 9a571cb..efdad63 100644 --- a/pina/geometry/difference_domain.py +++ b/pina/geometry/difference_domain.py @@ -1,73 +1,78 @@ -"""Module for Location class.""" +"""Module for Difference class.""" + import torch -from .exclusion_domain import Exclusion from .operation_interface import OperationInterface from ..label_tensor import LabelTensor class Difference(OperationInterface): - """ PINA implementation of Difference of Domains.""" def __init__(self, geometries): - """ + r""" PINA implementation of Difference of Domains. Given two sets :math:`A` and :math:`B` then the domain difference is defined as: - ..:math: - A \setminus B = \{x \mid x \in A \text{ and } x \not\in B\}, + .. math:: + A - B = \{x \mid x \in A \land x \not\in B\}, with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N` the dimension of the geometry space. - :param list geometries: A list of geometries from 'pina.geometry' - such as 'EllipsoidDomain' or 'CartesianDomain'. The first + :param list geometries: A list of geometries from ``pina.geometry`` + such as ``EllipsoidDomain`` or ``CartesianDomain``. The first geometry in the list is the geometry from which points are sampled. The rest of the geometries are the geometries that are excluded from the first geometry to find the difference. :Example: - # Create two ellipsoid domains + >>> # Create two ellipsoid domains >>> ellipsoid1 = EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}) >>> ellipsoid2 = EllipsoidDomain({'x': [0, 2], 'y': [0, 2]}) - - # Create a Difference of the ellipsoid domains + >>> # Create a Difference of the ellipsoid domains >>> difference = Difference([ellipsoid1, ellipsoid2]) """ super().__init__(geometries) def is_inside(self, point, check_border=False): + """ + Check if a point is inside the ``Difference`` domain. + + :param point: Point to be checked. + :type point: torch.Tensor + :param bool check_border: If ``True``, the border is considered inside. + :return: ``True`` if the point is inside the Exclusion domain, ``False`` otherwise. + :rtype: bool + """ for geometry in self.geometries[1:]: if geometry.is_inside(point): return False return self.geometries[0].is_inside(point, check_border) def sample(self, n, mode='random', variables='all'): - """Sample routine for difference domain. + """ + Sample routine for ``Difference`` domain. - :param n: Number of points to sample in the shape. - :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param int n: Number of points to sample in the shape. + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor :Example: - # Create two Cartesian domains + >>> # Create two Cartesian domains >>> cartesian1 = CartesianDomain({'x': [0, 2], 'y': [0, 2]}) >>> cartesian2 = CartesianDomain({'x': [1, 3], 'y': [1, 3]}) - - # Create a Difference of the ellipsoid domains + >>> # Create a Difference of the ellipsoid domains >>> difference = Difference([cartesian1, cartesian2]) - + >>> # Sampling >>> difference.sample(n=5) LabelTensor([[0.8400, 0.9179], [0.9154, 0.5769], [1.7403, 0.4835], [0.9545, 1.2851], [1.3726, 0.9831]]) - >>> len(difference.sample(n=5) 5 diff --git a/pina/geometry/ellipsoid.py b/pina/geometry/ellipsoid.py index d9c3680..e99425f 100644 --- a/pina/geometry/ellipsoid.py +++ b/pina/geometry/ellipsoid.py @@ -16,10 +16,10 @@ class EllipsoidDomain(Location): the domain extrema. :type ellipsoid_dict: dict :param sample_surface: A variable for choosing sample strategies. If - `sample_surface=True` only samples on the ellipsoid surface - frontier are taken. If `sample_surface=False` only samples on - the ellipsoid interior are taken, defaults to False. - :type sample_surface: bool, optional + ``sample_surface=True`` only samples on the ellipsoid surface + frontier are taken. If ``sample_surface=False`` only samples on + the ellipsoid interior are taken, defaults to ``False``. + :type sample_surface: bool .. warning:: Sampling for dimensions greater or equal to 10 could result @@ -84,22 +84,22 @@ class EllipsoidDomain(Location): """Check if a point is inside the ellipsoid domain. .. note:: - When ```'sample_surface'``` in the ```'__init()__'``` - is set to ```'True'```, then the method only checks + When ``sample_surface`` in the ``__init()__`` + is set to ``True``, then the method only checks points on the surface, and not inside the domain. :param point: Point to be checked. :type point: LabelTensor :param check_border: Check if the point is also on the frontier - of the ellipsoid, default False. + of the ellipsoid, default ``False``. :type check_border: bool - :return: Returning True if the point is inside, False otherwise. + :return: Returning True if the point is inside, ``False`` otherwise. :rtype: bool """ # small check that point is labeltensor check_consistency(point, LabelTensor) - + # get axis ellipse as tensors list_dict_vals = list(self._axis.values()) tmp = torch.tensor(list_dict_vals, dtype=torch.float) @@ -122,15 +122,15 @@ class EllipsoidDomain(Location): # calculate ellispoid equation eqn = torch.sum(point_sq.extract(ax_sq.labels) / ax_sq) - 1. - # if we have sampled only the surface, we check that the + # if we have sampled only the surface, we check that the # point is inside the surface border only if self._sample_surface: return torch.allclose(eqn, torch.zeros_like(eqn)) - # otherwise we check the ellipse + # otherwise we check the ellipse if check_border: return bool(eqn <= 0) - + return bool(eqn < 0) def _sample_range(self, n, mode, variables): @@ -138,8 +138,8 @@ class EllipsoidDomain(Location): :param n: Number of points to sample in the ellipsoid. :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. + :param mode: Mode for sampling, defaults to ``random``. + Available modes include: random sampling, ``random``. :type mode: str, optional :param variables: Variables to be rescaled in the samples. :type variables: torch.Tensor @@ -195,13 +195,12 @@ class EllipsoidDomain(Location): def sample(self, n, mode='random', variables='all'): """Sample routine. - :param n: Number of points to sample in the ellipsoid. - :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param int n: Number of points to sample in the shape. + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor :Example: >>> elips = Ellipsoid({'x':[1, 0], 'y':1}) @@ -219,12 +218,12 @@ class EllipsoidDomain(Location): :param n: Number of points to sample. :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'; + :param mode: Mode for sampling, defaults to ``random``. + Available modes include: random sampling, ``random``; latin hypercube sampling, 'latin' or 'lh'; chebyshev sampling, 'chebyshev'; grid sampling 'grid'. :type mode: str, optional. - :param variables: pinn variable to be sampled, defaults to 'all'. + :param variables: pinn variable to be sampled, defaults to ``all``. :type variables: str or list[str], optional. :return: Sample points. :rtype: list[torch.Tensor] diff --git a/pina/geometry/exclusion_domain.py b/pina/geometry/exclusion_domain.py index ebfbb8f..457289b 100644 --- a/pina/geometry/exclusion_domain.py +++ b/pina/geometry/exclusion_domain.py @@ -1,47 +1,45 @@ -"""Module for Location class.""" +"""Module for Exclusion class. """ + import torch -from .location import Location -from ..utils import check_consistency from ..label_tensor import LabelTensor import random from .operation_interface import OperationInterface class Exclusion(OperationInterface): - """ PINA implementation of Exclusion of Domains.""" def __init__(self, geometries): - """ + r""" PINA implementation of Exclusion of Domains. Given two sets :math:`A` and :math:`B` then the domain difference is defined as: - ..:math: - A \setminus B = \{x \mid x \in A \text{ and } x \in B\ \text{ and } x \not\in (A \text{ or } B)}, + .. math:: + A \setminus B = \{x \mid x \in A \land x \in B \land x \not\in (A \lor B)\}, with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N` the dimension of the geometry space. - :param list geometries: A list of geometries from 'pina.geometry' - such as 'EllipsoidDomain' or 'CartesianDomain'. + :param list geometries: A list of geometries from ``pina.geometry`` + such as ``EllipsoidDomain`` or ``CartesianDomain``. :Example: - # Create two ellipsoid domains + >>> # Create two ellipsoid domains >>> ellipsoid1 = EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}) >>> ellipsoid2 = EllipsoidDomain({'x': [0, 2], 'y': [0, 2]}) - - # Create a Exclusion of the ellipsoid domains + >>> # Create a Exclusion of the ellipsoid domains >>> exclusion = Exclusion([ellipsoid1, ellipsoid2]) """ super().__init__(geometries) def is_inside(self, point, check_border=False): - """Check if a point is inside the Exclusion domain. + """ + Check if a point is inside the ``Exclusion`` domain. :param point: Point to be checked. :type point: torch.Tensor - :param bool check_border: If True, the border is considered inside. - :return: True if the point is inside the Exclusion domain, False otherwise. + :param bool check_border: If ``True``, the border is considered inside. + :return: ``True`` if the point is inside the Exclusion domain, ``False`` otherwise. :rtype: bool """ flag = 0 @@ -51,31 +49,29 @@ class Exclusion(OperationInterface): return flag == 1 def sample(self, n, mode='random', variables='all'): - """Sample routine for exclusion domain. + """ + Sample routine for ``Exclusion`` domain. - :param n: Number of points to sample in the shape. - :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param int n: Number of points to sample in the shape. + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor :Example: - # Create two Cartesian domains + >>> # Create two Cartesian domains >>> cartesian1 = CartesianDomain({'x': [0, 2], 'y': [0, 2]}) >>> cartesian2 = CartesianDomain({'x': [1, 3], 'y': [1, 3]}) - - # Create a Exclusion of the ellipsoid domains + >>> # Create a Exclusion of the ellipsoid domains >>> Exclusion = Exclusion([cartesian1, cartesian2]) - + >>> # Sample >>> Exclusion.sample(n=5) LabelTensor([[2.4187, 1.5792], [2.7456, 2.3868], [2.3830, 1.7037], [0.8636, 1.8453], [0.1978, 0.3526]]) - >>> len(Exclusion.sample(n=5) 5 diff --git a/pina/geometry/intersection_domain.py b/pina/geometry/intersection_domain.py index be78885..e5ecb1a 100644 --- a/pina/geometry/intersection_domain.py +++ b/pina/geometry/intersection_domain.py @@ -1,48 +1,47 @@ -"""Module for Location class.""" +"""Module for Intersection class. """ + import torch -from .exclusion_domain import Exclusion from ..label_tensor import LabelTensor from .operation_interface import OperationInterface import random class Intersection(OperationInterface): - """ PINA implementation of Intersection of Domains.""" def __init__(self, geometries): - """ + r""" PINA implementation of Intersection of Domains. Given two sets :math:`A` and :math:`B` then the domain difference is defined as: - ..:math: - A \cap B = \{x \mid x \in A \text{ and } x \in B\}, + .. math:: + A \cap B = \{x \mid x \in A \land x \in B\}, with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N` the dimension of the geometry space. - :param list geometries: A list of geometries from 'pina.geometry' - such as 'EllipsoidDomain' or 'CartesianDomain'. The intersection + :param list geometries: A list of geometries from ``pina.geometry`` + such as ``EllipsoidDomain`` or ``CartesianDomain``. The intersection will be taken between all the geometries in the list. The resulting geometry will be the intersection of all the geometries in the list. :Example: - # Create two ellipsoid domains + >>> # Create two ellipsoid domains >>> ellipsoid1 = EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}) >>> ellipsoid2 = EllipsoidDomain({'x': [0, 2], 'y': [0, 2]}) - - # Create a Intersection of the ellipsoid domains + >>> # Create a Intersection of the ellipsoid domains >>> intersection = Intersection([ellipsoid1, ellipsoid2]) """ super().__init__(geometries) def is_inside(self, point, check_border=False): - """Check if a point is inside the Exclusion domain. + """ + Check if a point is inside the ``Intersection`` domain. :param point: Point to be checked. :type point: torch.Tensor - :param bool check_border: If True, the border is considered inside. - :return: True if the point is inside the Exclusion domain, False otherwise. + :param bool check_border: If ``True``, the border is considered inside. + :return: ``True`` if the point is inside the Intersection domain, ``False`` otherwise. :rtype: bool """ flag = 0 @@ -52,31 +51,29 @@ class Intersection(OperationInterface): return flag == len(self.geometries) def sample(self, n, mode='random', variables='all'): - """Sample routine for intersection domain. + """ + Sample routine for ``Intersection`` domain. - :param n: Number of points to sample in the shape. - :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param int n: Number of points to sample in the shape. + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor :Example: - # Create two Cartesian domains + >>> # Create two Cartesian domains >>> cartesian1 = CartesianDomain({'x': [0, 2], 'y': [0, 2]}) >>> cartesian2 = CartesianDomain({'x': [1, 3], 'y': [1, 3]}) - - # Create a Intersection of the ellipsoid domains + >>> # Create a Intersection of the ellipsoid domains >>> intersection = Intersection([cartesian1, cartesian2]) - + >>> # Sample >>> intersection.sample(n=5) LabelTensor([[1.7697, 1.8654], [1.2841, 1.1208], [1.7289, 1.9843], [1.3332, 1.2448], [1.9902, 1.4458]]) - >>> len(intersection.sample(n=5) 5 diff --git a/pina/geometry/location.py b/pina/geometry/location.py index c91b89a..a22dfe1 100644 --- a/pina/geometry/location.py +++ b/pina/geometry/location.py @@ -8,6 +8,7 @@ class Location(metaclass=ABCMeta): Abstract Location class. Any geometry entity should inherit from this class. """ + @abstractmethod def sample(self): """ @@ -22,9 +23,9 @@ class Location(metaclass=ABCMeta): Abstract method for checking if a point is inside the location. To be implemented in the child class. - :param tensor point: A tensor point to be checked. - :param bool check_border: a boolean that determines whether the border + :param torch.Tensor point: A tensor point to be checked. + :param bool check_border: A boolean that determines whether the border of the location is considered checked to be considered inside or - not. Defaults to False. + not. Defaults to ``False``. """ pass diff --git a/pina/geometry/operation_interface.py b/pina/geometry/operation_interface.py index ae6fc79..670e924 100644 --- a/pina/geometry/operation_interface.py +++ b/pina/geometry/operation_interface.py @@ -1,26 +1,18 @@ -import torch +""" Module for OperationInterface class. """ + from .location import Location from ..utils import check_consistency -from ..label_tensor import LabelTensor from abc import ABCMeta, abstractmethod -import random class OperationInterface(Location, metaclass=ABCMeta): - """PINA Operation Interface""" def __init__(self, geometries): """ - Abstract Operation class. - Any geometry operation entity must inherit from this class. + Abstract set operation class. Any geometry operation entity must inherit from this class. - .. warning:: - The ``sample_surface=True`` option is not implemented yet - for Difference, Intersection, and Exclusion. The usage will - result in unwanted behaviour. - - :param list geometries: A list of geometries from 'pina.geometry' - such as 'EllipsoidDomain' or 'CartesianDomain'. + :param list geometries: A list of geometries from ``pina.geometry`` + such as ``EllipsoidDomain`` or ``CartesianDomain``. """ # check consistency geometries check_consistency(geometries, Location) @@ -35,18 +27,33 @@ class OperationInterface(Location, metaclass=ABCMeta): @property def geometries(self): """ - The geometries.""" + The geometries to perform set operation. + """ return self._geometries @property def variables(self): """ - Spatial variables. + Spatial variables of the domain. :return: All the variables defined in ``__init__`` in order. :rtype: list[str] """ return self.geometries[0].variables + + @ abstractmethod + def is_inside(self, point, check_border=False): + """ + Check if a point is inside the resulting domain after + a set operation is applied. + + :param point: Point to be checked. + :type point: torch.Tensor + :param bool check_border: If ``True``, the border is considered inside. + :return: ``True`` if the point is inside the Intersection domain, ``False`` otherwise. + :rtype: bool + """ + pass def _check_dimensions(self, geometries): """Check if the dimensions of the geometries are consistent. diff --git a/pina/geometry/simplex.py b/pina/geometry/simplex.py index c371aec..6cfcfc7 100644 --- a/pina/geometry/simplex.py +++ b/pina/geometry/simplex.py @@ -13,17 +13,21 @@ class SimplexDomain(Location): :param simplex_matrix: A matrix of LabelTensor objects representing a vertex of the simplex (a tensor), and the coordinates of the point (a list of labels). + :type simplex_matrix: list[LabelTensor] :param sample_surface: A variable for choosing sample strategies. If - `sample_surface=True` only samples on the Simplex surface - frontier are taken. If `sample_surface=False`, no such criteria + ``sample_surface=True`` only samples on the Simplex surface + frontier are taken. If ``sample_surface=False``, no such criteria is followed. + :type sample_surface: bool + .. warning:: Sampling for dimensions greater or equal to 10 could result in a shrinking of the simplex, which degrades the quality of the samples. For dimensions higher than 10, other algorithms for sampling should be used. + :Example: >>> spatial_domain = SimplexDomain( [ @@ -48,12 +52,14 @@ class SimplexDomain(Location): matrix_labels = simplex_matrix[0].labels if not all(vertex.labels == matrix_labels for vertex in simplex_matrix): raise ValueError(f"Labels don't match.") - + # check consistency dimensions dim_simplex = len(matrix_labels) if len(simplex_matrix) != dim_simplex + 1: - raise ValueError("An n-dimensional simplex is composed by n + 1 tensors of dimension n.") - + raise ValueError( + "An n-dimensional simplex is composed by n + 1 tensors of dimension n." + ) + # creating vertices matrix self._vertices_matrix = LabelTensor.vstack(simplex_matrix) @@ -86,8 +92,10 @@ class SimplexDomain(Location): for i, coord in enumerate(self.variables): sorted_vertices = sorted(vertices, key=lambda vertex: vertex[i]) # respective coord bounded by the lowest and highest values - span_dict[coord] = [float(sorted_vertices[0][i]), - float(sorted_vertices[-1][i])] + span_dict[coord] = [ + float(sorted_vertices[0][i]), + float(sorted_vertices[-1][i]) + ] return CartesianDomain(span_dict) @@ -96,31 +104,32 @@ class SimplexDomain(Location): Check if a point is inside the simplex. Uses the algorithm described involving barycentric coordinates: https://en.wikipedia.org/wiki/Barycentric_coordinate_system. - .. note:: - When ```'sample_surface'``` in the ```'__init()__'``` - is set to ```'True'```, then the method only checks - points on the surface, and not inside the domain. + :param point: Point to be checked. :type point: LabelTensor :param check_border: Check if the point is also on the frontier - of the simplex, default False. + of the simplex, default ``False``. :type check_border: bool - :return: Returning True if the point is inside, False otherwise. + :return: Returning ``True`` if the point is inside, ``False`` otherwise. :rtype: bool + + .. note:: + When ``sample_surface`` in the ``__init()__`` + is set to ``True``, then the method only checks + points on the surface, and not inside the domain. """ if not all(label in self.variables for label in point.labels): - raise ValueError( - "Point labels different from constructor" - f" dictionary labels. Got {point.labels}," - f" expected {self.variables}." - ) + raise ValueError("Point labels different from constructor" + f" dictionary labels. Got {point.labels}," + f" expected {self.variables}.") point_shift = point - self._vertices_matrix[-1] point_shift = point_shift.tensor.reshape(-1, 1) # compute barycentric coordinates - lambda_ = torch.linalg.solve(self._vectors_shifted * 1.0, point_shift * 1.0) + lambda_ = torch.linalg.solve(self._vectors_shifted * 1.0, + point_shift * 1.0) lambda_1 = 1.0 - torch.sum(lambda_) lambdas = torch.vstack([lambda_, lambda_1]) @@ -128,16 +137,15 @@ class SimplexDomain(Location): if not check_border: return all(torch.gt(lambdas, 0.0)) and all(torch.lt(lambdas, 1.0)) - return all(torch.ge(lambdas, 0)) and ( - any(torch.eq(lambdas, 0)) or any(torch.eq(lambdas, 1)) - ) + return all(torch.ge(lambdas, 0)) and (any(torch.eq(lambdas, 0)) + or any(torch.eq(lambdas, 1))) def _sample_interior_randomly(self, n, variables): """ Randomly sample points inside a simplex of arbitrary dimension, without the boundary. :param int n: Number of points to sample in the shape. - :param variables: pinn variable to be sampled, defaults to 'all'. + :param variables: pinn variable to be sampled, defaults to ``all``. :type variables: str or list[str], optional :return: Returns tensor of n sampled points. :rtype: torch.Tensor @@ -155,9 +163,9 @@ class SimplexDomain(Location): sampled_points = [] while len(sampled_points) < n: - sampled_point = self._cartesian_bound.sample( - n=1, mode="random", variables=variables - ) + sampled_point = self._cartesian_bound.sample(n=1, + mode="random", + variables=variables) if self.is_inside(sampled_point, self._sample_surface): sampled_points.append(sampled_point) @@ -188,7 +196,9 @@ class SimplexDomain(Location): # extract number of vertices number_of_vertices = self._vertices_matrix.shape[0] # extract idx lambda to set to zero randomly - idx_lambda = torch.randint(low=0, high=number_of_vertices, size=(1,)) + idx_lambda = torch.randint(low=0, + high=number_of_vertices, + size=(1, )) # build lambda vector # 1. sampling [1, 2) lambdas = torch.rand((number_of_vertices, 1)) @@ -203,13 +213,14 @@ class SimplexDomain(Location): def sample(self, n, mode="random", variables="all"): """ Sample n points from Simplex domain. + :param int n: Number of points to sample in the shape. - :param str mode: Mode for sampling, defaults to 'random'. - Available modes include: 'random'. - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional - :return: Returns LabelTensor of n sampled points - :rtype: LabelTensor(tensor) + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor + .. warning:: When ``sample_surface = True`` in the initialization, all the variables are sampled, despite passing different once @@ -225,4 +236,4 @@ class SimplexDomain(Location): else: raise NotImplementedError(f"mode={mode} is not implemented.") - return LabelTensor(sample_pts, labels=self.variables) + return LabelTensor(sample_pts, labels=self.variables) \ No newline at end of file diff --git a/pina/geometry/union_domain.py b/pina/geometry/union_domain.py index 6f10c8a..1141236 100644 --- a/pina/geometry/union_domain.py +++ b/pina/geometry/union_domain.py @@ -1,49 +1,48 @@ +"""Module for Union class. """ + import torch -from .location import Location from .operation_interface import OperationInterface -from ..utils import check_consistency from ..label_tensor import LabelTensor import random class Union(OperationInterface): - """ PINA implementation of Unions of Domains.""" def __init__(self, geometries): - """ + r""" PINA implementation of Unions of Domains. Given two sets :math:`A` and :math:`B` then the domain difference is defined as: - ..:math: - A \cup B = \{x \mid x \in A \text{ or } x \in B\}, + .. math:: + A \cup B = \{x \mid x \in A \lor x \in B\}, with :math:`x` a point in :math:`\mathbb{R}^N` and :math:`N` the dimension of the geometry space. - :param list geometries: A list of geometries from 'pina.geometry' - such as 'EllipsoidDomain' or 'CartesianDomain'. + :param list geometries: A list of geometries from ``pina.geometry`` + such as ``EllipsoidDomain`` or ``CartesianDomain``. :Example: - # Create two ellipsoid domains + >>> # Create two ellipsoid domains >>> ellipsoid1 = EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}) >>> ellipsoid2 = EllipsoidDomain({'x': [0, 2], 'y': [0, 2]}) - - # Create a union of the ellipsoid domains + >>> # Create a union of the ellipsoid domains >>> union = GeometryUnion([ellipsoid1, ellipsoid2]) """ super().__init__(geometries) def is_inside(self, point, check_border=False): - """Check if a point is inside the union domain. + """ + Check if a point is inside the ``Union`` domain. :param point: Point to be checked. :type point: LabelTensor :param check_border: Check if the point is also on the frontier - of the ellipsoid, default False. + of the ellipsoid, default ``False``. :type check_border: bool - :return: Returning True if the point is inside, False otherwise. + :return: Returning ``True`` if the point is inside, ``False`` otherwise. :rtype: bool """ for geometry in self.geometries: @@ -52,31 +51,29 @@ class Union(OperationInterface): return False def sample(self, n, mode='random', variables='all'): - """Sample routine for union domain. + """ + Sample routine for ``Union`` domain. - :param n: Number of points to sample in the shape. - :type n: int - :param mode: Mode for sampling, defaults to 'random'. - Available modes include: random sampling, 'random'. - :type mode: str, optional - :param variables: pinn variable to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :param int n: Number of points to sample in the shape. + :param str mode: Mode for sampling, defaults to ``random``. Available modes include: ``random``. + :param variables: Variables to be sampled, defaults to ``all``. + :type variables: str | list[str] + :return: Returns ``LabelTensor`` of n sampled points. + :rtype: LabelTensor :Example: - # Create two ellipsoid domains + >>> # Create two ellipsoid domains >>> cartesian1 = CartesianDomain({'x': [0, 2], 'y': [0, 2]}) >>> cartesian2 = CartesianDomain({'x': [1, 3], 'y': [1, 3]}) - - # Create a union of the ellipsoid domains + >>> # Create a union of the ellipsoid domains >>> union = Union([cartesian1, cartesian2]) - + >>> # Sample >>> union.sample(n=5) LabelTensor([[1.2128, 2.1991], [1.3530, 2.4317], [2.2562, 1.6605], [0.8451, 1.9878], [1.8623, 0.7102]]) - >>> len(union.sample(n=5) 5 """ @@ -95,8 +92,9 @@ class Union(OperationInterface): # int(i < remainder) is one only if we have a remainder # different than zero. Notice that len(geometries) is # always smaller than remaider. - sampled_points.append(geometry.sample( - num_points + int(i < remainder), mode, variables)) + sampled_points.append( + geometry.sample(num_points + int(i < remainder), mode, + variables)) # in case number of sampled points is smaller than the number of geometries if len(sampled_points) >= n: break diff --git a/pina/label_tensor.py b/pina/label_tensor.py index c11f7a1..502d31f 100644 --- a/pina/label_tensor.py +++ b/pina/label_tensor.py @@ -17,9 +17,9 @@ class LabelTensor(torch.Tensor): labels. Such labels uniquely identify the columns of the tensor, allowing for an easier manipulation. - :param torch.Tensor x: the data tensor. - :param labels: the labels of the columns. - :type labels: str or iterable(str) + :param torch.Tensor x: The data tensor. + :param labels: The labels of the columns. + :type labels: str | list(str) | tuple(str) :Example: >>> from pina import LabelTensor @@ -72,10 +72,8 @@ class LabelTensor(torch.Tensor): labels = [labels] if len(labels) != x.shape[-1]: - raise ValueError( - 'the tensor has not the same number of columns of ' - 'the passed labels.' - ) + raise ValueError('the tensor has not the same number of columns of ' + 'the passed labels.') self._labels = labels @property @@ -90,11 +88,10 @@ class LabelTensor(torch.Tensor): @labels.setter def labels(self, labels): if len(labels) != self.shape[self.ndim - 1]: # small check - raise ValueError( - 'the tensor has not the same number of columns of ' - 'the passed labels.') + raise ValueError('The tensor has not the same number of columns of ' + 'the passed labels.') - self._labels = labels # assign the label + self._labels = labels # assign the label @staticmethod def vstack(label_tensors): @@ -123,7 +120,7 @@ class LabelTensor(torch.Tensor): Clone the LabelTensor. For more details, see :meth:`torch.Tensor.clone`. - :return: a copy of the tensor + :return: A copy of the tensor. :rtype: LabelTensor """ # # used before merging @@ -173,12 +170,12 @@ class LabelTensor(torch.Tensor): def extract(self, label_to_extract): """ Extract the subset of the original tensor by returning all the columns - corresponding to the passed `label_to_extract`. + corresponding to the passed ``label_to_extract``. - :param label_to_extract: the label(s) to extract. - :type label_to_extract: str or iterable(str) - :raises TypeError: labels are not str - :raises ValueError: label to extract is not in the labels list + :param label_to_extract: The label(s) to extract. + :type label_to_extract: str | list(str) | tuple(str) + :raises TypeError: Labels are not ``str``. + :raises ValueError: Label to extract is not in the labels ``list``. """ if isinstance(label_to_extract, str): @@ -211,7 +208,7 @@ class LabelTensor(torch.Tensor): return detached - def requires_grad_(self, mode = True) -> Tensor: + def requires_grad_(self, mode = True): lt = super().requires_grad_(mode) lt.labels = self.labels return lt @@ -220,9 +217,9 @@ class LabelTensor(torch.Tensor): """ Return a copy of the merged tensors. - :param LabelTensor lt: the tensor to merge. + :param LabelTensor lt: The tensor to merge. :param str mode: {'std', 'first', 'cross'} - :return: the merged tensors + :return: The merged tensors. :rtype: LabelTensor """ if set(self.labels).intersection(lt.labels): @@ -239,12 +236,9 @@ class LabelTensor(torch.Tensor): n1 = tensor1.shape[0] n2 = tensor2.shape[0] - tensor1 = LabelTensor( - tensor1.repeat(n2, 1), - labels=tensor1.labels) - tensor2 = LabelTensor( - tensor2.repeat_interleave(n1, dim=0), - labels=tensor2.labels) + tensor1 = LabelTensor(tensor1.repeat(n2, 1), labels=tensor1.labels) + tensor2 = LabelTensor(tensor2.repeat_interleave(n1, dim=0), + labels=tensor2.labels) new_tensor = torch.cat((tensor1, tensor2), dim=1) new_tensor = new_tensor.as_subclass(LabelTensor) @@ -290,7 +284,7 @@ class LabelTensor(torch.Tensor): def __len__(self) -> int: return super().__len__() - + def __str__(self): if hasattr(self, 'labels'): s = f'labels({str(self.labels)})\n' diff --git a/pina/loss.py b/pina/loss.py index d2d0574..8c0b67e 100644 --- a/pina/loss.py +++ b/pina/loss.py @@ -1,6 +1,5 @@ """ Module for Loss class """ - from abc import ABCMeta, abstractmethod from torch.nn.modules.loss import _Loss import torch @@ -8,39 +7,47 @@ from .utils import check_consistency __all__ = ['LossInterface', 'LpLoss', 'PowerLoss'] + class LossInterface(_Loss, metaclass=ABCMeta): """ - The abstract `LossInterface` class. All the class defining a PINA Loss + The abstract ``LossInterface`` class. All the class defining a PINA Loss should be inheritied from this class. """ - def __init__(self, reduction = 'mean'): + def __init__(self, reduction='mean'): """ :param str reduction: Specifies the reduction to apply to the output: - ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction - will be applied, ``'mean'``: the sum of the output will be divided - by the number of elements in the output, ``'sum'``: the output will - be summed. Note: :attr:`size_average` and :attr:`reduce` are in the + ``none`` | ``mean`` | ``sum``. When ``none``: no reduction + will be applied, ``mean``: the sum of the output will be divided + by the number of elements in the output, ``sum``: the output will + be summed. Note: ``size_average`` and ``reduce`` are in the process of being deprecated, and in the meantime, specifying either of - those two args will override :attr:`reduction`. Default: ``'mean'``. + those two args will override ``reduction``. Default: ``mean``. """ super().__init__(reduction=reduction, size_average=None, reduce=None) @abstractmethod - def forward(self): + def forward(self, input, target): + """Forward method for loss function. + + :param torch.Tensor input: Input tensor from real data. + :param torch.Tensor target: Model tensor output. + :return: Loss evaluation. + :rtype: torch.Tensor + """ pass def _reduction(self, loss): """Simple helper function to check reduction :param reduction: Specifies the reduction to apply to the output: - ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction - will be applied, ``'mean'``: the sum of the output will be divided - by the number of elements in the output, ``'sum'``: the output will - be summed. Note: :attr:`size_average` and :attr:`reduce` are in the + ``none`` | ``mean`` | ``sum``. When ``none``: no reduction + will be applied, ``mean``: the sum of the output will be divided + by the number of elements in the output, ``sum``: the output will + be summed. Note: ``size_average`` and ``reduce`` are in the process of being deprecated, and in the meantime, specifying either of - those two args will override :attr:`reduction`. Default: ``'mean'``. - :type reduction: str, optional + those two args will override ``reduction``. Default: ``mean``. + :type reduction: str :param loss: Loss tensor for each element. :type loss: torch.Tensor :return: Reduced loss. @@ -56,13 +63,14 @@ class LossInterface(_Loss, metaclass=ABCMeta): raise ValueError(self.reduction + " is not valid") return ret + class LpLoss(LossInterface): r""" The Lp loss implementation class. Creates a criterion that measures the Lp error between each element in the input :math:`x` and target :math:`y`. - The unreduced (i.e. with :attr:`reduction` set to ``none``) loss can + The unreduced (i.e. with ``reduction`` set to ``none``) loss can be described as: .. math:: @@ -75,8 +83,8 @@ class LpLoss(LossInterface): \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = \frac{ [\sum_{i=1}^{D} | x_n^i - y_n^i|^p] }{[\sum_{i=1}^{D}|y_n^i|^p]}, - where :math:`N` is the batch size. If :attr:`reduction` is not ``none`` - (default ``'mean'``), then: + where :math:`N` is the batch size. If ``reduction`` is not ``none`` + (default ``mean``), then: .. math:: \ell(x, y) = @@ -90,21 +98,20 @@ class LpLoss(LossInterface): The sum operation still operates over all the elements, and divides by :math:`n`. - The division by :math:`n` can be avoided if one sets :attr:`reduction` to ``sum``. + The division by :math:`n` can be avoided if one sets ``reduction`` to ``sum``. """ - def __init__(self, p=2, reduction = 'mean', relative = False): + def __init__(self, p=2, reduction='mean', relative=False): """ :param int p: Degree of Lp norm. It specifies the type of norm to - be calculated. See :meth:`torch.linalg.norm` ```'ord'``` to - see the possible degrees. Default 2 (euclidean norm). + be calculated. See `list of possible orders in torch linalg + `_ to + for possible degrees. Default 2 (euclidean norm). :param str reduction: Specifies the reduction to apply to the output: - ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction - will be applied, ``'mean'``: the sum of the output will be divided - by the number of elements in the output, ``'sum'``: the output will - be summed. Note: :attr:`size_average` and :attr:`reduce` are in the - process of being deprecated, and in the meantime, specifying either of - those two args will override :attr:`reduction`. Default: ``'mean'``. + ``none`` | ``mean`` | ``sum``. ``none``: no reduction + will be applied, ``mean``: the sum of the output will be divided + by the number of elements in the output, ``sum``: the output will + be summed. :param bool relative: Specifies if relative error should be computed. """ super().__init__(reduction=reduction) @@ -124,11 +131,10 @@ class LpLoss(LossInterface): :return: Loss evaluation. :rtype: torch.Tensor """ - loss = torch.linalg.norm((input-target), ord=self.p, dim=-1) + loss = torch.linalg.norm((input - target), ord=self.p, dim=-1) if self.relative: - loss = loss / torch.linalg.norm(input, ord=self.p, dim=-1) + loss = loss / torch.linalg.norm(input, ord=self.p, dim=-1) return self._reduction(loss) - class PowerLoss(LossInterface): @@ -137,7 +143,7 @@ class PowerLoss(LossInterface): the error between each element in the input :math:`x` and target :math:`y` powered to a specific integer. - The unreduced (i.e. with :attr:`reduction` set to ``none``) loss can + The unreduced (i.e. with ``reduction`` set to ``none``) loss can be described as: .. math:: @@ -150,8 +156,8 @@ class PowerLoss(LossInterface): \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = \frac{ \sum_{i=1}^{D} | x_n^i - y_n^i|^p }{\sum_{i=1}^{D}|y_n^i|^p}, - where :math:`N` is the batch size. If :attr:`reduction` is not ``none`` - (default ``'mean'``), then: + where :math:`N` is the batch size. If ``reduction`` is not ``none`` + (default ``mean``), then: .. math:: \ell(x, y) = @@ -165,27 +171,26 @@ class PowerLoss(LossInterface): The sum operation still operates over all the elements, and divides by :math:`n`. - The division by :math:`n` can be avoided if one sets :attr:`reduction` to ``sum``. + The division by :math:`n` can be avoided if one sets ``reduction`` to ``sum``. """ - def __init__(self, p=2, reduction = 'mean', relative = False): + def __init__(self, p=2, reduction='mean', relative=False): """ :param int p: Degree of Lp norm. It specifies the type of norm to - be calculated. See :meth:`torch.linalg.norm` ```'ord'``` to + be calculated. See `list of possible orders in torch linalg + `_ to see the possible degrees. Default 2 (euclidean norm). :param str reduction: Specifies the reduction to apply to the output: - ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction - will be applied, ``'mean'``: the sum of the output will be divided - by the number of elements in the output, ``'sum'``: the output will - be summed. Note: :attr:`size_average` and :attr:`reduce` are in the - process of being deprecated, and in the meantime, specifying either of - those two args will override :attr:`reduction`. Default: ``'mean'``. + ``none`` | ``mean`` | ``sum``. When ``none``: no reduction + will be applied, ``mean``: the sum of the output will be divided + by the number of elements in the output, ``sum``: the output will + be summed. :param bool relative: Specifies if relative error should be computed. """ super().__init__(reduction=reduction) # check consistency - check_consistency(p, (str,int,float)) + check_consistency(p, (str, int, float)) self.p = p check_consistency(relative, bool) self.relative = relative @@ -198,7 +203,7 @@ class PowerLoss(LossInterface): :return: Loss evaluation. :rtype: torch.Tensor """ - loss = torch.abs((input-target)).pow(self.p).mean(-1) + loss = torch.abs((input - target)).pow(self.p).mean(-1) if self.relative: - loss = loss / torch.abs(input).pow(self.p).mean(-1) - return self._reduction(loss) \ No newline at end of file + loss = loss / torch.abs(input).pow(self.p).mean(-1) + return self._reduction(loss) diff --git a/pina/meta.py b/pina/meta.py index cfd4e09..7924232 100644 --- a/pina/meta.py +++ b/pina/meta.py @@ -1,13 +1,7 @@ __all__ = [ - '__project__', - '__title__', - '__author__', - '__copyright__', - '__license__', - '__version__', - '__mail__', - '__maintainer__', - '__status__'] + '__project__', '__title__', '__author__', '__copyright__', '__license__', + '__version__', '__mail__', '__maintainer__', '__status__' +] __project__ = 'PINA' __title__ = "pina" @@ -15,8 +9,7 @@ __author__ = "PINA Contributors" __copyright__ = "Copyright 2021-2023, PINA Contributors" __license__ = "MIT" __version__ = "0.1" -__mail__ = 'demo.nicola@gmail.com, ' # TODO +__mail__ = 'demo.nicola@gmail.com, dario.coscia@sissa.it' # TODO __maintainer__ = __author__ __status__ = "Alpha" __packagename__ = "pina-mathlab" - diff --git a/pina/model/deeponet.py b/pina/model/deeponet.py index 454724c..290c877 100644 --- a/pina/model/deeponet.py +++ b/pina/model/deeponet.py @@ -17,15 +17,16 @@ class MIONet(torch.nn.Module): .. seealso:: **Original reference**: Jin, Pengzhan, Shuai Meng, and Lu Lu. - "MIONet: Learning multiple-input operators via tensor product." + *MIONet: Learning multiple-input operators via tensor product.* SIAM Journal on Scientific Computing 44.6 (2022): A3490-A351 DOI: `10.1137/22M1477751 `_ """ + def __init__(self, networks, - aggregator="*", + aggregator="*", reduction="+", scale=True, translation=True): @@ -35,28 +36,27 @@ class MIONet(torch.nn.Module): as value the list of indeces to extract from the input variable in the forward pass of the neural network. If a list of ``int`` is passed, the corresponding columns of the inner most entries are extracted. - If a list of ``str`` is passed the variables of the corresponding :class:`LabelTensor` + If a list of ``str`` is passed the variables of the corresponding :py:obj:`pina.label_tensor.LabelTensor` are extracted. The ``torch.nn.Module`` model has to take as input a - :class:`LabelTensor` or :class:`torch.Tensor`. Default implementation consist of different - branch nets and one trunk net. - :param str | callable aggregator: Aggregator to be used to aggregate + :py:obj:`pina.label_tensor.LabelTensor` or :class:`torch.Tensor`. + Default implementation consist of different branch nets and one trunk nets. + :param str or Callable aggregator: Aggregator to be used to aggregate partial results from the modules in `nets`. Partial results are - aggregated component-wise. See - :func:`pina.model.deeponet.MIONet._symbol_functions` for the - available default aggregators. - :param str | callable reduction: Reduction to be used to reduce + aggregated component-wise. Available aggregators include + sum: ``+``, product: ``*``, mean: ``mean``, min: ``min``, max: ``max``. + :param str or Callable reduction: Reduction to be used to reduce the aggregated result of the modules in `nets` to the desired output - dimension. See :py:obj:`pina.model.deeponet.MIONet._symbol_functions` - for the available default reductions. - :param bool | callable scale: Scaling the final output before returning the - forward pass, default True. - :param bool | callable translation: Translating the final output before - returning the forward pass, default True. + dimension. Available reductions include + sum: ``+``, product: ``*``, mean: ``mean``, min: ``min``, max: ``max``. + :param bool or Callable scale: Scaling the final output before returning the + forward pass, default ``True``. + :param bool or Callable translation: Translating the final output before + returning the forward pass, default ``True``. .. warning:: In the forward pass we do not check if the input is instance of - :class:`LabelTensor` or :class:`torch.Tensor`. A general rule is - that for a :class:`LabelTensor` input both list of integers and + :py:obj:`pina.label_tensor.LabelTensor` or :class:`torch.Tensor`. A general rule is + that for a :py:obj:`pina.label_tensor.LabelTensor` input both list of integers and list of strings can be passed for ``input_indeces_branch_net`` and ``input_indeces_trunk_net``. Differently, for a :class:`torch.Tensor` only a list of integers can be passed for ``input_indeces_branch_net`` @@ -133,8 +133,10 @@ class MIONet(torch.nn.Module): self._init_reduction(reduction=reduction) # scale and translation - self._scale = torch.nn.Parameter(torch.tensor([1.0])) if scale else torch.tensor([1.0]) - self._trasl = torch.nn.Parameter(torch.tensor([1.0])) if translation else torch.tensor([1.0]) + self._scale = torch.nn.Parameter(torch.tensor( + [1.0])) if scale else torch.tensor([1.0]) + self._trasl = torch.nn.Parameter(torch.tensor( + [1.0])) if translation else torch.tensor([1.0]) @staticmethod def _symbol_functions(**kwargs): @@ -149,7 +151,7 @@ class MIONet(torch.nn.Module): "min": lambda x: torch.min(x, **kwargs).values, "max": lambda x: torch.max(x, **kwargs).values, } - + def _init_aggregator(self, aggregator): aggregator_funcs = DeepONet._symbol_functions(dim=2) if aggregator in aggregator_funcs: @@ -161,7 +163,6 @@ class MIONet(torch.nn.Module): self._aggregator = aggregator_func - def _init_reduction(self, reduction): reduction_funcs = DeepONet._symbol_functions(dim=-1) if reduction in reduction_funcs: @@ -178,27 +179,32 @@ class MIONet(torch.nn.Module): try: return x.extract(indeces) except AttributeError: - raise RuntimeError('Not possible to extract input variables from tensor.' - ' Ensure that the passed tensor is a LabelTensor or' - ' pass list of integers to extract variables. For' - ' more information refer to warning in the documentation.') + raise RuntimeError( + 'Not possible to extract input variables from tensor.' + ' Ensure that the passed tensor is a LabelTensor or' + ' pass list of integers to extract variables. For' + ' more information refer to warning in the documentation.') elif isinstance(indeces[0], int): return x[..., indeces] else: - raise RuntimeError('Not able to extract right indeces for tensor.' - ' For more information refer to warning in the documentation.') - + raise RuntimeError( + 'Not able to extract right indeces for tensor.' + ' For more information refer to warning in the documentation.') + def forward(self, x): """ Defines the computation performed at every call. - :param LabelTensor | torch.Tensor x: The input tensor for the forward call. + :param LabelTensor or torch.Tensor x: The input tensor for the forward call. :return: The output computed by the DeepONet model. - :rtype: LabelTensor | torch.Tensor + :rtype: LabelTensor or torch.Tensor """ # forward pass - output_ = [model(self._get_vars(x, indeces)) for model, indeces in zip(self.models, self._indeces)] + output_ = [ + model(self._get_vars(x, indeces)) + for model, indeces in zip(self.models, self._indeces) + ] # aggregation aggregated = self._aggregator(torch.dstack(output_)) @@ -206,7 +212,7 @@ class MIONet(torch.nn.Module): # reduce output_ = self._reduction(aggregated).reshape(-1, 1) - # scale and translate + # scale and translate output_ *= self._scale output_ += self._trasl @@ -218,7 +224,7 @@ class MIONet(torch.nn.Module): The aggregator function. """ return self._aggregator - + @property def reduction(self): """ @@ -232,28 +238,28 @@ class MIONet(torch.nn.Module): The scale factor. """ return self._scale - + @property def translation(self): """ The translation factor for MIONet. """ return self._trasl - + @property def indeces_variables_extracted(self): """ The input indeces for each model in form of list. """ return self._indeces - + @property def model(self): """ The models in form of list. """ return self._indeces - + class DeepONet(MIONet): """ @@ -273,52 +279,52 @@ class DeepONet(MIONet): `_ """ + def __init__(self, branch_net, trunk_net, input_indeces_branch_net, input_indeces_trunk_net, - aggregator="*", + aggregator="*", reduction="+", scale=True, translation=True): """ :param torch.nn.Module branch_net: The neural network to use as branch - model. It has to take as input a :class:`LabelTensor` + model. It has to take as input a :py:obj:`pina.label_tensor.LabelTensor` or :class:`torch.Tensor`. The number of dimensions of the output has to be the same of the ``trunk_net``. :param torch.nn.Module trunk_net: The neural network to use as trunk - model. It has to take as input a :class:`LabelTensor` + model. It has to take as input a :py:obj:`pina.label_tensor.LabelTensor` or :class:`torch.Tensor`. The number of dimensions of the output has to be the same of the ``branch_net``. - :param list(int) | list(str) input_indeces_branch_net: List of indeces + :param list(int) or list(str) input_indeces_branch_net: List of indeces to extract from the input variable in the forward pass for the branch net. If a list of ``int`` is passed, the corresponding columns of the inner most entries are extracted. If a list of ``str`` is passed - the variables of the corresponding :class:`LabelTensor` are extracted. - :param list(int) | list(str) input_indeces_trunk_net: List of indeces + the variables of the corresponding :py:obj:`pina.label_tensor.LabelTensor` are extracted. + :param list(int) or list(str) input_indeces_trunk_net: List of indeces to extract from the input variable in the forward pass for the trunk net. If a list of ``int`` is passed, the corresponding columns of the inner most entries are extracted. If a list of ``str`` is passed - the variables of the corresponding :class:`LabelTensor` are extracted. - :param str | callable aggregator: Aggregator to be used to aggregate + the variables of the corresponding :py:obj:`pina.label_tensor.LabelTensor` are extracted. + :param str or Callable aggregator: Aggregator to be used to aggregate partial results from the modules in `nets`. Partial results are - aggregated component-wise. See - :func:`pina.model.deeponet.MIONet._symbol_functions` for the - available default aggregators. - :param str | callable reduction: Reduction to be used to reduce + aggregated component-wise. Available aggregators include + sum: ``+``, product: ``*``, mean: ``mean``, min: ``min``, max: ``max``. + :param str or Callable reduction: Reduction to be used to reduce the aggregated result of the modules in `nets` to the desired output - dimension. See :py:obj:`pina.model.deeponet.MIONet._symbol_functions` for the available default - reductions. - :param bool | callable scale: Scaling the final output before returning the + dimension. Available reductions include + sum: ``+``, product: ``*``, mean: ``mean``, min: ``min``, max: ``max``. + :param bool or Callable scale: Scaling the final output before returning the forward pass, default True. - :param bool | callable translation: Translating the final output before + :param bool or Callable translation: Translating the final output before returning the forward pass, default True. .. warning:: In the forward pass we do not check if the input is instance of - :class:`LabelTensor` or :class:`torch.Tensor`. A general rule is - that for a :class:`LabelTensor` input both list of integers and + :py:obj:`pina.label_tensor.LabelTensor` or :class:`torch.Tensor`. A general rule is + that for a :py:obj:`pina.label_tensor.LabelTensor` input both list of integers and list of strings can be passed for ``input_indeces_branch_net`` and ``input_indeces_trunk_net``. Differently, for a :class:`torch.Tensor` only a list of integers can be passed for ``input_indeces_branch_net`` @@ -355,24 +361,38 @@ class DeepONet(MIONet): ) ) """ - networks = {branch_net : input_indeces_branch_net, - trunk_net : input_indeces_trunk_net} + networks = { + branch_net: input_indeces_branch_net, + trunk_net: input_indeces_trunk_net + } super().__init__(networks=networks, aggregator=aggregator, reduction=reduction, scale=scale, translation=translation) - @property - def branch_net(self): - """ - The branch net for DeepONet. - """ - return self.models[0] - - @property - def trunk_net(self): - """ - The trunk net for DeepONet. - """ - return self.models[1] \ No newline at end of file + + def forward(self, x): + """ + Defines the computation performed at every call. + + :param LabelTensor or torch.Tensor x: The input tensor for the forward call. + :return: The output computed by the DeepONet model. + :rtype: LabelTensor or torch.Tensor + """ + return super().forward(x) + + + @property + def branch_net(self): + """ + The branch net for DeepONet. + """ + return self.models[0] + + @property + def trunk_net(self): + """ + The trunk net for DeepONet. + """ + return self.models[1] diff --git a/pina/model/feed_forward.py b/pina/model/feed_forward.py index 3ad75d9..63d9bb2 100644 --- a/pina/model/feed_forward.py +++ b/pina/model/feed_forward.py @@ -11,11 +11,11 @@ class FeedForward(torch.nn.Module): perceptron. :param int input_dimensions: The number of input components of the model. - Expected tensor shape of the form (*, input_dimensions), where * - means any number of dimensions including none. + Expected tensor shape of the form :math:`(*, d)`, where * + means any number of dimensions including none, and :math:`d` the ``input_dimensions``. :param int output_dimensions: The number of output components of the model. - Expected tensor shape of the form (*, output_dimensions), where * - means any number of dimensions including none. + Expected tensor shape of the form :math:`(*, d)`, where * + means any number of dimensions including none, and :math:`d` the ``output_dimensions``. :param int inner_size: number of neurons in the hidden layer(s). Default is 20. :param int n_layers: number of hidden layers. Default is 2. @@ -23,18 +23,24 @@ class FeedForward(torch.nn.Module): :class:`torch.nn.Module` is passed, this is used as activation function after any layers, except the last one. If a list of Modules is passed, they are used as activation functions at any layers, in order. - :param iterable(int) layers: a list containing the number of neurons for - any hidden layers. If specified, the parameters `n_layers` e - `inner_size` are not considered. - :param bool bias: If `True` the MLP will consider some bias. + :param list(int) | tuple(int) layers: a list containing the number of neurons for + any hidden layers. If specified, the parameters ``n_layers`` e + ``inner_size`` are not considered. + :param bool bias: If ``True`` the MLP will consider some bias. """ - def __init__(self, input_dimensions, output_dimensions, inner_size=20, - n_layers=2, func=nn.Tanh, layers=None, bias=True): + + def __init__(self, + input_dimensions, + output_dimensions, + inner_size=20, + n_layers=2, + func=nn.Tanh, + layers=None, + bias=True): """ """ super().__init__() - if not isinstance(input_dimensions, int): raise ValueError('input_dimensions expected to be int.') self.input_dimension = input_dimensions @@ -52,8 +58,7 @@ class FeedForward(torch.nn.Module): self.layers = [] for i in range(len(tmp_layers) - 1): self.layers.append( - nn.Linear(tmp_layers[i], tmp_layers[i + 1], bias=bias) - ) + nn.Linear(tmp_layers[i], tmp_layers[i + 1], bias=bias)) if isinstance(func, list): self.functions = func @@ -76,10 +81,10 @@ class FeedForward(torch.nn.Module): """ Defines the computation performed at every call. - :param x: . - :type x: :class:`pina.LabelTensor` + :param x: The tensor to apply the forward pass. + :type x: torch.Tensor :return: the output computed by the model. - :rtype: LabelTensor + :rtype: torch.Tensor """ return self.model(x) @@ -93,18 +98,18 @@ class ResidualFeedForward(torch.nn.Module): .. seealso:: **Original reference**: Wang, Sifan, Yujun Teng, and Paris Perdikaris. - "Understanding and mitigating gradient flow pathologies in physics-informed - neural networks." SIAM Journal on Scientific Computing 43.5 (2021): A3055-A3081. + *Understanding and mitigating gradient flow pathologies in physics-informed + neural networks*. SIAM Journal on Scientific Computing 43.5 (2021): A3055-A3081. DOI: `10.1137/20M1318043 `_ :param int input_dimensions: The number of input components of the model. - Expected tensor shape of the form (*, input_dimensions), where * - means any number of dimensions including none. + Expected tensor shape of the form :math:`(*, d)`, where * + means any number of dimensions including none, and :math:`d` the ``input_dimensions``. :param int output_dimensions: The number of output components of the model. - Expected tensor shape of the form (*, output_dimensions), where * - means any number of dimensions including none. + Expected tensor shape of the form :math:`(*, d)`, where * + means any number of dimensions including none, and :math:`d` the ``output_dimensions``. :param int inner_size: number of neurons in the hidden layer(s). Default is 20. :param int n_layers: number of hidden layers. Default is 2. @@ -112,14 +117,21 @@ class ResidualFeedForward(torch.nn.Module): :class:`torch.nn.Module` is passed, this is used as activation function after any layers, except the last one. If a list of Modules is passed, they are used as activation functions at any layers, in order. - :param bool bias: If `True` the MLP will consider some bias. + :param bool bias: If ``True`` the MLP will consider some bias. :param list | tuple transformer_nets: a list or tuple containing the two torch.nn.Module which act as transformer network. The input dimension of the network must be the same as ``input_dimensions``, and the output dimension must be the same as ``inner_size``. """ - def __init__(self, input_dimensions, output_dimensions, inner_size=20, - n_layers=2, func=nn.Tanh, bias=True, transformer_nets=None): + + def __init__(self, + input_dimensions, + output_dimensions, + inner_size=20, + n_layers=2, + func=nn.Tanh, + bias=True, + transformer_nets=None): """ """ super().__init__() @@ -135,26 +147,37 @@ class ResidualFeedForward(torch.nn.Module): # check transformer nets if transformer_nets is None: transformer_nets = [ - EnhancedLinear(nn.Linear(in_features=input_dimensions, out_features=inner_size), - nn.Tanh()), - EnhancedLinear(nn.Linear(in_features=input_dimensions, out_features=inner_size), - nn.Tanh()) - ] + EnhancedLinear( + nn.Linear(in_features=input_dimensions, + out_features=inner_size), nn.Tanh()), + EnhancedLinear( + nn.Linear(in_features=input_dimensions, + out_features=inner_size), nn.Tanh()) + ] elif isinstance(transformer_nets, (list, tuple)): if len(transformer_nets) != 2: - raise ValueError('transformer_nets needs to be a list of len two.') + raise ValueError( + 'transformer_nets needs to be a list of len two.') for net in transformer_nets: if not isinstance(net, nn.Module): - raise ValueError('transformer_nets needs to be a list of torch.nn.Module.') + raise ValueError( + 'transformer_nets needs to be a list of torch.nn.Module.' + ) x = torch.rand(10, input_dimensions) try: out = net(x) except RuntimeError: - raise ValueError('transformer network input incompatible with input_dimensions.') + raise ValueError( + 'transformer network input incompatible with input_dimensions.' + ) if out.shape[-1] != inner_size: - raise ValueError('transformer network output incompatible with inner_size.') + raise ValueError( + 'transformer network output incompatible with inner_size.' + ) else: - RuntimeError('Runtime error for transformer nets, check official documentation.') + RuntimeError( + 'Runtime error for transformer nets, check official documentation.' + ) # assign variables self.input_dimension = input_dimensions @@ -170,9 +193,10 @@ class ResidualFeedForward(torch.nn.Module): self.layers = [] for i in range(len(tmp_layers) - 1): self.layers.append( - nn.Linear(tmp_layers[i], tmp_layers[i + 1], bias=bias) - ) - self.last_layer = nn.Linear(tmp_layers[len(tmp_layers) - 1], output_dimensions, bias=bias) + nn.Linear(tmp_layers[i], tmp_layers[i + 1], bias=bias)) + self.last_layer = nn.Linear(tmp_layers[len(tmp_layers) - 1], + output_dimensions, + bias=bias) if isinstance(func, list): self.functions = func() @@ -184,28 +208,27 @@ class ResidualFeedForward(torch.nn.Module): unique_list = [] for layer, func in zip(self.layers, self.functions): - unique_list.append(EnhancedLinear(layer=layer, - activation=func)) + unique_list.append(EnhancedLinear(layer=layer, activation=func)) self.inner_layers = torch.nn.Sequential(*unique_list) - + def forward(self, x): """ Defines the computation performed at every call. - :param x: . - :type x: :class:`pina.LabelTensor` + :param x: The tensor to apply the forward pass. + :type x: torch.Tensor :return: the output computed by the model. - :rtype: LabelTensor + :rtype: torch.Tensor """ # enhance the input with transformer input_ = [] for nets in self.transformer_nets: input_.append(nets(x)) - + # skip connections pass for layer in self.inner_layers.children(): x = layer(x) x = (1. - x) * input_[0] + x * input_[1] # last layer - return self.last_layer(x) \ No newline at end of file + return self.last_layer(x) diff --git a/pina/model/fno.py b/pina/model/fno.py index 9e70066..6384a65 100644 --- a/pina/model/fno.py +++ b/pina/model/fno.py @@ -17,22 +17,23 @@ class FNO(torch.nn.Module): .. seealso:: **Original reference**: Li, Z., Kovachki, N., Azizzadenesheli, K., Liu, B., - Bhattacharya, K., Stuart, A., & Anandkumar, A. (2020). "Fourier neural operator for - parametric partial differential equations". + Bhattacharya, K., Stuart, A., & Anandkumar, A. (2020). *Fourier neural operator for + parametric partial differential equations*. DOI: `arXiv preprint arXiv:2010.08895. `_ """ + def __init__(self, - lifting_net, + lifting_net, projecting_net, n_modes, - dimensions = 3, - padding = 8, - padding_type = "constant", - inner_size = 20, - n_layers = 2, - func = nn.Tanh, - layers = None): + dimensions=3, + padding=8, + padding_type="constant", + inner_size=20, + n_layers=2, + func=nn.Tanh, + layers=None): super().__init__() # check type consistency @@ -50,10 +51,11 @@ class FNO(torch.nn.Module): else: raise ValueError('layers must be tuple or list of int.') if not isinstance(n_modes, (list, tuple, int)): - raise ValueError('n_modes must be a int or list or tuple of valid modes.' - ' More information on the official documentation.') - - # assign variables + raise ValueError( + 'n_modes must be a int or list or tuple of valid modes.' + ' More information on the official documentation.') + + # assign variables # TODO check input lifting net and input projecting net self._lifting_net = lifting_net self._projecting_net = projecting_net @@ -78,15 +80,18 @@ class FNO(torch.nn.Module): # 2. Assign activation functions for each FNO layer if isinstance(func, list): if len(layers) != len(func): - raise RuntimeError('Uncosistent number of layers and functions.') + raise RuntimeError( + 'Uncosistent number of layers and functions.') self._functions = func else: self._functions = [func for _ in range(len(layers))] # 3. Assign modes functions for each FNO layer if isinstance(n_modes, list): - if all(isinstance(i, list) for i in n_modes) and len(layers) != len(n_modes): - raise RuntimeError('Uncosistent number of layers and functions.') + if all(isinstance(i, list) + for i in n_modes) and len(layers) != len(n_modes): + raise RuntimeError( + 'Uncosistent number of layers and functions.') elif all(isinstance(i, int) for i in n_modes): n_modes = [n_modes] * len(layers) else: @@ -105,8 +110,7 @@ class FNO(torch.nn.Module): fourier_layer(input_numb_fields=tmp_layers[i], output_numb_fields=tmp_layers[i + 1], n_modes=n_modes[i], - activation=self._functions[i]) - ) + activation=self._functions[i])) self._layers = nn.Sequential(*self._layers) # 5. Padding values for spectral conv @@ -114,9 +118,9 @@ class FNO(torch.nn.Module): padding = [padding] * dimensions self._ipad = [-pad if pad > 0 else None for pad in padding[:dimensions]] self._padding_type = padding_type - self._pad = [val for pair in zip([0]*dimensions, padding) for val in pair] - - + self._pad = [ + val for pair in zip([0] * dimensions, padding) for val in pair + ] def forward(self, x): """ @@ -136,9 +140,9 @@ class FNO(torch.nn.Module): # lifting the input in higher dimensional space x = self._lifting_net(x) - + # permuting the input [batch, channels, x, y, ...] - permutation_idx = [0, x.ndim-1, *[i for i in range(1, x.ndim-1)]] + permutation_idx = [0, x.ndim - 1, *[i for i in range(1, x.ndim - 1)]] x = x.permute(permutation_idx) # padding the input @@ -148,7 +152,7 @@ class FNO(torch.nn.Module): x = self._layers(x) # remove padding - idxs = [slice(None), slice(None)] + [slice(pad) for pad in self._ipad] + idxs = [slice(None), slice(None)] + [slice(pad) for pad in self._ipad] x = x[idxs] # permuting back [batch, x, y, ..., channels] diff --git a/pina/model/layers/convolution.py b/pina/model/layers/convolution.py index 0539dcd..3b9fdcd 100644 --- a/pina/model/layers/convolution.py +++ b/pina/model/layers/convolution.py @@ -10,10 +10,16 @@ class BaseContinuousConv(torch.nn.Module, metaclass=ABCMeta): Abstract class """ - def __init__(self, input_numb_field, output_numb_field, - filter_dim, stride, model=None, optimize=False, + def __init__(self, + input_numb_field, + output_numb_field, + filter_dim, + stride, + model=None, + optimize=False, no_overlap=False): - """Base Class for Continuous Convolution. + """ + Base Class for Continuous Convolution. The algorithm expects input to be in the form: $$[B \times N_{in} \times N \times D]$$ @@ -50,7 +56,7 @@ class BaseContinuousConv(torch.nn.Module, metaclass=ABCMeta): :param stride: stride for the filter :type stride: dict :param model: neural network for inner parametrization, - defaults to None + defaults to None. :type model: torch.nn.Module, optional :param optimize: flag for performing optimization on the continuous filter, defaults to False. The flag `optimize=True` should be @@ -114,37 +120,37 @@ class BaseContinuousConv(torch.nn.Module, metaclass=ABCMeta): self.transpose = self.transpose_overlap class DefaultKernel(torch.nn.Module): + def __init__(self, input_dim, output_dim): super().__init__() assert isinstance(input_dim, int) assert isinstance(output_dim, int) - self._model = torch.nn.Sequential( - torch.nn.Linear(input_dim, 20), - torch.nn.ReLU(), - torch.nn.Linear(20, 20), - torch.nn.ReLU(), - torch.nn.Linear(20, output_dim) - ) + self._model = torch.nn.Sequential(torch.nn.Linear(input_dim, 20), + torch.nn.ReLU(), + torch.nn.Linear(20, 20), + torch.nn.ReLU(), + torch.nn.Linear(20, output_dim)) + def forward(self, x): return self._model(x) - @ property + @property def net(self): return self._net - @ property + @property def stride(self): return self._stride - @ property + @property def filter_dim(self): return self._dim - @ property + @property def input_numb_field(self): return self._input_numb_field - @ property + @property def output_numb_field(self): return self._output_numb_field diff --git a/pina/model/layers/convolution_2d.py b/pina/model/layers/convolution_2d.py index 86677d1..4668796 100644 --- a/pina/model/layers/convolution_2d.py +++ b/pina/model/layers/convolution_2d.py @@ -9,76 +9,66 @@ class ContinuousConvBlock(BaseContinuousConv): """ Implementation of Continuous Convolutional operator. + The algorithm expects input to be in the form: + :math:`[B, N_{in}, N, D]` + where :math:`B` is the batch_size, :math:`N_{in}` is the number of input + fields, :math:`N` the number of points in the mesh, :math:`D` the dimension + of the problem. In particular: + + * :math:`D` is the number of spatial variables + 1. The last column must + contain the field value. For example for 2D problems :math:`D=3` and + the tensor will be something like ``[first coordinate, second + coordinate, field value]``. + * :math:`N_{in}` represents the number of vectorial function presented. + For example a vectorial function :math:`f = [f_1, f_2]` will have + :math:`N_{in}=2`. + .. seealso:: - **Original reference**: Coscia, D., Meneghetti, L., Demo, N., - Stabile, G., & Rozza, G.. (2022). A Continuous Convolutional Trainable - Filter for Modelling Unstructured Data. - DOI: `10.48550/arXiv.2210.13416 - `_. + **Original reference**: Coscia, D., Meneghetti, L., Demo, N. et al. + *A continuous convolutional trainable filter for modelling unstructured data*. + Comput Mech 72, 253–265 (2023). DOI ``_ """ - def __init__(self, input_numb_field, output_numb_field, - filter_dim, stride, model=None, optimize=False, + def __init__(self, + input_numb_field, + output_numb_field, + filter_dim, + stride, + model=None, + optimize=False, no_overlap=False): """ - - :param input_numb_field: Number of fields N_in in the input. + :param input_numb_field: Number of fields :math:`N_{in}` in the input. :type input_numb_field: int - :param output_numb_field: Number of fields N_out in the output. + :param output_numb_field: Number of fields :math:`N_{out}` in the output. :type output_numb_field: int :param filter_dim: Dimension of the filter. - :type filter_dim: tuple/ list + :type filter_dim: tuple(int) | list(int) :param stride: Stride for the filter. :type stride: dict :param model: Neural network for inner parametrization, - defaults to None. If None, a default multilayer perceptron - is used, see BaseContinuousConv.DefaultKernel. - :type model: torch.nn.Module, optional + defaults to ``None``. If None, a default multilayer perceptron + of width three and size twenty with ReLU activation is used. + :type model: torch.nn.Module :param optimize: Flag for performing optimization on the continuous filter, defaults to False. The flag `optimize=True` should be used only when the scatter datapoints are fixed through the - training. If torch model is in `.eval()` mode, the flag is + training. If torch model is in ``.eval()`` mode, the flag is automatically set to False always. - :type optimize: bool, optional + :type optimize: bool :param no_overlap: Flag for performing optimization on the transpose continuous filter, defaults to False. The flag set to `True` should be used only when the filter positions do not overlap for different strides. RuntimeError will raise in case of non-compatible strides. - :type no_overlap: bool, optional + :type no_overlap: bool .. note:: Using `optimize=True` the filter can be use either in `forward` or in `transpose` mode, not both. If `optimize=False` the same filter can be used for both `transpose` and `forward` modes. - .. warning:: - The algorithm expects input to be in the form: [B x N_in x N x D] - where B is the batch_size, N_in is the number of input - fields, N the number of points in the mesh, D the dimension - of the problem. In particular: - - * D is the number of spatial variables + 1. The last column must - contain the field value. For example for 2D problems D=3 and - the tensor will be something like `[first coordinate, second - coordinate, field value]`. - - * N_in represents the number of vectorial function presented. - For example a vectorial function f = [f_1, f_2] will have - N_in=2. - - The algorithm returns a tensor of shape: [B x N_out x N x D] - where B is the batch_size, N_out is the number of output - fields, N' the number of points in the mesh, D the dimension - of the problem (coordinates + field value). - - For example, a 2-dimensional vectorial function N_in=2 of - 3-dimensionalcinput D=3+1=4 with 100 points input mesh and batch - size of 8 is represented as a tensor `[8, 2, 100, 4]`, where the - columnsc`[:, 0, :, -1]` and `[:, 1, :, -1]` represent the first and - second filed value respectively. - :Example: >>> class MLP(torch.nn.Module): def __init__(self) -> None: @@ -140,11 +130,12 @@ class ContinuousConvBlock(BaseContinuousConv): self._stride = self._stride._stride_discrete def _spawn_networks(self, model): - """Private method to create a collection of kernels + """ + Private method to create a collection of kernels - :param model: a torch.nn.Module model in form of Object class + :param model: A :class:`torch.nn.Module` model in form of Object class. :type model: torch.nn.Module - :return: list of torch.nn.Module models + :return: List of :class:`torch.nn.Module` models. :rtype: torch.nn.ModuleList """ @@ -169,12 +160,13 @@ class ContinuousConvBlock(BaseContinuousConv): return torch.nn.ModuleList(nets) def _extract_mapped_points(self, batch_idx, index, x): - """Priviate method to extract mapped points in the filter + """ + Priviate method to extract mapped points in the filter - :param x: input tensor [channel x N x dim] - :type x: torch.tensor - :return: mapped points and indeces for each channel - :rtype: tuple(torch.tensor, list) + :param x: Input tensor of shape ``[channel, N, dim]`` + :type x: torch.Tensor + :return: Mapped points and indeces for each channel, + :rtype: torch.Tensor, list """ mapped_points = [] @@ -210,10 +202,11 @@ class ContinuousConvBlock(BaseContinuousConv): return stacked_input, indeces_channels def _find_index(self, X): - """Private method to extract indeces for convolution. + """ + Private method to extract indeces for convolution. - :param X: input tensor, as in ContinuousConv2D docstring - :type X: torch.tensor + :param X: Input tensor, as in ContinuousConvBlock ``__init__``. + :type X: torch.Tensor """ # append the index for each stride @@ -227,10 +220,11 @@ class ContinuousConvBlock(BaseContinuousConv): self._index = index def _make_grid_forward(self, X): - """Private method to create forward convolution grid. + """ + Private method to create forward convolution grid. - :param X: input tensor, as in ContinuousConv2D docstring - :type X: torch.tensor + :param X: Input tensor, as in ContinuousConvBlock docstring. + :type X: torch.Tensor """ # filter dimension + number of points in output grid @@ -238,10 +232,8 @@ class ContinuousConvBlock(BaseContinuousConv): number_points = len(self._stride) # initialize the grid - grid = torch.zeros(size=(X.shape[0], - self._output_numb_field, - number_points, - filter_dim + 1), + grid = torch.zeros(size=(X.shape[0], self._output_numb_field, + number_points, filter_dim + 1), device=X.device, dtype=X.dtype) grid[..., :-1] = (self._stride + self._dim * 0.5) @@ -250,10 +242,12 @@ class ContinuousConvBlock(BaseContinuousConv): self._grid = grid.detach() def _make_grid_transpose(self, X): - """Private method to create transpose convolution grid. + """ + Private method to create transpose convolution grid. + + :param X: Input tensor, as in ContinuousConvBlock docstring. + :type X: torch.Tensor - :param X: input tensor, as in ContinuousConv2D docstring - :type X: torch.tensor """ # initialize to all zeros @@ -264,13 +258,14 @@ class ContinuousConvBlock(BaseContinuousConv): self._grid_transpose = tmp def _make_grid(self, X, type): - """Private method to create convolution grid. + """ + Private method to create convolution grid. - :param X: input tensor, as in ContinuousConv2D docstring - :type X: torch.tensor - :param type: type of convolution, ['forward', 'inverse'] the - possibilities - :type type: string + :param X: Input tensor, as in ContinuousConvBlock docstring. + :type X: torch.Tensor + :param type: Type of convolution, ``['forward', 'inverse']`` the + possibilities. + :type type: str """ # choose the type of convolution @@ -282,16 +277,16 @@ class ContinuousConvBlock(BaseContinuousConv): raise TypeError def _initialize_convolution(self, X, type='forward'): - """Private method to intialize the convolution. + """ + Private method to intialize the convolution. The convolution is initialized by setting a grid and calculate the index for finding the points inside the filter. - :param X: input tensor, as in ContinuousConv2D docstring - :type X: torch.tensor - :param type: type of convolution, ['forward', 'inverse'] the - possibilities - :type type: string + :param X: Input tensor, as in ContinuousConvBlock docstring. + :type X: torch.Tensor + :param str type: type of convolution, ``['forward', 'inverse'] ``the + possibilities. """ # variable for the convolution @@ -301,12 +296,13 @@ class ContinuousConvBlock(BaseContinuousConv): self._find_index(X) def forward(self, X): - """Forward pass in the layer + """ + Forward pass in the convolutional layer. - :param x: input data (input_numb_field x N x filter_dim) - :type x: torch.tensor - :return: feed forward convolution (output_numb_field x N x filter_dim) - :rtype: torch.tensor + :param x: Input data for the convolution :math:`[B, N_{in}, N, D]`. + :type x: torch.Tensor + :return: Convolution output :math:`[B, N_{out}, N, D]`. + :rtype: torch.Tensor """ # initialize convolution @@ -353,34 +349,35 @@ class ContinuousConvBlock(BaseContinuousConv): # sum filters (for each input fields) in groups # for different ouput fields - conv[batch_idx, ..., -1] = res_tmp.reshape(self._output_numb_field, - self._input_numb_field, - -1).sum(1) + conv[batch_idx, ..., + -1] = res_tmp.reshape(self._output_numb_field, + self._input_numb_field, -1).sum(1) return conv def transpose_no_overlap(self, integrals, X): - """Transpose pass in the layer for no-overlapping filters + """ + Transpose pass in the layer for no-overlapping filters :param integrals: Weights for the transpose convolution. Shape - [B x N_in x N] - where B is the batch_size, N_in is the number of input - fields, N the number of points in the mesh, D the dimension + :math:`[B, N_{in}, N]` + where B is the batch_size, :math`N_{in}` is the number of input + fields, :math:`N` the number of points in the mesh, D the dimension of the problem. :type integral: torch.tensor :param X: Input data. Expect tensor of shape - [B x N_in x M x D] where B is the batch_size, - N_in is the number of input fields, M the number of points - in the mesh, D the dimension of the problem. Note, last column - :type X: torch.tensor + :math:`[B, N_{in}, M, D]` where :math:`B` is the batch_size, + :math`N_{in}`is the number of input fields, :math:`M` the number of points + in the mesh, :math:`D` the dimension of the problem. + :type X: torch.Tensor :return: Feed forward transpose convolution. Tensor of shape - [B x N_out x N] where B is the batch_size, - N_out is the number of output fields, N the number of points - in the mesh, D the dimension of the problem. - :rtype: torch.tensor + :math:`[B, N_{out}, M, D]` where :math:`B` is the batch_size, + :math`N_{out}`is the number of input fields, :math:`M` the number of points + in the mesh, :math:`D` the dimension of the problem. + :rtype: torch.Tensor .. note:: - This function is automatically called when `.transpose()` - method is used and `no_overlap=True` + This function is automatically called when ``.transpose()`` + method is used and ``no_overlap=True`` """ # initialize convolution @@ -437,27 +434,28 @@ class ContinuousConvBlock(BaseContinuousConv): return conv_transposed def transpose_overlap(self, integrals, X): - """Transpose pass in the layer for overlapping filters + """ + Transpose pass in the layer for overlapping filters :param integrals: Weights for the transpose convolution. Shape - [B x N_in x N] - where B is the batch_size, N_in is the number of input - fields, N the number of points in the mesh, D the dimension + :math:`[B, N_{in}, N]` + where B is the batch_size, :math`N_{in}` is the number of input + fields, :math:`N` the number of points in the mesh, D the dimension of the problem. :type integral: torch.tensor :param X: Input data. Expect tensor of shape - [B x N_in x M x D] where B is the batch_size, - N_in is the number of input fields, M the number of points - in the mesh, D the dimension of the problem. Note, last column - :type X: torch.tensor + :math:`[B, N_{in}, M, D]` where :math:`B` is the batch_size, + :math`N_{in}`is the number of input fields, :math:`M` the number of points + in the mesh, :math:`D` the dimension of the problem. + :type X: torch.Tensor :return: Feed forward transpose convolution. Tensor of shape - [B x N_out x N] where B is the batch_size, - N_out is the number of output fields, N the number of points - in the mesh, D the dimension of the problem. - :rtype: torch.tensor + :math:`[B, N_{out}, M, D]` where :math:`B` is the batch_size, + :math`N_{out}`is the number of input fields, :math:`M` the number of points + in the mesh, :math:`D` the dimension of the problem. + :rtype: torch.Tensor - .. note:: This function is automatically called when `.transpose()` - method is used and `no_overlap=False` + .. note:: This function is automatically called when ``.transpose()`` + method is used and ``no_overlap=False`` """ # initialize convolution @@ -473,8 +471,9 @@ class ContinuousConvBlock(BaseContinuousConv): # list to iterate for calculating nn output tmp = [i for i in range(self._output_numb_field)] - iterate_conv = [item for item in tmp for _ in range( - self._input_numb_field)] + iterate_conv = [ + item for item in tmp for _ in range(self._input_numb_field) + ] for batch_idx, x in enumerate(X): diff --git a/pina/model/layers/fourier.py b/pina/model/layers/fourier.py index 4333276..ef9e76a 100644 --- a/pina/model/layers/fourier.py +++ b/pina/model/layers/fourier.py @@ -13,14 +13,19 @@ class FourierBlock1D(nn.Module): .. seealso:: - **Original reference**: Li, Zongyi, et al. - "Fourier neural operator for parametric partial - differential equations." arXiv preprint - arXiv:2010.08895 (2020) - `_. + **Original reference**: Li, Z., Kovachki, N., Azizzadenesheli, K., Liu, B., + Bhattacharya, K., Stuart, A., & Anandkumar, A. (2020). *Fourier neural operator for + parametric partial differential equations*. + DOI: `arXiv preprint arXiv:2010.08895. + `_ """ - def __init__(self, input_numb_fields, output_numb_fields, n_modes, activation=torch.nn.Tanh): + + def __init__(self, + input_numb_fields, + output_numb_fields, + n_modes, + activation=torch.nn.Tanh): super().__init__() """ PINA implementation of Fourier block one dimension. The module computes @@ -43,12 +48,13 @@ class FourierBlock1D(nn.Module): check_consistency(activation(), nn.Module) # assign variables - self._spectral_conv = SpectralConvBlock1D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=n_modes) + self._spectral_conv = SpectralConvBlock1D( + input_numb_fields=input_numb_fields, + output_numb_fields=output_numb_fields, + n_modes=n_modes) self._activation = activation() self._linear = nn.Conv1d(input_numb_fields, output_numb_fields, 1) - + def forward(self, x): """ Forward computation for Fourier Block. It performs a spectral @@ -74,13 +80,18 @@ class FourierBlock2D(nn.Module): .. seealso:: **Original reference**: Li, Zongyi, et al. - "Fourier neural operator for parametric partial - differential equations." arXiv preprint + *Fourier neural operator for parametric partial + differential equations*. arXiv preprint arXiv:2010.08895 (2020) `_. """ - def __init__(self, input_numb_fields, output_numb_fields, n_modes, activation=torch.nn.Tanh): + + def __init__(self, + input_numb_fields, + output_numb_fields, + n_modes, + activation=torch.nn.Tanh): """ PINA implementation of Fourier block two dimensions. The module computes the spectral convolution of the input with a linear kernel in the @@ -104,12 +115,13 @@ class FourierBlock2D(nn.Module): check_consistency(activation(), nn.Module) # assign variables - self._spectral_conv = SpectralConvBlock2D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=n_modes) + self._spectral_conv = SpectralConvBlock2D( + input_numb_fields=input_numb_fields, + output_numb_fields=output_numb_fields, + n_modes=n_modes) self._activation = activation() self._linear = nn.Conv2d(input_numb_fields, output_numb_fields, 1) - + def forward(self, x): """ Forward computation for Fourier Block. It performs a spectral @@ -135,13 +147,18 @@ class FourierBlock3D(nn.Module): .. seealso:: **Original reference**: Li, Zongyi, et al. - "Fourier neural operator for parametric partial - differential equations." arXiv preprint + *Fourier neural operator for parametric partial + differential equations*. arXiv preprint arXiv:2010.08895 (2020) `_. """ - def __init__(self, input_numb_fields, output_numb_fields, n_modes, activation=torch.nn.Tanh): + + def __init__(self, + input_numb_fields, + output_numb_fields, + n_modes, + activation=torch.nn.Tanh): """ PINA implementation of Fourier block three dimensions. The module computes the spectral convolution of the input with a linear kernel in the @@ -166,12 +183,13 @@ class FourierBlock3D(nn.Module): check_consistency(activation(), nn.Module) # assign variables - self._spectral_conv = SpectralConvBlock3D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=n_modes) + self._spectral_conv = SpectralConvBlock3D( + input_numb_fields=input_numb_fields, + output_numb_fields=output_numb_fields, + n_modes=n_modes) self._activation = activation() self._linear = nn.Conv3d(input_numb_fields, output_numb_fields, 1) - + def forward(self, x): """ Forward computation for Fourier Block. It performs a spectral diff --git a/pina/model/layers/residual.py b/pina/model/layers/residual.py index ddbf730..6b3734c 100644 --- a/pina/model/layers/residual.py +++ b/pina/model/layers/residual.py @@ -9,17 +9,21 @@ class ResidualBlock(nn.Module): .. seealso:: **Original reference**: He, Kaiming, et al. - "Deep residual learning for image recognition." + *Deep residual learning for image recognition.* Proceedings of the IEEE conference on computer vision and pattern recognition. 2016.. - `_. + DOI: ``_. """ - def __init__(self, input_dim, output_dim, - hidden_dim, spectral_norm=False, + def __init__(self, + input_dim, + output_dim, + hidden_dim, + spectral_norm=False, activation=torch.nn.ReLU()): - """Residual block constructor + """ + Initializes the ResidualBlock module. :param int input_dim: Dimension of the input to pass to the feedforward linear layer. @@ -48,9 +52,9 @@ class ResidualBlock(nn.Module): self._activation = activation # create layers - self.l1 = self._spect_norm(nn.Linear(input_dim, hidden_dim)) - self.l2 = self._spect_norm(nn.Linear(hidden_dim, output_dim)) - self.l3 = self._spect_norm(nn.Linear(input_dim, output_dim)) + self._l1 = self._spect_norm(nn.Linear(input_dim, hidden_dim)) + self._l2 = self._spect_norm(nn.Linear(hidden_dim, output_dim)) + self._l3 = self._spect_norm(nn.Linear(input_dim, output_dim)) def forward(self, x): """Forward pass for residual block layer. @@ -59,9 +63,9 @@ class ResidualBlock(nn.Module): :return: Output tensor for the residual layer. :rtype: torch.Tensor """ - y = self.activation(self.l1(x)) - y = self.l2(y) - x = self.l3(x) + y = self._activation(self._l1(x)) + y = self._l2(y) + x = self._l3(x) return y + x def _spect_norm(self, x): @@ -74,32 +78,40 @@ class ResidualBlock(nn.Module): """ return nn.utils.spectral_norm(x) if self._spectral_norm else x - @ property - def spectral_norm(self): - return self._spectral_norm - @ property - def input_dim(self): - return self._input_dim - - @ property - def output_dim(self): - return self._output_dim - - @ property - def hidden_dim(self): - return self._hidden_dim - - @ property - def activation(self): - return self._activation - +import torch +import torch.nn as nn class EnhancedLinear(torch.nn.Module): """ - TODO + A wrapper class for enhancing a linear layer with activation and/or dropout. + + :param layer: The linear layer to be enhanced. + :type layer: torch.nn.Module + :param activation: The activation function to be applied after the linear layer. + :type activation: torch.nn.Module + :param dropout: The dropout probability to be applied after the activation (if provided). + :type dropout: float + + :Example: + + >>> linear_layer = torch.nn.Linear(10, 20) + >>> activation = torch.nn.ReLU() + >>> dropout_prob = 0.5 + >>> enhanced_linear = EnhancedLinear(linear_layer, activation, dropout_prob) """ + def __init__(self, layer, activation=None, dropout=None): + """ + Initializes the EnhancedLinear module. + + :param layer: The linear layer to be enhanced. + :type layer: torch.nn.Module + :param activation: The activation function to be applied after the linear layer. + :type activation: torch.nn.Module + :param dropout: The dropout probability to be applied after the activation (if provided). + :type dropout: float + """ super().__init__() # check consistency @@ -108,23 +120,41 @@ class EnhancedLinear(torch.nn.Module): check_consistency(activation, nn.Module) if dropout is not None: check_consistency(dropout, float) - + # assign forward if (dropout is None) and (activation is None): self._model = torch.nn.Sequential(layer) elif (dropout is None) and (activation is not None): - self._model = torch.nn.Sequential(layer, - activation) - + self._model = torch.nn.Sequential(layer, activation) + elif (dropout is not None) and (activation is None): - self._model = torch.nn.Sequential(layer, - self._drop(dropout)) - + self._model = torch.nn.Sequential(layer, self._drop(dropout)) + elif (dropout is not None) and (activation is not None): - self._model = torch.nn.Sequential(layer, - activation, + self._model = torch.nn.Sequential(layer, activation, self._drop(dropout)) - + def forward(self, x): + """ + Forward pass through the enhanced linear module. + + :param x: Input tensor. + :type x: torch.Tensor + + :return: Output tensor after passing through the enhanced linear module. + :rtype: torch.Tensor + """ return self._model(x) + + def _drop(self, p): + """ + Applies dropout with probability p. + + :param p: Dropout probability. + :type p: float + + :return: Dropout layer with the specified probability. + :rtype: torch.nn.Dropout + """ + return torch.nn.Dropout(p) diff --git a/pina/model/layers/spectral.py b/pina/model/layers/spectral.py index e6a06f7..d86aa09 100644 --- a/pina/model/layers/spectral.py +++ b/pina/model/layers/spectral.py @@ -3,17 +3,17 @@ import torch.nn as nn from ...utils import check_consistency import warnings + ######## 1D Spectral Convolution ########### class SpectralConvBlock1D(nn.Module): """ - Implementation of Spectral Convolution Block for one - dimensional tensor. + PINA implementation of Spectral Convolution Block for one + dimensional tensors. """ def __init__(self, input_numb_fields, output_numb_fields, n_modes): """ - PINA implementation of spectral convolution. The module computes - the spectral convolution of the input with a linear kernel in the + The module computes the spectral convolution of the input with a linear kernel in the fourier space, and then it maps the input back to the physical space. @@ -37,22 +37,22 @@ class SpectralConvBlock1D(nn.Module): self._output_channels = output_numb_fields # scaling factor - scale = (1. / (self._input_channels * self._output_channels)) + scale = (1. / (self._input_channels * self._output_channels)) self._weights = nn.Parameter(scale * torch.rand(self._input_channels, self._output_channels, self._modes, dtype=torch.cfloat)) - + def _compute_mult1d(self, input, weights): """ Compute the matrix multiplication of the input with the linear kernel weights. :param input: The input tensor, expect of size - [batch, input_numb_fields, x]. + ``[batch, input_numb_fields, x]``. :type input: torch.Tensor :param weights: The kernel weights, expect of - size [input_numb_fields, output_numb_fields, x]. + size ``[input_numb_fields, output_numb_fields, x]``. :type weights: torch.Tensor :return: The matrix multiplication of the input with the linear kernel weights. @@ -65,10 +65,10 @@ class SpectralConvBlock1D(nn.Module): Forward computation for Spectral Convolution. :param x: The input tensor, expect of size - [batch, input_numb_fields, x]. + ``[batch, input_numb_fields, x]``. :type x: torch.Tensor :return: The output tensor obtained from the - spectral convolution of size [batch, output_numb_fields, x]. + spectral convolution of size ``[batch, output_numb_fields, x]``. :rtype: torch.Tensor """ batch_size = x.shape[0] @@ -82,23 +82,23 @@ class SpectralConvBlock1D(nn.Module): x.size(-1) // 2 + 1, device=x.device, dtype=torch.cfloat) - out_ft[:, :, :self._modes] = self._compute_mult1d(x_ft[:, :, :self._modes], self._weights) + out_ft[:, :, :self._modes] = self._compute_mult1d( + x_ft[:, :, :self._modes], self._weights) # Return to physical space return torch.fft.irfft(out_ft, n=x.size(-1)) - + ######## 2D Spectral Convolution ########### class SpectralConvBlock2D(nn.Module): """ - Implementation of spectral convolution block for two - dimensional tensor. + PINA implementation of spectral convolution block for two + dimensional tensors. """ def __init__(self, input_numb_fields, output_numb_fields, n_modes): """ - PINA implementation of spectral convolution. The module computes - the spectral convolution of the input with a linear kernel in the + The module computes the spectral convolution of the input with a linear kernel in the fourier space, and then it maps the input back to the physical space. @@ -118,17 +118,18 @@ class SpectralConvBlock2D(nn.Module): check_consistency(n_modes, int) if isinstance(n_modes, (tuple, list)): if len(n_modes) != 2: - raise ValueError('Expected n_modes to be a list or tuple of len two, ' - 'with each entry corresponding to the number of modes ' - 'for each dimension ') + raise ValueError( + 'Expected n_modes to be a list or tuple of len two, ' + 'with each entry corresponding to the number of modes ' + 'for each dimension ') elif isinstance(n_modes, int): - n_modes = [n_modes]*2 + n_modes = [n_modes] * 2 else: - raise ValueError('Expected n_modes to be a list or tuple of len two, ' - 'with each entry corresponding to the number of modes ' - 'for each dimension; or an int value representing the ' - 'number of modes for all dimensions') - + raise ValueError( + 'Expected n_modes to be a list or tuple of len two, ' + 'with each entry corresponding to the number of modes ' + 'for each dimension; or an int value representing the ' + 'number of modes for all dimensions') # assign variables self._modes = n_modes @@ -136,7 +137,7 @@ class SpectralConvBlock2D(nn.Module): self._output_channels = output_numb_fields # scaling factor - scale = (1. / (self._input_channels * self._output_channels)) + scale = (1. / (self._input_channels * self._output_channels)) self._weights1 = nn.Parameter(scale * torch.rand(self._input_channels, self._output_channels, self._modes[0], @@ -147,17 +148,17 @@ class SpectralConvBlock2D(nn.Module): self._modes[0], self._modes[1], dtype=torch.cfloat)) - + def _compute_mult2d(self, input, weights): """ Compute the matrix multiplication of the input with the linear kernel weights. :param input: The input tensor, expect of size - [batch, input_numb_fields, x, y]. + ``[batch, input_numb_fields, x, y]``. :type input: torch.Tensor :param weights: The kernel weights, expect of - size [input_numb_fields, output_numb_fields, x, y]. + size ``[input_numb_fields, output_numb_fields, x, y]``. :type weights: torch.Tensor :return: The matrix multiplication of the input with the linear kernel weights. @@ -170,10 +171,10 @@ class SpectralConvBlock2D(nn.Module): Forward computation for Spectral Convolution. :param x: The input tensor, expect of size - [batch, input_numb_fields, x]. + ``[batch, input_numb_fields, x, y]``. :type x: torch.Tensor :return: The output tensor obtained from the - spectral convolution of size [batch, output_numb_fields, x]. + spectral convolution of size ``[batch, output_numb_fields, x, y]``. :rtype: torch.Tensor """ @@ -186,29 +187,28 @@ class SpectralConvBlock2D(nn.Module): out_ft = torch.zeros(batch_size, self._output_channels, x.size(-2), - x.size(-1)//2 + 1, + x.size(-1) // 2 + 1, device=x.device, dtype=torch.cfloat) - out_ft[:, :, :self._modes[0], :self._modes[1]] = self._compute_mult2d(x_ft[:, :, :self._modes[0], :self._modes[1]], - self._weights1) - out_ft[:, :, -self._modes[0]:, :self._modes[1]:] = self._compute_mult2d(x_ft[:, :, -self._modes[0]:, :self._modes[1]], - self._weights2) + out_ft[:, :, :self._modes[0], :self._modes[1]] = self._compute_mult2d( + x_ft[:, :, :self._modes[0], :self._modes[1]], self._weights1) + out_ft[:, :, -self._modes[0]:, :self._modes[1]:] = self._compute_mult2d( + x_ft[:, :, -self._modes[0]:, :self._modes[1]], self._weights2) # Return to physical space return torch.fft.irfft2(out_ft, s=(x.size(-2), x.size(-1))) -######## 2D Spectral Convolution ########### +######## 3D Spectral Convolution ########### class SpectralConvBlock3D(nn.Module): """ - Implementation of spectral convolution block for two - dimensional tensor. + PINA implementation of spectral convolution block for three + dimensional tensors. """ def __init__(self, input_numb_fields, output_numb_fields, n_modes): """ - PINA implementation of spectral convolution. The module computes - the spectral convolution of the input with a linear kernel in the + The module computes the spectral convolution of the input with a linear kernel in the fourier space, and then it maps the input back to the physical space. @@ -229,16 +229,18 @@ class SpectralConvBlock3D(nn.Module): check_consistency(n_modes, int) if isinstance(n_modes, (tuple, list)): if len(n_modes) != 3: - raise ValueError('Expected n_modes to be a list or tuple of len three, ' - 'with each entry corresponding to the number of modes ' - 'for each dimension ') + raise ValueError( + 'Expected n_modes to be a list or tuple of len three, ' + 'with each entry corresponding to the number of modes ' + 'for each dimension ') elif isinstance(n_modes, int): - n_modes = [n_modes]*3 + n_modes = [n_modes] * 3 else: - raise ValueError('Expected n_modes to be a list or tuple of len three, ' - 'with each entry corresponding to the number of modes ' - 'for each dimension; or an int value representing the ' - 'number of modes for all dimensions') + raise ValueError( + 'Expected n_modes to be a list or tuple of len three, ' + 'with each entry corresponding to the number of modes ' + 'for each dimension; or an int value representing the ' + 'number of modes for all dimensions') # assign variables self._modes = n_modes @@ -246,7 +248,7 @@ class SpectralConvBlock3D(nn.Module): self._output_channels = output_numb_fields # scaling factor - scale = (1. / (self._input_channels * self._output_channels)) + scale = (1. / (self._input_channels * self._output_channels)) self._weights1 = nn.Parameter(scale * torch.rand(self._input_channels, self._output_channels, self._modes[0], @@ -271,17 +273,17 @@ class SpectralConvBlock3D(nn.Module): self._modes[1], self._modes[2], dtype=torch.cfloat)) - + def _compute_mult3d(self, input, weights): """ Compute the matrix multiplication of the input with the linear kernel weights. :param input: The input tensor, expect of size - [batch, input_numb_fields, x, y]. + ``[batch, input_numb_fields, x, y, z]``. :type input: torch.Tensor :param weights: The kernel weights, expect of - size [input_numb_fields, output_numb_fields, x, y]. + size ``[input_numb_fields, output_numb_fields, x, y, z]``. :type weights: torch.Tensor :return: The matrix multiplication of the input with the linear kernel weights. @@ -294,10 +296,10 @@ class SpectralConvBlock3D(nn.Module): Forward computation for Spectral Convolution. :param x: The input tensor, expect of size - [batch, input_numb_fields, x]. + ``[batch, input_numb_fields, x, y, z]``. :type x: torch.Tensor :return: The output tensor obtained from the - spectral convolution of size [batch, output_numb_fields, x]. + spectral convolution of size ``[batch, output_numb_fields, x, y, z]``. :rtype: torch.Tensor """ @@ -311,42 +313,45 @@ class SpectralConvBlock3D(nn.Module): self._output_channels, x.size(-3), x.size(-2), - x.size(-1)//2 + 1, + x.size(-1) // 2 + 1, device=x.device, dtype=torch.cfloat) - - slice0 = (slice(None), - slice(None), - slice(self._modes[0]), - slice(self._modes[1]), - slice(self._modes[2]), - ) + + slice0 = ( + slice(None), + slice(None), + slice(self._modes[0]), + slice(self._modes[1]), + slice(self._modes[2]), + ) out_ft[slice0] = self._compute_mult3d(x_ft[slice0], self._weights1) - slice1 = (slice(None), - slice(None), - slice(self._modes[0]), - slice(-self._modes[1], None), - slice(self._modes[2]), - ) + slice1 = ( + slice(None), + slice(None), + slice(self._modes[0]), + slice(-self._modes[1], None), + slice(self._modes[2]), + ) out_ft[slice1] = self._compute_mult3d(x_ft[slice1], self._weights2) - slice2 = (slice(None), - slice(None), - slice(-self._modes[0], None), - slice(self._modes[1]), - slice(self._modes[2]), - ) + slice2 = ( + slice(None), + slice(None), + slice(-self._modes[0], None), + slice(self._modes[1]), + slice(self._modes[2]), + ) out_ft[slice2] = self._compute_mult3d(x_ft[slice2], self._weights3) - slice3 = (slice(None), - slice(None), - slice(-self._modes[0], None), - slice(-self._modes[1], None), - slice(self._modes[2]), - ) + slice3 = ( + slice(None), + slice(None), + slice(-self._modes[0], None), + slice(-self._modes[1], None), + slice(self._modes[2]), + ) out_ft[slice3] = self._compute_mult3d(x_ft[slice3], self._weights4) # Return to physical space return torch.fft.irfftn(out_ft, s=(x.size(-3), x.size(-2), x.size(-1))) - diff --git a/pina/model/layers/stride.py b/pina/model/layers/stride.py index 02143e8..6facb01 100644 --- a/pina/model/layers/stride.py +++ b/pina/model/layers/stride.py @@ -68,11 +68,13 @@ class Stride(object): direction[i] = 1 # creating the stride grid - values_mesh = [torch.arange(0, i, step).float() - for i, step in zip(domain, jumps)] + values_mesh = [ + torch.arange(0, i, step).float() for i, step in zip(domain, jumps) + ] - values_mesh = [single * dim for single, - dim in zip(values_mesh, direction)] + values_mesh = [ + single * dim for single, dim in zip(values_mesh, direction) + ] mesh = torch.meshgrid(values_mesh) coordinates_mesh = [x.reshape(-1, 1) for x in mesh] diff --git a/pina/model/layers/utils_convolution.py b/pina/model/layers/utils_convolution.py index c1e6a4e..a2df5fe 100644 --- a/pina/model/layers/utils_convolution.py +++ b/pina/model/layers/utils_convolution.py @@ -3,8 +3,8 @@ import torch def check_point(x, current_stride, dim): max_stride = current_stride + dim - indeces = torch.logical_and(x[..., :-1] < max_stride, - x[..., :-1] >= current_stride).all(dim=-1) + indeces = torch.logical_and(x[..., :-1] < max_stride, x[..., :-1] + >= current_stride).all(dim=-1) return indeces diff --git a/pina/model/multi_feed_forward.py b/pina/model/multi_feed_forward.py index 2773696..20d0240 100644 --- a/pina/model/multi_feed_forward.py +++ b/pina/model/multi_feed_forward.py @@ -12,8 +12,9 @@ class MultiFeedForward(torch.nn.Module): together. The user has to define the `forward` method choosing how to combine the different FeedForward networks. - :param dict dff_dict: dictionary of FeedForward networks. + :param dict ffn_dict: dictionary of FeedForward networks. """ + def __init__(self, ffn_dict): super().__init__() diff --git a/pina/model/network.py b/pina/model/network.py index ff9dce5..f27d5b2 100644 --- a/pina/model/network.py +++ b/pina/model/network.py @@ -4,10 +4,19 @@ from ..utils import check_consistency class Network(torch.nn.Module): - """ Network class with starndard forward method - and possibility to pass extra features.""" def __init__(self, model, extra_features=None): + """ + Network class with standard forward method + and possibility to pass extra features. This + class is used internally in PINA to convert + any :class:`torch.nn.Module` s in a PINA module. + + :param model: The torch model to convert in a PINA model. + :type model: torch.nn.Module + :param extra_features: List of torch models to augment the input, defaults to None. + :type extra_features: list(torch.nn.Module) + """ super().__init__() # check model consistency @@ -27,12 +36,15 @@ class Network(torch.nn.Module): def forward(self, x): """ - Forward method for Network class. This class - implements the standard forward method, and + Forward method for Network class. This class + implements the standard forward method, and it adds the possibility to pass extra features. + All the PINA models ``forward`` s are overriden + by this class, to enable :class:`pina.label_tensor.LabelTensor` labels + extraction. - :param torch.tensor x: input of the network - :return torch.tensor: output of the network + :param torch.Tensor x: Input of the network. + :return torch.Tensor: Output of the network. """ # extract features and append for feature in self._extra_features: diff --git a/pina/operators.py b/pina/operators.py index cb5358e..563188c 100644 --- a/pina/operators.py +++ b/pina/operators.py @@ -1,4 +1,10 @@ -"""Module for operators vectorize implementation""" +""" +Module for operators vectorize implementation. Differential operators are used to write any differential problem. +These operators are implemented to work on different accellerators: CPU, GPU, TPU or MPS. +All operators take as input a tensor onto which computing the operator, a tensor with respect +to which computing the operator, the name of the output variables to calculate the operator +for (in case of multidimensional functions), and the variables name on which the operator is calculated. +""" import torch from pina.label_tensor import LabelTensor @@ -48,15 +54,15 @@ def grad(output_, input_, components=None, d=None): raise RuntimeError('derivative labels missing from input tensor') output_fieldname = output_.labels[0] - gradients = torch.autograd.grad( - output_, - input_, - grad_outputs=torch.ones(output_.size(), dtype=output_.dtype, - device=output_.device), - create_graph=True, - retain_graph=True, - allow_unused=True - )[0] + gradients = torch.autograd.grad(output_, + input_, + grad_outputs=torch.ones( + output_.size(), + dtype=output_.dtype, + device=output_.device), + create_graph=True, + retain_graph=True, + allow_unused=True)[0] gradients.labels = input_.labels gradients = gradients.extract(d) @@ -188,11 +194,13 @@ def laplacian(output_, input_, components=None, d=None, method='std'): result = torch.zeros(output_.shape[0], 1, device=output_.device) for i, label in enumerate(grad_output.labels): gg = grad(grad_output, input_, d=d, components=[label]) - result[:, 0] += super(torch.Tensor, gg.T).__getitem__(i) # TODO improve + result[:, 0] += super(torch.Tensor, + gg.T).__getitem__(i) # TODO improve labels = [f'dd{components[0]}'] else: - result = torch.empty(input_.shape[0], len(components), + result = torch.empty(input_.shape[0], + len(components), device=output_.device) labels = [None] * len(components) for idx, (ci, di) in enumerate(zip(components, d)): @@ -237,8 +245,8 @@ def advection(output_, input_, velocity_field, components=None, d=None): if components is None: components = output_.labels - tmp = grad(output_, input_, components, d - ).reshape(-1, len(components), len(d)).transpose(0, 1) + tmp = grad(output_, input_, components, d).reshape(-1, len(components), + len(d)).transpose(0, 1) tmp *= output_.extract(velocity_field) return tmp.sum(dim=2).T diff --git a/pina/plotter.py b/pina/plotter.py index 179a025..1c2c478 100644 --- a/pina/plotter.py +++ b/pina/plotter.py @@ -1,6 +1,5 @@ """ Module for plotting. """ - import matplotlib.pyplot as plt import torch from pina.callbacks import MetricTracker @@ -14,9 +13,9 @@ class Plotter: def plot_samples(self, problem, variables=None, **kwargs): """ - Plot the training grid samples. + Plot the training grid samples. - :param SolverInterface solver: The SolverInterface object. + :param SolverInterface solver: The ``SolverInterface`` object. :param list(str) variables: Variables to plot. If None, all variables are plotted. If 'spatial', only spatial variables are plotted. If 'temporal', only temporal variables are plotted. Defaults to None. @@ -44,11 +43,13 @@ class Plotter: proj = '3d' if len(variables) == 3 else None ax = fig.add_subplot(projection=proj) for location in problem.input_pts: - coords = problem.input_pts[location].extract( - variables).T.detach() + coords = problem.input_pts[location].extract(variables).T.detach() if coords.shape[0] == 1: # 1D samples - ax.plot(coords.flatten(), torch.zeros(coords.flatten().shape), '.', - label=location, **kwargs) + ax.plot(coords.flatten(), + torch.zeros(coords.flatten().shape), + '.', + label=location, + **kwargs) else: ax.plot(*coords, '.', label=location, **kwargs) @@ -92,13 +93,19 @@ class Plotter: plt.legend() plt.show() - def _2d_plot(self, pts, pred, v, res, method, truth_solution=None, + def _2d_plot(self, + pts, + pred, + v, + res, + method, + truth_solution=None, **kwargs): """Plot solution for two dimensional function :param pts: Points to plot the solution. :type pts: torch.Tensor - :param pred: SolverInterface solution evaluated at 'pts'. + :param pred: ``SolverInterface`` solution evaluated at 'pts'. :type pred: torch.Tensor :param method: Matplotlib method to plot 2-dimensional data, see https://matplotlib.org/stable/api/axes_api.html for @@ -116,32 +123,39 @@ class Plotter: truth_output = truth_solution(pts).float().reshape(res, res) fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(16, 6)) - cb = getattr(ax[0], method)( - *grids, pred_output.cpu().detach(), **kwargs) + cb = getattr(ax[0], method)(*grids, pred_output.cpu().detach(), + **kwargs) fig.colorbar(cb, ax=ax[0]) ax[0].title.set_text('Neural Network prediction') - cb = getattr(ax[1], method)( - *grids, truth_output.cpu().detach(), **kwargs) + cb = getattr(ax[1], method)(*grids, truth_output.cpu().detach(), + **kwargs) fig.colorbar(cb, ax=ax[1]) ax[1].title.set_text('True solution') - cb = getattr(ax[2], method)(*grids, - (truth_output-pred_output).cpu().detach(), - **kwargs) + cb = getattr(ax[2], + method)(*grids, + (truth_output - pred_output).cpu().detach(), + **kwargs) fig.colorbar(cb, ax=ax[2]) ax[2].title.set_text('Residual') else: fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8, 6)) - cb = getattr(ax, method)( - *grids, pred_output.cpu().detach(), **kwargs) + cb = getattr(ax, method)(*grids, pred_output.cpu().detach(), + **kwargs) fig.colorbar(cb, ax=ax) ax.title.set_text('Neural Network prediction') - def plot(self, solver, components=None, fixed_variables={}, method='contourf', - res=256, filename=None, **kwargs): + def plot(self, + solver, + components=None, + fixed_variables={}, + method='contourf', + res=256, + filename=None, + **kwargs): """ Plot sample of SolverInterface output. - :param SolverInterface solver: The SolverInterface object instance. + :param SolverInterface solver: The ``SolverInterface`` object instance. :param list(str) components: The output variable to plot. If None, all the output variables of the problem are selected. Default value is None. @@ -149,8 +163,9 @@ class Plotter: should be kept fixed during the plot. The keys of the dictionary are the variables name whereas the values are the corresponding values of the variables. Defaults is `dict()`. - :param {'contourf', 'pcolor'} method: The matplotlib method to use for - plotting the solution. Default is 'contourf'. + :param str method: The matplotlib method to use for + plotting the solution. Available methods are {'contourf', 'pcolor'}. + Default is 'contourf'. :param int res: The resolution, aka the number of points used for plotting in each axis. Default is 256. :param str filename: The file name to save the plot. If None, the plot @@ -184,8 +199,8 @@ class Plotter: self._1d_plot(pts, predicted_output, method, truth_solution, **kwargs) elif len(v) == 2: - self._2d_plot(pts, predicted_output, v, res, method, - truth_solution, **kwargs) + self._2d_plot(pts, predicted_output, v, res, method, truth_solution, + **kwargs) plt.tight_layout() if filename: @@ -193,12 +208,19 @@ class Plotter: else: plt.show() - def plot_loss(self, trainer, metrics=None, logy = False, logx=False, filename=None, **kwargs): + def plot_loss(self, + trainer, + metrics=None, + logy=False, + logx=False, + filename=None, + **kwargs): """ Plot the loss function values during traininig. - :param Trainer trainer: the PINA Trainer object instance. - :param str/list(str) metric: The metrics to use in the y axis. If None, the mean loss + :param trainer: the PINA Trainer object instance. + :type trainer: Trainer + :param str | list(str) metric: The metrics to use in the y axis. If None, the mean loss is plotted. :param bool logy: If True, the y axis is in log scale. Default is True. @@ -209,10 +231,14 @@ class Plotter: """ # check that MetricTracker has been used - list_ = [idx for idx, s in enumerate(trainer.callbacks) if isinstance(s, MetricTracker)] + list_ = [ + idx for idx, s in enumerate(trainer.callbacks) + if isinstance(s, MetricTracker) + ] if not bool(list_): - raise FileNotFoundError('MetricTracker should be used as a callback during training to' - ' use this method.') + raise FileNotFoundError( + 'MetricTracker should be used as a callback during training to' + ' use this method.') # extract trainer metrics trainer_metrics = trainer.callbacks[list_[0]].metrics @@ -220,11 +246,13 @@ class Plotter: metrics = ['mean_loss'] elif not isinstance(metrics, list): raise ValueError('metrics must be class list.') - + # loop over metrics to plot for metric in metrics: if metric not in trainer_metrics: - raise ValueError(f'{metric} not a valid metric. Available metrics are {list(trainer_metrics.keys())}.') + raise ValueError( + f'{metric} not a valid metric. Available metrics are {list(trainer_metrics.keys())}.' + ) loss = trainer_metrics[metric] epochs = range(len(loss)) plt.plot(epochs, loss, **kwargs) diff --git a/pina/problem/abstract_problem.py b/pina/problem/abstract_problem.py index 95fdb65..1bea870 100644 --- a/pina/problem/abstract_problem.py +++ b/pina/problem/abstract_problem.py @@ -27,7 +27,7 @@ class AbstractProblem(metaclass=ABCMeta): # put in self.input_pts all the points that we don't need to sample self._span_condition_points() - + @property def input_variables(self): """ @@ -55,10 +55,11 @@ class AbstractProblem(metaclass=ABCMeta): def domain(self): """ The domain(s) where the conditions of the AbstractProblem are valid. + If more than one domain type is passed, a list of Location is + retured. - :return: the domain(s) of self - :rtype: list (if more than one domain are defined), - `Span` domain (of only one domain is defined) + :return: the domain(s) of ``self`` + :rtype: list[Location] """ domains = [ getattr(self, f'{t}_domain') @@ -109,7 +110,11 @@ class AbstractProblem(metaclass=ABCMeta): self.input_pts[condition_name] = samples self._have_sampled_points[condition_name] = True - def discretise_domain(self, n, mode = 'random', variables = 'all', locations = 'all'): + def discretise_domain(self, + n, + mode='random', + variables='all', + locations='all'): """ Generate a set of points to span the `Location` of all the conditions of the problem. @@ -122,9 +127,9 @@ class AbstractProblem(metaclass=ABCMeta): latin hypercube sampling, ``latin`` or ``lh``; chebyshev sampling, ``chebyshev``; grid sampling ``grid``. :param variables: problem's variables to be sampled, defaults to 'all'. - :type variables: str or list[str], optional + :type variables: str | list[str] :param locations: problem's locations from where to sample, defaults to 'all'. - :type locations: str, optional + :type locations: str :Example: >>> pinn.discretise_domain(n=10, mode='grid') @@ -146,24 +151,24 @@ class AbstractProblem(metaclass=ABCMeta): check_consistency(mode, str) if mode not in ['random', 'grid', 'lh', 'chebyshev', 'latin']: raise TypeError(f'mode {mode} not valid.') - + # check consistency variables if variables == 'all': variables = self.input_variables else: check_consistency(variables, str) - - if sorted(variables) != sorted(self.input_variables): + + if sorted(variables) != sorted(self.input_variables): TypeError(f'Wrong variables for sampling. Variables ', f'should be in {self.input_variables}.') - + # check consistency location if locations == 'all': locations = [condition for condition in self.conditions] else: check_consistency(locations, str) - if sorted(locations) != sorted(self.conditions): + if sorted(locations) != sorted(self.conditions): TypeError(f'Wrong locations for sampling. Location ', f'should be in {self.conditions}.') @@ -174,7 +179,7 @@ class AbstractProblem(metaclass=ABCMeta): # we try to check if we have already sampled try: already_sampled = [self.input_pts[location]] - # if we have not sampled, a key error is thrown + # if we have not sampled, a key error is thrown except KeyError: already_sampled = [] @@ -187,16 +192,15 @@ class AbstractProblem(metaclass=ABCMeta): self._have_sampled_points[location] = False # build samples - samples = [condition.location.sample( - n=n, - mode=mode, - variables=variables) - ] + already_sampled + samples = [ + condition.location.sample(n=n, mode=mode, variables=variables) + ] + already_sampled pts = merge_tensors(samples) self.input_pts[location] = pts # the condition is sampled if input_pts contains all labels - if sorted(self.input_pts[location].labels) == sorted(self.input_variables): + if sorted(self.input_pts[location].labels) == sorted( + self.input_variables): self._have_sampled_points[location] = True def add_points(self, new_points): @@ -207,21 +211,22 @@ class AbstractProblem(metaclass=ABCMeta): and values the torch.Tensor points. """ - if sorted(new_points.keys()) != sorted(self.conditions): + if sorted(new_points.keys()) != sorted(self.conditions): TypeError(f'Wrong locations for new points. Location ', f'should be in {self.conditions}.') - + for location in new_points.keys(): # extract old and new points old_pts = self.input_pts[location] new_pts = new_points[location] # if they don't have the same variables error - if sorted(old_pts.labels) != sorted(new_pts.labels): + if sorted(old_pts.labels) != sorted(new_pts.labels): TypeError(f'Not matching variables for old and new points ' f'in condition {location}.') if old_pts.labels != new_pts.labels: - new_pts = torch.hstack([new_pts.extract([i]) for i in old_pts.labels]) + new_pts = torch.hstack( + [new_pts.extract([i]) for i in old_pts.labels]) new_pts.labels = old_pts.labels # merging @@ -233,13 +238,14 @@ class AbstractProblem(metaclass=ABCMeta): def have_sampled_points(self): """ Check if all points for - ``'Location'`` are sampled. - """ + ``Location`` are sampled. + """ return all(self._have_sampled_points.values()) - + @property def not_sampled_points(self): - """Check which points are + """ + Check which points are not sampled. """ # variables which are not sampled @@ -251,4 +257,3 @@ class AbstractProblem(metaclass=ABCMeta): if not is_sample: not_sampled.append(condition_name) return not_sampled - diff --git a/pina/problem/parametric_problem.py b/pina/problem/parametric_problem.py index f498379..17b8ed6 100644 --- a/pina/problem/parametric_problem.py +++ b/pina/problem/parametric_problem.py @@ -16,14 +16,17 @@ class ParametricProblem(AbstractProblem): :Example: >>> from pina.problem import SpatialProblem, ParametricProblem >>> from pina.operators import grad - >>> from pina import Condition, Span + >>> from pina.equations import Equation, FixedValue + >>> from pina import Condition + >>> from pina.geometry import CartesianDomain >>> import torch >>> + >>> >>> class ParametricODE(SpatialProblem, ParametricProblem): >>> >>> output_variables = ['u'] - >>> spatial_domain = Span({'x': [0, 1]}) - >>> parameter_domain = Span({'alpha': [1, 10]}) + >>> spatial_domain = CartesianDomain({'x': [0, 1]}) + >>> parameter_domain = CartesianDomain({'alpha': [1, 10]}) >>> >>> def ode_equation(input_, output_): >>> u_x = grad(output_, input_, components=['u'], d=['x']) @@ -31,14 +34,9 @@ class ParametricProblem(AbstractProblem): >>> alpha = input_.extract(['alpha']) >>> return alpha * u_x - u >>> - >>> def initial_condition(input_, output_): - >>> value = 1.0 - >>> u = output_.extract(['u']) - >>> return u - value - >>> >>> conditions = { - >>> 'x0': Condition(Span({'x': 0, 'alpha':[1, 10]}), initial_condition), - >>> 'D': Condition(Span({'x': [0, 1], 'alpha':[1, 10]}), ode_equation)} + >>> 'x0': Condition(CartesianDomain({'x': 0, 'alpha':[1, 10]}), FixedValue(1.)), + >>> 'D': Condition(CartesianDomain({'x': [0, 1], 'alpha':[1, 10]}), Equation(ode_equation))} """ @abstractmethod diff --git a/pina/problem/spatial_problem.py b/pina/problem/spatial_problem.py index 001373b..a0483e3 100644 --- a/pina/problem/spatial_problem.py +++ b/pina/problem/spatial_problem.py @@ -14,24 +14,25 @@ class SpatialProblem(AbstractProblem): :Example: >>> from pina.problem import SpatialProblem >>> from pina.operators import grad - >>> from pina import Condition, Span + >>> from pina.equations import Equation, FixedValue + >>> from pina import Condition + >>> from pina.geometry import CartesianDomain >>> import torch - >>> class SimpleODE(SpatialProblem): + >>> + >>> + >>> class SpatialODE(SpatialProblem: + >>> >>> output_variables = ['u'] - >>> spatial_domain = Span({'x': [0, 1]}) + >>> spatial_domain = CartesianDomain({'x': [0, 1]}) + >>> >>> def ode_equation(input_, output_): >>> u_x = grad(output_, input_, components=['u'], d=['x']) >>> u = output_.extract(['u']) >>> return u_x - u - >>> - >>> def initial_condition(input_, output_): - >>> value = 1.0 - >>> u = output_.extract(['u']) - >>> return u - value >>> >>> conditions = { - >>> 'x0': Condition(Span({'x': 0.}), initial_condition), - >>> 'D': Condition(Span({'x': [0, 1]}), ode_equation)} + >>> 'x0': Condition(CartesianDomain({'x': 0, 'alpha':[1, 10]}), FixedValue(1.)), + >>> 'D': Condition(CartesianDomain({'x': [0, 1], 'alpha':[1, 10]}), Equation(ode_equation))} """ diff --git a/pina/problem/timedep_problem.py b/pina/problem/timedep_problem.py index 7750414..2d0179e 100644 --- a/pina/problem/timedep_problem.py +++ b/pina/problem/timedep_problem.py @@ -14,14 +14,17 @@ class TimeDependentProblem(AbstractProblem): :Example: >>> from pina.problem import SpatialProblem, TimeDependentProblem >>> from pina.operators import grad, laplacian - >>> from pina import Condition, Span + >>> from pina.equations import Equation, FixedValue + >>> from pina import Condition + >>> from pina.geometry import CartesianDomain >>> import torch >>> + >>> >>> class Wave(TimeDependentSpatialProblem): >>> >>> output_variables = ['u'] - >>> spatial_domain = Span({'x': [0, 3]}) - >>> temporal_domain = Span({'t': [0, 1]}) + >>> spatial_domain = CartesianDomain({'x': [0, 3]}) + >>> temporal_domain = CartesianDomain({'t': [0, 1]}) >>> >>> def wave_equation(input_, output_): >>> u_t = grad(output_, input_, components=['u'], d=['t']) @@ -29,10 +32,6 @@ class TimeDependentProblem(AbstractProblem): >>> delta_u = laplacian(output_, input_, components=['u'], d=['x']) >>> return delta_u - u_tt >>> - >>> def nil_dirichlet(input_, output_): - >>> value = 0.0 - >>> return output_.extract(['u']) - value - >>> >>> def initial_condition(input_, output_): >>> u_expected = (-3*torch.sin(2*torch.pi*input_.extract(['x'])) >>> + 5*torch.sin(8/3*torch.pi*input_.extract(['x']))) @@ -40,10 +39,10 @@ class TimeDependentProblem(AbstractProblem): >>> return u - u_expected >>> >>> conditions = { - >>> 't0': Condition(Span({'x': [0, 3], 't':0}), initial_condition), - >>> 'gamma1': Condition(Span({'x':0, 't':[0, 1]}), nil_dirichlet), - >>> 'gamma2': Condition(Span({'x':3, 't':[0, 1]}), nil_dirichlet), - >>> 'D': Condition(Span({'x': [0, 3], 't':[0, 1]}), wave_equation)} + >>> 't0': Condition(CartesianDomain({'x': [0, 3], 't':0}), Equation(initial_condition)), + >>> '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))} """ diff --git a/pina/solvers/__init__.py b/pina/solvers/__init__.py index 39fbc2e..fdb6219 100644 --- a/pina/solvers/__init__.py +++ b/pina/solvers/__init__.py @@ -1,8 +1,12 @@ __all__ = [ 'PINN', 'GAROM', + 'SupervisedSolver', + 'SolverInterface' + ] from .garom import GAROM from .pinn import PINN from .supervised import SupervisedSolver +from .solver import SolverInterface diff --git a/pina/solvers/garom.py b/pina/solvers/garom.py index ddc16a3..972f156 100644 --- a/pina/solvers/garom.py +++ b/pina/solvers/garom.py @@ -4,7 +4,7 @@ import torch try: from torch.optim.lr_scheduler import LRScheduler # torch >= 2.0 except ImportError: - from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 + from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 from torch.optim.lr_scheduler import ConstantLR from .solver import SolverInterface @@ -22,28 +22,36 @@ class GAROM(SolverInterface): .. seealso:: **Original reference**: Coscia, D., Demo, N., & Rozza, G. (2023). - Generative Adversarial Reduced Order Modelling. - arXiv preprint arXiv:2305.15881. + *Generative Adversarial Reduced Order Modelling*. + DOI: `arXiv preprint arXiv:2305.15881. `_. """ - def __init__(self, - problem, - generator, - discriminator, - extra_features=None, - loss = None, - optimizer_generator=torch.optim.Adam, - optimizer_generator_kwargs={'lr' : 0.001}, - optimizer_discriminator=torch.optim.Adam, - optimizer_discriminator_kwargs={'lr' : 0.001}, - scheduler_generator=ConstantLR, - scheduler_generator_kwargs={"factor": 1, "total_iters": 0}, - scheduler_discriminator=ConstantLR, - scheduler_discriminator_kwargs={"factor": 1, "total_iters": 0}, - gamma = 0.3, - lambda_k = 0.001, - regularizer = False, - ): + + def __init__( + self, + problem, + generator, + discriminator, + extra_features=None, + loss=None, + optimizer_generator=torch.optim.Adam, + optimizer_generator_kwargs={'lr': 0.001}, + optimizer_discriminator=torch.optim.Adam, + optimizer_discriminator_kwargs={'lr': 0.001}, + scheduler_generator=ConstantLR, + scheduler_generator_kwargs={ + "factor": 1, + "total_iters": 0 + }, + scheduler_discriminator=ConstantLR, + scheduler_discriminator_kwargs={ + "factor": 1, + "total_iters": 0 + }, + gamma=0.3, + lambda_k=0.001, + regularizer=False, + ): """ :param AbstractProblem problem: The formualation of the problem. :param torch.nn.Module generator: The neural network model to use @@ -77,11 +85,11 @@ class GAROM(SolverInterface): rate scheduler for the discriminator. :param dict scheduler_discriminator_kwargs: LR scheduler constructor keyword args. :param gamma: Ratio of expected loss for generator and discriminator, defaults to 0.3. - :type gamma: float, optional + :type gamma: float :param lambda_k: Learning rate for control theory optimization, defaults to 0.001. - :type lambda_k: float, optional + :type lambda_k: float :param regularizer: Regularization term in the GAROM loss, defaults to False. - :type regularizer: bool, optional + :type regularizer: bool .. warning:: The algorithm works only for data-driven model. Hence in the ``problem`` definition @@ -90,22 +98,27 @@ class GAROM(SolverInterface): """ if isinstance(extra_features, dict): - extra_features = [extra_features['generator'], extra_features['discriminator']] + extra_features = [ + extra_features['generator'], extra_features['discriminator'] + ] + + super().__init__( + models=[generator, discriminator], + problem=problem, + extra_features=extra_features, + optimizers=[optimizer_generator, optimizer_discriminator], + optimizers_kwargs=[ + optimizer_generator_kwargs, optimizer_discriminator_kwargs + ]) - super().__init__(models=[generator, discriminator], - problem=problem, - extra_features=extra_features, - optimizers=[optimizer_generator, optimizer_discriminator], - optimizers_kwargs=[optimizer_generator_kwargs, optimizer_discriminator_kwargs]) - # set automatic optimization for GANs self.automatic_optimization = False # set loss if loss is None: loss = PowerLoss(p=1) - - # check consistency + + # check consistency check_consistency(scheduler_generator, LRScheduler, subclass=True) check_consistency(scheduler_generator_kwargs, dict) check_consistency(scheduler_discriminator, LRScheduler, subclass=True) @@ -134,6 +147,20 @@ class GAROM(SolverInterface): self.regularizer = float(regularizer) def forward(self, x, mc_steps=20, variance=False): + """ + Forward step for GAROM solver + + :param x: The input tensor. + :type x: torch.Tensor + :param mc_steps: Number of montecarlo samples to approximate the + expected value, defaults to 20. + :type mc_steps: int + :param variance: Returining also the sample variance of the solution, defaults to False. + :type variance: bool + :return: The expected value of the generator distribution. If ``variance=True`` also the + sample variance is returned. + :rtype: torch.Tensor | tuple(torch.Tensor, torch.Tensor) + """ # sampling field_sample = [self.sample(x) for _ in range(mc_steps)] @@ -147,10 +174,11 @@ class GAROM(SolverInterface): return mean, var return mean - + def configure_optimizers(self): - """Optimizer configuration for the GAROM - solver. + """ + Optimizer configuration for the GAROM + solver. :return: The optimizers and the schedulers :rtype: tuple(list, list) @@ -220,7 +248,7 @@ class GAROM(SolverInterface): return diff def training_step(self, batch, batch_idx): - """PINN solver training step. + """GAROM solver training step. :param batch: The batch element in the dataloader. :type batch: tuple @@ -265,27 +293,27 @@ class GAROM(SolverInterface): self.log('stability_metric', float(d_loss_real + torch.abs(diff)), prog_bar=True, logger=True, on_epoch=True, on_step=False) return - + @property def generator(self): return self.models[0] - + @property def discriminator(self): return self.models[1] - + @property def optimizer_generator(self): return self.optimizers[0] - + @property def optimizer_discriminator(self): return self.optimizers[1] - + @property def scheduler_generator(self): return self._schedulers[0] - + @property def scheduler_discriminator(self): return self._schedulers[1] diff --git a/pina/solvers/pinn.py b/pina/solvers/pinn.py index e986bb6..828b36d 100644 --- a/pina/solvers/pinn.py +++ b/pina/solvers/pinn.py @@ -3,7 +3,7 @@ import torch try: from torch.optim.lr_scheduler import LRScheduler # torch >= 2.0 except ImportError: - from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 + from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 from torch.optim.lr_scheduler import ConstantLR @@ -13,7 +13,6 @@ from ..utils import check_consistency from ..loss import LossInterface from torch.nn.modules.loss import _Loss - torch.pi = torch.acos(torch.zeros(1)).item() * 2 # which is 3.1415927410125732 @@ -30,27 +29,31 @@ class PINN(SolverInterface): Physics-informed machine learning. Nature Reviews Physics, 3(6), 422-440. `_. """ - def __init__(self, - problem, - model, - extra_features=None, - loss = torch.nn.MSELoss(), - optimizer=torch.optim.Adam, - optimizer_kwargs={'lr' : 0.001}, - scheduler=ConstantLR, - scheduler_kwargs={"factor": 1, "total_iters": 0}, - ): + + def __init__( + self, + problem, + model, + extra_features=None, + loss=torch.nn.MSELoss(), + optimizer=torch.optim.Adam, + optimizer_kwargs={'lr': 0.001}, + scheduler=ConstantLR, + scheduler_kwargs={ + "factor": 1, + "total_iters": 0 + }, + ): ''' :param AbstractProblem problem: The formualation of the problem. :param torch.nn.Module model: The neural network model to use. :param torch.nn.Module loss: The loss function used as minimizer, - default torch.nn.MSELoss(). + default :class:`torch.nn.MSELoss`. :param torch.nn.Module extra_features: The additional input features to use as augmented input. :param torch.optim.Optimizer optimizer: The neural network optimizer to - use; default is `torch.optim.Adam`. + use; default is :class:`torch.optim.Adam`. :param dict optimizer_kwargs: Optimizer constructor keyword args. - :param float lr: The learning rate; default is 0.001. :param torch.optim.LRScheduler scheduler: Learning rate scheduler. :param dict scheduler_kwargs: LR scheduler constructor keyword args. @@ -60,8 +63,8 @@ class PINN(SolverInterface): optimizers=[optimizer], optimizers_kwargs=[optimizer_kwargs], extra_features=extra_features) - - # check consistency + + # check consistency check_consistency(scheduler, LRScheduler, subclass=True) check_consistency(scheduler_kwargs, dict) check_consistency(loss, (LossInterface, _Loss), subclass=False) @@ -71,14 +74,14 @@ class PINN(SolverInterface): self._loss = loss self._neural_net = self.models[0] - def forward(self, x): - """Forward pass implementation for the PINN - solver. + """ + Forward pass implementation for the PINN + solver. - :param torch.tensor x: Input data. + :param torch.Tensor x: Input tensor. :return: PINN solution. - :rtype: torch.tensor + :rtype: torch.Tensor """ # extract labels x = x.extract(self.problem.input_variables) @@ -89,8 +92,9 @@ class PINN(SolverInterface): return output def configure_optimizers(self): - """Optimizer configuration for the PINN - solver. + """ + Optimizer configuration for the PINN + solver. :return: The optimizers and the schedulers :rtype: tuple(list, list) @@ -107,7 +111,8 @@ class PINN(SolverInterface): def training_step(self, batch, batch_idx): - """PINN solver training step. + """ + PINN solver training step. :param batch: The batch element in the dataloader. :type batch: tuple @@ -159,17 +164,17 @@ class PINN(SolverInterface): Scheduler for the PINN training. """ return self._scheduler - + @property def neural_net(self): """ Neural network for the PINN training. """ return self._neural_net - + @property def loss(self): """ Loss for the PINN training. """ - return self._loss \ No newline at end of file + return self._loss diff --git a/pina/solvers/solver.py b/pina/solvers/solver.py index c205840..698e088 100644 --- a/pina/solvers/solver.py +++ b/pina/solvers/solver.py @@ -2,30 +2,38 @@ from abc import ABCMeta, abstractmethod from ..model.network import Network -import pytorch_lightning as pl +import pytorch_lightning from ..utils import check_consistency from ..problem import AbstractProblem import torch -class SolverInterface(pl.LightningModule, metaclass=ABCMeta): - """ Solver base class. """ +class SolverInterface(pytorch_lightning.LightningModule, metaclass=ABCMeta): + """ + Solver base class. This class inherits is a wrapper of + LightningModule class, inheriting all the + LightningModule methods. + """ + def __init__(self, models, problem, - optimizers, - optimizers_kwargs, + optimizers, + optimizers_kwargs, extra_features=None): """ :param models: A torch neural network model instance. :type models: torch.nn.Module :param problem: A problem definition instance. :type problem: AbstractProblem - :param list(torch.nn.Module) extra_features: the additional input - features to use as augmented input. If ``None`` no extra features - are passed. If it is a list of ``torch.nn.Module``, the extra feature - list is passed to all models. If it is a list of extra features' lists, - each single list of extra feature is passed to a model. + :param list(torch.optim.Optimizer) optimizer: A list of neural network optimizers to + use. + :param list(dict) optimizer_kwargs: A list of optimizer constructor keyword args. + :param list(torch.nn.Module) extra_features: The additional input + features to use as augmented input. If ``None`` no extra features + are passed. If it is a list of :class:`torch.nn.Module`, the extra feature + list is passed to all models. If it is a list of extra features' lists, + each single list of extra feature is passed to a model. """ super().__init__() @@ -52,37 +60,40 @@ class SolverInterface(pl.LightningModule, metaclass=ABCMeta): raise ValueError('You must define one optimizer for each model.' f'Got {len_model} models, and {len_optimizer}' ' optimizers.') - + # check length consistency optimizers kwargs if len_optimizer_kwargs != len_optimizer: raise ValueError('You must define one dictionary of keyword' ' arguments for each optimizers.' f'Got {len_optimizer} optimizers, and' f' {len_optimizer_kwargs} dicitionaries') - + # extra features handling - if extra_features is None: + if extra_features is None: extra_features = [None] * len_model else: # if we only have a list of extra features if not isinstance(extra_features[0], (tuple, list)): extra_features = [extra_features] * len_model - else: # if we have a list of list extra features + else: # if we have a list of list extra features if len(extra_features) != len_model: - raise ValueError('You passed a list of extrafeatures list with len' - f'different of models len. Expected {len_model} ' - f'got {len(extra_features)}. If you want to use' - 'the same list of extra features for all models, ' - 'just pass a list of extrafeatures and not a list ' - 'of list of extra features.') - + raise ValueError( + 'You passed a list of extrafeatures list with len' + f'different of models len. Expected {len_model} ' + f'got {len(extra_features)}. If you want to use' + 'the same list of extra features for all models, ' + 'just pass a list of extrafeatures and not a list ' + 'of list of extra features.') + # assigning model and optimizers self._pina_models = [] self._pina_optimizers = [] for idx in range(len_model): - model_ = Network(model=models[idx], extra_features=extra_features[idx]) - optim_ = optimizers[idx](model_.parameters(), **optimizers_kwargs[idx]) + model_ = Network(model=models[idx], + extra_features=extra_features[idx]) + optim_ = optimizers[idx](model_.parameters(), + **optimizers_kwargs[idx]) self._pina_models.append(model_) self._pina_optimizers.append(optim_) @@ -90,9 +101,9 @@ class SolverInterface(pl.LightningModule, metaclass=ABCMeta): self._pina_problem = problem @abstractmethod - def forward(self): + def forward(self, *args, **kwargs): pass - + @abstractmethod def training_step(self): pass @@ -131,4 +142,4 @@ class SolverInterface(pl.LightningModule, metaclass=ABCMeta): # """ # Set the problem formulation.""" # check_consistency(problem, AbstractProblem, 'pina problem') - # self._problem = problem \ No newline at end of file + # self._problem = problem diff --git a/pina/solvers/supervised.py b/pina/solvers/supervised.py index be86b6e..2b33405 100644 --- a/pina/solvers/supervised.py +++ b/pina/solvers/supervised.py @@ -3,7 +3,7 @@ import torch try: from torch.optim.lr_scheduler import LRScheduler # torch >= 2.0 except ImportError: - from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 + from torch.optim.lr_scheduler import _LRScheduler as LRScheduler # torch < 2.0 from torch.optim.lr_scheduler import ConstantLR @@ -19,25 +19,30 @@ class SupervisedSolver(SolverInterface): SupervisedSolver solver class. This class implements a SupervisedSolver, using a user specified ``model`` to solve a specific ``problem``. """ - def __init__(self, - problem, - model, - extra_features=None, - loss = torch.nn.MSELoss(), - optimizer=torch.optim.Adam, - optimizer_kwargs={'lr' : 0.001}, - scheduler=ConstantLR, - scheduler_kwargs={"factor": 1, "total_iters": 0}, - ): + + def __init__( + self, + problem, + model, + extra_features=None, + loss=torch.nn.MSELoss(), + optimizer=torch.optim.Adam, + optimizer_kwargs={'lr': 0.001}, + scheduler=ConstantLR, + scheduler_kwargs={ + "factor": 1, + "total_iters": 0 + }, + ): ''' :param AbstractProblem problem: The formualation of the problem. :param torch.nn.Module model: The neural network model to use. :param torch.nn.Module loss: The loss function used as minimizer, - default torch.nn.MSELoss(). + default :class:`torch.nn.MSELoss`. :param torch.nn.Module extra_features: The additional input features to use as augmented input. :param torch.optim.Optimizer optimizer: The neural network optimizer to - use; default is `torch.optim.Adam`. + use; default is :class:`torch.optim.Adam`. :param dict optimizer_kwargs: Optimizer constructor keyword args. :param float lr: The learning rate; default is 0.001. :param torch.optim.LRScheduler scheduler: Learning @@ -49,8 +54,8 @@ class SupervisedSolver(SolverInterface): optimizers=[optimizer], optimizers_kwargs=[optimizer_kwargs], extra_features=extra_features) - - # check consistency + + # check consistency check_consistency(scheduler, LRScheduler, subclass=True) check_consistency(scheduler_kwargs, dict) check_consistency(loss, (LossInterface, _Loss), subclass=False) @@ -60,13 +65,12 @@ class SupervisedSolver(SolverInterface): self._loss = loss self._neural_net = self.models[0] - def forward(self, x): """Forward pass implementation for the solver. - :param torch.tensor x: Input data. + :param torch.Tensor x: Input tensor. :return: Solver solution. - :rtype: torch.tensor + :rtype: torch.Tensor """ # extract labels x = x.extract(self.problem.input_variables) @@ -83,7 +87,7 @@ class SupervisedSolver(SolverInterface): :rtype: tuple(list, list) """ return self.optimizers, [self.scheduler] - + def training_step(self, batch, batch_idx): """Solver training step. @@ -105,9 +109,11 @@ class SupervisedSolver(SolverInterface): # data loss if hasattr(condition, 'output_points'): input_pts, output_pts = samples - loss = self.loss(self.forward(input_pts), output_pts) * condition.data_weight + loss = self.loss(self.forward(input_pts), + output_pts) * condition.data_weight else: - raise RuntimeError('Supervised solver works only in data-driven mode.') + raise RuntimeError( + 'Supervised solver works only in data-driven mode.') self.log('mean_loss', float(loss), prog_bar=True, logger=True) return loss @@ -118,17 +124,17 @@ class SupervisedSolver(SolverInterface): Scheduler for training. """ return self._scheduler - + @property def neural_net(self): """ Neural network for training. """ return self._neural_net - + @property def loss(self): """ Loss for training. """ - return self._loss \ No newline at end of file + return self._loss diff --git a/pina/trainer.py b/pina/trainer.py index fc2a938..bef8b80 100644 --- a/pina/trainer.py +++ b/pina/trainer.py @@ -1,17 +1,35 @@ -""" Solver module. """ +""" Trainer module. """ -from pytorch_lightning import Trainer +import pytorch_lightning from .utils import check_consistency from .dataset import SamplePointDataset, SamplePointLoader, DataPointDataset from .solvers.solver import SolverInterface -class Trainer(Trainer): +class Trainer(pytorch_lightning.Trainer): def __init__(self, solver, batch_size=None, **kwargs): + """ + PINA Trainer class for costumizing every aspect of training via flags. + + :param solver: A pina:class:`SolverInterface` solver for the differential problem. + :type solver: SolverInterface + :param batch_size: How many samples per batch to load. If ``batch_size=None`` all + samples are loaded and data are not batched, defaults to None. + :type batch_size: int | None + + :Keyword Arguments: + The additional keyword arguments specify the training setup + and can be choosen from the `pytorch-lightning + Trainer API `_ + """ + super().__init__(**kwargs) - # check inheritance consistency for solver + # check inheritance consistency for solver and batch size check_consistency(solver, SolverInterface) + if batch_size is not None: + check_consistency(batch_size, int) + self._model = solver self.batch_size = batch_size @@ -45,7 +63,7 @@ class Trainer(Trainer): def train(self, **kwargs): """ - Train the solver. + Train the solver method. """ return super().fit(self._model, train_dataloaders=self._loader, **kwargs) @@ -54,4 +72,4 @@ class Trainer(Trainer): """ Returning trainer solver. """ - return self._model \ No newline at end of file + return self._model diff --git a/pina/utils.py b/pina/utils.py index bff9d7b..b21499b 100644 --- a/pina/utils.py +++ b/pina/utils.py @@ -39,7 +39,9 @@ def check_consistency(object, object_instance, subclass=False): raise ValueError(f"{type(obj).__name__} must be {object_instance}.") -def number_parameters(model, aggregate=True, only_trainable=True): # TODO: check +def number_parameters(model, + aggregate=True, + only_trainable=True): # TODO: check """ Return the number of parameters of a given `model`. @@ -140,6 +142,7 @@ def chebyshev_roots(n): nodes = torch.sort(torch.cos(pi * (k + 0.5) / n))[0] return nodes + # class PinaDataset(): # def __init__(self, pinn) -> None: @@ -187,7 +190,6 @@ def chebyshev_roots(n): # return self._len - class LabelTensorDataLoader(DataLoader): def collate_fn(self, data): diff --git a/pina/writer.py b/pina/writer.py index a556c03..36d1999 100644 --- a/pina/writer.py +++ b/pina/writer.py @@ -11,10 +11,7 @@ class Writer: Implementation of a writer class, for textual output. """ - def __init__(self, - frequency_print=10, - header='any') -> None: - + def __init__(self, frequency_print=10, header='any') -> None: """ The constructor of the class. @@ -25,7 +22,6 @@ class Writer: self._frequency_print = frequency_print self._header = header - def header(self, trainer): """ The method for printing the header. @@ -42,7 +38,6 @@ class Writer: """ pass - def write_loss_in_loop(self, trainer, loss): """ The method for writing the output within the training loop. diff --git a/tests/test_callbacks/test_adaptive_refinment_callbacks.py b/tests/test_callbacks/test_adaptive_refinment_callbacks.py index 1144025..8964e46 100644 --- a/tests/test_callbacks/test_adaptive_refinment_callbacks.py +++ b/tests/test_callbacks/test_adaptive_refinment_callbacks.py @@ -1,5 +1,3 @@ - - from pina.callbacks import R3Refinement import torch import pytest @@ -7,7 +5,8 @@ import pytest from pina.problem import SpatialProblem from pina.operators import laplacian from pina.geometry import CartesianDomain -from pina import Condition, LabelTensor, PINN +from pina import Condition, LabelTensor +from pina.solvers import PINN from pina.trainer import Trainer from pina.model import FeedForward from pina.equation.equation import Equation @@ -15,15 +14,17 @@ from pina.equation.equation_factory import FixedValue def laplace_equation(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u']), input_) return delta_u - force_term + my_laplace = Equation(laplace_equation) in_ = LabelTensor(torch.tensor([[0., 1.]]), ['x', 'y']) out_ = LabelTensor(torch.tensor([[0.]]), ['u']) + class Poisson(SpatialProblem): output_variables = ['u'] spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) @@ -55,7 +56,8 @@ poisson_problem = Poisson() boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] n = 10 poisson_problem.discretise_domain(n, 'grid', locations=boundaries) -model = FeedForward(len(poisson_problem.input_variables),len(poisson_problem.output_variables)) +model = FeedForward(len(poisson_problem.input_variables), + len(poisson_problem.output_variables)) # make the solver solver = PINN(problem=poisson_problem, model=model) @@ -64,8 +66,10 @@ solver = PINN(problem=poisson_problem, model=model) def test_r3constructor(): R3Refinement(sample_every=10) + def test_r3refinment_routine(): # make the trainer - trainer = Trainer(solver=solver, callbacks=[R3Refinement(sample_every=1)], max_epochs=5) + trainer = Trainer(solver=solver, + callbacks=[R3Refinement(sample_every=1)], + max_epochs=5) trainer.train() - diff --git a/tests/test_callbacks/test_optimizer_callbacks.py b/tests/test_callbacks/test_optimizer_callbacks.py index 9250ae1..6c167b6 100644 --- a/tests/test_callbacks/test_optimizer_callbacks.py +++ b/tests/test_callbacks/test_optimizer_callbacks.py @@ -1,5 +1,3 @@ - - from pina.callbacks import SwitchOptimizer import torch import pytest @@ -7,7 +5,8 @@ import pytest from pina.problem import SpatialProblem from pina.operators import laplacian from pina.geometry import CartesianDomain -from pina import Condition, LabelTensor, PINN +from pina import Condition, LabelTensor +from pina.solvers import PINN from pina.trainer import Trainer from pina.model import FeedForward from pina.equation.equation import Equation @@ -15,15 +14,17 @@ from pina.equation.equation_factory import FixedValue def laplace_equation(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u']), input_) return delta_u - force_term + my_laplace = Equation(laplace_equation) in_ = LabelTensor(torch.tensor([[0., 1.]]), ['x', 'y']) out_ = LabelTensor(torch.tensor([[0.]]), ['u']) + class Poisson(SpatialProblem): output_variables = ['u'] spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) @@ -55,7 +56,8 @@ poisson_problem = Poisson() boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] n = 10 poisson_problem.discretise_domain(n, 'grid', locations=boundaries) -model = FeedForward(len(poisson_problem.input_variables),len(poisson_problem.output_variables)) +model = FeedForward(len(poisson_problem.input_variables), + len(poisson_problem.output_variables)) # make the solver solver = PINN(problem=poisson_problem, model=model) @@ -63,19 +65,24 @@ solver = PINN(problem=poisson_problem, model=model) def test_switch_optimizer_constructor(): SwitchOptimizer(new_optimizers=torch.optim.Adam, - new_optimizers_kwargs={'lr':0.01}, + new_optimizers_kwargs={'lr': 0.01}, epoch_switch=10) - + with pytest.raises(ValueError): SwitchOptimizer(new_optimizers=[torch.optim.Adam, torch.optim.Adam], - new_optimizers_kwargs=[{'lr':0.01}], + new_optimizers_kwargs=[{ + 'lr': 0.01 + }], epoch_switch=10) def test_switch_optimizer_routine(): # make the trainer - trainer = Trainer(solver=solver, callbacks=[SwitchOptimizer(new_optimizers=torch.optim.LBFGS, - new_optimizers_kwargs={'lr':0.01}, - epoch_switch=3)], max_epochs=5) + trainer = Trainer(solver=solver, + callbacks=[ + SwitchOptimizer(new_optimizers=torch.optim.LBFGS, + new_optimizers_kwargs={'lr': 0.01}, + epoch_switch=3) + ], + max_epochs=5) trainer.train() - diff --git a/tests/test_condition.py b/tests/test_condition.py index cb82ab6..23c9d12 100644 --- a/tests/test_condition.py +++ b/tests/test_condition.py @@ -1,17 +1,19 @@ import torch import pytest -from pina import LabelTensor, Condition, CartesianDomain, PINN +from pina import LabelTensor, Condition +from pina.solvers import PINN +from pina.geometry import CartesianDomain from pina.problem import SpatialProblem from pina.model import FeedForward from pina.operators import laplacian from pina.equation.equation_factory import FixedValue - example_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) example_input_pts = LabelTensor(torch.tensor([[0, 0, 0]]), ['x', 'y', 'z']) example_output_pts = LabelTensor(torch.tensor([[1, 2]]), ['a', 'b']) + def test_init_inputoutput(): Condition(input_points=example_input_pts, output_points=example_output_pts) with pytest.raises(ValueError): @@ -21,8 +23,9 @@ def test_init_inputoutput(): with pytest.raises(TypeError): Condition(input_points=example_domain, output_points=example_domain) + def test_init_locfunc(): - Condition(location=example_domain, equation=FixedValue(0.0)) + Condition(location=example_domain, equation=FixedValue(0.0)) with pytest.raises(ValueError): Condition(example_domain, FixedValue(0.0)) with pytest.raises(TypeError): @@ -30,6 +33,7 @@ def test_init_locfunc(): with pytest.raises(TypeError): Condition(location=example_input_pts, equation=example_output_pts) + def test_init_inputfunc(): Condition(input_points=example_input_pts, equation=FixedValue(0.0)) with pytest.raises(ValueError): diff --git a/tests/test_equations/test_equation.py b/tests/test_equations/test_equation.py index 924513e..aed4b09 100644 --- a/tests/test_equations/test_equation.py +++ b/tests/test_equations/test_equation.py @@ -4,21 +4,25 @@ from pina import LabelTensor import torch import pytest + def eq1(input_, output_): u_grad = grad(output_, input_) u1_xx = grad(u_grad, input_, components=['du1dx'], d=['x']) u2_xy = grad(u_grad, input_, components=['du2dx'], d=['y']) - return torch.hstack([u1_xx , u2_xy]) + return torch.hstack([u1_xx, u2_xy]) + def eq2(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u1']), input_) return delta_u - force_term + def foo(): pass + def test_constructor(): Equation(eq1) Equation(eq2) @@ -27,6 +31,7 @@ def test_constructor(): with pytest.raises(ValueError): Equation(foo()) + def test_residual(): eq_1 = Equation(eq1) eq_2 = Equation(eq2) diff --git a/tests/test_equations/test_systemequation.py b/tests/test_equations/test_systemequation.py index 406a479..ae6825b 100644 --- a/tests/test_equations/test_systemequation.py +++ b/tests/test_equations/test_systemequation.py @@ -4,21 +4,25 @@ from pina import LabelTensor import torch import pytest + def eq1(input_, output_): u_grad = grad(output_, input_) u1_xx = grad(u_grad, input_, components=['du1dx'], d=['x']) u2_xy = grad(u_grad, input_, components=['du2dx'], d=['y']) - return torch.hstack([u1_xx , u2_xy]) + return torch.hstack([u1_xx, u2_xy]) + def eq2(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u1']), input_) return delta_u - force_term + def foo(): pass + def test_constructor(): SystemEquation([eq1, eq2]) SystemEquation([eq1, eq2], reduction='sum') @@ -27,6 +31,7 @@ def test_constructor(): with pytest.raises(ValueError): SystemEquation(foo) + def test_residual(): pts = LabelTensor(torch.rand(10, 2), labels=['x', 'y']) diff --git a/tests/test_geometry/test_cartesian.py b/tests/test_geometry/test_cartesian.py index 405c50d..3e7a8c9 100644 --- a/tests/test_geometry/test_cartesian.py +++ b/tests/test_geometry/test_cartesian.py @@ -1,12 +1,7 @@ import torch -import pytest - -from pina import LabelTensor, Condition, CartesianDomain, PINN -from pina.problem import SpatialProblem -from pina.model import FeedForward -from pina.operators import laplacian - +from pina import LabelTensor +from pina.geometry import CartesianDomain def test_constructor(): CartesianDomain({'x': [0, 1], 'y': [0, 1]}) @@ -20,6 +15,7 @@ def test_is_inside_check_border(): for pt, exp_result in zip([pt_1, pt_2, pt_3], [True, True, False]): assert domain.is_inside(pt, check_border=True) == exp_result + def test_is_inside_not_check_border(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[1.0, 0.5]]), ['x', 'y']) @@ -28,6 +24,7 @@ def test_is_inside_not_check_border(): for pt, exp_result in zip([pt_1, pt_2, pt_3], [True, False, False]): assert domain.is_inside(pt, check_border=False) == exp_result + def test_is_inside_fixed_variables(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[1.0, 0.5]]), ['x', 'y']) diff --git a/tests/test_geometry/test_difference.py b/tests/test_geometry/test_difference.py index e174521..b165fa7 100644 --- a/tests/test_geometry/test_difference.py +++ b/tests/test_geometry/test_difference.py @@ -5,25 +5,63 @@ from pina.geometry import Difference, EllipsoidDomain, CartesianDomain def test_constructor_two_CartesianDomains(): - Difference([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + Difference([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) def test_constructor_two_3DCartesianDomain(): - Difference([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + Difference([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) def test_constructor_three_CartesianDomains(): - Difference([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), CartesianDomain( - {'x': [1, 3], 'y': [1, 3]}), CartesianDomain({'x': [2, 4], 'y': [2, 4]})]) + Difference([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }), + CartesianDomain({ + 'x': [2, 4], + 'y': [2, 4] + }) + ]) def test_is_inside_two_CartesianDomains(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[-1, -0.5]]), ['x', 'y']) - domain = Difference([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + domain = Difference([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False @@ -31,16 +69,34 @@ def test_is_inside_two_CartesianDomains(): def test_is_inside_two_3DCartesianDomain(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5, 0.5]]), ['x', 'y', 'z']) pt_2 = LabelTensor(torch.tensor([[-1, -0.5, -0.5]]), ['x', 'y', 'z']) - domain = Difference([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [ - 0, 2]}), CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + domain = Difference([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False def test_sample(): n = 100 - domain = Difference([EllipsoidDomain( - {'x': [-1, 1], 'y': [-1, 1]}), CartesianDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5]})]) + domain = Difference([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1] + }), + CartesianDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5] + }) + ]) pts = domain.sample(n) assert isinstance(pts, LabelTensor) assert pts.shape[0] == n diff --git a/tests/test_geometry/test_ellipsoid.py b/tests/test_geometry/test_ellipsoid.py index 293cfd9..9ab0989 100644 --- a/tests/test_geometry/test_ellipsoid.py +++ b/tests/test_geometry/test_ellipsoid.py @@ -5,14 +5,13 @@ from pina import LabelTensor from pina.geometry import EllipsoidDomain - def test_constructor(): EllipsoidDomain({'x': [0, 1], 'y': [0, 1]}) - EllipsoidDomain({'x': [0, 1], 'y':[0, 1]}, sample_surface=True) + EllipsoidDomain({'x': [0, 1], 'y': [0, 1]}, sample_surface=True) def test_is_inside_sample_surface_false(): - domain = EllipsoidDomain({'x': [0, 1], 'y':[0, 1]}, sample_surface=False) + domain = EllipsoidDomain({'x': [0, 1], 'y': [0, 1]}, sample_surface=False) pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[1.0, 0.5]]), ['x', 'y']) pt_3 = LabelTensor(torch.tensor([[1.5, 0.5]]), ['x', 'y']) @@ -21,10 +20,11 @@ def test_is_inside_sample_surface_false(): for pt, exp_result in zip([pt_1, pt_2, pt_3], [True, True, False]): assert domain.is_inside(pt, check_border=True) == exp_result + def test_is_inside_sample_surface_true(): - domain = EllipsoidDomain({'x': [0, 1], 'y':[0, 1]}, sample_surface=True) + domain = EllipsoidDomain({'x': [0, 1], 'y': [0, 1]}, sample_surface=True) pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[1.0, 0.5]]), ['x', 'y']) pt_3 = LabelTensor(torch.tensor([[1.5, 0.5]]), ['x', 'y']) for pt, exp_result in zip([pt_1, pt_2, pt_3], [False, True, False]): - assert domain.is_inside(pt) == exp_result \ No newline at end of file + assert domain.is_inside(pt) == exp_result diff --git a/tests/test_geometry/test_exclusion.py b/tests/test_geometry/test_exclusion.py index 2ae53f3..b6400cd 100644 --- a/tests/test_geometry/test_exclusion.py +++ b/tests/test_geometry/test_exclusion.py @@ -5,25 +5,63 @@ from pina.geometry import Exclusion, EllipsoidDomain, CartesianDomain def test_constructor_two_CartesianDomains(): - Exclusion([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + Exclusion([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) def test_constructor_two_3DCartesianDomain(): - Exclusion([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + Exclusion([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) def test_constructor_three_CartesianDomains(): - Exclusion([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), CartesianDomain( - {'x': [1, 3], 'y': [1, 3]}), CartesianDomain({'x': [2, 4], 'y': [2, 4]})]) + Exclusion([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }), + CartesianDomain({ + 'x': [2, 4], + 'y': [2, 4] + }) + ]) def test_is_inside_two_CartesianDomains(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[-1, -0.5]]), ['x', 'y']) - domain = Exclusion([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + domain = Exclusion([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False @@ -31,16 +69,34 @@ def test_is_inside_two_CartesianDomains(): def test_is_inside_two_3DCartesianDomain(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5, 0.5]]), ['x', 'y', 'z']) pt_2 = LabelTensor(torch.tensor([[-1, -0.5, -0.5]]), ['x', 'y', 'z']) - domain = Exclusion([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [ - 0, 2]}), CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + domain = Exclusion([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False def test_sample(): n = 100 - domain = Exclusion([EllipsoidDomain( - {'x': [-1, 1], 'y': [-1, 1]}), CartesianDomain({'x': [0.3, 1.5], 'y': [0.3, 1.5]})]) + domain = Exclusion([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1] + }), + CartesianDomain({ + 'x': [0.3, 1.5], + 'y': [0.3, 1.5] + }) + ]) pts = domain.sample(n) assert isinstance(pts, LabelTensor) assert pts.shape[0] == n diff --git a/tests/test_geometry/test_intersection.py b/tests/test_geometry/test_intersection.py index 1c5cd81..6106107 100644 --- a/tests/test_geometry/test_intersection.py +++ b/tests/test_geometry/test_intersection.py @@ -5,18 +5,48 @@ from pina.geometry import Intersection, EllipsoidDomain, CartesianDomain def test_constructor_two_CartesianDomains(): - Intersection([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + Intersection([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) def test_constructor_two_3DCartesianDomain(): - Intersection([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + Intersection([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) def test_constructor_three_CartesianDomains(): - Intersection([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), CartesianDomain( - {'x': [1, 3], 'y': [1, 3]}), CartesianDomain({'x': [2, 4], 'y': [2, 4]})]) + Intersection([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }), + CartesianDomain({ + 'x': [2, 4], + 'y': [2, 4] + }) + ]) def test_is_inside_two_CartesianDomains(): @@ -24,8 +54,16 @@ def test_is_inside_two_CartesianDomains(): pt_2 = LabelTensor(torch.tensor([[-1, -0.5]]), ['x', 'y']) pt_3 = LabelTensor(torch.tensor([[1.5, 1.5]]), ['x', 'y']) - domain = Intersection([CartesianDomain({'x': [0, 2], 'y': [0, 2]}), - CartesianDomain({'x': [1, 3], 'y': [1, 3]})]) + domain = Intersection([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == False assert domain.is_inside(pt_2) == False assert domain.is_inside(pt_3) == True @@ -35,8 +73,18 @@ def test_is_inside_two_3DCartesianDomain(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5, 0.5]]), ['x', 'y', 'z']) pt_2 = LabelTensor(torch.tensor([[-1, -0.5, -0.5]]), ['x', 'y', 'z']) pt_3 = LabelTensor(torch.tensor([[1.5, 1.5, 1.5]]), ['x', 'y', 'z']) - domain = Intersection([CartesianDomain({'x': [0, 2], 'y': [0, 2], 'z': [ - 0, 2]}), CartesianDomain({'x': [1, 3], 'y': [1, 3], 'z': [1, 3]})]) + domain = Intersection([ + CartesianDomain({ + 'x': [0, 2], + 'y': [0, 2], + 'z': [0, 2] + }), + CartesianDomain({ + 'x': [1, 3], + 'y': [1, 3], + 'z': [1, 3] + }) + ]) assert domain.is_inside(pt_1) == False assert domain.is_inside(pt_2) == False assert domain.is_inside(pt_3) == True @@ -44,8 +92,16 @@ def test_is_inside_two_3DCartesianDomain(): def test_sample(): n = 100 - domain = Intersection([EllipsoidDomain( - {'x': [-1, 1], 'y': [-1, 1]}), CartesianDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5]})]) + domain = Intersection([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1] + }), + CartesianDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5] + }) + ]) pts = domain.sample(n) assert isinstance(pts, LabelTensor) assert pts.shape[0] == n diff --git a/tests/test_geometry/test_simplex.py b/tests/test_geometry/test_simplex.py index 8c4d864..1f59585 100644 --- a/tests/test_geometry/test_simplex.py +++ b/tests/test_geometry/test_simplex.py @@ -6,13 +6,11 @@ from pina.geometry import SimplexDomain def test_constructor(): - SimplexDomain( - [ - LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[1, 1]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), - ] - ) + SimplexDomain([ + LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[1, 1]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), + ]) SimplexDomain( [ LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), @@ -23,40 +21,33 @@ def test_constructor(): ) with pytest.raises(ValueError): # different labels - SimplexDomain( - [ - LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[1, 1]]), labels=["x", "z"]), - LabelTensor(torch.tensor([[0, 2]]), labels=["x", "a"]), - ] - ) + SimplexDomain([ + LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[1, 1]]), labels=["x", "z"]), + LabelTensor(torch.tensor([[0, 2]]), labels=["x", "a"]), + ]) # not LabelTensor - SimplexDomain( - [ - LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), - [1, 1], - LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), - ] - ) + SimplexDomain([ + LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), + [1, 1], + LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), + ]) # different number of vertices - SimplexDomain( - [ - LabelTensor(torch.tensor([[ 0., -2.]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[-.5, -.5]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[-2., 0.]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[-.5, .5]]), labels=["x", "y"]), - ] - ) + SimplexDomain([ + LabelTensor(torch.tensor([[0., -2.]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[-.5, -.5]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[-2., 0.]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[-.5, .5]]), labels=["x", "y"]), + ]) + def test_sample(): # sampling inside - simplex = SimplexDomain( - [ - LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[1, 1]]), labels=["x", "y"]), - LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), - ] - ) + simplex = SimplexDomain([ + LabelTensor(torch.tensor([[0, 0]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[1, 1]]), labels=["x", "y"]), + LabelTensor(torch.tensor([[0, 2]]), labels=["x", "y"]), + ]) pts = simplex.sample(10) assert isinstance(pts, LabelTensor) assert pts.size() == torch.Size([10, 2]) @@ -127,7 +118,8 @@ def test_is_inside_2D_check_border_false(): pt6 = LabelTensor(torch.tensor([[2.5, 1]]), ["x", "y"]) pt7 = LabelTensor(torch.tensor([[100, 100]]), ["x", "y"]) pts = [pt1, pt2, pt3, pt4, pt5, pt6, pt7] - for pt, exp_result in zip(pts, [False, False, False, False, True, True, False]): + for pt, exp_result in zip(pts, + [False, False, False, False, True, True, False]): assert domain.is_inside(point=pt, check_border=False) == exp_result @@ -152,8 +144,7 @@ def test_is_inside_3D_check_border_true(): pt9 = LabelTensor(torch.tensor([[2, 1, 1]]), ["x", "y", "z"]) pts = [pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, pt9] for pt, exp_result in zip( - pts, [True, True, True, True, True, False, True, True, False] - ): + pts, [True, True, True, True, True, False, True, True, False]): assert domain.is_inside(point=pt, check_border=True) == exp_result @@ -175,5 +166,6 @@ def test_is_inside_3D_check_border_false(): pt6 = LabelTensor(torch.tensor([[0, 0, 20]]), ["x", "y", "z"]) pt7 = LabelTensor(torch.tensor([[2, 1, 1]]), ["x", "y", "z"]) pts = [pt1, pt2, pt3, pt4, pt5, pt6, pt7] - for pt, exp_result in zip(pts, [False, False, False, False, False, False, True]): + for pt, exp_result in zip(pts, + [False, False, False, False, False, False, True]): assert domain.is_inside(point=pt, check_border=False) == exp_result diff --git a/tests/test_geometry/test_union.py b/tests/test_geometry/test_union.py index 07787a3..16f8bca 100644 --- a/tests/test_geometry/test_union.py +++ b/tests/test_geometry/test_union.py @@ -5,25 +5,59 @@ from pina.geometry import Union, EllipsoidDomain, CartesianDomain def test_constructor_two_CartesianDomains(): - Union([CartesianDomain({'x': [0, 1], 'y': [0, 1]}), - CartesianDomain({'x': [0.5, 2], 'y': [-1, 0.1]})]) + Union([ + CartesianDomain({ + 'x': [0, 1], + 'y': [0, 1] + }), + CartesianDomain({ + 'x': [0.5, 2], + 'y': [-1, 0.1] + }) + ]) def test_constructor_two_EllipsoidDomains(): - Union([EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1], 'z': [-1, 1]}), - EllipsoidDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5], 'z': [-0.5, 0.5]})]) + Union([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1], + 'z': [-1, 1] + }), + EllipsoidDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5], + 'z': [-0.5, 0.5] + }) + ]) def test_constructor_EllipsoidDomain_CartesianDomain(): - Union([EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}), - CartesianDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5]})]) + Union([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1] + }), + CartesianDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5] + }) + ]) def test_is_inside_two_CartesianDomains(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[-1, -1]]), ['x', 'y']) - domain = Union([CartesianDomain({'x': [0, 1], 'y': [0, 1]}), - CartesianDomain({'x': [0.5, 2], 'y': [-1, 0.1]})]) + domain = Union([ + CartesianDomain({ + 'x': [0, 1], + 'y': [0, 1] + }), + CartesianDomain({ + 'x': [0.5, 2], + 'y': [-1, 0.1] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False @@ -31,8 +65,18 @@ def test_is_inside_two_CartesianDomains(): def test_is_inside_two_EllipsoidDomains(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5, 0.5]]), ['x', 'y', 'z']) pt_2 = LabelTensor(torch.tensor([[-1, -1, -1]]), ['x', 'y', 'z']) - domain = Union([EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1], 'z': [-1, 1]}), - EllipsoidDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5], 'z': [-0.5, 0.5]})]) + domain = Union([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1], + 'z': [-1, 1] + }), + EllipsoidDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5], + 'z': [-0.5, 0.5] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False @@ -40,16 +84,32 @@ def test_is_inside_two_EllipsoidDomains(): def test_is_inside_EllipsoidDomain_CartesianDomain(): pt_1 = LabelTensor(torch.tensor([[0.5, 0.5]]), ['x', 'y']) pt_2 = LabelTensor(torch.tensor([[-1, -1]]), ['x', 'y']) - domain = Union([EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1], }), - CartesianDomain({'x': [0.6, 1.5], 'y': [-2, 0]})]) + domain = Union([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1], + }), + CartesianDomain({ + 'x': [0.6, 1.5], + 'y': [-2, 0] + }) + ]) assert domain.is_inside(pt_1) == True assert domain.is_inside(pt_2) == False def test_sample(): n = 100 - domain = Union([EllipsoidDomain({'x': [-1, 1], 'y': [-1, 1]}), - CartesianDomain({'x': [-0.5, 0.5], 'y': [-0.5, 0.5]})]) + domain = Union([ + EllipsoidDomain({ + 'x': [-1, 1], + 'y': [-1, 1] + }), + CartesianDomain({ + 'x': [-0.5, 0.5], + 'y': [-0.5, 0.5] + }) + ]) pts = domain.sample(n) assert isinstance(pts, LabelTensor) assert pts.shape[0] == n diff --git a/tests/test_label_tensor.py b/tests/test_label_tensor.py index 1365aec..05dace5 100644 --- a/tests/test_label_tensor.py +++ b/tests/test_label_tensor.py @@ -71,6 +71,7 @@ def test_merge(): tensor_bc = tensor_b.append(tensor_c) assert torch.allclose(tensor_bc, tensor.extract(['b', 'c'])) + def test_merge2(): tensor = LabelTensor(data, labels) tensor_b = tensor.extract('b') diff --git a/tests/test_layers/test_conv.py b/tests/test_layers/test_conv.py index f0ba2af..f8ef437 100644 --- a/tests/test_layers/test_conv.py +++ b/tests/test_layers/test_conv.py @@ -10,6 +10,7 @@ def prod(iterable): def make_grid(x): + def _transform_image(image): # extracting image info @@ -17,11 +18,13 @@ def make_grid(x): # initializing transfomed image coordinates = torch.zeros( - [channels, prod(dimension), len(dimension) + 1]).to(image.device) + [channels, prod(dimension), + len(dimension) + 1]).to(image.device) # creating the n dimensional mesh grid - values_mesh = [torch.arange(0, dim).float().to( - image.device) for dim in dimension] + values_mesh = [ + torch.arange(0, dim).float().to(image.device) for dim in dimension + ] mesh = torch.meshgrid(values_mesh) coordinates_mesh = [x.reshape(-1, 1) for x in mesh] coordinates_mesh.append(0) @@ -40,11 +43,9 @@ class MLP(torch.nn.Module): def __init__(self) -> None: super().__init__() - self. model = torch.nn.Sequential(torch.nn.Linear(2, 8), - torch.nn.ReLU(), - torch.nn.Linear(8, 8), - torch.nn.ReLU(), - torch.nn.Linear(8, 1)) + self.model = torch.nn.Sequential(torch.nn.Linear(2, 8), torch.nn.ReLU(), + torch.nn.Linear(8, 8), torch.nn.ReLU(), + torch.nn.Linear(8, 1)) def forward(self, x): return self.model(x) @@ -56,10 +57,12 @@ channel_output = 6 batch = 2 N = 10 dim = [3, 3] -stride = {"domain": [10, 10], - "start": [0, 0], - "jumps": [3, 3], - "direction": [1, 1.]} +stride = { + "domain": [10, 10], + "start": [0, 0], + "jumps": [3, 3], + "direction": [1, 1.] +} dim_filter = len(dim) dim_input = (batch, channel_input, 10, dim_filter) dim_output = (batch, channel_output, 4, dim_filter) @@ -71,15 +74,15 @@ def test_constructor(): model = MLP conv = ContinuousConvBlock(channel_input, - channel_output, - dim, - stride, - model=model) + channel_output, + dim, + stride, + model=model) conv = ContinuousConvBlock(channel_input, - channel_output, - dim, - stride, - model=None) + channel_output, + dim, + stride, + model=None) def test_forward(): @@ -87,19 +90,19 @@ def test_forward(): # simple forward conv = ContinuousConvBlock(channel_input, - channel_output, - dim, - stride, - model=model) + channel_output, + dim, + stride, + model=model) conv(x) # simple forward with optimization conv = ContinuousConvBlock(channel_input, - channel_output, - dim, - stride, - model=model, - optimize=True) + channel_output, + dim, + stride, + model=model, + optimize=True) conv(x) @@ -108,16 +111,16 @@ def test_transpose(): # simple transpose conv = ContinuousConvBlock(channel_input, - channel_output, - dim, - stride, - model=model) + channel_output, + dim, + stride, + model=model) conv2 = ContinuousConvBlock(channel_output, - channel_input, - dim, - stride, - model=model) + channel_input, + dim, + stride, + model=model) integrals = conv(x) conv2.transpose(integrals[..., -1], x) @@ -137,4 +140,4 @@ def test_transpose(): # no_overlap=True) # integrals = conv(x) - # conv.transpose(integrals[..., -1], x) \ No newline at end of file + # conv.transpose(integrals[..., -1], x) diff --git a/tests/test_layers/test_fourier.py b/tests/test_layers/test_fourier.py index af9425a..826c445 100644 --- a/tests/test_layers/test_fourier.py +++ b/tests/test_layers/test_fourier.py @@ -5,39 +5,44 @@ input_numb_fields = 3 output_numb_fields = 4 batch = 5 + def test_constructor_1d(): FourierBlock1D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=5) - + output_numb_fields=output_numb_fields, + n_modes=5) + + def test_forward_1d(): sconv = FourierBlock1D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=4) + output_numb_fields=output_numb_fields, + n_modes=4) x = torch.rand(batch, input_numb_fields, 10) sconv(x) def test_constructor_2d(): FourierBlock2D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=[5, 4]) - + output_numb_fields=output_numb_fields, + n_modes=[5, 4]) + + def test_forward_2d(): sconv = FourierBlock2D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=[5, 4]) + output_numb_fields=output_numb_fields, + n_modes=[5, 4]) x = torch.rand(batch, input_numb_fields, 10, 10) sconv(x) + def test_constructor_3d(): FourierBlock3D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=[5, 4, 4]) - + output_numb_fields=output_numb_fields, + n_modes=[5, 4, 4]) + + def test_forward_3d(): sconv = FourierBlock3D(input_numb_fields=input_numb_fields, - output_numb_fields=output_numb_fields, - n_modes=[5, 4, 4]) + output_numb_fields=output_numb_fields, + n_modes=[5, 4, 4]) x = torch.rand(batch, input_numb_fields, 10, 10, 10) sconv(x) diff --git a/tests/test_layers/test_residual.py b/tests/test_layers/test_residual.py index 2d2135f..fc61b7f 100644 --- a/tests/test_layers/test_residual.py +++ b/tests/test_layers/test_residual.py @@ -1,26 +1,69 @@ -from pina.model.layers import ResidualBlock +from pina.model.layers import ResidualBlock, EnhancedLinear import torch +import torch.nn as nn -def test_constructor(): +def test_constructor_residual_block(): + + res_block = ResidualBlock(input_dim=10, output_dim=3, hidden_dim=4) - res_block = ResidualBlock(input_dim=10, - output_dim=3, - hidden_dim=4) - res_block = ResidualBlock(input_dim=10, output_dim=3, hidden_dim=4, spectral_norm=True) -def test_forward(): +def test_forward_residual_block(): + + res_block = ResidualBlock(input_dim=10, output_dim=3, hidden_dim=4) - res_block = ResidualBlock(input_dim=10, - output_dim=3, - hidden_dim=4) - x = torch.rand(size=(80, 10)) y = res_block(x) - assert y.shape[1]==3 - assert y.shape[0]==x.shape[0] + assert y.shape[1] == 3 + assert y.shape[0] == x.shape[0] + +def test_constructor_no_activation_no_dropout(): + linear_layer = nn.Linear(10, 20) + enhanced_linear = EnhancedLinear(linear_layer) + + assert len(list(enhanced_linear.parameters())) == len(list(linear_layer.parameters())) + +def test_constructor_with_activation_no_dropout(): + linear_layer = nn.Linear(10, 20) + activation = nn.ReLU() + enhanced_linear = EnhancedLinear(linear_layer, activation) + + assert len(list(enhanced_linear.parameters())) == len(list(linear_layer.parameters())) + len(list(activation.parameters())) + +def test_constructor_no_activation_with_dropout(): + linear_layer = nn.Linear(10, 20) + dropout_prob = 0.5 + enhanced_linear = EnhancedLinear(linear_layer, dropout=dropout_prob) + + assert len(list(enhanced_linear.parameters())) == len(list(linear_layer.parameters())) + +def test_constructor_with_activation_with_dropout(): + linear_layer = nn.Linear(10, 20) + activation = nn.ReLU() + dropout_prob = 0.5 + enhanced_linear = EnhancedLinear(linear_layer, activation, dropout_prob) + + assert len(list(enhanced_linear.parameters())) == len(list(linear_layer.parameters())) + len(list(activation.parameters())) + +def test_forward_enhanced_linear_no_dropout(): + + enhanced_linear = EnhancedLinear(nn.Linear(10, 3)) + + x = torch.rand(size=(80, 10)) + y = enhanced_linear(x) + assert y.shape[1] == 3 + assert y.shape[0] == x.shape[0] + +def test_forward_enhanced_linear_dropout(): + + enhanced_linear = EnhancedLinear(nn.Linear(10, 3), dropout=0.5) + + x = torch.rand(size=(80, 10)) + y = enhanced_linear(x) + assert y.shape[1] == 3 + assert y.shape[0] == x.shape[0] \ No newline at end of file diff --git a/tests/test_layers/test_spectral_conv.py b/tests/test_layers/test_spectral_conv.py index db9f399..129d38b 100644 --- a/tests/test_layers/test_spectral_conv.py +++ b/tests/test_layers/test_spectral_conv.py @@ -5,11 +5,13 @@ input_numb_fields = 3 output_numb_fields = 4 batch = 5 + def test_constructor_1d(): SpectralConvBlock1D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, n_modes=5) - + + def test_forward_1d(): sconv = SpectralConvBlock1D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, @@ -22,7 +24,8 @@ def test_constructor_2d(): SpectralConvBlock2D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, n_modes=[5, 4]) - + + def test_forward_2d(): sconv = SpectralConvBlock2D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, @@ -30,11 +33,13 @@ def test_forward_2d(): x = torch.rand(batch, input_numb_fields, 10, 10) sconv(x) + def test_constructor_3d(): SpectralConvBlock3D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, n_modes=[5, 4, 4]) - + + def test_forward_3d(): sconv = SpectralConvBlock3D(input_numb_fields=input_numb_fields, output_numb_fields=output_numb_fields, diff --git a/tests/test_loss/test_lploss.py b/tests/test_loss/test_lploss.py index 24db012..3743970 100644 --- a/tests/test_loss/test_lploss.py +++ b/tests/test_loss/test_lploss.py @@ -16,34 +16,33 @@ def test_LpLoss_constructor(): for p in [float('inf'), -float('inf'), 1, 10, -8]: LpLoss(p=p) + def test_LpLoss_forward(): # l2 loss loss = LpLoss(p=2, reduction='mean') - l2_loss = torch.mean(torch.sqrt((input-target).pow(2))) + l2_loss = torch.mean(torch.sqrt((input - target).pow(2))) assert loss(input, target) == l2_loss # l1 loss loss = LpLoss(p=1, reduction='sum') - l1_loss = torch.sum(torch.abs(input-target)) + l1_loss = torch.sum(torch.abs(input - target)) assert loss(input, target) == l1_loss + def test_LpRelativeLoss_constructor(): # test reduction for reduction in available_reductions: LpLoss(reduction=reduction, relative=True) # test p for p in [float('inf'), -float('inf'), 1, 10, -8]: - LpLoss(p=p,relative=True) + LpLoss(p=p, relative=True) + def test_LpRelativeLoss_forward(): # l2 relative loss - loss = LpLoss(p=2, reduction='mean',relative=True) - l2_loss = torch.sqrt((input-target).pow(2))/torch.sqrt(input.pow(2)) + loss = LpLoss(p=2, reduction='mean', relative=True) + l2_loss = torch.sqrt((input - target).pow(2)) / torch.sqrt(input.pow(2)) assert loss(input, target) == torch.mean(l2_loss) # l1 relative loss - loss = LpLoss(p=1, reduction='sum',relative=True) - l1_loss = torch.abs(input-target)/torch.abs(input) + loss = LpLoss(p=1, reduction='sum', relative=True) + l1_loss = torch.abs(input - target) / torch.abs(input) assert loss(input, target) == torch.sum(l1_loss) - - - - diff --git a/tests/test_loss/test_powerloss.py b/tests/test_loss/test_powerloss.py index 5f72718..7ea2675 100644 --- a/tests/test_loss/test_powerloss.py +++ b/tests/test_loss/test_powerloss.py @@ -16,34 +16,33 @@ def test_PowerLoss_constructor(): for p in [float('inf'), -float('inf'), 1, 10, -8]: PowerLoss(p=p) + def test_PowerLoss_forward(): # l2 loss loss = PowerLoss(p=2, reduction='mean') - l2_loss = torch.mean((input-target).pow(2)) + l2_loss = torch.mean((input - target).pow(2)) assert loss(input, target) == l2_loss # l1 loss loss = PowerLoss(p=1, reduction='sum') - l1_loss = torch.sum(torch.abs(input-target)) + l1_loss = torch.sum(torch.abs(input - target)) assert loss(input, target) == l1_loss + def test_LpRelativeLoss_constructor(): # test reduction for reduction in available_reductions: PowerLoss(reduction=reduction, relative=True) # test p for p in [float('inf'), -float('inf'), 1, 10, -8]: - PowerLoss(p=p,relative=True) + PowerLoss(p=p, relative=True) + def test_LpRelativeLoss_forward(): # l2 relative loss - loss = PowerLoss(p=2, reduction='mean',relative=True) - l2_loss = (input-target).pow(2)/input.pow(2) + loss = PowerLoss(p=2, reduction='mean', relative=True) + l2_loss = (input - target).pow(2) / input.pow(2) assert loss(input, target) == torch.mean(l2_loss) # l1 relative loss - loss = PowerLoss(p=1, reduction='sum',relative=True) - l1_loss = torch.abs(input-target)/torch.abs(input) + loss = PowerLoss(p=1, reduction='sum', relative=True) + l1_loss = torch.abs(input - target) / torch.abs(input) assert loss(input, target) == torch.sum(l1_loss) - - - - diff --git a/tests/test_model/test_deeponet.py b/tests/test_model/test_deeponet.py index 348175b..cfba614 100644 --- a/tests/test_model/test_deeponet.py +++ b/tests/test_model/test_deeponet.py @@ -32,36 +32,39 @@ def test_constructor_fails_when_invalid_inner_layer_size(): reduction='+', aggregator='*') + def test_forward_extract_str(): branch_net = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=2, output_dimensions=10) model = DeepONet(branch_net=branch_net, - trunk_net=trunk_net, - input_indeces_branch_net=['a'], - input_indeces_trunk_net=['b', 'c'], - reduction='+', - aggregator='*') + trunk_net=trunk_net, + input_indeces_branch_net=['a'], + input_indeces_trunk_net=['b', 'c'], + reduction='+', + aggregator='*') model(input_) + def test_forward_extract_int(): branch_net = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=2, output_dimensions=10) model = DeepONet(branch_net=branch_net, - trunk_net=trunk_net, - input_indeces_branch_net=[0], - input_indeces_trunk_net=[1, 2], - reduction='+', - aggregator='*') + trunk_net=trunk_net, + input_indeces_branch_net=[0], + input_indeces_trunk_net=[1, 2], + reduction='+', + aggregator='*') model(data) + def test_forward_extract_str_wrong(): branch_net = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=2, output_dimensions=10) model = DeepONet(branch_net=branch_net, - trunk_net=trunk_net, - input_indeces_branch_net=['a'], - input_indeces_trunk_net=['b', 'c'], - reduction='+', - aggregator='*') + trunk_net=trunk_net, + input_indeces_branch_net=['a'], + input_indeces_trunk_net=['b', 'c'], + reduction='+', + aggregator='*') with pytest.raises(RuntimeError): model(data) diff --git a/tests/test_model/test_fnn.py b/tests/test_model/test_fnn.py index 20f2d8c..bdd38fe 100644 --- a/tests/test_model/test_fnn.py +++ b/tests/test_model/test_fnn.py @@ -3,7 +3,6 @@ import pytest from pina.model import FeedForward - data = torch.rand((20, 3)) input_vars = 3 output_vars = 4 @@ -13,19 +12,24 @@ def test_constructor(): FeedForward(input_vars, output_vars) FeedForward(input_vars, output_vars, inner_size=10, n_layers=20) FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2]) - FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2], + FeedForward(input_vars, + output_vars, + layers=[10, 20, 5, 2], func=torch.nn.ReLU) - FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2], + FeedForward(input_vars, + output_vars, + layers=[10, 20, 5, 2], func=[torch.nn.ReLU, torch.nn.ReLU, None, torch.nn.Tanh]) def test_constructor_wrong(): with pytest.raises(RuntimeError): - FeedForward(input_vars, output_vars, layers=[10, 20, 5, 2], + FeedForward(input_vars, + output_vars, + layers=[10, 20, 5, 2], func=[torch.nn.ReLU, torch.nn.ReLU]) - def test_forward(): dim_in, dim_out = 3, 2 fnn = FeedForward(dim_in, dim_out) diff --git a/tests/test_model/test_fno.py b/tests/test_model/test_fno.py index 7c2613c..322ce1f 100644 --- a/tests/test_model/test_fno.py +++ b/tests/test_model/test_fno.py @@ -1,7 +1,6 @@ import torch from pina.model import FNO - output_channels = 5 batch_size = 15 resolution = [30, 40, 50] @@ -11,7 +10,7 @@ lifting_dim = 128 def test_constructor(): input_channels = 3 lifting_net = torch.nn.Linear(input_channels, lifting_dim) - projecting_net = torch.nn.Linear(60, output_channels) + projecting_net = torch.nn.Linear(60, output_channels) # simple constructor FNO(lifting_net=lifting_net, @@ -20,7 +19,7 @@ def test_constructor(): dimensions=3, inner_size=60, n_layers=5) - + # simple constructor with n_modes list FNO(lifting_net=lifting_net, projecting_net=projecting_net, @@ -36,53 +35,61 @@ def test_constructor(): dimensions=3, inner_size=60, n_layers=2) - + # simple constructor with n_modes list of list - projecting_net = torch.nn.Linear(50, output_channels) + projecting_net = torch.nn.Linear(50, output_channels) FNO(lifting_net=lifting_net, projecting_net=projecting_net, n_modes=5, dimensions=3, layers=[50, 50]) - + + def test_1d_forward(): input_channels = 1 input_ = torch.rand(batch_size, resolution[0], input_channels) lifting_net = torch.nn.Linear(input_channels, lifting_dim) projecting_net = torch.nn.Linear(60, output_channels) fno = FNO(lifting_net=lifting_net, - projecting_net=projecting_net, - n_modes=5, - dimensions=1, - inner_size=60, - n_layers=2) + projecting_net=projecting_net, + n_modes=5, + dimensions=1, + inner_size=60, + n_layers=2) out = fno(input_) assert out.shape == torch.Size([batch_size, resolution[0], output_channels]) + def test_2d_forward(): input_channels = 2 - input_ = torch.rand(batch_size, resolution[0], resolution[1], input_channels) + input_ = torch.rand(batch_size, resolution[0], resolution[1], + input_channels) lifting_net = torch.nn.Linear(input_channels, lifting_dim) projecting_net = torch.nn.Linear(60, output_channels) fno = FNO(lifting_net=lifting_net, - projecting_net=projecting_net, - n_modes=5, - dimensions=2, - inner_size=60, - n_layers=2) + projecting_net=projecting_net, + n_modes=5, + dimensions=2, + inner_size=60, + n_layers=2) out = fno(input_) - assert out.shape == torch.Size([batch_size, resolution[0], resolution[1], output_channels]) + assert out.shape == torch.Size( + [batch_size, resolution[0], resolution[1], output_channels]) + def test_3d_forward(): input_channels = 3 - input_ = torch.rand(batch_size, resolution[0], resolution[1], resolution[2], input_channels) + input_ = torch.rand(batch_size, resolution[0], resolution[1], resolution[2], + input_channels) lifting_net = torch.nn.Linear(input_channels, lifting_dim) projecting_net = torch.nn.Linear(60, output_channels) fno = FNO(lifting_net=lifting_net, - projecting_net=projecting_net, - n_modes=5, - dimensions=3, - inner_size=60, - n_layers=2) + projecting_net=projecting_net, + n_modes=5, + dimensions=3, + inner_size=60, + n_layers=2) out = fno(input_) - assert out.shape == torch.Size([batch_size, resolution[0], resolution[1], resolution[2], output_channels]) \ No newline at end of file + assert out.shape == torch.Size([ + batch_size, resolution[0], resolution[1], resolution[2], output_channels + ]) diff --git a/tests/test_model/test_mionet.py b/tests/test_model/test_mionet.py index 1983429..4e9c03c 100644 --- a/tests/test_model/test_mionet.py +++ b/tests/test_model/test_mionet.py @@ -14,59 +14,42 @@ def test_constructor(): branch_net1 = FeedForward(input_dimensions=1, output_dimensions=10) branch_net2 = FeedForward(input_dimensions=2, output_dimensions=10) trunk_net = FeedForward(input_dimensions=1, output_dimensions=10) - networks = {branch_net1 : ['x'], - branch_net2 : ['x', 'y'], - trunk_net : ['z']} - MIONet(networks=networks, - reduction='+', - aggregator='*') + networks = {branch_net1: ['x'], branch_net2: ['x', 'y'], trunk_net: ['z']} + MIONet(networks=networks, reduction='+', aggregator='*') def test_constructor_fails_when_invalid_inner_layer_size(): branch_net1 = FeedForward(input_dimensions=1, output_dimensions=10) branch_net2 = FeedForward(input_dimensions=2, output_dimensions=10) trunk_net = FeedForward(input_dimensions=1, output_dimensions=12) - networks = {branch_net1 : ['x'], - branch_net2 : ['x', 'y'], - trunk_net : ['z']} + networks = {branch_net1: ['x'], branch_net2: ['x', 'y'], trunk_net: ['z']} with pytest.raises(ValueError): - MIONet(networks=networks, - reduction='+', - aggregator='*') + MIONet(networks=networks, reduction='+', aggregator='*') + def test_forward_extract_str(): branch_net1 = FeedForward(input_dimensions=1, output_dimensions=10) branch_net2 = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=1, output_dimensions=10) - networks = {branch_net1 : ['a'], - branch_net2 : ['b'], - trunk_net : ['c']} - model = MIONet(networks=networks, - reduction='+', - aggregator='*') + networks = {branch_net1: ['a'], branch_net2: ['b'], trunk_net: ['c']} + model = MIONet(networks=networks, reduction='+', aggregator='*') model(input_) + def test_forward_extract_int(): branch_net1 = FeedForward(input_dimensions=1, output_dimensions=10) branch_net2 = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=1, output_dimensions=10) - networks = {branch_net1 : [0], - branch_net2 : [1], - trunk_net : [2]} - model = MIONet(networks=networks, - reduction='+', - aggregator='*') + networks = {branch_net1: [0], branch_net2: [1], trunk_net: [2]} + model = MIONet(networks=networks, reduction='+', aggregator='*') model(data) + def test_forward_extract_str_wrong(): branch_net1 = FeedForward(input_dimensions=1, output_dimensions=10) branch_net2 = FeedForward(input_dimensions=1, output_dimensions=10) trunk_net = FeedForward(input_dimensions=1, output_dimensions=10) - networks = {branch_net1 : ['a'], - branch_net2 : ['b'], - trunk_net : ['c']} - model = MIONet(networks=networks, - reduction='+', - aggregator='*') + networks = {branch_net1: ['a'], branch_net2: ['b'], trunk_net: ['c']} + model = MIONet(networks=networks, reduction='+', aggregator='*') with pytest.raises(RuntimeError): model(data) diff --git a/tests/test_model/test_residualfnn.py b/tests/test_model/test_residualfnn.py index d8c07aa..eef05b1 100644 --- a/tests/test_model/test_residualfnn.py +++ b/tests/test_model/test_residualfnn.py @@ -2,21 +2,25 @@ import torch import pytest from pina.model import ResidualFeedForward + def test_constructor(): # simple constructor ResidualFeedForward(input_dimensions=2, output_dimensions=1) # wrong transformer nets (not 2) with pytest.raises(ValueError): - ResidualFeedForward(input_dimensions=2, output_dimensions=1, transformer_nets=[torch.nn.Linear(2, 20)]) + ResidualFeedForward(input_dimensions=2, + output_dimensions=1, + transformer_nets=[torch.nn.Linear(2, 20)]) # wrong transformer nets (not nn.Module) with pytest.raises(ValueError): - ResidualFeedForward(input_dimensions=2, output_dimensions=1, transformer_nets=[2, 2]) + ResidualFeedForward(input_dimensions=2, + output_dimensions=1, + transformer_nets=[2, 2]) + def test_forward(): x = torch.rand(10, 2) model = ResidualFeedForward(input_dimensions=2, output_dimensions=1) model(x) - - diff --git a/tests/test_operators.py b/tests/test_operators.py index f577c70..aa9ea9d 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -4,9 +4,11 @@ import pytest from pina import LabelTensor from pina.operators import grad, div, laplacian + def func_vec(x): return x**2 + def func_scalar(x): print('X') x_ = x.extract(['x']) @@ -14,6 +16,7 @@ def func_scalar(x): mu_ = x.extract(['mu']) return x_**2 + y_**2 + mu_**3 + data = torch.rand((20, 3), requires_grad=True) inp = LabelTensor(data, ['x', 'y', 'mu']) labels = ['a', 'b', 'c'] @@ -24,10 +27,15 @@ tensor_s = LabelTensor(func_scalar(inp).reshape(-1, 1), labels[0]) def test_grad_scalar_output(): grad_tensor_s = grad(tensor_s, inp) assert grad_tensor_s.shape == inp.shape - assert grad_tensor_s.labels == [f'd{tensor_s.labels[0]}d{i}' for i in inp.labels] + assert grad_tensor_s.labels == [ + f'd{tensor_s.labels[0]}d{i}' for i in inp.labels + ] grad_tensor_s = grad(tensor_s, inp, d=['x', 'y']) assert grad_tensor_s.shape == (inp.shape[0], 2) - assert grad_tensor_s.labels == [f'd{tensor_s.labels[0]}d{i}' for i in ['x', 'y']] + assert grad_tensor_s.labels == [ + f'd{tensor_s.labels[0]}d{i}' for i in ['x', 'y'] + ] + def test_grad_vector_output(): grad_tensor_v = grad(tensor_v, inp) @@ -35,19 +43,24 @@ def test_grad_vector_output(): grad_tensor_v = grad(tensor_v, inp, d=['x', 'mu']) assert grad_tensor_v.shape == (inp.shape[0], 6) + def test_div_vector_output(): grad_tensor_v = div(tensor_v, inp) assert grad_tensor_v.shape == (20, 1) grad_tensor_v = div(tensor_v, inp, components=['a', 'b'], d=['x', 'mu']) assert grad_tensor_v.shape == (inp.shape[0], 1) + def test_laplacian_scalar_output(): laplace_tensor_v = laplacian(tensor_s, inp, components=['a'], d=['x', 'y']) assert laplace_tensor_v.shape == tensor_s.shape + def test_laplacian_vector_output(): laplace_tensor_v = laplacian(tensor_v, inp) assert laplace_tensor_v.shape == tensor_v.shape - laplace_tensor_v = laplacian(tensor_v, inp, components=['a', 'b'], d=['x', 'y']) + laplace_tensor_v = laplacian(tensor_v, + inp, + components=['a', 'b'], + d=['x', 'y']) assert laplace_tensor_v.shape == tensor_v.extract(['a', 'b']).shape - diff --git a/tests/test_problem.py b/tests/test_problem.py index 09b4fc0..8dcd499 100644 --- a/tests/test_problem.py +++ b/tests/test_problem.py @@ -10,45 +10,59 @@ from pina.equation.equation_factory import FixedValue def laplace_equation(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u']), input_) return delta_u - force_term + my_laplace = Equation(laplace_equation) in_ = LabelTensor(torch.tensor([[0., 1.]], requires_grad=True), ['x', 'y']) out_ = LabelTensor(torch.tensor([[0.]], requires_grad=True), ['u']) + class Poisson(SpatialProblem): output_variables = ['u'] spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) conditions = { - 'gamma1': Condition( - location=CartesianDomain({'x': [0, 1], 'y': 1}), - equation=FixedValue(0.0)), - 'gamma2': Condition( - location=CartesianDomain({'x': [0, 1], 'y': 0}), - equation=FixedValue(0.0)), - 'gamma3': Condition( - location=CartesianDomain({'x': 1, 'y': [0, 1]}), - equation=FixedValue(0.0)), - 'gamma4': Condition( - location=CartesianDomain({'x': 0, 'y': [0, 1]}), - equation=FixedValue(0.0)), - 'D': Condition( - location=CartesianDomain({'x': [0, 1], 'y': [0, 1]}), - equation=my_laplace), - 'data': Condition( - input_points=in_, - output_points=out_) + 'gamma1': + Condition(location=CartesianDomain({ + 'x': [0, 1], + 'y': 1 + }), + equation=FixedValue(0.0)), + 'gamma2': + Condition(location=CartesianDomain({ + 'x': [0, 1], + 'y': 0 + }), + equation=FixedValue(0.0)), + 'gamma3': + Condition(location=CartesianDomain({ + 'x': 1, + 'y': [0, 1] + }), + equation=FixedValue(0.0)), + 'gamma4': + Condition(location=CartesianDomain({ + 'x': 0, + 'y': [0, 1] + }), + equation=FixedValue(0.0)), + 'D': + Condition(location=CartesianDomain({ + 'x': [0, 1], + 'y': [0, 1] + }), + equation=my_laplace), + 'data': + Condition(input_points=in_, output_points=out_) } def poisson_sol(self, pts): - return -( - torch.sin(pts.extract(['x'])*torch.pi) * - torch.sin(pts.extract(['y'])*torch.pi) - )/(2*torch.pi**2) + return -(torch.sin(pts.extract(['x']) * torch.pi) * + torch.sin(pts.extract(['y']) * torch.pi)) / (2 * torch.pi**2) truth_solution = poisson_sol @@ -78,11 +92,16 @@ def test_discretise_domain(): poisson_problem.discretise_domain(n, 'lh', locations=['D']) assert poisson_problem.input_pts['D'].shape[0] == n + def test_sampling_few_variables(): n = 10 - poisson_problem.discretise_domain(n, 'grid', locations=['D'], variables=['x']) + poisson_problem.discretise_domain(n, + 'grid', + locations=['D'], + variables=['x']) assert poisson_problem.input_pts['D'].shape[1] == 1 - assert poisson_problem._have_sampled_points['D'] is False + assert poisson_problem._have_sampled_points['D'] is False + # def test_sampling_all_args(): # n = 10 diff --git a/tests/test_solvers/test_garom.py b/tests/test_solvers/test_garom.py index 3087d7d..4ff4e1c 100644 --- a/tests/test_solvers/test_garom.py +++ b/tests/test_solvers/test_garom.py @@ -15,6 +15,7 @@ def func(x, mu1, mu2): norm = x[:, 0]**2 + x[:, 1]**2 return torch.exp(-(x_m1 + x_m2)) + class ParametricGaussian(AbstractProblem): output_variables = [f'u_{i}' for i in range(900)] @@ -24,7 +25,7 @@ class ParametricGaussian(AbstractProblem): params = LabelTensor(torch.cartesian_prod(xx, yy), labels=['mu1', 'mu2']) # define domain - x = torch.linspace(-1, 1, 30) + x = torch.linspace(-1, 1, 30) domain = torch.cartesian_prod(x, x) triang = tri.Triangulation(domain[:, 0], domain[:, 1]) sol = [] @@ -34,15 +35,18 @@ class ParametricGaussian(AbstractProblem): # define conditions conditions = { - 'data': Condition( - input_points=params, - output_points=snapshots) + 'data': Condition(input_points=params, output_points=snapshots) } + # simple Generator Network class Generator(nn.Module): - def __init__(self, input_dimension, parameters_dimension, - noise_dimension, activation=torch.nn.SiLU): + + def __init__(self, + input_dimension, + parameters_dimension, + noise_dimension, + activation=torch.nn.SiLU): super().__init__() self._noise_dimension = noise_dimension @@ -53,13 +57,12 @@ class Generator(nn.Module): self._activation(), torch.nn.Linear(input_dimension // 6, input_dimension // 3), self._activation(), - torch.nn.Linear(input_dimension // 3, input_dimension) - ) + torch.nn.Linear(input_dimension // 3, input_dimension)) self.condition = torch.nn.Sequential( torch.nn.Linear(parameters_dimension, 2 * self._noise_dimension), self._activation(), - torch.nn.Linear(2 * self._noise_dimension, 5 * self._noise_dimension) - ) + torch.nn.Linear(2 * self._noise_dimension, + 5 * self._noise_dimension)) def forward(self, param): # uniform sampling in [-1, 1] @@ -78,8 +81,12 @@ class Generator(nn.Module): # Simple Discriminator Network class Discriminator(nn.Module): - def __init__(self, input_dimension, parameter_dimension, - hidden_dimension, activation=torch.nn.ReLU): + + def __init__(self, + input_dimension, + parameter_dimension, + hidden_dimension, + activation=torch.nn.ReLU): super().__init__() self._activation = activation @@ -88,10 +95,9 @@ class Discriminator(nn.Module): self._activation(), torch.nn.Linear(input_dimension // 3, input_dimension // 6), self._activation(), - torch.nn.Linear(input_dimension // 6, hidden_dimension) - ) + torch.nn.Linear(input_dimension // 6, hidden_dimension)) self.decoding = torch.nn.Sequential( - torch.nn.Linear(2*hidden_dimension, input_dimension // 6), + torch.nn.Linear(2 * hidden_dimension, input_dimension // 6), self._activation(), torch.nn.Linear(input_dimension // 6, input_dimension // 3), self._activation(), @@ -101,9 +107,8 @@ class Discriminator(nn.Module): self.condition = torch.nn.Sequential( torch.nn.Linear(parameter_dimension, hidden_dimension // 2), self._activation(), - torch.nn.Linear(hidden_dimension // 2, hidden_dimension) - ) - + torch.nn.Linear(hidden_dimension // 2, hidden_dimension)) + def forward(self, data): x, condition = data encoding = self.encoding(x) @@ -114,49 +119,49 @@ class Discriminator(nn.Module): problem = ParametricGaussian() + def test_constructor(): - GAROM(problem = problem, - generator = Generator(input_dimension=900, - parameters_dimension=2, - noise_dimension=12), - discriminator = Discriminator(input_dimension=900, - parameter_dimension=2, - hidden_dimension=64) - ) + GAROM(problem=problem, + generator=Generator(input_dimension=900, + parameters_dimension=2, + noise_dimension=12), + discriminator=Discriminator(input_dimension=900, + parameter_dimension=2, + hidden_dimension=64)) + def test_train_cpu(): - solver = GAROM(problem = problem, - generator = Generator(input_dimension=900, - parameters_dimension=2, - noise_dimension=12), - discriminator = Discriminator(input_dimension=900, - parameter_dimension=2, - hidden_dimension=64) - ) + solver = GAROM(problem=problem, + generator=Generator(input_dimension=900, + parameters_dimension=2, + noise_dimension=12), + discriminator=Discriminator(input_dimension=900, + parameter_dimension=2, + hidden_dimension=64)) trainer = Trainer(solver=solver, max_epochs=4, accelerator='cpu', batch_size=20) trainer.train() + def test_sample(): - solver = GAROM(problem = problem, - generator = Generator(input_dimension=900, - parameters_dimension=2, - noise_dimension=12), - discriminator = Discriminator(input_dimension=900, - parameter_dimension=2, - hidden_dimension=64) - ) + solver = GAROM(problem=problem, + generator=Generator(input_dimension=900, + parameters_dimension=2, + noise_dimension=12), + discriminator=Discriminator(input_dimension=900, + parameter_dimension=2, + hidden_dimension=64)) solver.sample(problem.params) assert solver.sample(problem.params).shape == problem.snapshots.shape + def test_forward(): - solver = GAROM(problem = problem, - generator = Generator(input_dimension=900, - parameters_dimension=2, - noise_dimension=12), - discriminator = Discriminator(input_dimension=900, - parameter_dimension=2, - hidden_dimension=64) - ) + solver = GAROM(problem=problem, + generator=Generator(input_dimension=900, + parameters_dimension=2, + noise_dimension=12), + discriminator=Discriminator(input_dimension=900, + parameter_dimension=2, + hidden_dimension=64)) solver(problem.params, mc_steps=100, variance=True) - assert solver(problem.params).shape == problem.snapshots.shape \ No newline at end of file + assert solver(problem.params).shape == problem.snapshots.shape diff --git a/tests/test_solvers/test_pinn.py b/tests/test_solvers/test_pinn.py index 47570ac..0a42410 100644 --- a/tests/test_solvers/test_pinn.py +++ b/tests/test_solvers/test_pinn.py @@ -1,30 +1,31 @@ import torch -import pytest from pina.problem import SpatialProblem from pina.operators import laplacian from pina.geometry import CartesianDomain -from pina import Condition, LabelTensor, PINN +from pina import Condition, LabelTensor +from pina.solvers import PINN from pina.trainer import Trainer from pina.model import FeedForward from pina.equation.equation import Equation from pina.equation.equation_factory import FixedValue -from pina.plotter import Plotter from pina.loss import LpLoss def laplace_equation(input_, output_): - force_term = (torch.sin(input_.extract(['x'])*torch.pi) * - torch.sin(input_.extract(['y'])*torch.pi)) + force_term = (torch.sin(input_.extract(['x']) * torch.pi) * + torch.sin(input_.extract(['y']) * torch.pi)) delta_u = laplacian(output_.extract(['u']), input_) return delta_u - force_term + my_laplace = Equation(laplace_equation) in_ = LabelTensor(torch.tensor([[0., 1.]]), ['x', 'y']) out_ = LabelTensor(torch.tensor([[0.]]), ['u']) in2_ = LabelTensor(torch.rand(60, 2), ['x', 'y']) out2_ = LabelTensor(torch.rand(60, 1), ['u']) + class Poisson(SpatialProblem): output_variables = ['u'] spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]}) @@ -54,42 +55,48 @@ class Poisson(SpatialProblem): } def poisson_sol(self, pts): - return -( - torch.sin(pts.extract(['x'])*torch.pi) * - torch.sin(pts.extract(['y'])*torch.pi) - )/(2*torch.pi**2) + return -(torch.sin(pts.extract(['x']) * torch.pi) * + torch.sin(pts.extract(['y']) * torch.pi)) / (2 * torch.pi**2) truth_solution = poisson_sol + class myFeature(torch.nn.Module): """ Feature: sin(x) """ - def __init__(self): super(myFeature, self).__init__() def forward(self, x): - t = (torch.sin(x.extract(['x'])*torch.pi) * - torch.sin(x.extract(['y'])*torch.pi)) + t = (torch.sin(x.extract(['x']) * torch.pi) * + torch.sin(x.extract(['y']) * torch.pi)) return LabelTensor(t, ['sin(x)sin(y)']) # make the problem poisson_problem = Poisson() -model = FeedForward(len(poisson_problem.input_variables),len(poisson_problem.output_variables)) -model_extra_feats = FeedForward(len(poisson_problem.input_variables)+1,len(poisson_problem.output_variables)) +model = FeedForward(len(poisson_problem.input_variables), + len(poisson_problem.output_variables)) +model_extra_feats = FeedForward( + len(poisson_problem.input_variables) + 1, + len(poisson_problem.output_variables)) extra_feats = [myFeature()] def test_constructor(): - PINN(problem = poisson_problem, model=model, extra_features=None) + PINN(problem=poisson_problem, model=model, extra_features=None) def test_constructor_extra_feats(): - model_extra_feats = FeedForward(len(poisson_problem.input_variables)+1,len(poisson_problem.output_variables)) - PINN(problem = poisson_problem, model=model_extra_feats, extra_features=extra_feats) + model_extra_feats = FeedForward( + len(poisson_problem.input_variables) + 1, + len(poisson_problem.output_variables)) + PINN(problem=poisson_problem, + model=model_extra_feats, + extra_features=extra_feats) + def test_train_cpu(): poisson_problem = Poisson() @@ -100,14 +107,21 @@ def test_train_cpu(): trainer = Trainer(solver=pinn, max_epochs=1, accelerator='cpu', batch_size=20) trainer.train() + def test_train_restore(): tmpdir = "tests/tmp_restore" poisson_problem = Poisson() boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] n = 10 poisson_problem.discretise_domain(n, 'grid', locations=boundaries) - pinn = PINN(problem = poisson_problem, model=model, extra_features=None, loss=LpLoss()) - trainer = Trainer(solver=pinn, max_epochs=5, accelerator='cpu', default_root_dir=tmpdir) + pinn = PINN(problem=poisson_problem, + model=model, + extra_features=None, + loss=LpLoss()) + trainer = Trainer(solver=pinn, + max_epochs=5, + accelerator='cpu', + default_root_dir=tmpdir) trainer.train() ntrainer = Trainer(solver=pinn, max_epochs=15, accelerator='cpu') t = ntrainer.train( @@ -115,31 +129,40 @@ def test_train_restore(): import shutil shutil.rmtree(tmpdir) + def test_train_load(): tmpdir = "tests/tmp_load" poisson_problem = Poisson() boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] n = 10 poisson_problem.discretise_domain(n, 'grid', locations=boundaries) - pinn = PINN(problem = poisson_problem, model=model, extra_features=None, loss=LpLoss()) - trainer = Trainer(solver=pinn, max_epochs=15, accelerator='cpu', - default_root_dir=tmpdir) + pinn = PINN(problem=poisson_problem, + model=model, + extra_features=None, + loss=LpLoss()) + trainer = Trainer(solver=pinn, + max_epochs=15, + accelerator='cpu', + default_root_dir=tmpdir) trainer.train() new_pinn = PINN.load_from_checkpoint( f'{tmpdir}/lightning_logs/version_0/checkpoints/epoch=14-step=30.ckpt', problem = poisson_problem, model=model) test_pts = CartesianDomain({'x': [0, 1], 'y': [0, 1]}).sample(10) assert new_pinn.forward(test_pts).extract(['u']).shape == (10, 1) - assert new_pinn.forward(test_pts).extract(['u']).shape == pinn.forward(test_pts).extract(['u']).shape - torch.testing.assert_close(new_pinn.forward(test_pts).extract(['u']), pinn.forward(test_pts).extract(['u'])) + assert new_pinn.forward(test_pts).extract( + ['u']).shape == pinn.forward(test_pts).extract(['u']).shape + torch.testing.assert_close( + new_pinn.forward(test_pts).extract(['u']), + pinn.forward(test_pts).extract(['u'])) import shutil shutil.rmtree(tmpdir) - + # # TODO fix asap. Basically sampling few variables # # works only if both variables are in a range. # # if one is fixed and the other not, this will -# # not work. This test also needs to be fixed and +# # not work. This test also needs to be fixed and # # insert in test problem not in test pinn. # def test_train_cpu_sampling_few_vars(): # poisson_problem = Poisson() @@ -158,12 +181,15 @@ def test_train_extra_feats_cpu(): boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] n = 10 poisson_problem.discretise_domain(n, 'grid', locations=boundaries) - pinn = PINN(problem = poisson_problem, model=model_extra_feats, extra_features=extra_feats) + pinn = PINN(problem=poisson_problem, + model=model_extra_feats, + extra_features=extra_feats) trainer = Trainer(solver=pinn, max_epochs=5, accelerator='cpu') trainer.train() + # TODO, fix GitHub actions to run also on GPU -# def test_train_gpu(): +# def test_train_gpu(): # poisson_problem = Poisson() # boundaries = ['gamma1', 'gamma2', 'gamma3', 'gamma4'] # n = 10 @@ -171,7 +197,6 @@ def test_train_extra_feats_cpu(): # pinn = PINN(problem = poisson_problem, model=model, extra_features=None, loss=LpLoss()) # trainer = Trainer(solver=pinn, kwargs={'max_epochs' : 5, 'accelerator':'gpu'}) # trainer.train() - """ def test_train_gpu(): #TODO fix ASAP poisson_problem = Poisson() diff --git a/tests/test_utils.py b/tests/test_utils.py index 94895e5..46305f6 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -15,9 +15,9 @@ def test_merge_tensors(): tensor3 = LabelTensor(torch.ones((30, 3)), ['g', 'h', 'i']) merged_tensor = merge_tensors((tensor1, tensor2, tensor3)) - assert tuple(merged_tensor.labels) == ( - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i') - assert merged_tensor.shape == (20*20*30, 9) + assert tuple(merged_tensor.labels) == ('a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i') + assert merged_tensor.shape == (20 * 20 * 30, 9) assert torch.all(merged_tensor.extract(('d', 'e', 'f')) == 0) assert torch.all(merged_tensor.extract(('g', 'h', 'i')) == 1) @@ -25,7 +25,7 @@ def test_merge_tensors(): def test_check_consistency_correct(): ellipsoid1 = EllipsoidDomain({'x': [1, 2], 'y': [-2, 1]}) example_input_pts = LabelTensor(torch.tensor([[0, 0, 0]]), ['x', 'y', 'z']) - + check_consistency(example_input_pts, torch.Tensor) check_consistency(CartesianDomain, Location, subclass=True) check_consistency(ellipsoid1, Location) @@ -34,7 +34,7 @@ def test_check_consistency_correct(): def test_check_consistency_incorrect(): ellipsoid1 = EllipsoidDomain({'x': [1, 2], 'y': [-2, 1]}) example_input_pts = LabelTensor(torch.tensor([[0, 0, 0]]), ['x', 'y', 'z']) - + with pytest.raises(ValueError): check_consistency(example_input_pts, Location) with pytest.raises(ValueError):

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 literal 52492 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 diff --git a/docs/source/index_files/university_dev_pina.png b/docs/source/index_files/university_dev_pina.png new file mode 100644 index 0000000000000000000000000000000000000000..9afb04fd778cb511e18a35c5daf0bd52fda0dada GIT binary patch literal 119229 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