Thanks. This seems to work OK. It is ok if it fails on some expressions. Will add try/catch to catch the error in those cases.
Here is one case where it can’t handle
julia> expr=0.8103075638223697(((3//5) + x)^-1) + 0.0012552102783267068(((1//4) + x^2 - x)^-1) + 1.3505126063706157log((3//5) + x) + 0.01769427781144674(x^2)*(((1//4) + x^2 - x)^-1) - 0.804168197111734(((9//25) + (6//5)*x + x^2)^-1) - 0.06487901864197139log(x - (1//2)) - 0.011357559462376793x*(((1//4) + x^2 - x)^-1) - 1.3402803285195568x*(((9//25) + (6//5)*x + x^2)^-1)
julia> decompose_compose(expr)
gives
log(x - (1//2))
ERROR: no rule defined
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] decompose_compose(expr::SymbolicUtils.Term{Number, Nothing})
@ Main .\REPL[6]:16
[3] _broadcast_getindex_evalf
@ .\broadcast.jl:670 [inlined]
[4] _broadcast_getindex
@ .\broadcast.jl:643 [inlined]
[5] getindex
@ .\broadcast.jl:597 [inlined]
[6] copyto_nonleaf!(dest::Vector{Rational{Int64}}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(decompose_compose), Tuple{Base.Broadcast.Extruded{SubArray{Any, 1, Vector{Any}, Tuple{UnitRange{Int64}}, true}, Tuple{Bool}, Tuple{Int64}}}}, iter::Base.OneTo{Int64}, state::Int64, count::Int64)
@ Base.Broadcast .\broadcast.jl:1055
[7] copy
@ .\broadcast.jl:907 [inlined]
[8] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(decompose_compose), Tuple{SubArray{Any, 1, Vector{Any}, Tuple{UnitRange{Int64}}, true}}})
@ Base.Broadcast .\broadcast.jl:860
[9] decompose_compose(expr::SymbolicUtils.Mul{Number, Float64, Dict{Any, Number}, Nothing})
@ Main .\REPL[6]:19
[10] _broadcast_getindex_evalf
@ .\broadcast.jl:670 [inlined]
[11] _broadcast_getindex
@ .\broadcast.jl:643 [inlined]
[12] getindex
@ .\broadcast.jl:597 [inlined]
[13] copyto_nonleaf!(dest::Vector{SymbolicUtils.Mul{Number, Rational{Int64}, Dict{Any, Number}, Nothing}}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(decompose_compose), Tuple{Base.Broadcast.Extruded{SubArray{SymbolicUtils.Mul{Number, Float64, Dict{Any, Number}, Nothing}, 1, Vector{SymbolicUtils.Mul{Number, Float64, Dict{Any, Number}, Nothing}}, Tuple{UnitRange{Int64}}, true}, Tuple{Bool}, Tuple{Int64}}}}, iter::Base.OneTo{Int64}, state::Int64, count::Int64)
@ Base.Broadcast .\broadcast.jl:1055
[14] copy
@ .\broadcast.jl:907 [inlined]
[15] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(decompose_compose), Tuple{SubArray{SymbolicUtils.Mul{Number, Float64, Dict{Any, Number}, Nothing}, 1, Vector{SymbolicUtils.Mul{Number, Float64, Dict{Any, Number}, Nothing}}, Tuple{UnitRange{Int64}}, true}}})
@ Base.Broadcast .\broadcast.jl:860
[16] decompose_compose(expr::SymbolicUtils.Add{Number, Int64, Dict{Any, Number}, Nothing})
@ Main .\REPL[6]:19
[17] top-level scope
@ REPL[9]:1
julia>
Is it possible to make your function not fail when there is no real numbers in the expression? Here is an example
expr=(1//2)*log(1 + x) - (1//4)*log(1 + x^2) - (1//2)*atan(-x)
decompose_compose(expr)
gives
log(1 + x^2)
ERROR: no rule defined
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] decompose_compose(expr::SymbolicUtils.Term{Number, Nothing})
@ Main .\REPL[8]:16
[3] _broadcast_getindex_evalf
@ .\broadcast.jl:670 [inlined]
[4] _broadcast_getindex
@ .\broadcast.jl:643 [inlined]
[5] getindex
@ .\broadcast.jl:597 [inlined]
[6] copyto_nonleaf!(dest::Vector{Rational{Int64}}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(decompose_compose), Tuple{Base.Broadcast.Extruded{SubArray{Any, 1, Vector{Any}, Tuple{UnitRange{Int64}}, true}, Tuple{Bool}, Tuple{Int64}}}}, iter::Base.OneTo{Int64}, state::Int64, count::Int64)
@ Base.Broadcast .\broadcast.jl:1055
[7] copy
@ .\broadcast.jl:907 [inlined]
[8] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(decompose_compose), Tuple{SubArray{Any, 1, Vector{Any}, Tuple{UnitRange{Int64}}, true}}})
@ Base.Broadcast .\broadcast.jl:860
[9] decompose_compose(expr::SymbolicUtils.Mul{Number, Rational{Int64}, Dict{Any, Number}, Nothing})
@ Main .\REPL[8]:19
[10] _broadcast_getindex_evalf
@ .\broadcast.jl:670 [inlined]
[11] _broadcast_getindex
@ .\broadcast.jl:643 [inlined]
[12] getindex
@ .\broadcast.jl:597 [inlined]
[13] copy
@ .\broadcast.jl:899 [inlined]
[14] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(decompose_compose), Tuple{SubArray{SymbolicUtils.Mul{Number, Rational{Int64}, Dict{Any, Number}, Nothing}, 1, Vector{SymbolicUtils.Mul{Number, Rational{Int64}, Dict{Any, Number}, Nothing}}, Tuple{UnitRange{Int64}}, true}}})
@ Base.Broadcast .\broadcast.jl:860
[15] decompose_compose(expr::SymbolicUtils.Add{Number, Int64, Dict{Any, Number}, Nothing})
@ Main .\REPL[8]:19
[16] top-level scope
@ REPL[9]:1
Thanks