paramrf 0.37.0__tar.gz → 0.37.2__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.
Files changed (267) hide show
  1. {paramrf-0.37.0/paramrf.egg-info → paramrf-0.37.2}/PKG-INFO +2 -1
  2. {paramrf-0.37.0 → paramrf-0.37.2/paramrf.egg-info}/PKG-INFO +2 -1
  3. {paramrf-0.37.0 → paramrf-0.37.2}/paramrf.egg-info/SOURCES.txt +1 -0
  4. {paramrf-0.37.0 → paramrf-0.37.2}/paramrf.egg-info/requires.txt +1 -0
  5. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/__init__.py +17 -4
  6. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/__init__.py +2 -0
  7. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/ideal.py +47 -0
  8. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/nodal.py +46 -0
  9. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/objectives/__init__.py +37 -0
  10. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/__init__.py +69 -0
  11. {paramrf-0.37.0 → paramrf-0.37.2}/pyproject.toml +2 -1
  12. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_dc_limits.py +2 -0
  13. paramrf-0.37.2/tests/test_grouped_exports.py +156 -0
  14. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_edge_values.py +8 -1
  15. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_nodal.py +41 -1
  16. {paramrf-0.37.0 → paramrf-0.37.2}/.github/workflows/docs.yml +0 -0
  17. {paramrf-0.37.0 → paramrf-0.37.2}/.github/workflows/draft-pdf.yml +0 -0
  18. {paramrf-0.37.0 → paramrf-0.37.2}/.github/workflows/publish.yml +0 -0
  19. {paramrf-0.37.0 → paramrf-0.37.2}/.github/workflows/tests.yml +0 -0
  20. {paramrf-0.37.0 → paramrf-0.37.2}/.gitignore +0 -0
  21. {paramrf-0.37.0 → paramrf-0.37.2}/AGENTS.md +0 -0
  22. {paramrf-0.37.0 → paramrf-0.37.2}/CHANGELOG.md +0 -0
  23. {paramrf-0.37.0 → paramrf-0.37.2}/CITATION.cff +0 -0
  24. {paramrf-0.37.0 → paramrf-0.37.2}/CLAUDE.md +0 -0
  25. {paramrf-0.37.0 → paramrf-0.37.2}/CONTEXT.md +0 -0
  26. {paramrf-0.37.0 → paramrf-0.37.2}/CONTRIBUTING.md +0 -0
  27. {paramrf-0.37.0 → paramrf-0.37.2}/LICENSE +0 -0
  28. {paramrf-0.37.0 → paramrf-0.37.2}/NOTICE +0 -0
  29. {paramrf-0.37.0 → paramrf-0.37.2}/README.rst +0 -0
  30. {paramrf-0.37.0 → paramrf-0.37.2}/assets/logo.png +0 -0
  31. {paramrf-0.37.0 → paramrf-0.37.2}/docs/Makefile +0 -0
  32. {paramrf-0.37.0 → paramrf-0.37.2}/docs/_static/custom.css +0 -0
  33. {paramrf-0.37.0 → paramrf-0.37.2}/docs/_templates/autosummary/class.rst +0 -0
  34. {paramrf-0.37.0 → paramrf-0.37.2}/docs/_templates/autosummary/function.rst +0 -0
  35. {paramrf-0.37.0 → paramrf-0.37.2}/docs/_templates/autosummary/module.rst +0 -0
  36. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0001-line-modelling-architecture.md +0 -0
  37. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0002-parameter-api.md +0 -0
  38. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0003-derived-models.md +0 -0
  39. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0004-profiled-lines.md +0 -0
  40. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0005-priors-by-name.md +0 -0
  41. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0006-reference-impedance.md +0 -0
  42. {paramrf-0.37.0 → paramrf-0.37.2}/docs/adr/0007-edge-values.md +0 -0
  43. {paramrf-0.37.0 → paramrf-0.37.2}/docs/agents/domain.md +0 -0
  44. {paramrf-0.37.0 → paramrf-0.37.2}/docs/agents/issue-tracker.md +0 -0
  45. {paramrf-0.37.0 → paramrf-0.37.2}/docs/agents/triage-labels.md +0 -0
  46. {paramrf-0.37.0 → paramrf-0.37.2}/docs/api/index.rst +0 -0
  47. {paramrf-0.37.0 → paramrf-0.37.2}/docs/conf.py +0 -0
  48. {paramrf-0.37.0 → paramrf-0.37.2}/docs/core_concepts/core_primitives.rst +0 -0
  49. {paramrf-0.37.0 → paramrf-0.37.2}/docs/core_concepts/index.rst +0 -0
  50. {paramrf-0.37.0 → paramrf-0.37.2}/docs/core_concepts/jax_overview.rst +0 -0
  51. {paramrf-0.37.0 → paramrf-0.37.2}/docs/core_concepts/optimization_and_inference.rst +0 -0
  52. {paramrf-0.37.0 → paramrf-0.37.2}/docs/core_concepts/parameter_names.rst +0 -0
  53. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/cascading_and_terminating.rst +0 -0
  54. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/circuit_clc.png +0 -0
  55. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/circuit_models.rst +0 -0
  56. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/custom_models.rst +0 -0
  57. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/derivatives_and_sweeps.rst +0 -0
  58. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/discrepancy_prediction.rst +0 -0
  59. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/index.rst +0 -0
  60. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/model_optimization.rst +0 -0
  61. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/multiple_models_one_parameter_set.rst +0 -0
  62. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/parameter_naming_and_model_manipulation.rst +0 -0
  63. {paramrf-0.37.0 → paramrf-0.37.2}/docs/examples/shared_modules.rst +0 -0
  64. {paramrf-0.37.0 → paramrf-0.37.2}/docs/index.rst +0 -0
  65. {paramrf-0.37.0 → paramrf-0.37.2}/docs/license.rst +0 -0
  66. {paramrf-0.37.0 → paramrf-0.37.2}/docs/make.bat +0 -0
  67. {paramrf-0.37.0 → paramrf-0.37.2}/docs/research/conductor-loss-alternatives.md +0 -0
  68. {paramrf-0.37.0 → paramrf-0.37.2}/docs/research/holloway1994.pdf +0 -0
  69. {paramrf-0.37.0 → paramrf-0.37.2}/docs/research/microstrip-loss-conventions.md +0 -0
  70. {paramrf-0.37.0 → paramrf-0.37.2}/docs/research/precision-coax-microstrip-10-500mhz.md +0 -0
  71. {paramrf-0.37.0 → paramrf-0.37.2}/docs/skrf_comparison/index.rst +0 -0
  72. {paramrf-0.37.0 → paramrf-0.37.2}/docs/skrf_comparison/overview.rst +0 -0
  73. {paramrf-0.37.0 → paramrf-0.37.2}/docs/skrf_comparison/performance.rst +0 -0
  74. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/1_cable_fitting.ipynb +0 -0
  75. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/2_chip_inductor_fitting.ipynb +0 -0
  76. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/3_discrepancy_transfer.ipynb +0 -0
  77. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/data/CBN-1.5FT-SMSM.s2p +0 -0
  78. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/data/on-chip-inductor.s2p +0 -0
  79. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/index.rst +0 -0
  80. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/line_internal_discrepancy.py +0 -0
  81. {paramrf-0.37.0 → paramrf-0.37.2}/docs/tutorials/port_discrepancy.py +0 -0
  82. {paramrf-0.37.0 → paramrf-0.37.2}/paper/paper.bib +0 -0
  83. {paramrf-0.37.0 → paramrf-0.37.2}/paper/paper.md +0 -0
  84. {paramrf-0.37.0 → paramrf-0.37.2}/paper/rlc.png +0 -0
  85. {paramrf-0.37.0 → paramrf-0.37.2}/paramrf.egg-info/dependency_links.txt +0 -0
  86. {paramrf-0.37.0 → paramrf-0.37.2}/paramrf.egg-info/top_level.txt +0 -0
  87. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/_solver_view.py +0 -0
  88. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/__init__.py +0 -0
  89. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/minimize.py +0 -0
  90. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/result.py +0 -0
  91. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/routers.py +0 -0
  92. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/sample.py +0 -0
  93. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/fitting/targets.py +0 -0
  94. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/frequency.py +0 -0
  95. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/__init__.py +0 -0
  96. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/base.py +0 -0
  97. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/result.py +0 -0
  98. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/sample.py +0 -0
  99. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/solvers/__init__.py +0 -0
  100. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/solvers/blackjax.py +0 -0
  101. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/infer/solvers/polychord.py +0 -0
  102. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/__init__.py +0 -0
  103. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/conductor.py +0 -0
  104. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/dielectric.py +0 -0
  105. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/properties.py +0 -0
  106. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/roughness.py +0 -0
  107. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/substrate.py +0 -0
  108. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/materials/surface_impedance.py +0 -0
  109. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/__init__.py +0 -0
  110. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/aggregations.py +0 -0
  111. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/bessel.py +0 -0
  112. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/conversions.py +0 -0
  113. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/losses.py +0 -0
  114. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/math/misc.py +0 -0
  115. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/__init__.py +0 -0
  116. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/base.py +0 -0
  117. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/bridge.py +0 -0
  118. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/callable.py +0 -0
  119. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/delegated.py +0 -0
  120. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/derived.py +0 -0
  121. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/static.py +0 -0
  122. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/adapters/wrapped.py +0 -0
  123. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/base.py +0 -0
  124. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/__init__.py +0 -0
  125. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/ideal.py +0 -0
  126. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/__init__.py +0 -0
  127. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/base.py +0 -0
  128. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/coaxial.py +0 -0
  129. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/empirical.py +0 -0
  130. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/microstrip.py +0 -0
  131. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/nodal.py +0 -0
  132. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/nonuniform.py +0 -0
  133. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/planar.py +0 -0
  134. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/profiles.py +0 -0
  135. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lines/stripline.py +0 -0
  136. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/lumped.py +0 -0
  137. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/components/sections.py +0 -0
  138. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/__init__.py +0 -0
  139. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/__init__.py +0 -0
  140. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/cascade.py +0 -0
  141. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/__init__.py +0 -0
  142. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/base.py +0 -0
  143. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/circuit.py +0 -0
  144. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/solvers/__init__.py +0 -0
  145. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/solvers/nodal.py +0 -0
  146. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/circuit/solvers/scattering.py +0 -0
  147. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/interconnected/terminated.py +0 -0
  148. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/topological.py +0 -0
  149. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/composite/transformed.py +0 -0
  150. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/line_discrepancy.py +0 -0
  151. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/port_discrepancy.py +0 -0
  152. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/surrogates/__init__.py +0 -0
  153. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/surrogates/expansion.py +0 -0
  154. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/models/surrogates/rational.py +0 -0
  155. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/modules/__init__.py +0 -0
  156. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/modules/base.py +0 -0
  157. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/modules/wrapped.py +0 -0
  158. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/network_collection.py +0 -0
  159. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/objectives/evaluators.py +0 -0
  160. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/objectives/losses.py +0 -0
  161. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/objectives/problems.py +0 -0
  162. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/objectives/terms.py +0 -0
  163. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/__init__.py +0 -0
  164. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/base.py +0 -0
  165. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/minimize.py +0 -0
  166. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/result.py +0 -0
  167. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/solvers/__init__.py +0 -0
  168. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/solvers/jaxopt.py +0 -0
  169. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/solvers/optimistix.py +0 -0
  170. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/optimize/solvers/scipy.py +0 -0
  171. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/parameters/__init__.py +0 -0
  172. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/parameters/constraints.py +0 -0
  173. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/rf/__init__.py +0 -0
  174. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/rf/cascade.py +0 -0
  175. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/rf/conversions.py +0 -0
  176. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/rf/mna.py +0 -0
  177. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/serialization.py +0 -0
  178. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/bijectors.py +0 -0
  179. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/covariance_kernels.py +0 -0
  180. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/discrepancy_models.py +0 -0
  181. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/distributions.py +0 -0
  182. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/likelihoods.py +0 -0
  183. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/linearization.py +0 -0
  184. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/stats/noise_models.py +0 -0
  185. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/types.py +0 -0
  186. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/__init__.py +0 -0
  187. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/array.py +0 -0
  188. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/debug.py +0 -0
  189. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/network.py +0 -0
  190. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/random.py +0 -0
  191. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/rf.py +0 -0
  192. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/transforms.py +0 -0
  193. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/tree.py +0 -0
  194. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/utils/type.py +0 -0
  195. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/viz/__init__.py +0 -0
  196. {paramrf-0.37.0 → paramrf-0.37.2}/pmrf/viz/plots.py +0 -0
  197. {paramrf-0.37.0 → paramrf-0.37.2}/scripts/benchmark_gp_marginal_likelihood.py +0 -0
  198. {paramrf-0.37.0 → paramrf-0.37.2}/scripts/install-test-deps.sh +0 -0
  199. {paramrf-0.37.0 → paramrf-0.37.2}/setup.cfg +0 -0
  200. {paramrf-0.37.0 → paramrf-0.37.2}/tests/__init__.py +0 -0
  201. {paramrf-0.37.0 → paramrf-0.37.2}/tests/_jit.py +0 -0
  202. {paramrf-0.37.0 → paramrf-0.37.2}/tests/conftest.py +0 -0
  203. {paramrf-0.37.0 → paramrf-0.37.2}/tests/data/10m_cable.s2p +0 -0
  204. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_autodiff.py +0 -0
  205. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_box_space_solving.py +0 -0
  206. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_conversions.py +0 -0
  207. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_covariance_kernels.py +0 -0
  208. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_discrepancy_models.py +0 -0
  209. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_evaluators.py +0 -0
  210. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_fitting_minimize.py +0 -0
  211. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_fitting_routers.py +0 -0
  212. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_fitting_sample.py +0 -0
  213. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_fitting_targets.py +0 -0
  214. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_frequency.py +0 -0
  215. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_infer_base.py +0 -0
  216. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_infer_sample.py +0 -0
  217. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_line_internal_discrepancy_example.py +0 -0
  218. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_linearization.py +0 -0
  219. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_map_priors.py +0 -0
  220. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_materials/test_conductor.py +0 -0
  221. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_materials/test_dielectric.py +0 -0
  222. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_materials/test_serialization.py +0 -0
  223. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_materials/test_substrate.py +0 -0
  224. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_materials/test_surface_impedance.py +0 -0
  225. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_math/test_bessel.py +0 -0
  226. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_model.py +0 -0
  227. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_adapters.py +0 -0
  228. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_cascade.py +0 -0
  229. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_native_z0.py +0 -0
  230. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_nodal.py +0 -0
  231. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_port_order.py +0 -0
  232. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_scattering.py +0 -0
  233. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_shorted_ports.py +0 -0
  234. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_skrf_port_names.py +0 -0
  235. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_circuit_z0.py +0 -0
  236. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_current_distribution.py +0 -0
  237. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_derived.py +0 -0
  238. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_interconnected.py +0 -0
  239. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_line_discrepancy.py +0 -0
  240. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_lines.py +0 -0
  241. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_lines_skrf_matrix.py +0 -0
  242. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_lumped.py +0 -0
  243. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_port_discrepancy.py +0 -0
  244. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_profiles.py +0 -0
  245. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_rational.py +0 -0
  246. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_repeated_cascade.py +0 -0
  247. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_sections.py +0 -0
  248. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_transformed.py +0 -0
  249. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_models/test_transformers.py +0 -0
  250. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_module.py +0 -0
  251. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_naming.py +0 -0
  252. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_optimize_base.py +0 -0
  253. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_optimize_minimize.py +0 -0
  254. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_parameters.py +0 -0
  255. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_parameters_by_name.py +0 -0
  256. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_parameters_joint_prior.py +0 -0
  257. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_parameters_prior.py +0 -0
  258. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_parameters_validity.py +0 -0
  259. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_port_discrepancy_example.py +0 -0
  260. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_raw_space_solving.py +0 -0
  261. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_serialization.py +0 -0
  262. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_structural_updates.py +0 -0
  263. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_terms.py +0 -0
  264. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_transforms.py +0 -0
  265. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_utils/test_compress.py +0 -0
  266. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_utils/test_debug.py +0 -0
  267. {paramrf-0.37.0 → paramrf-0.37.2}/tests/test_utils/test_tree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paramrf
