# Reference/API

`SymPy.SymPy`

`SymPy.π`

`SymPy.False`

`SymPy.IM`

`SymPy.PI`

`SymPy.True`

`SymPy.oo`

`SymPy.sympy`

`SymPy.sympy_core`

`SymPy.sympy_matrices`

`SymPy.sympy_plotting`

`SymPy.zoo`

`SymPy.SymFunction`

`SymPy.SymMatrix`

`SymPy.VectorField`

`Base.getindex`

`Base.getindex`

`Base.match`

`Base.occursin`

`Base.replace`

`SymPy.:β¦`

`SymPy.:β§`

`SymPy.:βͺ`

`SymPy.:β«`

`SymPy.:β©΅`

`SymPy.N`

`SymPy.N`

`SymPy.Permutation`

`SymPy.PermutationGroup`

`SymPy.Wild`

`SymPy.ask`

`SymPy.dsolve`

`SymPy.elements`

`SymPy.free_symbols`

`SymPy.import_from`

`SymPy.import_sympy`

`SymPy.jprint`

`SymPy.lambdify`

`SymPy.nonlinsolve`

`SymPy.plot_implicit`

`SymPy.plot_parametric_surface`

`SymPy.refine`

`SymPy.simplify`

`SymPy.solve`

`SymPy.subs`

`SymPy.@symfuns`

`SymPy.@vars`

`SymPy.SymPy`

β Module`SymPy`

package to interface with Python's SymPy library through `PyCall`

.

The basic idea is that a new type β `Sym`

β is made to hold symbolic objects. For this type, the basic functions from SymPy and appropriate functions of `Julia`

are overloaded for `Sym`

objects so that the expressions are treated symbolically and not evaluated immediately. Instances of this type are created by the constructor `Sym`

, the function `symbols`

or the macro `@vars`

.

On loading, a priviledged set of the functions from the `sympy`

module are defined as generic functions with their first argument narrowed to symbolic types. Others may be accessed by qualification, as in `sympy.trigsimp`

. Calling `import_from(sympy)`

will import the rest. SymPy methods are called through Python's dot-call syntax. To find documentation on SymPy functions and methods, one should refer to SymPy's website.

Plotting is provided through `Plots`

recipes. For details, see the help page for `sympy_plotting`

.

The package documentation provides many examples.

`SymPy.π`

β Module`π`

Exported symbol for `SymPy.Q`

, a Julia module implementing `sympy.Q`

. "Questions" can be asked through the patterns `π.query(value)`

(π is entered as [slash]itQ[tab]) or `SymPy.Q.query(value)`

*but not* as `sympy.Q.query(value)`

At one time, the symbol `Q`

was exported for this. To avoid namespace clutter, the unicode alternative is now used. Legacy code would need a definition like `const Q = SymPy.Q`

to work.

`SymPy.False`

β ConstantFalse from SymPy

`SymPy.IM`

β ConstantIM is a symbolic `im`

`SymPy.PI`

β ConstantPI is symbolic `pi`

`SymPy.True`

β ConstantTrue from SymPy

`SymPy.oo`

β Constantoo is a symbolic infinity. Example: `integrate(exp(-x), x, 0, oo)`

.

`SymPy.sympy`

β Constant`sympy`

Variable from `pyimport("sympy")`

. Numerous methods are available through Python's dot-call syntax.

`SymPy.sympy_core`

β Constant`sympy_core`

Variable from `pyimport("sympy.core")`

.

`SymPy.sympy_matrices`

β Constant`sympy_matrices`

Variable from `pyimport("sympy.matrices")`

.

`SymPy.sympy_plotting`

β ConstantPlotting of symbolic objects.

The `Plots`

package provide a uniform interface to many of `Julia`

's plotting packages. `SymPy`

plugs into `Plots`

' "recipes."

The basic goal is that when `Plots`

provides an interface for function objects, this package extends the interface to symbolic expressions.

In particular:

`plot(ex::Sym, a, b; kwargs...)`

will plot a function evaluating`ex`

over [a,b]

Example. Here we use the default backend for `Plots`

to make a plot:

```
using Plots
@vars x
plot(x^2 - 2x, 0, 4)
```

`plot(ex1, ex2, a, b; kwargs...)`

