Repository navigation
Conversation
…Real` arguments A `Dual` with zero partials represents the same number as a `Real`, so the `Dual^Dual` branch of `^` and `NaNMath.pow` now uses the same check as the `Dual^Real` branch (`iszero(vy) || isconstant(x)`) and no longer returns `NaN` partials for, e.g., `Dual(0.0, 0.0)^Dual(0.5, 1.0)` and `Dual(0.0, 1.0)^Dual(0.0, 0.0)` (the latter also in NaN-safe mode). The check in the `Dual^Real` branch is rewritten equivalently as `iszero(y) || isconstant(x)` for consistency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the fix, `∂x^y/∂x = 0` at `(0, 0)`: in NaN-safe mode the gradient is now `[0.0, -Inf]`, and in the default mode `[NaN, -Inf]` (the remaining `NaN` is caused by the zero partial of `y` in the first direction multiplied by `log(0) = -Inf`, which only NaN-safe mode handles). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #856 +/- ##
==========================================
+ Coverage 91.23% 91.24% +0.01%
==========================================
Files 11 11
Lines 1072 1074 +2
==========================================
+ Hits 978 980 +2
Misses 94 94 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mathematically, a dual number with zero partials is just a regular number:
Dual(v, 0)andvrepresent the same quantity. Hence derivative rules should return the same result regardless of whether an unperturbed argument is aRealor aDualwith zero partials.Currently, this is not the case for
^andNaNMath.powif both arguments areDuals with the same tag:The second example returns
NaNalso in NaN-safe mode: there theNaNis not caused by a zero partial but bypowval = 0 * 0^(-1).This PR fixes both cases by setting
powvalto zero ifiszero(vy) || isconstant(x), i.e., the same check as in the existingDual^Realbranch, which makes theDual^Dualbranch consistent with both theDual^Realand theReal^Dualbranch. For consistency, the check in theDual^Realbranch is now also written asiszero(y) || isconstant(x)instead ofy == zero(y) || iszero(partials(x))(which is equivalent). The new tests check that replacing an argument with a zero-partialsDualdoes not change the result.With this PR, the derivatives at the special points agree with the
Realcase, SymPy, and WolframAlpha (default / NaN-safe mode where they differ):RealDualDual∂x^y/∂xat(0, 0)000NaN/NaN0∂x^y/∂xat(0, 0.5)∞∞InfInfInf∂x^y/∂xat(0, -0.5)-∞-∞-Inf-Inf-Inf∂x^y/∂xat(2, 0)00000∂x^y/∂yat(0, 0)-∞-∞-InfNaN/-Inf-Inf∂x^y/∂yat(0, 0.5)000NaN/00∂x^y/∂yat(0, 1.5)00000∂x^y/∂yat(0, -0.5)-∞-∞-InfNaN/-Inf-InfFor
x = 0, the SymPy and WolframAlpha values are the limitsx -> 0+ofy * x^(y - 1)andx^y * log(x)(at(0, 0),∂x^y/∂xisd/dx x^0 = 0). At(0, 0),∂x^y/∂y = -∞is also the limit of the one-sided difference quotients ofy -> 0^y.Note that this PR only makes the rules consistent for
Duals whose partials are all zero. ADualwith only some zero partials still propagatesNaNs in these directions in the default mode, so results depend on the chunk size, also with the existing check in theDual^Realbranch:That's not specific to
^(e.g.,sqrt(v[1]) + v[2]returns[Inf, NaN]for any chunk size), and only NaN-safe mode handles it consistently. See #857.🤖 Generated with Claude Code