feat: add Ekadhipatya Shodhana

(cherry picked from commit 868f1dadb69e870fbf20223e4fcd0550286bc220)
This commit is contained in:
732642856
2026-10-02 23:40:59 +08:00
committed by Jesse_Chen
parent 54f6930b23
commit 67aa1b33d7
2 changed files with 52 additions and 1 deletions
+42
View File
@@ -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.',
}