Open notchxu opened 2 years ago
Yeah, the issue is that though t
doesn't appear in free_symbols, it does show up when turning the sympy object into an expression:
julia> SymPy.convert_expr(ex)
:(Integral(t ^ 2, (:t, 0, :w)))
julia> free_symbols(ex)
1-element Vector{Sym}:
w
I'd guess this will only work if you call integrate
(which calls doit()
on the unevaluated integral expression to actually remove the dummy variable.)
doit()
may solve the issue in this specific case, but you can run into the same problem when the antiderivative has a case distinction which can't be resolved without concrete values. In the following example, x
will not appear in free_symbols
either, and therefore it yields an error.
x, a, b = symbols("x,a,b", real=true)
res = SymPy.integrate(abs(sin(2π * x)), (x, a, b))
I = SymPy.lambdify(res; use_julia_code=true)
@show res
@show SymPy.free_symbols(res)
@show I(0, 1)
res = Piecewise((Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, a, b)), a < b), (-Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, b, a)), True))
SymPy.free_symbols(res) = Sym{PyCall.PyObject}[a, b]
ERROR: LoadError: UndefVarError: `x` not defined
So I've tried to be smart and add x
to the final result, which will make it appear in free_symbols
again. However, this still doesn't work.
x, a, b = symbols("x,a,b", real=true)
res = x + SymPy.integrate(abs(sin(2π * x)), (x, a, b))
I = SymPy.lambdify(res; use_julia_code=true)
@show res
@show SymPy.free_symbols(res)
@show I(0, 1, 0)
res = x + Piecewise((Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, a, b)), a < b), (-Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, b, a)), True))
SymPy.free_symbols(res) = Sym{PyCall.PyObject}[a, b, x]
ERROR: LoadError: UndefVarError: `True` not defined
How do you get around this problem?
That is a tricky one. It isn't supported in the underlying sympy library either:
julia> sympy.o.julia_code(res.o)
"# Not supported in Julia:\n# Integral\n# Integral\n((a < b) ? (Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, a, b))) : (-Integral(Piecewise((1.0*sin(6.28318530717959*x), sin(6.28318530717959*x) >= 0), (-1.0*sin(6.28318530717959*x), True)), (x, b, a))))"
The issue is the x
shouldn't be part of the conditions, but it is. I'm surprised it isn't in free_symbols
given how it prints,
I was hoping this issue would be the one that got me to follow the lead of Symbolics
and more flexibly allow the arguments to be specified, but it is some other issue I don't know where to go with,
Attempting to evaluate
fn(5)
leads to errorUndefVarError: t not defined
. However, this should not be the case, since the only free symbol inex
isw
. The same error occurs if I don't try to replaceIntegral
with thequadgk
numerical.Attempting to fix this by replacing the final two lines with
leads to error
MethodError: no method matching iterate(::Symbol)
with corresponding stack trace