# New symbolic solver for Symbolics.jl!

**URL:** <https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466>\
**Category:** Package Announcements\
**Tags:** announcement, symbolics\
**Created:** [August 21, 2024, 9:16pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466 "2024-08-21T21:16:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yassin\_ElBedwihy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yassin_elbedwihy/32/208506_2.png) [@Yassin\_ElBedwihy](https://discourse.julialang.org/u/Yassin_ElBedwihy)\
**Post date:** [August 21, 2024, 9:16pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/1 "2024-08-21T21:16:48Z")

</div>

# New symbolic solver in Symbolics.jl

Hi, I am Yassin. A new symbolic solver authored by me has just been merged to Symbolics.jl, and is available in the latest release (v6.2.0). I want to share some of its capabilities here!

[Link](https://github.com/JuliaSymbolics/Symbolics.jl/pull/1192) to PR

The solver features:

- Multivariate polynomial solving
- Exact (symbolic) solutions
- Solving using isolation and attraction (inspired by a paper from R. W. Hamming)

## Examples and usage!

Solving with parameters and transcendental functions:

```julia
julia> @variables a b c d e x;
 
julia> symbolic_solve(a*log(x)^b + c ~ 0, x)
1-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
 ℯ^(((-c) / a)^(1 / b))

```

Solving by detecting polynomialization opportunities (`9^x + 3^x = 0` and the like also works 😄 )

```julia
julia> symbolic_solve(sin(x^2 +1)^2 + sin(x^2 + 1) + 3)
[ Info: var"##426" ϵ Ζ
[ Info: var"##429" ϵ Ζ
4-element Vector{SymbolicUtils.BasicSymbolic{Complex{Real}}}:
 (1//2)*√(-4(1 - asin((1//2)*(-1 + (0 + 1im)*√(11))) - (π*2var"##426")))
 (-1//2)*√(-4(1 - asin((1//2)*(-1 + (0 + 1im)*√(11))) - (π*2var"##426")))
 (1//2)*√(-4(1 - asin((1//2)*(-1 - ((0 + 1im)*√(11)))) - (π*2var"##429")))
 (-1//2)*√(-4(1 - asin((1//2)*(-1 - ((0 + 1im)*√(11)))) - (π*2var"##429")))

```

Solving high degree polynomials exactly:

```julia
julia> expr = expand((x + 2)*(x^2 + 2x + 1)*(x^4 - 3x^3 + x + 5)*(x^4 - 1))
-10 - 27x - 25(x^2) - 3(x^3) + 22(x^4) + 34(x^5) + 24(x^6) + 2(x^7) - 12(x^8) - 7(x^9) + x^10 + x^11

# output is truncated
julia> symbolic_solve(expr, x, dropmultiplicity=false)
9-element Vector{Any}:
 -2
 -1
 ...
 (-1//2)*(0 + 2im)

```

Also works with parameters:

```julia
julia> expr = expand((x + b)*(x^2 + 2x + 1)*(x^2 - a))
-a*b - a*x - 2a*b*x - 2a*(x^2) + b*(x^2) + x^3 - a*b*(x^2) - a*(x^3) + 2b*(x^3) + 2(x^4) + b*(x^4) + x^5

julia> symbolic_solve(expr, x, dropmultiplicity=false)
5-element Vector{Any}:
 -1
 -1
   -b
   (1//2)*√(4a)
   (-1//2)*√(4a)

```

Exact intersection of a sphere and a line in \mathbb{C}^3:

```julia
julia> symbolic_solve(
   [x^2 + y^2 + z^2 - 9, 
   x - 2y + 3,
   y - z]
   ,[x,y,z])
2-element Vector{Any}:
 Dict{Num, Any}(z => 2, y => 2, x => 1)
 Dict{Num, Any}(z => 0, y => 0, x => -3)

```

We can check our answers by plotting everything, and as expected there are only 2 intersections with the same coordinates our solver found:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/1/b10607b99764c6bace150193a00e1137dbfd52b6.png)

System of polynomials with infinite solutions are solved in terms of one of the variables:

```julia
julia> symbolic_solve([x*z - y - 1, x + z], [x, y, z])
┌ Warning: Infinite number of solutions
└ @ SymbolicsGroebnerExt ~/code/julia/Symbolics.jl/ext/SymbolicsGroebnerExt.jl:216
1-element Vector{Dict{Num, Any}}:
 Dict(z => z, y => -1 - (z^2), x => -z)

```

## What do i do?

The solver is available in the latest Symbolics.jl release (v6.2.0). Try solving your favorite equations and let us know about any bugs you encounter. You also need Groebner and Nemo depending on which solver `symbolic_solve` will use internally to solve your input.

You can find more examples in the [documentation](https://symbolics.juliasymbolics.org/dev/manual/solver/).

## Note and credits

Although the PR is merged, the release is actually still under preparation, as this is a work in progress. We plan to extend the solver to support more types of equations and integrate it with numerical solving.

Many thanks to @sumiya11 and @shashi for being great mentors throughout the project’s length!

---

<div class="post-metadata">

**Author:** ![isaacsas](https://avatars.discourse-cdn.com/v4/letter/i/f6c823/32.png) [@isaacsas](https://discourse.julialang.org/u/isaacsas)\
**Post date:** [August 21, 2024, 11:21pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/2 "2024-08-21T23:21:10Z")

</div>

Looks like a really great addition to Symbolics!

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [August 22, 2024, 5:32am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/3 "2024-08-22T05:32:44Z")

</div>

Is there a webpage called “Julia symbolics for newbies” so that new programmers can get up to speed with symbolics.jl?

With examples on how to use Symbolics to solve common problems.

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [August 22, 2024, 6:09am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/4 "2024-08-22T06:09:02Z")

</div>

Awesome! This has been sorely missing, and the API and functionality both look spot on. Great job 😁

---

<div class="post-metadata">

**Author:** ![tiZ](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tiz/32/211800_2.png) [@tiZ](https://discourse.julialang.org/u/tiZ)\
**Post date:** [August 22, 2024, 7:29am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/5 "2024-08-22T07:29:06Z")

</div>

Great news!!! I tried Symbolics a few weeks ago while its solver only supports linear equations.

BTW, Is there a trick to importing the `symbolic_solve` function?

> [@Yassin\_ElBedwihy](#):
>
> `symbolic_solve(a*log(x)^b + c ~ 0, x)`

I encountered the following error in the latest version, V6.2.0

```julia
> symbolic_solve(a*log(x)^b + c ~ 0, x)
ERROR: UndefVarError: `symbolic_solve` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[11]:1

pkg> st
Status `~/.julia/environments/symbolic/Project.toml`
  [0c5d862f] Symbolics v6.2.0

```

---

<div class="post-metadata">

**Author:** ![Yassin\_ElBedwihy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yassin_elbedwihy/32/208506_2.png) [@Yassin\_ElBedwihy](https://discourse.julialang.org/u/Yassin_ElBedwihy)\
**Post date:** [August 22, 2024, 9:09am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/6 "2024-08-22T09:09:50Z")

</div>

Hello @tiZ. Thanks for the kind words! For your problem, please try removing your local repo completely and cloning [symbolics](https://github.com/JuliaSymbolics/Symbolics.jl) once again. I also had this problem once we merged.

---

<div class="post-metadata">

**Author:** ![fgerick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fgerick/32/13228_2.png) [@fgerick](https://discourse.julialang.org/u/fgerick)\
**Post date:** [August 22, 2024, 10:01am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/7 "2024-08-22T10:01:02Z")

</div>

I had the same problem, and I believe it is just because this functionality was not released yet. It works if you do `]add Symbolics#master`.

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [August 22, 2024, 12:19pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/9 "2024-08-22T12:19:39Z")

</div>

TTFX is not ideal for linear equations. Is it possible to automatically detect linear cases and forward to `symbolic_linear_solve` instead? See timing below.

```julia
julia> using Symbolics, Groebner

julia> @variables x y z;

julia> @time symbolic_linear_solve([x-y, y+2z], [x,y])
  1.606491 seconds (3.11 M allocations: 211.991 MiB, 19.11% gc time, 99.90% compilation time)
2-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
 -2z
 -2z

julia> @time symbolic_solve([x-y, y+2z], [x,y])
 19.045450 seconds (44.65 M allocations: 2.988 GiB, 6.72% gc time, 99.85% compilation time: <1% of which was recompilation)
1-element Vector{Dict{Num, Any}}:
 Dict(y => -2z, x => -2z)

```

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [August 22, 2024, 12:40pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/10 "2024-08-22T12:40:32Z")

</div>

Here’s something `symbolic_solve` handles better than `symbolic_linear_solve`, as I want an exact solution without rounding to floats:

```julia
julia> symbolic_solve([x-1], [x])
1-element Vector{BigInt}:
 1

julia> symbolic_linear_solve([x-1], [x])
1-element Vector{Float64}:
 1.0

```

Here’s something only `symbolic_linear_solve` can handle, i.e. solving for “composite” variables:

```julia
julia> @variables f(..), x;

julia> symbolic_linear_solve([f(1)-x], [f(1)])
1-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
 x

julia> symbolic_solve([f(1)-x], [f(1)])
ERROR: MethodError: no method matching solve_multipoly(::Vector{Num}, ::SymbolicUtils.BasicSymbolic{Real}; dropmultiplicity::Bool, warns::Bool)

```

---

<div class="post-metadata">

**Author:** ![sumiya11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sumiya11/32/207147_2.png) [@sumiya11](https://discourse.julialang.org/u/sumiya11)\
**Post date:** [August 22, 2024, 2:33pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/11 "2024-08-22T14:33:45Z")

</div>

Thank you for your comments. The release should be out just about now, so this should work:  
`pkg> add Symbolics@6.3`

> TTFX is not ideal for linear equations. Is it possible to automatically detect linear cases and forward to `symbolic_linear_solve` instead?

Sure, we can do that for the linear case. By the way, in general, is it possible to precompile package extensions to reduce TTFX ?

> Here’s something only `symbolic_linear_solve` can handle, i.e. solving for “composite” variables:

Thanks for the report. Yes, handling composition of functions is in the todo for `symbolic_solve` :^).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 22, 2024, 2:55pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/12 "2024-08-22T14:55:37Z")

</div>

> [@StevenSiew](#):
>
> Is there a webpage called “Julia symbolics for newbies” so that new programmers can get up to speed with symbolics.jl?

There’s the getting started page:

> **[Getting Started with Symbolics.jl · Symbolics.jl](https://symbolics.juliasymbolics.org/dev/getting_started/)**
>
> Documentation for Symbolics.jl.

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [August 23, 2024, 8:11am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/13 "2024-08-23T08:11:05Z")

</div>

I am trying to understand Symbolics.jl  
In the code below, why is the position at t\_sv=17 given as “Position(t=17.0) is (1085.6,)”  
Why is the answer (1085.6,0) in brackets, is it a complex number?

```julia
using Symbolics

# Tutorial Symbolics for Newbies
#
# In Symbolics we have two type of variables
# 1. Normal Julia Programming Language variable 
# 2. Symbolic variables
#
# we shall denote symbolic variables with suffix t_sv
# eg. t_sv

@variables t_sv

# Next we create a lazy function to differentiate with respect
# to the symbolic variable t_sv
D_lazyfunc = Differential(t_sv)

Position = 3.4 * t_sv^2 + 5.6 * t_sv + 7.8
println("Position is ",Position)

# Velocity is the derivative of Position with respect to time
Velocity = expand_derivatives(D_lazyfunc(Position))

# Acceleration is the derivative of Velocity with respect to time
Acceleration = expand_derivatives(D_lazyfunc(Velocity))

# Derivative is 
println("Velocity is ",Velocity)
println("Acceleration is ",Acceleration)
println()

println("Find the varies attributes of Position")
println("The polynomial degree of position wrt t_sv is ",Symbolics.degree(Position))
println("The coefficient of position wrt 1 is ",Symbolics.coeff(Position,1))
println("The coefficient of position wrt t_sv is ",Symbolics.coeff(Position,t_sv))
println("The coefficient of position wrt t_sv^2 is ",Symbolics.coeff(Position,t_sv^2))

println()
println("What is the Position, Velocity and Acceleration at time = 17.0?")

Position_at_t17 = substitute.( Position, (Dict(t_sv => 17.0),) )
println("Position(t=17.0) is ",Position_at_t17)

Velocity_at_t17 = substitute.( Velocity, (Dict(t_sv => 17.0),) )
println("Velocity(t=17.0) is ",Velocity_at_t17)

Acceleration_at_t17 = substitute.( Acceleration, (Dict(t_sv => 17.0),) )
println("Acceleration(t=17.0) is ",Acceleration_at_t17)

```

with output:

Position is 7.8 + 5.6t\_sv + 3.4(t\_sv^2)  
Velocity is 5.6 + 6.8t\_sv  
Acceleration is 6.8

Find the varies attributes of Position  
The polynomial degree of position wrt t\_sv is 2  
The coefficient of position wrt 1 is 7.8  
The coefficient of position wrt t\_sv is 5.6  
The coefficient of position wrt t\_sv^2 is 3.4

What is the Position, Velocity and Acceleration at time = 17.0?  
Position(t=17.0) is (1085.6,)  
Velocity(t=17.0) is (121.19999999999999,)  
Acceleration(t=17.0) is (6.8,)

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 23, 2024, 8:21am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/14 "2024-08-23T08:21:05Z")

</div>

> [@StevenSiew](#):
>
> In the code below, why is the position at t\_sv=17 given as “Position(t=17.0) is (1085.6,)”  
> Why is the answer (1085.6,0) in brackets, is it a complex number?

I don’t know this package but presumably `(1085.6,)` indicates a one element tuple.

```julia-auto
julia> typeof((1085.6,))
Tuple{Float64}

```

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [August 24, 2024, 5:43pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/15 "2024-08-24T17:43:45Z")

</div>

> [@sumiya11](#):
>
> By the way, in general, is it possible to precompile package extensions to reduce TTFX ?

I don’t know, but here’s my workaround from the user side, i.e. creating a wrapper package which loads both the original package and the extensions, and then using `PrecompileTools`:

```julia
module SymbolicsWithGroebner

import Groebner
import Symbolics: @variables, symbolic_solve
using PrecompileTools: @setup_workload, @compile_workload

export symbolic_solve

@setup_workload begin
    @variables x y z
    @compile_workload begin
        solution = symbolic_solve([x-y, y+2z], [x,y])
    end
end

end # module SymbolicsWithGroebner

```

It’s used as follows:

```julia
import Groebner
import Symbolics: @variables
import SymbolicsWithGroebner: symbolic_solve

@variables x y z
@time symbolic_solve([x-y, y+2z], [x,y])

```

The last `@time` measurement is below 0.5 seconds, down from about 20 seconds.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 24, 2024, 6:29pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/16 "2024-08-24T18:29:52Z")

</div>

PR that? That’s a good thing to add.

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [August 24, 2024, 6:53pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/17 "2024-08-24T18:53:23Z")

</div>

Since my workaround involves loading both Symbolics.jl and Groebner.jl in a super-package, what’s a proper way to add the precompile statements directy into Symbolics.jl? I guess that’s why @sumiya11 hasn’t done it so far.

---

<div class="post-metadata">

**Author:** ![Yassin\_ElBedwihy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yassin_elbedwihy/32/208506_2.png) [@Yassin\_ElBedwihy](https://discourse.julialang.org/u/Yassin_ElBedwihy)\
**Post date:** [August 24, 2024, 7:05pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/18 "2024-08-24T19:05:38Z")

</div>

You can add it to SymbolicsGroebnerExt.jl in the ext dir (i think?)

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [August 24, 2024, 8:55pm UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/19 "2024-08-24T20:55:16Z")

</div>

Yes, that works! I’ve created a PR:

> <https://github.com/JuliaSymbolics/Symbolics.jl/pull/1233>
>
> Currently, \`symbolic\_solve\`, which uses the Groebner.jl package extension, takes… about 20 seconds to run for the first time on my laptop. I've added precompilation statements (using PrecompileTools) in the file \`SymbolicsGroebnerExt.jl\` to significantly reduce the latency for users, following some discussions on Discourse:
> https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/

---

<div class="post-metadata">

**Author:** ![Paul\_Warburton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_warburton/32/206802_2.png) [@Paul\_Warburton](https://discourse.julialang.org/u/Paul_Warburton)\
**Post date:** [August 30, 2024, 6:04am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/20 "2024-08-30T06:04:19Z")

</div>

This does not work at all !

---

<div class="post-metadata">

**Author:** ![lupemba](https://avatars.discourse-cdn.com/v4/letter/l/e5b9ba/32.png) [@lupemba](https://discourse.julialang.org/u/lupemba)\
**Post date:** [August 30, 2024, 6:40am UTC](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466/21 "2024-08-30T06:40:23Z")

</div>

I believe that you are referring to the issues posted in [Symbolics 'solve' command undefined - #9 by abraemer](https://discourse.julialang.org/t/symbolics-solve-command-undefined/118766/9)

I just add the link here so future readers have some context and not just a one line statement.

[Next page](https://discourse.julialang.org/t/new-symbolic-solver-for-symbolics-jl/118466.md?page=2)
