Skip to content

Fix operator precedence in climb_angle - #103

Merged
dbetchkal merged 1 commit into
dbetchkal:mainfrom
arpitjain099:fix/climb-angle-operator-precedence
Jul 24, 2026
Merged

Fix operator precedence in climb_angle#103
dbetchkal merged 1 commit into
dbetchkal:mainfrom
arpitjain099:fix/climb-angle-operator-precedence

Conversation

@arpitjain099

Copy link
Copy Markdown
Contributor

Noticed this reading through computation.py. climb_angle doesn't match its own docstring:

np.arcsin(np.dot(n, v) / np.linalg.norm(n) * np.linalg.norm(v))

Python evaluates that left to right, so it works out to (n.v / |n|) * |v| instead of n.v / (|n| * |v|). The docstring gives A = n.b = |n||b|sin(θ), and the version in legacy_code/active_space_utils.py has the parentheses, so I think this is just a typo that slipped in during the port.

Because n is a unit vector the division by |n| is a no-op, and the code ends up computing arcsin(v_z * |v|). Anything longer than unit length pushes the arcsin argument past 1, so numpy returns NaN:

  • [3, 0, 4] returns NaN, should be 53.13 degrees
  • [1, 1, 1] returns NaN, should be 35.26
  • [10, 0, 10] returns NaN, should be 45

It only gives the right answer when |v| happens to be exactly 1.

Worth saying up front: nothing in the package calls this today, so I can't point at any actual breakage. (The climb_angle mentions in active_space_generator.py are a trajectory column that happens to share the name, not this function.) It is exported in __all__ though, so it's reachable as public API, and the math is wrong either way.

I put the tests in their own file instead of tests/utils/test_computation.py since #95 is currently adding that file and I didn't want the two to collide. Happy to fold them in there once that one lands.

The arcsin argument was written as np.dot(n, v) / np.linalg.norm(n) * np.linalg.norm(v),
which evaluates as (n.v / |n|) * |v| rather than n.v / (|n| * |v|). Since n is a unit
vector this reduces to arcsin(v_z * |v|), so any vector longer than unit length pushes
the argument past 1 and numpy returns NaN. The docstring formula and the implementation
in legacy_code/active_space_utils.py both use the parenthesized form. Added tests.

Signed-off-by: arpitjain099 <arpitjain099@gmail.com>
@dbetchkal
dbetchkal merged commit 62a2fa4 into dbetchkal:main Jul 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants