sparam ¤
S-parameter preprocessing with delay de-embedding for vector fitting.
Provides a pipeline that extracts per-port group delay from S-parameter data, de-embeds it via a reference-plane shift, fits the smooth remainder with AAA, and enforces passivity — yielding a low-order rational model.
Classes:
| Name | Description |
|---|---|
CausalityError | Strict causality policy rejected a delay-model fit. |
CausalityWarning | A fitted delay model has evidence of a non-causal intermediate fit. |
Functions:
| Name | Description |
|---|---|
deembed_delay | De-embed group delay via reference-plane shift S' = P @ S @ P. |
embed_delay | Re-embed group delay (inverse of deembed_delay). |
evaluate_sparameter_model | Evaluate a fitted, delay-embedded state-space model as S parameters. |
extract_group_delay | Extract per-port group delay from S-parameter transmission phase. |
fit_with_delay | De-embed delay and fit a simulation-ready admittance realization. |
s_to_y | Convert S-parameter matrix to Y-parameter matrix (Kurokawa form). |
scattering_state_space_to_admittance | Checked scalar wrapper around the JAX S-to-Y conversion kernel. |
scattering_state_space_to_admittance_jax | JAX kernel for exact S-to-Y state-space conversion. |
vmap_scattering_state_space_to_admittance | Convert a leading batch of fixed-shape S realizations to Y in parallel. |
y_to_s | Convert Y-parameter matrix to S-parameter matrix. |
CausalityError ¤
Bases: ValueError
Strict causality policy rejected a delay-model fit.
CausalityWarning ¤
Bases: RuntimeWarning
A fitted delay model has evidence of a non-causal intermediate fit.
deembed_delay ¤
De-embed group delay via reference-plane shift S' = P @ S @ P.
P = diag(exp(+j * omega * tau_i / 2)) advances each port's reference plane by half the total delay, preserving S-matrix structure (reciprocity, passivity, unitarity for lossless).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
S | ndarray | (Ns, Nc, Nc) complex S-parameter data. | required |
freqs | ndarray | (Ns,) real frequencies in Hz. | required |
tau_per_port | ndarray | (Nc,) per-port group delay in seconds. | required |
Returns:
| Name | Type | Description |
|---|---|---|
S_deembedded | ndarray | (Ns, Nc, Nc) complex. |
Source code in circulax/fitting/sparam.py
embed_delay ¤
Re-embed group delay (inverse of deembed_delay).
S = P_inv @ S' @ P_inv where P_inv = diag(exp(-j * omega * tau_i / 2)).
Source code in circulax/fitting/sparam.py
evaluate_sparameter_model ¤
evaluate_sparameter_model(
ss: SSModel, freqs: ndarray, tau_per_port: ndarray, z0: complex = 50.0
) -> ndarray
Evaluate a fitted, delay-embedded state-space model as S parameters.
Source code in circulax/fitting/sparam.py
extract_group_delay ¤
Extract per-port group delay from S-parameter transmission phase.
Uses least-squares slope of the unwrapped S21 phase vs angular frequency. For a 2-port, uses S21; for N-port, uses each off-diagonal S[0,i] (i>0).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
S | ndarray | (Ns, Nc, Nc) complex S-parameter data. | required |
freqs | ndarray | (Ns,) real frequencies in Hz. | required |
scale | float | Scale factor applied to the fitted delay (default 1.0). Use < 1.0 (e.g. 0.95) to deliberately under-estimate and avoid de-embedding more delay than physically present. | 1.0 |
Returns:
| Name | Type | Description |
|---|---|---|
tau | ndarray | (Nc,) per-port group delay in seconds. |
Raises:
| Type | Description |
|---|---|
ValueError | If adjacent phase differences exceed pi (undersampled data). |
Source code in circulax/fitting/sparam.py
fit_with_delay ¤
fit_with_delay(
S: ndarray,
freqs: ndarray,
z0: complex = 50.0,
opts: FitOptions | None = None,
delay_scale: float = 1.0,
tol: float = 1e-10,
mmax: int = 100,
enforce_passive: bool = True,
reciprocal: bool = True,
delay_mode: Literal["auto", "port", "none"] = "auto",
causality: Literal["warn", "error", "ignore"] = "warn",
fit_domain: Literal["y", "s"] = "y",
s_refinement_iterations: int = 6,
max_poles: int | None = None,
pole_count_candidates: tuple[int, ...] | None = None,
verbose: bool = True,
aaa_backend: Literal["numpy", "jax"] = "numpy",
) -> tuple[SSModel, ndarray, dict]
De-embed delay and fit a simulation-ready admittance realization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
S | ndarray | (Ns, Nc, Nc) complex S-parameter data. | required |
freqs | ndarray | (Ns,) real frequencies in Hz. | required |
z0 | complex | Reference impedance for S-to-Y conversion. | 50.0 |
opts | FitOptions | None | FitOptions (N is ignored for AAA; asymp=2 default). | None |
delay_scale | float | Scale factor for delay extraction (< 1.0 to under-estimate). | 1.0 |
tol | float | AAA convergence tolerance. | 1e-10 |
mmax | int | Maximum AAA support points per selected matrix response. | 100 |
enforce_passive | bool | Whether to enforce passivity after fitting. | True |
reciprocal | bool | Whether the network is reciprocal. When false, fit every ordered matrix response independently instead of mirroring one triangle. | True |
delay_mode | Literal['auto', 'port', 'none'] |
| 'auto' |
causality | Literal['warn', 'error', 'ignore'] | How to handle evidence of a non-causal intermediate fit. | 'warn' |
fit_domain | Literal['y', 's'] | Fit admittance directly with | 'y' |
s_refinement_iterations | int | Common-pole vector-fitting iterations after AAA initialization when | 6 |
max_poles | int | None | Optional pole budget. AAA pole pairs are ranked by their aggregate contribution over all measured responses before fitting their residues again. In the S domain, the retained poles are also refined by common-pole vector fitting. | None |
pole_count_candidates | tuple[int, ...] | None | Optional candidate budgets to refit and screen concurrently with a fixed-shape | None |
verbose | bool | Print progress. | True |
aaa_backend | Literal['numpy', 'jax'] | NumPy or JAX for AAA support discovery only. Pole extraction uses SciPy; residue fitting and VF still use JAX. | 'numpy' |
Returns:
| Name | Type | Description |
|---|---|---|
ss | SSModel | SSModel — fitted state-space model of the de-embedded response. |
tau_per_port | ndarray | (Nc,) per-port group delay in seconds. |
metadata | dict | dict with keys: - pole_count: int - rmserr_Y: float — RMS error in Y-parameters - rmserr_S: float — RMS error in S-parameters (after re-embedding) - passivity_margin: float — min eigenvalue of Re(Y) (None if not enforced) - pole_flips: int — number of RHP poles flipped by _collect_poles - reciprocal: bool — whether response matrices were mirrored - delay_mode: str — resolved delay strategy - causality: raw delay, phase-fit, and pre-stabilization pole diagnostics |
Source code in circulax/fitting/sparam.py
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | |
s_to_y ¤
Convert S-parameter matrix to Y-parameter matrix (Kurokawa form).
Y = (I - S) @ inv(z0S + conj(z0)I)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
S | ndarray | (..., N, N) complex S-parameter matrix. | required |
z0 | complex | Reference impedance. A small imaginary part regularises near-lossless components; pass | 50.0 |
Returns:
| Name | Type | Description |
|---|---|---|
Y | ndarray | (..., N, N) complex admittance matrix. |
Source code in circulax/fitting/sparam.py
scattering_state_space_to_admittance ¤
scattering_state_space_to_admittance(
scattering_ss: SSModel, z0: complex = 50.0
) -> tuple[SSModel, float]
Checked scalar wrapper around the JAX S-to-Y conversion kernel.
Source code in circulax/fitting/sparam.py
scattering_state_space_to_admittance_jax ¤
scattering_state_space_to_admittance_jax(
scattering_ss: SSModel, z0: Array
) -> tuple[SSModel, Array]
JAX kernel for exact S-to-Y state-space conversion.
The transformation eliminates the incident waves through v=sqrt(z0)*(a+b) and i=(a-b)/sqrt(z0). Its feedback generally changes the poles, so the dense transformed state matrix is diagonalized with :func:jax.numpy.linalg.eig before constructing the diagonal :class:SSModel consumed by Circulax.
This kernel assumes a positive real z0 and a proper model (E=0). It deliberately performs no Python-side validation so it can be composed under :func:jax.jit and :func:jax.vmap; use :func:scattering_state_space_to_admittance for checked scalar calls.
Source code in circulax/fitting/sparam.py
vmap_scattering_state_space_to_admittance ¤
vmap_scattering_state_space_to_admittance(
scattering_ss: SSModel, z0: Array
) -> tuple[SSModel, Array]
Convert a leading batch of fixed-shape S realizations to Y in parallel.
Source code in circulax/fitting/sparam.py
y_to_s ¤
Convert Y-parameter matrix to S-parameter matrix.
S = (I - z0Y) @ inv(I + z0Y)