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,212 @@
1
+ """Core constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, field
6
+ from types import MappingProxyType
7
+ from typing import Any, Mapping
8
+
9
+ from ..compat.dataclass import dataclass
10
+
11
+ SELECTOR_THRESHOLD_DEFAULTS: Mapping[str, float] = MappingProxyType(
12
+ {
13
+ "si_hi": 0.66,
14
+ "si_lo": 0.33,
15
+ "dnfr_hi": 0.50,
16
+ "dnfr_lo": 0.10,
17
+ "accel_hi": 0.50,
18
+ "accel_lo": 0.10,
19
+ }
20
+ )
21
+
22
+
23
+ @dataclass(frozen=True, slots=True)
24
+ class CoreDefaults:
25
+ """Default parameters for the core engine.
26
+
27
+ The fields are exported via :data:`CORE_DEFAULTS` and may therefore appear
28
+ unused to static analysis tools such as Vulture.
29
+ """
30
+
31
+ DT: float = 1.0
32
+ INTEGRATOR_METHOD: str = "euler"
33
+ DT_MIN: float = 0.1
34
+ EPI_MIN: float = -1.0
35
+ EPI_MAX: float = 1.0
36
+ VF_MIN: float = 0.0
37
+ VF_MAX: float = 10.0
38
+ THETA_WRAP: bool = True
39
+ CLIP_MODE: str = "hard"
40
+ CLIP_SOFT_K: float = 3.0
41
+ DNFR_WEIGHTS: dict[str, float] = field(
42
+ default_factory=lambda: {
43
+ "phase": 0.34,
44
+ "epi": 0.33,
45
+ "vf": 0.33,
46
+ "topo": 0.0,
47
+ }
48
+ )
49
+ SI_WEIGHTS: dict[str, float] = field(
50
+ default_factory=lambda: {"alpha": 0.34, "beta": 0.33, "gamma": 0.33}
51
+ )
52
+ PHASE_K_GLOBAL: float = 0.05
53
+ PHASE_K_LOCAL: float = 0.15
54
+ PHASE_ADAPT: dict[str, Any] = field(
55
+ default_factory=lambda: {
56
+ "enabled": True,
57
+ "R_hi": 0.90,
58
+ "R_lo": 0.60,
59
+ "disr_hi": 0.50,
60
+ "disr_lo": 0.25,
61
+ "kG_min": 0.01,
62
+ "kG_max": 0.20,
63
+ "kL_min": 0.05,
64
+ "kL_max": 0.25,
65
+ "up": 0.10,
66
+ "down": 0.07,
67
+ }
68
+ )
69
+ UM_COMPAT_THRESHOLD: float = 0.75
70
+ UM_CANDIDATE_MODE: str = "sample"
71
+ UM_CANDIDATE_COUNT: int = 0
72
+ GLYPH_HYSTERESIS_WINDOW: int = 7
73
+ AL_MAX_LAG: int = 5
74
+ EN_MAX_LAG: int = 3
75
+ GLYPH_SELECTOR_MARGIN: float = 0.05
76
+ VF_ADAPT_TAU: int = 5
77
+ VF_ADAPT_MU: float = 0.1
78
+ HZ_STR_BRIDGE: float = 1.0
79
+ GLYPH_FACTORS: dict[str, float] = field(
80
+ default_factory=lambda: {
81
+ "AL_boost": 0.05,
82
+ "EN_mix": 0.25,
83
+ "IL_dnfr_factor": 0.7,
84
+ "OZ_dnfr_factor": 1.3,
85
+ "UM_theta_push": 0.25,
86
+ "UM_vf_sync": 0.10,
87
+ "UM_dnfr_reduction": 0.15,
88
+ "RA_epi_diff": 0.15,
89
+ "RA_vf_amplification": 0.05,
90
+ "RA_phase_coupling": 0.10, # Canonical phase alignment strengthening
91
+ "SHA_vf_factor": 0.85,
92
+ # Conservative scaling (1.05) prevents EPI overflow near boundaries
93
+ # while maintaining meaningful expansion capacity. Critical threshold:
94
+ # EPI × 1.05 = 1.0 when EPI ≈ 0.952 (vs previous threshold ≈ 0.870).
95
+ # This preserves structural identity at boundary (EPI_MAX as identity frontier).
96
+ "VAL_scale": 1.05,
97
+ "NUL_scale": 0.85,
98
+ # NUL canonical ΔNFR densification factor: implements structural pressure
99
+ # concentration due to volume reduction. When V' = V × 0.85, density increases
100
+ # by ~1.176× geometrically. Canonical value 1.35 accounts for nonlinear
101
+ # structural effects at smaller scales, per TNFR theory.
102
+ "NUL_densification_factor": 1.35,
103
+ "THOL_accel": 0.10,
104
+ # ZHIR now uses canonical transformation by default (θ → θ' based on ΔNFR)
105
+ # To use fixed shift, explicitly set ZHIR_theta_shift in graph
106
+ "ZHIR_theta_shift_factor": 0.3, # Canonical transformation magnitude
107
+ "NAV_jitter": 0.05,
108
+ "NAV_eta": 0.5,
109
+ "REMESH_alpha": 0.5,
110
+ }
111
+ )
112
+ GLYPH_THRESHOLDS: dict[str, float] = field(
113
+ default_factory=lambda: {"hi": 0.66, "lo": 0.33, "dnfr": 1e-3}
114
+ )
115
+ NAV_RANDOM: bool = True
116
+ NAV_STRICT: bool = False
117
+ RANDOM_SEED: int = 0
118
+ JITTER_CACHE_SIZE: int = 256
119
+ OZ_NOISE_MODE: bool = False
120
+ OZ_SIGMA: float = 0.1
121
+ GRAMMAR: dict[str, Any] = field(
122
+ default_factory=lambda: {
123
+ "window": 3,
124
+ "avoid_repeats": ["ZHIR", "OZ", "THOL"],
125
+ "force_dnfr": 0.60,
126
+ "force_accel": 0.60,
127
+ "fallbacks": {"ZHIR": "NAV", "OZ": "ZHIR", "THOL": "NAV"},
128
+ }
129
+ )
130
+ SELECTOR_WEIGHTS: dict[str, float] = field(
131
+ default_factory=lambda: {"w_si": 0.5, "w_dnfr": 0.3, "w_accel": 0.2}
132
+ )
133
+ SELECTOR_THRESHOLDS: dict[str, float] = field(
134
+ default_factory=lambda: dict(SELECTOR_THRESHOLD_DEFAULTS)
135
+ )
136
+ GAMMA: dict[str, Any] = field(
137
+ default_factory=lambda: {"type": "none", "beta": 0.0, "R0": 0.0}
138
+ )
139
+ CALLBACKS_STRICT: bool = False
140
+ VALIDATORS_STRICT: bool = False
141
+ PROGRAM_TRACE_MAXLEN: int = 50
142
+ HISTORY_MAXLEN: int = 0
143
+ NODAL_EQUATION_CLIP_AWARE: bool = True
144
+ NODAL_EQUATION_TOLERANCE: float = 1e-9
145
+ # THOL (Self-organization) vibrational metabolism parameters
146
+ THOL_METABOLIC_ENABLED: bool = True
147
+ THOL_METABOLIC_GRADIENT_WEIGHT: float = 0.15
148
+ THOL_METABOLIC_COMPLEXITY_WEIGHT: float = 0.10
149
+ THOL_BIFURCATION_THRESHOLD: float = 0.1
150
+
151
+ # THOL network propagation and cascade parameters
152
+ THOL_PROPAGATION_ENABLED: bool = True
153
+ THOL_MIN_COUPLING_FOR_PROPAGATION: float = 0.5
154
+ THOL_PROPAGATION_ATTENUATION: float = 0.7
155
+ THOL_CASCADE_MIN_NODES: int = 3
156
+
157
+ # THOL precondition thresholds
158
+ THOL_MIN_EPI: float = 0.2 # Minimum EPI for bifurcation
159
+ THOL_MIN_VF: float = 0.1 # Minimum structural frequency for reorganization
160
+ THOL_MIN_DEGREE: int = 1 # Minimum network connectivity
161
+ THOL_MIN_HISTORY_LENGTH: int = 3 # Minimum EPI history for acceleration computation
162
+ THOL_ALLOW_ISOLATED: bool = False # Require network context by default
163
+ THOL_MIN_COLLECTIVE_COHERENCE: float = 0.3 # Minimum collective coherence for sub-EPI ensemble
164
+
165
+ # VAL (Expansion) precondition thresholds
166
+ VAL_MAX_VF: float = 10.0 # Maximum structural frequency threshold
167
+ VAL_MIN_DNFR: float = 1e-6 # Minimum positive ΔNFR for coherent expansion (very low to minimize breaking changes)
168
+ VAL_MIN_EPI: float = 0.2 # Minimum EPI for coherent expansion base
169
+ VAL_CHECK_NETWORK_CAPACITY: bool = False # Optional network capacity validation
170
+ VAL_MAX_NETWORK_SIZE: int = 1000 # Maximum network size if capacity checking enabled
171
+
172
+ # VAL (Expansion) metric thresholds (Issue #2724)
173
+ VAL_BIFURCATION_THRESHOLD: float = 0.3 # Threshold for |∂²EPI/∂t²| bifurcation detection
174
+ VAL_MIN_COHERENCE: float = 0.5 # Minimum local coherence for healthy expansion
175
+ VAL_FRACTAL_RATIO_MIN: float = 0.5 # Minimum vf_growth/epi_growth ratio for fractality
176
+ VAL_FRACTAL_RATIO_MAX: float = 2.0 # Maximum vf_growth/epi_growth ratio for fractality
177
+
178
+
179
+ @dataclass(frozen=True, slots=True)
180
+ class RemeshDefaults:
181
+ """Default parameters for the remeshing subsystem.
182
+
183
+ As with :class:`CoreDefaults`, the fields are exported via
184
+ :data:`REMESH_DEFAULTS` and may look unused to static analysers.
185
+ """
186
+
187
+ EPS_DNFR_STABLE: float = 1e-3
188
+ EPS_DEPI_STABLE: float = 1e-3
189
+ FRACTION_STABLE_REMESH: float = 0.80
190
+ REMESH_COOLDOWN_WINDOW: int = 20
191
+ REMESH_COOLDOWN_TS: float = 0.0
192
+ REMESH_REQUIRE_STABILITY: bool = True
193
+ REMESH_STABILITY_WINDOW: int = 25
194
+ REMESH_MIN_PHASE_SYNC: float = 0.85
195
+ REMESH_MAX_GLYPH_DISR: float = 0.35
196
+ REMESH_MIN_SIGMA_MAG: float = 0.50
197
+ REMESH_MIN_KURAMOTO_R: float = 0.80
198
+ REMESH_MIN_SI_HI_FRAC: float = 0.50
199
+ REMESH_LOG_EVENTS: bool = True
200
+ REMESH_MODE: str = "knn"
201
+ REMESH_COMMUNITY_K: int = 2
202
+ REMESH_TAU_GLOBAL: int = 8
203
+ REMESH_TAU_LOCAL: int = 4
204
+ REMESH_ALPHA: float = 0.5
205
+ REMESH_ALPHA_HARD: bool = False
206
+
207
+
208
+ _core_defaults = asdict(CoreDefaults())
209
+ _remesh_defaults = asdict(RemeshDefaults())
210
+
211
+ CORE_DEFAULTS = MappingProxyType(_core_defaults)
212
+ REMESH_DEFAULTS = MappingProxyType(_remesh_defaults)
@@ -0,0 +1,33 @@
1
+ """Initialization constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from dataclasses import asdict
7
+
8
+ from ..compat.dataclass import dataclass
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class InitDefaults:
13
+ """Default parameters for node initialisation.
14
+
15
+ The fields are collected into :data:`INIT_DEFAULTS` and may therefore
16
+ appear unused to tools like Vulture.
17
+ """
18
+
19
+ INIT_RANDOM_PHASE: bool = True
20
+ INIT_THETA_MIN: float = -math.pi
21
+ INIT_THETA_MAX: float = math.pi
22
+ INIT_VF_MODE: str = "uniform"
23
+ INIT_VF_MIN: float | None = None
24
+ INIT_VF_MAX: float | None = None
25
+ INIT_VF_MEAN: float = 0.5
26
+ INIT_VF_STD: float = 0.15
27
+ INIT_VF_CLAMP_TO_LIMITS: bool = True
28
+ INIT_SI_MIN: float = 0.4
29
+ INIT_SI_MAX: float = 0.7
30
+ INIT_EPI_VALUE: float = 0.0
31
+
32
+
33
+ INIT_DEFAULTS = asdict(InitDefaults())
@@ -0,0 +1,104 @@
1
+ """Metric constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, field
6
+ from types import MappingProxyType
7
+ from typing import Any
8
+
9
+ from ..compat.dataclass import dataclass
10
+
11
+
12
+ @dataclass(frozen=True, slots=True)
13
+ class MetricDefaults:
14
+ """Default parameters for metric computation.
15
+
16
+ The fields are gathered into :data:`METRIC_DEFAULTS` and exposed through
17
+ read-only views below, so they may appear unused to static analysis tools.
18
+ """
19
+
20
+ PHASE_HISTORY_MAXLEN: int = 50
21
+ STOP_EARLY: dict[str, Any] = field(
22
+ default_factory=lambda: {
23
+ "enabled": False,
24
+ "window": 25,
25
+ "fraction": 0.90,
26
+ }
27
+ )
28
+ SIGMA: dict[str, Any] = field(
29
+ default_factory=lambda: {
30
+ "enabled": True,
31
+ "weight": "Si", # "Si" | "EPI" | "1"
32
+ "smooth": 0.0, # EMA over the global vector (0=off)
33
+ "history_key": "sigma_global",
34
+ "per_node": False,
35
+ }
36
+ )
37
+ TRACE: dict[str, Any] = field(
38
+ default_factory=lambda: {
39
+ "enabled": True,
40
+ "verbosity": "debug",
41
+ "history_key": "trace_meta",
42
+ }
43
+ )
44
+ METRICS: dict[str, Any] = field(
45
+ default_factory=lambda: {
46
+ "enabled": True,
47
+ "save_by_node": True,
48
+ "normalize_series": False,
49
+ "n_jobs": 1,
50
+ "verbosity": "debug",
51
+ }
52
+ )
53
+ GRAMMAR_CANON: dict[str, Any] = field(
54
+ default_factory=lambda: {
55
+ "enabled": True,
56
+ "zhir_requires_oz_window": 3,
57
+ "zhir_dnfr_min": 0.05,
58
+ "thol_min_len": 2,
59
+ "thol_max_len": 6,
60
+ "thol_close_dnfr": 0.15,
61
+ "si_high": 0.66,
62
+ }
63
+ )
64
+ COHERENCE: dict[str, Any] = field(
65
+ default_factory=lambda: {
66
+ "enabled": True,
67
+ "scope": "neighbors",
68
+ "weights": {"phase": 0.34, "epi": 0.33, "vf": 0.20, "si": 0.13},
69
+ "self_on_diag": True,
70
+ "store_mode": "sparse",
71
+ "threshold": 0.0,
72
+ "n_jobs": 1,
73
+ "history_key": "W_sparse",
74
+ "Wi_history_key": "W_i",
75
+ "stats_history_key": "W_stats",
76
+ }
77
+ )
78
+ DIAGNOSIS: dict[str, Any] = field(
79
+ default_factory=lambda: {
80
+ "enabled": True,
81
+ "window": 16,
82
+ "history_key": "nodal_diag",
83
+ "stable": {"Rloc_hi": 0.80, "dnfr_lo": 0.20, "persist": 3},
84
+ "dissonance": {"Rloc_lo": 0.40, "dnfr_hi": 0.50, "persist": 3},
85
+ "transition": {"persist": 2},
86
+ "compute_symmetry": True,
87
+ "include_typology": False,
88
+ "advice": {
89
+ "stable": ["Coherence", "Coupling", "Resonance"],
90
+ "transition": ["Transition", "Resonance", "Self-organisation"],
91
+ "dissonant": ["Silence", "Contraction", "Mutation"],
92
+ },
93
+ }
94
+ )
95
+
96
+
97
+ METRIC_DEFAULTS = asdict(MetricDefaults())
98
+
99
+ SIGMA = MappingProxyType(METRIC_DEFAULTS["SIGMA"])
100
+ TRACE = MappingProxyType(METRIC_DEFAULTS["TRACE"])
101
+ METRICS = MappingProxyType(METRIC_DEFAULTS["METRICS"])
102
+ GRAMMAR_CANON = MappingProxyType(METRIC_DEFAULTS["GRAMMAR_CANON"])
103
+ COHERENCE = MappingProxyType(METRIC_DEFAULTS["COHERENCE"])
104
+ DIAGNOSIS = MappingProxyType(METRIC_DEFAULTS["DIAGNOSIS"])
@@ -0,0 +1,81 @@
1
+ """Math feature flag configuration helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from contextlib import contextmanager
7
+ from dataclasses import dataclass, replace
8
+ from typing import Iterator
9
+
10
+ __all__ = ("MathFeatureFlags", "get_flags", "context_flags")
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class MathFeatureFlags:
15
+ """Toggle optional mathematical behaviours in the engine."""
16
+
17
+ enable_math_validation: bool = False
18
+ enable_math_dynamics: bool = False
19
+ log_performance: bool = False
20
+ math_backend: str = "numpy"
21
+
22
+
23
+ _TRUE_VALUES = {"1", "true", "on", "yes", "y", "t"}
24
+ _FALSE_VALUES = {"0", "false", "off", "no", "n", "f"}
25
+
26
+ _BASE_FLAGS: MathFeatureFlags | None = None
27
+ _FLAGS_STACK: list[MathFeatureFlags] = []
28
+
29
+
30
+ def _parse_env_flag(name: str, default: bool) -> bool:
31
+ value = os.getenv(name)
32
+ if value is None:
33
+ return default
34
+ lowered = value.strip().lower()
35
+ if lowered in _TRUE_VALUES:
36
+ return True
37
+ if lowered in _FALSE_VALUES:
38
+ return False
39
+ return default
40
+
41
+
42
+ def _load_base_flags() -> MathFeatureFlags:
43
+ global _BASE_FLAGS
44
+ if _BASE_FLAGS is None:
45
+ backend = os.getenv("TNFR_MATH_BACKEND")
46
+ backend_choice = backend.strip() if backend else "numpy"
47
+ _BASE_FLAGS = MathFeatureFlags(
48
+ enable_math_validation=_parse_env_flag(
49
+ "TNFR_ENABLE_MATH_VALIDATION", False
50
+ ),
51
+ enable_math_dynamics=_parse_env_flag("TNFR_ENABLE_MATH_DYNAMICS", False),
52
+ log_performance=_parse_env_flag("TNFR_LOG_PERF", False),
53
+ math_backend=backend_choice or "numpy",
54
+ )
55
+ return _BASE_FLAGS
56
+
57
+
58
+ def get_flags() -> MathFeatureFlags:
59
+ """Return the currently active feature flags."""
60
+
61
+ if _FLAGS_STACK:
62
+ return _FLAGS_STACK[-1]
63
+ return _load_base_flags()
64
+
65
+
66
+ @contextmanager
67
+ def context_flags(**overrides: bool) -> Iterator[MathFeatureFlags]:
68
+ """Temporarily override math feature flags."""
69
+
70
+ invalid = set(overrides) - set(MathFeatureFlags.__annotations__)
71
+ if invalid:
72
+ invalid_names = ", ".join(sorted(invalid))
73
+ raise TypeError(f"Unknown flag overrides: {invalid_names}")
74
+
75
+ previous = get_flags()
76
+ next_flags = replace(previous, **overrides)
77
+ _FLAGS_STACK.append(next_flags)
78
+ try:
79
+ yield next_flags
80
+ finally:
81
+ _FLAGS_STACK.pop()
@@ -0,0 +1,16 @@
1
+ from contextlib import contextmanager
2
+ from dataclasses import dataclass
3
+ from typing import Iterator
4
+
5
+ __all__ = ["MathFeatureFlags", "get_flags", "context_flags"]
6
+
7
+ @dataclass(frozen=True)
8
+ class MathFeatureFlags:
9
+ enable_math_validation: bool = ...
10
+ enable_math_dynamics: bool = ...
11
+ log_performance: bool = ...
12
+ math_backend: str = ...
13
+
14
+ def get_flags() -> MathFeatureFlags: ...
15
+ @contextmanager
16
+ def context_flags(**overrides: bool) -> Iterator[MathFeatureFlags]: ...
@@ -0,0 +1,31 @@
1
+ """Shared alias constants for TNFR attributes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from . import get_aliases
6
+
7
+ ALIAS_VF = get_aliases("VF")
8
+ ALIAS_THETA = get_aliases("THETA")
9
+ ALIAS_DNFR = get_aliases("DNFR")
10
+ ALIAS_EPI = get_aliases("EPI")
11
+ ALIAS_EPI_KIND = get_aliases("EPI_KIND")
12
+ ALIAS_SI = get_aliases("SI")
13
+ ALIAS_DEPI = get_aliases("DEPI")
14
+ ALIAS_D2EPI = get_aliases("D2EPI")
15
+ ALIAS_DVF = get_aliases("DVF")
16
+ ALIAS_D2VF = get_aliases("D2VF")
17
+ ALIAS_DSI = get_aliases("DSI")
18
+
19
+ __all__ = [
20
+ "ALIAS_VF",
21
+ "ALIAS_THETA",
22
+ "ALIAS_DNFR",
23
+ "ALIAS_EPI",
24
+ "ALIAS_EPI_KIND",
25
+ "ALIAS_SI",
26
+ "ALIAS_DEPI",
27
+ "ALIAS_D2EPI",
28
+ "ALIAS_DVF",
29
+ "ALIAS_D2VF",
30
+ "ALIAS_DSI",
31
+ ]
tnfr/config/init.py ADDED
@@ -0,0 +1,77 @@
1
+ """Core configuration helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from pathlib import Path
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from ..utils import read_structured_file
10
+
11
+ if TYPE_CHECKING: # pragma: no cover - only for type checkers
12
+ import networkx as nx
13
+
14
+ __all__ = ("load_config", "apply_config")
15
+
16
+
17
+ def load_config(
18
+ path: str | Path,
19
+ *,
20
+ base_dir: str | Path | None = None,
21
+ ) -> Mapping[str, Any]:
22
+ """Read a JSON/YAML file and return a mapping with parameters.
23
+
24
+ Parameters
25
+ ----------
26
+ path : str | Path
27
+ Path to the configuration file.
28
+ base_dir : str | Path | None, optional
29
+ Base directory to restrict config file access. If provided, the
30
+ resolved path must stay within this directory (prevents path traversal).
31
+
32
+ Returns
33
+ -------
34
+ Mapping[str, Any]
35
+ Configuration parameters as a mapping.
36
+
37
+ Raises
38
+ ------
39
+ ValueError
40
+ If the configuration file is invalid or contains unsafe patterns.
41
+ PathTraversalError
42
+ If path traversal is detected when base_dir is provided.
43
+ StructuredFileError
44
+ If the file cannot be read or parsed.
45
+ """
46
+ path_obj = path if isinstance(path, Path) else Path(path)
47
+ data = read_structured_file(path_obj, base_dir=base_dir)
48
+ if not isinstance(data, Mapping):
49
+ raise ValueError("Configuration file must contain an object")
50
+ return data
51
+
52
+
53
+ def apply_config(
54
+ G: "nx.Graph",
55
+ path: str | Path,
56
+ *,
57
+ base_dir: str | Path | None = None,
58
+ ) -> None:
59
+ """Inject parameters from ``path`` into ``G.graph``.
60
+
61
+ Uses inject_defaults from this module to keep canonical default
62
+ semantics.
63
+
64
+ Parameters
65
+ ----------
66
+ G : nx.Graph
67
+ The graph to configure.
68
+ path : str | Path
69
+ Path to the configuration file.
70
+ base_dir : str | Path | None, optional
71
+ Base directory to restrict config file access.
72
+ """
73
+ # Import inject_defaults locally to avoid circular import
74
+ from . import inject_defaults
75
+
76
+ cfg = load_config(path, base_dir=base_dir)
77
+ inject_defaults(G, cfg, override=True)
tnfr/config/init.pyi ADDED
@@ -0,0 +1,8 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ apply_config: Any
8
+ load_config: Any