# Trying to switch from sympy

**URL:** <https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927>\
**Category:** General Usage\
**Created:** [March 23, 2018, 6:03pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927 "2018-03-23T18:03:04Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![EvilPictureBook](https://avatars.discourse-cdn.com/v4/letter/e/5fc32e/32.png) [@EvilPictureBook](https://discourse.julialang.org/u/EvilPictureBook)\
**Post date:** [March 23, 2018, 6:03pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/1 "2018-03-23T18:03:04Z")

</div>

Hi,

I’m pretty new to Julia, coming from Python. In the transition process I’m looking at the different symbolic math options in Julia, both SymEngine.jl, and SymPy.jl

I was wondering if there’s a way to lambdify a symbolic matrix using either of the two (or some other) packages. Something like (I tried doing this in SymPy.sj too):

```julia
using SymEngine

@vars x1 x2 x3 x4

x = [x1, x2, x3, x4]

A = [[x1 x2];[x3 x4]]

f1 = lambdify(A[1,1]) #works, but not really what I'm looking for

f2 = lambdify(x,A) #does not work
f3 = lambdify(A) #does not work

```

In python - sympy I can do (with equivalent setup):

```julia
f = lambdify(x,A)

```

I was hoping someone here may have an idea of what I’m doing wrong . . .

Thanks.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 23, 2018, 6:58pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/2 "2018-03-23T18:58:58Z")

</div>

> [@EvilPictureBook](#):
>
> lambdify(A)

`lambdify.(A)` if you want to apply it elementwise?

---

<div class="post-metadata">

**Author:** ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)\
**Post date:** [March 23, 2018, 7:44pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/3 "2018-03-23T19:44:16Z")

</div>

What is `lambdify(x,A)` supposed to do?

---

<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:** [March 23, 2018, 8:10pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/4 "2018-03-23T20:10:52Z")

</div>