will plot the two expressions in a parametric plot over the interval`[a,b]`

.

Example:

```
@vars x
plot(sin(2x), cos(3x), 0, 4pi) ## also
```

For a few backends (those that support `:path3d`

) a third symbolic expression may be added to have a 3d parametric plot rendered:

`plot(sin(x), cos(x), x, 0, 4pi) # helix in 3d`

`plot(xs, ys, expression)`

will make a contour plot (for many backends).

```
@vars x y
plot(range(0,stop=5, length=50), range(0,stop=5, length=50), x*y)
```

- To plot the surface
`z=ex(x,y)`

over a region we have`Plots.surface`

. For example,

```
@vars x y
surface(-5:5, -5:5, 25 - x^2 - y^2)
```

- a vectorfield plot can (inefficiently but directly) be produced following this example:

```
function vfieldplot(fx, fy; xlim=(-5,5), ylim=(-5,5), n=8)
xs = range(xlim[1], stop=xlim[2], length=n)
ys = range(ylim[1], stop=ylim[2], length=n)
us = vec([x for x in xs, y in ys])
vs = vec([y for x in xs, y in ys])
fxs = vec([fx(x,y) for x in xs, y in ys])
fys = vec([fy(x,y) for x in xs, y in ys])
mxs = maximum(abs.(filter(!isinf, filter(!isnan, fxs))))
mys = maximum(abs.(filter(!isinf, filter(!isnan, fys))))
d = 1/2 * max((xlim[2]-xlim[1])/mxs, (ylim[2]-ylim[1])/mys) / n
quiver(us, vs, quiver=(fxs.*d, fys.*d))
end
fx = (x + y) / sqrt(x^2 + y^2)
fy = (x - y) / sqrt(x^2 + y^2)
vfieldplot(fx, fy)
```

- To plot two or more functions at once, the style
`plot([ex1, ex2], a, b)`

does not work. Rather, use`plot(ex1, a, b); plot!(ex2)`

, as in:

```
@vars x
plot(sin(x), 0, 2pi)
plot!(cos(x))
```

Some graphics provided by `SymPy`

are available if `PyPlot`

is installed, such as:

`sympy.plotting.plot3d_parametric_surface`

`sympy.plotting.plot_implicit`

Plot the parametrically defined surface `[exs[1](u,v), exs[2](u,v), exs[3](u,v)]`

over `[a0,a1] x [b0,b1]`

. The specification of the variables uses a tuple of the form `(Sym, Real, Real)`

following the style of SymPy in `integrate`

, say, where disambiguation of variable names is needed.

```
@vars theta, phi
r = 1
sympy.plotting.plot3d_parametric_surface((r*sin(theta)*sin(phi), r*sin(theta)*cos(phi), r*cos(theta)),
(theta, 0, pi), (phi, 0, pi/2))
```

`sympy.plotting.plot_implicit(equation, (xvar, x0, x1), (yvar, y0, y1))`

will plot implicitly the equation.

```
@syms x y
sympy.plotting.plot_implicit(Eq(x^2+ y^2,3), (x, -2, 2), (y, -2, 2)) # draw a circle
```

`SymPy.zoo`

β Constantzoo complex inifinity

`SymPy.SymFunction`

β TypeCreate a symbolic function. These can be used for specifying differential equations. For these objects we can specify derivatives with the transpose operator (e.g., `u''`

) as opposed to, say `diff(u(x), x, 2)`

.

Example:

```
u = SymFunction("u")
u'
```

Alternatively, we can pass a comma separated string of variable names to create more than one at a time. (The `cls=symfunction`

is no longer supported):

`F,G,H = SymFunction("F, G, H")`

This is just a thin wrapper around `sympy.Functioni`

for symbolic functions that allows prime notation in place of using `diff`

.

The macro `@symfuns`

is also available for constructing symbolic functions.

`SymPy.SymMatrix`

β Type`SymMatrix`

Type to store a SymPy matrix, as created by `sympy.ImmutableMatrix`

.

These have 0-based indexing defined for them to match SymPy

The traditional infix mathmatical operations are defined, but no dot broadcasting.

The `convert(Matrix{Sym}, M)`

call is useful to covert to a Julia matrix

