Chua double and multiple scrolls
Chua's circuit, whose double-scroll or multiscroll attractor is chaotic.
- Name:
chua - Field:
engineering/circuits - Formalism: ordinary differential equations
- References: Chua, Komuro, and Matsumoto 1986; Tang et al. 2001; Trzaska 2023
Factory
@register_model(
field='engineering/circuits',
tags=('circuit', 'chaos', 'ode', 'attractor'),
references=('Chua, Komuro, and Matsumoto 1986', 'Tang et al. 2001', 'Trzaska 2023'),
defaults={'until': 100.0, 'dt': 0.05},
)
def chua(
x: float | None = None,
y: float | None = None,
z: float = 0.0,
*,
nonlinearity: str = 'piecewise-linear',
alpha: float | None = None,
beta: float | None = None,
) -> System:
"""Return Chua's circuit, whose double-scroll or multiscroll attractor is chaotic.
The voltages of the two capacitors and the current of the inductor, in dimensionless form, follow
`x' = alpha (y - f(x))`, `y' = x - y + z`, and `z' = -β y`. The piecewise-linear diode has
`f(x) = x + m1 x + (m0 - m1) (|x + 1| - |x - 1|) / 2`, which gives the double scroll. The sine diode has
`f(x) = -b sin(π x / (2 a))`, continued linearly beyond `|x| = 2 a c`, which gives several scrolls side by side.
Args:
x:
The initial voltage of the first capacitor, or `None` for 0.1 with the piecewise-linear diode and 1 with
the sine diode.
y:
The initial voltage of the second capacitor, or `None` for 0 with the piecewise-linear diode and 1 with the
sine diode.
z:
The initial current of the inductor.
nonlinearity:
The characteristic of the diode, `'piecewise-linear'` for the double scroll or `'sine'` for multiple
scrolls.
alpha:
The ratio of the capacitances, or `None` for 15.6 with the piecewise-linear diode and 10.82 with the sine
diode.
beta:
The ratio of the inductance to the second capacitance, or `None` for 28 with the piecewise-linear diode and
14.286 with the sine diode.
Returns:
system:
The model, with the states `circuit.x`, `circuit.y`, and `circuit.z`.
Raises:
ParameterError:
The nonlinearity is neither `'piecewise-linear'` nor `'sine'`.
Examples:
>>> from skcomplex.models.engineering.circuits import chua
>>> chua(nonlinearity='sine').elements[0].alpha
10.82
"""
if nonlinearity not in CHUA_NONLINEARITIES:
error_msg = f"Unknown nonlinearity {nonlinearity!r}. Use 'piecewise-linear' or 'sine'."
raise ParameterError(error_msg)
element = ChuaCircuitElement if nonlinearity == 'piecewise-linear' else MultiscrollChuaCircuitElement
initial = {'x': x, 'y': y, 'alpha': alpha, 'beta': beta}
values: dict[str, float] = {name: value for name, value in initial.items() if value is not None}
return System(elements=[element('circuit', z=z).set_params(**values)])
Components
class ChuaCircuitElement(Element):
"""Chua circuit with the piecewise-linear current of its diode."""
def __init__(
self,
label: str,
visual: VisualSpec | None = None,
*,
x: Annotated[object, StateSpec()] = 0.1,
y: Annotated[object, StateSpec()] = 0.0,
z: Annotated[object, StateSpec()] = 0.0,
alpha: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 15.6,
beta: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 28.0,
m0: Annotated[object, ParameterSpec()] = -8 / 7,
m1: Annotated[object, ParameterSpec()] = -5 / 7,
) -> None:
super().__init__(label, visual=visual)
self.x = x
self.y = y
self.z = z
self.alpha = alpha
self.beta = beta
self.m0 = m0
self.m1 = m1
def _get_laws(self, s: SimpleNamespace) -> list[BaseLaw]:
"""Return the rates of the states of the circuit."""
return [
RateLaw(s.x, s.alpha * (s.y - s.x - s.m1 * s.x - (s.m0 - s.m1) * (abs(s.x + 1) - abs(s.x - 1)) / 2)),
RateLaw(s.y, s.x - s.y + s.z),
RateLaw(s.z, -s.beta * s.y),
]
Equations
circuit.x: diff(x_circuit(t), t) == -1/2*((m0_circuit - m1_circuit)*(abs(x_circuit(t) + 1) - abs(x_circuit(t) - 1)) + 2*m1_circuit*x_circuit(t) + 2*x_circuit(t) - 2*y_circuit(t))*alpha_circuit
circuit.y: diff(y_circuit(t), t) == x_circuit(t) - y_circuit(t) + z_circuit(t)
circuit.z: diff(z_circuit(t), t) == -beta_circuit*y_circuit(t)
