Skip to content

Commit 542b073

Browse files
Copilotfermga
andcommitted
Add comprehensive regression tests for phase compatibility refactoring
Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
1 parent 9f4bd4b commit 542b073

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
"""Regression tests for phase compatibility refactoring.
2+
3+
Verifies that the unified phase compatibility functions produce identical
4+
results to the original inline implementations that were replaced in UM
5+
and THOL operators.
6+
"""
7+
8+
import math
9+
import pytest
10+
11+
from tnfr.metrics.phase_compatibility import compute_phase_coupling_strength
12+
from tnfr.utils.numeric import angle_diff
13+
14+
15+
class TestPhaseCompatibilityRegression:
16+
"""Test that refactored code produces identical results to original."""
17+
18+
def test_thol_propagation_formula_equivalence(self):
19+
"""Verify THOL propagation coupling formula remains identical."""
20+
# Original THOL implementation:
21+
# phase_diff = abs(angle_diff(neighbor_theta, parent_theta))
22+
# coupling_strength = 1.0 - (phase_diff / math.pi)
23+
24+
test_cases = [
25+
(0.0, 0.0), # Perfect alignment
26+
(0.0, math.pi/2), # Orthogonal
27+
(0.0, math.pi), # Antiphase
28+
(0.1, 0.15), # Small difference
29+
(0.0, 2*math.pi - 0.1), # Wrap-around
30+
(math.pi/4, 3*math.pi/4), # 90 degree separation
31+
]
32+
33+
for parent_theta, neighbor_theta in test_cases:
34+
# Original formula
35+
phase_diff_original = abs(angle_diff(neighbor_theta, parent_theta))
36+
coupling_original = 1.0 - (phase_diff_original / math.pi)
37+
38+
# New unified formula
39+
coupling_unified = compute_phase_coupling_strength(parent_theta, neighbor_theta)
40+
41+
assert abs(coupling_original - coupling_unified) < 1e-10, \
42+
f"Mismatch for θ_parent={parent_theta}, θ_neighbor={neighbor_theta}: " \
43+
f"original={coupling_original}, unified={coupling_unified}"
44+
45+
def test_thol_capture_signals_formula_equivalence(self):
46+
"""Verify THOL capture_network_signals coupling formula remains identical."""
47+
# Original implementation in capture_network_signals:
48+
# phase_diff = abs(n_theta - node_theta)
49+
# if phase_diff > math.pi:
50+
# phase_diff = 2 * math.pi - phase_diff
51+
# coupling_strength = 1.0 - (phase_diff / math.pi)
52+
53+
test_cases = [
54+
(0.0, 0.0),
55+
(0.0, math.pi/2),
56+
(0.0, math.pi),
57+
(0.1, 0.15),
58+
(0.0, 1.9 * math.pi), # Should wrap to small difference
59+
(math.pi/6, 5*math.pi/6), # 120 degree separation
60+
]
61+
62+
for node_theta, n_theta in test_cases:
63+
# Original formula (manual normalization)
64+
phase_diff_original = abs(n_theta - node_theta)
65+
if phase_diff_original > math.pi:
66+
phase_diff_original = 2 * math.pi - phase_diff_original
67+
coupling_original = 1.0 - (phase_diff_original / math.pi)
68+
69+
# New unified formula (uses angle_diff internally)
70+
coupling_unified = compute_phase_coupling_strength(node_theta, n_theta)
71+
72+
assert abs(coupling_original - coupling_unified) < 1e-10, \
73+
f"Mismatch for θ_node={node_theta}, θ_n={n_theta}: " \
74+
f"original={coupling_original}, unified={coupling_unified}"
75+
76+
def test_um_phase_alignment_formula_equivalence(self):
77+
"""Verify UM operator phase alignment formula remains identical."""
78+
# Original UM implementation for ΔNFR reduction:
79+
# dphi = abs(angle_diff(neighbor.theta, node.theta))
80+
# alignment = 1.0 - dphi / math.pi
81+
82+
test_cases = [
83+
(0.0, 0.0),
84+
(0.0, math.pi/2),
85+
(0.0, math.pi),
86+
(0.1, 0.2),
87+
(math.pi, math.pi + 0.1),
88+
(0.1, 2*math.pi - 0.1),
89+
]
90+
91+
for node_theta, neighbor_theta in test_cases:
92+
# Original formula
93+
dphi_original = abs(angle_diff(neighbor_theta, node_theta))
94+
alignment_original = 1.0 - dphi_original / math.pi
95+
96+
# New unified formula
97+
alignment_unified = compute_phase_coupling_strength(node_theta, neighbor_theta)
98+
99+
assert abs(alignment_original - alignment_unified) < 1e-10, \
100+
f"Mismatch for θ_node={node_theta}, θ_neighbor={neighbor_theta}: " \
101+
f"original={alignment_original}, unified={alignment_unified}"
102+
103+
def test_um_functional_links_formula_equivalence(self):
104+
"""Verify UM functional link formation phase coupling remains identical."""
105+
# Original UM implementation for link formation:
106+
# th_j = j.theta
107+
# dphi = abs(angle_diff(th_j, th_i)) / math.pi
108+
# phase_coupling = (1 - dphi)
109+
110+
test_cases = [
111+
(0.0, 0.0),
112+
(0.0, math.pi/2),
113+
(0.0, math.pi),
114+
(math.pi/4, 3*math.pi/4),
115+
(0.05, 0.1),
116+
(5.0, 5.5),
117+
]
118+
119+
for th_i, th_j in test_cases:
120+
# Original formula
121+
dphi_original = abs(angle_diff(th_j, th_i)) / math.pi
122+
phase_coupling_original = 1 - dphi_original
123+
124+
# New unified formula
125+
phase_coupling_unified = compute_phase_coupling_strength(th_i, th_j)
126+
127+
assert abs(phase_coupling_original - phase_coupling_unified) < 1e-10, \
128+
f"Mismatch for θ_i={th_i}, θ_j={th_j}: " \
129+
f"original={phase_coupling_original}, unified={phase_coupling_unified}"
130+
131+
def test_comprehensive_equivalence_scan(self):
132+
"""Scan through many angle combinations to ensure complete equivalence."""
133+
import random
134+
random.seed(42)
135+
136+
# Test 100 random angle pairs
137+
for _ in range(100):
138+
theta_a = random.uniform(0, 2*math.pi)
139+
theta_b = random.uniform(0, 2*math.pi)
140+
141+
# Original formula (most general form)
142+
phase_diff = abs(angle_diff(theta_b, theta_a))
143+
coupling_original = 1.0 - (phase_diff / math.pi)
144+
145+
# Unified formula
146+
coupling_unified = compute_phase_coupling_strength(theta_a, theta_b)
147+
148+
assert abs(coupling_original - coupling_unified) < 1e-10, \
149+
f"Random test failed for θ_a={theta_a}, θ_b={theta_b}"
150+
151+
152+
class TestBackwardCompatibility:
153+
"""Test that operator behavior is preserved after refactoring."""
154+
155+
def test_um_compatibility_calculation_unchanged(self):
156+
"""UM compatibility formula should produce same results as before."""
157+
# Test the full compatibility calculation used in UM functional links
158+
# compat = (1 - dphi) * 0.5 + 0.25 * epi_sim + 0.25 * si_sim
159+
160+
th_i, th_j = 0.0, math.pi/4
161+
epi_i, epi_j = 0.8, 0.7
162+
si_i, si_j = 0.9, 0.85
163+
164+
# Original calculation
165+
dphi_original = abs(angle_diff(th_j, th_i)) / math.pi
166+
epi_sim = 1.0 - abs(epi_i - epi_j) / (abs(epi_i) + abs(epi_j) + 1e-9)
167+
si_sim = 1.0 - abs(si_i - si_j)
168+
compat_original = (1 - dphi_original) * 0.5 + 0.25 * epi_sim + 0.25 * si_sim
169+
170+
# New calculation
171+
phase_coupling_unified = compute_phase_coupling_strength(th_i, th_j)
172+
compat_unified = phase_coupling_unified * 0.5 + 0.25 * epi_sim + 0.25 * si_sim
173+
174+
assert abs(compat_original - compat_unified) < 1e-10, \
175+
f"UM compatibility mismatch: original={compat_original}, unified={compat_unified}"
176+
177+
def test_thol_propagation_threshold_unchanged(self):
178+
"""THOL propagation thresholding should work identically."""
179+
# Test that the same neighbors would be selected for propagation
180+
181+
parent_theta = 0.0
182+
neighbor_thetas = [0.1, math.pi/3, math.pi/2, 2.0, math.pi, 3.0]
183+
threshold = 0.5
184+
185+
# Original logic
186+
selected_original = []
187+
for neighbor_theta in neighbor_thetas:
188+
phase_diff = abs(angle_diff(neighbor_theta, parent_theta))
189+
coupling = 1.0 - (phase_diff / math.pi)
190+
if coupling >= threshold:
191+
selected_original.append(neighbor_theta)
192+
193+
# New logic
194+
selected_unified = []
195+
for neighbor_theta in neighbor_thetas:
196+
coupling = compute_phase_coupling_strength(parent_theta, neighbor_theta)
197+
if coupling >= threshold:
198+
selected_unified.append(neighbor_theta)
199+
200+
assert selected_original == selected_unified, \
201+
f"THOL propagation selection mismatch: " \
202+
f"original={selected_original}, unified={selected_unified}"
203+
204+
205+
if __name__ == "__main__":
206+
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)