tnfr 4.3.0__tar.gz → 4.5.0__tar.gz
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-4.3.0/src/tnfr.egg-info → tnfr-4.5.0}/PKG-INFO +2 -2
- {tnfr-4.3.0 → tnfr-4.5.0}/README.md +1 -1
- {tnfr-4.3.0 → tnfr-4.5.0}/pyproject.toml +5 -4
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/__init__.py +40 -12
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/cli.py +53 -1
- tnfr-4.5.0/src/tnfr/config.py +41 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/constants.py +82 -25
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/dynamics.py +191 -42
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/gamma.py +17 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/helpers.py +33 -21
- tnfr-4.5.0/src/tnfr/metrics.py +597 -0
- tnfr-4.5.0/src/tnfr/node.py +202 -0
- tnfr-4.5.0/src/tnfr/operators.py +525 -0
- tnfr-4.5.0/src/tnfr/structural.py +201 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/types.py +2 -1
- tnfr-4.5.0/src/tnfr/validators.py +38 -0
- {tnfr-4.3.0 → tnfr-4.5.0/src/tnfr.egg-info}/PKG-INFO +2 -2
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr.egg-info/SOURCES.txt +11 -1
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_grammar.py +13 -0
- tnfr-4.5.0/tests/test_integrators.py +36 -0
- tnfr-4.5.0/tests/test_nav.py +32 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_remesh.py +2 -0
- tnfr-4.5.0/tests/test_remesh_community.py +18 -0
- tnfr-4.5.0/tests/test_structural.py +47 -0
- tnfr-4.5.0/tests/test_validators.py +38 -0
- tnfr-4.5.0/tests/test_vf_coherencia.py +27 -0
- tnfr-4.3.0/src/tnfr/metrics.py +0 -234
- tnfr-4.3.0/src/tnfr/operators.py +0 -352
- {tnfr-4.3.0 → tnfr-4.5.0}/LICENSE.md +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/setup.cfg +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/grammar.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/main.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/observers.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/ontosim.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/presets.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/program.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/scenarios.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/sense.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr/trace.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr.egg-info/dependency_links.txt +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr.egg-info/entry_points.txt +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr.egg-info/requires.txt +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/src/tnfr.egg-info/top_level.txt +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_canon.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_cli_sanity.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_edge_cases.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_gamma.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_history.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_history_series.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_invariants.py +0 -0
- {tnfr-4.3.0 → tnfr-4.5.0}/tests/test_program.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tnfr
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.5.0
|
|
4
4
|
Summary: Canonical TNFR: modular glyph-based dynamics on networks.
|
|
5
5
|
Author: fmg
|
|
6
6
|
License: MIT
|
|
@@ -25,7 +25,7 @@ License-File: LICENSE.md
|
|
|
25
25
|
Requires-Dist: networkx>=2.6
|
|
26
26
|
Dynamic: license-file
|
|
27
27
|
|
|
28
|
-
# TNFR
|
|
28
|
+
# TNFR Python Project
|
|
29
29
|
|
|
30
30
|
Reference implementation of the Resonant Fractal Nature Theory (TNFR).
|
|
31
31
|
It models glyph-driven dynamics on NetworkX graphs, providing a modular
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tnfr"
|
|
3
|
-
version = "4.
|
|
4
|
-
description = "Canonical TNFR: modular glyph-based dynamics on networks."
|
|
3
|
+
version = "4.5.0"
|
|
4
|
+
description = "Canonical TNFR: modular glyph-based dynamics on networks."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.9"
|
|
7
7
|
license = { text = "MIT" }
|
|
8
8
|
authors = [{ name = "fmg" }]
|
|
9
9
|
keywords = [
|
|
10
|
-
"TNFR", "resonant fractal", "resonance", "glyphs",
|
|
11
|
-
"networkx", "dynamics", "coherence", "EPI", "Kuramoto"
|
|
10
|
+
"TNFR", "resonant fractal", "resonance", "glyphs",
|
|
11
|
+
"networkx", "dynamics", "coherence", "EPI", "Kuramoto"
|
|
12
12
|
]
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Programming Language :: Python :: 3",
|
|
@@ -39,3 +39,4 @@ requires = ["setuptools>=61", "wheel"]
|
|
|
39
39
|
build-backend = "setuptools.build_meta"
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
|
|
@@ -8,10 +8,10 @@ Ecuación nodal:
|
|
|
8
8
|
∂EPI/∂t = νf · ΔNFR(t)
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = "4.
|
|
11
|
+
__version__ = "4.5.0"
|
|
12
12
|
|
|
13
13
|
# Re-exports de la API pública
|
|
14
|
-
from .dynamics import step, run, set_delta_nfr_hook, validate_canon
|
|
14
|
+
from .dynamics import step, run, set_delta_nfr_hook, validate_canon
|
|
15
15
|
from .ontosim import preparar_red
|
|
16
16
|
from .observers import attach_standard_observer, coherencia_global, orden_kuramoto
|
|
17
17
|
from .gamma import GAMMA_REGISTRY, eval_gamma, kuramoto_R_psi
|
|
@@ -22,23 +22,44 @@ from .sense import (
|
|
|
22
22
|
push_sigma_snapshot, sigma_series, sigma_rose,
|
|
23
23
|
register_sigma_callback,
|
|
24
24
|
)
|
|
25
|
-
from .metrics import (
|
|
26
|
-
register_metrics_callbacks,
|
|
27
|
-
Tg_global, Tg_by_node,
|
|
28
|
-
latency_series, glifogram_series,
|
|
29
|
-
glyph_top, glyph_dwell_stats, export_history,
|
|
30
|
-
)
|
|
25
|
+
from .metrics import (
|
|
26
|
+
register_metrics_callbacks,
|
|
27
|
+
Tg_global, Tg_by_node,
|
|
28
|
+
latency_series, glifogram_series,
|
|
29
|
+
glyph_top, glyph_dwell_stats, export_history,
|
|
30
|
+
)
|
|
31
|
+
from .operators import aplicar_remesh_red_topologico
|
|
31
32
|
from .trace import register_trace
|
|
32
33
|
from .program import play, seq, block, target, wait, THOL, TARGET, WAIT, ejemplo_canonico_basico
|
|
33
34
|
from .cli import main as cli_main
|
|
34
35
|
from .scenarios import build_graph
|
|
35
36
|
from .presets import get_preset
|
|
36
37
|
from .types import NodeState
|
|
38
|
+
from .structural import (
|
|
39
|
+
create_nfr,
|
|
40
|
+
Operador,
|
|
41
|
+
Emision,
|
|
42
|
+
Recepcion,
|
|
43
|
+
Coherencia,
|
|
44
|
+
Disonancia,
|
|
45
|
+
Acoplamiento,
|
|
46
|
+
Resonancia,
|
|
47
|
+
Silencio,
|
|
48
|
+
Expansion,
|
|
49
|
+
Contraccion,
|
|
50
|
+
Autoorganizacion,
|
|
51
|
+
Mutacion,
|
|
52
|
+
Transicion,
|
|
53
|
+
Recursividad,
|
|
54
|
+
OPERADORES,
|
|
55
|
+
validate_sequence,
|
|
56
|
+
run_sequence,
|
|
57
|
+
)
|
|
37
58
|
|
|
38
59
|
|
|
39
60
|
__all__ = [
|
|
40
|
-
"preparar_red",
|
|
41
|
-
"step", "run", "set_delta_nfr_hook", "validate_canon",
|
|
61
|
+
"preparar_red",
|
|
62
|
+
"step", "run", "set_delta_nfr_hook", "validate_canon",
|
|
42
63
|
|
|
43
64
|
"attach_standard_observer", "coherencia_global", "orden_kuramoto",
|
|
44
65
|
"GAMMA_REGISTRY", "eval_gamma", "kuramoto_R_psi",
|
|
@@ -51,11 +72,18 @@ __all__ = [
|
|
|
51
72
|
"register_trace",
|
|
52
73
|
"Tg_global", "Tg_by_node",
|
|
53
74
|
"latency_series", "glifogram_series",
|
|
54
|
-
"glyph_top", "glyph_dwell_stats",
|
|
55
|
-
"export_history",
|
|
75
|
+
"glyph_top", "glyph_dwell_stats",
|
|
76
|
+
"export_history",
|
|
77
|
+
"aplicar_remesh_red_topologico",
|
|
56
78
|
"play", "seq", "block", "target", "wait", "THOL", "TARGET", "WAIT",
|
|
57
79
|
"cli_main", "build_graph", "get_preset", "NodeState",
|
|
58
80
|
"ejemplo_canonico_basico",
|
|
81
|
+
"create_nfr",
|
|
82
|
+
"Operador", "Emision", "Recepcion", "Coherencia", "Disonancia",
|
|
83
|
+
"Acoplamiento", "Resonancia", "Silencio", "Expansion", "Contraccion",
|
|
84
|
+
"Autoorganizacion", "Mutacion", "Transicion", "Recursividad",
|
|
85
|
+
"OPERADORES", "validate_sequence", "run_sequence",
|
|
59
86
|
"__version__",
|
|
60
87
|
]
|
|
61
88
|
|
|
89
|
+
|
|
@@ -26,6 +26,7 @@ from .dynamics import step, _update_history, default_glyph_selector, parametric_
|
|
|
26
26
|
from .gamma import GAMMA_REGISTRY
|
|
27
27
|
from .scenarios import build_graph
|
|
28
28
|
from .presets import get_preset
|
|
29
|
+
from .config import apply_config
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def _save_json(path: str, data: Any) -> None:
|
|
@@ -91,8 +92,16 @@ def _attach_callbacks(G: nx.Graph) -> None:
|
|
|
91
92
|
|
|
92
93
|
def cmd_run(args: argparse.Namespace) -> int:
|
|
93
94
|
G = build_graph(n=args.nodes, topology=args.topology, seed=args.seed)
|
|
95
|
+
if getattr(args, "config", None):
|
|
96
|
+
apply_config(G, args.config)
|
|
94
97
|
_attach_callbacks(G)
|
|
95
98
|
validate_canon(G)
|
|
99
|
+
if args.dt is not None:
|
|
100
|
+
G.graph["DT"] = float(args.dt)
|
|
101
|
+
if args.integrator is not None:
|
|
102
|
+
G.graph["INTEGRATOR_METHOD"] = str(args.integrator)
|
|
103
|
+
if getattr(args, "remesh_mode", None):
|
|
104
|
+
G.graph["REMESH_MODE"] = str(args.remesh_mode)
|
|
96
105
|
gcanon = dict(DEFAULTS["GRAMMAR_CANON"])
|
|
97
106
|
gcanon.update(_args_to_dict(args, prefix="grammar."))
|
|
98
107
|
if hasattr(args, "grammar_canon") and args.grammar_canon is not None:
|
|
@@ -120,10 +129,25 @@ def cmd_run(args: argparse.Namespace) -> int:
|
|
|
120
129
|
if args.export_history_base:
|
|
121
130
|
export_history(G, args.export_history_base, fmt=args.export_format)
|
|
122
131
|
|
|
132
|
+
# Resúmenes rápidos (si están activados)
|
|
133
|
+
if G.graph.get("COHERENCE", DEFAULTS["COHERENCE"]).get("enabled", True):
|
|
134
|
+
Wstats = G.graph.get("history", {}).get(
|
|
135
|
+
G.graph.get("COHERENCE", DEFAULTS["COHERENCE"]).get("stats_history_key", "W_stats"), []
|
|
136
|
+
)
|
|
137
|
+
if Wstats:
|
|
138
|
+
print("[COHERENCE] último paso:", Wstats[-1])
|
|
139
|
+
if G.graph.get("DIAGNOSIS", DEFAULTS["DIAGNOSIS"]).get("enabled", True):
|
|
140
|
+
last_diag = G.graph.get("history", {}).get(
|
|
141
|
+
G.graph.get("DIAGNOSIS", DEFAULTS["DIAGNOSIS"]).get("history_key", "nodal_diag"), []
|
|
142
|
+
)
|
|
143
|
+
if last_diag:
|
|
144
|
+
sample = list(last_diag[-1].values())[:3]
|
|
145
|
+
print("[DIAGNOSIS] ejemplo:", sample)
|
|
146
|
+
|
|
123
147
|
if args.summary:
|
|
124
148
|
tg = Tg_global(G, normalize=True)
|
|
125
149
|
lat = latency_series(G)
|
|
126
|
-
print("Top
|
|
150
|
+
print("Top operadores por Tg:", glyph_top(G, k=5))
|
|
127
151
|
if lat["value"]:
|
|
128
152
|
print("Latencia media:", sum(lat["value"]) / max(1, len(lat["value"])) )
|
|
129
153
|
return 0
|
|
@@ -131,8 +155,16 @@ def cmd_run(args: argparse.Namespace) -> int:
|
|
|
131
155
|
|
|
132
156
|
def cmd_sequence(args: argparse.Namespace) -> int:
|
|
133
157
|
G = build_graph(n=args.nodes, topology=args.topology, seed=args.seed)
|
|
158
|
+
if getattr(args, "config", None):
|
|
159
|
+
apply_config(G, args.config)
|
|
134
160
|
_attach_callbacks(G)
|
|
135
161
|
validate_canon(G)
|
|
162
|
+
if args.dt is not None:
|
|
163
|
+
G.graph["DT"] = float(args.dt)
|
|
164
|
+
if args.integrator is not None:
|
|
165
|
+
G.graph["INTEGRATOR_METHOD"] = str(args.integrator)
|
|
166
|
+
if getattr(args, "remesh_mode", None):
|
|
167
|
+
G.graph["REMESH_MODE"] = str(args.remesh_mode)
|
|
136
168
|
gcanon = dict(DEFAULTS["GRAMMAR_CANON"])
|
|
137
169
|
gcanon.update(_args_to_dict(args, prefix="grammar."))
|
|
138
170
|
if hasattr(args, "grammar_canon") and args.grammar_canon is not None:
|
|
@@ -165,8 +197,16 @@ def cmd_sequence(args: argparse.Namespace) -> int:
|
|
|
165
197
|
|
|
166
198
|
def cmd_metrics(args: argparse.Namespace) -> int:
|
|
167
199
|
G = build_graph(n=args.nodes, topology=args.topology, seed=args.seed)
|
|
200
|
+
if getattr(args, "config", None):
|
|
201
|
+
apply_config(G, args.config)
|
|
168
202
|
_attach_callbacks(G)
|
|
169
203
|
validate_canon(G)
|
|
204
|
+
if args.dt is not None:
|
|
205
|
+
G.graph["DT"] = float(args.dt)
|
|
206
|
+
if args.integrator is not None:
|
|
207
|
+
G.graph["INTEGRATOR_METHOD"] = str(args.integrator)
|
|
208
|
+
if getattr(args, "remesh_mode", None):
|
|
209
|
+
G.graph["REMESH_MODE"] = str(args.remesh_mode)
|
|
170
210
|
G.graph.setdefault("GRAMMAR_CANON", DEFAULTS["GRAMMAR_CANON"]).update({"enabled": bool(args.grammar_canon)})
|
|
171
211
|
G.graph["glyph_selector"] = default_glyph_selector if args.selector == "basic" else parametric_glyph_selector
|
|
172
212
|
G.graph["GAMMA"] = {
|
|
@@ -205,10 +245,14 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
205
245
|
p_run.add_argument("--steps", type=int, default=200)
|
|
206
246
|
p_run.add_argument("--seed", type=int, default=1)
|
|
207
247
|
p_run.add_argument("--preset", type=str, default=None)
|
|
248
|
+
p_run.add_argument("--config", type=str, default=None)
|
|
249
|
+
p_run.add_argument("--dt", type=float, default=None)
|
|
250
|
+
p_run.add_argument("--integrator", choices=["euler", "rk4"], default=None)
|
|
208
251
|
p_run.add_argument("--save-history", dest="save_history", type=str, default=None)
|
|
209
252
|
p_run.add_argument("--export-history-base", dest="export_history_base", type=str, default=None)
|
|
210
253
|
p_run.add_argument("--export-format", dest="export_format", choices=["csv", "json"], default="json")
|
|
211
254
|
p_run.add_argument("--summary", action="store_true")
|
|
255
|
+
p_run.add_argument("--remesh-mode", choices=["knn", "mst", "community"], default=None)
|
|
212
256
|
p_run.add_argument("--no-canon", dest="grammar_canon", action="store_false", default=True, help="Desactiva gramática canónica")
|
|
213
257
|
p_run.add_argument("--grammar.enabled", dest="grammar_enabled", type=_str2bool, default=None)
|
|
214
258
|
p_run.add_argument("--grammar.zhir_requires_oz_window", dest="grammar_zhir_requires_oz_window", type=int, default=None)
|
|
@@ -230,9 +274,13 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
230
274
|
p_seq.add_argument("--seed", type=int, default=1)
|
|
231
275
|
p_seq.add_argument("--preset", type=str, default=None)
|
|
232
276
|
p_seq.add_argument("--sequence-file", type=str, default=None)
|
|
277
|
+
p_seq.add_argument("--config", type=str, default=None)
|
|
278
|
+
p_seq.add_argument("--dt", type=float, default=None)
|
|
279
|
+
p_seq.add_argument("--integrator", choices=["euler", "rk4"], default=None)
|
|
233
280
|
p_seq.add_argument("--save-history", dest="save_history", type=str, default=None)
|
|
234
281
|
p_seq.add_argument("--export-history-base", dest="export_history_base", type=str, default=None)
|
|
235
282
|
p_seq.add_argument("--export-format", dest="export_format", choices=["csv", "json"], default="json")
|
|
283
|
+
p_seq.add_argument("--remesh-mode", choices=["knn", "mst", "community"], default=None)
|
|
236
284
|
p_seq.add_argument("--gamma-type", choices=list(GAMMA_REGISTRY.keys()), default="none")
|
|
237
285
|
p_seq.add_argument("--gamma-beta", type=float, default=0.0)
|
|
238
286
|
p_seq.add_argument("--gamma-R0", type=float, default=0.0)
|
|
@@ -251,12 +299,16 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
251
299
|
p_met.add_argument("--topology", choices=["ring", "complete", "erdos"], default="ring")
|
|
252
300
|
p_met.add_argument("--steps", type=int, default=300)
|
|
253
301
|
p_met.add_argument("--seed", type=int, default=1)
|
|
302
|
+
p_met.add_argument("--dt", type=float, default=None)
|
|
303
|
+
p_met.add_argument("--integrator", choices=["euler", "rk4"], default=None)
|
|
254
304
|
p_met.add_argument("--no-canon", dest="grammar_canon", action="store_false", default=True, help="Desactiva gramática canónica")
|
|
255
305
|
p_met.add_argument("--selector", choices=["basic", "param"], default="basic")
|
|
256
306
|
p_met.add_argument("--gamma-type", choices=list(GAMMA_REGISTRY.keys()), default="none")
|
|
257
307
|
p_met.add_argument("--gamma-beta", type=float, default=0.0)
|
|
258
308
|
p_met.add_argument("--gamma-R0", type=float, default=0.0)
|
|
309
|
+
p_met.add_argument("--remesh-mode", choices=["knn", "mst", "community"], default=None)
|
|
259
310
|
p_met.add_argument("--save", type=str, default=None)
|
|
311
|
+
p_met.add_argument("--config", type=str, default=None)
|
|
260
312
|
p_met.set_defaults(func=cmd_metrics)
|
|
261
313
|
|
|
262
314
|
args = p.parse_args(argv)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Carga e inyección de configuraciones externas.
|
|
2
|
+
|
|
3
|
+
Permite definir parámetros en JSON o YAML y aplicarlos sobre ``G.graph``
|
|
4
|
+
reutilizando :func:`tnfr.constants.inject_defaults`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from typing import Any, Dict
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
try: # pragma: no cover - dependencia opcional
|
|
12
|
+
import yaml # type: ignore
|
|
13
|
+
except Exception: # pragma: no cover
|
|
14
|
+
yaml = None
|
|
15
|
+
|
|
16
|
+
from .constants import inject_defaults
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def load_config(path: str) -> Dict[str, Any]:
|
|
20
|
+
"""Lee un archivo JSON/YAML y devuelve un ``dict`` con los parámetros."""
|
|
21
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
22
|
+
text = f.read()
|
|
23
|
+
if path.endswith((".yaml", ".yml")):
|
|
24
|
+
if not yaml: # pragma: no cover - fallo en entorno sin pyyaml
|
|
25
|
+
raise RuntimeError("pyyaml no está instalado")
|
|
26
|
+
data = yaml.safe_load(text)
|
|
27
|
+
else:
|
|
28
|
+
data = json.loads(text)
|
|
29
|
+
if not isinstance(data, dict):
|
|
30
|
+
raise ValueError("El archivo de configuración debe contener un objeto")
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def apply_config(G, path: str) -> None:
|
|
35
|
+
"""Inyecta parámetros desde ``path`` sobre ``G.graph``.
|
|
36
|
+
|
|
37
|
+
Se reutiliza :func:`inject_defaults` para mantener la semántica de los
|
|
38
|
+
*defaults* canónicos.
|
|
39
|
+
"""
|
|
40
|
+
cfg = load_config(path)
|
|
41
|
+
inject_defaults(G, cfg, override=True)
|
|
@@ -11,8 +11,10 @@ from typing import Dict, Any
|
|
|
11
11
|
# Parámetros canónicos
|
|
12
12
|
# -------------------------
|
|
13
13
|
DEFAULTS: Dict[str, Any] = {
|
|
14
|
-
# Discretización
|
|
15
|
-
"DT": 1.0,
|
|
14
|
+
# Discretización
|
|
15
|
+
"DT": 1.0,
|
|
16
|
+
"INTEGRATOR_METHOD": "euler",
|
|
17
|
+
"DT_MIN": 0.1,
|
|
16
18
|
|
|
17
19
|
# Rango de EPI (estructura primaria)
|
|
18
20
|
"EPI_MIN": -1.0,
|
|
@@ -43,9 +45,10 @@ DEFAULTS: Dict[str, Any] = {
|
|
|
43
45
|
"INIT_VF_CLAMP_TO_LIMITS": True,
|
|
44
46
|
|
|
45
47
|
|
|
46
|
-
# Mezcla para ΔNFR (campo nodal)
|
|
47
|
-
# phase: dispersión de fase local; epi: gradiente de EPI; vf: desajuste de νf
|
|
48
|
-
|
|
48
|
+
# Mezcla para ΔNFR (campo nodal)
|
|
49
|
+
# phase: dispersión de fase local; epi: gradiente de EPI; vf: desajuste de νf;
|
|
50
|
+
# topo: término topológico (p. ej., centralidad). Pesos se normalizan.
|
|
51
|
+
"DNFR_WEIGHTS": {"phase": 0.34, "epi": 0.33, "vf": 0.33, "topo": 0.0},
|
|
49
52
|
|
|
50
53
|
# Índice de sentido Si = α·νf_norm + β·(1 - disp_fase) + γ·(1 - |ΔNFR|/max)
|
|
51
54
|
"SI_WEIGHTS": {"alpha": 0.34, "beta": 0.33, "gamma": 0.33},
|
|
@@ -76,7 +79,7 @@ DEFAULTS: Dict[str, Any] = {
|
|
|
76
79
|
"REMESH_COOLDOWN_VENTANA": 20, # pasos mínimos entre RE’MESH
|
|
77
80
|
"REMESH_COOLDOWN_TS": 0.0, # cooldown adicional por tiempo simulado
|
|
78
81
|
# Gating adicional basado en observadores (conmutador + ventana)
|
|
79
|
-
"REMESH_REQUIRE_STABILITY":
|
|
82
|
+
"REMESH_REQUIRE_STABILITY": True, # si True, exige ventana de estabilidad multi-métrica
|
|
80
83
|
"REMESH_STABILITY_WINDOW": 25, # tamaño de ventana para evaluar estabilidad
|
|
81
84
|
"REMESH_MIN_PHASE_SYNC": 0.85, # media mínima de sincronía de fase en ventana
|
|
82
85
|
"REMESH_MAX_GLYPH_DISR": 0.35, # media máxima de carga glífica disruptiva en ventana
|
|
@@ -84,6 +87,8 @@ DEFAULTS: Dict[str, Any] = {
|
|
|
84
87
|
"REMESH_MIN_KURAMOTO_R": 0.80, # R de Kuramoto mínimo en ventana
|
|
85
88
|
"REMESH_MIN_SI_HI_FRAC": 0.50, # fracción mínima de nodos con Si alto
|
|
86
89
|
"REMESH_LOG_EVENTS": True, # guarda eventos y metadatos del RE’MESH
|
|
90
|
+
"REMESH_MODE": "knn", # modo de remallado topológico
|
|
91
|
+
"REMESH_COMMUNITY_K": 2, # conexiones por comunidad
|
|
87
92
|
|
|
88
93
|
# RE’MESH: memoria τ y mezcla α (global/local)
|
|
89
94
|
"REMESH_TAU": 8, # compatibilidad: tau global por defecto
|
|
@@ -91,23 +96,37 @@ DEFAULTS: Dict[str, Any] = {
|
|
|
91
96
|
"REMESH_TAU_LOCAL": 4, # pasos hacia atrás (escala local)
|
|
92
97
|
"REMESH_ALPHA": 0.5, # mezcla con pasado
|
|
93
98
|
"REMESH_ALPHA_HARD": False, # si True ignora GLYPH_FACTORS['REMESH_alpha']
|
|
99
|
+
|
|
100
|
+
# Soporte y norma de la EPI
|
|
101
|
+
"EPI_SUPPORT_THR": 0.05, # umbral para Supp(EPI)
|
|
102
|
+
|
|
103
|
+
# U'M — compatibilidad mínima para crear/reforzar enlaces funcionales
|
|
104
|
+
"UM_COMPAT_THRESHOLD": 0.75,
|
|
94
105
|
|
|
95
|
-
# Histéresis glífica
|
|
96
|
-
"GLYPH_HYSTERESIS_WINDOW": 7,
|
|
97
|
-
|
|
98
|
-
#
|
|
99
|
-
"
|
|
106
|
+
# Histéresis glífica
|
|
107
|
+
"GLYPH_HYSTERESIS_WINDOW": 7,
|
|
108
|
+
|
|
109
|
+
# Lags máximos sin emisión (A’L) y recepción (E’N)
|
|
110
|
+
"AL_MAX_LAG": 5,
|
|
111
|
+
"EN_MAX_LAG": 3,
|
|
112
|
+
|
|
113
|
+
# Margen de histéresis del selector (cuánto "aguanta" sin cambiar glifo si está cerca de un umbral)
|
|
114
|
+
"GLYPH_SELECTOR_MARGIN": 0.05,
|
|
100
115
|
|
|
101
|
-
# Ventana para estimar la carga glífica en history/plots
|
|
116
|
+
# Ventana para estimar la carga glífica en history/plots
|
|
102
117
|
"GLYPH_LOAD_WINDOW": 50,
|
|
103
|
-
|
|
104
|
-
# Tamaño de ventana para coherencia promedio W̄
|
|
105
|
-
"WBAR_WINDOW": 25,
|
|
106
|
-
|
|
107
|
-
#
|
|
118
|
+
|
|
119
|
+
# Tamaño de ventana para coherencia promedio W̄
|
|
120
|
+
"WBAR_WINDOW": 25,
|
|
121
|
+
|
|
122
|
+
# Adaptación de frecuencia estructural por coherencia
|
|
123
|
+
"VF_ADAPT_TAU": 5, # pasos estables antes de ajustar νf
|
|
124
|
+
"VF_ADAPT_MU": 0.1, # velocidad de ajuste hacia la media vecinal
|
|
125
|
+
|
|
126
|
+
# Factores suaves por glifo (operadores)
|
|
108
127
|
"GLYPH_FACTORS": {
|
|
109
|
-
"AL_boost": 0.05, # A’L — pequeña emisión
|
|
110
|
-
"EN_mix": 0.25, # E’N — mezcla con vecindad
|
|
128
|
+
"AL_boost": 0.05, # A’L — pequeña emisión
|
|
129
|
+
"EN_mix": 0.25, # E’N — mezcla con vecindad
|
|
111
130
|
"IL_dnfr_factor": 0.7, # I’L — reduce ΔNFR
|
|
112
131
|
"OZ_dnfr_factor": 1.3, # O’Z — aumenta ΔNFR
|
|
113
132
|
"UM_theta_push": 0.25, # U’M — empuje adicional de fase local
|
|
@@ -116,17 +135,19 @@ DEFAULTS: Dict[str, Any] = {
|
|
|
116
135
|
"VAL_scale": 1.15, # VA’L — expande EPI
|
|
117
136
|
"NUL_scale": 0.85, # NU’L — contrae EPI
|
|
118
137
|
"THOL_accel": 0.10, # T’HOL — acelera (seg. deriv.) si hay umbral
|
|
119
|
-
"ZHIR_theta_shift": 1.57079632679, # Z’HIR — desplazamiento ~π/2
|
|
120
|
-
"NAV_jitter": 0.05, # NA’V — pequeña inestabilidad creativa
|
|
121
|
-
"
|
|
122
|
-
|
|
138
|
+
"ZHIR_theta_shift": 1.57079632679, # Z’HIR — desplazamiento ~π/2
|
|
139
|
+
"NAV_jitter": 0.05, # NA’V — pequeña inestabilidad creativa
|
|
140
|
+
"NAV_eta": 0.5, # NA’V — peso de convergencia hacia νf
|
|
141
|
+
"REMESH_alpha": 0.5, # RE’MESH — mezcla si no se usa REMESH_ALPHA
|
|
142
|
+
},
|
|
123
143
|
|
|
124
144
|
# Umbrales para el selector glífico por defecto
|
|
125
145
|
"GLYPH_THRESHOLDS": {"hi": 0.66, "lo": 0.33, "dnfr": 1e-3},
|
|
126
146
|
|
|
127
147
|
# Comportamiento NA’V
|
|
128
|
-
"NAV_RANDOM": True, # si True, usa jitter aleatorio en [-j, j]; si False, jitter determinista por signo
|
|
129
|
-
"
|
|
148
|
+
"NAV_RANDOM": True, # si True, usa jitter aleatorio en [-j, j]; si False, jitter determinista por signo
|
|
149
|
+
"NAV_STRICT": False, # si True, fuerza ΔNFR ← νf (sin mezcla)
|
|
150
|
+
"RANDOM_SEED": 0, # semilla base para reproducibilidad del jitter
|
|
130
151
|
|
|
131
152
|
# Modo ruido para O’Z
|
|
132
153
|
"OZ_NOISE_MODE": False, # si True, añade ruido aditivo en ΔNFR
|
|
@@ -174,6 +195,41 @@ DEFAULTS.setdefault("GRAMMAR_CANON", {
|
|
|
174
195
|
"thol_close_dnfr": 0.15, # si el campo calma, cerramos con SH’A/NU’L
|
|
175
196
|
"si_high": 0.66, # umbral para elegir NU’L vs SH’A al cerrar
|
|
176
197
|
})
|
|
198
|
+
|
|
199
|
+
# --- Coherencia (W) ---
|
|
200
|
+
DEFAULTS.setdefault("COHERENCE", {
|
|
201
|
+
"enabled": True,
|
|
202
|
+
"scope": "neighbors", # "neighbors" | "all"
|
|
203
|
+
"weights": {
|
|
204
|
+
"phase": 0.34,
|
|
205
|
+
"epi": 0.33,
|
|
206
|
+
"vf": 0.20,
|
|
207
|
+
"si": 0.13,
|
|
208
|
+
},
|
|
209
|
+
"self_on_diag": True, # W_ii = 1.0
|
|
210
|
+
"store_mode": "sparse", # "sparse" | "dense"
|
|
211
|
+
"threshold": 0.0,
|
|
212
|
+
"history_key": "W_sparse",
|
|
213
|
+
"Wi_history_key": "W_i",
|
|
214
|
+
"stats_history_key": "W_stats",
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
# --- Diagnóstico nodal ---
|
|
218
|
+
DEFAULTS.setdefault("DIAGNOSIS", {
|
|
219
|
+
"enabled": True,
|
|
220
|
+
"window": 16,
|
|
221
|
+
"history_key": "nodal_diag",
|
|
222
|
+
"stable": {"Rloc_hi": 0.80, "dnfr_lo": 0.20, "persist": 3},
|
|
223
|
+
"dissonance": {"Rloc_lo": 0.40, "dnfr_hi": 0.50, "persist": 3},
|
|
224
|
+
"transition": {"persist": 2},
|
|
225
|
+
"compute_symmetry": True,
|
|
226
|
+
"include_typology": False,
|
|
227
|
+
"advice": {
|
|
228
|
+
"stable": ["Coherencia", "Acoplamiento", "Resonancia"],
|
|
229
|
+
"transition": ["Transición", "Resonancia", "Autoorganización"],
|
|
230
|
+
"dissonant": ["Silencio", "Contracción", "Mutación"],
|
|
231
|
+
},
|
|
232
|
+
})
|
|
177
233
|
|
|
178
234
|
|
|
179
235
|
# -------------------------
|
|
@@ -212,6 +268,7 @@ ALIAS_VF = ("νf", "nu_f", "nu-f", "nu", "freq", "frequency")
|
|
|
212
268
|
ALIAS_THETA = ("θ", "theta", "fase", "phi", "phase")
|
|
213
269
|
ALIAS_DNFR = ("ΔNFR", "delta_nfr", "dnfr")
|
|
214
270
|
ALIAS_EPI = ("EPI", "psi", "PSI", "value")
|
|
271
|
+
ALIAS_EPI_KIND = ("EPI_kind", "epi_kind", "source_glifo")
|
|
215
272
|
ALIAS_SI = ("Si", "sense_index", "S_i", "sense", "meaning_index")
|
|
216
273
|
ALIAS_dEPI = ("dEPI_dt", "dpsi_dt", "dEPI", "velocity")
|
|
217
274
|
ALIAS_D2EPI = ("d2EPI_dt2", "d2psi_dt2", "d2EPI", "accel")
|