paramrf 0.25.2__tar.gz → 0.26.0__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.25.2/paramrf.egg-info → paramrf-0.26.0}/PKG-INFO +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/api/index.rst +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/custom_parametric_models.rst +2 -2
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/tutorials/1_cable_fitting.ipynb +5 -5
- {paramrf-0.25.2 → paramrf-0.26.0/paramrf.egg-info}/PKG-INFO +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/__init__.py +2 -2
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/nodal.py +23 -3
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/parameters.py +22 -21
- {paramrf-0.25.2 → paramrf-0.26.0}/pyproject.toml +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_adapters.py +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_optimize_minimize.py +1 -1
- {paramrf-0.25.2 → paramrf-0.26.0}/.github/workflows/docs.yml +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/.github/workflows/draft-pdf.yml +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/.github/workflows/publish.yml +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/.github/workflows/tests.yml +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/.gitignore +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/CONTRIBUTING.md +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/LICENSE +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/README.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/assets/logo.png +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/Makefile +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/_static/custom.css +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/_templates/autosummary/class.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/_templates/autosummary/function.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/_templates/autosummary/module.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/conf.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/core_concepts/core_primitives.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/core_concepts/index.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/core_concepts/jax_overview.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/core_concepts/optimization_and_inference.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/cascading_and_terminating.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/circuit_clc.png +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/circuit_models.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/custom_composite_models.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/derivatives_and_sweeps.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/index.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/model_optimization.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/examples/parameter_naming_and_model_manipulation.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/index.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/license.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/make.bat +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/models/index.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/skrf_comparison.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/tutorials/data/CBN-1.5FT-SMSM.s2p +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/docs/tutorials/index.rst +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paper/paper.bib +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paper/paper.md +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paper/rlc.png +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paramrf.egg-info/SOURCES.txt +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paramrf.egg-info/dependency_links.txt +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paramrf.egg-info/requires.txt +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/paramrf.egg-info/top_level.txt +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/constraints.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/covariance_kernels.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/discrepancy_models.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/distributions.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/evaluators.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/fitting/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/fitting/minimize.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/fitting/result.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/fitting/routers.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/fitting/sample.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/frequency.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/result.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/sample.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/solvers/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/solvers/blackjax.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/infer/solvers/polychord.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/likelihoods.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/losses.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/math/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/math/aggregations.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/math/conversions.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/math/losses.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/math/misc.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/adapters/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/adapters/base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/adapters/bridge.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/adapters/callable.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/adapters/static.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/ideal.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/lines/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/lines/nonuniform.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/lines/uniform.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/lumped.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/components/sections.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/interconnected.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/topological.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/transformed.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/composite/wrapped.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/surrogates/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/surrogates/expansion.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/models/surrogates/rational.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/network_collection.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/noise_models.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/minimize.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/result.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/solvers/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/solvers/jaxopt.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/solvers/optimistix.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/optimize/solvers/scipy.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/problem.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/rf/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/rf/conversions.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/serialization.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/cascade.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/reduce.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/result.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/hallbjorner.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/kron.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/linear_fractional_terminator.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/mobius_terminator.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/redheffer.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/solvers/transfer_cascader.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/simulate/terminate.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/topology.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/types.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/array.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/network.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/optix.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/random.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/rf.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/transforms.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/tree.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/utils/type.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/viz/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/pmrf/viz/plots.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/setup.cfg +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/__init__.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/data/10m_cable.s2p +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_autodiff.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_evaluators.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_fitting_minimize.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_fitting_routers.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_fitting_sample.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_frequency.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_infer_base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_infer_sample.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_model.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_interconnected.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_lines.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_lumped.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_nodal.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_topological.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_models/test_transformed.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_naming.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_optimize_base.py +0 -0
- {paramrf-0.25.2 → paramrf-0.26.0}/tests/test_transforms.py +0 -0
|
@@ -58,12 +58,12 @@ The code below demonstrates this by extending the previous class, while constrai
|
|
|
58
58
|
from pmrf.constraints import Positive
|
|
59
59
|
|
|
60
60
|
class Capacitor(Capacitor):
|
|
61
|
-
C: prf.Param = prf.param(constraint=Positive(),
|
|
61
|
+
C: prf.Param = prf.param(constraint=Positive(), as_free=True, scale=1e-12)
|
|
62
62
|
|
|
63
63
|
# def a(self, freq: prf.Frequency) -> jnp.ndarray:
|
|
64
64
|
# <same as before>
|
|
65
65
|
|
|
66
|
-
By passing ``
|
|
66
|
+
By passing ``as_free=True``, ParamRF will enforce that the incoming value is a tunable parameter even if a float is passed. Similarly, ``as_fixed=True`` can be used to fix any incoming parameters. However, these converters are entirely optionaly, and by default the parameter's "tunability" is left unchanged, which is the most common use-case (simply registering the value in the parameter hierarchy).
|
|
67
67
|
|
|
68
68
|
Note that constraints will also always be enforced (even for unconstrained optimizers!), and will also automatically be intersected with any new constraints provided by the caller.
|
|
69
69
|
|
|
@@ -108,12 +108,12 @@
|
|
|
108
108
|
"source": [
|
|
109
109
|
"ParamRF provides a few transmission line models, such as ``PhysicalLine``, ``CoaxialLine`` and ``DatasheetLine``. Looking at the datasheet, we see no mention of physical parameters like loss tangent, conductor loss or detailed geometry dimensions. However, there is a velocity factor, as well as loss factors ``k1`` and ``k2``. This is just what ``DatasheetLine`` was meant for.\n",
|
|
110
110
|
"\n",
|
|
111
|
-
"Let's try fitting the model with its expected length and default parameters as a quick check.
|
|
111
|
+
"Let's try fitting the model with its expected length and default parameters as a quick check. Note that if we construct a default model or pass in float values, all parameters in the model are seen as fixed (non-tunable). For demonstration purposes, if we want to optimize the default model but don't have an initial guess, we can set all the parameters to be variable (tunable) using ``pmrf.as_variable``."
|
|
112
112
|
]
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"cell_type": "code",
|
|
116
|
-
"execution_count":
|
|
116
|
+
"execution_count": null,
|
|
117
117
|
"id": "40843bab",
|
|
118
118
|
"metadata": {},
|
|
119
119
|
"outputs": [
|
|
@@ -155,10 +155,10 @@
|
|
|
155
155
|
"\n",
|
|
156
156
|
"# Free all parameters\n",
|
|
157
157
|
"for name in default_model.named_params().keys():\n",
|
|
158
|
-
" default_model = default_model.at(name).apply(prf.
|
|
158
|
+
" default_model = default_model.at(name).apply(prf.as_free)\n",
|
|
159
159
|
"\n",
|
|
160
|
-
"# We could also have
|
|
161
|
-
"# default_model = default_model.map(
|
|
160
|
+
"# We could also have used a map\n",
|
|
161
|
+
"# default_model = default_model.map(prf.as_free, predicate=prf.is_param)\n",
|
|
162
162
|
"\n",
|
|
163
163
|
"default_results = prf.fitting.fit(default_model, measured)\n",
|
|
164
164
|
"\n",
|
|
@@ -41,7 +41,7 @@ Param: TypeAlias = parax.AbstractVariable | ArrayLike
|
|
|
41
41
|
|
|
42
42
|
from pmrf.parameters import (
|
|
43
43
|
param as param,
|
|
44
|
-
|
|
44
|
+
as_free as as_free,
|
|
45
45
|
as_fixed as as_fixed,
|
|
46
46
|
Unconstrained as Unconstrained,
|
|
47
47
|
Fixed as Fixed,
|
|
@@ -103,7 +103,7 @@ __all__ = [
|
|
|
103
103
|
|
|
104
104
|
"Param",
|
|
105
105
|
"param",
|
|
106
|
-
"
|
|
106
|
+
"as_free",
|
|
107
107
|
"as_fixed",
|
|
108
108
|
"Unconstrained",
|
|
109
109
|
"Fixed",
|
|
@@ -345,13 +345,27 @@ class CoupledTwoPorts(Model):
|
|
|
345
345
|
n = len(self.coupled)
|
|
346
346
|
|
|
347
347
|
z_branch_list = []
|
|
348
|
+
y_shunt1_list = []
|
|
349
|
+
y_shunt2_list = []
|
|
350
|
+
|
|
348
351
|
for m in self.coupled:
|
|
349
352
|
y_i = m.y(freq)
|
|
350
|
-
|
|
353
|
+
|
|
354
|
+
# Decompose the Pi-Network
|
|
355
|
+
# Series branch
|
|
356
|
+
y_series = -y_i[..., 0, 1]
|
|
357
|
+
z_series = 1.0 / y_series
|
|
351
358
|
z_branch_list.append(z_series)
|
|
352
359
|
|
|
360
|
+
# Shunt branches to ground
|
|
361
|
+
y_shunt1_list.append(y_i[..., 0, 0] + y_i[..., 0, 1])
|
|
362
|
+
y_shunt2_list.append(y_i[..., 1, 1] + y_i[..., 1, 0])
|
|
363
|
+
|
|
353
364
|
z_branch = jnp.stack(z_branch_list, axis=-1)
|
|
365
|
+
y_p1 = jnp.stack(y_shunt1_list, axis=-1)
|
|
366
|
+
y_p2 = jnp.stack(y_shunt2_list, axis=-1)
|
|
354
367
|
|
|
368
|
+
# Couple the series branches exactly as before
|
|
355
369
|
x_branch = jnp.imag(z_branch)
|
|
356
370
|
x_outer = x_branch[..., :, jnp.newaxis] * x_branch[..., jnp.newaxis, :]
|
|
357
371
|
|
|
@@ -362,14 +376,20 @@ class CoupledTwoPorts(Model):
|
|
|
362
376
|
i = jnp.arange(n)
|
|
363
377
|
z_b_matrix = z_b_matrix.at[..., i, i].set(z_branch)
|
|
364
378
|
|
|
365
|
-
# Invert to get branch admittances
|
|
366
379
|
y_b_matrix = jnp.linalg.inv(z_b_matrix)
|
|
367
380
|
|
|
368
|
-
# Nodal incidence matrix translation
|
|
369
381
|
A = jnp.zeros((2 * n, n), dtype=jnp.float64)
|
|
370
382
|
A = A.at[0::2, :].set(jnp.eye(n))
|
|
371
383
|
A = A.at[1::2, :].set(-jnp.eye(n))
|
|
372
384
|
|
|
373
385
|
y_nodal = jnp.einsum('pi,...ij,qj->...pq', A, y_b_matrix, A)
|
|
374
386
|
|
|
387
|
+
# Glue the substrate/shunt parasitics back onto the final nodes
|
|
388
|
+
# Model 'm' has Port 1 at index 2*m, and Port 2 at index 2*m + 1
|
|
389
|
+
even_indices = jnp.arange(0, 2 * n, 2)
|
|
390
|
+
odd_indices = jnp.arange(1, 2 * n, 2)
|
|
391
|
+
|
|
392
|
+
y_nodal = y_nodal.at[..., even_indices, even_indices].add(y_p1)
|
|
393
|
+
y_nodal = y_nodal.at[..., odd_indices, odd_indices].add(y_p2)
|
|
394
|
+
|
|
375
395
|
return y_nodal
|
|
@@ -22,7 +22,7 @@ from pmrf.types import Param
|
|
|
22
22
|
from pmrf.utils import unfreeze
|
|
23
23
|
|
|
24
24
|
def apply_wrappers(value: Any, scale: float, fixed: bool, name: str | None) -> Param:
|
|
25
|
-
value = prx.
|
|
25
|
+
value = prx.as_free(value)
|
|
26
26
|
if scale != 1.0:
|
|
27
27
|
scale_val = jnp.asarray(scale, dtype=float)
|
|
28
28
|
try:
|
|
@@ -73,7 +73,7 @@ def extract_name(value: Any) -> str | None:
|
|
|
73
73
|
return named_variable[0].metadata['name']
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def
|
|
76
|
+
def as_free(
|
|
77
77
|
value: Any = None,
|
|
78
78
|
*,
|
|
79
79
|
distribution: Optional[AbstractDistribution] = None,
|
|
@@ -82,7 +82,7 @@ def as_variable(
|
|
|
82
82
|
name: Optional[str] = None,
|
|
83
83
|
) -> Param:
|
|
84
84
|
"""
|
|
85
|
-
Coerces a value into a
|
|
85
|
+
Coerces a value into a free parameter.
|
|
86
86
|
|
|
87
87
|
The incoming value can be an existing parameter or any
|
|
88
88
|
parameter-like object (float, array etc.).
|
|
@@ -183,7 +183,7 @@ def as_fixed(
|
|
|
183
183
|
pmrf.Param
|
|
184
184
|
A fixed parameter.
|
|
185
185
|
"""
|
|
186
|
-
variable =
|
|
186
|
+
variable = as_free(
|
|
187
187
|
value,
|
|
188
188
|
distribution=distribution,
|
|
189
189
|
constraint=constraint,
|
|
@@ -197,7 +197,7 @@ def as_fixed(
|
|
|
197
197
|
def param(
|
|
198
198
|
*,
|
|
199
199
|
default: Any = dataclasses.MISSING,
|
|
200
|
-
|
|
200
|
+
as_free: bool = False,
|
|
201
201
|
as_fixed: bool = False,
|
|
202
202
|
distribution: Optional[AbstractDistribution] = None,
|
|
203
203
|
constraint: Optional[AbstractConstraint] = None,
|
|
@@ -241,7 +241,7 @@ def param(
|
|
|
241
241
|
----------
|
|
242
242
|
default : Any, optional
|
|
243
243
|
The default value of the parameter.
|
|
244
|
-
|
|
244
|
+
as_free : bool, optional
|
|
245
245
|
Whether to enforce that the value is a variable parameter.
|
|
246
246
|
If False, incoming values will keep the variability (e.g. constants will remain constants).
|
|
247
247
|
If True, all values will be co-erced into variable parameters.
|
|
@@ -263,22 +263,22 @@ def param(
|
|
|
263
263
|
Any
|
|
264
264
|
An equinox field with a built-in converter for parameter rules.
|
|
265
265
|
"""
|
|
266
|
-
if as_fixed and
|
|
267
|
-
raise ValueError("Cannot pass both `as_fixed=True` and `
|
|
266
|
+
if as_fixed and as_free:
|
|
267
|
+
raise ValueError("Cannot pass both `as_fixed=True` and `as_free=True` to `pmrf.param`")
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
as_free_func = globals()['as_free']
|
|
270
270
|
as_fixed_func = globals()['as_fixed']
|
|
271
271
|
|
|
272
272
|
def converter(x):
|
|
273
|
-
if
|
|
274
|
-
return
|
|
273
|
+
if as_free:
|
|
274
|
+
return as_free_func(value=x, distribution=distribution, constraint=constraint, scale=scale)
|
|
275
275
|
if as_fixed:
|
|
276
276
|
return as_fixed_func(value=x, distribution=distribution, constraint=constraint, scale=scale)
|
|
277
277
|
|
|
278
278
|
if x is None:
|
|
279
279
|
return None
|
|
280
280
|
elif (prx.is_variable(x) or isinstance(x, jax.Array)) and not prx.is_constant(x):
|
|
281
|
-
return
|
|
281
|
+
return as_free_func(value=x, distribution=distribution, constraint=constraint, scale=scale)
|
|
282
282
|
return as_fixed_func(value=x, distribution=distribution, constraint=constraint, scale=scale)
|
|
283
283
|
|
|
284
284
|
return eqx.field(default=default, converter=converter, **kwargs)
|
|
@@ -322,7 +322,7 @@ def Unconstrained(
|
|
|
322
322
|
name: Optional[str] = None,
|
|
323
323
|
) -> Param:
|
|
324
324
|
"""
|
|
325
|
-
Create an unconstrained
|
|
325
|
+
Create an unconstrained free parameter.
|
|
326
326
|
|
|
327
327
|
Parameters
|
|
328
328
|
----------
|
|
@@ -338,7 +338,7 @@ def Unconstrained(
|
|
|
338
338
|
pmrf.Param
|
|
339
339
|
An unconstrained parameter.
|
|
340
340
|
"""
|
|
341
|
-
return
|
|
341
|
+
return as_free(value, scale=scale, name=name)
|
|
342
342
|
|
|
343
343
|
|
|
344
344
|
def Constrained(
|
|
@@ -349,7 +349,7 @@ def Constrained(
|
|
|
349
349
|
name: Optional[str] = None,
|
|
350
350
|
) -> Param:
|
|
351
351
|
"""
|
|
352
|
-
Create a
|
|
352
|
+
Create a free parameter constrained to a specific domain.
|
|
353
353
|
|
|
354
354
|
See :mod:`pmrf.constraints` for built-in constraints.
|
|
355
355
|
|
|
@@ -369,7 +369,7 @@ def Constrained(
|
|
|
369
369
|
pmrf.Param
|
|
370
370
|
The constrained parameter.
|
|
371
371
|
"""
|
|
372
|
-
return
|
|
372
|
+
return as_free(value, constraint=constraint, scale=scale, name=name)
|
|
373
373
|
|
|
374
374
|
|
|
375
375
|
def Bounded(
|
|
@@ -381,7 +381,7 @@ def Bounded(
|
|
|
381
381
|
name: Optional[str] = None,
|
|
382
382
|
) -> Param:
|
|
383
383
|
"""
|
|
384
|
-
Create a
|
|
384
|
+
Create a free parameter constrained within a specific interval.
|
|
385
385
|
|
|
386
386
|
Used as the main factory to define parameters for bounded optimization.
|
|
387
387
|
|
|
@@ -405,7 +405,7 @@ def Bounded(
|
|
|
405
405
|
pmrf.Param
|
|
406
406
|
The bounded parameter.
|
|
407
407
|
"""
|
|
408
|
-
return
|
|
408
|
+
return as_free(value, constraint=Interval(lower, upper), scale=scale, name=name)
|
|
409
409
|
|
|
410
410
|
|
|
411
411
|
def Random(
|
|
@@ -417,7 +417,7 @@ def Random(
|
|
|
417
417
|
name: Optional[str] = None,
|
|
418
418
|
) -> Param:
|
|
419
419
|
"""
|
|
420
|
-
Create a
|
|
420
|
+
Create a free parameter with an associated probability distribution.
|
|
421
421
|
|
|
422
422
|
Used as the main factory to define parameters for Bayesian inference.
|
|
423
423
|
Can also be used for bounded optimization, in which case the random
|
|
@@ -451,11 +451,12 @@ def Random(
|
|
|
451
451
|
ValueError
|
|
452
452
|
If `value` is None and the distribution does not implement `mean()`.
|
|
453
453
|
"""
|
|
454
|
-
return
|
|
454
|
+
return as_free(value, distribution=distribution, constraint=constraint, scale=scale, name=name)
|
|
455
455
|
|
|
456
456
|
|
|
457
457
|
__all__ = [
|
|
458
|
-
"
|
|
458
|
+
"as_free",
|
|
459
|
+
"as_fixed",
|
|
459
460
|
"Unconstrained",
|
|
460
461
|
"Fixed",
|
|
461
462
|
"Bounded",
|
|
@@ -74,7 +74,7 @@ def test_single_property_routing(fine_freq):
|
|
|
74
74
|
|
|
75
75
|
class DummyHostModel(Host):
|
|
76
76
|
"""A dummy host model representing an external simulator."""
|
|
77
|
-
val: Param = param(default=10.0,
|
|
77
|
+
val: Param = param(default=10.0, as_free=True)
|
|
78
78
|
|
|
79
79
|
@property
|
|
80
80
|
def number_of_ports(self):
|
|
@@ -15,7 +15,7 @@ from pmrf.optimize.solvers.scipy import ScipyMinimize
|
|
|
15
15
|
|
|
16
16
|
class DummyOptModel(Model):
|
|
17
17
|
"""A simple 1-port model with one free parameter for optimization."""
|
|
18
|
-
val: prf.Param = prf.param(default=1.0,
|
|
18
|
+
val: prf.Param = prf.param(default=1.0, as_free=True)
|
|
19
19
|
|
|
20
20
|
def s(self, freq: Frequency) -> jnp.ndarray:
|
|
21
21
|
nf = freq.npoints
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|