3
- Version: 0.37.0
3
+ Version: 0.37.2
4
4
  Summary: Parametric radio frequency modeling
5
5
  Author-email: Gary Allen <gvcallen@gmail.com>
6
6
  Project-URL: homepage, https://github.com/gvcallen/paramrf
@@ -35,6 +35,7 @@ Requires-Dist: jupyter-sphinx; extra == "docs"
35
35
  Provides-Extra: tests
36
36
  Requires-Dist: pytest; extra == "tests"
37
37
  Requires-Dist: pytest-xdist; extra == "tests"
38
+ Requires-Dist: jedi==0.20.0; extra == "tests"
38
39
  Requires-Dist: filelock; extra == "tests"
39
40
  Requires-Dist: ipython; extra == "tests"
40
41
  Requires-Dist: scikit-rf; extra == "tests"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paramrf
3
- Version: 0.37.0
3
+ Version: 0.37.2
4
4
  Summary: Parametric radio frequency modeling
5
5
  Author-email: Gary Allen <gvcallen@gmail.com>
6
6
  Project-URL: homepage, https://github.com/gvcallen/paramrf
@@ -35,6 +35,7 @@ Requires-Dist: jupyter-sphinx; extra == "docs"
35
35
  Provides-Extra: tests
36
36
  Requires-Dist: pytest; extra == "tests"
