|
| 1 | +PySINDy Object Model |
| 2 | +======================== |
| 3 | +This document describes the main types of objects in pysindy |
| 4 | +and how users tend to interact with them. |
| 5 | +It then proceeds to summarize the problems and planned changes to the type system, |
| 6 | +as discussed in issues like |
| 7 | +`this one <https://github.com/dynamicslab/pysindy/issues/351>`_. |
| 8 | +It is most useful for people who want to implement their own variant of SINDy |
| 9 | +within the pysindy package. |
| 10 | + |
| 11 | +Current typing system |
| 12 | +---------------------------- |
| 13 | +The PySINDy package revolves around the abstract base class ``_BaseSINDy`` which represents |
| 14 | +the problem of fitting a dynamical system :math:`X' = \Xi^T \Theta(X)`. |
| 15 | +It implements the basics of printing the discovered system of equations and |
| 16 | +fitting the shape of inputs and outputs. |
| 17 | +For example, it contains methods like ``equations()``, ``print()``, and ``_fit_shape()``. |
| 18 | +Different subclasses handle how that fitting actually occurs: |
| 19 | +As the only current concrete subclass, ``SINDy`` objects follow the traditional approach, comprising a |
| 20 | + |
| 21 | +* ``differentiation_method: BaseDifferentiation``: computes :math:`X'`. |
| 22 | + Subclasses often accept an ``axis`` and ``order`` argument, and are callable objects. |
| 23 | + When creating new differentiation methods, add them to the |derivative|_. |
| 24 | +* ``feature_library: BaseFeatureLibrary``: specifies the candidate basis functions to be used to construct :math:`\Theta(X)`. |
| 25 | + Most significantly for the end user, ``fit()`` determines the number and string format |
| 26 | + of the feature library, as applied to the input variables. |
| 27 | + You can see these with ``BaseFeatureLibrary.get_feature_names()`` or ``BaseFeatureLibrary.n_features_out_``. |
| 28 | + One challenge with the straight-pipeline approach is that constraints must be manually constructed as arrays, |
| 29 | + and require knowing the order of the features, which in turn requires the feature library to be fit. |
| 30 | + There is no harm, however, in fitting the feature library on the data before fitting ``SINDy``, |
| 31 | + even though the latter will refit the feature library. |
| 32 | + ``transform()`` is used to actually calculate the feature values on input data. |
| 33 | +* ``optimizer: BaseOptimizer``: implements a sparse regression method for solving for :math:`\Xi`. |
| 34 | + These share a common ``fit()`` method, with different implementations going in ``_reduce()``. |
| 35 | + Most notably, they share a ``history_`` of coefficient values and a ``coef_`` array of the final coefficients. |
| 36 | + When subclassing ``BaseOptimizer``, be sure to note whether your approach can be unbiased, |
| 37 | + and if not, raise an error if set to ``True``. |
| 38 | + |
| 39 | + |
| 40 | +.. |derivative| replace:: ``derivative`` package |
| 41 | +.. _derivative: https://derivative.readthedocs.io/en/latest/ |
| 42 | + |
| 43 | +Once a ``SINDy`` object has been created it must be fit to measurement data, similar to a ``scikit-learn`` model. |
| 44 | +It can then be used to predict derivatives given new measurements in ``predict()`` |
| 45 | +as well as evolve novel initial conditions forward in time using ``simulate()``. |
| 46 | +It can also ``score()`` itself. Take care, however, as there are different metrics |
| 47 | +for a SINDy model (`issue 1`_, `issue 2`_). |
| 48 | + |
| 49 | +.. _issue 1: https://github.com/dynamicslab/pysindy/issues/372 |
| 50 | + |
| 51 | +.. _issue 2: https://github.com/scikit-learn/scikit-learn/issues/31360 |
| 52 | + |
| 53 | + |
| 54 | +Problems |
| 55 | +--------------------- |
| 56 | +.. admonition:: A good rule |
| 57 | + |
| 58 | + Type compatibility should equate to mathematical compatibility |
| 59 | + |
| 60 | +While the single base class ``SINDy`` worked for a while, it ran into problems as different innovations |
| 61 | +were added as either differentiation methods, feature libraries, or optimizers, |
| 62 | +but not as new types. |
| 63 | +Oftentimes the innovations were only compatible with correct decisions on other objects in the SINDy model, |
| 64 | +e.g. trapping SINDy is implemented as a ``TrappingSR3`` optimizer, but is only mathematically sensible with a quadratic Polynomial library. |
| 65 | +At the same time, the Polynomial library type is not parameterized by polynomial order, |
| 66 | +which is just one of the changes that would need to exist in order for the type system to enforce mathematical compatibility. |
| 67 | + |
| 68 | +Similar problems exist in Weak SINDy and SINDy-PI, whose implementations are deeply coupled. |
| 69 | + |
| 70 | +Future type system changes |
| 71 | +----------------------------- |
| 72 | +Currently weak SINDy is implemented through the ``WeakPDELibrary`` in a basic SINDy model. |
| 73 | +However, as it eschews derivative calculation, ``WeakSINDy`` will soon exist as a subclass of ``_BaseSINDy`` |
| 74 | +for fitting continuous dynamics using the integral form. |
| 75 | + |
| 76 | +Similarly, discrete SINDy, which does not use a differentiation method, will become a subclass of ``_BaseSINDy`` |
| 77 | +rather than an argument to the ``SINDy`` initialization. |
| 78 | + |
| 79 | +SINDy-PI is a unique problem in that it represents the problem of fitting a dynamical system, |
| 80 | +as does ``_BaseSINDy``, |
| 81 | +but produces a set of possible coefficient matrices with no ability to choose from them. |
| 82 | +Moreover, the equations it attempts to discover are implicit and do not create predictions in a uniform way. |
| 83 | +This means that ``predict()``, ``simulate()``, and ``equations()`` do not work. |
| 84 | +SINDy-PI is currently implemented across the ``PDELibrary``, ``WeakPDELibrary`` and ``SINDyPIOptimizer``, |
| 85 | +but will eventually become its own class that interacts with ``SINDy``, ``WeakSINDy``, Discrete SINDy, |
| 86 | +and component objects in a unique way. |
| 87 | + |
| 88 | +``EnsembleOptimizer`` and ``SBR`` are two different optimizers that result in a distribution of coefficients. |
| 89 | +The former wraps another optimizer, however it should not wrap ``SBR`` or another ``EnsembleOptimizer``. |
| 90 | +This reflects a fundamental difference in types: ``RandomVariableOptimizers`` whose coefficients are understaood to be random variables |
| 91 | +and ``DeterministicOptimizers`` whose coefficients are deterministic. |
| 92 | +Moreover, post-analysis of random variable optimizers is ad-hoc; |
| 93 | +users must access the underlying numpy arrays (``EnsembleOptimizer``) |
| 94 | +or numpyro random variables (``SBR``) in order to visualize the distributions. |
| 95 | +While that is a smaller problem, it suggests a unified API would support better comparison of these approaches. |
| 96 | + |
| 97 | + |
| 98 | +Trapping SINDy, as mentioned, requires some spooky action at a distance. |
| 99 | +It may become a factory function which chooses the optimizer and feature library for the user, |
| 100 | +depending on whether the user wants weak or traditional SINDy. |
| 101 | + |
| 102 | +Differentiation began with ``FiniteDifference``, but quickly moved to methods that |
| 103 | +both smooth and differentiate. |
| 104 | +For a while pysindy did not use the smooth coordinates, only the smoothed derivatives. |
| 105 | +For backwards compatibility, the smoothed coordinates were attached |
| 106 | +to the ``BaseDifferentiation`` object, rather than returned. |
| 107 | +Using differentiation for PDEs adds additional complexity. |
| 108 | +Some differentation/smoothing methods assume a single order of smoothness, |
| 109 | +which makes them unsuitable for most PDEs. |
| 110 | +Smoothing that only smoothes in one axis as a time does not result in consistent |
| 111 | +trajectories when smoothed along different axes. |
| 112 | +Moreover, most existing implementations are defined in the ``derivative`` package. |
| 113 | +Ideally, ``pysindy`` gets out of the business of derivative implementations, |
| 114 | +merely specifying (and correctly using) an API that treats differentiation and smoothing |
| 115 | +as two aspects of applying assumptions to a random process. |
0 commit comments