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.
- tnfr/__init__.py +375 -56
- tnfr/__init__.pyi +33 -0
- tnfr/_compat.py +10 -0
- tnfr/_generated_version.py +34 -0
- tnfr/_version.py +49 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +723 -0
- tnfr/alias.pyi +108 -0
- tnfr/backends/__init__.py +354 -0
- tnfr/backends/jax_backend.py +173 -0
- tnfr/backends/numpy_backend.py +238 -0
- tnfr/backends/optimized_numpy.py +420 -0
- tnfr/backends/torch_backend.py +408 -0
- tnfr/cache.py +171 -0
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +110 -0
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +489 -0
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +914 -0
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +51 -0
- tnfr/cli/utils.pyi +7 -0
- tnfr/cli/validate.py +236 -0
- tnfr/compat/__init__.py +85 -0
- tnfr/compat/dataclass.py +136 -0
- tnfr/compat/jsonschema_stub.py +61 -0
- tnfr/compat/matplotlib_stub.py +73 -0
- tnfr/compat/numpy_stub.py +155 -0
- tnfr/config/__init__.py +224 -0
- tnfr/config/__init__.pyi +10 -0
- tnfr/config/constants.py +104 -0
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/config/defaults_core.py +212 -0
- tnfr/config/defaults_init.py +33 -0
- tnfr/config/defaults_metric.py +104 -0
- tnfr/config/feature_flags.py +81 -0
- tnfr/config/feature_flags.pyi +16 -0
- tnfr/config/glyph_constants.py +31 -0
- tnfr/config/init.py +77 -0
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +254 -0
- tnfr/config/operator_names.pyi +36 -0
- tnfr/config/physics_derivation.py +354 -0
- tnfr/config/presets.py +83 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/config/security.py +927 -0
- tnfr/config/thresholds.py +114 -0
- tnfr/config/tnfr_config.py +498 -0
- tnfr/constants/__init__.py +92 -0
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +33 -0
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +104 -0
- tnfr/constants/metric.pyi +19 -0
- tnfr/core/__init__.py +33 -0
- tnfr/core/container.py +226 -0
- tnfr/core/default_implementations.py +329 -0
- tnfr/core/interfaces.py +279 -0
- tnfr/dynamics/__init__.py +238 -0
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +267 -0
- tnfr/dynamics/adaptation.pyi +7 -0
- tnfr/dynamics/adaptive_sequences.py +189 -0
- tnfr/dynamics/adaptive_sequences.pyi +14 -0
- tnfr/dynamics/aliases.py +23 -0
- tnfr/dynamics/aliases.pyi +19 -0
- tnfr/dynamics/bifurcation.py +232 -0
- tnfr/dynamics/canonical.py +229 -0
- tnfr/dynamics/canonical.pyi +48 -0
- tnfr/dynamics/coordination.py +385 -0
- tnfr/dynamics/coordination.pyi +25 -0
- tnfr/dynamics/dnfr.py +3034 -0
- tnfr/dynamics/dnfr.pyi +26 -0
- tnfr/dynamics/dynamic_limits.py +225 -0
- tnfr/dynamics/feedback.py +252 -0
- tnfr/dynamics/feedback.pyi +24 -0
- tnfr/dynamics/fused_dnfr.py +454 -0
- tnfr/dynamics/homeostasis.py +157 -0
- tnfr/dynamics/homeostasis.pyi +14 -0
- tnfr/dynamics/integrators.py +661 -0
- tnfr/dynamics/integrators.pyi +36 -0
- tnfr/dynamics/learning.py +310 -0
- tnfr/dynamics/learning.pyi +33 -0
- tnfr/dynamics/metabolism.py +254 -0
- tnfr/dynamics/nbody.py +796 -0
- tnfr/dynamics/nbody_tnfr.py +783 -0
- tnfr/dynamics/propagation.py +326 -0
- tnfr/dynamics/runtime.py +908 -0
- tnfr/dynamics/runtime.pyi +77 -0
- tnfr/dynamics/sampling.py +36 -0
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +711 -0
- tnfr/dynamics/selectors.pyi +85 -0
- tnfr/dynamics/structural_clip.py +207 -0
- tnfr/errors/__init__.py +37 -0
- tnfr/errors/contextual.py +492 -0
- tnfr/execution.py +223 -0
- tnfr/execution.pyi +45 -0
- tnfr/extensions/__init__.py +205 -0
- tnfr/extensions/__init__.pyi +18 -0
- tnfr/extensions/base.py +173 -0
- tnfr/extensions/base.pyi +35 -0
- tnfr/extensions/business/__init__.py +71 -0
- tnfr/extensions/business/__init__.pyi +11 -0
- tnfr/extensions/business/cookbook.py +88 -0
- tnfr/extensions/business/cookbook.pyi +8 -0
- tnfr/extensions/business/health_analyzers.py +202 -0
- tnfr/extensions/business/health_analyzers.pyi +9 -0
- tnfr/extensions/business/patterns.py +183 -0
- tnfr/extensions/business/patterns.pyi +8 -0
- tnfr/extensions/medical/__init__.py +73 -0
- tnfr/extensions/medical/__init__.pyi +11 -0
- tnfr/extensions/medical/cookbook.py +88 -0
- tnfr/extensions/medical/cookbook.pyi +8 -0
- tnfr/extensions/medical/health_analyzers.py +181 -0
- tnfr/extensions/medical/health_analyzers.pyi +9 -0
- tnfr/extensions/medical/patterns.py +163 -0
- tnfr/extensions/medical/patterns.pyi +8 -0
- tnfr/flatten.py +262 -0
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +354 -0
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +377 -0
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +218 -0
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +203 -0
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +10 -0
- tnfr/io.pyi +13 -0
- tnfr/locking.py +37 -0
- tnfr/locking.pyi +7 -0
- tnfr/mathematics/__init__.py +79 -0
- tnfr/mathematics/backend.py +453 -0
- tnfr/mathematics/backend.pyi +99 -0
- tnfr/mathematics/dynamics.py +408 -0
- tnfr/mathematics/dynamics.pyi +90 -0
- tnfr/mathematics/epi.py +391 -0
- tnfr/mathematics/epi.pyi +65 -0
- tnfr/mathematics/generators.py +242 -0
- tnfr/mathematics/generators.pyi +29 -0
- tnfr/mathematics/metrics.py +119 -0
- tnfr/mathematics/metrics.pyi +16 -0
- tnfr/mathematics/operators.py +239 -0
- tnfr/mathematics/operators.pyi +59 -0
- tnfr/mathematics/operators_factory.py +124 -0
- tnfr/mathematics/operators_factory.pyi +11 -0
- tnfr/mathematics/projection.py +87 -0
- tnfr/mathematics/projection.pyi +33 -0
- tnfr/mathematics/runtime.py +182 -0
- tnfr/mathematics/runtime.pyi +64 -0
- tnfr/mathematics/spaces.py +256 -0
- tnfr/mathematics/spaces.pyi +83 -0
- tnfr/mathematics/transforms.py +305 -0
- tnfr/mathematics/transforms.pyi +62 -0
- tnfr/metrics/__init__.py +79 -0
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/buffer_cache.py +163 -0
- tnfr/metrics/buffer_cache.pyi +24 -0
- tnfr/metrics/cache_utils.py +214 -0
- tnfr/metrics/coherence.py +2009 -0
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +158 -0
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +316 -0
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +833 -0
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +179 -0
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +379 -0
- tnfr/metrics/glyph_timing.pyi +81 -0
- tnfr/metrics/learning_metrics.py +280 -0
- tnfr/metrics/learning_metrics.pyi +21 -0
- tnfr/metrics/phase_coherence.py +351 -0
- tnfr/metrics/phase_compatibility.py +349 -0
- tnfr/metrics/reporting.py +183 -0
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1203 -0
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +373 -0
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +233 -0
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +763 -0
- tnfr/node.pyi +139 -0
- tnfr/observers.py +255 -130
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +144 -137
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1672 -0
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/algebra.py +277 -0
- tnfr/operators/canonical_patterns.py +420 -0
- tnfr/operators/cascade.py +267 -0
- tnfr/operators/cycle_detection.py +358 -0
- tnfr/operators/definitions.py +4108 -0
- tnfr/operators/definitions.pyi +78 -0
- tnfr/operators/grammar.py +1164 -0
- tnfr/operators/grammar.pyi +140 -0
- tnfr/operators/hamiltonian.py +710 -0
- tnfr/operators/health_analyzer.py +809 -0
- tnfr/operators/jitter.py +272 -0
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/lifecycle.py +314 -0
- tnfr/operators/metabolism.py +618 -0
- tnfr/operators/metrics.py +2138 -0
- tnfr/operators/network_analysis/__init__.py +27 -0
- tnfr/operators/network_analysis/source_detection.py +186 -0
- tnfr/operators/nodal_equation.py +395 -0
- tnfr/operators/pattern_detection.py +660 -0
- tnfr/operators/patterns.py +669 -0
- tnfr/operators/postconditions/__init__.py +38 -0
- tnfr/operators/postconditions/mutation.py +236 -0
- tnfr/operators/preconditions/__init__.py +1226 -0
- tnfr/operators/preconditions/coherence.py +305 -0
- tnfr/operators/preconditions/dissonance.py +236 -0
- tnfr/operators/preconditions/emission.py +128 -0
- tnfr/operators/preconditions/mutation.py +580 -0
- tnfr/operators/preconditions/reception.py +125 -0
- tnfr/operators/preconditions/resonance.py +364 -0
- tnfr/operators/registry.py +74 -0
- tnfr/operators/registry.pyi +9 -0
- tnfr/operators/remesh.py +1809 -0
- tnfr/operators/remesh.pyi +26 -0
- tnfr/operators/structural_units.py +268 -0
- tnfr/operators/unified_grammar.py +105 -0
- tnfr/parallel/__init__.py +54 -0
- tnfr/parallel/auto_scaler.py +234 -0
- tnfr/parallel/distributed.py +384 -0
- tnfr/parallel/engine.py +238 -0
- tnfr/parallel/gpu_engine.py +420 -0
- tnfr/parallel/monitoring.py +248 -0
- tnfr/parallel/partitioner.py +459 -0
- tnfr/py.typed +0 -0
- tnfr/recipes/__init__.py +22 -0
- tnfr/recipes/cookbook.py +743 -0
- tnfr/rng.py +178 -0
- tnfr/rng.pyi +26 -0
- tnfr/schemas/__init__.py +8 -0
- tnfr/schemas/grammar.json +94 -0
- tnfr/sdk/__init__.py +107 -0
- tnfr/sdk/__init__.pyi +19 -0
- tnfr/sdk/adaptive_system.py +173 -0
- tnfr/sdk/adaptive_system.pyi +21 -0
- tnfr/sdk/builders.py +370 -0
- tnfr/sdk/builders.pyi +51 -0
- tnfr/sdk/fluent.py +1121 -0
- tnfr/sdk/fluent.pyi +74 -0
- tnfr/sdk/templates.py +342 -0
- tnfr/sdk/templates.pyi +41 -0
- tnfr/sdk/utils.py +341 -0
- tnfr/secure_config.py +46 -0
- tnfr/security/__init__.py +70 -0
- tnfr/security/database.py +514 -0
- tnfr/security/subprocess.py +503 -0
- tnfr/security/validation.py +290 -0
- tnfr/selector.py +247 -0
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +378 -0
- tnfr/sense.pyi +23 -0
- tnfr/services/__init__.py +17 -0
- tnfr/services/orchestrator.py +325 -0
- tnfr/sparse/__init__.py +39 -0
- tnfr/sparse/representations.py +492 -0
- tnfr/structural.py +705 -0
- tnfr/structural.pyi +83 -0
- tnfr/telemetry/__init__.py +35 -0
- tnfr/telemetry/cache_metrics.py +226 -0
- tnfr/telemetry/cache_metrics.pyi +64 -0
- tnfr/telemetry/nu_f.py +422 -0
- tnfr/telemetry/nu_f.pyi +108 -0
- tnfr/telemetry/verbosity.py +36 -0
- tnfr/telemetry/verbosity.pyi +15 -0
- tnfr/tokens.py +58 -0
- tnfr/tokens.pyi +36 -0
- tnfr/tools/__init__.py +20 -0
- tnfr/tools/domain_templates.py +478 -0
- tnfr/tools/sequence_generator.py +846 -0
- tnfr/topology/__init__.py +13 -0
- tnfr/topology/asymmetry.py +151 -0
- tnfr/trace.py +543 -0
- tnfr/trace.pyi +42 -0
- tnfr/tutorials/__init__.py +38 -0
- tnfr/tutorials/autonomous_evolution.py +285 -0
- tnfr/tutorials/interactive.py +1576 -0
- tnfr/tutorials/structural_metabolism.py +238 -0
- tnfr/types.py +775 -0
- tnfr/types.pyi +357 -0
- tnfr/units.py +68 -0
- tnfr/units.pyi +13 -0
- tnfr/utils/__init__.py +282 -0
- tnfr/utils/__init__.pyi +215 -0
- tnfr/utils/cache.py +4223 -0
- tnfr/utils/cache.pyi +470 -0
- tnfr/utils/callbacks.py +375 -0
- tnfr/utils/callbacks.pyi +49 -0
- tnfr/utils/chunks.py +108 -0
- tnfr/utils/chunks.pyi +22 -0
- tnfr/utils/data.py +428 -0
- tnfr/utils/data.pyi +74 -0
- tnfr/utils/graph.py +85 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +821 -0
- tnfr/utils/init.pyi +80 -0
- tnfr/utils/io.py +559 -0
- tnfr/utils/io.pyi +66 -0
- tnfr/utils/numeric.py +114 -0
- tnfr/utils/numeric.pyi +21 -0
- tnfr/validation/__init__.py +257 -0
- tnfr/validation/__init__.pyi +85 -0
- tnfr/validation/compatibility.py +460 -0
- tnfr/validation/compatibility.pyi +6 -0
- tnfr/validation/config.py +73 -0
- tnfr/validation/graph.py +139 -0
- tnfr/validation/graph.pyi +18 -0
- tnfr/validation/input_validation.py +755 -0
- tnfr/validation/invariants.py +712 -0
- tnfr/validation/rules.py +253 -0
- tnfr/validation/rules.pyi +44 -0
- tnfr/validation/runtime.py +279 -0
- tnfr/validation/runtime.pyi +28 -0
- tnfr/validation/sequence_validator.py +162 -0
- tnfr/validation/soft_filters.py +170 -0
- tnfr/validation/soft_filters.pyi +32 -0
- tnfr/validation/spectral.py +164 -0
- tnfr/validation/spectral.pyi +42 -0
- tnfr/validation/validator.py +1266 -0
- tnfr/validation/window.py +39 -0
- tnfr/validation/window.pyi +1 -0
- tnfr/visualization/__init__.py +98 -0
- tnfr/visualization/cascade_viz.py +256 -0
- tnfr/visualization/hierarchy.py +284 -0
- tnfr/visualization/sequence_plotter.py +784 -0
- tnfr/viz/__init__.py +60 -0
- tnfr/viz/matplotlib.py +278 -0
- tnfr/viz/matplotlib.pyi +35 -0
- tnfr-8.5.0.dist-info/METADATA +573 -0
- tnfr-8.5.0.dist-info/RECORD +353 -0
- tnfr-8.5.0.dist-info/entry_points.txt +3 -0
- tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
- tnfr/constants.py +0 -183
- tnfr/dynamics.py +0 -543
- tnfr/helpers.py +0 -198
- tnfr/main.py +0 -37
- tnfr/operators.py +0 -296
- tnfr-3.0.3.dist-info/METADATA +0 -35
- tnfr-3.0.3.dist-info/RECORD +0 -13
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
tnfr/utils/numeric.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""Numeric helper functions and compensated summation utilities."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
from collections.abc import Iterable, Sequence
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
__all__ = (
|
|
10
|
+
"clamp",
|
|
11
|
+
"clamp01",
|
|
12
|
+
"within_range",
|
|
13
|
+
"similarity_abs",
|
|
14
|
+
"kahan_sum_nd",
|
|
15
|
+
"angle_diff",
|
|
16
|
+
"angle_diff_array",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def clamp(x: float, a: float, b: float) -> float:
|
|
21
|
+
"""Return ``x`` clamped to the ``[a, b]`` interval."""
|
|
22
|
+
|
|
23
|
+
return max(a, min(b, x))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def clamp01(x: float) -> float:
|
|
27
|
+
"""Clamp ``x`` to the ``[0,1]`` interval."""
|
|
28
|
+
|
|
29
|
+
return clamp(float(x), 0.0, 1.0)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def within_range(val: float, lower: float, upper: float, tol: float = 1e-9) -> bool:
|
|
33
|
+
"""Return ``True`` if ``val`` lies in ``[lower, upper]`` within ``tol``."""
|
|
34
|
+
|
|
35
|
+
v = float(val)
|
|
36
|
+
return lower <= v <= upper or abs(v - lower) <= tol or abs(v - upper) <= tol
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _norm01(x: float, lo: float, hi: float) -> float:
|
|
40
|
+
"""Normalize ``x`` to the unit interval given bounds."""
|
|
41
|
+
|
|
42
|
+
if hi <= lo:
|
|
43
|
+
return 0.0
|
|
44
|
+
return clamp01((float(x) - float(lo)) / (float(hi) - float(lo)))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def similarity_abs(a: float, b: float, lo: float, hi: float) -> float:
|
|
48
|
+
"""Return absolute similarity of ``a`` and ``b`` over ``[lo, hi]``."""
|
|
49
|
+
|
|
50
|
+
return 1.0 - _norm01(abs(float(a) - float(b)), 0.0, hi - lo)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def kahan_sum_nd(values: Iterable[Sequence[float]], dims: int) -> tuple[float, ...]:
|
|
54
|
+
"""Return compensated sums of ``values`` with ``dims`` components."""
|
|
55
|
+
|
|
56
|
+
if dims < 1:
|
|
57
|
+
raise ValueError("dims must be >= 1")
|
|
58
|
+
totals = [0.0] * dims
|
|
59
|
+
comps = [0.0] * dims
|
|
60
|
+
for vs in values:
|
|
61
|
+
for i in range(dims):
|
|
62
|
+
v = vs[i]
|
|
63
|
+
t = totals[i] + v
|
|
64
|
+
if abs(totals[i]) >= abs(v):
|
|
65
|
+
comps[i] += (totals[i] - t) + v
|
|
66
|
+
else:
|
|
67
|
+
comps[i] += (v - t) + totals[i]
|
|
68
|
+
totals[i] = t
|
|
69
|
+
return tuple(float(totals[i] + comps[i]) for i in range(dims))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def angle_diff(a: float, b: float) -> float:
|
|
73
|
+
"""Return the minimal difference between two angles in radians."""
|
|
74
|
+
|
|
75
|
+
return (float(a) - float(b) + math.pi) % math.tau - math.pi
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def angle_diff_array(
|
|
79
|
+
a: Sequence[float] | "np.ndarray", # noqa: F821
|
|
80
|
+
b: Sequence[float] | "np.ndarray", # noqa: F821
|
|
81
|
+
*,
|
|
82
|
+
np: Any,
|
|
83
|
+
out: "np.ndarray | None" = None, # noqa: F821
|
|
84
|
+
where: "np.ndarray | None" = None, # noqa: F821
|
|
85
|
+
) -> "np.ndarray": # noqa: F821
|
|
86
|
+
"""Vectorised :func:`angle_diff` compatible with NumPy arrays."""
|
|
87
|
+
|
|
88
|
+
if np is None:
|
|
89
|
+
raise TypeError("angle_diff_array requires a NumPy module")
|
|
90
|
+
|
|
91
|
+
kwargs = {"where": where} if where is not None else {}
|
|
92
|
+
minuend = np.asarray(a, dtype=float)
|
|
93
|
+
subtrahend = np.asarray(b, dtype=float)
|
|
94
|
+
if out is None:
|
|
95
|
+
out = np.empty_like(minuend, dtype=float)
|
|
96
|
+
if where is not None:
|
|
97
|
+
out.fill(0.0)
|
|
98
|
+
else:
|
|
99
|
+
if getattr(out, "shape", None) != minuend.shape:
|
|
100
|
+
raise ValueError("out must match the broadcasted shape of inputs")
|
|
101
|
+
|
|
102
|
+
np.subtract(minuend, subtrahend, out=out, **kwargs)
|
|
103
|
+
np.add(out, math.pi, out=out, **kwargs)
|
|
104
|
+
if where is not None:
|
|
105
|
+
mask = np.asarray(where, dtype=bool)
|
|
106
|
+
if mask.shape != out.shape:
|
|
107
|
+
raise ValueError("where mask must match the broadcasted shape of inputs")
|
|
108
|
+
selected = out[mask]
|
|
109
|
+
if selected.size:
|
|
110
|
+
out[mask] = np.remainder(selected, math.tau)
|
|
111
|
+
else:
|
|
112
|
+
np.remainder(out, math.tau, out=out)
|
|
113
|
+
np.subtract(out, math.pi, out=out, **kwargs)
|
|
114
|
+
return out
|
tnfr/utils/numeric.pyi
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable, Sequence
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
__all__: tuple[str, ...]
|
|
7
|
+
|
|
8
|
+
def clamp(x: float, a: float, b: float) -> float: ...
|
|
9
|
+
def clamp01(x: float) -> float: ...
|
|
10
|
+
def within_range(val: float, lower: float, upper: float, tol: float = ...) -> bool: ...
|
|
11
|
+
def similarity_abs(a: float, b: float, lo: float, hi: float) -> float: ...
|
|
12
|
+
def kahan_sum_nd(values: Iterable[Sequence[float]], dims: int) -> tuple[float, ...]: ...
|
|
13
|
+
def angle_diff(a: float, b: float) -> float: ...
|
|
14
|
+
def angle_diff_array(
|
|
15
|
+
a: Sequence[float] | Any,
|
|
16
|
+
b: Sequence[float] | Any,
|
|
17
|
+
*,
|
|
18
|
+
np: Any,
|
|
19
|
+
out: Any | None = ...,
|
|
20
|
+
where: Any | None = ...,
|
|
21
|
+
) -> Any: ...
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""Unified validation interface consolidating grammar, graph and spectral checks.
|
|
2
|
+
|
|
3
|
+
RECOMMENDED: Use TNFRValidator for unified validation pipeline
|
|
4
|
+
==============================================================
|
|
5
|
+
|
|
6
|
+
The TNFRValidator class provides a single entry point for all TNFR validation
|
|
7
|
+
operations, consolidating input validation, graph validation, invariant checking,
|
|
8
|
+
operator preconditions, and runtime validation into one coherent API.
|
|
9
|
+
|
|
10
|
+
Example Usage::
|
|
11
|
+
|
|
12
|
+
from tnfr.validation import TNFRValidator
|
|
13
|
+
|
|
14
|
+
validator = TNFRValidator()
|
|
15
|
+
|
|
16
|
+
# Comprehensive validation in one call
|
|
17
|
+
result = validator.validate(
|
|
18
|
+
graph=G,
|
|
19
|
+
epi=0.5,
|
|
20
|
+
vf=1.0,
|
|
21
|
+
include_invariants=True,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if not result['passed']:
|
|
25
|
+
print(f"Validation failed: {result['errors']}")
|
|
26
|
+
|
|
27
|
+
For detailed migration guide, see UNIFIED_VALIDATION_PIPELINE.md
|
|
28
|
+
|
|
29
|
+
Legacy API
|
|
30
|
+
==========
|
|
31
|
+
|
|
32
|
+
This package also re-exports individual validation functions for backward
|
|
33
|
+
compatibility, but these may be deprecated in future versions. New code should
|
|
34
|
+
use TNFRValidator instead.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
from __future__ import annotations
|
|
38
|
+
|
|
39
|
+
from ..compat.dataclass import dataclass
|
|
40
|
+
from typing import Any, Generic, Mapping, Protocol, TypeVar, runtime_checkable
|
|
41
|
+
|
|
42
|
+
SubjectT = TypeVar("SubjectT")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(slots=True)
|
|
46
|
+
class ValidationOutcome(Generic[SubjectT]):
|
|
47
|
+
"""Result emitted by all canonical TNFR validators."""
|
|
48
|
+
|
|
49
|
+
subject: SubjectT
|
|
50
|
+
"""The validated subject in canonical form."""
|
|
51
|
+
|
|
52
|
+
passed: bool
|
|
53
|
+
"""Whether the validation succeeded without invariant violations."""
|
|
54
|
+
|
|
55
|
+
summary: Mapping[str, Any]
|
|
56
|
+
"""Structured diagnostics describing the performed checks."""
|
|
57
|
+
|
|
58
|
+
artifacts: Mapping[str, Any] | None = None
|
|
59
|
+
"""Optional artefacts (e.g. clamped nodes, normalised vectors)."""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@runtime_checkable
|
|
63
|
+
class Validator(Protocol[SubjectT]):
|
|
64
|
+
"""Contract implemented by runtime and spectral validators."""
|
|
65
|
+
|
|
66
|
+
def validate(
|
|
67
|
+
self, subject: SubjectT, /, **kwargs: Any
|
|
68
|
+
) -> ValidationOutcome[SubjectT]:
|
|
69
|
+
"""Validate ``subject`` returning a :class:`ValidationOutcome`."""
|
|
70
|
+
|
|
71
|
+
def report(self, outcome: "ValidationOutcome[SubjectT]") -> str:
|
|
72
|
+
"""Produce a concise textual explanation for ``outcome``."""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# NOTE: Compatibility module deprecated - grammar emerges from TNFR structural dynamics
|
|
76
|
+
# Legacy exports kept for backward compatibility but will be removed in future versions
|
|
77
|
+
try:
|
|
78
|
+
from .compatibility import ( # noqa: F401
|
|
79
|
+
CANON_COMPAT,
|
|
80
|
+
CANON_FALLBACK,
|
|
81
|
+
CompatibilityLevel,
|
|
82
|
+
GRADUATED_COMPATIBILITY,
|
|
83
|
+
get_compatibility_level,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
_COMPAT_AVAILABLE = True
|
|
87
|
+
except ImportError:
|
|
88
|
+
# Compatibility module removed - provide stubs for backward compatibility
|
|
89
|
+
_COMPAT_AVAILABLE = False
|
|
90
|
+
CANON_COMPAT = {}
|
|
91
|
+
CANON_FALLBACK = {}
|
|
92
|
+
|
|
93
|
+
class CompatibilityLevel:
|
|
94
|
+
EXCELLENT = "excellent"
|
|
95
|
+
GOOD = "good"
|
|
96
|
+
CAUTION = "caution"
|
|
97
|
+
AVOID = "avoid"
|
|
98
|
+
|
|
99
|
+
GRADUATED_COMPATIBILITY = {}
|
|
100
|
+
|
|
101
|
+
def get_compatibility_level(prev: str, next_op: str) -> str:
|
|
102
|
+
"""Deprecated: Use frequency transition validation instead."""
|
|
103
|
+
import warnings
|
|
104
|
+
|
|
105
|
+
warnings.warn(
|
|
106
|
+
"get_compatibility_level is deprecated. "
|
|
107
|
+
"Grammar rules now emerge naturally from TNFR structural dynamics. "
|
|
108
|
+
"Use validate_frequency_transition from tnfr.operators.grammar instead.",
|
|
109
|
+
DeprecationWarning,
|
|
110
|
+
stacklevel=2,
|
|
111
|
+
)
|
|
112
|
+
return "good"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
from ..operators import grammar as _grammar
|
|
116
|
+
from ..types import Glyph
|
|
117
|
+
from .graph import GRAPH_VALIDATORS, run_validators # noqa: F401
|
|
118
|
+
from .window import validate_window # noqa: F401
|
|
119
|
+
from .runtime import (
|
|
120
|
+
GraphCanonicalValidator,
|
|
121
|
+
apply_canonical_clamps,
|
|
122
|
+
validate_canon,
|
|
123
|
+
) # noqa: F401
|
|
124
|
+
from .rules import coerce_glyph, get_norm, glyph_fallback, normalized_dnfr # noqa: F401
|
|
125
|
+
from .soft_filters import ( # noqa: F401
|
|
126
|
+
acceleration_norm,
|
|
127
|
+
check_repeats,
|
|
128
|
+
maybe_force,
|
|
129
|
+
soft_grammar_filters,
|
|
130
|
+
)
|
|
131
|
+
from .input_validation import ( # noqa: F401
|
|
132
|
+
ValidationError,
|
|
133
|
+
validate_epi_value,
|
|
134
|
+
validate_vf_value,
|
|
135
|
+
validate_theta_value,
|
|
136
|
+
validate_dnfr_value,
|
|
137
|
+
validate_node_id,
|
|
138
|
+
validate_glyph,
|
|
139
|
+
validate_tnfr_graph,
|
|
140
|
+
validate_glyph_factors,
|
|
141
|
+
validate_operator_parameters,
|
|
142
|
+
)
|
|
143
|
+
from .invariants import ( # noqa: F401
|
|
144
|
+
InvariantSeverity,
|
|
145
|
+
InvariantViolation,
|
|
146
|
+
TNFRInvariant,
|
|
147
|
+
Invariant1_EPIOnlyThroughOperators,
|
|
148
|
+
Invariant2_VfInHzStr,
|
|
149
|
+
Invariant3_DNFRSemantics,
|
|
150
|
+
Invariant4_OperatorClosure,
|
|
151
|
+
Invariant5_ExplicitPhaseChecks,
|
|
152
|
+
Invariant6_NodeBirthCollapse,
|
|
153
|
+
Invariant7_OperationalFractality,
|
|
154
|
+
Invariant8_ControlledDeterminism,
|
|
155
|
+
Invariant9_StructuralMetrics,
|
|
156
|
+
Invariant10_DomainNeutrality,
|
|
157
|
+
)
|
|
158
|
+
from .validator import ( # noqa: F401
|
|
159
|
+
TNFRValidator,
|
|
160
|
+
TNFRValidationError,
|
|
161
|
+
)
|
|
162
|
+
from .sequence_validator import ( # noqa: F401
|
|
163
|
+
SequenceSemanticValidator,
|
|
164
|
+
)
|
|
165
|
+
from .config import ( # noqa: F401
|
|
166
|
+
ValidationConfig,
|
|
167
|
+
validation_config,
|
|
168
|
+
configure_validation,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
_GRAMMAR_EXPORTS = tuple(getattr(_grammar, "__all__", ()))
|
|
172
|
+
|
|
173
|
+
globals().update({name: getattr(_grammar, name) for name in _GRAMMAR_EXPORTS})
|
|
174
|
+
|
|
175
|
+
_RUNTIME_EXPORTS = (
|
|
176
|
+
"ValidationOutcome",
|
|
177
|
+
"Validator",
|
|
178
|
+
"GraphCanonicalValidator",
|
|
179
|
+
"apply_canonical_clamps",
|
|
180
|
+
"validate_canon",
|
|
181
|
+
"GRAPH_VALIDATORS",
|
|
182
|
+
"run_validators",
|
|
183
|
+
"CANON_COMPAT",
|
|
184
|
+
"CANON_FALLBACK",
|
|
185
|
+
"validate_window",
|
|
186
|
+
"coerce_glyph",
|
|
187
|
+
"get_norm",
|
|
188
|
+
"glyph_fallback",
|
|
189
|
+
"normalized_dnfr",
|
|
190
|
+
"acceleration_norm",
|
|
191
|
+
"check_repeats",
|
|
192
|
+
"maybe_force",
|
|
193
|
+
"soft_grammar_filters",
|
|
194
|
+
"NFRValidator",
|
|
195
|
+
"ValidationError",
|
|
196
|
+
"validate_epi_value",
|
|
197
|
+
"validate_vf_value",
|
|
198
|
+
"validate_theta_value",
|
|
199
|
+
"validate_dnfr_value",
|
|
200
|
+
"validate_node_id",
|
|
201
|
+
"validate_glyph",
|
|
202
|
+
"validate_tnfr_graph",
|
|
203
|
+
"validate_glyph_factors",
|
|
204
|
+
"validate_operator_parameters",
|
|
205
|
+
"InvariantSeverity",
|
|
206
|
+
"InvariantViolation",
|
|
207
|
+
"TNFRInvariant",
|
|
208
|
+
"Invariant1_EPIOnlyThroughOperators",
|
|
209
|
+
"Invariant2_VfInHzStr",
|
|
210
|
+
"Invariant3_DNFRSemantics",
|
|
211
|
+
"Invariant4_OperatorClosure",
|
|
212
|
+
"Invariant5_ExplicitPhaseChecks",
|
|
213
|
+
"Invariant6_NodeBirthCollapse",
|
|
214
|
+
"Invariant7_OperationalFractality",
|
|
215
|
+
"Invariant8_ControlledDeterminism",
|
|
216
|
+
"Invariant9_StructuralMetrics",
|
|
217
|
+
"Invariant10_DomainNeutrality",
|
|
218
|
+
"TNFRValidator",
|
|
219
|
+
"TNFRValidationError",
|
|
220
|
+
"SequenceSemanticValidator",
|
|
221
|
+
"ValidationConfig",
|
|
222
|
+
"validation_config",
|
|
223
|
+
"configure_validation",
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
__all__ = _GRAMMAR_EXPORTS + _RUNTIME_EXPORTS
|
|
227
|
+
|
|
228
|
+
_ENFORCE_CANONICAL_GRAMMAR = _grammar.enforce_canonical_grammar
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def enforce_canonical_grammar(
|
|
232
|
+
G: Any,
|
|
233
|
+
n: Any,
|
|
234
|
+
cand: Any,
|
|
235
|
+
ctx: Any | None = None,
|
|
236
|
+
) -> Any:
|
|
237
|
+
"""Proxy to the canonical grammar enforcement helper preserving Glyph outputs."""
|
|
238
|
+
|
|
239
|
+
result = _ENFORCE_CANONICAL_GRAMMAR(G, n, cand, ctx)
|
|
240
|
+
if isinstance(cand, Glyph) and not isinstance(result, Glyph):
|
|
241
|
+
translated = _grammar.function_name_to_glyph(result)
|
|
242
|
+
if translated is None and isinstance(result, str):
|
|
243
|
+
try:
|
|
244
|
+
translated = Glyph(result)
|
|
245
|
+
except (TypeError, ValueError):
|
|
246
|
+
translated = None
|
|
247
|
+
if translated is not None:
|
|
248
|
+
return translated
|
|
249
|
+
return result
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def __getattr__(name: str) -> Any:
|
|
253
|
+
if name == "NFRValidator":
|
|
254
|
+
from .spectral import NFRValidator as _NFRValidator
|
|
255
|
+
|
|
256
|
+
return _NFRValidator
|
|
257
|
+
raise AttributeError(name)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any, Generic, Protocol, TypeVar
|
|
5
|
+
|
|
6
|
+
from ..types import Glyph, TNFRGraph
|
|
7
|
+
from .compatibility import (
|
|
8
|
+
CANON_COMPAT as CANON_COMPAT,
|
|
9
|
+
CANON_FALLBACK as CANON_FALLBACK,
|
|
10
|
+
)
|
|
11
|
+
from ..operators.grammar import (
|
|
12
|
+
GrammarContext,
|
|
13
|
+
MutationPreconditionError,
|
|
14
|
+
RepeatWindowError,
|
|
15
|
+
SequenceSyntaxError,
|
|
16
|
+
SequenceValidationResult,
|
|
17
|
+
StructuralGrammarError,
|
|
18
|
+
TholClosureError,
|
|
19
|
+
TransitionCompatibilityError,
|
|
20
|
+
apply_glyph_with_grammar,
|
|
21
|
+
enforce_canonical_grammar,
|
|
22
|
+
on_applied_glyph,
|
|
23
|
+
record_grammar_violation,
|
|
24
|
+
validate_sequence,
|
|
25
|
+
)
|
|
26
|
+
from .graph import GRAPH_VALIDATORS, run_validators
|
|
27
|
+
from .window import validate_window
|
|
28
|
+
from .rules import coerce_glyph, get_norm, glyph_fallback, normalized_dnfr
|
|
29
|
+
from .soft_filters import (
|
|
30
|
+
acceleration_norm,
|
|
31
|
+
check_repeats,
|
|
32
|
+
maybe_force,
|
|
33
|
+
soft_grammar_filters,
|
|
34
|
+
)
|
|
35
|
+
from .runtime import GraphCanonicalValidator, apply_canonical_clamps, validate_canon
|
|
36
|
+
from .spectral import NFRValidator
|
|
37
|
+
|
|
38
|
+
SubjectT = TypeVar("SubjectT")
|
|
39
|
+
|
|
40
|
+
class ValidationOutcome(Generic[SubjectT]):
|
|
41
|
+
subject: SubjectT
|
|
42
|
+
passed: bool
|
|
43
|
+
summary: Mapping[str, Any]
|
|
44
|
+
artifacts: Mapping[str, Any] | None
|
|
45
|
+
|
|
46
|
+
class Validator(Protocol[SubjectT]):
|
|
47
|
+
def validate(
|
|
48
|
+
self, subject: SubjectT, /, **kwargs: Any
|
|
49
|
+
) -> ValidationOutcome[SubjectT]: ...
|
|
50
|
+
def report(self, outcome: ValidationOutcome[SubjectT]) -> str: ...
|
|
51
|
+
|
|
52
|
+
__all__ = (
|
|
53
|
+
"validate_sequence",
|
|
54
|
+
"GrammarContext",
|
|
55
|
+
"StructuralGrammarError",
|
|
56
|
+
"RepeatWindowError",
|
|
57
|
+
"MutationPreconditionError",
|
|
58
|
+
"TholClosureError",
|
|
59
|
+
"TransitionCompatibilityError",
|
|
60
|
+
"SequenceSyntaxError",
|
|
61
|
+
"SequenceValidationResult",
|
|
62
|
+
"apply_glyph_with_grammar",
|
|
63
|
+
"enforce_canonical_grammar",
|
|
64
|
+
"on_applied_glyph",
|
|
65
|
+
"record_grammar_violation",
|
|
66
|
+
"ValidationOutcome",
|
|
67
|
+
"Validator",
|
|
68
|
+
"GraphCanonicalValidator",
|
|
69
|
+
"apply_canonical_clamps",
|
|
70
|
+
"validate_canon",
|
|
71
|
+
"GRAPH_VALIDATORS",
|
|
72
|
+
"run_validators",
|
|
73
|
+
"CANON_COMPAT",
|
|
74
|
+
"CANON_FALLBACK",
|
|
75
|
+
"validate_window",
|
|
76
|
+
"coerce_glyph",
|
|
77
|
+
"get_norm",
|
|
78
|
+
"glyph_fallback",
|
|
79
|
+
"normalized_dnfr",
|
|
80
|
+
"acceleration_norm",
|
|
81
|
+
"check_repeats",
|
|
82
|
+
"maybe_force",
|
|
83
|
+
"soft_grammar_filters",
|
|
84
|
+
"NFRValidator",
|
|
85
|
+
)
|