tnfr 4.5.2__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 (365) hide show
  1. tnfr/__init__.py +334 -50
  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 +214 -37
  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 +149 -556
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +51 -16
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +344 -32
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +676 -50
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +18 -3
  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/{constants_glyphs.py → config/constants.py} +26 -20
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/{constants/core.py → config/defaults_core.py} +59 -6
  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 +51 -133
  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 +3 -1
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +9 -15
  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 +213 -633
  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 +2699 -398
  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 +496 -102
  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 +10 -5
  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 +77 -55
  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 +29 -50
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +66 -53
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +144 -57
  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 +70 -30
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +22 -16
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +5 -241
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.pyi +7 -0
  139. tnfr/mathematics/__init__.py +79 -0
  140. tnfr/mathematics/backend.py +453 -0
  141. tnfr/mathematics/backend.pyi +99 -0
  142. tnfr/mathematics/dynamics.py +408 -0
  143. tnfr/mathematics/dynamics.pyi +90 -0
  144. tnfr/mathematics/epi.py +391 -0
  145. tnfr/mathematics/epi.pyi +65 -0
  146. tnfr/mathematics/generators.py +242 -0
  147. tnfr/mathematics/generators.pyi +29 -0
  148. tnfr/mathematics/metrics.py +119 -0
  149. tnfr/mathematics/metrics.pyi +16 -0
  150. tnfr/mathematics/operators.py +239 -0
  151. tnfr/mathematics/operators.pyi +59 -0
  152. tnfr/mathematics/operators_factory.py +124 -0
  153. tnfr/mathematics/operators_factory.pyi +11 -0
  154. tnfr/mathematics/projection.py +87 -0
  155. tnfr/mathematics/projection.pyi +33 -0
  156. tnfr/mathematics/runtime.py +182 -0
  157. tnfr/mathematics/runtime.pyi +64 -0
  158. tnfr/mathematics/spaces.py +256 -0
  159. tnfr/mathematics/spaces.pyi +83 -0
  160. tnfr/mathematics/transforms.py +305 -0
  161. tnfr/mathematics/transforms.pyi +62 -0
  162. tnfr/metrics/__init__.py +47 -9
  163. tnfr/metrics/__init__.pyi +20 -0
  164. tnfr/metrics/buffer_cache.py +163 -0
  165. tnfr/metrics/buffer_cache.pyi +24 -0
  166. tnfr/metrics/cache_utils.py +214 -0
  167. tnfr/metrics/coherence.py +1510 -330
  168. tnfr/metrics/coherence.pyi +129 -0
  169. tnfr/metrics/common.py +23 -16
  170. tnfr/metrics/common.pyi +35 -0
  171. tnfr/metrics/core.py +251 -36
  172. tnfr/metrics/core.pyi +13 -0
  173. tnfr/metrics/diagnosis.py +709 -110
  174. tnfr/metrics/diagnosis.pyi +86 -0
  175. tnfr/metrics/emergence.py +245 -0
  176. tnfr/metrics/export.py +60 -18
  177. tnfr/metrics/export.pyi +7 -0
  178. tnfr/metrics/glyph_timing.py +233 -43
  179. tnfr/metrics/glyph_timing.pyi +81 -0
  180. tnfr/metrics/learning_metrics.py +280 -0
  181. tnfr/metrics/learning_metrics.pyi +21 -0
  182. tnfr/metrics/phase_coherence.py +351 -0
  183. tnfr/metrics/phase_compatibility.py +349 -0
  184. tnfr/metrics/reporting.py +63 -28
  185. tnfr/metrics/reporting.pyi +25 -0
  186. tnfr/metrics/sense_index.py +1126 -43
  187. tnfr/metrics/sense_index.pyi +9 -0
  188. tnfr/metrics/trig.py +215 -23
  189. tnfr/metrics/trig.pyi +13 -0
  190. tnfr/metrics/trig_cache.py +148 -24
  191. tnfr/metrics/trig_cache.pyi +10 -0
  192. tnfr/multiscale/__init__.py +32 -0
  193. tnfr/multiscale/hierarchical.py +517 -0
  194. tnfr/node.py +646 -140
  195. tnfr/node.pyi +139 -0
  196. tnfr/observers.py +160 -45
  197. tnfr/observers.pyi +31 -0
  198. tnfr/ontosim.py +23 -19
  199. tnfr/ontosim.pyi +28 -0
  200. tnfr/operators/__init__.py +1358 -106
  201. tnfr/operators/__init__.pyi +31 -0
  202. tnfr/operators/algebra.py +277 -0
  203. tnfr/operators/canonical_patterns.py +420 -0
  204. tnfr/operators/cascade.py +267 -0
  205. tnfr/operators/cycle_detection.py +358 -0
  206. tnfr/operators/definitions.py +4108 -0
  207. tnfr/operators/definitions.pyi +78 -0
  208. tnfr/operators/grammar.py +1164 -0
  209. tnfr/operators/grammar.pyi +140 -0
  210. tnfr/operators/hamiltonian.py +710 -0
  211. tnfr/operators/health_analyzer.py +809 -0
  212. tnfr/operators/jitter.py +107 -38
  213. tnfr/operators/jitter.pyi +11 -0
  214. tnfr/operators/lifecycle.py +314 -0
  215. tnfr/operators/metabolism.py +618 -0
  216. tnfr/operators/metrics.py +2138 -0
  217. tnfr/operators/network_analysis/__init__.py +27 -0
  218. tnfr/operators/network_analysis/source_detection.py +186 -0
  219. tnfr/operators/nodal_equation.py +395 -0
  220. tnfr/operators/pattern_detection.py +660 -0
  221. tnfr/operators/patterns.py +669 -0
  222. tnfr/operators/postconditions/__init__.py +38 -0
  223. tnfr/operators/postconditions/mutation.py +236 -0
  224. tnfr/operators/preconditions/__init__.py +1226 -0
  225. tnfr/operators/preconditions/coherence.py +305 -0
  226. tnfr/operators/preconditions/dissonance.py +236 -0
  227. tnfr/operators/preconditions/emission.py +128 -0
  228. tnfr/operators/preconditions/mutation.py +580 -0
  229. tnfr/operators/preconditions/reception.py +125 -0
  230. tnfr/operators/preconditions/resonance.py +364 -0
  231. tnfr/operators/registry.py +74 -0
  232. tnfr/operators/registry.pyi +9 -0
  233. tnfr/operators/remesh.py +1415 -91
  234. tnfr/operators/remesh.pyi +26 -0
  235. tnfr/operators/structural_units.py +268 -0
  236. tnfr/operators/unified_grammar.py +105 -0
  237. tnfr/parallel/__init__.py +54 -0
  238. tnfr/parallel/auto_scaler.py +234 -0
  239. tnfr/parallel/distributed.py +384 -0
  240. tnfr/parallel/engine.py +238 -0
  241. tnfr/parallel/gpu_engine.py +420 -0
  242. tnfr/parallel/monitoring.py +248 -0
  243. tnfr/parallel/partitioner.py +459 -0
  244. tnfr/py.typed +0 -0
  245. tnfr/recipes/__init__.py +22 -0
  246. tnfr/recipes/cookbook.py +743 -0
  247. tnfr/rng.py +75 -151
  248. tnfr/rng.pyi +26 -0
  249. tnfr/schemas/__init__.py +8 -0
  250. tnfr/schemas/grammar.json +94 -0
  251. tnfr/sdk/__init__.py +107 -0
  252. tnfr/sdk/__init__.pyi +19 -0
  253. tnfr/sdk/adaptive_system.py +173 -0
  254. tnfr/sdk/adaptive_system.pyi +21 -0
  255. tnfr/sdk/builders.py +370 -0
  256. tnfr/sdk/builders.pyi +51 -0
  257. tnfr/sdk/fluent.py +1121 -0
  258. tnfr/sdk/fluent.pyi +74 -0
  259. tnfr/sdk/templates.py +342 -0
  260. tnfr/sdk/templates.pyi +41 -0
  261. tnfr/sdk/utils.py +341 -0
  262. tnfr/secure_config.py +46 -0
  263. tnfr/security/__init__.py +70 -0
  264. tnfr/security/database.py +514 -0
  265. tnfr/security/subprocess.py +503 -0
  266. tnfr/security/validation.py +290 -0
  267. tnfr/selector.py +59 -22
  268. tnfr/selector.pyi +19 -0
  269. tnfr/sense.py +92 -67
  270. tnfr/sense.pyi +23 -0
  271. tnfr/services/__init__.py +17 -0
  272. tnfr/services/orchestrator.py +325 -0
  273. tnfr/sparse/__init__.py +39 -0
  274. tnfr/sparse/representations.py +492 -0
  275. tnfr/structural.py +639 -263
  276. tnfr/structural.pyi +83 -0
  277. tnfr/telemetry/__init__.py +35 -0
  278. tnfr/telemetry/cache_metrics.py +226 -0
  279. tnfr/telemetry/cache_metrics.pyi +64 -0
  280. tnfr/telemetry/nu_f.py +422 -0
  281. tnfr/telemetry/nu_f.pyi +108 -0
  282. tnfr/telemetry/verbosity.py +36 -0
  283. tnfr/telemetry/verbosity.pyi +15 -0
  284. tnfr/tokens.py +2 -4
  285. tnfr/tokens.pyi +36 -0
  286. tnfr/tools/__init__.py +20 -0
  287. tnfr/tools/domain_templates.py +478 -0
  288. tnfr/tools/sequence_generator.py +846 -0
  289. tnfr/topology/__init__.py +13 -0
  290. tnfr/topology/asymmetry.py +151 -0
  291. tnfr/trace.py +300 -126
  292. tnfr/trace.pyi +42 -0
  293. tnfr/tutorials/__init__.py +38 -0
  294. tnfr/tutorials/autonomous_evolution.py +285 -0
  295. tnfr/tutorials/interactive.py +1576 -0
  296. tnfr/tutorials/structural_metabolism.py +238 -0
  297. tnfr/types.py +743 -12
  298. tnfr/types.pyi +357 -0
  299. tnfr/units.py +68 -0
  300. tnfr/units.pyi +13 -0
  301. tnfr/utils/__init__.py +282 -0
  302. tnfr/utils/__init__.pyi +215 -0
  303. tnfr/utils/cache.py +4223 -0
  304. tnfr/utils/cache.pyi +470 -0
  305. tnfr/{callback_utils.py → utils/callbacks.py} +26 -39
  306. tnfr/utils/callbacks.pyi +49 -0
  307. tnfr/utils/chunks.py +108 -0
  308. tnfr/utils/chunks.pyi +22 -0
  309. tnfr/utils/data.py +428 -0
  310. tnfr/utils/data.pyi +74 -0
  311. tnfr/utils/graph.py +85 -0
  312. tnfr/utils/graph.pyi +10 -0
  313. tnfr/utils/init.py +821 -0
  314. tnfr/utils/init.pyi +80 -0
  315. tnfr/utils/io.py +559 -0
  316. tnfr/utils/io.pyi +66 -0
  317. tnfr/{helpers → utils}/numeric.py +51 -24
  318. tnfr/utils/numeric.pyi +21 -0
  319. tnfr/validation/__init__.py +257 -0
  320. tnfr/validation/__init__.pyi +85 -0
  321. tnfr/validation/compatibility.py +460 -0
  322. tnfr/validation/compatibility.pyi +6 -0
  323. tnfr/validation/config.py +73 -0
  324. tnfr/validation/graph.py +139 -0
  325. tnfr/validation/graph.pyi +18 -0
  326. tnfr/validation/input_validation.py +755 -0
  327. tnfr/validation/invariants.py +712 -0
  328. tnfr/validation/rules.py +253 -0
  329. tnfr/validation/rules.pyi +44 -0
  330. tnfr/validation/runtime.py +279 -0
  331. tnfr/validation/runtime.pyi +28 -0
  332. tnfr/validation/sequence_validator.py +162 -0
  333. tnfr/validation/soft_filters.py +170 -0
  334. tnfr/validation/soft_filters.pyi +32 -0
  335. tnfr/validation/spectral.py +164 -0
  336. tnfr/validation/spectral.pyi +42 -0
  337. tnfr/validation/validator.py +1266 -0
  338. tnfr/validation/window.py +39 -0
  339. tnfr/validation/window.pyi +1 -0
  340. tnfr/visualization/__init__.py +98 -0
  341. tnfr/visualization/cascade_viz.py +256 -0
  342. tnfr/visualization/hierarchy.py +284 -0
  343. tnfr/visualization/sequence_plotter.py +784 -0
  344. tnfr/viz/__init__.py +60 -0
  345. tnfr/viz/matplotlib.py +278 -0
  346. tnfr/viz/matplotlib.pyi +35 -0
  347. tnfr-8.5.0.dist-info/METADATA +573 -0
  348. tnfr-8.5.0.dist-info/RECORD +353 -0
  349. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
  350. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
  351. tnfr/collections_utils.py +0 -300
  352. tnfr/config.py +0 -32
  353. tnfr/grammar.py +0 -344
  354. tnfr/graph_utils.py +0 -84
  355. tnfr/helpers/__init__.py +0 -71
  356. tnfr/import_utils.py +0 -228
  357. tnfr/json_utils.py +0 -162
  358. tnfr/logging_utils.py +0 -116
  359. tnfr/presets.py +0 -60
  360. tnfr/validators.py +0 -84
  361. tnfr/value_utils.py +0 -59
  362. tnfr-4.5.2.dist-info/METADATA +0 -379
  363. tnfr-4.5.2.dist-info/RECORD +0 -67
  364. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  365. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
