tnfr 3.0.3__py3-none-any.whl → 8.5.0__py3-none-any.whl

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.

Potentially problematic release.


This version of tnfr might be problematic. Click here for more details.

Files changed (360) hide show
  1. tnfr/__init__.py +375 -56
  2. tnfr/__init__.pyi +33 -0
  3. tnfr/_compat.py +10 -0
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +49 -0
  6. tnfr/_version.pyi +7 -0
  7. tnfr/alias.py +723 -0
  8. tnfr/alias.pyi +108 -0
  9. tnfr/backends/__init__.py +354 -0
  10. tnfr/backends/jax_backend.py +173 -0
  11. tnfr/backends/numpy_backend.py +238 -0
  12. tnfr/backends/optimized_numpy.py +420 -0
  13. tnfr/backends/torch_backend.py +408 -0
  14. tnfr/cache.py +171 -0
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +110 -0
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +489 -0
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +914 -0
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +51 -0
  24. tnfr/cli/utils.pyi +7 -0
  25. tnfr/cli/validate.py +236 -0
  26. tnfr/compat/__init__.py +85 -0
  27. tnfr/compat/dataclass.py +136 -0
  28. tnfr/compat/jsonschema_stub.py +61 -0
  29. tnfr/compat/matplotlib_stub.py +73 -0
  30. tnfr/compat/numpy_stub.py +155 -0
  31. tnfr/config/__init__.py +224 -0
  32. tnfr/config/__init__.pyi +10 -0
  33. tnfr/config/constants.py +104 -0
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/config/defaults_core.py +212 -0
  37. tnfr/config/defaults_init.py +33 -0
  38. tnfr/config/defaults_metric.py +104 -0
  39. tnfr/config/feature_flags.py +81 -0
  40. tnfr/config/feature_flags.pyi +16 -0
  41. tnfr/config/glyph_constants.py +31 -0
  42. tnfr/config/init.py +77 -0
  43. tnfr/config/init.pyi +8 -0
  44. tnfr/config/operator_names.py +254 -0
  45. tnfr/config/operator_names.pyi +36 -0
  46. tnfr/config/physics_derivation.py +354 -0
  47. tnfr/config/presets.py +83 -0
  48. tnfr/config/presets.pyi +7 -0
  49. tnfr/config/security.py +927 -0
  50. tnfr/config/thresholds.py +114 -0
  51. tnfr/config/tnfr_config.py +498 -0
  52. tnfr/constants/__init__.py +92 -0
  53. tnfr/constants/__init__.pyi +92 -0
  54. tnfr/constants/aliases.py +33 -0
  55. tnfr/constants/aliases.pyi +27 -0
  56. tnfr/constants/init.py +33 -0
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +104 -0
  59. tnfr/constants/metric.pyi +19 -0
  60. tnfr/core/__init__.py +33 -0
  61. tnfr/core/container.py +226 -0
  62. tnfr/core/default_implementations.py +329 -0
  63. tnfr/core/interfaces.py +279 -0
  64. tnfr/dynamics/__init__.py +238 -0
  65. tnfr/dynamics/__init__.pyi +83 -0
  66. tnfr/dynamics/adaptation.py +267 -0
  67. tnfr/dynamics/adaptation.pyi +7 -0
  68. tnfr/dynamics/adaptive_sequences.py +189 -0
  69. tnfr/dynamics/adaptive_sequences.pyi +14 -0
  70. tnfr/dynamics/aliases.py +23 -0
  71. tnfr/dynamics/aliases.pyi +19 -0
  72. tnfr/dynamics/bifurcation.py +232 -0
  73. tnfr/dynamics/canonical.py +229 -0
  74. tnfr/dynamics/canonical.pyi +48 -0
  75. tnfr/dynamics/coordination.py +385 -0
  76. tnfr/dynamics/coordination.pyi +25 -0
  77. tnfr/dynamics/dnfr.py +3034 -0
  78. tnfr/dynamics/dnfr.pyi +26 -0
  79. tnfr/dynamics/dynamic_limits.py +225 -0
  80. tnfr/dynamics/feedback.py +252 -0
  81. tnfr/dynamics/feedback.pyi +24 -0
  82. tnfr/dynamics/fused_dnfr.py +454 -0
  83. tnfr/dynamics/homeostasis.py +157 -0
  84. tnfr/dynamics/homeostasis.pyi +14 -0
  85. tnfr/dynamics/integrators.py +661 -0
  86. tnfr/dynamics/integrators.pyi +36 -0
  87. tnfr/dynamics/learning.py +310 -0
  88. tnfr/dynamics/learning.pyi +33 -0
  89. tnfr/dynamics/metabolism.py +254 -0
  90. tnfr/dynamics/nbody.py +796 -0
  91. tnfr/dynamics/nbody_tnfr.py +783 -0
  92. tnfr/dynamics/propagation.py +326 -0
  93. tnfr/dynamics/runtime.py +908 -0
  94. tnfr/dynamics/runtime.pyi +77 -0
  95. tnfr/dynamics/sampling.py +36 -0
  96. tnfr/dynamics/sampling.pyi +7 -0
  97. tnfr/dynamics/selectors.py +711 -0
  98. tnfr/dynamics/selectors.pyi +85 -0
  99. tnfr/dynamics/structural_clip.py +207 -0
  100. tnfr/errors/__init__.py +37 -0
  101. tnfr/errors/contextual.py +492 -0
  102. tnfr/execution.py +223 -0
  103. tnfr/execution.pyi +45 -0
  104. tnfr/extensions/__init__.py +205 -0
  105. tnfr/extensions/__init__.pyi +18 -0
  106. tnfr/extensions/base.py +173 -0
  107. tnfr/extensions/base.pyi +35 -0
  108. tnfr/extensions/business/__init__.py +71 -0
  109. tnfr/extensions/business/__init__.pyi +11 -0
  110. tnfr/extensions/business/cookbook.py +88 -0
  111. tnfr/extensions/business/cookbook.pyi +8 -0
  112. tnfr/extensions/business/health_analyzers.py +202 -0
  113. tnfr/extensions/business/health_analyzers.pyi +9 -0
  114. tnfr/extensions/business/patterns.py +183 -0
  115. tnfr/extensions/business/patterns.pyi +8 -0
  116. tnfr/extensions/medical/__init__.py +73 -0
  117. tnfr/extensions/medical/__init__.pyi +11 -0
  118. tnfr/extensions/medical/cookbook.py +88 -0
  119. tnfr/extensions/medical/cookbook.pyi +8 -0
  120. tnfr/extensions/medical/health_analyzers.py +181 -0
  121. tnfr/extensions/medical/health_analyzers.pyi +9 -0
  122. tnfr/extensions/medical/patterns.py +163 -0
  123. tnfr/extensions/medical/patterns.pyi +8 -0
  124. tnfr/flatten.py +262 -0
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +354 -0
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +377 -0
  129. tnfr/glyph_history.pyi +35 -0
  130. tnfr/glyph_runtime.py +19 -0
  131. tnfr/glyph_runtime.pyi +8 -0
  132. tnfr/immutable.py +218 -0
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +203 -0
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +10 -0
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.py +37 -0
  139. tnfr/locking.pyi +7 -0
  140. tnfr/mathematics/__init__.py +79 -0
  141. tnfr/mathematics/backend.py +453 -0
  142. tnfr/mathematics/backend.pyi +99 -0
  143. tnfr/mathematics/dynamics.py +408 -0
  144. tnfr/mathematics/dynamics.pyi +90 -0
  145. tnfr/mathematics/epi.py +391 -0
  146. tnfr/mathematics/epi.pyi +65 -0
  147. tnfr/mathematics/generators.py +242 -0
  148. tnfr/mathematics/generators.pyi +29 -0
  149. tnfr/mathematics/metrics.py +119 -0
  150. tnfr/mathematics/metrics.pyi +16 -0
  151. tnfr/mathematics/operators.py +239 -0
  152. tnfr/mathematics/operators.pyi +59 -0
  153. tnfr/mathematics/operators_factory.py +124 -0
  154. tnfr/mathematics/operators_factory.pyi +11 -0
  155. tnfr/mathematics/projection.py +87 -0
  156. tnfr/mathematics/projection.pyi +33 -0
  157. tnfr/mathematics/runtime.py +182 -0
  158. tnfr/mathematics/runtime.pyi +64 -0
  159. tnfr/mathematics/spaces.py +256 -0
  160. tnfr/mathematics/spaces.pyi +83 -0
  161. tnfr/mathematics/transforms.py +305 -0
  162. tnfr/mathematics/transforms.pyi +62 -0
  163. tnfr/metrics/__init__.py +79 -0
  164. tnfr/metrics/__init__.pyi +20 -0
  165. tnfr/metrics/buffer_cache.py +163 -0
  166. tnfr/metrics/buffer_cache.pyi +24 -0
  167. tnfr/metrics/cache_utils.py +214 -0
  168. tnfr/metrics/coherence.py +2009 -0
  169. tnfr/metrics/coherence.pyi +129 -0
  170. tnfr/metrics/common.py +158 -0
  171. tnfr/metrics/common.pyi +35 -0
  172. tnfr/metrics/core.py +316 -0
  173. tnfr/metrics/core.pyi +13 -0
  174. tnfr/metrics/diagnosis.py +833 -0
  175. tnfr/metrics/diagnosis.pyi +86 -0
  176. tnfr/metrics/emergence.py +245 -0
  177. tnfr/metrics/export.py +179 -0
  178. tnfr/metrics/export.pyi +7 -0
  179. tnfr/metrics/glyph_timing.py +379 -0
  180. tnfr/metrics/glyph_timing.pyi +81 -0
  181. tnfr/metrics/learning_metrics.py +280 -0
  182. tnfr/metrics/learning_metrics.pyi +21 -0
  183. tnfr/metrics/phase_coherence.py +351 -0
  184. tnfr/metrics/phase_compatibility.py +349 -0
  185. tnfr/metrics/reporting.py +183 -0
  186. tnfr/metrics/reporting.pyi +25 -0
  187. tnfr/metrics/sense_index.py +1203 -0
  188. tnfr/metrics/sense_index.pyi +9 -0
  189. tnfr/metrics/trig.py +373 -0
  190. tnfr/metrics/trig.pyi +13 -0
  191. tnfr/metrics/trig_cache.py +233 -0
  192. tnfr/metrics/trig_cache.pyi +10 -0
  193. tnfr/multiscale/__init__.py +32 -0
  194. tnfr/multiscale/hierarchical.py +517 -0
  195. tnfr/node.py +763 -0
  196. tnfr/node.pyi +139 -0
  197. tnfr/observers.py +255 -130
  198. tnfr/observers.pyi +31 -0
  199. tnfr/ontosim.py +144 -137
  200. tnfr/ontosim.pyi +28 -0
  201. tnfr/operators/__init__.py +1672 -0
  202. tnfr/operators/__init__.pyi +31 -0
  203. tnfr/operators/algebra.py +277 -0
  204. tnfr/operators/canonical_patterns.py +420 -0
  205. tnfr/operators/cascade.py +267 -0
  206. tnfr/operators/cycle_detection.py +358 -0
  207. tnfr/operators/definitions.py +4108 -0
  208. tnfr/operators/definitions.pyi +78 -0
  209. tnfr/operators/grammar.py +1164 -0
  210. tnfr/operators/grammar.pyi +140 -0
  211. tnfr/operators/hamiltonian.py +710 -0
  212. tnfr/operators/health_analyzer.py +809 -0
  213. tnfr/operators/jitter.py +272 -0
  214. tnfr/operators/jitter.pyi +11 -0
  215. tnfr/operators/lifecycle.py +314 -0
  216. tnfr/operators/metabolism.py +618 -0
  217. tnfr/operators/metrics.py +2138 -0
  218. tnfr/operators/network_analysis/__init__.py +27 -0
  219. tnfr/operators/network_analysis/source_detection.py +186 -0
  220. tnfr/operators/nodal_equation.py +395 -0
  221. tnfr/operators/pattern_detection.py +660 -0
  222. tnfr/operators/patterns.py +669 -0
  223. tnfr/operators/postconditions/__init__.py +38 -0
  224. tnfr/operators/postconditions/mutation.py +236 -0
  225. tnfr/operators/preconditions/__init__.py +1226 -0
  226. tnfr/operators/preconditions/coherence.py +305 -0
  227. tnfr/operators/preconditions/dissonance.py +236 -0
  228. tnfr/operators/preconditions/emission.py +128 -0
  229. tnfr/operators/preconditions/mutation.py +580 -0
  230. tnfr/operators/preconditions/reception.py +125 -0
  231. tnfr/operators/preconditions/resonance.py +364 -0
  232. tnfr/operators/registry.py +74 -0
  233. tnfr/operators/registry.pyi +9 -0
  234. tnfr/operators/remesh.py +1809 -0
  235. tnfr/operators/remesh.pyi +26 -0
  236. tnfr/operators/structural_units.py +268 -0
  237. tnfr/operators/unified_grammar.py +105 -0
  238. tnfr/parallel/__init__.py +54 -0
  239. tnfr/parallel/auto_scaler.py +234 -0
  240. tnfr/parallel/distributed.py +384 -0
  241. tnfr/parallel/engine.py +238 -0
  242. tnfr/parallel/gpu_engine.py +420 -0
  243. tnfr/parallel/monitoring.py +248 -0
  244. tnfr/parallel/partitioner.py +459 -0
  245. tnfr/py.typed +0 -0
  246. tnfr/recipes/__init__.py +22 -0
  247. tnfr/recipes/cookbook.py +743 -0
  248. tnfr/rng.py +178 -0
  249. tnfr/rng.pyi +26 -0
  250. tnfr/schemas/__init__.py +8 -0
  251. tnfr/schemas/grammar.json +94 -0
  252. tnfr/sdk/__init__.py +107 -0
  253. tnfr/sdk/__init__.pyi +19 -0
  254. tnfr/sdk/adaptive_system.py +173 -0
  255. tnfr/sdk/adaptive_system.pyi +21 -0
  256. tnfr/sdk/builders.py +370 -0
  257. tnfr/sdk/builders.pyi +51 -0
  258. tnfr/sdk/fluent.py +1121 -0
  259. tnfr/sdk/fluent.pyi +74 -0
  260. tnfr/sdk/templates.py +342 -0
  261. tnfr/sdk/templates.pyi +41 -0
  262. tnfr/sdk/utils.py +341 -0
  263. tnfr/secure_config.py +46 -0
  264. tnfr/security/__init__.py +70 -0
  265. tnfr/security/database.py +514 -0
  266. tnfr/security/subprocess.py +503 -0
  267. tnfr/security/validation.py +290 -0
  268. tnfr/selector.py +247 -0
  269. tnfr/selector.pyi +19 -0
  270. tnfr/sense.py +378 -0
  271. tnfr/sense.pyi +23 -0
  272. tnfr/services/__init__.py +17 -0
  273. tnfr/services/orchestrator.py +325 -0
  274. tnfr/sparse/__init__.py +39 -0
  275. tnfr/sparse/representations.py +492 -0
  276. tnfr/structural.py +705 -0
  277. tnfr/structural.pyi +83 -0
  278. tnfr/telemetry/__init__.py +35 -0
  279. tnfr/telemetry/cache_metrics.py +226 -0
  280. tnfr/telemetry/cache_metrics.pyi +64 -0
  281. tnfr/telemetry/nu_f.py +422 -0
  282. tnfr/telemetry/nu_f.pyi +108 -0
  283. tnfr/telemetry/verbosity.py +36 -0
  284. tnfr/telemetry/verbosity.pyi +15 -0
  285. tnfr/tokens.py +58 -0
  286. tnfr/tokens.pyi +36 -0
  287. tnfr/tools/__init__.py +20 -0
  288. tnfr/tools/domain_templates.py +478 -0
  289. tnfr/tools/sequence_generator.py +846 -0
  290. tnfr/topology/__init__.py +13 -0
  291. tnfr/topology/asymmetry.py +151 -0
  292. tnfr/trace.py +543 -0
  293. tnfr/trace.pyi +42 -0
  294. tnfr/tutorials/__init__.py +38 -0
  295. tnfr/tutorials/autonomous_evolution.py +285 -0
  296. tnfr/tutorials/interactive.py +1576 -0
  297. tnfr/tutorials/structural_metabolism.py +238 -0
  298. tnfr/types.py +775 -0
  299. tnfr/types.pyi +357 -0
  300. tnfr/units.py +68 -0
  301. tnfr/units.pyi +13 -0
  302. tnfr/utils/__init__.py +282 -0
  303. tnfr/utils/__init__.pyi +215 -0
  304. tnfr/utils/cache.py +4223 -0
  305. tnfr/utils/cache.pyi +470 -0
  306. tnfr/utils/callbacks.py +375 -0
  307. tnfr/utils/callbacks.pyi +49 -0
  308. tnfr/utils/chunks.py +108 -0
  309. tnfr/utils/chunks.pyi +22 -0
  310. tnfr/utils/data.py +428 -0
  311. tnfr/utils/data.pyi +74 -0
  312. tnfr/utils/graph.py +85 -0
  313. tnfr/utils/graph.pyi +10 -0
  314. tnfr/utils/init.py +821 -0
  315. tnfr/utils/init.pyi +80 -0
  316. tnfr/utils/io.py +559 -0
  317. tnfr/utils/io.pyi +66 -0
  318. tnfr/utils/numeric.py +114 -0
  319. tnfr/utils/numeric.pyi +21 -0
  320. tnfr/validation/__init__.py +257 -0
  321. tnfr/validation/__init__.pyi +85 -0
  322. tnfr/validation/compatibility.py +460 -0
  323. tnfr/validation/compatibility.pyi +6 -0
  324. tnfr/validation/config.py +73 -0
  325. tnfr/validation/graph.py +139 -0
  326. tnfr/validation/graph.pyi +18 -0
  327. tnfr/validation/input_validation.py +755 -0
  328. tnfr/validation/invariants.py +712 -0
  329. tnfr/validation/rules.py +253 -0
  330. tnfr/validation/rules.pyi +44 -0
  331. tnfr/validation/runtime.py +279 -0
  332. tnfr/validation/runtime.pyi +28 -0
  333. tnfr/validation/sequence_validator.py +162 -0
  334. tnfr/validation/soft_filters.py +170 -0
  335. tnfr/validation/soft_filters.pyi +32 -0
  336. tnfr/validation/spectral.py +164 -0
  337. tnfr/validation/spectral.pyi +42 -0
  338. tnfr/validation/validator.py +1266 -0
  339. tnfr/validation/window.py +39 -0
  340. tnfr/validation/window.pyi +1 -0
  341. tnfr/visualization/__init__.py +98 -0
  342. tnfr/visualization/cascade_viz.py +256 -0
  343. tnfr/visualization/hierarchy.py +284 -0
  344. tnfr/visualization/sequence_plotter.py +784 -0
  345. tnfr/viz/__init__.py +60 -0
  346. tnfr/viz/matplotlib.py +278 -0
  347. tnfr/viz/matplotlib.pyi +35 -0
  348. tnfr-8.5.0.dist-info/METADATA +573 -0
  349. tnfr-8.5.0.dist-info/RECORD +353 -0
  350. tnfr-8.5.0.dist-info/entry_points.txt +3 -0
  351. tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
  352. tnfr/constants.py +0 -183
  353. tnfr/dynamics.py +0 -543
  354. tnfr/helpers.py +0 -198
  355. tnfr/main.py +0 -37
  356. tnfr/operators.py +0 -296
  357. tnfr-3.0.3.dist-info/METADATA +0 -35
  358. tnfr-3.0.3.dist-info/RECORD +0 -13
  359. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  360. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,710 @@
1
+ r"""Internal Hamiltonian operator construction for TNFR.
2
+
3
+ This module implements the explicit construction of the internal Hamiltonian:
4
+
5
+ .. math::
6
+ \hat{H}_{int} = \hat{H}_{coh} + \hat{H}_{freq} + \hat{H}_{coupling}
7
+
8
+ Mathematical Foundation
9
+ -----------------------
10
+
11
+ The internal Hamiltonian :math:`\hat{H}_{int}` governs the structural evolution
12
+ of resonant fractal nodes through the canonical nodal equation:
13
+
14
+ .. math::
15
+ \frac{\partial \text{EPI}}{\partial t} = \nu_f \cdot \Delta\text{NFR}(t)
16
+
17
+ where the reorganization operator :math:`\Delta\text{NFR}` is defined as:
18
+
19
+ .. math::
20
+ \Delta\text{NFR} = \frac{d}{dt} + \frac{i[\hat{H}_{int}, \cdot]}{\hbar_{str}}
21
+
22
+ **Components**:
23
+
24
+ 1. **Coherence Potential** :math:`\hat{H}_{coh}`:
25
+ Potential energy from structural alignment between nodes.
26
+
27
+ .. math::
28
+ \hat{H}_{coh} = -C_0 \sum_{ij} w_{ij} |i\rangle\langle j|
29
+
30
+ where :math:`w_{ij}` is the coherence weight from similarity metrics.
31
+
32
+ 2. **Frequency Operator** :math:`\hat{H}_{freq}`:
33
+ Diagonal operator encoding each node's structural frequency.
34
+
35
+ .. math::
36
+ \hat{H}_{freq} = \sum_i \nu_{f,i} |i\rangle\langle i|
37
+
38
+ 3. **Coupling Hamiltonian** :math:`\hat{H}_{coupling}`:
39
+ Network topology-induced interactions.
40
+
41
+ .. math::
42
+ \hat{H}_{coupling} = J_0 \sum_{(i,j) \in E} (|i\rangle\langle j| + |j\rangle\langle i|)
43
+
44
+ Theoretical References
45
+ ----------------------
46
+
47
+ See:
48
+ - Mathematical formalization: ``Formalizacion-Matematica-TNFR-Unificada.pdf``, §2.4
49
+ - ΔNFR development: ``Desarrollo-Exhaustivo_-Formalizacion-Matematica-Ri-3.pdf``
50
+ - Quantum time evolution: Sakurai, "Modern Quantum Mechanics", Chapter 2
51
+
52
+ Examples
53
+ --------
54
+
55
+ **Basic Hamiltonian construction**:
56
+
57
+ >>> import networkx as nx
58
+ >>> from tnfr.operators.hamiltonian import InternalHamiltonian
59
+ >>> G = nx.Graph()
60
+ >>> G.add_edges_from([(0, 1), (1, 2), (2, 0)])
61
+ >>> for i, node in enumerate(G.nodes):
62
+ ... G.nodes[node].update({
63
+ ... 'nu_f': 0.5 + 0.1 * i,
64
+ ... 'phase': 0.0,
65
+ ... 'epi': 1.0,
66
+ ... 'si': 0.7
67
+ ... })
68
+ >>> ham = InternalHamiltonian(G)
69
+ >>> print("Total Hamiltonian shape:", ham.H_int.shape)
70
+ Total Hamiltonian shape: (3, 3)
71
+
72
+ **Time evolution**:
73
+
74
+ >>> U_t = ham.time_evolution_operator(t=1.0)
75
+ >>> import numpy as np
76
+ >>> is_unitary = np.allclose(U_t @ U_t.conj().T, np.eye(3))
77
+ >>> print("Evolution operator is unitary:", is_unitary)
78
+ Evolution operator is unitary: True
79
+
80
+ **Energy spectrum**:
81
+
82
+ >>> eigenvalues, eigenvectors = ham.get_spectrum()
83
+ >>> print("Ground state energy:", eigenvalues[0])
84
+ Ground state energy: ...
85
+ """
86
+
87
+ from __future__ import annotations
88
+
89
+ from typing import TYPE_CHECKING, Any, Tuple
90
+
91
+ from ..alias import get_attr
92
+ from ..constants.aliases import ALIAS_VF
93
+ from ..utils.cache import cached_node_list, CacheManager, _graph_cache_manager
94
+
95
+ if TYPE_CHECKING: # pragma: no cover
96
+ import numpy as np
97
+ from ..types import TNFRGraph, FloatMatrix
98
+
99
+ __all__ = (
100
+ "InternalHamiltonian",
101
+ "build_H_coherence",
102
+ "build_H_frequency",
103
+ "build_H_coupling",
104
+ )
105
+
106
+
107
+ class InternalHamiltonian:
108
+ """Constructs and manipulates the internal Hamiltonian H_int.
109
+
110
+ Mathematical Definition
111
+ -----------------------
112
+
113
+ .. math::
114
+ \hat{H}_{int} = \hat{H}_{coh} + \hat{H}_{freq} + \hat{H}_{coupling}
115
+
116
+ where each component is an N×N Hermitian matrix (N = number of nodes).
117
+
118
+ Attributes
119
+ ----------
120
+ G : TNFRGraph
121
+ Network graph with structural attributes
122
+ H_coh : ndarray, shape (N, N)
123
+ Coherence potential matrix
124
+ H_freq : ndarray, shape (N, N)
125
+ Frequency operator matrix (diagonal)
126
+ H_coupling : ndarray, shape (N, N)
127
+ Coupling matrix from network topology
128
+ H_int : ndarray, shape (N, N)
129
+ Total internal Hamiltonian
130
+ hbar_str : float
131
+ Structural Planck constant (ℏ_str)
132
+ nodes : list
133
+ Ordered list of node identifiers
134
+ N : int
135
+ Number of nodes in the network
136
+
137
+ Notes
138
+ -----
139
+
140
+ This implementation leverages existing cache infrastructure:
141
+
142
+ - Uses ``cached_node_list()`` for consistent node ordering
143
+ - Reuses ``coherence_matrix()`` computation for H_coh
144
+ - Integrates with ``CacheManager`` for performance optimization
145
+
146
+ All matrix components are verified to be Hermitian (self-adjoint),
147
+ ensuring real eigenvalues and unitary time evolution.
148
+ """
149
+
150
+ def __init__(
151
+ self,
152
+ G: TNFRGraph,
153
+ hbar_str: float = 1.0,
154
+ cache_manager: CacheManager | None = None,
155
+ ):
156
+ """Initialize Hamiltonian from graph structure.
157
+
158
+ Parameters
159
+ ----------
160
+ G : TNFRGraph
161
+ Graph with nodes containing 'nu_f', 'phase', 'epi', 'si' attributes
162
+ hbar_str : float, default=1.0
163
+ Structural Planck constant (ℏ_str). This sets the scale for
164
+ structural reorganization rates. Default value of 1.0 gives natural
165
+ units where the Hamiltonian directly represents structural energy scales.
166
+ cache_manager : CacheManager, optional
167
+ Cache manager for performance optimization. If None, uses the
168
+ graph's internal cache manager.
169
+
170
+ Raises
171
+ ------
172
+ ValueError
173
+ If any Hamiltonian component fails Hermiticity check
174
+ ImportError
175
+ If NumPy is not available
176
+ """
177
+ # Import NumPy (required for matrix operations)
178
+ try:
179
+ import numpy as np
180
+
181
+ self._np = np
182
+ except ImportError as exc:
183
+ raise ImportError(
184
+ "NumPy is required for Hamiltonian construction. "
185
+ "Install with: pip install numpy"
186
+ ) from exc
187
+
188
+ self.G = G
189
+ self.hbar_str = float(hbar_str)
190
+
191
+ # Use unified cache infrastructure
192
+ if cache_manager is None:
193
+ cache_manager = _graph_cache_manager(G.graph)
194
+ self._cache_manager = cache_manager
195
+
196
+ # Get consistent node ordering using cached utility
197
+ self.nodes = cached_node_list(G)
198
+ self.N = len(self.nodes)
199
+
200
+ # Build Hamiltonian components
201
+ self.H_coh = self._build_H_coherence()
202
+ self.H_freq = self._build_H_frequency()
203
+ self.H_coupling = self._build_H_coupling()
204
+
205
+ # Combine into total Hamiltonian
206
+ self.H_int = self.H_coh + self.H_freq + self.H_coupling
207
+
208
+ # Verify Hermiticity (critical for physical validity)
209
+ self._verify_hermitian()
210
+
211
+ def _build_H_coherence(self) -> FloatMatrix:
212
+ """Construct coherence potential H_coh from coherence matrix.
213
+
214
+ Theory
215
+ ------
216
+
217
+ .. math::
218
+ \hat{H}_{coh} = -C_0 \sum_{ij} w_{ij} |i\rangle\langle j|
219
+
220
+ where :math:`w_{ij}` is the coherence weight computed from structural
221
+ similarity (phase, EPI, νf, Si). The negative sign ensures coherent
222
+ states have lower energy (potential well).
223
+
224
+ Returns
225
+ -------
226
+ H_coh : ndarray, shape (N, N)
227
+ Coherence potential matrix (Hermitian)
228
+
229
+ Notes
230
+ -----
231
+
232
+ Reuses ``coherence_matrix()`` function to avoid code duplication and
233
+ ensure consistency with existing coherence computations.
234
+ """
235
+ np = self._np
236
+
237
+ # Handle empty graph case
238
+ if self.N == 0:
239
+ return np.zeros((0, 0), dtype=complex)
240
+
241
+ # Import here to avoid circular dependency
242
+ from ..metrics.coherence import coherence_matrix
243
+
244
+ # Reuse existing coherence_matrix computation
245
+ nodes, W = coherence_matrix(self.G)
246
+
247
+ # Convert to dense NumPy array
248
+ if isinstance(W, list):
249
+ # Empty list case
250
+ if len(W) == 0:
251
+ W_matrix = np.zeros((self.N, self.N), dtype=complex)
252
+ # Check if sparse format (list of tuples) or dense (list of lists)
253
+ elif isinstance(W[0], (list, tuple)) and len(W[0]) == 3:
254
+ # Sparse format: [(i, j, w), ...]
255
+ W_matrix = np.zeros((self.N, self.N), dtype=complex)
256
+ for i, j, w in W:
257
+ W_matrix[i, j] = w
258
+ else:
259
+ # Dense format: [[...], [...], ...]
260
+ W_matrix = np.array(W, dtype=complex)
261
+ else:
262
+ W_matrix = np.asarray(W, dtype=complex)
263
+
264
+ # Reshape if necessary (handle 1D case)
265
+ if W_matrix.ndim == 1:
266
+ if len(W_matrix) == 0:
267
+ W_matrix = np.zeros((self.N, self.N), dtype=complex)
268
+ elif len(W_matrix) == self.N * self.N:
269
+ W_matrix = W_matrix.reshape((self.N, self.N))
270
+ else:
271
+ raise ValueError(
272
+ f"Cannot reshape coherence vector of length {len(W_matrix)} "
273
+ f"into ({self.N}, {self.N}) matrix"
274
+ )
275
+
276
+ # Ensure correct shape
277
+ if W_matrix.shape != (self.N, self.N):
278
+ raise ValueError(
279
+ f"Coherence matrix shape {W_matrix.shape} does not match "
280
+ f"node count ({self.N}, {self.N})"
281
+ )
282
+
283
+ # Scale by coherence strength (negative for potential well)
284
+ C_0 = self.G.graph.get("H_COH_STRENGTH", -1.0)
285
+ H_coh = C_0 * W_matrix
286
+
287
+ return H_coh
288
+
289
+ def _build_H_frequency(self) -> FloatMatrix:
290
+ """Construct frequency operator H_freq (diagonal).
291
+
292
+ Theory
293
+ ------
294
+
295
+ .. math::
296
+ \hat{H}_{freq} = \sum_i \nu_{f,i} |i\rangle\langle i|
297
+
298
+ Each node's structural frequency :math:`\nu_{f,i}` becomes its diagonal
299
+ energy. Nodes with higher νf have higher "kinetic" reorganization energy.
300
+
301
+ Returns
302
+ -------
303
+ H_freq : ndarray, shape (N, N)
304
+ Diagonal frequency operator (Hermitian)
305
+
306
+ Notes
307
+ -----
308
+
309
+ Uses ``get_attr()`` with ``ALIAS_VF`` to support attribute aliasing
310
+ and maintain consistency with the rest of the codebase.
311
+ """
312
+ np = self._np
313
+
314
+ frequencies = np.zeros(self.N, dtype=float)
315
+
316
+ for i, node in enumerate(self.nodes):
317
+ # Use unified attribute access with aliasing support
318
+ nu_f = get_attr(self.G.nodes[node], ALIAS_VF, 0.0)
319
+ frequencies[i] = float(nu_f)
320
+
321
+ # Create diagonal matrix (automatically Hermitian)
322
+ H_freq = np.diag(frequencies).astype(complex)
323
+
324
+ return H_freq
325
+
326
+ def _build_H_coupling(self) -> FloatMatrix:
327
+ """Construct coupling Hamiltonian from network topology.
328
+
329
+ Theory
330
+ ------
331
+
332
+ .. math::
333
+ \hat{H}_{coupling} = J_0 \sum_{(i,j) \in E} (|i\rangle\langle j| + |j\rangle\langle i|)
334
+
335
+ where E is the edge set and :math:`J_0` is coupling strength.
336
+ The sum is symmetric (Hermitian) for undirected graphs.
337
+
338
+ Returns
339
+ -------
340
+ H_coupling : ndarray, shape (N, N)
341
+ Coupling matrix (Hermitian for undirected graphs)
342
+
343
+ Notes
344
+ -----
345
+
346
+ For directed graphs, the matrix may not be Hermitian unless the graph
347
+ is explicitly symmetrized.
348
+ """
349
+ np = self._np
350
+
351
+ H_coupling = np.zeros((self.N, self.N), dtype=complex)
352
+
353
+ # Build node index mapping (use consistent ordering)
354
+ node_to_idx = {node: i for i, node in enumerate(self.nodes)}
355
+
356
+ # Get coupling strength from graph configuration
357
+ J_0 = self.G.graph.get("H_COUPLING_STRENGTH", 0.1)
358
+
359
+ # Populate coupling matrix from edges
360
+ for u, v in self.G.edges():
361
+ i = node_to_idx[u]
362
+ j = node_to_idx[v]
363
+
364
+ # Symmetric coupling (ensures Hermiticity)
365
+ H_coupling[i, j] = J_0
366
+ H_coupling[j, i] = J_0
367
+
368
+ return H_coupling
369
+
370
+ def _verify_hermitian(self, tolerance: float = 1e-10) -> None:
371
+ """Verify that all Hamiltonian components are Hermitian.
372
+
373
+ Parameters
374
+ ----------
375
+ tolerance : float, default=1e-10
376
+ Maximum allowed deviation from Hermiticity
377
+
378
+ Raises
379
+ ------
380
+ ValueError
381
+ If any component fails Hermiticity check with detailed diagnostics
382
+
383
+ Notes
384
+ -----
385
+
386
+ A matrix H is Hermitian if :math:`H = H^\dagger`, where :math:`\dagger`
387
+ denotes conjugate transpose. This ensures:
388
+
389
+ 1. Real eigenvalues (energy spectrum)
390
+ 2. Unitary time evolution
391
+ 3. Probability conservation
392
+ """
393
+ np = self._np
394
+
395
+ # Handle empty graph case
396
+ if self.N == 0:
397
+ return
398
+
399
+ components = [
400
+ ("H_coh", self.H_coh),
401
+ ("H_freq", self.H_freq),
402
+ ("H_coupling", self.H_coupling),
403
+ ("H_int", self.H_int),
404
+ ]
405
+
406
+ for name, H in components:
407
+ # Check Hermiticity: H = H†
408
+ H_dagger = H.conj().T
409
+ deviation = np.max(np.abs(H - H_dagger))
410
+
411
+ if deviation > tolerance:
412
+ raise ValueError(
413
+ f"{name} is not Hermitian: max deviation = {deviation:.2e} "
414
+ f"(tolerance = {tolerance:.2e})"
415
+ )
416
+
417
+ def compute_delta_nfr_operator(self) -> FloatMatrix:
418
+ """Compute ΔNFR operator from Hamiltonian commutator.
419
+
420
+ Theory
421
+ ------
422
+
423
+ .. math::
424
+ \Delta\text{NFR} = \frac{i[\hat{H}_{int}, \cdot]}{\hbar_{str}}
425
+
426
+ For a state :math:`|\psi\rangle`:
427
+
428
+ .. math::
429
+ \Delta\text{NFR}|\psi\rangle = \frac{i}{\hbar_{str}}(\hat{H}_{int}|\psi\rangle - |\psi\rangle\hat{H}_{int})
430
+
431
+ Returns
432
+ -------
433
+ Delta_NFR_matrix : ndarray, shape (N, N)
434
+ ΔNFR operator in matrix form (anti-Hermitian)
435
+
436
+ Notes
437
+ -----
438
+
439
+ The ΔNFR operator is anti-Hermitian: :math:`\Delta\text{NFR}^\dagger = -\Delta\text{NFR}`,
440
+ which ensures imaginary eigenvalues and corresponds to generator of
441
+ time evolution.
442
+ """
443
+ # ΔNFR = (i/ℏ_str) * H_int (for operators acting on states)
444
+ return (1j / self.hbar_str) * self.H_int
445
+
446
+ def time_evolution_operator(self, t: float) -> FloatMatrix:
447
+ r"""Compute time evolution operator U(t) = exp(-i H_int t / ℏ_str).
448
+
449
+ Parameters
450
+ ----------
451
+ t : float
452
+ Evolution time in structural time units
453
+
454
+ Returns
455
+ -------
456
+ U_t : ndarray, shape (N, N)
457
+ Unitary time evolution operator
458
+
459
+ Raises
460
+ ------
461
+ ValueError
462
+ If the computed operator is not unitary (indicates numerical issues)
463
+ ImportError
464
+ If scipy is not installed
465
+
466
+ Notes
467
+ -----
468
+
469
+ The time evolution operator propagates states forward in time:
470
+
471
+ .. math::
472
+ |\psi(t)\rangle = U(t)|\psi(0)\rangle
473
+
474
+ Unitarity :math:`U^\dagger U = I` ensures probability conservation.
475
+ """
476
+ try:
477
+ from scipy.linalg import expm
478
+ except ImportError as exc:
479
+ raise ImportError(
480
+ "scipy is required for time evolution computation. "
481
+ "Install with: pip install scipy"
482
+ ) from exc
483
+
484
+ np = self._np
485
+
486
+ # Compute matrix exponential
487
+ exponent = -1j * self.H_int * t / self.hbar_str
488
+ U_t = expm(exponent)
489
+
490
+ # Verify unitarity: U†U = I
491
+ U_dag_U = U_t.conj().T @ U_t
492
+ identity = np.eye(self.N)
493
+
494
+ if not np.allclose(U_dag_U, identity):
495
+ max_error = np.max(np.abs(U_dag_U - identity))
496
+ raise ValueError(
497
+ f"Evolution operator is not unitary: max error = {max_error:.2e}. "
498
+ "This indicates numerical instability, possibly due to "
499
+ "ill-conditioned Hamiltonian or inappropriate time step."
500
+ )
501
+
502
+ return U_t
503
+
504
+ def get_spectrum(self) -> Tuple[Any, Any]:
505
+ """Compute eigenvalues and eigenvectors of H_int.
506
+
507
+ Returns
508
+ -------
509
+ eigenvalues : ndarray, shape (N,)
510
+ Energy eigenvalues (sorted in ascending order)
511
+ eigenvectors : ndarray, shape (N, N)
512
+ Eigenvector matrix (columns are eigenstates)
513
+
514
+ Notes
515
+ -----
516
+
517
+ The eigenvalue equation:
518
+
519
+ .. math::
520
+ \hat{H}_{int}|\phi_n\rangle = E_n|\phi_n\rangle
521
+
522
+ gives the stationary states :math:`|\phi_n\rangle` with energies :math:`E_n`.
523
+ These are the maximally stable coherent configurations.
524
+ """
525
+ np = self._np
526
+
527
+ # Use eigh for Hermitian matrices (more efficient and numerically stable)
528
+ eigenvalues, eigenvectors = np.linalg.eigh(self.H_int)
529
+
530
+ return eigenvalues, eigenvectors
531
+
532
+ def compute_node_delta_nfr(self, node: Any) -> float:
533
+ """Compute ΔNFR for a single node using Hamiltonian commutator.
534
+
535
+ Parameters
536
+ ----------
537
+ node : NodeId
538
+ Node identifier
539
+
540
+ Returns
541
+ -------
542
+ delta_nfr : float
543
+ ΔNFR value for the specified node
544
+
545
+ Theory
546
+ ------
547
+
548
+ For node n, the ΔNFR is computed as:
549
+
550
+ .. math::
551
+ \Delta\text{NFR}_n = \frac{i}{\hbar_{str}} \langle n | [\hat{H}_{int}, \rho_n] | n \rangle
552
+
553
+ where :math:`\rho_n = |n\rangle\langle n|` is the density matrix for a
554
+ pure state localized on node n.
555
+
556
+ Notes
557
+ -----
558
+
559
+ The commutator result is anti-Hermitian, so its diagonal elements are
560
+ purely imaginary in theory. We extract the real part to obtain the ΔNFR
561
+ observable value. In practice, numerical precision may introduce small
562
+ real components that represent the actual structural reorganization rate.
563
+ """
564
+ np = self._np
565
+
566
+ # Get node index
567
+ try:
568
+ node_idx = self.nodes.index(node)
569
+ except ValueError:
570
+ raise ValueError(f"Node {node} not found in Hamiltonian")
571
+
572
+ # Node density matrix (pure state |n⟩⟨n|)
573
+ rho_n = np.zeros((self.N, self.N), dtype=complex)
574
+ rho_n[node_idx, node_idx] = 1.0
575
+
576
+ # Commutator: [H_int, ρ_n] = H_int ρ_n - ρ_n H_int
577
+ commutator = self.H_int @ rho_n - rho_n @ self.H_int
578
+
579
+ # ΔNFR operator
580
+ delta_nfr_matrix = (1j / self.hbar_str) * commutator
581
+
582
+ # Extract diagonal element for node n
583
+ # Note: Take real part to obtain observable. Diagonal elements of the
584
+ # anti-Hermitian commutator are purely imaginary theoretically; any
585
+ # nonzero real part comes from numerical precision or represents the
586
+ # actual structural reorganization rate.
587
+ delta_nfr = float(delta_nfr_matrix[node_idx, node_idx].real)
588
+
589
+ return delta_nfr
590
+
591
+
592
+ # Standalone builder functions for modular usage
593
+
594
+
595
+ def build_H_coherence(
596
+ G: TNFRGraph,
597
+ nodes: list | None = None,
598
+ C_0: float = -1.0,
599
+ ) -> FloatMatrix:
600
+ """Construct coherence potential matrix from graph.
601
+
602
+ Parameters
603
+ ----------
604
+ G : TNFRGraph
605
+ Graph with structural attributes
606
+ nodes : list, optional
607
+ Ordered list of nodes. If None, uses cached_node_list(G)
608
+ C_0 : float, default=-1.0
609
+ Coherence potential strength (negative for attractive potential)
610
+
611
+ Returns
612
+ -------
613
+ H_coh : ndarray, shape (N, N)
614
+ Coherence potential matrix
615
+ """
616
+ import numpy as np
617
+
618
+ # Import here to avoid circular dependency
619
+ from ..metrics.coherence import coherence_matrix
620
+
621
+ if nodes is None:
622
+ nodes = cached_node_list(G)
623
+
624
+ N = len(nodes)
625
+ _, W = coherence_matrix(G)
626
+
627
+ # Convert to NumPy array
628
+ if isinstance(W, list):
629
+ if W and isinstance(W[0], (list, tuple)) and len(W[0]) == 3:
630
+ W_matrix = np.zeros((N, N), dtype=complex)
631
+ for i, j, w in W:
632
+ W_matrix[i, j] = w
633
+ else:
634
+ W_matrix = np.array(W, dtype=complex)
635
+ else:
636
+ W_matrix = np.asarray(W, dtype=complex)
637
+
638
+ return C_0 * W_matrix
639
+
640
+
641
+ def build_H_frequency(
642
+ G: TNFRGraph,
643
+ nodes: list | None = None,
644
+ ) -> FloatMatrix:
645
+ """Construct diagonal frequency operator from graph.
646
+
647
+ Parameters
648
+ ----------
649
+ G : TNFRGraph
650
+ Graph with 'nu_f' attributes
651
+ nodes : list, optional
652
+ Ordered list of nodes. If None, uses cached_node_list(G)
653
+
654
+ Returns
655
+ -------
656
+ H_freq : ndarray, shape (N, N)
657
+ Diagonal frequency operator
658
+ """
659
+ import numpy as np
660
+
661
+ if nodes is None:
662
+ nodes = cached_node_list(G)
663
+
664
+ N = len(nodes)
665
+ frequencies = np.zeros(N, dtype=float)
666
+
667
+ for i, node in enumerate(nodes):
668
+ nu_f = get_attr(G.nodes[node], ALIAS_VF, 0.0)
669
+ frequencies[i] = float(nu_f)
670
+
671
+ return np.diag(frequencies).astype(complex)
672
+
673
+
674
+ def build_H_coupling(
675
+ G: TNFRGraph,
676
+ nodes: list | None = None,
677
+ J_0: float = 0.1,
678
+ ) -> FloatMatrix:
679
+ """Construct coupling matrix from graph topology.
680
+
681
+ Parameters
682
+ ----------
683
+ G : TNFRGraph
684
+ Graph with edge structure
685
+ nodes : list, optional
686
+ Ordered list of nodes. If None, uses cached_node_list(G)
687
+ J_0 : float, default=0.1
688
+ Coupling strength
689
+
690
+ Returns
691
+ -------
692
+ H_coupling : ndarray, shape (N, N)
693
+ Coupling matrix (symmetric for undirected graphs)
694
+ """
695
+ import numpy as np
696
+
697
+ if nodes is None:
698
+ nodes = cached_node_list(G)
699
+
700
+ N = len(nodes)
701
+ H_coupling = np.zeros((N, N), dtype=complex)
702
+ node_to_idx = {node: i for i, node in enumerate(nodes)}
703
+
704
+ for u, v in G.edges():
705
+ i = node_to_idx[u]
706
+ j = node_to_idx[v]
707
+ H_coupling[i, j] = J_0
708
+ H_coupling[j, i] = J_0
709
+
710
+ return H_coupling