build: support SymbolicUtils 4 / Symbolics 7#74
Merged
Conversation
* `substitute_all` now recurses into callable variable arguments by passing `filterer = _ -> true` to `SymbolicUtils.substitute`, matching the pre-SU 4 behaviour where `substitute(x(t), t => T)` reached inside `x(t)`. * `is_trig` compares the operation against `cos` / `sin` with `===` so that a callable variable head (e.g. `v1(T)`) no longer triggers symbolic `in`. * `my_isnan(::BasicSymbolic)` unwraps Const-wrapped numbers before calling `isnan`, so `hasnan` on a matrix of `Num(NaN)` returns `true` again. * Drop the now-unused `Symbolics.substitute` import.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #74 +/- ##
==========================================
- Coverage 82.20% 81.80% -0.40%
==========================================
Files 10 10
Lines 500 511 +11
==========================================
+ Hits 411 418 +7
- Misses 89 93 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Set julia compat to 1.12 and run Tests and Documentation on 1.12 only. Remove the Downgrade workflow. Widen OrderedCollections compat to allow v2. Add an informational codecov config so coverage does not fail CI. Apply JuliaFormatter v2.
`trig_reduce` linearises trigonometric expressions through an exponential round-trip, but `add_div` first merges `a/b + c/d` into a single fraction and the round-trip only reaches the numerator. Identities such as the Pythagorean cos(ωt)² + sin(ωt)² therefore survived in the denominator of the result. `get_independent` then saw a time-dependent denominator and discarded the whole fraction (returned 0). This silently collapsed the Krylov-Bogoliubov slow-flow equations produced by HarmonicBalance to `0 ~ d/dT`. Add `reduce_denominator`, applied at the end of `trig_reduce`, which reduces the denominator on its own (it holds no nested fraction, so the recursion terminates) and leaves the numerator untouched. Reducing the whole fraction with `simplify` instead would send the associative-commutative term matcher into a combinatorial blow-up on the large numerators of higher-order equations. Add tests that `trig_reduce` collapses the identity both in a bare expression and in a fraction denominator.
`symbolic_linear_solve(...; simplify=false)` returns nested fractions whose denominators hold the coefficient determinant. For a trigonometric ansatz that determinant contains identities like cos(ωt)² + sin(ωt)² = 1, which SymbolicUtils 4's `simplify` no longer collapses downstream. Consumers were therefore left working with superficially time-dependent denominators: the Krylov-Bogoliubov order-2 objects Fₜ, Fₜ′ and D₁ all inherited trig-laden denominators and averaging their products blew up combinatorially, going from ~10 s before the Symbolics 7 migration to never finishing (this is what stalled the HarmonicBalance Benchmark Tracking CI job for hours). Flatten the nested solution with `simplify_fractions` (polynomial-level, no AC matching) and collapse the trig identities with `reduce_denominator` inside `rearrange!` itself, so no consumer ever sees the unreduced determinant. As a bonus, `rearrange_standard` output on the harmonic-balance path is now a single flat fraction over the determinant instead of a nested Gaussian-elimination expression. Guard `reduce_denominator` with a `contains_trig` tree scan so trig-free denominators skip the exponential round-trip. Add tests for the guard and for `rearrange!` collapsing the determinant of a trigonometric ansatz.
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.
substitute_allnow recurses into callable variable arguments by passingfilterer = _ -> truetoSymbolicUtils.substitute, matching the pre-SU 4 behaviour wheresubstitute(x(t), t => T)reached insidex(t).is_trigcompares the operation againstcos/sinwith===so that a callable variable head (e.g.v1(T)) no longer triggers symbolicin.my_isnan(::BasicSymbolic)unwraps Const-wrapped numbers before callingisnan, sohasnanon a matrix ofNum(NaN)returnstrueagain.Symbolics.substituteimport.Checklist
Thank you for contributing to
QuestBase.jl! Please make sure you have finished the following tasks before finishing the PR.make test.juliaformatted by running:make format.docs/folder) related to code changes were updated and able to build locally by running:make docs.Request for a review after you have completed all the tasks. If you have not finished them all, you can also open a Draft Pull Request to let the others know this on-going work.
Description
Describe the proposed change here.
Related issues or PRs
Please mention the related issues or PRs here. If the PR fixes an issue, use the keyword close/closes/closed/fix/fixes/fixed/resolve/resolves/resolved followed by the issue id, e.g. fix #[id]
Additional context