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
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ from .._compat import TypeAlias as TypeAlias
4
+ from ..alias import (
5
+ collect_attr as collect_attr,
6
+ collect_theta_attr as collect_theta_attr,
7
+ get_attr as get_attr,
8
+ set_attr as set_attr,
9
+ )
10
+ from ..constants import get_param as get_param
11
+ from ..constants.aliases import (
12
+ ALIAS_D2VF as ALIAS_D2VF,
13
+ ALIAS_DEPI as ALIAS_DEPI,
14
+ ALIAS_DNFR as ALIAS_DNFR,
15
+ ALIAS_DSI as ALIAS_DSI,
16
+ ALIAS_DVF as ALIAS_DVF,
17
+ ALIAS_EPI as ALIAS_EPI,
18
+ ALIAS_SI as ALIAS_SI,
19
+ ALIAS_VF as ALIAS_VF,
20
+ )
21
+ from ..glyph_history import (
22
+ append_metric as append_metric,
23
+ ensure_history as ensure_history,
24
+ )
25
+ from ..observers import (
26
+ DEFAULT_GLYPH_LOAD_SPAN as DEFAULT_GLYPH_LOAD_SPAN,
27
+ DEFAULT_WBAR_SPAN as DEFAULT_WBAR_SPAN,
28
+ glyph_load as glyph_load,
29
+ kuramoto_order as kuramoto_order,
30
+ phase_sync as phase_sync,
31
+ )
32
+ from ..sense import sigma_vector as sigma_vector
33
+ from ..types import (
34
+ CoherenceMetric as CoherenceMetric,
35
+ FloatArray as FloatArray,
36
+ FloatMatrix as FloatMatrix,
37
+ GlyphLoadDistribution as GlyphLoadDistribution,
38
+ HistoryState as HistoryState,
39
+ NodeId as NodeId,
40
+ ParallelWijPayload as ParallelWijPayload,
41
+ SigmaVector as SigmaVector,
42
+ TNFRGraph as TNFRGraph,
43
+ )
44
+ from ..utils import (
45
+ CallbackEvent as CallbackEvent,
46
+ callback_manager as callback_manager,
47
+ clamp01 as clamp01,
48
+ ensure_node_index_map as ensure_node_index_map,
49
+ get_logger as get_logger,
50
+ get_numpy as get_numpy,
51
+ normalize_weights as normalize_weights,
52
+ resolve_chunk_size as resolve_chunk_size,
53
+ )
54
+ from .common import (
55
+ compute_coherence as compute_coherence,
56
+ min_max_range as min_max_range,
57
+ )
58
+ from .trig_cache import (
59
+ compute_theta_trig as compute_theta_trig,
60
+ get_trig_cache as get_trig_cache,
61
+ )
62
+ from _typeshed import Incomplete
63
+ from collections.abc import Callable, Mapping, Sequence
64
+ from dataclasses import dataclass
65
+ from types import ModuleType
66
+ from typing import Any
67
+
68
+ logger: Incomplete
69
+ GLYPH_LOAD_STABILIZERS_KEY: str
70
+
71
+ @dataclass
72
+ class SimilarityInputs:
73
+ th_vals: Sequence[float]
74
+ epi_vals: Sequence[float]
75
+ vf_vals: Sequence[float]
76
+ si_vals: Sequence[float]
77
+ cos_vals: Sequence[float] | None = ...
78
+ sin_vals: Sequence[float] | None = ...
79
+
80
+ CoherenceMatrixDense = list[list[float]]
81
+ CoherenceMatrixSparse = list[tuple[int, int, float]]
82
+ CoherenceMatrixPayload = CoherenceMatrixDense | CoherenceMatrixSparse
83
+ PhaseSyncWeights: TypeAlias
84
+ SimilarityComponents = tuple[float, float, float, float]
85
+ VectorizedComponents: TypeAlias
86
+ ScalarOrArray: TypeAlias
87
+ StabilityChunkArgs = tuple[
88
+ Sequence[float],
89
+ Sequence[float],
90
+ Sequence[float],
91
+ Sequence[float | None],
92
+ Sequence[float],
93
+ Sequence[float | None],
94
+ Sequence[float | None],
95
+ float,
96
+ float,
97
+ float,
98
+ ]
99
+ StabilityChunkResult = tuple[
100
+ int, int, float, float, list[float], list[float], list[float]
101
+ ]
102
+ MetricValue: TypeAlias
103
+ MetricProvider = Callable[[], MetricValue]
104
+ MetricRecord: TypeAlias
105
+
106
+ def compute_wij_phase_epi_vf_si(
107
+ inputs: SimilarityInputs,
108
+ i: int | None = None,
109
+ j: int | None = None,
110
+ *,
111
+ trig: Any | None = None,
112
+ G: TNFRGraph | None = None,
113
+ nodes: Sequence[NodeId] | None = None,
114
+ epi_range: float = 1.0,
115
+ vf_range: float = 1.0,
116
+ np: ModuleType | None = None,
117
+ ) -> SimilarityComponents | VectorizedComponents: ...
118
+ def coherence_matrix(
119
+ G: TNFRGraph, use_numpy: bool | None = None, *, n_jobs: int | None = None
120
+ ) -> tuple[list[NodeId] | None, CoherenceMatrixPayload | None]: ...
121
+ def local_phase_sync_weighted(
122
+ G: TNFRGraph,
123
+ n: NodeId,
124
+ nodes_order: Sequence[NodeId] | None = None,
125
+ W_row: PhaseSyncWeights | None = None,
126
+ node_to_index: Mapping[NodeId, int] | None = None,
127
+ ) -> float: ...
128
+ def local_phase_sync(G: TNFRGraph, n: NodeId) -> float: ...
129
+ def register_coherence_callbacks(G: TNFRGraph) -> None: ...
tnfr/metrics/common.py CHANGED
@@ -6,17 +6,11 @@ from types import MappingProxyType
6
6
  from typing import Any, Iterable, Mapping, Sequence
