Skip to content

fix(ddx-core): divide a quotient's derivative by its denominator once - #96

Merged
alxmrs merged 1 commit into
mainfrom
fix/quotient-rule
Oct 3, 2026
Merged

alxmrs merged 1 commit into
mainfrom
fix/quotient-rule

Conversation

@alxmrs

@alxmrs alxmrs commented Sep 29, 2026

Copy link
Copy Markdown
Member

Stacked on the #87 PR. Found by the v2 soak (#92), which had to exempt infinite data because of it, and refined after a tiny-values soak.

The textbook quotient rule (du·v - u·dv)/v² squares v:

  • at v = ∞ (a value in the data) it evaluates ∞/∞ = NaN where the limit is 0;
  • at a tiny v (1e-163) v² underflows to 0.

ddx now emits (du - (u/v)·dv)/v, which divides by v once, through the quotient itself. That's the same number everywhere else, finite at v = ∞, and it never squares v.

I first tried splitting it into du/v - u·dv/v². That handles v = ∞, but at a tiny v its two 1/v terms cancel to noise: u/sinh(u) differentiated to ±1e159 instead of about 0. When the denominator doesn't depend on the variable, the result is just du/v.

Rendered derivatives change accordingly: d/dx x/y is CAST(1.0 AS DOUBLE) / y. The JAX oracle suites (137 tests), ddxdb's tests, and a 5-minute soak (227k cases) pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CvszJhH8pn8H9G69wEPMU2

@alxmrs

alxmrs commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

😈🧪 Adversarial tester: ✅ approved for correctness. Reviewed at d2c7bdc (identical tree to today's rebase febfc15). Workspace tests, doctests, a 20-min soak (0 failures) and a mutation spot-check all pass. The one blocker in the stack is on #79 (#79 (comment)); the full report is in #102 (comment).

Base automatically changed from fix/integer-cast to main October 3, 2026 02:13
The v2 soak (#92) noted that with infinite values in the data, the
quotient rule's (du·v - u·dv)/v² evaluates ∞/∞ = NaN where the partial's
limit is 0; and with tiny values (1e-163) v² underflows. ddx now emits
(du - (u/v)·dv)/v, dividing by v once through the quotient itself: the
same number everywhere else, finite at v = ∞ whether or not v depends on
the variable, and never squaring v. (Splitting it into du/v - u·dv/v²
fixes the infinite case but not the tiny one, where two 1/v terms cancel
to noise: u/sinh(u) differentiated to ±1e159 instead of about 0.) A
denominator constant in the variable leaves just du/v, which is also
shorter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvszJhH8pn8H9G69wEPMU2
@alxmrs
alxmrs force-pushed the fix/quotient-rule branch from 52ee36e to 16ab8b2 Compare October 3, 2026 02:16

@alxmrs alxmrs left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good catch.

@alxmrs
alxmrs merged commit 8efa2bf into main Oct 3, 2026
14 checks passed
@alxmrs
alxmrs deleted the fix/quotient-rule branch October 3, 2026 02:22
@github-actions github-actions Bot mentioned this pull request Oct 3, 2026
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.

1 participant