tnfr/dynamics/dnfr.pyi ADDED
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from tnfr.types import DeltaNFRHook, TNFRGraph
6
+ from tnfr.utils.cache import DnfrCache as DnfrCache
7
+
8
+ __all__: tuple[str, ...]
9
+
10
+ def default_compute_delta_nfr(
11
+ G: TNFRGraph,
12
+ *,
13
+ cache_size: int | None = ...,
14
+ n_jobs: int | None = ...,
15
+ ) -> None: ...
16
+ def dnfr_epi_vf_mixed(G: TNFRGraph, *, n_jobs: int | None = ...) -> None: ...
17
+ def dnfr_laplacian(G: TNFRGraph, *, n_jobs: int | None = ...) -> None: ...
18
+ def dnfr_phase_only(G: TNFRGraph, *, n_jobs: int | None = ...) -> None: ...
19
+ def set_delta_nfr_hook(
20
+ G: TNFRGraph,
21
+ func: DeltaNFRHook,
22
+ *,
23
+ name: str | None = ...,
24
+ note: str | None = ...,
25
+ ) -> None: ...
26
+ def __getattr__(name: str) -> Any: ...
@@ -0,0 +1,225 @@
1
+ """Dynamic canonical limits based on network coherence.
2
+
3
+ This module implements dynamic canonical limits for EPI and νf that adapt
4
+ based on network coherence metrics. This addresses the theoretical question
5
+ of whether fixed limits contradict TNFR's self-organizing principles.
6
+
7
+ Theoretical Foundation
8
+ ----------------------
9
+ TNFR paradigm principles:
10
+ 1. **Operational fractality**: Patterns should scale without artificial bounds
11
+ 2. **Self-organization**: System should find its own natural limits
12
+ 3. **Coherence emergence**: Stability arises from resonance, not external constraints
13
+
14
+ Fixed limits may contradict these principles by imposing external constraints
15
+ that don't emerge from the system's own dynamics. Dynamic limits address this
16
+ by making bounds proportional to network coherence metrics.
17
+
18
+ Dynamic Limit Formulas
19
+ ----------------------
20
+ EPI effective maximum:
21
+ EPI_effective_max(t) = EPI_base_max × (1 + α × C(t) × Si_avg)
22
+
23
+ νf effective maximum:
24
+ νf_effective_max(t) = νf_base_max × (1 + β × R_kuramoto)
25
+
26
+ Where:
27
+ - C(t): Global coherence at time t (0 to 1)
28
+ - Si_avg: Average sense index across network (0 to 1+)
29
+ - R_kuramoto: Kuramoto order parameter (0 to 1)
30
+ - α, β: Expansion coefficients (default: 0.5, 0.3)
31
+
32
+ Theoretical Justification
33
+ --------------------------
34
+ 1. **Coherent networks** (high C(t), Si) can sustain higher EPI values
35
+ 2. **Synchronized networks** (high R_kuramoto) can sustain higher νf
36
+ 3. **Self-regulation** through coupling to system state
37
+ 4. **Fractality preservation** via proportional scaling
38
+ 5. **Safety bounds** via maximum expansion factors
39
+
40
+ References
41
+ ----------
42
+ - AGENTS.md: Section 3 (Canonical invariants)
43
+ - Issue fermga/TNFR-Python-Engine#2624: Theoretical review of limits
44
+ - TNFR.pdf: Nodal equation and coherence theory
45
+ """
46
+
47
+ from __future__ import annotations
48
+
49
+ from dataclasses import dataclass
50
+ from typing import TYPE_CHECKING
51
+
52
+ from ..alias import collect_attr
53
+ from ..constants.aliases import ALIAS_SI
54
+ from ..metrics.common import compute_coherence
55
+ from ..observers import kuramoto_order
56
+ from ..utils import get_numpy
57
+
58
+ if TYPE_CHECKING:
59
+ from ..types import TNFRGraph
60
+
61
+ __all__ = (
62
+ "DynamicLimits",
63
+ "DynamicLimitsConfig",
64
+ "compute_dynamic_limits",
65
+ "DEFAULT_SI_FALLBACK",
66
+ )
67
+
68
+ # Default fallback value for sense index when nodes have no Si attribute
69
+ # This represents a "neutral" sense index - neither high stability nor instability
70
+ DEFAULT_SI_FALLBACK = 0.5
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class DynamicLimitsConfig:
75
+ """Configuration for dynamic canonical limits.
76
+
77
+ Attributes:
78
+ base_epi_max: Base maximum for EPI (static fallback)
79
+ base_vf_max: Base maximum for νf (static fallback)
80
+ alpha: Expansion coefficient for EPI (via C(t) × Si)
81
+ beta: Expansion coefficient for νf (via R_kuramoto)
82
+ max_expansion_factor: Maximum allowed expansion multiplier
83
+ enabled: Whether dynamic limits are active
84
+ """
85
+
86
+ base_epi_max: float = 1.0
87
+ base_vf_max: float = 10.0
88
+ alpha: float = 0.5
89
+ beta: float = 0.3
90
+ max_expansion_factor: float = 3.0
91
+ enabled: bool = True
92
+
93
+
94
+ @dataclass(frozen=True)
95
+ class DynamicLimits:
96
+ """Result of dynamic limits computation.
97
+
98
+ Attributes:
99
+ epi_max_effective: Computed effective maximum for EPI
100
+ vf_max_effective: Computed effective maximum for νf
101
+ coherence: C(t) value used in computation
102
+ si_avg: Average Si value used in computation
103
+ kuramoto_r: Kuramoto order parameter used in computation
104
+ coherence_factor: Combined coherence metric (C(t) × Si_avg)
105
+ config: Configuration used for computation
106
+ """
107
+
108
+ epi_max_effective: float
109
+ vf_max_effective: float
110
+ coherence: float
111
+ si_avg: float
112
+ kuramoto_r: float
113
+ coherence_factor: float
114
+ config: DynamicLimitsConfig
115
+
116
+
117
+ def compute_dynamic_limits(
118
+ G: TNFRGraph,
119
+ config: DynamicLimitsConfig | None = None,
120
+ ) -> DynamicLimits:
121
+ """Compute dynamic canonical limits based on network state.
122
+
123
+ This function computes effective maximum values for EPI and νf that
124
+ adapt based on the network's coherence metrics. More coherent networks
125
+ are allowed higher values, reflecting their greater structural stability.
126
+
127
+ The computation respects TNFR invariants:
128
+ - Operator closure: bounds scale but remain finite
129
+ - Structural semantics: expansion proportional to coherence
130
+ - Self-organization: limits emerge from system state
131
+ - Fractality: proportional scaling preserves structure
132
+
133
+ Args:
134
+ G: TNFR graph with node attributes
135
+ config: Configuration for dynamic limits (uses defaults if None)
136
+
137
+ Returns:
138
+ DynamicLimits containing effective bounds and metrics
139
+
140
+ Examples:
141
+ >>> import networkx as nx
142
+ >>> G = nx.Graph()
143
+ >>> G.add_node(0, **{"νf": 1.0, "theta": 0.0, "EPI": 0.5, "Si": 0.7})
144
+ >>> limits = compute_dynamic_limits(G)
145
+ >>> limits.epi_max_effective >= 1.0 # May be expanded
146
+ True
147
+
148
+ >>> # With custom configuration
149
+ >>> config = DynamicLimitsConfig(alpha=0.8, beta=0.5)
150
+ >>> limits = compute_dynamic_limits(G, config)
151
+ >>> limits.config.alpha
152
+ 0.8
153
+
154
+ Notes:
155
+ - Returns base limits if graph is empty
156
+ - Clamps expansion to max_expansion_factor for safety
157
+ - If config.enabled is False, returns base limits only
158
+ - All metrics computed using existing TNFR functions
159
+ """
160
+ if config is None:
161
+ config = DynamicLimitsConfig()
162
+
163
+ # Handle empty graph
164
+ n_nodes = G.number_of_nodes()
165
+ if n_nodes == 0:
166
+ return DynamicLimits(
167
+ epi_max_effective=config.base_epi_max,
168
+ vf_max_effective=config.base_vf_max,
169
+ coherence=0.0,
170
+ si_avg=0.0,
171
+ kuramoto_r=0.0,
172
+ coherence_factor=0.0,
173
+ config=config,
174
+ )
175
+
176
+ # If dynamic limits disabled, return base values
177
+ if not config.enabled:
178
+ return DynamicLimits(
179
+ epi_max_effective=config.base_epi_max,
180
+ vf_max_effective=config.base_vf_max,
181
+ coherence=1.0,
182
+ si_avg=1.0,
183
+ kuramoto_r=1.0,
184
+ coherence_factor=1.0,
185
+ config=config,
186
+ )
187
+
188
+ # Compute coherence metrics
189
+ C_t = compute_coherence(G)
190
+
191
+ # Compute average sense index
192
+ np_module = get_numpy()
193
+ si_values = collect_attr(G, G.nodes, ALIAS_SI, DEFAULT_SI_FALLBACK, np=np_module)
194
+ if np_module is not None:
195
+ Si_avg = float(np_module.mean(si_values))
196
+ else:
197
+ Si_avg = sum(si_values) / len(si_values) if si_values else DEFAULT_SI_FALLBACK
198
+
199
+ # Compute Kuramoto order parameter
200
+ R_kuramoto = kuramoto_order(G)
201
+
202
+ # Compute coherence factor
203
+ coherence_factor = C_t * Si_avg
204
+
205
+ # Compute dynamic limits
206
+ epi_expansion = 1.0 + config.alpha * coherence_factor
207
+ vf_expansion = 1.0 + config.beta * R_kuramoto
208
+
209
+ # Apply maximum expansion factor as safety bound
210
+ epi_expansion = min(epi_expansion, config.max_expansion_factor)
211
+ vf_expansion = min(vf_expansion, config.max_expansion_factor)
212
+
213
+ # Compute effective limits
214
+ epi_max_effective = config.base_epi_max * epi_expansion
215
+ vf_max_effective = config.base_vf_max * vf_expansion
216
+
217
+ return DynamicLimits(
218
+ epi_max_effective=epi_max_effective,
219
+ vf_max_effective=vf_max_effective,
220
+ coherence=C_t,
221
+ si_avg=Si_avg,
222
+ kuramoto_r=R_kuramoto,
223
+ coherence_factor=coherence_factor,
224
+ config=config,
225
+ )
@@ -0,0 +1,252 @@
1
+ """Structural feedback loops for TNFR adaptive dynamics.
2
+
3
+ This module implements feedback loops that automatically adjust nodal parameters
4
+ based on current structural state. Feedback loops enable autonomous regulation
5
+ and homeostatic cycles as specified in TNFR dynamics theory.
6
+
7
+ The core principle: ΔNFR → operator selection → application → measure effect →
8
+ adjust thresholds, creating closed-loop structural regulation.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import TYPE_CHECKING, Any
14
+
15
+ if TYPE_CHECKING:
16
+ from ..types import TNFRGraph, NodeId
17
+
18
+ from ..alias import get_attr
19
+ from ..constants.aliases import ALIAS_DNFR, ALIAS_EPI, ALIAS_VF
20
+ from ..operators.registry import get_operator_class
21
+ from ..config.operator_names import (
22
+ COHERENCE,
23
+ DISSONANCE,
24
+ EMISSION,
25
+ SELF_ORGANIZATION,
26
+ SILENCE,
27
+ )
28
+
29
+ __all__ = ["StructuralFeedbackLoop"]
30
+
31
+
32
+ class StructuralFeedbackLoop:
33
+ """Feedback loop that adapts nodal dynamics based on structural state.
34
+
35
+ This class implements closed-loop regulation where the system measures its
36
+ current coherence state and selects appropriate operators to maintain
37
+ target coherence levels. The feedback loop adjusts thresholds adaptively
38
+ based on performance.
39
+
40
+ **Feedback Cycle:**
41
+
42
+ 1. **Measure**: Compute current coherence from ΔNFR and local state
43
+ 2. **Decide**: Select operator based on deviation from target
44
+ 3. **Act**: Apply selected operator
45
+ 4. **Learn**: Adjust thresholds based on achieved coherence
46
+
47
+ Parameters
48
+ ----------
49
+ graph : TNFRGraph
50
+ Graph containing the regulated node
51
+ node : NodeId
52
+ Identifier of the node to regulate
53
+ target_coherence : float, default=0.7
54
+ Target coherence level (C_target)
55
+ tau_adaptive : float, default=0.1
56
+ Initial bifurcation threshold (adaptive)
57
+ learning_rate : float, default=0.05
58
+ Rate of threshold adaptation
59
+ coherence_tolerance_low : float, default=0.2
60
+ Deviation below target that triggers stabilization
61
+ coherence_tolerance_high : float, default=0.1
62
+ Deviation above target that triggers exploration
63
+ dnfr_threshold : float, default=0.15
64
+ ΔNFR threshold for self-organization
65
+ epi_threshold : float, default=0.3
66
+ EPI threshold for emission
67
+
68
+ Attributes
69
+ ----------
70
+ G : TNFRGraph
71
+ Graph containing the node
72
+ node : NodeId
73
+ Node identifier
74
+ target_coherence : float
75
+ Target C(t) for homeostasis
76
+ tau_adaptive : float
77
+ Adaptive bifurcation threshold
78
+ learning_rate : float
79
+ Threshold adjustment rate
80
+ COHERENCE_TOL_LOW : float
81
+ Lower tolerance for coherence regulation
82
+ COHERENCE_TOL_HIGH : float
83
+ Upper tolerance for coherence regulation
84
+ DNFR_THRESHOLD : float
85
+ Threshold for self-organization activation
86
+ EPI_THRESHOLD : float
87
+ Threshold for emission activation
88
+
89
+ Examples
90
+ --------
91
+ >>> from tnfr.structural import create_nfr
92
+ >>> from tnfr.dynamics.feedback import StructuralFeedbackLoop
93
+ >>> G, node = create_nfr("test_node")
94
+ >>> loop = StructuralFeedbackLoop(G, node, target_coherence=0.7)
95
+ >>> operator_name = loop.regulate()
96
+ >>> loop.homeostatic_cycle(num_steps=5)
97
+ """
98
+
99
+ # Regulation thresholds
100
+ COHERENCE_TOL_LOW = 0.2 # Deviation below target triggers stabilization
101
+ COHERENCE_TOL_HIGH = 0.1 # Deviation above target triggers exploration
102
+ DNFR_THRESHOLD = 0.15 # ΔNFR threshold for self-organization
103
+ EPI_THRESHOLD = 0.3 # EPI threshold for emission
104
+
105
+ def __init__(
106
+ self,
107
+ graph: TNFRGraph,
108
+ node: NodeId,
109
+ target_coherence: float = 0.7,
110
+ tau_adaptive: float = 0.1,
111
+ learning_rate: float = 0.05,
112
+ coherence_tolerance_low: float = COHERENCE_TOL_LOW,
113
+ coherence_tolerance_high: float = COHERENCE_TOL_HIGH,
114
+ dnfr_threshold: float = DNFR_THRESHOLD,
115
+ epi_threshold: float = EPI_THRESHOLD,
116
+ ) -> None:
117
+ self.G = graph
118
+ self.node = node
119
+ self.target_coherence = float(target_coherence)
120
+ self.tau_adaptive = float(tau_adaptive)
121
+ self.learning_rate = float(learning_rate)
122
+ self.COHERENCE_TOL_LOW = float(coherence_tolerance_low)
123
+ self.COHERENCE_TOL_HIGH = float(coherence_tolerance_high)
124
+ self.DNFR_THRESHOLD = float(dnfr_threshold)
125
+ self.EPI_THRESHOLD = float(epi_threshold)
126
+
127
+ def regulate(self) -> str:
128
+ """Select appropriate operator based on current structural state.
129
+
130
+ Decision logic follows TNFR canonical regulation principles:
131
+
132
+ - **Low coherence**: Stabilize with IL (Coherence)
133
+ - **High coherence**: Explore with OZ (Dissonance)
134
+ - **High ΔNFR**: Self-organize with THOL
135
+ - **Low EPI**: Activate with AL (Emission)
136
+ - **Stable**: Consolidate with SHA (Silence)
137
+
138
+ Returns
139
+ -------
140
+ str
141
+ Operator name to apply
142
+
143
+ Notes
144
+ -----
145
+ The regulation logic implements structural decision-making based on
146
+ current node state. It avoids arbitrary choices by following TNFR
147
+ coherence principles.
148
+ """
149
+ dnfr = get_attr(self.G.nodes[self.node], ALIAS_DNFR, 0.0)
150
+ epi = get_attr(self.G.nodes[self.node], ALIAS_EPI, 0.0)
151
+
152
+ # Compute local coherence estimate
153
+ coherence = self._compute_local_coherence()
154
+
155
+ # Structural decision tree
156
+ if coherence < self.target_coherence - self.COHERENCE_TOL_LOW:
157
+ # Very low coherence → stabilize
158
+ return COHERENCE
159
+ elif coherence > self.target_coherence + self.COHERENCE_TOL_HIGH:
160
+ # High coherence → explore
161
+ return DISSONANCE
162
+ elif dnfr > self.DNFR_THRESHOLD:
163
+ # High reorganization pressure → self-organize
164
+ return SELF_ORGANIZATION
165
+ elif epi < self.EPI_THRESHOLD:
166
+ # Low activation → emit
167
+ return EMISSION
168
+ else:
169
+ # Stable state → consolidate
170
+ return SILENCE
171
+
172
+ def _compute_local_coherence(self) -> float:
173
+ """Estimate local coherence from ΔNFR.
174
+
175
+ Coherence is inversely proportional to reorganization pressure.
176
+ When ΔNFR is low, coherence is high (structure is stable).
177
+
178
+ Returns
179
+ -------
180
+ float
181
+ Estimated coherence in [0, 1]
182
+ """
183
+ dnfr = get_attr(self.G.nodes[self.node], ALIAS_DNFR, 0.0)
184
+ # Coherence inversely proportional to |ΔNFR|
185
+ return max(0.0, min(1.0, 1.0 - abs(dnfr)))
186
+
187
+ def adapt_thresholds(self, performance_metric: float) -> None:
188
+ """Adapt thresholds based on achieved performance.
189
+
190
+ Uses proportional feedback control to adjust tau_adaptive toward
191
+ target coherence. This implements learning in the feedback loop.
192
+
193
+ Parameters
194
+ ----------
195
+ performance_metric : float
196
+ Achieved coherence or other performance measure
197
+
198
+ Notes
199
+ -----
200
+ Threshold adaptation follows:
201
+
202
+ .. math::
203
+
204
+ \\tau_{t+1} = \\tau_t + \\alpha (C_{target} - C_{achieved})
205
+
206
+ where α is the learning rate.
207
+ """
208
+ error = self.target_coherence - performance_metric
209
+
210
+ # Proportional adjustment
211
+ self.tau_adaptive += self.learning_rate * error
212
+
213
+ # Clamp to valid range
214
+ self.tau_adaptive = max(0.05, min(0.25, self.tau_adaptive))
215
+
216
+ def homeostatic_cycle(self, num_steps: int = 10) -> None:
217
+ """Execute homeostatic regulation cycle.
218
+
219
+ Maintains target coherence through repeated sense-decide-act-learn cycles.
220
+
221
+ Parameters
222
+ ----------
223
+ num_steps : int, default=10
224
+ Number of regulation steps
225
+
226
+ Notes
227
+ -----
228
+ Each step:
229
+
230
+ 1. Measures current coherence
231
+ 2. Selects operator via regulate()
232
+ 3. Applies operator
233
+ 4. Measures new coherence
234
+ 5. Adapts thresholds
235
+
236
+ This implements autonomous structural homeostasis.
237
+ """
238
+ for step in range(num_steps):
239
+ # Measure state before
240
+ coherence_before = self._compute_local_coherence()
241
+
242
+ # Select and apply operator
243
+ operator_name = self.regulate()
244
+ operator_class = get_operator_class(operator_name)
245
+ operator = operator_class()
246
+ operator(self.G, self.node, tau=self.tau_adaptive)
247
+
248
+ # Measure state after
249
+ coherence_after = self._compute_local_coherence()
250
+
251
+ # Adapt thresholds based on performance
252
+ self.adapt_thresholds(coherence_after)
@@ -0,0 +1,24 @@
1
+ """Type stubs for tnfr.dynamics.feedback module."""
2
+
3
+ from typing import Any
4
+ from ..types import TNFRGraph, NodeId
5
+
6
+ class StructuralFeedbackLoop:
7
+ G: TNFRGraph
8
+ node: NodeId
9
+ target_coherence: float
10
+ tau_adaptive: float
11
+ learning_rate: float
12
+
13
+ def __init__(
14
+ self,
15
+ graph: TNFRGraph,
16
+ node: NodeId,
17
+ target_coherence: float = ...,
18
+ tau_adaptive: float = ...,
19
+ learning_rate: float = ...,
20
+ ) -> None: ...
21
+ def regulate(self) -> str: ...
22
+ def _compute_local_coherence(self) -> float: ...
23
+ def adapt_thresholds(self, performance_metric: float) -> None: ...
24
+ def homeostatic_cycle(self, num_steps: int = ...) -> None: ...