extend substitute syntax to more than one pair; add call method conve… - #11
Closed
jverzani wants to merge 2 commits into
Closed
extend substitute syntax to more than one pair; add call method conve…#11jverzani wants to merge 2 commits into
jverzani wants to merge 2 commits into
Conversation
Collaborator
|
Maybe we should simply add doctests for all of this. Related #3 |
s-celles
reviewed
Apr 30, 2026
| Uses call syntax for `substitute` when arguments are pairs. | ||
|
|
||
| # Examples | ||
| ```julia |
Collaborator
There was a problem hiding this comment.
Doctest such as
4785235#diff-5223be791c850df6b50e8950a30d18af4e58e429c96f51a52a9a743165a4f91dR21-R23
could probably be used here as it both documents code and test it
s-celles
reviewed
Apr 30, 2026
| expr = substitute(expr, p) | ||
| end | ||
| expr | ||
| end |
Collaborator
There was a problem hiding this comment.
We should ensure that
substitute(expr, x => y, y => x)
give similar result than
substitute(expr, Dict(x => y, y => x))
See
julia> expr = x + 2*y
GiacExpr: x+2*y
julia> Giac.substitute(expr, Dict(x => y, y => x))
GiacExpr: y+2*x
julia> function substitute(expr, pairs...)
for p in pairs
expr = substitute(expr, p)
end
expr
end
substitute (generic function with 2 methods)
julia> substitute(expr, x => y, y => x)
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.
ERROR: StackOverflowError:
Stacktrace:
[1] substitute(expr::GiacExpr, pairs::Pair{GiacExpr, GiacExpr})
@ Main ./REPL[2]:1
[2] substitute(expr::GiacExpr, pairs::Pair{GiacExpr, GiacExpr}) (repeats 79983 times)
@ Main ./REPL[2]:3
We should also take care of order as Julia Dict don't preserve insertion order.
on the other side I don't think such method prototype exists in Symbolics.jl...
julia> using Symbolics
julia> methods(Symbolics.substitute)
# 1 method for generic function "substitute" from SymbolicUtils:
[1] substitute(expr, dict; fold, filterer)
@ ~/.julia/packages/SymbolicUtils/uHteK/src/substitute.jl:261
help?> Symbolics.substitute
substitute(expr, dict; fold=Val(false))
substitute any subexpression that matches a key in dict with the corresponding value. If fold=Val(false), expressions which can be evaluated won't be evaluated.
julia> substitute(1+sqrt(y), Dict(y => 2), fold=Val(true))
2.414213562373095
julia> substitute(1+sqrt(y), Dict(y => 2), fold=Val(false))
1 + sqrt(2)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
substitute(expr, s; fold=Val(false))
Performs the substitution on expr according to rule(s) s. If fold=Val(true), expressions which can be fully evaluated will be evaluated to a number.
│ Does not penetrate `Differential`
│
│ As of Symbolics.jl v7 (SymbolicUtils.jl v4), substitute does not recurse into the arguments of Differential expressions. For example, substitute(D(x), Dict(x => y)) returns D(x), not D(y). Use
│ substitute_in_deriv or substitute_in_deriv_and_depvar to substitute inside Differential applications.
Examples
≡≡≡≡≡≡≡≡
julia> @variables t x y z(t)
4-element Vector{Num}:
t
x
y
z(t)
julia> ex = x + y + sin(z)
(x + y) + sin(z(t))
julia> substitute(ex, Dict([x => z, sin(z) => z^2]))
(z(t) + y) + (z(t) ^ 2)
julia> substitute(sqrt(2x), Dict([x => 1]))
sqrt(2)
julia> substitute(sqrt(2x), Dict([x => 1]); fold=Val(true))
1.4142135623730951
I even wonder if all this string based version of substitute shouldn't be written using
Giac.Commands.subst(expr, [x, y], [y, x])
s-celles
added a commit
that referenced
this pull request
May 1, 2026
Refactor substitute(expr, dict) and substitute(matrix, dict) to call GiacCxxBindings.giac_subst directly with structured Gen vectors built via make_vect, instead of formatting a subst(...) command string and re-parsing it through GIAC. Simultaneous-substitution semantics are preserved (a single giac_subst call with [vars] / [vals] list args, the same path the parser takes for bracketed-list literals), and Float64 replacement values are no longer at risk from textual round-trips. On a representative non-trivial expression with two pairs over 1000 calls, this is roughly 1.5-2x faster than the prior implementation. Also add two ergonomic surfaces aligned with Symbolics.substitute: substitute(expr, x => 1, y => 2) # varargs of pairs substitute(matrix, x => 1, y => 2) # matrix counterpart expr(a => 15, b => 10, c => 5, d => 0) # call-syntax sugar Both delegate to substitute(expr, Dict(pairs)) so they inherit the simultaneous semantics. The call-syntax overload requires at least one pair so existing function-evaluation calls (u(0), f(x)) keep their meaning. Call-syntax idea contributed by @jverzani in PR #11. Tests: add explicit coverage for the canonical swap, value-references- key, GiacMatrix analogs, varargs/dict equivalence, zero-pairs no-op, Float64 precision preservation, and call-syntax (single pair, multi- pair == substitute, swap, u(0) non-regression). Total +47 passing tests, suite green at 8045 pass. Bump 0.11.2 -> 0.12.0 (MINOR per SemVer for the new methods). Internal helper _build_subst_command removed (no callers remain). CHANGELOG entries for 0.11.1 and 0.11.2 backfilled from git tags.
Collaborator
Contributor
Author
|
Great. Thanks |
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.
Extends the
substitutesyntax to multiple pairs ofPairsAdds call syntax for symbolic expression when called with
Pairs.Again, I didn't include any tests, but can if you want.