Is there any straight way or a function to substitute symbols in an expression?
For example:
ex = :(x + x^2 + x^3)
substitute(ex, :x => :y) # yields :(y + y^2 + y^3)
substitute(ex, :x => 1.5) # yields :(1.5 + 1.5^2 + 1.5^3)
Is there any straight way or a function to substitute symbols in an expression?
For example:
ex = :(x + x^2 + x^3)
substitute(ex, :x => :y) # yields :(y + y^2 + y^3)
substitute(ex, :x => 1.5) # yields :(1.5 + 1.5^2 + 1.5^3)
julia> function rep!(e, old, new)
for (i,a) in enumerate(e.args)
if a==old
e.args[i] = new
elseif a isa Expr
rep!(a, old, new)
end
## otherwise do nothing
end
e
end
rep! (generic function with 1 method)
julia> rep!(:(x + x^2 + x^3), :x, :y)
:(y + y ^ 2 + y ^ 3)
julia> rep!(:(x + x^2 + x^3), :x, 1.5)
:(1.5 + 1.5 ^ 2 + 1.5 ^ 3)
With the MacroTools package you can do
using MacroTools
ex = :(x + x^2 + x^3)
MacroTools.postwalk(ex -> ex == :x ? :y : ex, ex)
MacroTools.postwalk(ex -> ex == :x ? 1.5 : ex, ex)
This is how you could do it with my Reduce.jl package
julia> using Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...
julia> ex = :(x+x^2+x^3)
:(x + x ^ 2 + x ^ 3)
julia> rcall(:(x=y)); rcall(ex)
:((y ^ 2 + y + 1) * y)
julia> rcall(:(x=1.5)); rcall(ex)
:(57 / 8)
Alternatively, you can also use the Reduce.Algebra.sub
method,
julia> using Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...
julia> ex = :(x+x^2+x^3)
:(x + x ^ 2 + x ^ 3)
julia> Algebra.sub(:x=>:y,ex)
:((y ^ 2 + y + 1) * y)
julia> Algebra.sub(:x=>1.5,ex)
:(57 / 8)
which is closer to your original proposal and is probably better than my original example
Thanks all for the nice suggestions. I also found a native function:
Base.Cartesian.lreplace(:(x + x^2 + x^3), :x, 1)
but it does not work with float numbers.