Skip to content

build: support SymbolicUtils 4 / Symbolics 7#74

Merged
oameye merged 4 commits into
mainfrom
symbolicsv7-upgrade
Jul 24, 2026
Merged

build: support SymbolicUtils 4 / Symbolics 7#74
oameye merged 4 commits into
mainfrom
symbolicsv7-upgrade

Conversation

@oameye

@oameye oameye commented May 25, 2026

Copy link
Copy Markdown
Member
  • 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.

Checklist

Thank you for contributing to QuestBase.jl! Please make sure you have finished the following tasks before finishing the PR.

  • Appropriate tests were added and tested locally by running: make test.
  • Any code changes should be julia formatted by running: make format.
  • All documents (in 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

* `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

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.80%. Comparing base (273c52f) to head (83f2fab).

Files with missing lines Patch % Lines
src/utils.jl 0.00% 4 Missing ⚠️
src/Symbolics/Symbolics_utils.jl 87.50% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

oameye added 3 commits July 24, 2026 09:34
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.
@oameye
oameye merged commit 48db566 into main Jul 24, 2026
9 checks 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.

1 participant