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

Fechada Para iniciantes
#1,864 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 3 dias

@hongyuchen1030 já está trabalhando nisso.

Desde 30/10/2026.

  • #1863 de @hongyuchen1030 — integrado

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
78/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
numpy, python
Domínio
data, testing

Direção de pesquisa

Leia uxarray/grid/utils.py para _small_angle_of_2_vectors e uxarray/utils/computing.py para o helper existente diff_of_products. Adicione testes para vetores quase paralelos, incluindo o caso reproduzível fornecido, e depois compare os resultados com ângulos precisos para as entradas float64. O trabalho estará concluído quando o erro para ângulos pequenos for reduzido a poucos ulps sem prejudicar os chamadores existentes.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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
Linguagem predominante
Python
Estrelas
231
Forks
58
Merge médio
5d 7h
PRs com merge (30d)
18

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de UXARRAY/uxarray

Todas as issues de UXARRAY/uxarray

Issues semelhantes

Mais issues de Python

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.