paramrf 0.35.0__tar.gz → 0.35.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 (228) hide show
  1. {paramrf-0.35.0 → paramrf-0.35.2}/PKG-INFO +1 -1
  2. {paramrf-0.35.0 → paramrf-0.35.2}/paramrf.egg-info/PKG-INFO +1 -1
  3. {paramrf-0.35.0 → paramrf-0.35.2}/paramrf.egg-info/SOURCES.txt +1 -0
  4. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/circuit.py +53 -9
  5. {paramrf-0.35.0 → paramrf-0.35.2}/pyproject.toml +1 -1
  6. paramrf-0.35.2/tests/test_models/test_circuit_port_order.py +168 -0
  7. {paramrf-0.35.0 → paramrf-0.35.2}/.github/workflows/docs.yml +0 -0
  8. {paramrf-0.35.0 → paramrf-0.35.2}/.github/workflows/draft-pdf.yml +0 -0
  9. {paramrf-0.35.0 → paramrf-0.35.2}/.github/workflows/publish.yml +0 -0
  10. {paramrf-0.35.0 → paramrf-0.35.2}/.github/workflows/tests.yml +0 -0
  11. {paramrf-0.35.0 → paramrf-0.35.2}/.gitignore +0 -0
  12. {paramrf-0.35.0 → paramrf-0.35.2}/AGENTS.md +0 -0
  13. {paramrf-0.35.0 → paramrf-0.35.2}/CHANGELOG.md +0 -0
  14. {paramrf-0.35.0 → paramrf-0.35.2}/CITATION.cff +0 -0
  15. {paramrf-0.35.0 → paramrf-0.35.2}/CLAUDE.md +0 -0
  16. {paramrf-0.35.0 → paramrf-0.35.2}/CONTEXT.md +0 -0
  17. {paramrf-0.35.0 → paramrf-0.35.2}/CONTRIBUTING.md +0 -0
  18. {paramrf-0.35.0 → paramrf-0.35.2}/LICENSE +0 -0
  19. {paramrf-0.35.0 → paramrf-0.35.2}/NOTICE +0 -0
  20. {paramrf-0.35.0 → paramrf-0.35.2}/README.rst +0 -0
  21. {paramrf-0.35.0 → paramrf-0.35.2}/assets/logo.png +0 -0
  22. {paramrf-0.35.0 → paramrf-0.35.2}/docs/Makefile +0 -0
  23. {paramrf-0.35.0 → paramrf-0.35.2}/docs/_static/custom.css +0 -0
  24. {paramrf-0.35.0 → paramrf-0.35.2}/docs/_templates/autosummary/class.rst +0 -0
  25. {paramrf-0.35.0 → paramrf-0.35.2}/docs/_templates/autosummary/function.rst +0 -0
  26. {paramrf-0.35.0 → paramrf-0.35.2}/docs/_templates/autosummary/module.rst +0 -0
  27. {paramrf-0.35.0 → paramrf-0.35.2}/docs/adr/0001-line-modelling-architecture.md +0 -0
  28. {paramrf-0.35.0 → paramrf-0.35.2}/docs/adr/0002-parameter-api.md +0 -0
  29. {paramrf-0.35.0 → paramrf-0.35.2}/docs/agents/domain.md +0 -0
  30. {paramrf-0.35.0 → paramrf-0.35.2}/docs/agents/issue-tracker.md +0 -0
  31. {paramrf-0.35.0 → paramrf-0.35.2}/docs/agents/triage-labels.md +0 -0
  32. {paramrf-0.35.0 → paramrf-0.35.2}/docs/api/index.rst +0 -0
  33. {paramrf-0.35.0 → paramrf-0.35.2}/docs/conf.py +0 -0
  34. {paramrf-0.35.0 → paramrf-0.35.2}/docs/core_concepts/core_primitives.rst +0 -0
  35. {paramrf-0.35.0 → paramrf-0.35.2}/docs/core_concepts/index.rst +0 -0
  36. {paramrf-0.35.0 → paramrf-0.35.2}/docs/core_concepts/jax_overview.rst +0 -0
  37. {paramrf-0.35.0 → paramrf-0.35.2}/docs/core_concepts/optimization_and_inference.rst +0 -0
  38. {paramrf-0.35.0 → paramrf-0.35.2}/docs/core_concepts/parameter_names.rst +0 -0
  39. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/cascading_and_terminating.rst +0 -0
  40. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/circuit_clc.png +0 -0
  41. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/circuit_models.rst +0 -0
  42. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/custom_models.rst +0 -0
  43. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/derivatives_and_sweeps.rst +0 -0
  44. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/index.rst +0 -0
  45. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/model_optimization.rst +0 -0
  46. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/multiple_models_one_parameter_set.rst +0 -0
  47. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/parameter_naming_and_model_manipulation.rst +0 -0
  48. {paramrf-0.35.0 → paramrf-0.35.2}/docs/examples/shared_substrates.rst +0 -0
  49. {paramrf-0.35.0 → paramrf-0.35.2}/docs/index.rst +0 -0
  50. {paramrf-0.35.0 → paramrf-0.35.2}/docs/license.rst +0 -0
  51. {paramrf-0.35.0 → paramrf-0.35.2}/docs/make.bat +0 -0
  52. {paramrf-0.35.0 → paramrf-0.35.2}/docs/research/conductor-loss-alternatives.md +0 -0
  53. {paramrf-0.35.0 → paramrf-0.35.2}/docs/research/holloway1994.pdf +0 -0
  54. {paramrf-0.35.0 → paramrf-0.35.2}/docs/research/microstrip-loss-conventions.md +0 -0
  55. {paramrf-0.35.0 → paramrf-0.35.2}/docs/research/precision-coax-microstrip-10-500mhz.md +0 -0
  56. {paramrf-0.35.0 → paramrf-0.35.2}/docs/skrf_comparison/index.rst +0 -0
  57. {paramrf-0.35.0 → paramrf-0.35.2}/docs/skrf_comparison/overview.rst +0 -0
  58. {paramrf-0.35.0 → paramrf-0.35.2}/docs/skrf_comparison/performance.rst +0 -0
  59. {paramrf-0.35.0 → paramrf-0.35.2}/docs/tutorials/1_cable_fitting.ipynb +0 -0
  60. {paramrf-0.35.0 → paramrf-0.35.2}/docs/tutorials/2_chip_inductor_fitting.ipynb +0 -0
  61. {paramrf-0.35.0 → paramrf-0.35.2}/docs/tutorials/data/CBN-1.5FT-SMSM.s2p +0 -0
  62. {paramrf-0.35.0 → paramrf-0.35.2}/docs/tutorials/data/on-chip-inductor.s2p +0 -0
  63. {paramrf-0.35.0 → paramrf-0.35.2}/docs/tutorials/index.rst +0 -0
  64. {paramrf-0.35.0 → paramrf-0.35.2}/paper/paper.bib +0 -0
  65. {paramrf-0.35.0 → paramrf-0.35.2}/paper/paper.md +0 -0
  66. {paramrf-0.35.0 → paramrf-0.35.2}/paper/rlc.png +0 -0
  67. {paramrf-0.35.0 → paramrf-0.35.2}/paramrf.egg-info/dependency_links.txt +0 -0
  68. {paramrf-0.35.0 → paramrf-0.35.2}/paramrf.egg-info/requires.txt +0 -0
  69. {paramrf-0.35.0 → paramrf-0.35.2}/paramrf.egg-info/top_level.txt +0 -0
  70. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/__init__.py +0 -0
  71. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/_solver_view.py +0 -0
  72. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/bijectors.py +0 -0
  73. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/constraints.py +0 -0
  74. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/covariance_kernels.py +0 -0
  75. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/discrepancy_models.py +0 -0
  76. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/distributions.py +0 -0
  77. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/evaluators.py +0 -0
  78. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/__init__.py +0 -0
  79. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/minimize.py +0 -0
  80. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/result.py +0 -0
  81. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/routers.py +0 -0
  82. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/sample.py +0 -0
  83. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/fitting/targets.py +0 -0
  84. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/frequency.py +0 -0
  85. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/__init__.py +0 -0
  86. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/base.py +0 -0
  87. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/result.py +0 -0
  88. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/sample.py +0 -0
  89. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/solvers/__init__.py +0 -0
  90. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/solvers/blackjax.py +0 -0
  91. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/infer/solvers/polychord.py +0 -0
  92. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/likelihoods.py +0 -0
  93. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/losses.py +0 -0
  94. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/__init__.py +0 -0
  95. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/conductor.py +0 -0
  96. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/dielectric.py +0 -0
  97. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/properties.py +0 -0
  98. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/roughness.py +0 -0
  99. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/substrate.py +0 -0
  100. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/materials/surface_impedance.py +0 -0
  101. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/__init__.py +0 -0
  102. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/aggregations.py +0 -0
  103. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/bessel.py +0 -0
  104. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/conversions.py +0 -0
  105. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/losses.py +0 -0
  106. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/math/misc.py +0 -0
  107. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/__init__.py +0 -0
  108. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/__init__.py +0 -0
  109. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/base.py +0 -0
  110. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/bridge.py +0 -0
  111. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/callable.py +0 -0
  112. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/delegated.py +0 -0
  113. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/static.py +0 -0
  114. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/adapters/wrapped.py +0 -0
  115. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/base.py +0 -0
  116. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/__init__.py +0 -0
  117. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/ideal.py +0 -0
  118. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/__init__.py +0 -0
  119. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/base.py +0 -0
  120. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/coaxial.py +0 -0
  121. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/empirical.py +0 -0
  122. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/ideal.py +0 -0
  123. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/microstrip.py +0 -0
  124. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/nodal.py +0 -0
  125. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/nonuniform.py +0 -0
  126. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/planar.py +0 -0
  127. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lines/stripline.py +0 -0
  128. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/lumped.py +0 -0
  129. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/components/sections.py +0 -0
  130. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/__init__.py +0 -0
  131. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/__init__.py +0 -0
  132. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/cascade.py +0 -0
  133. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/__init__.py +0 -0
  134. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/base.py +0 -0
  135. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/solvers/__init__.py +0 -0
  136. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/solvers/nodal.py +0 -0
  137. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/circuit/solvers/scattering.py +0 -0
  138. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/interconnected/terminated.py +0 -0
  139. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/nodal.py +0 -0
  140. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/topological.py +0 -0
  141. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/composite/transformed.py +0 -0
  142. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/surrogates/__init__.py +0 -0
  143. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/surrogates/expansion.py +0 -0
  144. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/models/surrogates/rational.py +0 -0
  145. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/modules/__init__.py +0 -0
  146. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/modules/base.py +0 -0
  147. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/modules/wrapped.py +0 -0
  148. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/network_collection.py +0 -0
  149. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/noise_models.py +0 -0
  150. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/__init__.py +0 -0
  151. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/base.py +0 -0
  152. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/minimize.py +0 -0
  153. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/result.py +0 -0
  154. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/solvers/__init__.py +0 -0
  155. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/solvers/jaxopt.py +0 -0
  156. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/solvers/optimistix.py +0 -0
  157. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/optimize/solvers/scipy.py +0 -0
  158. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/parameters.py +0 -0
  159. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/problems.py +0 -0
  160. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/rf/__init__.py +0 -0
  161. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/rf/conversions.py +0 -0
  162. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/rf/mna.py +0 -0
  163. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/serialization.py +0 -0
  164. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/terms.py +0 -0
  165. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/types.py +0 -0
  166. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/__init__.py +0 -0
  167. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/array.py +0 -0
  168. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/debug.py +0 -0
  169. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/network.py +0 -0
  170. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/random.py +0 -0
  171. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/rf.py +0 -0
  172. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/transforms.py +0 -0
  173. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/tree.py +0 -0
  174. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/utils/type.py +0 -0
  175. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/viz/__init__.py +0 -0
  176. {paramrf-0.35.0 → paramrf-0.35.2}/pmrf/viz/plots.py +0 -0
  177. {paramrf-0.35.0 → paramrf-0.35.2}/scripts/install-test-deps.sh +0 -0
  178. {paramrf-0.35.0 → paramrf-0.35.2}/setup.cfg +0 -0
  179. {paramrf-0.35.0 → paramrf-0.35.2}/tests/__init__.py +0 -0
  180. {paramrf-0.35.0 → paramrf-0.35.2}/tests/_dependency_checks.py +0 -0
  181. {paramrf-0.35.0 → paramrf-0.35.2}/tests/_jit.py +0 -0
  182. {paramrf-0.35.0 → paramrf-0.35.2}/tests/conftest.py +0 -0
  183. {paramrf-0.35.0 → paramrf-0.35.2}/tests/data/10m_cable.s2p +0 -0
  184. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_autodiff.py +0 -0
  185. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_conversions.py +0 -0
  186. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_covariance_kernels.py +0 -0
  187. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_dc_limits.py +0 -0
  188. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_evaluators.py +0 -0
  189. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_fitting_minimize.py +0 -0
  190. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_fitting_routers.py +0 -0
  191. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_fitting_sample.py +0 -0
  192. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_fitting_targets.py +0 -0
  193. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_frequency.py +0 -0
  194. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_infer_base.py +0 -0
  195. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_infer_sample.py +0 -0
  196. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_map_priors.py +0 -0
  197. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_materials/test_conductor.py +0 -0
  198. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_materials/test_dielectric.py +0 -0
  199. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_materials/test_serialization.py +0 -0
  200. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_materials/test_substrate.py +0 -0
  201. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_materials/test_surface_impedance.py +0 -0
  202. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_math/test_bessel.py +0 -0
  203. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_model.py +0 -0
  204. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_adapters.py +0 -0
  205. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_circuit_nodal.py +0 -0
  206. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_circuit_scattering.py +0 -0
  207. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_current_distribution.py +0 -0
  208. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_interconnected.py +0 -0
  209. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_lines.py +0 -0
  210. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_lines_skrf_matrix.py +0 -0
  211. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_lumped.py +0 -0
  212. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_nodal.py +0 -0
  213. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_sections.py +0 -0
  214. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_transformed.py +0 -0
  215. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_models/test_transformers.py +0 -0
  216. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_module.py +0 -0
  217. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_naming.py +0 -0
  218. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_optimize_base.py +0 -0
  219. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_optimize_minimize.py +0 -0
  220. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_parameters.py +0 -0
  221. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_parameters_by_name.py +0 -0
  222. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_raw_space_solving.py +0 -0
  223. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_serialization.py +0 -0
  224. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_structural_updates.py +0 -0
  225. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_terms.py +0 -0
  226. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_transforms.py +0 -0
  227. {paramrf-0.35.0 → paramrf-0.35.2}/tests/test_utils/test_compress.py +0 -0
  228. {paramrf-0.35.0 → paramrf-0.35.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.35.0
3
+ Version: 0.35.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paramrf
3
- Version: 0.35.0
3
+ Version: 0.35.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
@@ -211,6 +211,7 @@ tests/test_materials/test_surface_impedance.py
211
211
  tests/test_math/test_bessel.py
212
212
  tests/test_models/test_adapters.py
213
213
  tests/test_models/test_circuit_nodal.py
214
+ tests/test_models/test_circuit_port_order.py
214
215
  tests/test_models/test_circuit_scattering.py
215
216
  tests/test_models/test_current_distribution.py
216
217
  tests/test_models/test_interconnected.py
@@ -48,18 +48,26 @@ class Circuit(Model):
48
48
  of nodes. Each node connects one or more ports of the constituent models
49
49
  to form a composite network.
50
50
 
51
+ The external ports follow `Port` declaration order: scanning `connections`
52
+ node by node, left to right, the first `Port` found is port 0. This holds for
53
+ every solver, nested or flattened.
54
+
51
55
  Parameters
52
56
  ----------
53
57
  connections : list[list[tuple[Model, int]]]
54
58
  A list representing the nodes of the circuit. Each node is a list of
55
59
  tuples, where each tuple contains a model and the integer
56
60
  index of the port to connect to that node.
57
- flatten: bool, default=True
61
+ flatten: bool, default=False
58
62
  Flattens sub-circuits and sub-cascades to perform a single solve.
59
- Defaults to True.
60
- solver : AbstractCircuitSolver, default=GlobalScatteringCircuitSolver()
63
+ solver : AbstractCircuitSolver, default=GlobalMNACircuitSolver()
61
64
  The circuit solver to use. Available solvers can be found in :mod:`pmrf.models`.
62
65
 
66
+ Raises
67
+ ------
68
+ ValueError
69
+ If two `Port`\\ s share a net, or a `Port` shares a net with a `Ground`.
70
+
63
71
  Examples
64
72
  --------
65
73
  Create a two-port PI-CLC network. External nodes are defined using `Port`,
@@ -75,8 +83,8 @@ class Circuit(Model):
75
83
  >>>
76
84
  >>> # Create the connections list
77
85
  >>> connections = [
78
- ... [(p0, 0), (C1, 1), (L, 1)], # Node 0 -> Port 1
79
- ... [(p1, 0), (C2, 1), (L, 0)], # Node 1 -> Port 2
86
+ ... [(p0, 0), (C1, 1), (L, 1)], # Node 0 -> Port 0
87
+ ... [(p1, 0), (C2, 1), (L, 0)], # Node 1 -> Port 1
80
88
  ... [(ground, 0), (C1, 0), (C2, 0)], # Node 2 -> Ground
81
89
  ... ]
82
90
  >>>
@@ -149,6 +157,34 @@ class Circuit(Model):
149
157
 
150
158
  self.circuit = models
151
159
  self.indexed_connections = indexed_connections
160
+ self._validate_port_nets()
161
+
162
+ def _validate_port_nets(self):
163
+ """Ensures every `Port` has a net to itself that is not grounded."""
164
+ global_net_map = compute_unique_nets(self.circuit, self.indexed_connections)
165
+
166
+ net_to_port = {}
167
+ ground_nets = set()
168
+ offset = 0
169
+ port_idx = 0
170
+ for model in self.circuit:
171
+ if isinstance(model, Ground):
172
+ ground_nets.update(global_net_map[offset : offset + model.nports].tolist())
173
+ elif isinstance(model, Port):
174
+ net = int(global_net_map[offset])
175
+ label = f"Port {port_idx} ('{getattr(model, 'name', None) or 'unnamed'}')"
176
+ if net in net_to_port:
177
+ raise ValueError(
178
+ f"{net_to_port[net]} and {label} are connected to the same net. "
179
+ "Each Port must be on its own net."
180
+ )
181
+ net_to_port[net] = label
182
+ port_idx += 1
183
+ offset += model.nports
184
+
185
+ for net, label in net_to_port.items():
186
+ if net in ground_nets:
187
+ raise ValueError(f"{label} is connected to a Ground net. A Port cannot be grounded.")
152
188
 
153
189
  def expand(self):
154
190
  internal_ports = [comp for comp in self.circuit if isinstance(comp, Port)]
@@ -209,14 +245,14 @@ class Circuit(Model):
209
245
  global_net_map = compute_unique_nets(self.circuit, self.indexed_connections)
210
246
 
211
247
  ground_nets = set()
212
- ext_nets = set()
248
+ ext_nets = [] # In `Port` declaration order, which fixes the external port order
213
249
  offset = 0
214
250
  for model in self.circuit:
215
251
  nets = global_net_map[offset : offset + model.nports]
216
252
  if isinstance(model, Ground):
217
253
  ground_nets.update(nets)
218
254
  elif isinstance(model, Port):
219
- ext_nets.update(nets)
255
+ ext_nets.extend(nets)
220
256
  offset += model.nports
221
257
 
222
258
  unique_all_nets = np.unique(global_net_map)
@@ -243,7 +279,7 @@ class Circuit(Model):
243
279
  r_idx_mapped = mapping[_safe_cat(r_idx)]
244
280
  c_idx_mapped = mapping[_safe_cat(c_idx)]
245
281
 
246
- ext_active = np.array([n for n in ext_nets if n not in ground_nets], dtype=int)
282
+ ext_active = np.array(ext_nets, dtype=int)
247
283
  int_active = np.setdiff1d(active_nets, ext_active)
248
284
 
249
285
  return NodalRepresentation(
@@ -723,6 +759,14 @@ def flatten_hierarchy(connections: list[list[tuple[Model, int]]]) -> list[list[t
723
759
  group.sort(key=lambda x: (model_discovery_order[id(x[0])], x[1]))
724
760
  valid_groups.append(group)
725
761
 
726
- valid_groups.sort(key=lambda g: (model_discovery_order[id(g[0][0])], g[0][1]))
762
+ # Nets holding a top-level `Port` come first, in `Port` declaration order, since
763
+ # the flat circuit's external port order is the order its `Port`s first appear.
764
+ def group_order(group):
765
+ port_orders = [model_discovery_order[id(m)] for m, _ in group if isinstance(m, Port)]
766
+ if port_orders:
767
+ return (0, min(port_orders), 0)
768
+ return (1, model_discovery_order[id(group[0][0])], group[0][1])
769
+
770
+ valid_groups.sort(key=group_order)
727
771
 
728
772
  return valid_groups
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "paramrf"
3
- version = "0.35.0"
3
+ version = "0.35.2"
4
4
  description = "Parametric radio frequency modeling"
5
5
  readme = "README.rst"
6
6
  authors = [
@@ -0,0 +1,168 @@
1
+ # tests/test_models/test_circuit_port_order.py
2
+ """
3
+ A `Circuit` orders its external ports by `Port` declaration: the first `Port` found
4
+ scanning `connections` node by node, left to right, is port 0. This must hold for
5
+ every solver and must not depend on how internal components are wired.
6
+ """
7
+ import pytest
8
+ import numpy as np
9
+
10
+ from pmrf.frequency import Frequency
11
+ from pmrf.models import (
12
+ Circuit, Port, Ground, Resistor, Capacitor, Inductor,
13
+ GlobalScatteringCircuitSolver,
14
+ HierarchicalScatteringCircuitSolver,
15
+ SequentialScatteringCircuitSolver,
16
+ GlobalNodalCircuitSolver,
17
+ GlobalMNACircuitSolver,
18
+ )
19
+
20
+ SOLVERS = [
21
+ GlobalScatteringCircuitSolver,
22
+ HierarchicalScatteringCircuitSolver,
23
+ SequentialScatteringCircuitSolver,
24
+ GlobalNodalCircuitSolver,
25
+ GlobalMNACircuitSolver,
26
+ ]
27
+
28
+ Z0 = 50.0
29
+
30
+
31
+ @pytest.fixture
32
+ def freq():
33
+ return Frequency(start=1.0, stop=10.0, npoints=3, unit='GHz')
34
+
35
+
36
+ def _y_to_s(Y, z0=Z0):
37
+ """Independent reference: S = (I - z0 Y)(I + z0 Y)^-1 for a real, uniform z0."""
38
+ eye = np.eye(Y.shape[0])
39
+ return (eye - z0 * Y) @ np.linalg.inv(eye + z0 * Y)
40
+
41
+
42
+ # Asymmetric two-port: node A has a 10 Ω shunt, node B a 1000 Ω shunt, with a 5 Ω
43
+ # series resistor between them. Nodal Y written down by hand, ordered (A, B).
44
+ R_A, R_B, R_SERIES = 10.0, 1000.0, 5.0
45
+ Y_AB = np.array([
46
+ [1 / R_A + 1 / R_SERIES, -1 / R_SERIES],
47
+ [-1 / R_SERIES, 1 / R_B + 1 / R_SERIES],
48
+ ])
49
+ S_AB = _y_to_s(Y_AB)
50
+
51
+
52
+ def _asymmetric_two_port(solver, a_first: bool, series_flipped: bool, **kwargs):
53
+ shunt_a, shunt_b, series = Resistor(R=R_A), Resistor(R=R_B), Resistor(R=R_SERIES)
54
+ port_a, port_b, ground = Port(), Port(), Ground()
55
+
56
+ series_a, series_b = ((series, 1), (series, 0)) if series_flipped else ((series, 0), (series, 1))
57
+ node_a = [(port_a, 0), (shunt_a, 0), series_a]
58
+ node_b = [(port_b, 0), (shunt_b, 0), series_b]
59
+ nodes = [node_a, node_b] if a_first else [node_b, node_a]
60
+
61
+ return Circuit(
62
+ nodes + [[(ground, 0), (shunt_a, 1), (shunt_b, 1)]],
63
+ solver=solver,
64
+ **kwargs,
65
+ )
66
+
67
+
68
+ def test_asymmetric_two_port_reference_values():
69
+ # Values quoted in issue #165, as a guard on the hand-written reference.
70
+ assert np.isclose(S_AB[0, 0], -0.7122, atol=1e-4)
71
+ assert np.isclose(S_AB[1, 1], -0.5833, atol=1e-4)
72
+
73
+
74
+ @pytest.mark.parametrize("series_flipped", [False, True])
75
+ @pytest.mark.parametrize("a_first", [True, False])
76
+ @pytest.mark.parametrize("solver_cls", SOLVERS)
77
+ def test_ports_follow_declaration_order(solver_cls, a_first, series_flipped, freq):
78
+ circuit = _asymmetric_two_port(solver_cls(), a_first, series_flipped)
79
+ expected = S_AB if a_first else S_AB[::-1, ::-1]
80
+
81
+ s = circuit.s(freq, z0=Z0)
82
+
83
+ np.testing.assert_allclose(s, np.broadcast_to(expected, s.shape), atol=1e-8)
84
+
85
+
86
+ def _kron_reduce(Y, keep):
87
+ """Independent reference: eliminate every node not in `keep` by Schur complement."""
88
+ keep = np.asarray(keep)
89
+ drop = np.setdiff1d(np.arange(Y.shape[0]), keep)
90
+ return Y[np.ix_(keep, keep)] - Y[np.ix_(keep, drop)] @ np.linalg.solve(
91
+ Y[np.ix_(drop, drop)], Y[np.ix_(drop, keep)]
92
+ )
93
+
94
+
95
+ @pytest.mark.parametrize("flatten", [False, True])
96
+ @pytest.mark.parametrize("solver_cls", SOLVERS)
97
+ def test_nested_circuit_ports_follow_declaration_order(solver_cls, flatten, freq):
98
+ # The inner circuit has its series element's port indices swapped.
99
+ inner = _asymmetric_two_port(solver_cls(), a_first=True, series_flipped=True)
100
+
101
+ # The outer circuit adds a 3 Ω series resistor on A and a 2 Ω one on B. The
102
+ # resistor on B is declared first, so it is discovered before either `Port`,
103
+ # but port A is still the first `Port` declared.
104
+ r_ta, r_tb = 3.0, 2.0
105
+ t_a, t_b = Resistor(R=r_ta), Resistor(R=r_tb)
106
+ port_a, port_b = Port(), Port()
107
+ outer = Circuit([
108
+ [(t_b, 0), (inner, 1)],
109
+ [(t_a, 0), (inner, 0)],
110
+ [(port_a, 0), (t_a, 1)],
111
+ [(port_b, 0), (t_b, 1)],
112
+ ], solver=solver_cls(), flatten=flatten)
113
+
114
+ # Nodes (A, B, port A, port B), by hand.
115
+ Y = np.zeros((4, 4))
116
+ Y[:2, :2] = Y_AB
117
+ for i, j, R in [(0, 2, r_ta), (1, 3, r_tb)]:
118
+ Y[np.ix_([i, j], [i, j])] += np.array([[1, -1], [-1, 1]]) / R
119
+ expected = _y_to_s(_kron_reduce(Y, keep=[2, 3]))
120
+
121
+ s = outer.s(freq, z0=Z0)
122
+
123
+ np.testing.assert_allclose(s, np.broadcast_to(expected, s.shape), atol=1e-8)
124
+
125
+
126
+ def test_ports_sharing_a_net_raise():
127
+ shunt, ground = Resistor(R=R_A), Ground()
128
+ port_a, port_b = Port(name="port_a"), Port(name="port_b")
129
+
130
+ with pytest.raises(ValueError, match="port_a.*port_b"):
131
+ Circuit([
132
+ [(port_a, 0), (port_b, 0), (shunt, 0)],
133
+ [(ground, 0), (shunt, 1)],
134
+ ])
135
+
136
+
137
+ def test_port_sharing_a_net_with_ground_raises():
138
+ shunt, ground = Resistor(R=R_A), Ground()
139
+ port_a, port_b = Port(name="port_a"), Port(name="port_b")
140
+
141
+ with pytest.raises(ValueError, match="port_b.*Ground"):
142
+ Circuit([
143
+ [(port_a, 0), (shunt, 0)],
144
+ [(ground, 0), (shunt, 1), (port_b, 0)],
145
+ ])
146
+
147
+
148
+ @pytest.mark.parametrize("solver_cls", SOLVERS)
149
+ def test_pi_clc_docstring_example_matches_skrf(solver_cls, freq):
150
+ skrf = pytest.importorskip("skrf")
151
+
152
+ # Exactly the `Circuit` docstring example: `(L, 1)` on the first node.
153
+ C1, C2 = Capacitor(C=2e-12), Capacitor(C=1.5e-12)
154
+ L = Inductor(L=3e-9)
155
+ p0, p1, ground = Port(), Port(), Ground()
156
+ pi_clc = Circuit([
157
+ [(p0, 0), (C1, 1), (L, 1)],
158
+ [(p1, 0), (C2, 1), (L, 0)],
159
+ [(ground, 0), (C1, 0), (C2, 0)],
160
+ ], solver=solver_cls())
161
+
162
+ # Port 1 is the C1 side.
163
+ media = skrf.media.DefinedGammaZ0(frequency=freq.to_skrf(), z0_port=Z0)
164
+ expected = (
165
+ media.shunt_capacitor(2e-12) ** media.inductor(3e-9) ** media.shunt_capacitor(1.5e-12)
166
+ ).s
167
+
168
+ np.testing.assert_allclose(pi_clc.s(freq, z0=Z0), expected, atol=1e-8)
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