JuliaSymbolics / Symbolics.jl

Symbolic programming for the next generation of numerical software
https://docs.sciml.ai/Symbolics/stable/
Other
1.37k stars 153 forks source link

cannot solve x * a ^ b + x for x (but sympy can) #1302

Open thorek1 opened 1 week ago

thorek1 commented 1 week ago
import Symbolics as Smb
using Nemo
using Groebner
Smb.@variables x, a, b
Smb.symbolic_solve(x * a ^ b + x, x)
# ┌ Warning: This expression cannot be solved with the methods available to ia_solve. Try a numerical method instead.
# └ @ Symbolics ~/.julia/packages/Symbolics/rtkf9/src/solver/ia_main.jl:27
# ERROR: MethodError: no method matching iterate(::Nothing)
# The function `iterate` exists, but no method is defined for this combination of argument types.

# Closest candidates are:
#   iterate(::Base.MethodSpecializations)
#    @ Base reflection.jl:1299
#   iterate(::Base.MethodSpecializations, ::Nothing)
#    @ Base reflection.jl:1305
#   iterate(::Base.MethodSpecializations, ::Int64)
#    @ Base reflection.jl:1306
#   ...

# Stacktrace:
#  [1] indexed_iterate(I::Nothing, i::Int64)
#    @ Base ./tuple.jl:162
#  [2] ia_solve(lhs::Symbolics.Num, var::Symbolics.Num; warns::Bool)
#    @ Symbolics ~/.julia/packages/Symbolics/rtkf9/src/solver/ia_main.jl:270
#  [3] ia_solve
#    @ ~/.julia/packages/Symbolics/rtkf9/src/solver/ia_main.jl:262 [inlined]
#  [4] symbolic_solve(expr::Symbolics.Num, x::Symbolics.Num; dropmultiplicity::Bool, warns::Bool)
#    @ Symbolics ~/.julia/packages/Symbolics/rtkf9/src/solver/main.jl:186
#  [5] symbolic_solve(expr::Symbolics.Num, x::Symbolics.Num)
#    @ Symbolics ~/.julia/packages/Symbolics/rtkf9/src/solver/main.jl:145
#  [6] top-level scope
#    @ ~/check_sym.jl:5

import SymPyPythonCall as Smbpy
Smbpy.@syms xx aa bb
Smbpy.solve(xx * aa ^ bb + xx, xx)
# 1-element Vector{SymPyCore.Sym{PythonCall.Core.Py}}:
#  0

# ⌃ [0b43b601] + Groebner v0.7.5
# ⌅ [2edaba10] + Nemo v0.45.7
#   [bc8888f7] + SymPyPythonCall v0.4.0
#   [0c5d862f] + Symbolics v6.13.1
ChrisRackauckas commented 1 week ago

Is that solution even correct? What if a = 0? Then x^0 + x = 1 + x and so 0 is not a solution.

thorek1 commented 1 week ago

if a = 0 then x * a ^ b + x = x * 0 ^ b + x = x * (0 ^ b + 1) if b is not negative x * (0 ^ b + 1) = x * (0 + 1) = x the solution is x = 0 what am I missing here?

ChrisRackauckas commented 1 week ago

You would need to pass that assumption though. SymPy's result is strictly not correct without it.

thorek1 commented 1 week ago

What about Symbolics making the assumption and giving the result? The same way it is done in this case:

Smb.symbolic_solve(x / a + x / b, x)
[ Info: Assuming (a*b) != 0
[ Info: Assuming (a*b) != 0
1-element Vector{Int64}:
 0

so that in the case of Smb.symbolic_solve(x * a ^ b + x, x) the return would be:

Smb.symbolic_solve(x * a ^ b + x, x)
[ Info: Assuming !(a = 0 & b < 0)
1-element Vector{Int64}:
 0
ChrisRackauckas commented 1 week ago

That could be the case, yes. We could add a ia_solve rule for that.