feat: add auditable Trikona Shodhana
(cherry picked from commit 9531d1dcc70d1c3e2b70c9627ac077d47d484b92)
This commit is contained in:
@@ -586,3 +586,37 @@ def calc_sodhita_av(bav_results: Dict, planets: Dict, asc_sign_idx: int) -> Dict
|
||||
'reduction_summary': total_reduction,
|
||||
'validation_note': 'Sodhita AV ≤ 原始BAV(逐宫位)',
|
||||
}
|
||||
|
||||
|
||||
TRIKONA_SIGN_GROUPS = (
|
||||
(0, 4, 8), # Aries, Leo, Sagittarius
|
||||
(1, 5, 9), # Taurus, Virgo, Capricorn
|
||||
(2, 6, 10), # Gemini, Libra, Aquarius
|
||||
(3, 7, 11), # Cancer, Scorpio, Pisces
|
||||
)
|
||||
|
||||
|
||||
def calc_trikona_shodhana(sav_scores: List[int]) -> Dict:
|
||||
"""Apply the classical Trikona Shodhana reduction to a 12-sign SAV row.
|
||||
|
||||
The minimum value in each elemental trine is removed from all three signs;
|
||||
the original row remains in the result for auditability.
|
||||
"""
|
||||
if len(sav_scores) != 12:
|
||||
raise ValueError('SAV scores must contain exactly 12 signs')
|
||||
original = [int(value) for value in sav_scores]
|
||||
reduced = original[:]
|
||||
groups = []
|
||||
for indexes in TRIKONA_SIGN_GROUPS:
|
||||
baseline = min(original[index] for index in indexes)
|
||||
for index in indexes:
|
||||
reduced[index] -= baseline
|
||||
groups.append({'sign_indexes': list(indexes), 'baseline_removed': baseline})
|
||||
return {
|
||||
'method': 'Trikona Shodhana',
|
||||
'original_scores': original,
|
||||
'reduced_scores': reduced,
|
||||
'trikona_groups': groups,
|
||||
'status': 'executed',
|
||||
'claim_boundary': 'Standalone classical reduction; Ekadhipatya Shodhana remains a separate layer.',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / 'scripts'))
|
||||
|
||||
from ashtakavarga import calc_trikona_shodhana # noqa: E402
|
||||
|
||||
|
||||
def test_trikona_shodhana_removes_each_trine_baseline() -> None:
|
||||
result = calc_trikona_shodhana(list(range(1, 13)))
|
||||
assert result['reduced_scores'] == [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8]
|
||||
assert result['trikona_groups'][0]['baseline_removed'] == 1
|
||||
Reference in New Issue
Block a user