37
37
  Requires-Dist: pytest-xdist; extra == "tests"
38
+ Requires-Dist: jedi==0.20.0; extra == "tests"
38
39
  Requires-Dist: filelock; extra == "tests"
39
40
  Requires-Dist: ipython; extra == "tests"
40
41
  Requires-Dist: scikit-rf; extra == "tests"
@@ -206,6 +206,7 @@ tests/test_fitting_routers.py
206
206
  tests/test_fitting_sample.py
207
207
  tests/test_fitting_targets.py
208
208
  tests/test_frequency.py
209
+ tests/test_grouped_exports.py
209
210
  tests/test_infer_base.py
210
211
  tests/test_infer_sample.py
211
212
  tests/test_line_internal_discrepancy_example.py
@@ -28,6 +28,7 @@ jupyter-sphinx
28
28
  [tests]
29
29
  pytest
30
30
  pytest-xdist
31
+ jedi==0.20.0
31
32
  filelock
32
33
  ipython
33
34
  scikit-rf
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
  import warnings
3
3
  import os
4
+ from importlib import import_module
5
+ from typing import TYPE_CHECKING
4
6
 
5
7
  # Stop thread contention between vmap and CPU backend multithreading
6
8
  os.environ["OPENBLAS_NUM_THREADS"] = "1"
