Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

`_small_angle_of_2_vectors` loses accuracy for nearly parallel vectors (naive difference of products in Kahan's formula)

已关闭 适合新手
#1,864 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 3 天内回复

@hongyuchen1030 已经在做这个了。

开始于 2026年10月30日。

  • #1863 来自 @hongyuchen1030 —— 已合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
numpy, python
领域
data, testing

调研方向

阅读 uxarray/grid/utils.py 中的 _small_angle_of_2_vectors,以及 uxarray/utils/computing.py 中现有的 helper diff_of_products。为近乎平行的向量添加测试,包括提供的可复现案例,然后将结果与 float64 输入对应的精确角度进行比较。完成标准是:小角度误差降低到几个 ulps,同时不影响现有调用方。

由索引模型根据 Issue 内容生成。

描述

bug
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

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

UXARRAY/uxarray 的其他 Issue

查看 UXARRAY/uxarray 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。