Skip to content

Sprott flow with a conservative torus and a chaotic attractor

Sprott's flow with a conservative torus and a dissipative chaotic attractor side by side.

  • Name: sprott_mixed_flow
  • Field: mathematics/dynamical_systems
  • Formalism: ordinary differential equations
  • References: Sprott 2014; Datseris and Parlitz 2022

Select this system

from skcomplex.systems import create_simulation, create_system, describe

system = create_system('sprott_mixed_flow')
entry = describe('sprott_mixed_flow')
trajectory = create_simulation('sprott_mixed_flow').prepare().run().trajectory_

Factory

@register_system(
    field='mathematics/dynamical_systems',
    tags=('chaos', 'ode', 'conservative', 'strange attractor', 'torus'),
    references=('Sprott 2014', 'Datseris and Parlitz 2022'),
    defaults={'until': 200.0, 'dt': 0.05},
)
def sprott_mixed_flow(x: float = 2.0, y: float = 0.0, z: float = 0.0) -> System:
    """Return Sprott's flow with a conservative torus and a dissipative chaotic attractor side by side.

    The flow is `x' = y + 2xy + xz`, `y' = 1 - 2x² + yz`, `z' = x - x² - y²`, whose volumes change at the rate
    `2(y + z)`. From `(1, 0, 0)` the orbit winds on a 2-torus where this rate averages to zero, and from the default
    `(2, 0, 0)` it falls onto a chaotic attractor where it averages below zero (Datseris and Parlitz 2022, Exercises
    3.17 and 8.16).

    Args:
        x:
            The initial first coordinate.

        y:
            The initial second coordinate.

        z:
            The initial third coordinate.

    Returns:
        system:
            The system, with the states `flow.x`, `flow.y`, and `flow.z`.

    Examples:
        >>> from skcomplex.systems.mathematics.dynamical_systems import sprott_mixed_flow
        >>> sprott_mixed_flow(1.0).elements[0].x
        1.0
    """
    return System(elements=[MixedFlowElement('flow', x=x, y=y, z=z)])

Components

Elements:

  • MixedFlowElement, from Element
class MixedFlowElement(Element):
    """Sprott's flow `x' = y + 2xy + xz`, `y' = 1 - 2x² + yz`, `z' = x - x² - y²`, conservative and dissipative at once.

    Args:
        label:
            The label of the element.

        visual:
            How the element is drawn, or `None` for `default_visual_`.

        x:
            The initial first coordinate.

        y:
            The initial second coordinate.

        z:
            The initial third coordinate.

    Examples:
        >>> from skcomplex.systems.mathematics.dynamical_systems import MixedFlowElement
        >>> MixedFlowElement('flow', x=2.0).x
        2.0
    """

    def __init__(
        self,
        label: str,
        visual: VisualSpec | None = None,
        *,
        x: Annotated[object, StateSpec()] = 1.0,
        y: Annotated[object, StateSpec()] = 0.0,
        z: Annotated[object, StateSpec()] = 0.0,
    ) -> None:
        super().__init__(label, visual=visual)
        self.x = x
        self.y = y
        self.z = z

    def _get_laws(self, s: SimpleNamespace) -> list[BaseLaw]:
        """Return the rates of the three coordinates.

        Args:
            s:
                The namespace of the symbols the laws can use.

        Returns:
            laws:
                The laws of the element.
        """
        return [
            RateLaw(s.x, s.y + 2 * s.x * s.y + s.x * s.z),
            RateLaw(s.y, 1 - 2 * s.x**2 + s.y * s.z),
            RateLaw(s.z, s.x - s.x**2 - s.y**2),
        ]

Equations

flow.x: diff(x_flow(t), t) == 2*x_flow(t)*y_flow(t) + x_flow(t)*z_flow(t) + y_flow(t)
flow.y: diff(y_flow(t), t) == -2*x_flow(t)^2 + y_flow(t)*z_flow(t) + 1
flow.z: diff(z_flow(t), t) == -x_flow(t)^2 - y_flow(t)^2 + x_flow(t)