base_component ¤
Base class and decorators for defining JAX-compatible circuit components.
Circuit components are defined as plain Python functions decorated with :func:component or :func:source, which compile them into :class:CircuitComponent subclasses — Equinox modules whose parameters are JAX-traceable leaves. The resulting classes expose two entry points:
__call__— a debug-friendly instance method that accepts port voltages and state values as keyword arguments and returns the physics dicts directly.solver_call— a class method used by the transient solver that operates on flat JAX arrays and a parameter container, and is compatible withjax.vmapandjax.jacfwd.
Example::
@component(ports=("p1", "p2"))
def Resistor(signals: Signals, R: float = 1.0):
i = (signals.p1 - signals.p2) / R
return {"p1": i, "p2": -i}, {}
r = Resistor(R=100.0)
f, q = r(p1=1.0, p2=0.0)
Classes:
| Name | Description |
|---|---|
CircuitComponent | Base class for all JAX-compatible circuit components. |
Signals | Unified view of a component's ports and internal state variables. |
States | Legacy state-variable view retained for the Circulax 0.2.3 API. |
Functions:
| Name | Description |
|---|---|
component | Decorator for defining a time-independent circuit component. |
source | Decorator for defining a time-dependent circuit component. |
CircuitComponent ¤
Bases: Module
Base class for all JAX-compatible circuit components.
Subclasses are not written by hand — they are generated at import time by the :func:component and :func:source decorators, which inspect the decorated function's signature to populate the class variables and wire up the two physics entry points.
Class Variables
ports: Ordered tuple of port names, e.g. ("p1", "p2"). states: Ordered tuple of internal state variable names, e.g. ("i_L",). Empty for purely algebraic components. _uses_time: True for components decorated with :func:source whose physics function accepts a t argument. _n_ports: Number of ports, cached to avoid repeated len calls in the hot path. _fast_physics: Static closure over the user-defined physics function, compatible with jax.vmap and jax.jacfwd. Signature is (vars_vec, params, t) -> (f_vec, q_vec).
Methods:
| Name | Description |
|---|---|
delay_values | Return inline delays used by a generated component, if any. |
physics | Raw physics dispatch; overridden by the decorator-generated subclass. |
solver_call | Evaluate the component physics (solver entry point). |
delay_values staticmethod ¤
physics ¤
Raw physics dispatch; overridden by the decorator-generated subclass.
solver_call classmethod ¤
Evaluate the component physics (solver entry point).
Thin wrapper around the static _fast_physics closure. Called by the transient solver inside jax.vmap across all instances in a component group, and differentiated via jax.jacfwd to assemble the system Jacobian.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t | float | Current simulation time. | required |
y | Array | Flat state vector of shape | required |
args | Any | Parameter container for this instance. May be a dict | required |
hist | Array | None | Internally supplied delayed local-variable vector of shape | None |
Returns:
| Type | Description |
|---|---|
Array | A two-tuple |
Array |
|
tuple[Array, Array] | contributions for every port and state variable. |
Source code in circulax/components/base_component.py
Signals ¤
Signals(
values: Any,
names: tuple[str, ...],
*,
delayed: Any | None = None,
delay_recorder: list[Any] | None = None
)
Unified view of a component's ports and internal state variables.
signals.name reads the value at the current analysis time, while signals.at_delay(tau).name reads it at t - tau. The analysis supplies the delayed values in its natural representation (history interpolation for transient, phase rotation for AC/HB, and identity for DC), so component physics stays independent of the solver.
Methods:
| Name | Description |
|---|---|
at_delay | Return component-local values at |
Source code in circulax/components/base_component.py
at_delay ¤
Return component-local values at t - delay.
Delays are causal durations and must therefore be non-negative. The current implementation supports one unique delay per component.
Source code in circulax/components/base_component.py
States ¤
States(
values: Any,
names: tuple[str, ...],
*,
delayed: Any | None = None,
delay_recorder: list[Any] | None = None
)
Bases: Signals
Legacy state-variable view retained for the Circulax 0.2.3 API.
New components may read ports and states from a unified :class:Signals object. Components written against 0.2.3 continue to receive a separate States object when they declare (signals, s, ...).
Methods:
| Name | Description |
|---|---|
at_delay | Return component-local values at |
Source code in circulax/components/base_component.py
at_delay ¤
Return component-local values at t - delay.
Delays are causal durations and must therefore be non-negative. The current implementation supports one unique delay per component.
Source code in circulax/components/base_component.py
component ¤
component(
ports: tuple[str, ...] = (),
states: tuple[str, ...] = (),
amplitude_param: str = "",
port_aliases: dict[str, str | tuple[str, ...]] | None = None,
holomorphic: bool = False,
) -> Any
Decorator for defining a time-independent circuit component.
Compiles the decorated physics function into a :class:CircuitComponent subclass. The function must begin with signals followed by parameters with defaults, which become JAX-traceable Equinox fields on the resulting class. Ports and internal states share the signals namespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ports | tuple[str, ...] | Ordered tuple of port names. Must match the connection keys used in the netlist. | () |
states | tuple[str, ...] | Ordered tuple of internal state variable names. State variables are appended to the solver's state vector after the node voltages. | () |
amplitude_param | str | Name of the parameter that represents the source amplitude (e.g. | '' |
port_aliases | dict[str, str | tuple[str, ...]] | None | Optional mapping from a canonical port name to one or more alternate names a netlist may use instead, e.g. | None |
holomorphic | bool | If | False |
Returns:
| Type | Description |
|---|---|
Any | A decorator that accepts a physics function and returns a |
Any | class: |
Example::
@component(ports=("p1", "p2"))
def Resistor(signals: Signals, R: float = 1.0):
i = (signals.p1 - signals.p2) / R
return {"p1": i, "p2": -i}, {}
Source code in circulax/components/base_component.py
source ¤
source(
ports: tuple[str, ...] = (),
states: tuple[str, ...] = (),
amplitude_param: str = "",
port_aliases: dict[str, str | tuple[str, ...]] | None = None,
holomorphic: bool = False,
) -> Any
Decorator for defining a time-dependent circuit component.
Identical to :func:component except the decorated physics function must accept t as its second argument (after signals), and may use it to implement time-varying behaviour such as sinusoidal sources or delayed step functions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ports | tuple[str, ...] | Ordered tuple of port names. | () |
states | tuple[str, ...] | Ordered tuple of internal state variable names. | () |
amplitude_param | str | Name of the parameter that represents the source amplitude (e.g. | '' |
port_aliases | dict[str, str | tuple[str, ...]] | None | Optional mapping from a canonical port name to one or more alternate names a netlist may use instead. See :func: | None |
holomorphic | bool | If | False |
Returns:
| Type | Description |
|---|---|
Any | A decorator that accepts a physics function and returns a |
Any | class: |
Example::
@source(ports=("p1", "p2"), states=("i_src",))
def VoltageSource(signals: Signals, t: float, V: float = 1.0):
constraint = (signals.p1 - signals.p2) - V
return {"p1": signals.i_src, "p2": -signals.i_src, "i_src": constraint}, {}