214 lines
9.9 KiB
Python
214 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
大规模协同验证:18名人婚姻案例 × 5功能模块
|
|
测试: Double Transit PAC+D9, Transit LL/7L, 行星聚集, Vivah Saham, Chara Dasha
|
|
"""
|
|
import sys, json, os
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'scripts'))
|
|
import swisseph as swe
|
|
swe.set_ephe_path('')
|
|
|
|
from jyotish_engine import (
|
|
compute_chart_data, cmd_double_transit_pac, cmd_transit_ll7l,
|
|
cmd_planetary_congregation, cmd_vivah_saham, SIGN_LORDS, SIGNS
|
|
)
|
|
from jaimini import calc_chara_dasha_with_antardasha
|
|
|
|
# 18名人案例(来自 v6.1 验证脚本)
|
|
CASES = [
|
|
{'name':'Nelson Mandela','birth':(1918,7,18,14.0,-33.32,26.52),'gender':'M',
|
|
'marriage1':(1944,10,5)},
|
|
{'name':'Tom Cruise','birth':(1962,7,3,19.25,43.05,-76.15),'gender':'M',
|
|
'marriage1':(1987,5,9)},
|
|
{'name':'Elon Musk','birth':(1971,6,28,5.0,-25.74,28.19),'gender':'M',
|
|
'marriage1':(2000,1,1)},
|
|
{'name':'Oprah Winfrey','birth':(1954,1,29,11.88,33.51,-88.52),'gender':'F',
|
|
'marriage1':(1986,1,1)},
|
|
{'name':'Prince Harry','birth':(1984,9,15,15.33,51.5,-0.17),'gender':'M',
|
|
'marriage1':(2018,5,19)},
|
|
{'name':'Jeff Bezos','birth':(1964,1,12,9.63,25.78,-80.19),'gender':'M',
|
|
'marriage1':(1993,1,1)},
|
|
{'name':'Priyanka Chopra','birth':(1982,7,18,10.5,23.57,87.19),'gender':'F',
|
|
'marriage1':(2018,12,1)},
|
|
{'name':'Shah Rukh Khan','birth':(1965,11,1,21.25,28.61,77.21),'gender':'M',
|
|
'marriage1':(1991,10,25)},
|
|
{'name':'Britney Spears','birth':(1981,12,2,19.92,31.17,-89.18),'gender':'F',
|
|
'marriage1':(2004,1,3)},
|
|
{'name':'Mark Zuckerberg','birth':(1984,5,14,19.67,40.71,-74.01),'gender':'M',
|
|
'marriage1':(2012,5,19)},
|
|
{'name':'Narendra Modi','birth':(1950,9,17,4.78,23.03,72.58),'gender':'M',
|
|
'marriage1':(1968,1,1)},
|
|
{'name':'Amitabh Bachchan','birth':(1942,10,11,10.5,25.43,81.85),'gender':'M',
|
|
'marriage1':(1973,6,3)},
|
|
]
|
|
|
|
def make_args(y,m,d,h,mi,lat,lon,tz,date_str,house=7):
|
|
"""构建 args 对象"""
|
|
return type('Args', (), {
|
|
'year':y,'month':m,'day':d,'hour':h,'minute':mi,
|
|
'lat':lat,'lon':lon,'tz':tz,
|
|
'date':date_str,'house':house,
|
|
'transit_date':date_str,
|
|
})()
|
|
|
|
def run():
|
|
results = []
|
|
stats = {'dt':0,'p5':0,'p8':0,'pariv':0,'cong':0,'vs':0,'cd':0}
|
|
total = 0
|
|
|
|
for case in CASES:
|
|
y,m,d,h_utc,lat,lon = case['birth']
|
|
name = case['name']
|
|
my,mm,md_d = case['marriage1']
|
|
date_str = f"{my}-{mm:02d}-{md_d:02d}"
|
|
total += 1
|
|
|
|
# 转UTC hour (假设 birth 中 h 已经是 UTC)
|
|
hour_int = int(h_utc)
|
|
minute_int = int((h_utc - hour_int) * 60)
|
|
tz = 0 # UTC
|
|
|
|
print(f"\n{'='*50}")
|
|
print(f"[{total}] {name} | 婚姻: {date_str}")
|
|
print(f"{'='*50}")
|
|
|
|
signals = []
|
|
|
|
# 1. Double Transit PAC + D9
|
|
dt_hit = False
|
|
try:
|
|
dt_r = cmd_double_transit_pac(make_args(y,m,d,hour_int,minute_int,lat,lon,tz,date_str))
|
|
dt_hit = len(dt_r.get('double_transit',[])) > 0
|
|
if dt_hit:
|
|
signals.append('DT')
|
|
stats['dt'] += 1
|
|
dt_list = dt_r.get('double_transit',[])
|
|
layer_str = ','.join(set(l['layer'] for l in dt_list)) if dt_list else '-'
|
|
dt_summary = dt_r.get('summary','')
|
|
print(f" [DT PAC+D9] {'✅' if dt_hit else '❌'} layers={layer_str} {dt_summary}")
|
|
except Exception as e:
|
|
print(f" [DT PAC+D9] ERROR: {e}")
|
|
dt_hit = False # ERROR不计为hit
|
|
|
|
# 2. Transit LL/7L
|
|
try:
|
|
ll7l_r = cmd_transit_ll7l(make_args(y,m,d,hour_int,minute_int,lat,lon,tz,date_str))
|
|
p5 = ll7l_r['p5']['hit']
|
|
p8 = ll7l_r['p8']['hit']
|
|
pariv = ll7l_r['parivartana']['hit']
|
|
if p5: signals.append('P5'); stats['p5'] += 1
|
|
if p8: signals.append('P8'); stats['p8'] += 1
|
|
if pariv: signals.append('Pariv'); stats['pariv'] += 1
|
|
print(f" [LL/7L] P5={'✅' if p5 else '❌'} P8={'✅' if p8 else '❌'} Pariv={'✅' if pariv else '❌'}")
|
|
except Exception as e:
|
|
print(f" [LL/7L] ERROR: {e}")
|
|
|
|
# 3. 行星聚集
|
|
try:
|
|
cong_r = cmd_planetary_congregation(make_args(y,m,d,hour_int,minute_int,lat,lon,tz,date_str,7))
|
|
cong_hit = cong_r.get('hit', False)
|
|
if cong_hit: signals.append('聚集'); stats['cong'] += 1
|
|
print(f" [聚集] {'✅' if cong_hit else '❌'} {cong_r.get('summary','')}")
|
|
except Exception as e:
|
|
print(f" [聚集] ERROR: {e}")
|
|
|
|
# 4. Vivah Saham
|
|
try:
|
|
vs_r = cmd_vivah_saham(make_args(y,m,d,hour_int,minute_int,lat,lon,tz,date_str))
|
|
ta = vs_r.get('transit_activation', {})
|
|
vs_double = ta.get('double_activation', False) if ta else False
|
|
if vs_double: signals.append('VS双星'); stats['vs'] += 1
|
|
jup = [c['type'] for c in ta.get('jupiter',[])] if ta else []
|
|
sat = [c['type'] for c in ta.get('saturn',[])] if ta else []
|
|
vs_s = vs_r.get('vivah_saham',{})
|
|
print(f" [VivahSaham] {vs_s.get('sign_cn','?')} {vs_s.get('degree_in_sign',0):.1f}° | 双星={'✅' if vs_double else '❌'} Jup={jup} Sat={sat}")
|
|
except Exception as e:
|
|
print(f" [VivahSaham] ERROR: {e}")
|
|
|
|
# 5. Chara Dasha (Antardasha)
|
|
try:
|
|
chart, asc_idx, jd, aya = compute_chart_data(y,m,d,hour_int,minute_int,lat,lon,tz)
|
|
if chart:
|
|
p_lons = {pn: pd['degree'] for pn, pd in chart['planets'].items() if 'degree' in pd}
|
|
cd = calc_chara_dasha_with_antardasha(asc_idx, p_lons, y, m)
|
|
m_year, m_month = my, mm
|
|
md_name = ''; ad_name = ''
|
|
for md_d in cd['dasha_sequence']:
|
|
s_y, s_m = map(int, md_d['start_date'].split('-'))
|
|
e_y, e_m = map(int, md_d['end_date'].split('-'))
|
|
if (m_year > s_y or (m_year == s_y and m_month >= s_m)) and \
|
|
(m_year < e_y or (m_year == e_y and m_month <= e_m)):
|
|
md_name = f"{md_d['sign']}({md_d['lord']})"
|
|
for ad in md_d.get('antardashas', []):
|
|
as_y, as_m = map(int, ad['start_date'].split('-'))
|
|
ae_y, ae_m = map(int, ad['end_date'].split('-'))
|
|
if (m_year > as_y or (m_year == as_y and m_month >= as_m)) and \
|
|
(m_year < ae_y or (m_year == ae_y and m_month <= ae_m)):
|
|
ad_name = f"{ad['sign']}({ad['lord']})"
|
|
break
|
|
break
|
|
# 检查 MD 或 AD 是否涉及 7 宫相关
|
|
seven_sign = SIGNS[(asc_idx + 6) % 12]
|
|
seven_lord = SIGN_LORDS[seven_sign]
|
|
ll = SIGN_LORDS[SIGNS[asc_idx]]
|
|
cd_relevant = seven_lord in md_name or ll in md_name or seven_lord in ad_name or ll in ad_name
|
|
if cd_relevant: signals.append('CD'); stats['cd'] += 1
|
|
print(f" [CharaDasha] MD={md_name} AD={ad_name} | 7宫相关={'✅' if cd_relevant else '❌'}")
|
|
except Exception as e:
|
|
print(f" [CharaDasha] ERROR: {e}")
|
|
|
|
score = len(signals)
|
|
if score >= 3: verdict = '✅强'
|
|
elif score == 2: verdict = '⚠️中'
|
|
elif score == 1: verdict = '⚠️弱'
|
|
else: verdict = '❌无'
|
|
|
|
print(f" >>> 综合: {verdict} ({score}/6) 信号={signals}")
|
|
|
|
results.append({
|
|
'name': name, 'marriage': date_str,
|
|
'signals': signals, 'score': score, 'verdict': verdict,
|
|
})
|
|
|
|
# 汇总
|
|
print(f"\n{'='*60}")
|
|
print(f"大规模验证汇总 ({total} 案例)")
|
|
print(f"{'='*60}")
|
|
|
|
strong = sum(1 for r in results if r['score'] >= 3)
|
|
medium = sum(1 for r in results if r['score'] == 2)
|
|
weak = sum(1 for r in results if r['score'] == 1)
|
|
none_c = sum(1 for r in results if r['score'] == 0)
|
|
|
|
print(f"\n综合评分分布:")
|
|
print(f" 强确认 (≥3信号): {strong}/{total} ({strong/total*100:.0f}%)")
|
|
print(f" 中等确认 (2信号): {medium}/{total} ({medium/total*100:.0f}%)")
|
|
print(f" 弱信号 (1信号): {weak}/{total} ({weak/total*100:.0f}%)")
|
|
print(f" 无确认 (0信号): {none_c}/{total} ({none_c/total*100:.0f}%)")
|
|
|
|
print(f"\n各功能命中率:")
|
|
print(f" Double Transit PAC+D9: {stats['dt']}/{total} ({stats['dt']/total*100:.0f}%)")
|
|
print(f" Transit LL/7L P5: {stats['p5']}/{total} ({stats['p5']/total*100:.0f}%)")
|
|
print(f" Transit LL/7L P8: {stats['p8']}/{total} ({stats['p8']/total*100:.0f}%)")
|
|
print(f" Parivartana 互换: {stats['pariv']}/{total} ({stats['pariv']/total*100:.0f}%)")
|
|
print(f" 行星聚集: {stats['cong']}/{total} ({stats['cong']/total*100:.0f}%)")
|
|
print(f" Vivah Saham 双星激活: {stats['vs']}/{total} ({stats['vs']/total*100:.0f}%)")
|
|
print(f" Chara Dasha 7宫相关: {stats['cd']}/{total} ({stats['cd']/total*100:.0f}%)")
|
|
|
|
avg_score = sum(r['score'] for r in results) / total
|
|
at_least_1 = sum(1 for r in results if r['score'] >= 1)
|
|
at_least_2 = sum(1 for r in results if r['score'] >= 2)
|
|
print(f"\n核心指标:")
|
|
print(f" 平均信号数: {avg_score:.1f}/6")
|
|
print(f" ≥1信号覆盖率: {at_least_1}/{total} ({at_least_1/total*100:.0f}%)")
|
|
print(f" ≥2信号覆盖率: {at_least_2}/{total} ({at_least_2/total*100:.0f}%)")
|
|
|
|
# 保存
|
|
out = os.path.join(os.path.dirname(__file__), 'test-data', 'verify-large-scale-results.json')
|
|
with open(out, 'w', encoding='utf-8') as f:
|
|
json.dump({'results': results, 'stats': stats, 'total': total}, f, ensure_ascii=False, indent=2)
|
|
print(f"\n结果已保存: {out}")
|
|
|
|
if __name__ == '__main__':
|
|
run()
|