feat(domy): osiem systemów potwierdzonych co do zera wobec wyroczni
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 17s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 18s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 17s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 18s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
Etap 1: systemy o zamkniętym wzorze. Dochodzą vehlow, morinus, regiomontanus, campanus i alcabitus — każdy zgodny ze Swiss Ephemeris z maksymalnym odchyleniem 0,000000000° na 240 000 porównań (zestaw brzegowy + przemiał 20 000 losowych). Cuspy pośrednie liczone wektorowo: koło domu to przecięcie płaszczyzny (wyznaczonej iloczynem wektorowym normalnych) z ekliptyką. Dwa punkty przecięcia wymagają wyboru gałęzi — rozstrzygany stroną względem MC, przy czym cztery osie bierzemy z dokładnych wzorów, bo przy przesunięciu równym 0° albo 180° test strony jest numerycznie niestabilny. Dwie rzeczy, które wyszły dopiero z porównania z wyrocznią: - swisseph zamienia MC z IC dla systemów opartych na horyzoncie, gdy punkt kulminujący jest pod horyzontem (za kołem podbiegunowym) — stąd _culminating_mc, - morinus wymaga bezpośredniej zamiany współrzędnych, nie rzutu po kole godzinnym. Topocentric (Polich–Page) zaimplementowany, ale świadomie POZA houses.SYSTEMS: rozjeżdża się z wyrocznią przy |φ| ≈ 89,9° i RAMC 90°/270°, gdzie kolejność domów się odwraca. Powód jest rzeczywisty, nie numeryczny — jego „biegun" atan(tan(89,9°)/3) to już 89,7°. Zawężenie dziedziny tylko po to, żeby test przeszedł, byłoby dopasowaniem kryterium do wyniku. Testy regresji w suicie logiki działają bez swissepha: antypodyczność domów przeciwległych, zakotwiczenie kwadrantowych na Ascendencie, niezależność morinusa od szerokości, odrzucanie nieznanej nazwy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit was merged in pull request #62.
This commit is contained in:
@@ -75,3 +75,54 @@ def test_polar_circle_moves_with_obliquity():
|
||||
a ε zmienia się z datą. Testy brzegowe muszą ją liczyć per data."""
|
||||
assert H.polar_circle(23.4393) == pytest.approx(66.5607, abs=1e-4) # dziś
|
||||
assert H.polar_circle(23.747) == pytest.approx(66.253, abs=1e-4) # 370 p.n.e.
|
||||
|
||||
|
||||
# ── systemy egzotyczne o zamkniętym wzorze (Etap 1) ──────────────────────
|
||||
# Zgodność z wyrocznią sprawdza tests/oracle; tu pilnujemy niezmienników, które
|
||||
# muszą zachodzić także bez swissepha (czyli w każdym środowisku).
|
||||
|
||||
EXOTIC = ("vehlow", "morinus", "regiomontanus", "campanus", "alcabitus")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("system", EXOTIC)
|
||||
def test_exotic_returns_twelve_cusps_in_range(system):
|
||||
out = H.cusps_for(100.0, 23.4393, 50.0, system)
|
||||
assert len(out) == 12
|
||||
assert all(0.0 <= c < 360.0 for c in out)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("system", EXOTIC)
|
||||
def test_opposite_houses_are_antipodal(system):
|
||||
"""Domy przeciwległe leżą na tym samym kole wielkim, więc ich cuspy są
|
||||
dokładnie antypodyczne. Naruszenie tego oznacza błąd w wyborze gałęzi."""
|
||||
out = H.cusps_for(137.0, 23.4393, 42.0, system)
|
||||
for i in range(6):
|
||||
assert abs(((out[i + 6] - out[i]) % 360.0) - 180.0) < 1e-9, f"domy {i+1}/{i+7}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("system", ("regiomontanus", "campanus", "alcabitus"))
|
||||
def test_quadrant_systems_anchor_on_ascendant(system):
|
||||
"""Systemy kwadrantowe zaczynają dom I na Ascendencie."""
|
||||
ramc, eps, lat = 100.0, 23.4393, 50.0
|
||||
assert H.cusps_for(ramc, eps, lat, system)[0] == pytest.approx(
|
||||
H.compute_asc(ramc, eps, lat), abs=1e-9)
|
||||
|
||||
|
||||
def test_vehlow_puts_ascendant_in_the_middle_of_house_one():
|
||||
ramc, eps, lat = 100.0, 23.4393, 50.0
|
||||
asc = H.compute_asc(ramc, eps, lat)
|
||||
assert H.cusps_for(ramc, eps, lat, "vehlow")[0] == pytest.approx(
|
||||
H.norm360(asc - 15.0), abs=1e-9)
|
||||
|
||||
|
||||
def test_morinus_ignores_latitude():
|
||||
"""Morinus rzutuje równik wprost na ekliptykę, bez horyzontu — jako jedyny
|
||||
nie zależy od szerokości geograficznej."""
|
||||
a = H.cusps_for(100.0, 23.4393, 20.0, "morinus")
|
||||
b = H.cusps_for(100.0, 23.4393, 65.0, "morinus")
|
||||
assert a == pytest.approx(b, abs=1e-12)
|
||||
|
||||
|
||||
def test_unknown_system_is_rejected():
|
||||
with pytest.raises(ValueError):
|
||||
H.cusps_for(100.0, 23.4393, 50.0, "nie-ma-takiego")
|
||||
|
||||
Reference in New Issue
Block a user