Repository navigation
Take higher-order derivative expressions from DiffRules instead of evaluating ChainRules rules symbolically - #114
Merged
Merged
Conversation
`get_term_raiser` evaluated ChainRules' `frule` on a Symbolics variable, which breaks as soon as a rule branches on values (#113, ChainRules 1.74.11). DiffRules' expressions are value-free by design, so take the derivative from `DiffRules.diffrule` and drop the Symbolics and SymbolicUtils dependencies. Also import the names used by the code generated in `TaylorDiffSFExt`, which was broken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Format the new Float32 testset as JuliaFormatter (sciml) expects - Don't link to the undocumented `raise`/`raiseinv` in the `get_term_raiser` docstring; it is rendered by `@autodocs` and broke the docs build - Don't import `raise`/`raiseinv` in TaylorDiffSFExt; the generated code interpolates the function objects Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for this! This solves the precompilation errors with TaylorDiff |
Member
|
Thanks this makes sense |
Member
Author
|
Thank you! Could you tag a release with this change @tansongchen? I already updated the version number in this PR. |
Member
|
just did! |
Member
Author
|
Thank you! |
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.
Fixes #113.
Problem
To raise unary functions to higher orders,
get_term_raiserevaluates ChainRules'fruleon a Symbolics variable during precompilation. The resulting expression is then evaluated on Taylor series. This relies on two properties that ChainRules doesn't promise, since its rules are only meant to be evaluated on numbers:tanhruleabs(real(x)) < 1 ? 1 - Ω^2 : sech(x)^2, so TaylorDiff fails to precompile with ChainRules ≥ 1.74.11. A branch on the value is fine for numbers. A Symbolics variable can't be compared, though, so precompilation throws.Changes
get_term_raisertakes the derivative fromDiffRules.diffrule(M, f, :z). DiffRules' expressions are value-free by design, and Symbolics' own derivatives are built from them.raiseinvwhen the expression isinv(g),1 / gor a negation of those, matched withMacroTools.@capture; otherwiseraise.abs(sign(z), as before) andsign(zero; DiffRules has no rule) are defined explicitly.pkgversion(Symbolics)branches.using TaylorDiffgoes from 1.76 s to 0.38 s (warm, precompiled).TaylorDiffSFExtimports the names its generated methods refer to by name. It was broken before: every SpecialFunctions derivative threwUndefVarError: value not defined in TaylorDiffSFExt.fruleon numbers, unchanged.This requires DiffRules 1.17 (JuliaDiff/DiffRules.jl#122), which is now released and registered. DiffRules 1.16 uses
sqrt(x^2 - 1)foracosh, which would be less accurate near 1 than thesqrt(x - 1) * sqrt(x + 1)that TaylorDiff got from ChainRules 1.74.10. DiffRules 1.17 also makes higher-ordertanh,atanh,acothetc. accurate in the cases where they weren't before.Verification
I compared
derivative(f, x, Val(k))for k = 1:4 against TaylorDiff 0.3.5 with ChainRules 1.74.10, for all 28 functions at 2–3 points each (including near-singular ones), in Float64 and Float32, with BigFloat as the reference:atanh/acothimprove from 10–28 ulps to about 1 ulp.deg2rad/rad2degin Float32.New tests:
fruleat in-domain points.SpecialFunctions is added to the test dependencies to cover the extension.
A known issue remains, unchanged by this PR:
acos,acosh,acsc,acsch,asec,asech,asinandasinhstill error for Float32 inputs at orders ≥ 2. The cause issqrt(t::TaylorScalar) = t^0.5(src/primitive.jl), which promotes to Float64. I can open a separate PR for that.Version bumped to 0.3.6. A patch release would make TaylorDiff load again with current ChainRules.
CI notes
main(since April). The latest JuliaFormatter reformats code that predates this PR (examples/,src/scalar.jl,processinsrc/utils.jl, older tests intest/primitive.jl). This PR only fixes the formatting of the lines it adds. The rest can go in a separate PR.test/downstream.jl:34, matrixexpgradient) fails locally on bothmainand this PR with ChainRules 1.74.10, Zygote 0.7.16 and DifferentiationInterface 0.7.22, so the failure predates this PR.🤖 Generated with Claude Code