`SymPy.VectorField`

β Type`VectorField(fx, fy`

): create an object that can be `plot`

ted as a vector field.

A vectorfield plot draws arrows at grid points proportional to `[fx(x_i,y_i), fy(x_i,y_i)]`

to visualize the field generated by `[fx, fy]`

.

The plot command: `plot(VectorField(fx, fy), xlims=(-5,5), ylims=(-5,5), n=8)`

will draw the vectorfield. This uses the default values, so the same graph would be rendered by `plot(VectorField(fx,fy))`

.

To faciliate the visualization of solution to the ODE y' = F(x, y(x)), the call `plot(VectorField(F))`

will work. (The order is x then y, though often this is written as F(y(x),x).)

`SymPy`

objects can be passed to `VectorField`

, but this is a bit fragile, as they must each have two variables so that they can be called with two variables. (E.g., `y(1,2)`

will be `1`

not `2`

, as might be intended.)

Examples:

```
using Plots
fx(x,y) = sin(y); fy(x,y) = cos(y)
plot(VectorField(fx, fy), xlims=(-2pi, 2pi), ylims=(-2pi,2pi))
# plot field of y' = 3y*x over (-5,5) x (-5,5)
F(x,y) = 3*y*x
plot(VectorField(F))
# plot field and solution u' = u*(1-u)
u = SymFunction("u"); @vars x
F(x,y) = y*(1-y)
out = dsolve(u'(x) - F(x, u(x)), x, (u, 0, 1))
plot(VectorField(F), xlims=(0,5), ylims=(0,2))
plot!(rhs(out))
```

`Base.getindex`

β Method`x[i]`

Some SymPy Python objects have index notation provided for them through `__getitem__`

. This allows Julia's `getindex`

to dispatch to Python's `__getitem__`

. The index (indices) must be symbolic. This will use 0-based indexing, as it is a simple pass through to Python.

Examples:

```
julia> using SymPy
julia> i,j = sympy.symbols("i j", integer=True)
(i, j)
julia> x = sympy.IndexedBase("x")
x
julia> a = sympy.Sum(x[i], (i, 1, j))
j
___
β²
β²
β± x[i]
β±
βΎβΎβΎ
i = 1
```

`Base.getindex`

β Method`M[i,j]`

Define `getindex`

for SymPy's `ImmutableMatrix`

class.

SymMatrix is 0-based, like python, not Julia. Use Matrix{Sym} for that.

`Base.match`

β Method`match(pattern, expression, ...)`

Match a pattern against an expression; returns a dictionary of matches.

If a match is unsuccesful, returns an *empty* dictionary. (SymPy returns "nothing")

The order of the arguments follows `Julia`

's `match`

function, not `sympy.match`

, which can be used directly, otherwise.

`Base.occursin`

β Methodoccursin(x, G::SymPermutationGroup)

