feat(domy): topocentric zgodny co do zera — wybór gałęzi liczony, nie zgadywany
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
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 18s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build-render / build (push) Successful in 5m34s
build / build (push) Successful in 39s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m46s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m31s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m27s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 19s
Testy / Kontrola składni wszystkich warstw (push) Successful in 11s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
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 18s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build-render / build (push) Successful in 5m34s
build / build (push) Successful in 39s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m46s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m31s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m27s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 19s
Testy / Kontrola składni wszystkich warstw (push) Successful in 11s
Topocentric był wycofany z powodu rozjazdu przy |φ| ≈ 89,9°. Ta diagnoza była BŁĘDNA: opierała się wyłącznie na zestawie brzegowym, który próbkuje tylko wybrane szerokości. Przemiał losowy pokazał prawdziwą skalę — błędy od ~70° w górę, do 50% przypadków blisko biegunów, 6,5% całości. Nie dwa przypadki brzegowe. Przyczyną nie była jednak konstrukcja, tylko wybór gałęzi: dwa koła wielkie przecinają się w dwóch punktach antypodycznych. Kolejno zawiodły reguły „po której stronie MC", „w łuku kwadrantu", „wschodnia połowa horyzontu" i śledzenie ciągłości krokami (to ostatnie maskuje własną patologię — po korekcie do bliższej gałęzi zmierzony skok ZAWSZE wychodzi ≤ 90°, więc detektor nigdy się nie zapala). Wszystkie te reguły rozstrzygają lokalnie, a przy dużych szerokościach kolejność domów potrafi się odwrócić: przy φ = −79,55° MC wypada na 306,8°, a dom 11 na 291,4°. To jest poprawne — wyrocznia zwraca to samo. Rozwiązanie: nie wybierać w ogóle. Iloczyn wektorowy zenitu z biegunem ekliptyki jest ciągłą funkcją parametru rodziny i sam niesie właściwy zwrot; dwuznaczność wprowadza dopiero atan2. Zostajemy w wektorach, znak ustalamy raz — kotwicząc rodzinę na MC górującym. Wynik: 0,000000000° na 240 000 porównań, cała dziedzina, bez iteracji i bez zawężania szerokości. Żadna granica dziedziny nie jest tu potrzebna, więc żadnej nie udajemy — test pilnuje, że topocentric liczy się wszędzie i nie fallbackuje. Morał do frameworka: zestaw brzegowy mówi, CZY system się psuje; dopiero przemiał losowy mówi JAK BARDZO. Wniosek o skali wyciągnięty z samych brzegów był tu zaniżony o trzy rzędy wielkości. Odnotowane w tests/oracle/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit was merged in pull request #63.
This commit is contained in:
@@ -83,7 +83,8 @@ def test_polar_circle_moves_with_obliquity():
|
||||
# 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")
|
||||
EXOTIC = ("vehlow", "morinus", "regiomontanus", "campanus", "alcabitus",
|
||||
"topocentric")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("system", EXOTIC)
|
||||
@@ -196,3 +197,36 @@ def test_polar_circle_boundary_moves_with_the_date():
|
||||
with pytest.raises(H.HouseSystemUndefined):
|
||||
H.cusps_for(100.0, 23.4393, lat, "placidus")
|
||||
assert len(H.cusps_for(100.0, 23.3528, lat, "placidus")) == 12
|
||||
|
||||
|
||||
def test_topocentric_cusps_stay_in_order_between_mc_and_ascendant():
|
||||
"""Regresja na to, co topocentrica psuło najdłużej — wybór gałęzi.
|
||||
|
||||
Cuspy 11 i 12 to punkty CIĄGŁEJ rodziny biegnącej od MC do Ascendentu, więc
|
||||
czwórka MC → 11 → 12 → Asc leży na okręgu w kolejności, bez wyprzedzania się.
|
||||
Zły wybór gałęzi przerzuca któryś punkt o 180° i kolejność pęka.
|
||||
|
||||
Kierunek celowo NIE jest ustalony: przy dużych szerokościach domy biegną
|
||||
wstecz (przy φ=−79,55° MC=306,8°, a dom 11 to 291,4°) i to jest poprawne —
|
||||
wyrocznia zwraca tam dokładnie to samo. Sprawdzamy więc, że kolejność trzyma
|
||||
się w JEDNĄ ze stron, a nie że rośnie."""
|
||||
def d(a, b):
|
||||
return H.norm360(b - a)
|
||||
|
||||
for lat in (-89.9, -79.55, -67.18, 0.0, 50.06, 73.69, 80.66, 89.9):
|
||||
c = H.cusps_for(129.2387, 23.4393, lat, "topocentric")
|
||||
mc, c11, c12, asc = c[9], c[10], c[11], c[0]
|
||||
forward = d(mc, c11) + d(c11, c12) + d(c12, asc)
|
||||
backward = d(c11, mc) + d(c12, c11) + d(asc, c12)
|
||||
assert (abs(forward - d(mc, asc)) < 1e-9
|
||||
or abs(backward - d(asc, mc)) < 1e-9), \
|
||||
f"φ={lat}: MC={mc:.3f} 11={c11:.3f} 12={c12:.3f} Asc={asc:.3f} nie po kolei"
|
||||
|
||||
|
||||
def test_topocentric_needs_no_domain_limit():
|
||||
"""W przeciwieństwie do Placidusa/Kocha topocentric liczy się WSZĘDZIE —
|
||||
nie ma tu granicy dziedziny do wyprowadzenia, więc nie wolno jej udawać."""
|
||||
for lat in (0.0, 66.5, 69.65, 89.9, -89.9):
|
||||
assert len(H.cusps_for(100.0, 23.4393, lat, "topocentric")) == 12
|
||||
cs = H.cusps_detailed(100.0, 23.4393, 89.9, "topocentric")
|
||||
assert not cs.is_fallback and cs.notice is None
|
||||
|
||||
Reference in New Issue
Block a user