@@ -102,21 +104,32 @@ from pmrf.utils import (
102
104
 
103
105
  # Public packages
104
106
  from pmrf import (
105
- fitting as fitting,
106
- infer as infer,
107
107
  materials as materials,
108
108
  math as math,
109
109
  models as models,
110
110
  modules as modules,
111
111
  objectives as objectives,
112
- optimize as optimize,
113
112
  parameters as parameters,
114
113
  rf as rf,
115
114
  serialization as serialization,
116
115
  stats as stats,
117
- viz as viz,
118
116
  )
119
117
 
118
+ # These packages pull in objective implementations. Expose them on first access.
119
+ if TYPE_CHECKING:
120
+ from pmrf import fitting as fitting, infer as infer, optimize as optimize, viz as viz
121
+
122
+ def __getattr__(name):
123
+ if name in ("fitting", "infer", "optimize", "viz"):
124
+ module = import_module(f"{__name__}.{name}")
125
+ globals()[name] = module
126
+ return module
127
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
128
+
129
+
130
+ def __dir__():
131
+ return sorted(set(globals()) | set(__all__))
132
+
120
133
  __all__ = [
121
134
  # Base/Core
122
135
  "Model",
@@ -96,6 +96,7 @@ from pmrf.models.components.lines.nodal import (
96
96
  )
97
97
 
98
98
  from pmrf.models.components.lines.ideal import (
99
+ DelayLine as DelayLine,
99
100
  PhaseLine as PhaseLine,
100
101
  RLGCLine as RLGCLine,
101
102
  )
@@ -206,6 +207,7 @@ from pmrf.models.composite.transformed import (
206
207
  from pmrf.models.composite.nodal import (
207
208
  FloatingTwoPort as FloatingTwoPort,
208
209
  Shunt as Shunt,
210
+ Series as Series,
209
211
  GroundLifted as GroundLifted,
210
212
  GroundExposed as GroundExposed,
211
213
  CoupledOnePorts as CoupledOnePorts,
@@ -66,6 +66,53 @@ class PhaseLine(AbstractUniformLine):
66
66
  return zc, gammaL
67
67
 
68
68
 
69
+ class DelayLine(AbstractUniformLine):
70
+ r"""
71
+ Ideal, lossless, and dispersionless transmission line defined by
72
+ a constant time delay. Characteristic impedance is real and constant;
73
+ phase scales linearly with frequency.
74
+
75
+ **Mathematical Formulation**
76
+
77
+ $$Z_c(\omega) = Z_c$$
78
+ $$\gamma L(\omega) = j \cdot \omega \cdot t_d$$
79
+
80
+ Example
81
+ --------
82
+ .. code-block:: python
83
+
84
+ import pmrf as prf
85
+ from pmrf.models import DelayLine
86
+
87
+ # Create an ideal 1 ns delay line with 50-ohm characteristic impedance
88
+ line = DelayLine(
89
+ z0=50.0,
90
+ td=1.0e-9
91
+ )
92
+
93
+ freq = prf.Frequency(start=0.5, stop=1.5, npoints=101, unit='ghz')
94
+ s = line.s(freq)
95
+
96
+ Parameters
97
+ ----------
98
+ z0 : Param, default=50.0
99
+ Characteristic impedance in Ohms.
100
+ td : Param, default=1.0e-9
101
+ Time delay in seconds.
102
+ """
103
+ #: Characteristic impedance
104
+ z0: Param = param(default=50.0, constraint=Positive())
105
+
106
+ #: Time delay
107
+ td: Param = param(default=1.0e-9, constraint=Positive())
108
+
109
+ def zc_and_gammaL(self, frequency: Frequency) -> tuple[jnp.ndarray, jnp.ndarray]:
110
+ zc = self.z0 * jnp.ones(frequency.npoints, dtype=complex)
111
+ gammaL = 1j * frequency.w * self.td
112
+
113
+ return zc, gammaL
114
+
115
+
69
116
  class RLGCLine(AbstractImmittanceLine):
70
117
  r"""
71
118
  Transmission line with specified RLGC parameters.
@@ -203,6 +203,52 @@ class Shunt(Model):
203
203
  return renormalize_s(S_shunt, z0_eval, z0, 'power', 'power')
204
204
 
205
205
 
206
+ class Series(Model):
207
+ r"""Connect a 1-port impedance in series along a 2-port line.
208
+
209
+ **Mathematical Formulation**
210
+
211
+ At a common reference impedance of 50 ohms, the wrapped 1-port's
212
+ reflection coefficient $\Gamma$ gives
213
+
214
+ $$S_{11} = S_{22} = \frac{1 + \Gamma}{3 - \Gamma}, \qquad
215
+ S_{21} = S_{12} = \frac{2(1 - \Gamma)}{3 - \Gamma}.$$
216
+
217
+ The resulting two-port is then renormalized to the requested reference
218
+ impedance. This form also covers ideal shorts and opens without converting
219
+ the wrapped reflection coefficient to an impedance.
220
+
221
+ Parameters
222
+ ----------
223
+ series : Model
224
+ The 1-port model to insert in series.
225
+
226
+ References
227
+ ----------
228
+ D. M. Pozar, *Microwave Engineering*, 4th ed., Wiley, 2012, sec. 4.4.
229
+ """
230
+ #: The 1-port model to insert in series.
231
+ series: Model
232
+
233
+ def __post_init__(self):
234
+ if self.series.nports != 1:
235
+ raise ValueError(
236
+ f"Series requires a 1-port model. Received a {self.series.nports}-port model."
237
+ )
238
+
239
+ def s(self, freq: Frequency, z0: ArrayLike = 50.0) -> jnp.ndarray:
240
+ z0_eval = 50.0
241
+ gamma = self.series.s(freq, z0=z0_eval)[:, 0, 0]
242
+ denom = 3.0 - gamma
243
+ s11 = (1.0 + gamma) / denom
244
+ s21 = 2.0 * (1.0 - gamma) / denom
245
+ s_series = jnp.array([
246
+ [s11, s21],
247
+ [s21, s11],
248
+ ]).transpose(2, 0, 1)
249
+ return renormalize_s(s_series, z0_eval, z0, 'power', 'power')
250
+
251
+
206
252
  class CoupledOnePorts(Model):
207
253
  r"""
208
254
  (experimental) Wraps N 1-port models (e.g. inductors) and couples them via a given K-matrix.
@@ -1,6 +1,43 @@
1
1
  """Public objectives modules and their common entry points."""
2
2
 
3
3
  from importlib import import_module
4
+ from typing import TYPE_CHECKING
5
+
6
+ # Keep static analyzers aware of the public names without loading them at runtime.
7
+ if TYPE_CHECKING:
8
+ from .evaluators import (
9
+ AbstractEvaluator as AbstractEvaluator,
10
+ EvaluatorFn as EvaluatorFn,
11
+ EvaluatorLike as EvaluatorLike,
12
+ Feature as Feature,
13
+ GibbsMarginalLogLikelihood as GibbsMarginalLogLikelihood,
14
+ Goal as Goal,
15
+ MarginalLogLikelihood as MarginalLogLikelihood,
16
+ Negated as Negated,
17
+ TargetLoss as TargetLoss,
18
+ )
19
+ from .losses import (
20
+ AbstractLoss as AbstractLoss,
21
+ HingeLoss as HingeLoss,
22
+ HuberLoss as HuberLoss,
23
+ LogMSELoss as LogMSELoss,
24
+ MSELoss as MSELoss,
25
+ MAPELoss as MAPELoss,
26
+ RMSELoss as RMSELoss,
27
+ )
28
+ from .problems import (
29
+ AbstractProblem as AbstractProblem,
30
+ PriorPenalized as PriorPenalized,
31
+ SummedTerms as SummedTerms,
32
+ problem_terms as problem_terms,
33
+ )
34
+ from .terms import (
35
+ AbstractTerm as AbstractTerm,
36
+ BoundEvaluator as BoundEvaluator,
37
+ TermFn as TermFn,
38
+ TermLike as TermLike,
39
+ as_terms as as_terms,
40
+ )
4
41
 
5
42
  _EXPORTS = {
6
43
  'AbstractEvaluator': 'evaluators',
@@ -1,6 +1,75 @@
1
1
  """Public stats modules and their common entry points."""
2
2
 
3
3
  from importlib import import_module
4
+ from typing import TYPE_CHECKING
5
+
6
+ # Keep static analyzers aware of the public names without loading them at runtime.
7
+ if TYPE_CHECKING:
8
+ from .bijectors import (
9
+ AbstractBijector as AbstractBijector,
10
+ Chain as Chain,
11
+ DiagLinear as DiagLinear,
12
+ Exp as Exp,
13
+ Identity as Identity,
14
+ Inverse as Inverse,
15
+ Leafwise as Leafwise,
16
+ Permute as Permute,
17
+ R2ToComplex as R2ToComplex,
18
+ ScalarAffine as ScalarAffine,
19
+ Shift as Shift,
20
+ Sigmoid as Sigmoid,
21
+ Softplus as Softplus,
22
+ Tanh as Tanh,
23
+ Transpose as Transpose,
24
+ TriangularLinear as TriangularLinear,
25
+ )
26
+ from .covariance_kernels import (
27
+ AbstractCovarianceKernel as AbstractCovarianceKernel,
28
+ AutoCrossKernel as AutoCrossKernel,
29
+ ConstantKernel as ConstantKernel,
30
+ CosineKernel as CosineKernel,
31
+ Matern32Kernel as Matern32Kernel,
32
+ Matern52Kernel as Matern52Kernel,
33
+ PeriodicKernel as PeriodicKernel,
34
+ ProductKernel as ProductKernel,
35
+ RBFKernel as RBFKernel,
36
+ SharedIndependentKernel as SharedIndependentKernel,
37
+ SumKernel as SumKernel,
38
+ WhiteNoiseKernel as WhiteNoiseKernel,
39
+ ZeroKernel as ZeroKernel,
40
+ cross_gram as cross_gram,
41
+ gram as gram,
42
+ )
43
+ from .discrepancy_models import (
44
+ AbstractDiscrepancyModel as AbstractDiscrepancyModel,
45
+ GaussianProcess as GaussianProcess,
46
+ )
47
+ from .distributions import (
48
+ AbstractDistribution as AbstractDistribution,
49
+ CenteredUniform as CenteredUniform,
50
+ Gamma as Gamma,
51
+ Joint as Joint,
52
+ LogNormal as LogNormal,
53
+ Normal as Normal,
54
+ RelativeNormal as RelativeNormal,
55
+ RelativeTruncatedNormal as RelativeTruncatedNormal,
56
+ Transformed as Transformed,
57
+ TruncatedNormal as TruncatedNormal,
58
+ Uniform as Uniform,
59
+ truncate as truncate,
60
+ )
61
+ from .likelihoods import (
62
+ AbstractLikelihood as AbstractLikelihood,
63
+ GaussianLikelihood as GaussianLikelihood,
64
+ )
65
+ from .linearization import (
66
+ Linearization as Linearization,
67
+ posterior_covariance as posterior_covariance,
68
+ )
69
+ from .noise_models import (
70
+ AbstractNoiseModel as AbstractNoiseModel,
71
+ AutoCrossNoise as AutoCrossNoise,
72
+ )
4
73
 
5
74
  _EXPORTS = {
6
75
  'AbstractBijector': 'bijectors',
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "paramrf"
3
- version = "0.37.0"
3
+ version = "0.37.2"
4
4
  description = "Parametric radio frequency modeling"
5
5
  readme = "README.rst"
6
6
  authors = [
@@ -39,6 +39,7 @@ docs = [
39
39
  tests = [
40
40
  "pytest",
41
41
  "pytest-xdist",
42
+ "jedi==0.20.0",
42
43
  "filelock",
43
44
  "ipython",
44
45
  "scikit-rf",
@@ -33,6 +33,7 @@ from pmrf.models.components.lines.base import TransmissionLine
33
33
  from pmrf.models import (
34
34
  CoaxialLine,
35
35
  DatasheetLine,
36
+ DelayLine,
36
37
  FloatingLine,
37
38
  MicrostripLine,
38
39
  PhaseLine,
@@ -55,6 +56,7 @@ def dc_freq():
55
56
 
56
57
  LINES = {
57
58
  "PhaseLine": PhaseLine(z0=50.0, theta=90.0, f0=5e9),
59
+ "DelayLine": DelayLine(z0=50.0, td=1e-9),
58
60
  "RLGCLine": RLGCLine(R=0.1, L=250e-9, G=1e-6, C=100e-12, length=0.1),
59
61
  "RLGCLine (lossless)": RLGCLine(R=0.0, L=250e-9, G=0.0, C=100e-12, length=0.1),
60
62
  "PhysicalLine": PhysicalLine(
@@ -0,0 +1,156 @@
1
+ """Grouped export checks. Run with ``python -m pytest tests/test_grouped_exports.py``.
2
+
3
+ The static checks use the test extra's pinned Jedi 0.20.0. They check source
4
+ analysis, not any particular notebook editor or language server.
5
+ """
6
+
7
+ import ast
8
+ import importlib
9
+ import subprocess
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import jedi
14
+ import pytest
15
+
16
+
17
+ ROOT = Path(__file__).resolve().parents[1]
18
+ PACKAGES = ("objectives", "stats")
19
+
20
+
21
+ def exports(package):
22
+ source = ast.parse((ROOT / "pmrf" / package / "__init__.py").read_text())
23
+ assignment = next(
24
+ node for node in source.body
25
+ if isinstance(node, ast.Assign)
26
+ and any(isinstance(target, ast.Name) and target.id == "_EXPORTS"
27
+ for target in node.targets)
28
+ )
29
+ return ast.literal_eval(assignment.value)
30
+
31
+
32
+ def infer(source):
33
+ line = len(source.splitlines())
34
+ return jedi.Script(source, project=jedi.Project(str(ROOT))).infer(
35
+ line=line, column=len(source.splitlines()[-1])
36
+ )
37
+
38
+
39
+ @pytest.mark.parametrize("package", PACKAGES)
40
+ def test_jedi_resolves_every_declared_export(package):
41
+ unresolved = [
42
+ name for name in exports(package)
43
+ if not infer(f"import pmrf as prf\nprf.{package}.{name}")
44
+ ]
45
+ assert not unresolved
46
+
47
+
48
+ @pytest.mark.parametrize("package,name", [("objectives", "Goal"), ("stats", "Normal")])
49
+ def test_jedi_resolves_direct_and_qualified_imports(package, name):
50
+ for source in (
51
+ f"import pmrf as prf\nprf.{package}.{name}",
52
+ f"import pmrf.{package} as grouped\ngrouped.{name}",
53
+ f"from pmrf import {package}\n{package}.{name}",
54
+ f"from pmrf.{package} import {name}\n{name}",
55
+ ):
56
+ assert infer(source), source
57
+
58
+
59
+ @pytest.mark.parametrize("package,name", [("objectives", "Goal"), ("stats", "Normal")])
60
+ def test_jedi_completes_grouped_names(package, name):
61
+ source = f"import pmrf as prf\nprf.{package}."
62
+ completions = jedi.Script(source, project=jedi.Project(str(ROOT))).complete(
63
+ line=2, column=len(source.splitlines()[-1])
64
+ )
65
+ assert name in {completion.name for completion in completions}
66
+
67
+
68
+ def test_jedi_infers_goal_instance():
69
+ result = infer(
70
+ "import pmrf as prf\n"
71
+ "goal = prf.objectives.Goal('s11_db', '<', -20)\n"
72
+ "goal"
73
+ )
74
+ assert any(item.name == "Goal" and item.type == "instance" for item in result)
75
+
76
+
77
+ @pytest.mark.parametrize("package", PACKAGES)
78
+ def test_runtime_exports_keep_implementation_identity(package):
79
+ grouped = importlib.import_module(f"pmrf.{package}")
80
+ import pmrf as prf
81
+
82
+ assert set(exports(package)).issubset(grouped.__all__)
83
+ for name in set(grouped.__all__) - set(exports(package)):
84
+ implementation = importlib.import_module(f"pmrf.{package}.{name}")
85
+ assert getattr(grouped, name) is implementation
86
+ assert getattr(getattr(prf, package), name) is implementation
87
+
88
+ for name, module in exports(package).items():
89
+ implementation = getattr(importlib.import_module(f"pmrf.{package}.{module}"), name)
90
+ assert getattr(grouped, name) is implementation
91
+ assert getattr(getattr(prf, package), name) is implementation
92
+ assert getattr(importlib.import_module(f"pmrf.{package}"), name) is implementation
93
+ namespace = {}
94
+ exec(f"from pmrf.{package} import {name}", namespace)
95
+ assert namespace[name] is implementation
96
+
97
+ with pytest.raises(AttributeError):
98
+ getattr(grouped, "NotAnExport")
99
+
100
+
101
+ @pytest.mark.parametrize("package", PACKAGES)
102
+ def test_grouped_initializer_keeps_implementations_lazy(package):
103
+ script = f"""
104
+ import sys
105
+ import types
106
+ root = types.ModuleType('pmrf')
107
+ root.__path__ = [{str(ROOT / 'pmrf')!r}]
108
+ sys.modules['pmrf'] = root
109
+ import pmrf.{package}
110
+ loaded = {{name for name in sys.modules if name.startswith('pmrf.{package}.')}}
111
+ assert not loaded, loaded
112
+ """
113
+ subprocess.run([sys.executable, "-P", "-c", script], cwd=ROOT, check=True)
114
+
115
+
116
+ @pytest.mark.parametrize("import_statement", [
117
+ "import pmrf",
118
+ "import pmrf.objectives",
119
+ "import pmrf.stats",
120
+ ])
121
+ def test_fresh_import_does_not_load_every_grouped_implementation(import_statement):
122
+ modules = {
123
+ package: sorted(set(exports(package).values())) for package in PACKAGES
124
+ }
125
+ script = f"""
126
+ import sys
127
+ {import_statement}
128
+ for package, modules in {modules!r}.items():
129
+ assert not all(f'pmrf.{{package}}.{{module}}' in sys.modules for module in modules), package
130
+ """
131
+ subprocess.run([sys.executable, "-P", "-c", script], cwd=ROOT, check=True)
132
+
133
+
134
+ def test_root_lazy_packages_remain_available():
135
+ script = """
136
+ import importlib
137
+ import pmrf
138
+ for name in ('fitting', 'infer', 'optimize', 'viz'):
139
+ assert name in dir(pmrf)
140
+ assert getattr(pmrf, name) is importlib.import_module(f'pmrf.{name}')
141
+ """
142
+ subprocess.run([sys.executable, "-P", "-c", script], cwd=ROOT, check=True)
143
+
144
+
145
+ @pytest.mark.parametrize("package,name,module", [
146
+ ("objectives", "Goal", "evaluators"),
147
+ ("stats", "AutoCrossNoise", "noise_models"),
148
+ ])
149
+ def test_fresh_export_access_loads_defining_module(package, name, module):
150
+ script = f"""
151
+ import sys
152
+ import pmrf as prf
153
+ assert getattr(prf.{package}, '{name}') is not None
154
+ assert 'pmrf.{package}.{module}' in sys.modules
155
+ """
156
+ subprocess.run([sys.executable, "-P", "-c", script], cwd=ROOT, check=True)
@@ -52,13 +52,14 @@ import pmrf.models
52
52
  from pmrf.frequency import Frequency
53
53
  from pmrf.materials import ColeColeDielectric, MultipoleDebyeDielectric, RoughConductor
54
54
  from pmrf.parameters import Param
55
+ from pmrf.parameters.constraints import Interval
55
56
  from pmrf.models import (
56
57
  Model, Circuit, Port,
57
58
  GlobalMNACircuitSolver, GlobalScatteringCircuitSolver,
58
59
  Load, Short, Open, Match, Ground, Transformer, CentreTappedTransformer,
59
60
  Autotransformer, Balun, SourceConverter, MixedModeConverter, Isolator, Splitter,
60
61
  Tee, Attenuator, Amplifier, DirectionalCoupler,
61
- PhaseLine, RLGCLine, PhysicalLine, DatasheetLine, CoaxialLine, MicrostripLine,
62
+ PhaseLine, DelayLine, RLGCLine, PhysicalLine, DatasheetLine, CoaxialLine, MicrostripLine,
62
63
  StriplineLine, FloatingLine,
63
64
  Resistor, Capacitor, Inductor, CoupledInductors, SeriesRL, Impedance, Admittance,
64
65
  ShuntResistor, ShuntCapacitor, ShuntInductor, CapacitorQ, InductorQ,
@@ -91,6 +92,12 @@ EXAMPLES = {
91
92
  Amplifier: lambda: Amplifier(gain=10.0),
92
93
  DirectionalCoupler: lambda: DirectionalCoupler(coupling=10.0),
93
94
  PhaseLine: lambda: PhaseLine(z0=50.0, theta=90.0, f0=0.5e9),
95
+ # Both built-in bounds are open or infinite. A finite fitting limit gives the
96
+ # sweep a closed edge for DelayLine's delay parameter to evaluate.
97
+ DelayLine: lambda: DelayLine(
98
+ z0=50.0,
99
+ td=Param(value=0.25e-9, validity=Interval(0.0, 0.3e-9, closed=(False, True))),
100
+ ),
94
101
  # Not a multiple of a half wavelength on FREQ. There a nearly lossless line's Y has a
95
102
  # pole, and the MNA solver, which stamps lines from `y()`, loses precision: at
96
103
  # length=0.1 (half a wavelength at 1 GHz) with R = 0, MNA and scattering differ by 7e-6.
@@ -3,6 +3,7 @@ import pytest
3
3
  import numpy as np
4
4
  import jax.numpy as jnp
5
5
  import equinox as eqx
6
+ from skrf.media import DefinedGammaZ0
6
7
 
7
8
  from pmrf.frequency import Frequency
8
9
  from pmrf.parameters import Unconstrained
@@ -10,7 +11,8 @@ from pmrf.rf import s2y
10
11
 
11
12
  from pmrf.models import (
12
13
  Model, Cascade, Circuit, FloatingLine, FloatingTwoPort, GroundLifted,
13
- GroundExposed, Shunt, PhaseLine, Port, RLGCLine, Resistor, Short, Open,
14
+ GroundExposed, Shunt, Series, PhaseLine, Port, RLGCLine, Resistor, Short, Open,
15
+ Load,
14
16
  Inductor
15
17
  )
16
18
  from pmrf.models.composite.nodal import CoupledOnePorts, CoupledTwoPorts
@@ -282,6 +284,44 @@ def test_shunt_invalid_port_count():
282
284
  with pytest.raises(ValueError, match="Shunt requires a 1-port model"):
283
285
  Shunt(shunt=res_model)
284
286
 
287
+ # ---------------------------------------------------------
288
+ # Series Tests
289
+ # ---------------------------------------------------------
290
+
291
+ @pytest.mark.parametrize("inner, reflection, transmission", [
292
+ (Short(), 0.0, 1.0),
293
+ (Open(), 1.0, 0.0),
294
+ ])
295
+ def test_series_ideal_limits(inner, reflection, transmission, basic_freq):
296
+ s = Series(series=inner).s(basic_freq)
297
+
298
+ assert s.shape == (basic_freq.npoints, 2, 2)
299
+ assert jnp.all(jnp.isfinite(s))
300
+ np.testing.assert_allclose(s[:, 0, 0], reflection, atol=1e-12)
301
+ np.testing.assert_allclose(s[:, 1, 1], reflection, atol=1e-12)
302
+ np.testing.assert_allclose(s[:, 0, 1], transmission, atol=1e-12)
303
+ np.testing.assert_allclose(s[:, 1, 0], transmission, atol=1e-12)
304
+
305
+
306
+ @pytest.mark.parametrize("resistance", [25.0, 50.0, 200.0])
307
+ @pytest.mark.parametrize("z0", [50.0, 75.0, np.array([45.0, 75.0])])
308
+ def test_series_resistance_matches_skrf(resistance, z0, basic_freq):
309
+ gamma = (resistance - 50.0) / (resistance + 50.0)
310
+ actual = Series(series=Load(gamma=gamma, z0=50.0)).s(basic_freq, z0=z0)
311
+
312
+ # A series element has a singular two-port Z matrix. Construct directly at
313
+ # the target z0: scikit-rf's S -> Z -> S renormalization perturbs that
314
+ # singularity and introduces errors of order 1e-8.
315
+ media = DefinedGammaZ0(basic_freq.to_skrf(), z0=50.0)
316
+ reference = media.resistor(resistance, z0=z0)
317
+
318
+ np.testing.assert_allclose(actual, reference.s, rtol=1e-12, atol=1e-12)
319
+
320
+
321
+ def test_series_invalid_port_count():
322
+ with pytest.raises(ValueError, match="Series requires a 1-port model"):
323
+ Series(series=Resistor(R=50.0))
324
+
285
325
  # ---------------------------------------------------------
286
326
  # CoupledOnePorts Tests
287
327
  # ---------------------------------------------------------
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