|
| 1 | +# SPDX-License-Identifier: AGPL-3.0-or-later | Commercial license available |
| 2 | +# © Concepts 1996–2026 Miroslav Šotek. All rights reserved. |
| 3 | +# © Code 2020–2026 Miroslav Šotek. All rights reserved. |
| 4 | +# ORCID: 0009-0009-3560-0851 |
| 5 | +# Contact: www.anulum.li | protoscience@anulum.li |
| 6 | +# SCPN Phase Orchestrator — TE adaptive coupling tests |
| 7 | + |
| 8 | +from __future__ import annotations |
| 9 | + |
| 10 | +import numpy as np |
| 11 | + |
| 12 | +from scpn_phase_orchestrator.coupling.te_adaptive import te_adapt_coupling |
| 13 | + |
| 14 | + |
| 15 | +class TestTEAdaptive: |
| 16 | + def test_output_shape(self): |
| 17 | + knm = np.full((4, 4), 0.5) |
| 18 | + np.fill_diagonal(knm, 0.0) |
| 19 | + rng = np.random.default_rng(42) |
| 20 | + history = rng.uniform(0, 2 * np.pi, (4, 100)) |
| 21 | + result = te_adapt_coupling(knm, history) |
| 22 | + assert result.shape == (4, 4) |
| 23 | + |
| 24 | + def test_zero_diagonal(self): |
| 25 | + knm = np.full((3, 3), 0.5) |
| 26 | + np.fill_diagonal(knm, 0.0) |
| 27 | + rng = np.random.default_rng(42) |
| 28 | + history = rng.uniform(0, 2 * np.pi, (3, 100)) |
| 29 | + result = te_adapt_coupling(knm, history) |
| 30 | + np.testing.assert_array_equal(np.diag(result), 0.0) |
| 31 | + |
| 32 | + def test_non_negative(self): |
| 33 | + knm = np.full((3, 3), 0.1) |
| 34 | + np.fill_diagonal(knm, 0.0) |
| 35 | + rng = np.random.default_rng(42) |
| 36 | + history = rng.uniform(0, 2 * np.pi, (3, 200)) |
| 37 | + result = te_adapt_coupling(knm, history, lr=0.01) |
| 38 | + assert np.all(result >= 0) |
| 39 | + |
| 40 | + def test_coupling_increases(self): |
| 41 | + knm = np.full((4, 4), 0.1) |
| 42 | + np.fill_diagonal(knm, 0.0) |
| 43 | + rng = np.random.default_rng(42) |
| 44 | + history = rng.uniform(0, 2 * np.pi, (4, 200)) |
| 45 | + result = te_adapt_coupling(knm, history, lr=1.0) |
| 46 | + # With lr=1.0, TE contribution should increase off-diagonal |
| 47 | + assert float(result.sum()) >= float(knm.sum()) |
| 48 | + |
| 49 | + def test_decay_reduces(self): |
| 50 | + knm = np.full((3, 3), 1.0) |
| 51 | + np.fill_diagonal(knm, 0.0) |
| 52 | + rng = np.random.default_rng(42) |
| 53 | + history = rng.uniform(0, 2 * np.pi, (3, 100)) |
| 54 | + result = te_adapt_coupling(knm, history, lr=0.0, decay=0.5) |
| 55 | + assert float(result.sum()) < float(knm.sum()) |
0 commit comments