`_small_angle_of_2_vectors` loses accuracy for nearly parallel vectors (naive difference of products in Kahan's formula)
维护者通常 3 天内回复
评估
调研方向
阅读 uxarray/grid/utils.py 中的 _small_angle_of_2_vectors,以及 uxarray/utils/computing.py 中现有的 helper diff_of_products。为近乎平行的向量添加测试,包括提供的可复现案例,然后将结果与 float64 输入对应的精确角度进行比较。完成标准是:小角度误差降低到几个 ulps,同时不影响现有调用方。
由索引模型根据 Issue 内容生成。
描述
Version
v2026.09.1 (main at 88815a8c)
How did you install UXarray?
Source
What happened?
uxarray.grid.utils._small_angle_of_2_vectors loses accuracy for nearly parallel vectors. It implements Kahan's angle formula for vectors of arbitrary length,
angle = 2 * atan2(| v|u| - u|v| |, | v|u| + u|v| |)
but forms each component of v|u| - u|v| from two separately rounded products, i.e. a naive difference of two nearly equal products. The relative error grows as eps/angle: a mean of 2.5e-12 at 1e-5 rad, 2.4e-10 at 1e-7 rad, and 2.1e-8 at 1e-9 rad (200 random pairs of different lengths per angle, against the exact angle of the float64 inputs).
The function is used by grid/angles.py (face node angles), grid/point_in_face.py (winding number), and grid/coordinates.py (bounding circles). It currently has no tests. Found while reviewing #1806.
What did you expect to happen?
Kahan's formula should be accurate to a few ulps for small angles. Evaluating each component of v|u| - u|v| with the FMA-based diff_of_products (already in uxarray/utils/computing.py) brings the mean error down to below 1e-16 for angles down to 1e-7 rad.
Can you provide a MCVE to repoduce the bug?
import math
from fractions import Fraction
import numpy as np
from uxarray.grid.utils import _small_angle_of_2_vectors
# Two nearly parallel vectors in the xy-plane, with different lengths.
theta = 1e-9
u = np.array([3.7 * math.cos(0.4), 3.7 * math.sin(0.4), 0.0])
v = np.array([0.21 * math.cos(0.4 + theta), 0.21 * math.sin(0.4 + theta), 0.0])
# Exact angle between the float64 inputs: (u x v)_z and u . v in exact rationals.
ux, uy, vx, vy = (Fraction(float(c)) for c in (u[0], u[1], v[0], v[1]))
exact = math.atan(float((ux * vy - uy * vx) / (ux * vx + uy * vy)))
got = _small_angle_of_2_vectors(u, v)
print(f"exact = {exact:.17e}")
print(f"computed = {got:.17e}")
print(f"relative error = {abs(got - exact) / exact:.1e}")
Output on main:
exact = 1.00000003822873689e-09
computed = 1.00000004983169261e-09
relative error = 1.2e-08
- 主要语言
- Python
- 星标
- 231
- 派生
- 58
- 平均合并
- 6 天 12 小时
- 30 天内合并 PR
- 19
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
UXARRAY/uxarray 的其他 Issue
-
ux.open_dataset currently supports structured data可能已有人在做 @Sevans711 于 2 天前认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
UXARRAY/uxarray#1854 · 1 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
-
developer experience
难度 1/5 1 小时以内 新手友好度 90/100
维护者通常 3 天内回复
-
zonal_mean() and weighted_mean() should return the same type of object可能重新可做 @Sevans711 于 39 天前认领,目前没有进行中的 PR。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
UXARRAY/uxarray#1733 · 已指派 1 人 ·
维护者通常 3 天内回复
-
documentation
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 3 天内回复
-
Pre-commit bot update requires substantial code updates可能已有人在做 @cmdupuis3 于 2 天前认领。 未关闭developer experience github_actions
UXARRAY/uxarray#1858 · 已指派 1 人 ·
维护者通常 3 天内回复
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 86/100
NousResearch/hermes-agent#147104 ·
维护者通常 1 天内回复
-
[oblt-aw][autodoc] Document new required `shared-org-key` input for `obs-aw-dependency-review`可能已有人在做 @github-actions 今天认领。 未关闭
难度 1/5 1 小时以内 新手友好度 90/100
维护者通常 1 天内回复
-
bot-triaged module: inductor oncall: pt2 topic: fuzzer triaged
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
getchaintips leaves out the active tip once a header is staged on it, where Core always lists it未关闭
难度 2/5 1-3 小时 新手友好度 88/100
btclib-org/btclib-node#2158 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
patrick-hudson/put.gd-desktop#979 · 1 条评论 ·
维护者通常 1 天内回复