7
7
 
8
8
  from ..alias import collect_attr, get_attr, multi_recompute_abs_max
9
- from ..collections_utils import normalize_weights
10
- from ..constants import DEFAULTS, get_aliases
11
- from ..cache import edge_version_cache
12
- from ..helpers.numeric import clamp01, kahan_sum_nd
13
- from ..import_utils import get_numpy
14
- from ..types import GraphLike
15
-
16
- ALIAS_DNFR = get_aliases("DNFR")
17
- ALIAS_D2EPI = get_aliases("D2EPI")
18
- ALIAS_DEPI = get_aliases("DEPI")
19
- ALIAS_VF = get_aliases("VF")
9
+ from ..constants import DEFAULTS
10
+ from ..constants.aliases import ALIAS_D2EPI, ALIAS_DEPI, ALIAS_DNFR, ALIAS_VF
11
+ from ..utils import clamp01, kahan_sum_nd, normalize_optional_int
12
+ from ..types import GraphLike, NodeAttrMap
13
+ from ..utils import edge_version_cache, get_numpy, normalize_weights
20
14
 
21
15
  __all__ = (
22
16
  "GraphLike",
@@ -27,6 +21,7 @@ __all__ = (
27
21
  "merge_graph_weights",
28
22
  "merge_and_normalize_weights",
29
23
  "min_max_range",
24
+ "_coerce_jobs",
30
25
  "_get_vf_dnfr_max",
31
26
  )
32
27
 
@@ -72,7 +67,10 @@ def ensure_neighbors_map(G: GraphLike) -> Mapping[Any, Sequence[Any]]:
72
67
  def merge_graph_weights(G: GraphLike, key: str) -> dict[str, float]:
73
68
  """Merge default weights for ``key`` with any graph overrides."""
74
69
 
75
- return {**DEFAULTS[key], **G.graph.get(key, {})}
70
+ overrides = G.graph.get(key, {})
71
+ if overrides is None or not isinstance(overrides, Mapping):
72
+ overrides = {}
73
+ return {**DEFAULTS[key], **overrides}
76
74
 
77
75
 
78
76
  def merge_and_normalize_weights(
@@ -103,7 +101,7 @@ def compute_dnfr_accel_max(G: GraphLike) -> dict[str, float]:
103
101
  )
104
102
 
105
103
 
106
- def normalize_dnfr(nd: Mapping[str, Any], max_val: float) -> float:
104
+ def normalize_dnfr(nd: NodeAttrMap, max_val: float) -> float:
107
105
  """Normalise ``|ΔNFR|`` using ``max_val``."""
108
106
 
109
107
  if max_val <= 0:
@@ -137,9 +135,7 @@ def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]:
137
135
  vfmax = G.graph.get("_vfmax")
138
136
  dnfrmax = G.graph.get("_dnfrmax")
139
137
  if vfmax is None or dnfrmax is None:
140
- maxes = multi_recompute_abs_max(
141
- G, {"_vfmax": ALIAS_VF, "_dnfrmax": ALIAS_DNFR}
142
- )
138
+ maxes = multi_recompute_abs_max(G, {"_vfmax": ALIAS_VF, "_dnfrmax": ALIAS_DNFR})
143
139
  if vfmax is None:
144
140
  vfmax = maxes["_vfmax"]
145
141
  if dnfrmax is None:
@@ -149,3 +145,14 @@ def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]:
149
145
  vfmax = 1.0 if vfmax == 0 else vfmax
150
146
  dnfrmax = 1.0 if dnfrmax == 0 else dnfrmax
151
147
  return float(vfmax), float(dnfrmax)
148
+
149
+
150
+ def _coerce_jobs(raw_jobs: Any | None) -> int | None:
151
+ """Normalise parallel job hints shared by metrics modules."""
152
+
153
+ return normalize_optional_int(
154
+ raw_jobs,
155
+ allow_non_positive=False,
156
+ strict=False,
157
+ sentinels=None,
158
+ )
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable, Mapping, Sequence
4
+ from typing import Any, Literal, overload
5
+
6
+ from ..types import GraphLike, NodeAttrMap
7
+
8
+ __all__: tuple[str, ...]
9
+
10
+ def __getattr__(name: str) -> Any: ...
11
+ @overload
12
+ def compute_coherence(G: GraphLike, *, return_means: Literal[False] = ...) -> float: ...
13
+ @overload
14
+ def compute_coherence(
15
+ G: GraphLike, *, return_means: Literal[True]
16
+ ) -> tuple[float, float, float]: ...
17
+ def compute_coherence(
18
+ G: GraphLike, *, return_means: bool = ...
19
+ ) -> float | tuple[float, float, float]: ...
20
+ def ensure_neighbors_map(G: GraphLike) -> Mapping[Any, Sequence[Any]]: ...
21
+ def merge_graph_weights(G: GraphLike, key: str) -> dict[str, float]: ...
22
+ def merge_and_normalize_weights(
23
+ G: GraphLike,
24
+ key: str,
25
+ fields: Sequence[str],
26
+ *,
27
+ default: float = ...,
28
+ ) -> dict[str, float]: ...
29
+ def compute_dnfr_accel_max(G: GraphLike) -> dict[str, float]: ...
30
+ def normalize_dnfr(nd: NodeAttrMap, max_val: float) -> float: ...
31
+ def min_max_range(
32
+ values: Iterable[float], *, default: tuple[float, float] = ...
33
+ ) -> tuple[float, float]: ...
34
+ def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]: ...
35
+ def _coerce_jobs(raw_jobs: Any | None) -> int | None: ...
tnfr/metrics/core.py CHANGED
@@ -2,13 +2,34 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any
5
+ from collections.abc import Mapping, MutableMapping
6
+ from typing import Any, NamedTuple, cast
6
7
 
7
- from ..callback_utils import CallbackEvent, callback_manager
8
+ from ..utils import CallbackEvent, callback_manager
8
9
  from ..constants import get_param
9
10
  from ..glyph_history import append_metric, ensure_history
10
- from ..logging_utils import get_logger
11
+ from ..telemetry import ensure_nu_f_telemetry
12
+ from ..units import get_hz_bridge
13
+ from ..telemetry.verbosity import (
14
+ TELEMETRY_VERBOSITY_DEFAULT,
15
+ TELEMETRY_VERBOSITY_LEVELS,
16
+ TelemetryVerbosity,
17
+ )
18
+ from ..types import (
19
+ GlyphSelector,
20
+ NodeId,
21
+ SelectorPreselectionChoices,
22
+ SelectorPreselectionMetrics,
23
+ SelectorPreselectionPayload,
24
+ TNFRGraph,
25
+ TraceCallback,
26
+ TraceFieldFn,
27
+ TraceFieldMap,
28
+ TraceFieldRegistry,
29
+ )
30
+ from ..utils import get_logger
11
31
  from .coherence import (
32
+ GLYPH_LOAD_STABILIZERS_KEY,
12
33
  _aggregate_si,
13
34
  _track_stability,
14
35
  _update_coherence,
@@ -17,18 +38,28 @@ from .coherence import (
17
38
  register_coherence_callbacks,
18
39
  )
19
40
  from .diagnosis import register_diagnosis_callbacks
20
- from .glyph_timing import _compute_advanced_metrics
41
+ from .glyph_timing import GlyphMetricsHistory, _compute_advanced_metrics
21
42
  from .reporting import (
22
43
  Tg_by_node,
23
44
  Tg_global,
24
- glyphogram_series,
25
45
  glyph_top,
46
+ glyphogram_series,
26
47
  latency_series,
27
48
  )
28
49
 
29
50
  logger = get_logger(__name__)
30
51
 
31
52
  __all__ = [
53
+ "TNFRGraph",
54
+ "NodeId",
55
+ "GlyphSelector",
56
+ "SelectorPreselectionMetrics",
57
+ "SelectorPreselectionChoices",
58
+ "SelectorPreselectionPayload",
59
+ "TraceCallback",
60
+ "TraceFieldFn",
61
+ "TraceFieldMap",
62
+ "TraceFieldRegistry",
32
63
  "_metrics_step",
33
64
  "register_metrics_callbacks",
34
65
  "Tg_global",
@@ -39,32 +70,176 @@ __all__ = [
39
70
  ]
40
71
 
41
72
 
42
- def _metrics_step(G, ctx: dict[str, Any] | None = None):
73
+ class MetricsVerbositySpec(NamedTuple):
74
+ """Runtime configuration for metrics verbosity tiers."""
75
+
76
+ name: str
77
+ enable_phase_sync: bool
78
+ enable_sigma: bool
79
+ enable_aggregate_si: bool
80
+ enable_advanced: bool
81
+ attach_coherence_hooks: bool
82
+ attach_diagnosis_hooks: bool
83
+ enable_nu_f: bool
84
+
85
+
86
+ METRICS_VERBOSITY_DEFAULT = TELEMETRY_VERBOSITY_DEFAULT
87
+
88
+ _METRICS_VERBOSITY_PRESETS: dict[str, MetricsVerbositySpec] = {}
89
+
90
+
91
+ def _register_metrics_preset(spec: MetricsVerbositySpec) -> None:
92
+ if spec.name not in TELEMETRY_VERBOSITY_LEVELS:
93
+ raise ValueError(
94
+ "Unknown metrics verbosity '%s'; use %s"
95
+ % (
96
+ spec.name,
97
+ ", ".join(TELEMETRY_VERBOSITY_LEVELS),
98
+ )
99
+ )
100
+ _METRICS_VERBOSITY_PRESETS[spec.name] = spec
101
+
102
+
103
+ _register_metrics_preset(
104
+ MetricsVerbositySpec(
105
+ name=TelemetryVerbosity.BASIC.value,
106
+ enable_phase_sync=False,
107
+ enable_sigma=False,
108
+ enable_aggregate_si=False,
109
+ enable_advanced=False,
110
+ attach_coherence_hooks=False,
111
+ attach_diagnosis_hooks=False,
112
+ enable_nu_f=False,
113
+ )
114
+ )
115
+
116
+ _detailed_spec = MetricsVerbositySpec(
117
+ name=TelemetryVerbosity.DETAILED.value,
118
+ enable_phase_sync=True,
119
+ enable_sigma=True,
120
+ enable_aggregate_si=True,
121
+ enable_advanced=False,
122
+ attach_coherence_hooks=True,
123
+ attach_diagnosis_hooks=False,
124
+ enable_nu_f=True,
125
+ )
126
+ _register_metrics_preset(_detailed_spec)
127
+ _register_metrics_preset(
128
+ _detailed_spec._replace(
129
+ name=TelemetryVerbosity.DEBUG.value,
130
+ enable_advanced=True,
131
+ attach_diagnosis_hooks=True,
132
+ enable_nu_f=True,
133
+ )
134
+ )
135
+
136
+ _METRICS_BASE_HISTORY_KEYS = ("C_steps", "stable_frac", "delta_Si", "B")
137
+ _METRICS_PHASE_HISTORY_KEYS = ("phase_sync", "kuramoto_R")
138
+ _METRICS_SIGMA_HISTORY_KEYS = (
139
+ GLYPH_LOAD_STABILIZERS_KEY,
140
+ "glyph_load_disr",
141
+ "sense_sigma_x",
142
+ "sense_sigma_y",
143
+ "sense_sigma_mag",
144
+ "sense_sigma_angle",
145
+ )
146
+ _METRICS_SI_HISTORY_KEYS = ("Si_mean", "Si_hi_frac", "Si_lo_frac")
147
+ _METRICS_NU_F_HISTORY_KEYS = (
148
+ "nu_f_rate_hz_str",
149
+ "nu_f_rate_hz",
150
+ "nu_f_ci_lower_hz_str",
151
+ "nu_f_ci_upper_hz_str",
152
+ "nu_f_ci_lower_hz",
153
+ "nu_f_ci_upper_hz",
154
+ )
155
+
156
+
157
+ def _update_nu_f_snapshot(
158
+ G: TNFRGraph,
159
+ hist: MutableMapping[str, Any],
160
+ *,
161
+ record_history: bool,
162
+ ) -> None:
163
+ """Refresh νf telemetry snapshot and optionally persist it in history."""
164
+
165
+ accumulator = ensure_nu_f_telemetry(G, confidence_level=None)
166
+ snapshot = accumulator.snapshot(graph=G)
167
+ payload = snapshot.as_payload()
168
+ bridge: float | None
169
+ try:
170
+ bridge = float(get_hz_bridge(G))
171
+ except (TypeError, ValueError, KeyError):
172
+ bridge = None
173
+ else:
174
+ payload["hz_bridge"] = bridge
175
+
176
+ telemetry = G.graph.setdefault("telemetry", {})
177
+ if not isinstance(telemetry, MutableMapping):
178
+ telemetry = {}
179
+ G.graph["telemetry"] = telemetry
180
+ telemetry["nu_f_snapshot"] = payload
181
+ telemetry["nu_f_bridge"] = bridge
182
+
183
+ if record_history:
184
+ append_metric(hist, "nu_f_rate_hz_str", snapshot.rate_hz_str)
185
+ append_metric(hist, "nu_f_rate_hz", snapshot.rate_hz)
186
+ append_metric(hist, "nu_f_ci_lower_hz_str", snapshot.ci_lower_hz_str)
187
+ append_metric(hist, "nu_f_ci_upper_hz_str", snapshot.ci_upper_hz_str)
188
+ append_metric(hist, "nu_f_ci_lower_hz", snapshot.ci_lower_hz)
189
+ append_metric(hist, "nu_f_ci_upper_hz", snapshot.ci_upper_hz)
190
+
191
+ G.graph["_nu_f_snapshot_payload"] = payload
192
+
193
+
194
+ def _resolve_metrics_verbosity(cfg: Mapping[str, Any]) -> MetricsVerbositySpec:
195
+ """Return the preset matching ``cfg['verbosity']``."""
196
+
197
+ raw_value = cfg.get("verbosity", METRICS_VERBOSITY_DEFAULT)
198
+ key = str(raw_value).lower()
199
+ spec = _METRICS_VERBOSITY_PRESETS.get(key)
200
+ if spec is not None:
201
+ return spec
202
+ logger.warning(
203
+ "Unknown METRICS verbosity '%s'; falling back to '%s'",
204
+ raw_value,
205
+ METRICS_VERBOSITY_DEFAULT,
206
+ )
207
+ return _METRICS_VERBOSITY_PRESETS[METRICS_VERBOSITY_DEFAULT]
208
+
209
+
210
+ def _metrics_step(G: TNFRGraph, ctx: dict[str, Any] | None = None) -> None:
43
211
  """Update operational TNFR metrics per step."""
44
212
 
45
213
  del ctx
46
214
 
47
- cfg = get_param(G, "METRICS")
215
+ cfg = cast(Mapping[str, Any], get_param(G, "METRICS"))
48
216
  if not cfg.get("enabled", True):
49
217
  return
50
218
 
219
+ spec = _resolve_metrics_verbosity(cfg)
51
220
  hist = ensure_history(G)
221
+ if "glyph_load_estab" in hist:
222
+ raise ValueError(
223
+ "History payloads using 'glyph_load_estab' are no longer supported. "
224
+ "Rename the series to 'glyph_load_stabilizers' before loading the graph."
225
+ )
52
226
  metrics_sentinel_key = "_metrics_history_id"
53
227
  history_id = id(hist)
54
228
  if G.graph.get(metrics_sentinel_key) != history_id:
55
- for k in (
56
- "C_steps",
57
- "stable_frac",
58
- "phase_sync",
59
- "glyph_load_estab",
60
- "glyph_load_disr",
61
- "Si_mean",
62
- "Si_hi_frac",
63
- "Si_lo_frac",
64
- "delta_Si",
65
- "B",
66
- ):
67
- hist.setdefault(k, [])
229
+ for key in _METRICS_BASE_HISTORY_KEYS:
230
+ hist.setdefault(key, [])
231
+ if spec.enable_phase_sync:
232
+ for key in _METRICS_PHASE_HISTORY_KEYS:
233
+ hist.setdefault(key, [])
234
+ if spec.enable_sigma:
235
+ for key in _METRICS_SIGMA_HISTORY_KEYS:
236
+ hist.setdefault(key, [])
237
+ if spec.enable_aggregate_si:
238
+ for key in _METRICS_SI_HISTORY_KEYS:
239
+ hist.setdefault(key, [])
240
+ if spec.enable_nu_f:
241
+ for key in _METRICS_NU_F_HISTORY_KEYS:
242
+ hist.setdefault(key, [])
68
243
  G.graph[metrics_sentinel_key] = history_id
69
244
 
70
245
  dt = float(get_param(G, "DT"))
@@ -73,29 +248,69 @@ def _metrics_step(G, ctx: dict[str, Any] | None = None):
73
248
  t = float(G.graph.get("_t", 0.0))
74
249
 
75
250
  _update_coherence(G, hist)
76
- _track_stability(G, hist, dt, eps_dnfr, eps_depi)
251
+
252
+ raw_jobs = cfg.get("n_jobs")
253
+ metrics_jobs: int | None
77
254
  try:
78
- _update_phase_sync(G, hist)
79
- _update_sigma(G, hist)
80
- if hist.get("C_steps") and hist.get("stable_frac"):
81
- append_metric(
82
- hist,
83
- "iota",
84
- hist["C_steps"][-1] * hist["stable_frac"][-1],
85
- )
86
- except (KeyError, AttributeError, TypeError) as exc:
87
- logger.debug("observer update failed: %s", exc)
255
+ metrics_jobs = None if raw_jobs is None else int(raw_jobs)
256
+ except (TypeError, ValueError):
257
+ metrics_jobs = None
258
+ else:
259
+ if metrics_jobs <= 0:
260
+ metrics_jobs = None
261
+
262
+ _track_stability(
263
+ G,
264
+ hist,
265
+ dt,
266
+ eps_dnfr,
267
+ eps_depi,
268
+ n_jobs=metrics_jobs,
269
+ )
270
+ if spec.enable_phase_sync or spec.enable_sigma:
271
+ try:
272
+ if spec.enable_phase_sync:
273
+ _update_phase_sync(G, hist)
274
+ if spec.enable_sigma:
275
+ _update_sigma(G, hist)
276
+ except (KeyError, AttributeError, TypeError) as exc:
277
+ logger.debug("observer update failed: %s", exc)
278
+
279
+ if hist.get("C_steps") and hist.get("stable_frac"):
280
+ append_metric(
281
+ hist,
282
+ "iota",
283
+ hist["C_steps"][-1] * hist["stable_frac"][-1],
284
+ )
285
+
286
+ if spec.enable_aggregate_si:
287
+ _aggregate_si(G, hist, n_jobs=metrics_jobs)
288
+
289
+ _update_nu_f_snapshot(G, hist, record_history=spec.enable_nu_f)
290
+
291
+ if spec.enable_advanced:
292
+ _compute_advanced_metrics(
293
+ G,
294
+ cast(GlyphMetricsHistory, hist),
295
+ t,
296
+ dt,
297
+ cfg,
298
+ n_jobs=metrics_jobs,
299
+ )
88
300
 
89
- _aggregate_si(G, hist)
90
- _compute_advanced_metrics(G, hist, t, dt, cfg)
91
301
 
302
+ def register_metrics_callbacks(G: TNFRGraph) -> None:
303
+ """Attach canonical metrics callbacks according to graph configuration."""
92
304
 
93
- def register_metrics_callbacks(G) -> None:
305
+ cfg = cast(Mapping[str, Any], get_param(G, "METRICS"))
306
+ spec = _resolve_metrics_verbosity(cfg)
94
307
  callback_manager.register_callback(
95
308
  G,
96
309
  event=CallbackEvent.AFTER_STEP.value,
97
310
  func=_metrics_step,
98
311
  name="metrics_step",
99
312
  )
100
- register_coherence_callbacks(G)
101
- register_diagnosis_callbacks(G)
313
+ if spec.attach_coherence_hooks:
314
+ register_coherence_callbacks(G)
315
+ if spec.attach_diagnosis_hooks:
316
+ register_diagnosis_callbacks(G)
tnfr/metrics/core.pyi ADDED
@@ -0,0 +1,13 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ Tg_by_node: Any
8
+ Tg_global: Any
9
+ _metrics_step: Any
10
+ glyph_top: Any
11
+ glyphogram_series: Any
12
+ latency_series: Any
13
+ register_metrics_callbacks: Any