feat: add Ekadhipatya Shodhana
(cherry picked from commit 868f1dadb69e870fbf20223e4fcd0550286bc220)
This commit is contained in:
@@ -620,3 +620,45 @@ def calc_trikona_shodhana(sav_scores: List[int]) -> Dict:
|
||||
'status': 'executed',
|
||||
'claim_boundary': 'Standalone classical reduction; Ekadhipatya Shodhana remains a separate layer.',
|
||||
}
|
||||
|
||||
|
||||
EKADHIPATYA_SIGN_PAIRS = ((0, 7), (1, 6), (2, 5), (8, 11), (9, 10))
|
||||
|
||||
|
||||
def calc_ekadhipatya_shodhana(
|
||||
rows: Dict[str, List[int]], occupied_signs: set[int]
|
||||
) -> Dict:
|
||||
"""Apply PyJHora/PVR Ekadhipatya Shodhana to post-Trikona rows."""
|
||||
reduced = {planet: list(values) for planet, values in rows.items()}
|
||||
audit = []
|
||||
for planet, values in reduced.items():
|
||||
if len(values) != 12:
|
||||
raise ValueError('each BAV row must contain exactly 12 signs')
|
||||
for first, second in EKADHIPATYA_SIGN_PAIRS:
|
||||
first_value, second_value = values[first], values[second]
|
||||
if first_value == 0 or second_value == 0:
|
||||
continue
|
||||
first_occupied = first in occupied_signs
|
||||
second_occupied = second in occupied_signs
|
||||
before = [first_value, second_value]
|
||||
if first_occupied and second_occupied:
|
||||
continue
|
||||
if first_occupied != second_occupied:
|
||||
occupied, vacant = (first, second) if first_occupied else (second, first)
|
||||
values[vacant] = values[occupied] if values[occupied] < values[vacant] else 0
|
||||
elif first_value == second_value:
|
||||
values[first] = values[second] = 0
|
||||
elif first_value > second_value:
|
||||
values[first] = second_value
|
||||
else:
|
||||
values[second] = first_value
|
||||
audit.append({'planet': planet, 'pair': [first, second], 'before': before,
|
||||
'after': [values[first], values[second]]})
|
||||
return {
|
||||
'method': 'Ekadhipatya Shodhana',
|
||||
'rows': reduced,
|
||||
'occupied_signs': sorted(occupied_signs),
|
||||
'audit': audit,
|
||||
'status': 'executed',
|
||||
'claim_boundary': 'Applied after Trikona Shodhana; source profile follows PyJHora/PVR rule ordering.',
|
||||
}
|
||||
|
||||
@@ -5,10 +5,19 @@ 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
|
||||
from ashtakavarga import calc_ekadhipatya_shodhana, 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
|
||||
|
||||
|
||||
def test_ekadhipatya_shodhana_records_occupied_vacant_pair() -> None:
|
||||
result = calc_ekadhipatya_shodhana(
|
||||
{'Sun': [0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0]},
|
||||
{9},
|
||||
)
|
||||
assert result['rows']['Sun'][9:11] == [6, 0]
|
||||
assert result['audit'][0]['pair'] == [9, 10]
|
||||
|
||||
Reference in New Issue
Block a user