# Who "Symbolics.jl" is for?

Just a generic question on who is the target user for the Symbolics.jl package.
I had a quick look on it, looking to find some alternative to the python-based SymPy (and the SymPy.jl wrapper), but I have now doubts if the two packages are for the same kind of users.

I am a low-math, lazy guy, and all I want is find simple way to avoid pen and paper for computing tedious derivatives, integral (no, by parts no!), solving a few system of equations and so on.
SymPy and the SymPy tutorial are fantastic for these kind of things. I can even say I can arrive to understand them

But then, looking at Symbolic.jl package I am pretty lostâ€¦ it is full of topics that for me are â€śadvancedâ€ť or look â€śof detailâ€ťâ€¦ ok, I can arrive to understand a bit about IR and ASL because I frequent the Julia community by a while now, but my colleagues would be completely lost.
`Sym`, `istree`, â€śexpressionâ€ť, `Num`â€¦ what are these ?? (donâ€™t answer, I got it after a whileâ€¦) By comparison the SymPy tutorial is much more gently, it starts by showing how to achieve basic stuff and, for example, the â€śtreeâ€ť concept is given only at the very end of the tutorial.
So, my question is if indeed the objective of the package is to provide a sympy-alternative in native Julia or the focus is a bit different/ do more advanced stuffâ€¦
I would point that I am not â€ścomplainingâ€ť about the documentation, I am only trying to understand who is the target group of this package.
For example the API is also more elaborated than SymPy.
For a derivative:
SymPy:

``````using SymPy
@vars q
utility   = 100q - 2q^2
marg_util = diff(utility,q)
``````

Symbolics.jl:

``````using Symbolics
@variables q
utility   = 100q - 2q^2
marg_util = expand_derivatives(Differential(q)(utility)) # doesn't feel very intuitive...
``````

Perhaps to be more general and/or efficientâ€¦ but for basic things it is overwhelming :-/

9 Likes

I think Symbolics.jl would benefit from a tutorial that is similar to the Sympy walk through. I also could not follow how to do some straightforward things. In the mean time, a pointer to some example code snippets from other projects might be helpful.

1 Like

You can just write

``````Symbolics.derivative(utility, q)
``````

Itâ€™s a bit unfortunate that `derivative` is not exported by default.

Personally, I think `Symbolic.jl` and other Julia packages for symbolic calculations are very useful when you want to embed symbolic calculations into high-performance Julia code. If you just need a glorified calculator to get some math done, probably there are better choices elsewhere.

2 Likes

I think a lot of the answer is that `Symbolics` was partially designed for use by code rather than users. The library came out of internal usage of the `DifferentialEquations` ecosystem, and it still has some of that heritage in its API.

5 Likes

The real answer is that itâ€™s still young and needs work both in APIs and docs.

11 Likes

Yeah, this block of code shows up halfway through the very first tutorial, and Iâ€™ll go out on a limb and say that thereâ€™s not a single new user whoâ€™s gained a better understanding of Symbolics.jl by seeing it:

``````(var"##MTIIPVar#317", var"##MTKArg#315")->begin
@inbounds begin
@sync begin
let (x, y) = (var"##MTKArg#315"[1], var"##MTKArg#315"[2])
begin
(var"##MTIIPVar#317").nzval[1] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 1), (getproperty(Base, :^))(y, 7))
(var"##MTIIPVar#317").nzval[2] = (getproperty(Base, :^))(x, 1)
(var"##MTIIPVar#317").nzval[3] = (getproperty(Base, :^))(y, 1)
(var"##MTIIPVar#317").nzval[4] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 2), (getproperty(Base, :^))(y, 6))
(var"##MTIIPVar#317").nzval[5] = (getproperty(Base, :^))(x, 2)
(var"##MTIIPVar#317").nzval[6] = (getproperty(Base, :^))(y, 2)
end
end
begin
(var"##MTIIPVar#317").nzval[7] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 3), (getproperty(Base, :^))(y, 5))
(var"##MTIIPVar#317").nzval[8] = (getproperty(Base, :^))(x, 3)
(var"##MTIIPVar#317").nzval[9] = (getproperty(Base, :^))(y, 3)
(var"##MTIIPVar#317").nzval[10] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 4), (getproperty(Base, :^))(y, 4))
(var"##MTIIPVar#317").nzval[11] = (getproperty(Base, :^))(x, 4)
(var"##MTIIPVar#317").nzval[12] = (getproperty(Base, :^))(y, 4)
end
end
begin
(var"##MTIIPVar#317").nzval[13] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 5), (getproperty(Base, :^))(y, 3))
(var"##MTIIPVar#317").nzval[14] = (getproperty(Base, :^))(x, 5)
(var"##MTIIPVar#317").nzval[15] = (getproperty(Base, :^))(y, 5)
(var"##MTIIPVar#317").nzval[16] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 6), (getproperty(Base, :^))(y, 2))
(var"##MTIIPVar#317").nzval[17] = (getproperty(Base, :^))(x, 6)
(var"##MTIIPVar#317").nzval[18] = (getproperty(Base, :^))(y, 6)
end
end
begin
(var"##MTIIPVar#317").nzval[19] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 7), (getproperty(Base, :^))(y, 1))
(var"##MTIIPVar#317").nzval[20] = (getproperty(Base, :^))(x, 7)
(var"##MTIIPVar#317").nzval[21] = (getproperty(Base, :^))(y, 7)
(var"##MTIIPVar#317").nzval[22] = (getproperty(Base, :*))((getproperty(Base, :^))(x, 8), (getproperty(Base, :^))(y, 0))
end
end
end
end
end
nothing
end
``````

I just created a PR to move this example to the end of the tutorial (itâ€™s currently before the examples for substitution and differentiation).

8 Likes