theta and deltaangle lose precision for small angles
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
Read the theta and deltaangle implementations, then inspect the existing tests and the SymPy tests that pin the acos expressions. Reproduce the small-angle precision loss with the examples in the issue and review the proposed atan2 approach and its zero-vector behavior changes. Done means small angles retain precision, equivalent vector representations yield zero separation, and the tests reflect the agreed edge-case behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Vector Version
1.9.1.dev4+gcaf34cddf
Python Version
Python 3.13.16
OS / Environment
Linux
Describe the bug
theta and deltaangle lose precision for small angles. theta is computed as arccos(z / mag) and deltaangle as arccos(dot / (|v1| |v2|)). For a small angle the argument rounds to 1, so most digits are gone, and below about 1e-8 rad the result is exactly 0.
Reproducer:
import math
import vector
print("vector", vector.__version__)
for small in (1e-4, 1e-6, 1e-8, 1e-10):
theta = vector.obj(x=small, y=0.0, z=1.0).theta
print(f"theta({small:g}) = {theta!r:24} exact {math.atan(small)!r:24}")
pt, pz = 0.01, 6800.0
p = vector.obj(pt=pt, phi=0.3, pz=pz, E=math.hypot(pt, pz))
print("forward theta", p.theta, "exact", math.atan2(pt, pz))
for delta in (1e-4, 1e-6, 1e-8, 1e-10):
a = vector.obj(x=1.0, y=0.0, z=0.0)
b = vector.obj(x=1.0, y=delta, z=0.0)
print(f"deltaangle({delta:g}) = {a.deltaangle(b)!r:24} exact {math.atan(delta)!r}")
v = vector.obj(x=1.0, y=1.0, z=1.0)
print("same vector, xytheta vs rhophiz:", v.to_xytheta().deltaangle(v.to_rhophiz()))
Output on main:
vector 1.9.1.dev4+gcaf34cddf
theta(0.0001) = np.float64(9.999999973779312e-05) exact 9.999999966666667e-05
theta(1e-06) = np.float64(1.000044449303342e-06) exact 9.999999999996666e-07
theta(1e-08) = np.float64(0.0) exact 1e-08
theta(1e-10) = np.float64(0.0) exact 1e-10
forward theta 1.4706170310349988e-06 exact 1.4705882352930577e-06
deltaangle(0.0001) = np.float64(9.999999973779312e-05) exact 9.999999966666667e-05
deltaangle(1e-06) = np.float64(1.000044449303342e-06) exact 9.999999999996666e-07
deltaangle(1e-08) = np.float64(0.0) exact 1e-08
deltaangle(1e-10) = np.float64(0.0) exact 1e-10
same vector, xytheta vs rhophiz: 1.4901161193847656e-08
theta(1e-6) is off by about 4e-5 relative and theta(1e-8) is 0.0. The forward proton (pt = 0.01 GeV, pz = 6800 GeV) has theta wrong by about 2e-5 relative which would matter for forward proton or elastic scattering analyses. The last line shows the same vector in xytheta and in rhophiz having a deltaangle of 1.49e-8 instead of 0.
arctan2 fixes both: theta = arctan2(rho, z) and deltaangle = arctan2(|v1 x v2|, v1 . v2). ROOT's TVector3::Theta also uses atan2(Perp(), z).
I have a patch for both and can open a PR if you are fine with this. deltaangle.py changes a lot but only because it gets shorter the other coordinate combinations are built from the Cartesian one the way cross.py does it 710 lines down to 146. ran the existing test suite on it 4960 passed 17 skipped including 49 new tests that fail on current main. Nine SymPy tests that pinned the acos expressions needed new expected values. In benchmark on 1e6 vectors theta got faster 12 ms to 7 ms and deltaangle slower 31 ms to 38 ms because of the cross product.
Two behaviour changes I would like your view on:
- deltaangle with a zero length vector returns 0.0 instead of nan. ROOT's TVector3::Angle returns 0 there too.
- theta of (0, 0, -0.0) returns pi instead of 0. ROOT returns 0 for any zero vector.
the same root cause as #463 where deltaangle between identical vectors gave nan because the arccos argument rounded above 1. #465 fixed that by clamping the argument which removes the nan but the angle is still only accurate to about 1.5e-8 rad the square root of the double precision epsilon.
Any additional but relevant log output
No response
- Lingua principale
- Python
- Stelle
- 102
- Fork
- 47
- Merge medio
- 7g 3h
- PR unite (30g)
- 2
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di scikit-hep/vector
-
Add AI_POLICYAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 35/100
scikit-hep/vector#761 ·
-
Numba object backend: missing to_2D/to_3D/to_4D, momentum-named conversions, and like()Forse già presa @Thanatos9404 l’ha presa 23 giorni fa. Apertafeature
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
scikit-hep/vector#750 · 1 commento ·
-
Add ability to somehow map field names to coordinate axis names that vector expectsForse di nuovo libera @hjaat l’ha presa 103 giorni fa e non c’è nessuna pull request aperta. Apertafeature
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
scikit-hep/vector#732 · 3 commenti ·
-
feature
Difficoltà 5/5 Più di una settimana Idoneità per principianti 45/100
scikit-hep/vector#731 · 1 commento ·
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
scikit-hep/vector#711 · 1 commento ·
Tutte le issue di scikit-hep/vector
Issue simili
-
[BUG]: Compliance rules never see Unity Catalog views as viewsForse già presa @wagnercsantos l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
databrickslabs/ontos#1348 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
ibm-granite/granite.build#649 ·
I maintainer di solito rispondono entro 1 giorno
-
`forum_pr_poster` action will always return `none` when checking for pre-existing feedback threads, even if a feedback thread already exists.Forse già presa @pgmzeta l’ha presa oggi. ApertaE-Verified P-Major
Difficoltà 2/5 1-3 ore Idoneità per principianti 79/100
goonstation/goonstation#28259 ·
I maintainer di solito rispondono entro 2 giorni
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
woonstadrotterdam/monumenten#70 ·
I maintainer di solito rispondono entro 15 giorni
-
binding:python bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno