fix(shadbala): Ayana hemisphere after wrap, civil-weekday hora lord, continuous mean motion, short-arc Chesta midpoint (upstream 0afa2780)
Ported from yinduzhanxing 0afa2780 (algorithm hunks and its four regression tests; the PyJHora / profile-metadata hunks do not apply to our file). The archived-PyJHora Kala test follows upstream's rewrite. The V.P. Jain benchmark expectations still need the three-column update (follow-up in this branch). TASK-upstream-sync4-20261002 T3. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
96767418ee
commit
08376cf0a8
+37
-15
@@ -24,6 +24,7 @@ import swisseph as swe
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from datetime import date
|
||||
from typing import Dict, Tuple
|
||||
|
||||
# v6.1.10: 导入实际Varga计算器(支持脚本和包两种调用方式)
|
||||
@@ -351,7 +352,7 @@ def _lagrange_interpolate(xs: tuple[float, ...], ys: tuple[float, ...], value: f
|
||||
def _ayana_bala(pname: str, longitude: float, ayanamsa: float) -> tuple[float, float]:
|
||||
raw_tropical = longitude + ayanamsa
|
||||
tropical = raw_tropical % 360.0
|
||||
north = raw_tropical < 180.0
|
||||
north = tropical < 180.0
|
||||
folded = tropical
|
||||
if 90.0 < tropical < 180.0:
|
||||
folded = 180.0 - tropical
|
||||
@@ -397,12 +398,14 @@ def _calendar_lords(context: Dict) -> Dict[str, str]:
|
||||
vaara_ahargana -= 1
|
||||
vaara = _ABDA_WEEKDAY_PLANETS[int(vaara_ahargana) % 7]
|
||||
|
||||
civil_weekday = int(math.ceil(local_jd + 1.0) % 7)
|
||||
# Civil weekday must not change at astronomical Julian noon. Sunday=0.
|
||||
civil_weekday = (date(year, month, day).weekday() + 1) % 7
|
||||
local_hour = context["local_hour"]
|
||||
if local_hour < context["sunrise_hour"]:
|
||||
civil_weekday = (civil_weekday - 1) % 7
|
||||
local_hour += 24.0
|
||||
hora_index = (int(local_hour - context["sunrise_hour"]) + civil_weekday + 1) % 7
|
||||
weekday_lord = ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn")[civil_weekday]
|
||||
hora_index = (int(local_hour - context["sunrise_hour"]) + _HORA_ORDER.index(weekday_lord)) % 7
|
||||
return {"abda": abda, "masa": masa, "vaara": vaara, "hora": _HORA_ORDER[hora_index]}
|
||||
|
||||
|
||||
@@ -452,15 +455,38 @@ def calc_kala_bala_precise(pname: str, all_planets: Dict, context: Dict) -> Dict
|
||||
|
||||
|
||||
def _surya_mean_longitude(pname: str, context: Dict) -> float:
|
||||
"""Surya Siddhanta mean motion with desantara correction from Ujjain."""
|
||||
local_jd = context["jd_local"]
|
||||
kali_days = int(local_jd - 588_465.0)
|
||||
weekday = int(math.ceil(local_jd + 1.0) % 7)
|
||||
kali_days += weekday - 5 - kali_days % 7
|
||||
"""Surya Siddhanta mean motion at the Ujjain mean-time meridian.
|
||||
|
||||
Civil clock time is not local mean solar time. Convert through UTC so
|
||||
changing a time-zone representation cannot change a geocentric mean.
|
||||
"""
|
||||
if "jd_ut" in context:
|
||||
jd_ut = float(context["jd_ut"])
|
||||
else:
|
||||
# Legacy callers must explicitly identify their civil-clock offset.
|
||||
jd_ut = float(context["jd_local"]) - float(context["timezone"]) / 24.0
|
||||
ujjain_jd = jd_ut + _UJJAIN_LONGITUDE / 360.0
|
||||
# Mean motion is continuous elapsed time. Re-aligning this count to a
|
||||
# weekday introduced seven-day jumps; integer truncation lost sub-day
|
||||
# motion. Preserve the existing epoch/rates rather than tune to an oracle.
|
||||
kali_days = ujjain_jd - 588_465.0
|
||||
daily_motion = round(_SURYA_REVOLUTIONS[pname] / _SURYA_CIVIL_DAYS * 360.0, 7)
|
||||
mean_longitude = (kali_days * daily_motion) % 360.0
|
||||
desantara = (_UJJAIN_LONGITUDE - context["lon"]) / 360.0 * daily_motion
|
||||
return (mean_longitude + desantara) % 360.0
|
||||
return mean_longitude
|
||||
|
||||
|
||||
def chesta_from_longitudes(mean: float, true: float, apogee: float) -> float:
|
||||
"""Bounded Chesta with a coordinate-invariant short-arc midpoint.
|
||||
|
||||
Short-arc continuation across zero is geometric, not an additional rule
|
||||
explicitly supplied by Raman's non-crossing published example.
|
||||
"""
|
||||
separation = (true - mean + 180.0) % 360.0 - 180.0
|
||||
if abs(separation) == 180.0:
|
||||
raise ValueError("Antipodal mean/true longitudes have no unique short-arc midpoint")
|
||||
midpoint = (mean + separation / 2.0) % 360.0
|
||||
angle = (apogee - midpoint + 180.0) % 360.0 - 180.0
|
||||
return round(abs(angle) / 3.0, 2)
|
||||
|
||||
|
||||
def calc_chesta_bala_precise(pname: str, all_planets: Dict, kala: Dict, context: Dict) -> float:
|
||||
@@ -479,11 +505,7 @@ def calc_chesta_bala_precise(pname: str, all_planets: Dict, kala: Dict, context:
|
||||
seeghrochcha, mean_longitude = planet_mean, sun_mean
|
||||
else:
|
||||
seeghrochcha, mean_longitude = sun_mean, planet_mean
|
||||
average_longitude = (_planet_longitude(pname, all_planets) + mean_longitude) / 2.0
|
||||
chesta_kendra = abs(seeghrochcha - average_longitude)
|
||||
if chesta_kendra > 180.0:
|
||||
chesta_kendra = 360.0 - chesta_kendra
|
||||
return round(max(0.0, chesta_kendra) / 3.0, 2)
|
||||
return chesta_from_longitudes(mean_longitude, _planet_longitude(pname, all_planets), seeghrochcha)
|
||||
|
||||
|
||||
def calc_shadbala(planets: Dict, asc_sign: str, birth_hour: float,
|
||||
|
||||
Reference in New Issue
Block a user