paramrf 0.26.1__tar.gz → 0.26.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {paramrf-0.26.1/paramrf.egg-info → paramrf-0.26.4}/PKG-INFO +1 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/api/index.rst +1 -1
- {paramrf-0.26.1 → paramrf-0.26.4/paramrf.egg-info}/PKG-INFO +1 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/paramrf.egg-info/SOURCES.txt +5 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/__init__.py +1 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/base.py +58 -14
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/ideal.py +1 -20
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/lumped.py +175 -202
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/sections.py +16 -101
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/interconnected.py +17 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/parameters.py +2 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/rf/__init__.py +10 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/rf/conversions.py +291 -42
- paramrf-0.26.4/pmrf/rf/mna.py +25 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/__init__.py +7 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/base.py +75 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/reduce.py +114 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/kron.py +15 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/mobius_terminator.py +5 -5
- paramrf-0.26.4/pmrf/simulate/solvers/modified_kron.py +82 -0
- {paramrf-0.26.1/pmrf → paramrf-0.26.4/pmrf/simulate}/topology.py +63 -2
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/__init__.py +3 -1
- paramrf-0.26.4/pmrf/utils/debug.py +72 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pyproject.toml +1 -1
- {paramrf-0.26.1 → paramrf-0.26.4}/.github/workflows/docs.yml +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/.github/workflows/draft-pdf.yml +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/.github/workflows/publish.yml +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/.github/workflows/tests.yml +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/.gitignore +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/CONTRIBUTING.md +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/LICENSE +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/README.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/assets/logo.png +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/Makefile +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/_static/custom.css +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/_templates/autosummary/class.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/_templates/autosummary/function.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/_templates/autosummary/module.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/conf.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/core_concepts/core_primitives.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/core_concepts/index.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/core_concepts/jax_overview.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/core_concepts/optimization_and_inference.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/cascading_and_terminating.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/circuit_clc.png +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/circuit_models.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/custom_composite_models.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/custom_parametric_models.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/derivatives_and_sweeps.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/index.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/model_optimization.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/examples/parameter_naming_and_model_manipulation.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/index.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/license.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/make.bat +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/models/index.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/skrf_comparison.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/tutorials/1_cable_fitting.ipynb +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/tutorials/2_chip_inductor_fitting.ipynb +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/tutorials/data/CBN-1.5FT-SMSM.s2p +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/tutorials/data/on-chip-inductor.s2p +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/docs/tutorials/index.rst +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paper/paper.bib +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paper/paper.md +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paper/rlc.png +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paramrf.egg-info/dependency_links.txt +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paramrf.egg-info/requires.txt +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/paramrf.egg-info/top_level.txt +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/constraints.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/covariance_kernels.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/discrepancy_models.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/distributions.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/evaluators.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/fitting/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/fitting/minimize.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/fitting/result.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/fitting/routers.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/fitting/sample.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/frequency.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/base.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/result.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/sample.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/solvers/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/solvers/blackjax.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/infer/solvers/polychord.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/likelihoods.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/losses.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/math/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/math/aggregations.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/math/conversions.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/math/losses.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/math/misc.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/adapters/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/adapters/base.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/adapters/bridge.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/adapters/callable.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/adapters/static.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/lines/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/lines/nonuniform.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/components/lines/uniform.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/nodal.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/topological.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/transformed.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/composite/wrapped.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/surrogates/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/surrogates/expansion.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/models/surrogates/rational.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/network_collection.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/noise_models.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/base.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/minimize.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/result.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/solvers/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/solvers/jaxopt.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/solvers/optimistix.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/optimize/solvers/scipy.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/problem.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/serialization.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/cascade.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/result.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/hallbjorner.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/linear_fractional_terminator.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/redheffer.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/solvers/transfer_cascader.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/simulate/terminate.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/types.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/array.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/network.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/optix.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/random.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/rf.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/transforms.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/tree.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/utils/type.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/viz/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/pmrf/viz/plots.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/setup.cfg +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/__init__.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/data/10m_cable.s2p +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_autodiff.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_evaluators.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_fitting_minimize.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_fitting_routers.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_fitting_sample.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_frequency.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_infer_base.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_infer_sample.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_model.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_adapters.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_interconnected.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_lines.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_lumped.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_nodal.py +0 -0
- /paramrf-0.26.1/tests/test_models/test_topological.py → /paramrf-0.26.4/tests/test_models/test_sections.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_models/test_transformed.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_naming.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_optimize_base.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_optimize_minimize.py +0 -0
- {paramrf-0.26.1 → paramrf-0.26.4}/tests/test_transforms.py +0 -0
|
@@ -60,7 +60,6 @@ pmrf/noise_models.py
|
|
|
60
60
|
pmrf/parameters.py
|
|
61
61
|
pmrf/problem.py
|
|
62
62
|
pmrf/serialization.py
|
|
63
|
-
pmrf/topology.py
|
|
64
63
|
pmrf/types.py
|
|
65
64
|
pmrf/fitting/__init__.py
|
|
66
65
|
pmrf/fitting/minimize.py
|
|
@@ -112,21 +111,25 @@ pmrf/optimize/solvers/optimistix.py
|
|
|
112
111
|
pmrf/optimize/solvers/scipy.py
|
|
113
112
|
pmrf/rf/__init__.py
|
|
114
113
|
pmrf/rf/conversions.py
|
|
114
|
+
pmrf/rf/mna.py
|
|
115
115
|
pmrf/simulate/__init__.py
|
|
116
116
|
pmrf/simulate/base.py
|
|
117
117
|
pmrf/simulate/cascade.py
|
|
118
118
|
pmrf/simulate/reduce.py
|
|
119
119
|
pmrf/simulate/result.py
|
|
120
120
|
pmrf/simulate/terminate.py
|
|
121
|
+
pmrf/simulate/topology.py
|
|
121
122
|
pmrf/simulate/solvers/__init__.py
|
|
122
123
|
pmrf/simulate/solvers/hallbjorner.py
|
|
123
124
|
pmrf/simulate/solvers/kron.py
|
|
124
125
|
pmrf/simulate/solvers/linear_fractional_terminator.py
|
|
125
126
|
pmrf/simulate/solvers/mobius_terminator.py
|
|
127
|
+
pmrf/simulate/solvers/modified_kron.py
|
|
126
128
|
pmrf/simulate/solvers/redheffer.py
|
|
127
129
|
pmrf/simulate/solvers/transfer_cascader.py
|
|
128
130
|
pmrf/utils/__init__.py
|
|
129
131
|
pmrf/utils/array.py
|
|
132
|
+
pmrf/utils/debug.py
|
|
130
133
|
pmrf/utils/network.py
|
|
131
134
|
pmrf/utils/optix.py
|
|
132
135
|
pmrf/utils/random.py
|
|
@@ -156,5 +159,5 @@ tests/test_models/test_interconnected.py
|
|
|
156
159
|
tests/test_models/test_lines.py
|
|
157
160
|
tests/test_models/test_lumped.py
|
|
158
161
|
tests/test_models/test_nodal.py
|
|
159
|
-
tests/test_models/
|
|
162
|
+
tests/test_models/test_sections.py
|
|
160
163
|
tests/test_models/test_transformed.py
|
|
@@ -27,7 +27,7 @@ except PackageNotFoundError:
|
|
|
27
27
|
# Re-exports
|
|
28
28
|
from pmrf.models import Model as Model
|
|
29
29
|
from pmrf.frequency import Frequency as Frequency
|
|
30
|
-
from pmrf.topology import Topology as Topology
|
|
30
|
+
from pmrf.simulate.topology import Topology as Topology
|
|
31
31
|
from pmrf.problem import Problem as Problem
|
|
32
32
|
|
|
33
33
|
#: The canonical type hint for a float, or a numpy or JAX array.
|
|
@@ -3,6 +3,7 @@ Base class for RF models.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from typing import Any, Callable, Self, TypeVar, Union
|
|
6
|
+
from functools import cached_property
|
|
6
7
|
import dataclasses
|
|
7
8
|
|
|
8
9
|
import jax
|
|
@@ -12,12 +13,12 @@ import equinox as eqx
|
|
|
12
13
|
import skrf
|
|
13
14
|
import parax as prx
|
|
14
15
|
|
|
16
|
+
from pmrf.rf.mna import MNAStamp
|
|
15
17
|
from pmrf.utils.optix import focus, Lens
|
|
16
18
|
from pmrf.parameters import Param
|
|
17
19
|
from pmrf.frequency import Frequency
|
|
18
20
|
from pmrf.rf import (
|
|
19
|
-
|
|
20
|
-
y2z, z2y, a2y, y2a, a2z, z2a,
|
|
21
|
+
a2s, s2a, s2y, y2s, s2z, z2s, y2z, z2y, a2y, y2a, a2z, z2a, s2mna, y2mna, z2mna, a2mna,
|
|
21
22
|
)
|
|
22
23
|
from pmrf.math import CONVERSION_LOOKUP
|
|
23
24
|
from pmrf.utils.type import is_overridden
|
|
@@ -25,7 +26,7 @@ from pmrf.utils import field, unwrap, unwrap_self
|
|
|
25
26
|
|
|
26
27
|
T = TypeVar('T')
|
|
27
28
|
|
|
28
|
-
PRIMARY_DOMAINS = ('s', 'a', 'y', 'z')
|
|
29
|
+
PRIMARY_DOMAINS = ('s', 'a', 'y', 'z', 'mna')
|
|
29
30
|
PRIMARY_METHODS = PRIMARY_DOMAINS + ('build', 'primary_matrix')
|
|
30
31
|
HUB_Z0 = 50.0 + 0.0j
|
|
31
32
|
|
|
@@ -64,6 +65,7 @@ class Model(eqx.Module):
|
|
|
64
65
|
:meth:`a` ABCD parameter matrix.
|
|
65
66
|
:meth:`z` Impedance (Z) parameter matrix.
|
|
66
67
|
:meth:`y` Admittance (Y) parameter matrix.
|
|
68
|
+
:meth:`mna` Modified Nodal Analysis (MNA) stamp matrices.
|
|
67
69
|
:meth:`build` Build the model. Can be overridden for advanced models.
|
|
68
70
|
:meth:`primary_matrix` Return the primary matrix. Can be overridden for dynamic dispatch.
|
|
69
71
|
:attr:`primary_domain` The domain of the primary matrix as a string (e.g. ``"s"``, ``"a"``).
|
|
@@ -181,7 +183,7 @@ class Model(eqx.Module):
|
|
|
181
183
|
|
|
182
184
|
# ---- Introspection properties --------------------------------------------------------
|
|
183
185
|
|
|
184
|
-
@
|
|
186
|
+
@cached_property
|
|
185
187
|
def number_of_ports(self) -> int:
|
|
186
188
|
"""Number of ports.
|
|
187
189
|
|
|
@@ -189,11 +191,14 @@ class Model(eqx.Module):
|
|
|
189
191
|
-------
|
|
190
192
|
int
|
|
191
193
|
"""
|
|
194
|
+
if is_overridden(type(self), Model, 'build'):
|
|
195
|
+
return self.build().number_of_ports
|
|
196
|
+
|
|
192
197
|
freq = Frequency(1, 2, 2)
|
|
193
198
|
eval = jax.eval_shape(lambda: self.s(freq))
|
|
194
199
|
return eval.shape[1]
|
|
195
200
|
|
|
196
|
-
@
|
|
201
|
+
@cached_property
|
|
197
202
|
def nports(self) -> int:
|
|
198
203
|
"""Alias of :attr:`number_of_ports`."""
|
|
199
204
|
return self.number_of_ports
|
|
@@ -490,11 +495,11 @@ class Model(eqx.Module):
|
|
|
490
495
|
kwargs = {'z0': HUB_Z0} if primary_domain == 's' else {}
|
|
491
496
|
val = self.primary_matrix(freq, **kwargs)
|
|
492
497
|
|
|
493
|
-
# Return
|
|
498
|
+
# Return direct
|
|
494
499
|
if primary_domain == 'a':
|
|
495
500
|
return val
|
|
496
501
|
|
|
497
|
-
# Convert
|
|
502
|
+
# Convert with priority s, z, y
|
|
498
503
|
if primary_domain == 's':
|
|
499
504
|
return s2a(val, z0=HUB_Z0)
|
|
500
505
|
elif primary_domain == 'z':
|
|
@@ -529,11 +534,11 @@ class Model(eqx.Module):
|
|
|
529
534
|
kwargs = {'z0': HUB_Z0} if primary_domain == 's' else {}
|
|
530
535
|
val = self.primary_matrix(freq, **kwargs)
|
|
531
536
|
|
|
532
|
-
# Return
|
|
537
|
+
# Return direct
|
|
533
538
|
if primary_domain == 'z':
|
|
534
539
|
return val
|
|
535
540
|
|
|
536
|
-
# Convert
|
|
541
|
+
# Convert with priority s, a, y
|
|
537
542
|
if primary_domain == 's':
|
|
538
543
|
return s2z(val, z0=HUB_Z0)
|
|
539
544
|
elif primary_domain == 'a':
|
|
@@ -568,11 +573,11 @@ class Model(eqx.Module):
|
|
|
568
573
|
kwargs = {'z0': HUB_Z0} if primary_domain == 's' else {}
|
|
569
574
|
val = self.primary_matrix(freq, **kwargs)
|
|
570
575
|
|
|
571
|
-
# Return
|
|
576
|
+
# Return direct
|
|
572
577
|
if primary_domain == 'y':
|
|
573
578
|
return val
|
|
574
579
|
|
|
575
|
-
# Convert
|
|
580
|
+
# Convert with priority s, a, z
|
|
576
581
|
if primary_domain == 's':
|
|
577
582
|
return s2y(val, HUB_Z0)
|
|
578
583
|
elif primary_domain == 'a':
|
|
@@ -581,6 +586,43 @@ class Model(eqx.Module):
|
|
|
581
586
|
return z2y(val)
|
|
582
587
|
else:
|
|
583
588
|
raise NotImplementedError(f"Conversion from '{primary_domain}' to 'y' is not implemented.")
|
|
589
|
+
|
|
590
|
+
@eqx.filter_jit
|
|
591
|
+
@unwrap_self
|
|
592
|
+
def mna(self, freq: Frequency) -> MNAStamp:
|
|
593
|
+
"""
|
|
594
|
+
(experimental) Modified Nodal Analysis (MNA) stamp.
|
|
595
|
+
|
|
596
|
+
Can be overridden in sub-classes.
|
|
597
|
+
|
|
598
|
+
If the model does not explicitly define an MNA stamp, this automatically
|
|
599
|
+
delegates to the appropriate conversion utility (`s2mna`, `z2mna`, etc.).
|
|
600
|
+
Explicitly defined Y-matrices are prioritized to maximize matrix sparsity,
|
|
601
|
+
while other domains fall back to auxiliary variables to guarantee stability.
|
|
602
|
+
"""
|
|
603
|
+
if is_overridden(type(self), Model, 'build'):
|
|
604
|
+
return self.build().mna(freq)
|
|
605
|
+
|
|
606
|
+
primary_domain = self.primary_domain
|
|
607
|
+
|
|
608
|
+
if primary_domain == 'mna':
|
|
609
|
+
return self.primary_matrix(freq)
|
|
610
|
+
|
|
611
|
+
# We prioritize y, z and a for sparsity, assuming the caller
|
|
612
|
+
# has created a numerically stable implementation.
|
|
613
|
+
if primary_domain == 'y' or is_overridden(type(self), Model, 'y'):
|
|
614
|
+
return y2mna(self.y(freq))
|
|
615
|
+
|
|
616
|
+
if primary_domain == 'z' or is_overridden(type(self), Model, 'z'):
|
|
617
|
+
return z2mna(self.z(freq))
|
|
618
|
+
|
|
619
|
+
if primary_domain == 'a' or is_overridden(type(self), Model, 'a'):
|
|
620
|
+
return a2mna(self.a(freq))
|
|
621
|
+
|
|
622
|
+
if primary_domain == 's' or is_overridden(type(self), Model, 's'):
|
|
623
|
+
return s2mna(self.s(freq, z0=HUB_Z0), z0=HUB_Z0)
|
|
624
|
+
|
|
625
|
+
return y2mna(self.y(freq))
|
|
584
626
|
|
|
585
627
|
# ---- Magic methods and copying --------------------------------------------------
|
|
586
628
|
|
|
@@ -669,9 +711,11 @@ class Model(eqx.Module):
|
|
|
669
711
|
methods like `.get()` and `.set()` to retrieve values
|
|
670
712
|
or an updated model.
|
|
671
713
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
714
|
+
WARNING: All updates made by this method are "surgical".
|
|
715
|
+
In order words, values are replaced *as-is* without any converters
|
|
716
|
+
or verification applied (a new instance is still returned).
|
|
717
|
+
Any invariants must therefore be enforced or checked manually.
|
|
718
|
+
For example, when replacing parameters, ensure to pass in a fully
|
|
675
719
|
constructed parameter and not a float.
|
|
676
720
|
|
|
677
721
|
Examples
|
|
@@ -9,7 +9,7 @@ import equinox as eqx
|
|
|
9
9
|
|
|
10
10
|
from pmrf.models import Model
|
|
11
11
|
from pmrf.frequency import Frequency
|
|
12
|
-
from pmrf.utils import field
|
|
12
|
+
from pmrf.utils import field, error_if
|
|
13
13
|
from pmrf.rf import renormalize_s
|
|
14
14
|
from pmrf.types import ArrayLike, Param
|
|
15
15
|
from pmrf.parameters import param
|
|
@@ -37,25 +37,6 @@ class Load(Model):
|
|
|
37
37
|
repeat(freq.npoints, 0)
|
|
38
38
|
return s
|
|
39
39
|
|
|
40
|
-
def y(self, freq: Frequency) -> jnp.ndarray:
|
|
41
|
-
gamma_arr = jnp.asarray(self.gamma)
|
|
42
|
-
|
|
43
|
-
is_invalid = jnp.any(gamma_arr == -1.0)
|
|
44
|
-
|
|
45
|
-
gamma_safe = eqx.error_if(
|
|
46
|
-
gamma_arr,
|
|
47
|
-
is_invalid,
|
|
48
|
-
"Y-matrix is singular and undefined for ideal short (-1.0) loads."
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
y_val = (1.0 - gamma_safe) / (1.0 + gamma_safe)
|
|
52
|
-
|
|
53
|
-
y = jnp.asarray(y_val).reshape(-1, 1, 1) * \
|
|
54
|
-
jnp.eye(self.nports, dtype=jnp.complex128).reshape((-1, self.nports, self.nports)).\
|
|
55
|
-
repeat(freq.npoints, 0)
|
|
56
|
-
|
|
57
|
-
return y
|
|
58
|
-
|
|
59
40
|
|
|
60
41
|
class Short(Model):
|
|
61
42
|
"""
|