
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/01b_custom_system.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_01b_custom_system.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_01b_custom_system.py:


Writing your own system: no registry needed
===============================================

``rhs`` is just a plain ``state -> jnp.ndarray`` callable -- not a fixed
set of named systems dispatched through hardcoded if/elif branches
internally. That means using your own equations never requires touching
the library's source or registering anything: any function with the
right signature works with ``ode_problem``, exactly like the built-in
``lorenz``/``rossler``/``linear_system`` in ``lyapax.systems``.

**The system.** To prove the two are interchangeable, this demo
reimplements ``lyapax.systems.lorenz`` by hand -- no import from
``lyapax.systems`` at all -- and checks the result against the same
exact structural invariant used in
:ref:`03_chaotic_flows.py <sphx_glr_auto_examples_03_chaotic_flows.py>`:
``trace(J) = -(sigma + 1 + beta)`` is constant, so the sum of all three
exponents is known exactly, regardless of how well the attractor itself
is resolved.

.. GENERATED FROM PYTHON SOURCE LINES 22-35

.. code-block:: Python

    import os

    os.environ["JAX_PLATFORMS"] = "cpu"

    import jax
    import jax.numpy as jnp
    import numpy as np

    jax.config.update("jax_enable_x64", True)

    from lyapax.core import lyapunov_spectrum, ode_problem



.. GENERATED FROM PYTHON SOURCE LINES 36-48

.. code-block:: Python

    def my_lorenz(state):
        """A user-written system -- deliberately not imported from
        lyapax.systems, to prove the extension point needs no library
        changes and no registration step."""
        x, y, z = state[0], state[1], state[2]
        return jnp.array([
            sigma * (y - x),
            x * (rho - z) - y,
            x * y - beta * z,
        ])



.. GENERATED FROM PYTHON SOURCE LINES 49-62

.. code-block:: Python

    sigma, rho, beta = 10.0, 28.0, 8.0 / 3.0
    problem = ode_problem(my_lorenz, state0=jnp.array([1.0, 1.0, 1.0]), dt=1e-2)

    result = lyapunov_spectrum(
        problem, n_steps=50_000, renorm_every=10, t_transient=100.0,
    )

    expected_sum = -(sigma + 1.0 + beta)
    estimate = np.array(result.exponents)
    print(f"lambda        = {estimate}")
    print(f"sum(lambda)   = {float(jnp.sum(result.exponents)):.4f}"
          f"   exact -(sigma+1+beta) = {expected_sum:.4f}")
    print(f"lambda1       = {float(result.exponents[0]):.4f}   published ~0.9056")


.. _sphx_glr_download_auto_examples_01b_custom_system.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: 01b_custom_system.ipynb <01b_custom_system.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: 01b_custom_system.py <01b_custom_system.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: 01b_custom_system.zip <01b_custom_system.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
