Skip to content

types ¤

Core data structures for Circulax rational fitting.

Classes:

Name Description
FitOptions

Fitting hyperparameters.

SSModel

State-space model with diagonal A.

VFModel

Pole-residue model.

Functions:

Name Description
eval_model

Evaluate model at all frequency points.

ss_to_vfmodel

Convert SSModel back to VFModel.

vfmodel_to_ss

Convert VFModel (pole-residue) to SSModel (state-space).

FitOptions dataclass ¤

FitOptions(
    N: int,
    asymp: int = 2,
    stable: bool = True,
    relax: bool = True,
    weightparam: int = 1,
    Niter1: int = 4,
    Niter2: int = 4,
    parametertype: str = "Y",
    TOLG: float = 1e-06,
    TOLD: float = 0.001,
    TOLE: float = 1e-12,
    Niter_out: int = 20,
    passive_DE: bool = False,
    nu: float = 0.001,
)

Fitting hyperparameters.

Frozen so the instance can be used as a JIT static argument (it is hashable).

SSModel dataclass ¤

SSModel(A: ndarray, B: ndarray, C: ndarray, D: ndarray, E: ndarray)

State-space model with diagonal A.

Represents: H(s) = C * diag(1/(s - A)) * B + D + s*E A is stored as a 1-D vector of diagonal entries to avoid materialising the large sparse block-diagonal matrix.

VFModel dataclass ¤

VFModel(poles: ndarray, residues: ndarray, D: ndarray, E: ndarray)

Pole-residue model.

Represents: H(s) = sum_m residues[:, :, m] / (s - poles[m]) + D + s*E

eval_model ¤

eval_model(s: ndarray, ss: SSModel) -> ndarray

Evaluate model at all frequency points.

Parameters:

Name Type Description Default
s ndarray

(Ns,) complex frequency points (= j*omega).

required
ss SSModel

SSModel.

required

Returns:

Name Type Description
H ndarray

(Ns, Nc, Nc) complex — model response at each frequency.

Source code in circulax/fitting/types.py
def eval_model(s: jnp.ndarray, ss: SSModel) -> jnp.ndarray:
    """Evaluate model at all frequency points.

    Args:
        s: (Ns,) complex frequency points (= j*omega).
        ss: SSModel.

    Returns:
        H: (Ns, Nc, Nc) complex — model response at each frequency.

    """
    return jax.vmap(lambda sk: _eval_at_one_freq(sk, ss.A, ss.B, ss.C, ss.D, ss.E))(s)

ss_to_vfmodel ¤

ss_to_vfmodel(ss: SSModel, N: int, Nc: int) -> VFModel

Convert SSModel back to VFModel.

Inverse of vfmodel_to_ss. Equivalent to ss2pr.

Source code in circulax/fitting/types.py
def ss_to_vfmodel(ss: SSModel, N: int, Nc: int) -> VFModel:
    """Convert SSModel back to VFModel.

    Inverse of vfmodel_to_ss. Equivalent to ss2pr.
    """
    poles = ss.A[:N]
    residues = ss.C.reshape(Nc, Nc, N)
    return VFModel(
        poles=poles,
        residues=residues,
        D=jnp.real(ss.D),
        E=jnp.real(ss.E),
    )

vfmodel_to_ss ¤

vfmodel_to_ss(model: VFModel, Nc: int) -> SSModel

Convert VFModel (pole-residue) to SSModel (state-space).

Equivalent to pr2ss.m.

For Nc ports and N poles, the block-diagonal structure is: A (as vector): [poles, poles, ..., poles] (repeated Nc times) → (NcN,) B[nN:(n+1)N, n] = 1, rest 0 (NcN, Nc) C[row, colN:(col+1)N] = residues[row, col, :] (Nc, Nc*N)

Source code in circulax/fitting/types.py
def vfmodel_to_ss(model: VFModel, Nc: int) -> SSModel:
    """Convert VFModel (pole-residue) to SSModel (state-space).

    Equivalent to pr2ss.m.

    For Nc ports and N poles, the block-diagonal structure is:
        A (as vector): [poles, poles, ..., poles]  (repeated Nc times) → (Nc*N,)
        B[n*N:(n+1)*N, n] = 1, rest 0             (Nc*N, Nc)
        C[row, col*N:(col+1)*N] = residues[row, col, :]  (Nc, Nc*N)
    """
    N = model.poles.shape[0]
    A_diag = jnp.tile(model.poles, Nc)  # (Nc*N,)

    # B: kron(eye(Nc), ones(N,1)) gives the block identity structure
    B = jnp.kron(
        jnp.eye(Nc, dtype=jnp.complex128),
        jnp.ones((N, 1), dtype=jnp.complex128),
    )  # (Nc*N, Nc)

    # C: residues (Nc, Nc, N) → reshape so C[row, col*N+k] = residues[row, col, k]
    C = model.residues.astype(jnp.complex128).reshape(Nc, Nc * N)

    return SSModel(
        A=A_diag,
        B=B,
        C=C,
        D=model.D.astype(jnp.complex128),
        E=model.E.astype(jnp.complex128),
    )