> [@stevengj](#):
>
> lambdify.(A) if you want to apply it elementwise?

That will give an array of functions though, instead of a function that produces an array. There’s an open issue on this topic (I’m guessing the same author).

> <https://github.com/symengine/SymEngine.jl/issues/113>
>
> Hi,
> 
> I was wondering if there's a way to lambdify a symbolic matrix. Something… like:
> 
> \`\`\`
> using SymEngine
> 
> @vars x1 x2 x3 x4
> 
> x = \[x1, x2, x3, x4\]
> 
> A = \[\[x1 x2\];\[x3 x4\]\]
> 
> f1 = lambdify(A\[1,1\]) #works, but not really what I'm looking for
> 
> f2 = lambdify(x,A) #does not work
> f3 = lambdify(A) #does not work
> \`\`\`
> 
> In sympy I can do (with equivalent setup):
> \`\`\`
> f = lambdify(x,A)
> \`\`\`
> 
> Thanks.

It probably needs a function defined that internally `lambdify`s the array and then builds the return function. If there’s a more standard SymEngine answer, @isuruf would be the one who would know.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [March 23, 2018, 9:23pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/5 "2018-03-23T21:23:03Z")

</div>

Why do you even want to use sympy for this? can’t you just do:

```nohighlight
f(x) = [[a b];[c d]]

```

Why not just do that if that’s the function you want. With my symbolic package [Reduce.jl](https://github.com/chakravala/Reduce.jl), there is no such thing as `lambdify` because it works directly on Julia abstract syntax trees. No need to overcomplicate things.

From my perspective, having separate types of symbolic variables and implementing a lambdify function are all superfluous, since one can just work with abstract syntax trees to manipulate and construct the expression one wants to get. So the way I see it the other symbolic packages way overcomplicate things that can be accomplished in a much simpler way using Julia’s language itself.

Since you do not appear to do any symbolic operations, you can just do this:

```nohighlight
julia> f(a,b,c,d) = [a b;c d]
f (generic function with 1 method)

julia> f(1,2,3,4)
2×2 Array{Int64,2}:
 1 2
 3 4

```

Although, you could also manipulate an expression like that `using Reduce`. For example, you could differentiate with respect to variable `a` like so:

```nohighlight
julia> Expr(:function,:(f(a,b,c,d)),:([a b;c d]))
:(function f(a, b, c, d)
        [a b; c d]
    end)

julia> df(ans, :a)
:(function f(a, b, c, d)
        [1 0; 0 0]
    end)

```

Then to use the function you just created, you can `eval` it and use it like any other Julia function. With a `Reduce.jl` style symbolic package in Julia, you don’t even need `lambdify` or declare `@vars`.

Here is another example:

```nohighlight
julia> using Reduce;
julia> Expr(:function,:(f(a,b,c,d)),:([a^2 b*x;c*a d]))
:(function f(a, b, c, d)
        [a ^ 2 b * x; c * a d]
    end)

julia> df(ans,:a)
:(function f(a, b, c, d)
        [2a 0; c 0]
    end)

julia> eval(ans)
f (generic function with 1 method)

julia> f(1,2,3,4)
2×2 Array{Int64,2}:
 2 0
 3 0

```

Just work with julia’s abstract syntax tree, is what I would say.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [March 23, 2018, 10:23pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/6 "2018-03-23T22:23:36Z")

</div>

One way to do this in [`Symata.jl`](https://github.com/jlapeyre/Symata.jl) is

```julia
symata > A = [[x1,x2], [x3,x4]]
Out(1) = [[x1,x2],[x3,x4]]

symata 2> f = Compile(Evaluate(A))
Out(2) = (::#3) (generic function with 1 method)

symata 3> f(1,2,3,4)
Out(3) = [[1,2],[3,4]]

symata 4> g = Compile(sin(x)/x)
Out(4) = (::#5) (generic function with 1 method)

symata 5> g(0.0001)
Out(5) = 0.9999999983333334

```

I should mention that this is done with Julia v0.5. But these work with v0.6.2 as well.

---

<div class="post-metadata">

**Author:** ![EvilPictureBook](https://avatars.discourse-cdn.com/v4/letter/e/5fc32e/32.png) [@EvilPictureBook](https://discourse.julialang.org/u/EvilPictureBook)\
**Post date:** [March 23, 2018, 10:29pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/7 "2018-03-23T22:29:14Z")

</div>

Thank you all for the replies.

@mzaffalon lambdify(x,A) generates a function which will return a matrix A, when given a vector of parameters the same length and order as x. So it’s a way to take a symbolic matrix with symbols in x, and then get a numeric matrix out.

@stevengj and @ChrisRackauckas. You’re right, that’s my issue as well. I wasn’t sure if I was just missing something, so I thought I’d ask here as well.

@chakravala thanks for pointing out your repo I’ll take a closer look at it. The example I gave was the smallest working bit of code to show what I was trying to do. The matrices I’m trying to lambdify come from robot kinematics/dynamics. So I’m symbolically calculating things like jacobian, inertia, and coriolis matrices and I want to be able to get numerical versions of those as a function of the robot state.

Thanks all.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 24, 2018, 2:05am UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/8 "2018-03-24T02:05:15Z")

</div>

If that’s your use case, you might be interested in [https://github.com/JuliaRobotics/RigidBodyDynamics.jl/blob/master/notebooks/Symbolic%20double%20pendulum.ipynb](https://github.com/JuliaRobotics/RigidBodyDynamics.jl/blob/master/notebooks/Symbolic%20double%20pendulum.ipynb). I don’t know of a good solution to your particular problem (maybe try [https://github.com/rdeits/CommonSubexpressions.jl](https://github.com/rdeits/CommonSubexpressions.jl) ?), but please feel free to contact me about robot kinematics and dynamics in Julia, and please share your findings!

---

<div class="post-metadata">

**Author:** ![isuruf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isuruf/32/106_2.png) [@isuruf](https://discourse.julialang.org/u/isuruf)\
**Post date:** [March 25, 2018, 6:26am UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/9 "2018-03-25T06:26:57Z")

</div>

Following works in SymEngine.jl master version.

```julia
f2 = lambdify(A, x)
f3 = lambdify(A)

```

I recommend the first method as the order of the variables in the second one is undefined if there is more than one variable.

---

<div class="post-metadata">

**Author:** ![EvilPictureBook](https://avatars.discourse-cdn.com/v4/letter/e/5fc32e/32.png) [@EvilPictureBook](https://discourse.julialang.org/u/EvilPictureBook)\
**Post date:** [March 25, 2018, 3:41pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/10 "2018-03-25T15:41:17Z")

</div>

@isuruf Thank you! Cloning the package (as opposed to just Pkg.add()) did it. Everything seems to work in the master branch.

@tkoolen Thanks for the notebook link. I actually started looking at Julia because of RigidBodyDynamics.jl. I’ll be sure to post anything interesting I end up doing with Julia.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [March 25, 2018, 3:48pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/11 "2018-03-25T15:48:33Z")

</div>

Awesome, thank you!

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [March 25, 2018, 8:28pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/12 "2018-03-25T20:28:41Z")

</div>

I noticed that in the example above the output of the compiled Symata code is still a Symata `List`. But, the result is meant to be used in julia-only code. So, the `Lists` should be converted to Julia `Array`s. I changed this and committed to both branches `jv0.5only`, and ` v0.6-a`. Below is the corrected example plus another way to get the same result from `Symata`

```julia
symata 1> A = [[x1,x2], [x3,x4]]
Out(1) = [[x1,x2],[x3,x4]]

symata 2> f = Compile(Evaluate(A))
Out(2) = (::#3) (generic function with 1 method)

symata 3> f(1,2,3,4) # result is now a Julia Array
Out(3) = 2-element Array{Array{Int64,1},1}:
 [1, 2]
 [3, 4]
symata 4> ExportJ(f) # export the function from Symata to Julia

julia> f(5,6,7,8) # now call from Julia (after changing repl mode with `=`)
2-element Array{Array{Int64,1},1}:
 [5, 6]
 [7, 8]

# @symExpr interprets its argument as a Symata expression,
# evaluates it, and translates the result to a Julia expression
julia> g(x1,x2,x3,x4) = @symExpr A
g (generic function with 1 method)

julia> g(5,6,7,8)
2-element Array{Array{Int64,1},1}:
 [5, 6]
 [7, 8]

```

A more interesting example:

```julia
symata 26> Table(LegendreP(i,x), [i,1,3])
Out(26) = [x,-1/2 + (3/2)*x^2,(-3/2)*x + (5/2)*x^3]

julia> j(x) = @symExpr Table(LegendreP(i,x), [i,1,3])
j (generic function with 1 method)

julia> j(.5)
3-element Array{Float64,1}:
  0.5   
 -0.125 
 -0.4375

julia> j(1//2)
3-element Array{Rational{Int64},1}:
  1//2 
 -1//8 
 -7//16

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [March 25, 2018, 8:35pm UTC](https://discourse.julialang.org/t/trying-to-switch-from-sympy/9927/13 "2018-03-25T20:35:52Z")

</div>

Instead of cloning, you can also use `Pkg.add("Pack")` and then `Pkg.checkout("Pack")` to get the master branch. Then `Pkg.free("Pack")` to return to version management to `Pkg`.