Does G contain x. (In SymPy, this is `contains.)

`Base.replace`

β Method`replace(expression, pattern, value, ...)`

From: SymPy Docs

Traverses an expression tree and performs replacement of matching subexpressions from the bottom to the top of the tree. The default approach is to do the replacement in a simultaneous fashion so changes made are targeted only once. If this is not desired or causes problems, `simultaneous`

can be set to `false`

. In addition, if an expression containing more than one `Wild`

symbol is being used to match subexpressions and the `exact`

flag is `true`

, then the match will only succeed if non-zero values are received for each `Wild`

that appears in the match pattern.

Differences from SymPy:

"types" are specified via calling

`func`

on the head of an expression:`func(sin(x))`

->`sin`

, or directly through`sympy.sin`

functions are supported, but only with

`PyCall`

commands.

Examples (from the SymPy docs)

```
julia> using SymPy
julia> x, y, z = symbols("x, y, z")
(x, y, z)
julia> f = log(sin(x)) + tan(sin(x^2)); string(f) # `string(f)` only so doctest can run
"log(sin(x)) + tan(sin(x^2))"
```

**"type" -> "type"**

Types are specified through `func`

:

```
julia> func = SymPy.Introspection.func
func (generic function with 1 method)
julia> replace(f, func(sin(x)), func(cos(x))) |> string # type -> type
"log(cos(x)) + tan(cos(x^2))"
julia> replace(f, sympy.sin, sympy.cos) |> string
"log(cos(x)) + tan(cos(x^2))"
julia> sin(x).replace(sympy.sin, sympy.cos, map=true)
(cos(x), Dict{Any,Any}(sin(x) => cos(x)))
```

The `func`

function finds the head of an expression (`sin`

and `cos`

above). This could also have been written (perhaps more directly) as:

```
julia> replace(f, sympy.sin, sympy.cos) |> string
"log(cos(x)) + tan(cos(x^2))"
```

**"type" -> "function"**

To replace with a more complicated function, requires some assistance from `Python`

, as an anonymous function must be defined witin Python, not `Julia`

:

```
julia> import PyCall
julia> ## Anonymous function a -> sin(2a)
PyCall.py"""
from sympy import sin, Mul
def anonfn(*args):
return sin(2*Mul(*args))
""")
julia> replace(f, sympy.sin, PyCall.py"anonfn")
β β 2ββ
log(sin(2β
x)) + tanβsinβ2β
x β β
```

**"pattern" -> "expression"**

Using "`Wild`

" variables allows a pattern to be replaced by an expression:

```
julia> a, b = Wild("a"), Wild("b")
(a_, b_)
julia> replace(f, sin(a), tan(2a)) |> string
"log(tan(2*x)) + tan(tan(2*x^2))"
julia> replace(f, sin(a), tan(a/2)) |> string
"log(tan(x/2)) + tan(tan(x^2/2))"
julia> f.replace(sin(a), a) |> string
"log(x) + tan(x^2)"
julia> (x*y).replace(a*x, a)
y
```

In the SymPy docs we have:

Matching is exact by default when more than one Wild symbol is used: matching fails unless the match gives non-zero values for all Wild symbols."

```
julia> replace(2x + y, a*x+b, b-a) # y - 2
y - 2
julia> replace(2x + y, a*x+b, b-a, exact=false) # y + 2/x
2
y + β
x
```

**"pattern" -> "func"**

The function is redefined, as a fixed argument is passed:

```
julia> PyCall.py"""
from sympy import sin
def anonfn(a):
return sin(2*a)
"""
julia> replace(f, sin(a), PyCall.py"anonfn")
β β 2ββ
log(sin(2β
x)) + tanβsinβ2β
x β β
```

**"func" -> "func"**

```
julia> PyCall.py"""
def fn1(expr):
return expr.is_Number
def fn2(expr):
return expr**2
"""
julia> replace(2*sin(x^3), PyCall.py"fn1", PyCall.py"fn2")
β 9β
4β
sinβx β
```

```
julia> PyCall.py"""
def fn1(x):
return x.is_Mul
def fn2(x):
return 2*x
"""
julia> replace(x*(x*y + 1), PyCall.py"fn1", PyCall.py"fn2")
2β
xβ
(2β
xβ
y + 1)
```

`SymPy.:β¦`

β MethodThis is `\leqq<tab>`

mapped as an infix operator to `Le`

`SymPy.:β§`

β MethodThis is `\geqq<tab>`

mapped as an infix operator to `Ge`

`SymPy.:βͺ`

β MethodThis is `\ll<tab>`

mapped as an infix operator to `Lt`

`SymPy.:β«`

β MethodThis is `\gg<tab>`

mapped as an infix operator to `Gt`

`SymPy.:β©΅`

β MethodFor infix `Eq`

one can use \Equal<tab> unicode operator

`SymPy.N`

β Method`N(x::Sym, digits::Int)`

`N`

can take a precision argument, whichm when given as an integer greater than 16, we try to match the digits of accuracy using `BigFloat`

precision on conversions to floating point.

`SymPy.N`

β Method`N(ex)`

Convert a `Sym`

value to a numeric Julian value.

In SymPy, `N(ex, options...)`

is identifcal to `ex.evalf(options...)`

and is used to convert expressions into floating-point approximations. A positional precision argument indicates the number of digits, keyword arguments `chop`

can be used to trim floating point roundoff errors and `subs`

for free variable substitution prior to conversions.

For example, symbolic roots can be computed numerically, even if not available symbolically, by calling `N`

on the values.

Using `SymPy`

within `Julia`

makes having two such functions useful:

- one to do the equivalent of SymPy's
`evalf`

call - one to convert these expressions back into
`Julia`

objects (like`convert(T, ex)`

)

We use `N`

to return a `Julia`

object and `evalf`

to return a symbolic object. The type of `Julia`

object is heurisitically identified.

Examples:

```
julia> using SymPy
julia> x = Sym("x")
x
julia> p = subs(x, x, pi)
Ο
julia> N(p) # float version of pi
Ο = 3.1415926535897...
julia> p.evalf(60) # 60 digits of pi, as a symbolic value
3.14159265358979323846264338327950288419716939937510582097494
julia> N(p, 60) # when a precision is given, "Big" values are returned
3.141592653589793238462643383279502884197169399375105820974939
julia> r = subs(x,x,1.2)
1.20000000000000
julia> N(r) # float
1.2
julia> q = subs(x, x, 1//2)
1/2
julia> N(q) # 1//2
1//2
julia> z = solve(x^2 + 1)[1] # -β
-β
julia> N(z) # 0 - 1im
0 - 1im
julia> z.evalf()
-1.0β
β
julia> rts = solve(x^5 - x + 1)
5-element Array{Sym,1}:
CRootOf(x^5 - x + 1, 0)
CRootOf(x^5 - x + 1, 1)
CRootOf(x^5 - x + 1, 2)
CRootOf(x^5 - x + 1, 3)
CRootOf(x^5 - x + 1, 4)
julia> [r.evalf() for r in rts] # numeric solutions to quintic
5-element Array{Sym,1}:
-1.16730397826142
-0.181232444469875 - 1.08395410131771*I
-0.181232444469875 + 1.08395410131771*I
0.764884433600585 - 0.352471546031726*I
0.764884433600585 + 0.352471546031726*I
julia> [N(r) for r in rts]
5-element Array{Number,1}:
-1.167303978261418684256045899854842180720560371525489039140082449275651903429536
-0.18123244446987538 - 1.0839541013177107im
-0.18123244446987538 + 1.0839541013177107im
0.7648844336005847 - 0.35247154603172626im
0.7648844336005847 + 0.35247154603172626im
```

`N`

returns the value unchanged when it has free symbols.

`SymPy.Permutation`

β Method`Permutation(args...)`

This module mostly implements SymPy's Permutation module.

A permuation can be represented in different ways. Here a permutation is a reaarangment of the values 0, 1, ..., n. For example, the mapping `0->2, 1->3, 2->0, 3->1`

can be presented by a vector: `sigma = [2,3,0,1]`

where `sigma[i] = j`

when `i -> j`

. Otheriwse, it can be presented as a product of cycles: `(0 2)(1 3)`

which reads 0 goes to 2 which goes to 0 (wrapping) and 1 goes to 3 and 3 goes to 1.

Either representation can be passed through the `Permutation`

constructor.

For the vector notation β 0-based β it is passed directly to the constructor:

```
julia> using SymPy
julia> p = Permutation([2,3,0,1])
(0 2)(1 3)
```

If a range describes a permutation, it can be used as well:

```
julia> id = Permutation(10:-1:0)
(0 10)(1 9)(2 8)(3 7)(4 6)
```

Cycle notation can more compactly describe a permuation, it can be passed in as a container of cycles specified through tuples or vectors:

```
julia> p = Permutation([(0,2), (1,3)])
(0 2)(1 3)
```

The latter can be be expresed more quickly as

```
julia> p = Permutation(0,2)(1,3)
(0 2)(1 3)
```

This works as a single cycle can be passed to the `Permutation`

constructor with values separated by commas and the "call" method for `Permuation`

objects is overloaded: for a single argument, the mapping `i -> j`

is created (also the notation `i^p`

returns this) *but* if more than one argument is given, a cycle is created and multiplied on the *right* by `p`

, so that the above becomes `(0,2) * (1,3)`

.

Here are two permutations forming the symmetries of square, naturally represented in the two ways:

```
julia> flip = Permutation([[0,1],[2,3]]) # or Permutation(0,1)(2,3)
(0 1)(2 3)
julia> rotate = Permutation([1,2,3,0]) # or Permutation(0,1,2,3) in cycle notation
(0 1 2 3)
```

Operations on permutations include:

- a function call,
`p(i)`

to recover`j`

where`i -> j`

, also`i^p`

. `*`

for multiplication. The convention is`(p*q)(i) = q(p(i))`

or with the`^`

notation:`i^(p*q) = (i^p)^q`

.`+`

for multiplication when`p`

and`q`

commute, where a check on commuting is performed.`inv`

for the inverse permutation.`/`

, where`p/q`

is`p * inv(q)`

.`p^n`

for powers. We have`inv(p) = p^(-1)`

and`p^order(p)`

is the identity.`p^q`

for conjugate, defined by`inv(q) * p * q`

.

We can see that a flip is an involution through:

```
julia> flip^2 # the identity
(3)
```

whereas a rotation is not (as it has order 4)

```
julia> rotate * rotate
(0 2)(1 3)
julia> rotate.order()
4
```

These two operations do not commute:

```
julia> flip * rotate # (3)(0 2) -- note (n) is the identity
(3)(0 2)
```

```
julia> rotate * flip # (1 3)
(1 3)
```

We can see this is the correct mapping `1 -> 3`

with

```
julia> (1^rotate)^flip, 1^(rotate*flip), flip(rotate(1))
(3, 3, 3)
```

We can check that `flip`

and `rotate^2`

do commute:

```
julia> id = Permutation(3) # (n) is the identify
(3)
julia> flip.commutator(rotate^2) == id
true
```

The conjugate for flip and rotate does the inverse of the flip, then rotates, then flips:

```
julia> rotate^flip
(0 3 2 1)
```

This is different than `flip^rotate`

. As `flip`

commutes with `rotate^2`

this will return `rotate^2`

:

```
julia> (rotate^2)^flip
(0 2)(1 3)
```

There is no support currently for the `Cycle`

class

`SymPy.PermutationGroup`

β Method`PermutationGroup()`

Create Permutation group from group generators

A PermutationGroup is one generated by a collection of permutations.

Some pre-defined groups are built-in:

`SymmetricgGroup(n)`

: S_n or all symmetries of an n-gon`CyclicGroup`

: the group Z_n`DihedralGroup`

: Group formed by a flip and rotation`AlternativeGroup`

: Subgroup of S_n of even elements`AbelianGroup`

: Returns the direct product of cyclic groups with the given orders.

Differences:

- use
`collect(generate(G))`

in place of`list(G.generate())`

`SymPy.Wild`

β Method`Wild(x)`

create a "wild card" for pattern matching

`SymPy.ask`

β Method`ask(query)`

Returns `true`

, `false`

, or `nothing`

; ask

Example:

```
julia> using SymPy
julia> @vars x y integer=true
(x, y)
julia> ask(π.integer(x*y), And(π.integer(x), π.integer(y)))
true
julia> ## really slow isprime:
filter(x -> ask(π.prime(x)), 1:10)
4-element Array{Int64,1}:
2
3
5
7
```

`SymPy.dsolve`

β Methoddsolve(eqn, var, args..,; ics=nothing, kwargs...)

Call `sympy.dsolve`

with possible difference for initial condition specification.

For problems with an initial condition, the `ics`

argument may be specified. This is *different* from the `ics`

argument of `sympy.dsolve`

. (Call directly if that is preferred.)

Here `ics`

allows the specification of a term like `f(x0) = y0`

as a tuple `(f, x0, y0)`

. Similarly, a term like `f''(x0)=y0`

is specified through `(f'', x0, y0)`

. If more than one initial condition is needed, a tuple of tuples is used, as in `((f,x0,y0), (f',x0,z0))`

.

Example:

```
julia> using SymPy
julia> x = Sym("x")
x
julia> y = SymFunction("y")
y
julia> eqn = y'(x) - y(x);
julia> dsolve(eqn, y(x), ics=(y,0,1)) |> string # technical to avoid parsing issue with doctesting
"Eq(y(x), exp(x))"
julia> eqn = y''(x) - y(x) - exp(x);
julia> dsolve(eqn, y(x), ics=((y,0,1), (y, 1, 1//2))) |> string
"Eq(y(x), (x/2 - (-1 + 2*exp(-1) + E)/(4*sinh(1)))*exp(x) - (1 - 3*E)*exp(-x)/(4*sinh(1)))"
```

`SymPy.elements`

β Method`elements(s)`

return elements of a set s as an array, unlike `convert(Set,s)`

`SymPy.free_symbols`

β Method```
free_symbols(ex)
free_symbols(ex::Vector{Sym})
```

Return vector of free symbols of expression or vector of expressions. The results are orderded by `sortperm(string.(fs))`

.

Example:

```
julia> using SymPy
julia> @vars x y z a
(x, y, z, a)
julia> free_symbols(2*x + a*y) # [a, x, y]
3-element Array{Sym,1}:
a
x
y
```

`SymPy.import_from`

β Method`import_from(module, meths; kwargs...)`

Import methods from a python module. Implements functionality of `from module import function`

in Python.

`module`

: a python module, such as`sympy`

`meths`

: nothing or a tuple of symbols to import. If`nothing`

, then all member functions of the module are imported (but not constructors or other objects)`Ms`

: additional Julia Modules to import from. By default, a few base modules are searched for to avoid namespace collisions.`typ`

: a symbol indicating variable type for first argument that the new function should be restricted to. For most, the default,`:SymbolicObject`

will be appropriate`exclude`

: when importing all (`meths=nothing`

), this can be used to avoid importing some methods by name. The default has a few to avoid.

Examples:

```
import_from(sympy) # bring in functions from sympy (done `import_sympy`)
import_from(sympy, (:sin, :cos)) # just bring in a few methods
import_from(sympy , (:Wild,), typ=:Any) # Allows `Wild("x")`
#
import PyCall
PyCall.pyimport_conda("sympy.physics.wigner", "sympy")
import_from(sympy.physics.wigner)
```

`SymPy.import_sympy`

β Method`import_sympy`

This method imports all functions from `mpmath`

and a priviledged set of functions from `sympy`

, as well as the relational operators.

These functions are narrowed on their first argument being of type `SymbolicObject`

.

A few modules are checked for namespace collisions.

If a function naturally takes an non-Symbolic argument as a first argument, then it can be qualified: e.g. `sympy.sin(2)`

(as opposed to `sin(Sym(2))`

).

If a constructor is needed (which is not a function) then it must be qualified. (E.g. `sympy.Function("F")`

, though for this particular case, there is `SymFunction`

defined for convenience.)

`SymPy.jprint`

β Methodcreate basic printed output

`SymPy.lambdify`

β Function```
lambdify(ex, vars=free_symbols();
fns=Dict(), values=Dict, use_julia_code=false,
invoke_latest=true)
```

Take a symbolic expression and return a `Julia`

function or expression to build a function.

`ex::Sym`

a symbolic expression with 0, 1, or more free symbols`vars`

a container of symbols to use for the function arguments. The default is`free_symbols`

which has a specific ordering. Specifying`vars`

allows this default ordering of arguments to be customized.`fns::Dict`

,`vals::Dict`

: Dictionaries that allow customization of the function that walks the expression`ex`

and creates the corresponding AST for a Julia expression. See`SymPy.fn_map`

and`SymPy.val_map`

for the default mappings of sympy functions and values into`Julia`

's AST.`use_julia_code::Bool`

: use SymPy's conversion to an expression, the default is`false`

`invoke_latest=true`

: if`true`

will call`eval`

and`Base.invokelatest`

to return a function that should not have any world age issue. If`false`

will return a Julia expression that can be`eval`

ed to produce a function.

Example:

```
julia> using SymPy
julia> @vars x y z
(x, y, z)
julia> ex = x^2 * sin(x)
2
x β
sin(x)
julia> fn = lambdify(ex)
#87 (generic function with 1 method)
julia> fn(pi)
1.2086779438644711e-15
julia> ex = x + 2y + 3z
x + 2β
y + 3β
z
julia> fn = lambdify(ex)
#87 (generic function with 1 method)
julia> fn(1,2,3) # order is by free_symbols
14
julia> ex(x=>1, y=>2, z=>3)
14
julia> fn = lambdify(ex, (y,x,z))
#87 (generic function with 1 method)
julia> fn(1,2,3)
13
```

!!! Note:

The default produces slower functions due to the calls to `eval`

and `Base.invokelatest`

. In the following `g2`

(which, as seen, requires additional work to compute) is as fast as calling `f`

(on non symbolic types), whereas `g1`

is an order of magnitude slower in this example.

```
julia> @vars x
(x,)
julia> f(x) = exp(cot(x))
f (generic function with 1 method)
julia> g1 = lambdify(f(x))
#88 (generic function with 1 method)
julia> ex = lambdify(f(x), invoke_latest=false)
:(function var"##271"(x)
exp(cot(x))
end)
julia> @eval g2(x) = ($ex)(x)
g2 (generic function with 1 method)
```

An alternative, say, is to use `GeneralizedGenerated`

's `mk_function`

, as follows:

```
julia> using GeneralizedGenerated
julia> body = convert(Expr, f(x))
:(exp(cot(x)))
julia> g3 = mk_function((:x,), (), body)
function = (x;) -> begin
(Main).exp((Main).cot(x))
end
```

This function will be about 2-3 times slower than `f`

.

`SymPy.nonlinsolve`

β Method`nonlinsolve`

Note: if passing variables in use a tuple (e.g., `(x,y)`

) and *not* a vector (e.g., `[x,y]`

).

`SymPy.plot_implicit`

β MethodPlot an implicit equation

```
@syms x y
plot_implicit(Eq(x^2+ y^2,3), (x, -2, 2), (y, -2, 2))
```

`SymPy.plot_parametric_surface`

β FunctionRender a parametrically defined surface plot.

Example:

```
@vars u, v
plot_parametric_surface((u*v,u-v,u+v), (u,0,1), (v,0,1))
```

This uses `PyPlot`

, not `Plots`

for now.

`SymPy.refine`

β Method` refine`

Simplify an expression using assumptions; refine.

`SymPy.simplify`

β Method`simplify`

SymPy has dozens of functions to perform various kinds of simplification. There is also one general function called `simplify`

that attempts to apply all of these functions in an intelligent way to arrive at the simplest form of an expression. (See Simplification for details on `simplify`

and other related functionality).

For non-symbolic expressions, `simplify`

returns its first argument.

`SymPy.solve`

β Method`solve`

Use `solve`

to solve algebraic equations.

Examples:

```
julia> using SymPy
julia> @vars x y a b c d
(x, y, a, b, c, d)
julia> solve(x^2 + 2x + 1, x) # [-1]
1-element Array{Sym,1}:
-1
julia> solve(x^2 + 2a*x + a^2, x) # [-a]
1-element Array{Sym,1}:
-a
julia> solve([a*x + b*y-3, c*x + b*y - 1], [x,y]) # Dict(y => (a - 3*c)/(b*(a - c)),x => 2/(a - c))
Dict{Any,Any} with 2 entries:
x => 2/(a - c)
y => (a - 3*c)/(b*(a - c))
```

A very nice example using `solve`

is a blog entry on Napolean's theorem by Xing Shi Cai.

`SymPy.subs`

β Method`subs`

is used to subsitute a value in an expression with another value. Examples:

```
julia> using SymPy
julia> x,y = symbols("x,y")
(x, y)
julia> ex = (x-y)*(x+2y)
(x - y)β
(x + 2β
y)
julia> subs(ex, (y, y^2))
β 2β β 2β
βx - y β β
βx + 2β
y β
julia> subs(ex, (x,1), (y,2))
-5
julia> subs(ex, (x,y^3), (y,2))
72
julia> subs(ex, y, 3)
(x - 3)β
(x + 6)
```

There is a curried form of `subs`

to use with the chaining `|>`

operator

```
julia> ex |> subs(x,β―)
(β― - y)β
(2β
y + β―)
```

The use of pairs gives a convenient alternative:

```
julia> subs(ex, x=>1, y=>2)
-5
julia> ex |> subs(x=>1, y=>2)
-5
```

`SymPy.@symfuns`

β Macro`symfuns...`

Thanks to `@alhirzel`

for the contribution.

`SymPy.@vars`

β Macro`@vars x y z`

Define symbolic values, possibly with names and assumptions

Examples:

```
@vars x y
@vars a1=>"Ξ±β"
@vars a b real=true
```