Narrative graph stability analysis using eigenmode decomposition and spectral perturbation theory.
Project description
spectral-narrative-analysis
A Python package for analyzing narrative graph stability using eigenmode decomposition and spectral perturbation theory.
Narrative graphs are converted into operator matrices whose eigenmodes represent dominant narrative patterns. Evidence shocks are modeled as perturbations, and eigenmode shifts measure how structurally stable — or fragile — a narrative is.
Why this exists
Existing tools can tell you what events happened or how confident you are in them. This package asks a different question:
If new evidence appears, does the entire narrative structure change — or just one edge?
spectral-narrative-analysis answers this by treating the narrative as an operator system:
- Dominant eigenmodes = stable narrative patterns
- Eigenvalue magnitude = how strongly that pattern dominates
- Spectral perturbation = what happens when evidence shocks the system
- Eigenvector shift = whether the core narrative axis changed
This is inspired by the Seoul Interpretation of Quantum Mechanics (SIQM), which treats state description (상태서술) not as a fixed entity but as a structured organization of events and evidence.
Installation
pip install spectral-narrative-analysis
With optional scipy for optimal mode matching:
pip install spectral-narrative-analysis "scipy"
Requires Python 3.10 or later. Core dependency: numpy.
Quick start
from sna import (
NarrativeNode,
NarrativeEdge,
PerturbationEntry,
SpectralConfig,
NarrativeStabilityAnalyzer,
)
# 1. Define nodes (confidence can come from evidence-confidence-propagation)
nodes = [
NarrativeNode(id="kain", label="Kain Incident", confidence=0.9),
NarrativeNode(id="rift", label="Rift Opening", confidence=0.8),
NarrativeNode(id="archive", label="Archive Fall", confidence=0.7),
]
# 2. Define edges (p_forward can come from temporal-belief-graph)
edges = [
NarrativeEdge(source_id="kain", target_id="rift", p_forward=0.9, confidence=0.8),
NarrativeEdge(source_id="rift", target_id="archive", p_forward=0.8, confidence=0.7),
]
# 3. Define a perturbation (new evidence shock)
perturbations = [
PerturbationEntry(
source_id="kain", target_id="rift",
delta=0.5,
note="New official source confirms Kain caused the Rift.",
)
]
# 4. Analyze
analyzer = NarrativeStabilityAnalyzer()
result = analyzer.analyze(nodes, edges, perturbations)
print(result.stability_score) # float in [0, 1]
print(result.stability_label) # stable / moderate / fragile / unstable
print(result.regime_changed) # True if dominant narrative node shifted
print(result.report()) # full Markdown report
print(result.summary()) # compact dict
A full working example is in examples/basic_usage.py.
Core concepts
Narrative Operator
The narrative graph is converted into a matrix A where:
A[i, j] = node_factor(i, j) × p_forward × confidence × causal_strength
Default node factor: sqrt(source.confidence × target.confidence)
Three symmetry modes:
| Mode | Construction | Use case |
|---|---|---|
symmetric |
(A + A.T) / 2 |
Real eigenvalues, clean analysis |
directed |
raw A |
Preserves causal direction |
undirected_laplacian |
D - (A + A.T)/2 |
Structural clustering |
directed_laplacian |
D - A |
Direction-sensitive stability |
Eigenmodes
Eigenmodes of A represent dominant narrative patterns. The most dominant eigenmode (largest eigenvalue magnitude) tells you which nodes are central to the current narrative structure.
Spectral Perturbation
When new evidence appears, a perturbation matrix V is constructed:
A' = A + epsilon × V
Three perturbation modes:
| Mode | Formula | Use case |
|---|---|---|
raw |
A + εV |
Default; unconstrained experiments |
bounded |
clip(A + εV, min, max) |
Confidence-bounded systems |
relative |
A × (1 + εV) |
Proportional strengthening/weakening |
Mode Matching
After perturbation, eigenmodes may reorder. SNA matches original and perturbed modes using:
cost = (1 - eigenvector_overlap) + 0.05 × relative_eigenvalue_gap
| Method | Complexity | When used |
|---|---|---|
hungarian |
polynomial | scipy available (best) |
permutation |
O(k!) | small k, no scipy |
greedy |
O(k² log k) | fallback |
auto |
adaptive | default |
Stability Score
stability = exp(-alpha × instability)
| Score | Label |
|---|---|
| ≥ 0.85 | stable |
| ≥ 0.60 | moderate |
| ≥ 0.35 | fragile |
| < 0.35 | unstable |
Package structure
sna/
├── schema.py NarrativeNode, NarrativeEdge, PerturbationEntry, SpectralConfig
├── operator.py NarrativeOperator, OperatorResult
├── spectral.py EigenmodeAnalyzer, SpectralResult, EigenMode
├── perturbation.py SpectralPerturbationAnalyzer, PerturbationResult, ModeShift
└── stability.py NarrativeStabilityAnalyzer, NarrativeStabilityResult
docs/
└── model.md Full mathematical model documentation
examples/
└── basic_usage.py End-to-end example
Relationship to other packages
This package is the third layer in a narrative intelligence stack:
| Layer | Package | Question |
|---|---|---|
| Ordering | temporal-belief-graph |
Does A happen before B? |
| Trustworthiness | evidence-confidence-propagation |
How much should I trust this item? |
| Structure | spectral-narrative-analysis |
Is the narrative structurally stable? |
Development
pip install -e ".[dev]"
pytest
tox
python -m build
This package is currently in alpha. APIs may change before version 1.0.0.
Contributing
Contributions, issues, and feature requests are welcome. Please open an issue before submitting a pull request.
Contributors
| Handle | GitHub | Role |
|---|---|---|
| lajjadred | @lajjadred | Project lead |
| 이채문 | @CHML-real | Mathematical algorithm development |
| CUBE | @90cube | Idea proposal and data collection |
License
MIT License. See LICENSE for details.
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 spectral_narrative_analysis-0.2.1.tar.gz.
File metadata
- Download URL: spectral_narrative_analysis-0.2.1.tar.gz
- Upload date:
- Size: 22.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3eb3903a03fe3fe8a46f39c29c1cba3bd9a6fce027b9f3c3fbc654bcacbd5c40
|
|
| MD5 |
f3ac4b054690705741cf46442d4007eb
|
|
| BLAKE2b-256 |
c2ba784b8f8b22c0edb4507b3bbc889d6695d995a5859bb8a5c3da12cab1af2d
|
File details
Details for the file spectral_narrative_analysis-0.2.1-py3-none-any.whl.
File metadata
- Download URL: spectral_narrative_analysis-0.2.1-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2c8f65e7d6736e150d2da3d6ca109ee7e42da1f3f97893ebe1233388534ca05
|
|
| MD5 |
4038b5f52bfc88f969502aaf16f02adb
|
|
| BLAKE2b-256 |
82817a458289ddb450e166eb2f989d29a397c17b282331ff30f51270c8777417
|