Skip to content

Saddle-node

The saddle-node normal form x' = μ - x², whose two equilibria ±√μ meet and vanish at μ = 0.

  • Name: saddle_node_form
  • Field: mathematics/dynamical_systems
  • Formalism: ordinary differential equations
  • References: Gros 2015; Dilão 2023

Factory

@register_model(
    field='mathematics/dynamical_systems',
    tags=('bifurcation', 'normal form', 'ode'),
    references=('Gros 2015', 'Dilão 2023'),
    defaults={'until': 10.0, 'dt': 0.05},
)
def saddle_node_form(x: float = 0.0, *, mu: float = 1.0) -> System:
    """Return the saddle-node normal form `x' = μ - x²`, whose two equilibria `±√μ` meet and vanish at μ = 0.

    Args:
        x:
            The initial value.

        mu:
            The bifurcation parameter.

    Returns:
        system:
            The model, with the state `form.x`.

    Examples:
        >>> from skcomplex.models.mathematics.dynamical_systems import saddle_node_form
        >>> saddle_node_form(mu=0.5).elements[0].mu
        0.5
    """
    return System(elements=[SaddleNodeElement('form', x=x, mu=mu)])

Components

class SaddleNodeElement(Element):
    """Normal form `x' = mu - x^2` of the saddle-node bifurcation.

    Args:
        label:
            The label of the element.

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

        x:
            The initial value.

        mu:
            The bifurcation parameter.

    Examples:
        >>> from skcomplex.models.mathematics.dynamical_systems import SaddleNodeElement
        >>> SaddleNodeElement('form', mu=-1.0).mu
        -1.0
    """

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

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

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

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

Equations

form.x: diff(x_form(t), t) == -x_form(t)^2 + mu_form