Modular structural-based dynamics on networks.
Project description
TNFR Python Engine
Engine for modeling, simulation and measurement of multiscale structural coherence through structural operators (emission, reception, coherence, dissonance, coupling, resonance, silence, expansion, contraction, self‑organization, mutation, transition, recursivity).
What is tnfr?
tnfr is a Python library to operate with form: build nodes, couple them into networks, and modulate their coherence over time using structural operators. It does not describe “things”; it activates processes. Its theoretical basis is the Teoria de la Naturaleza Fractal Resonante (TNFR), which understands reality as networks of coherence that persist because they resonate.
In practical terms, tnfr lets you:
- Model Resonant Fractal Nodes (NFR) with parameters for frequency (νf), phase (θ), and form (EPI). Use the ASCII constants
VF_KEYandTHETA_KEYto reference these attributes programmatically; the Unicode names remain available as aliases. - Apply structural operators to start, stabilize, propagate, or reconfigure coherence.
- Simulate nodal dynamics with discrete/continuous integrators.
- Measure global coherence C(t), nodal gradient ΔNFR, and the Sense Index (Si).
- Visualize states and trajectories (coupling matrices, C(t) curves, graphs).
A form emerges and persists when internal reorganization (ΔNFR) resonates with the node’s frequency (νf).
Quick start
Desde Python
from tnfr import create_nfr, run_sequence
from tnfr.structural import (
Emision,
Recepcion,
Coherencia,
Resonancia,
Silencio,
)
from tnfr.metrics.common import compute_coherence
from tnfr.metrics.sense_index import compute_Si
G, nodo = create_nfr("A", epi=0.2, vf=1.0, theta=0.0)
ops = [Emision(), Recepcion(), Coherencia(), Resonancia(), Silencio()]
run_sequence(G, nodo, ops)
C, delta_nfr_medio, depi_medio = compute_coherence(G, return_means=True)
si_por_nodo = compute_Si(G)
print(f"C(t)={C:.3f}, ΔNFR̄={delta_nfr_medio:.3f}, dEPI/dt̄={depi_medio:.3f}, Si={si_por_nodo[nodo]:.3f}")
La secuencia respeta la ecuación nodal porque create_nfr inicializa el nodo con su νf y fase, y run_sequence valida la gramática TNFR antes de aplicar los operadores en el orden provisto. Tras cada operador invoca el gancho compute_delta_nfr del grafo para recalcular únicamente ΔNFR (por defecto usa dnfr_epi_vf_mixed, que mezcla EPI y νf sin alterar la fase). La fase solo cambiará si los propios operadores la modifican o si se ejecutan pasos dinámicos posteriores (por ejemplo tnfr.dynamics.step o coordinate_global_local_phase). Cuando necesites sincronización de fase automática, utiliza el ciclo de dinámica completo (tnfr.dynamics.step/tnfr.dynamics.run) o invoca explícitamente los coordinadores de fase después de run_sequence. Esa telemetría permite medir C(t) y Si, adelantando lo que se desarrolla en Key concepts (operational summary) y Main metrics.
Desde la línea de comandos
Archivo secuencia.json:
[
"emision",
"recepcion",
"coherencia",
"resonancia",
"silencio"
]
tnfr sequence --nodes 1 --sequence-file secuencia.json --save-history historia.json
El subcomando sequence carga la trayectoria canónica del archivo JSON, ejecuta los operadores con la gramática oficial y actualiza νf, ΔNFR y fase usando los mismos ganchos que la API de Python. Al finalizar se vuelcan en historia.json las series de C(t), ΔNFR medio y Si, que amplían las secciones sobre operadores estructurales y métricas.
Installation
pip install tnfr
- https://pypi.org/project/tnfr/
- Requires Python ≥ 3.9.
- Install extras:
- NumPy:
pip install tnfr[numpy] - YAML:
pip install tnfr[yaml] - orjson (faster JSON serialization):
pip install tnfr[orjson] - All:
pip install tnfr[numpy,yaml,orjson]
- NumPy:
- When
orjsonis unavailable the engine falls back to Python's built-injsonmodule.
Optional imports with cache
Use tnfr.cached_import to load optional dependencies and cache the result
via a process-wide LRU cache. Missing modules (or attributes) yield None
without triggering repeated imports. The helper records failures and emits a
single warning per module to keep logs tidy. When optional packages are
installed at runtime call prune_failed_imports to clear the consolidated
failure/warning registry before retrying:
from tnfr import cached_import, prune_failed_imports
np = cached_import("numpy")
safe_load = cached_import("yaml", "safe_load")
# provide a shared cache with an explicit lock
from cachetools import TTLCache
import threading
cache = TTLCache(32, 60)
lock = threading.Lock()
cached_import("numpy", cache=cache, lock=lock)
# clear caches after installing a dependency at runtime
cached_import.cache_clear()
prune_failed_imports()
Tests
Run the test suite from the project root using the helper script, which sets
the necessary PYTHONPATH and mirrors the checks described in
CONTRIBUTING.md:
./scripts/run_tests.sh
The script sequentially executes pydocstyle, pytest under coverage, the
coverage summary, and vulture --min-confidence 80 src tests. Avoid running
pytest directly or executing the script from other directories, as the
environment may be misconfigured and imports will fail. To pass additional
flags to pytest, append them after --, for example:
./scripts/run_tests.sh -- -k coherence
Locking policy
The engine centralises reusable process-wide locks in
tnfr.locking. Modules obtain named locks via locking.get_lock() and
use the returned threading.Lock in their own critical sections. This
avoids scattering threading.Lock instances across the codebase and
ensures that shared resources are synchronised consistently.
Module-level caches or global state should always use these named
locks; only short-lived objects may instantiate ad-hoc locks directly
when they are not shared.
Callback error handling
Callback errors are stored in a ring buffer attached to the graph. The
buffer retains at most the last 100 errors by default, but the limit can be
adjusted at runtime via tnfr.callback_utils.callback_manager.set_callback_error_limit
and inspected with tnfr.callback_utils.callback_manager.get_callback_error_limit.
Helper utilities API
tnfr.helpers bundles a compact set of public helpers that stay stable across
releases. They provide ergonomic access to the most common preparation steps
when orchestrating TNFR experiments.
Collections and numeric helpers
ensure_collection(it, *, max_materialize=...)— materialize potentially lazy iterables once, enforcing a configurable limit to keep simulations bounded.clamp(x, a, b)andclamp01(x)— restrict scalars to safe ranges for operator parameters.kahan_sum_nd(values, dims)— numerically stable accumulators used to track coherence magnitudes across long trajectories (usedims=1for scalars,dims=2for paired values, etc.).angle_diff(a, b)— compute minimal angular differences (radians) to compare structural phases.
Historial de operadores estructurales
push_glyph(nd, glyph, window)— registra la aplicación de un operador en el historial del nodo respetando la ventana configurada.recent_glyph(nd, glyph, window)— comprueba si un operador específico aparece en el historial reciente de un nodo.ensure_history(G)— prepare the graph-level history container with the appropriate bounds.last_glyph(nd)— inspecciona el último operador emitido por un nodo.count_glyphs(G, window=None, *, last_only=False)— agrega el uso de operadores estructurales en la red ya sea desde todo el historial o una ventana limitada.
Graph caches and ΔNFR invalidation
cached_node_list(G)— lazily cache a stable tuple of node identifiers, respecting opt-in sorted ordering.ensure_node_index_map(G)/ensure_node_offset_map(G)— expose cached index and offset mappings for graphs that need to project nodes to arrays.node_set_checksum(G, nodes=None, *, presorted=False, store=True)— produce deterministic BLAKE2b hashes to detect topology changes.stable_json(obj)— render deterministic JSON strings suited for hashing and reproducible logs.get_graph(obj)/get_graph_mapping(G, key, warn_msg)— normalise access to graph-level metadata regardless of wrappers.EdgeCacheManagertogether withedge_version_cache,cached_nodes_and_Aandedge_version_updateencapsulate the edge version cache.increment_edge_versionbumps the version manually for imperative workflows.mark_dnfr_prep_dirty(G)— invalidate precomputed ΔNFR preparation when mutating edges outside the cache helpers.
Why TNFR (in 60 seconds)
- From objects to coherences: you model processes that hold, not fixed entities.
- Operators instead of rules: you compose structural operators (e.g., emission, coherence, dissonance) to build trajectories.
- Operational fractality: the same pattern works for ideas, teams, tissues, narratives; the scales change, the logic doesn’t.
Key concepts (operational summary)
-
Node (NFR): a unit that persists because it resonates. Parameterized by νf (frequency), θ (phase), and EPI (coherent form).
-
Structural operators - functions that reorganize the network:
- Emission (start), Reception (open), Coherence (stabilize), Dissonance (creative tension), Coupling (synchrony), Resonance (propagate), Silence (latency), Expansion, Contraction, Self‑organization, Mutation, Transition, Recursivity.
-
Magnitudes:
- C(t): global coherence.
- ΔNFR: nodal gradient (need for reorganization).
- νf: structural frequency (Hz_str).
- Si: sense index (ability to generate stable shared coherence).
Typical workflow
- Model your system as a network: nodes (agents, ideas, tissues, modules) and couplings.
- Select a trajectory of operators aligned with your goal (e.g., start → couple → stabilize).
- Simulate the dynamics: number of steps, step size, tolerances.
- Measure: C(t), ΔNFR, Si; identify bifurcations and collapses.
- Iterate with controlled dissonance to open mutations without losing form.
Main metrics
coherence(traj) → C(t): global stability; higher values indicate sustained form.gradient(state) → ΔNFR: local demand for reorganization (high = risk of collapse/bifurcation).sense_index(traj) → Si: proxy for structural sense (capacity to generate shared coherence) combining νf, phase, and topology.
Topological remeshing
Use tnfr.operators.apply_topological_remesh (from tnfr.operators import apply_topological_remesh)
to reorganize connectivity based on nodal EPI similarity while preserving
graph connectivity. Modes:
"knn"– connect each node to itsknearest neighbours (with optional rewiring)."mst"– retain only a minimum spanning tree."community"– collapse modular communities and reconnect them by similarity.
All modes ensure connectivity by adding a base MST.
History configuration
Recorded series are stored under G.graph['history']. Set HISTORY_MAXLEN in
the graph (or override the default) to keep only the most recent entries. The
value must be non‑negative; negative values raise ValueError. When the
limit is positive the library uses bounded deque objects and removes the
least populated series when the number of history keys grows beyond the limit.
Random node sampling
To reduce costly comparisons the engine stores a per‑step random subset of
node ids under G.graph['_node_sample']. Operators may use this to avoid
scanning the whole network. Sampling is skipped automatically when the graph
has fewer than 50 nodes, in which case all nodes are included.
Jitter RNG cache
random_jitter uses an LRU cache of random.Random instances keyed by (seed, node).
JITTER_CACHE_SIZE controls the maximum number of cached generators (default: 256);
when the limit is exceeded the least‑recently used entry is discarded. Increase it for
large graphs or heavy jitter usage, or lower it to save memory.
To adjust the number of cached jitter sequences used for deterministic noise,
obtain the manager with get_jitter_manager before calling setup:
from tnfr.operators import get_jitter_manager
manager = get_jitter_manager()
# Resize cache to keep only 512 entries
manager.max_entries = 512
# or in a single call that also clears previous counters
manager.setup(max_entries=512)
setup preserves the current size unless a new max_entries value is
supplied. Custom sizes persist across subsequent setup calls, and
max_entries assignments take effect immediately.
Edge version tracking
Wrap sequences of edge mutations with edge_version_update(G) so the edge
version increments on entry and exit. This keeps caches and structural logs
aligned with the network's evolution.
Defaults injection performance
inject_defaults evita copias profundas cuando los valores son inmutables (números,
cadenas, tuplas). Solo se usa copy.deepcopy para estructuras mutables, reduciendo
el costo de inicializar grafos con parámetros por defecto.
Trained GPT
Changelog
- Removed deprecated alias
sigma_vector_global; usesigma_vector_from_graphinstead. - Removed legacy
tnfr.programalias; import programming helpers fromtnfr.execution. - Stopped re-exporting
CallbackSpecandapply_topological_remeshat the package root; import them viatnfr.traceandtnfr.operators.
MIT License
Copyright (c) 2025 TNFR - Teoría de la naturaleza fractral resonante
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
If you use tnfr in research or projects, please cite the TNFR conceptual framework and link to the PyPI package.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tnfr-4.5.2.tar.gz.
File metadata
- Download URL: tnfr-4.5.2.tar.gz
- Upload date:
- Size: 193.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dee16f87485ac97768590c618fcc136f5ea0ef9e3a5eff602477049fd4840b2b
|
|
| MD5 |
ac9ad361b2a2c086a72c93a761e9626c
|
|
| BLAKE2b-256 |
34f31047790a77c928340e32f3f708ef94f9900abda2458af019579888a99ae6
|
File details
Details for the file tnfr-4.5.2-py3-none-any.whl.
File metadata
- Download URL: tnfr-4.5.2-py3-none-any.whl
- Upload date:
- Size: 143.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45a81c9b2e53d9363a5d1f6002531cb7224bc2d1455e25f4107c8522c483659f
|
|
| MD5 |
722117f38f0c13994e705359f7e297c1
|
|
| BLAKE2b-256 |
e0eb7a512fb4e3ab921d834571779925c3faafd038c5781a25c84c0e960be78a
|