Skip to content

Commit

Permalink
fix errors with doctests (JuliaPy#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
jverzani authored Dec 6, 2020
1 parent 4cef288 commit ade148c
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 1,350 deletions.
23 changes: 0 additions & 23 deletions docs/src/Tutorial/calculus.md
Original file line number Diff line number Diff line change
Expand Up @@ -771,29 +771,6 @@ julia> sympy.differentiate_finite(f(x)*g(x))
(The functions `f` and `g` can also be created with the command `@symfuns f g`, using the `@symfuns` macro.)
----
If we want to expand the intermediate derivative we may pass the
flag `evaluate=True`:
```python
>>> differentiate_finite(f(x)*g(x), evaluate=True)
(-f(x - 1/2) + f(x + 1/2))⋅g(x) + (-g(x - 1/2) + g(x + 1/2))⋅f(x)
```
##### In `Julia`:
```jldoctest calculus
julia> sympy.differentiate_finite(f(x)*g(x), evaluate=true)
/Users/verzani/.julia/conda/3/lib/python3.7/site-packages/sympy/calculus/finite_diff.py:477: SymPyDeprecationWarning:
``evaluate`` flag has been deprecated since SymPy 1.5. See
https://github.com/sympy/sympy/issues/17881 for more info.
deprecated_since_version="1.5").warn()
(-f(x - 1/2) + f(x + 1/2))⋅g(x) + (-g(x - 1/2) + g(x + 1/2))⋅f(x)
```
----
Expand Down
4 changes: 2 additions & 2 deletions docs/src/Tutorial/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The `SymPy` package for `Julia` allows `Julia` users to interact with python's
----

```@contents
Pages = ["intro.md", "gotchas.md", "basic_operations.md", "simplification.md", "calculus.md",
"solvers.md", "matrices.md", "manipulation.md"]
Pages = ["intro.md","gotchas.md", "basic_operations.md", "simplification.md", "calculus.md", "solvers.md",
"matrices.md", "manipulation.md"]
```

4 changes: 2 additions & 2 deletions docs/src/Tutorial/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,8 @@ Solve $x^2 - 2 = 0$.
```jldoctest intro
julia> solve(x^2 - 2, x)
2-element Array{Sym,1}:
-sqrt(2)
sqrt(2)
-√2
√2
```

----
Expand Down
5 changes: 3 additions & 2 deletions docs/src/Tutorial/matrices.md
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ julia> p = M.charpoly(lambda)
PurePoly(lambda**4 - 11*lambda**3 + 29*lambda**2 + 35*lambda - 150, lambda, domain='ZZ')
julia> factor(p) |> string
"(lambda - 5)^2*(lambda - 3)*(lambda + 2)"
"PurePoly(lambda^4 - 11*lambda^3 + 29*lambda^2 + 35*lambda - 150, lambda, domain='ZZ')"
```

Expand Down Expand Up @@ -1200,7 +1200,8 @@ julia> m = Sym[-2*cosh(q/3) exp(-q) 1; exp(q) -2*cosh(q/3) 1; 1 1 -2*cosh(q/3)]
1 1 -2*cosh(q/3)
julia> m.nullspace()
0-element Array{Any,1}
1-element Array{Array{Sym,2},1}:
[-(-2*exp(q)*cosh(q/3) - 4*cosh(q/3)^2 - 1 - 2*exp(-q)*cosh(q/3))/(4*exp(q)*cosh(q/3)^2 + 4*cosh(q/3) + exp(-q)); -(1 - 4*cosh(q/3)^2)/(2*cosh(q/3) + exp(-q)); 1]
```

Expand Down
4 changes: 2 additions & 2 deletions docs/src/Tutorial/simplification.md
Original file line number Diff line number Diff line change
Expand Up @@ -1614,14 +1614,14 @@ it from the expression, and take the reciprocal to get the `f` part.

```jldoctest simplification
julia> l = Sym[]
0-element Array{Sym,1}
Sym[]
julia> frac = apart(frac, a0); string(frac)
"a0 + (a2*a3*a4 + a2 + a4)/(a1*a2*a3*a4 + a1*a2 + a1*a4 + a3*a4 + 1)"
julia> push!(l, a0)
1-element Array{Sym,1}:
a0
a₀
julia> frac = 1/(frac - a0); string(frac)
"(a1*a2*a3*a4 + a1*a2 + a1*a4 + a3*a4 + 1)/(a2*a3*a4 + a2 + a4)"
Expand Down
1,174 changes: 18 additions & 1,156 deletions docs/src/Tutorial/solvers.md

Large diffs are not rendered by default.

124 changes: 9 additions & 115 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,15 @@
# SymPy.jl
# The SymPy tutorial (1.3) in `Julia`

Documentation for [SymPy.jl](https://github.com/JuliaPy/SymPy.jl) a `Julia` interface to Python's [SymPy](https://www.sympy.org/en/index.html) library for symbolic mathematics.

```@index
Pages = ["index.md", "introduction.md", "Tutorial/index.md"]
Depth = 1
```


To install the package, run

```julia
(v1.4) pkg> add SymPy
```

This package relies on `PyCall` to provide a link between `Julia` and `Python`. Installation should install `PyCall`, the `sympy` module for python, and if needed, a python executable.



## Quick example

This package provides a convenient way to access the functionality of the `sympy` library for `Python` from `Julia`, utilizing the `PyCall` package to provide the interface. A symbolic type, a wrapper around a `PyCall.PyObject`, is provided and, as much as reasonable, generic `Julia` methods are created for this type. Many sympy specific features are available through a qualified function call, e.g. `sympy.funcname(...)` or a `Python` method call, e.g., `obj.methname(...)`.

This example from calculus provides an illustation of each.

```jldoctest index
julia> using SymPy
```

Here we create some symbolic variables, one with an assumption:

```jldoctest index
julia> @vars x
(x,)
julia> @vars a real=true
(a,)
```

The basic math functions have methods for symbolic expressions:

```jldoctest index
julia> sin(x)
sin(x)
julia> log(x)
log(x)
```

The output is a symbolic expression.
Here the tutorial for SymPy 1.3 is re-expressed using Julia commands and `SymPy.jl`.

----

A selection of SymPy functions are defined as `Julia` functions. Here are three common calculus operations:
The `SymPy` package for `Julia` allows `Julia` users to interact with python's SymPy module in a mostly seamless manner, thanks to the power of the `PyCall` package for `Julia`. The following pages reexpress the SymPy tutorial illustrating the associated `Julia` commands. There are some changes, but mostly modest ones. To create these pages, the `.rst` files were downloaded and modfied. There is only hand sychronization available with new versions of the SymPy tutorial for Python.

```jldoctest index
julia> limit(sin(a*x)/x, x => 0)
a
----

julia> diff(x^x, (x,3))
x ⎛ 3 3⋅(log(x) + 1) 1 ⎞
x ⋅⎜(log(x) + 1) + ────────────── - ──⎟
⎜ x 2⎟
⎝ x ⎠
julia> integrate(exp(-a*x) * sin(x), x)
a⋅sin(x) cos(x)
- ────────────── - ──────────────
2 a⋅x a⋅x 2 a⋅x a⋅x
a ⋅ℯ + ℯ a ⋅ℯ + ℯ
```

Both `limit` and `integrate` are defined within the package, whereas `diff`, a generic `Julia` function, has a method defined for the first argument being symbolic.


The `diff` function finds derivatives, SymPy's `Derivative` function defines *unevaluated* derivatives, which are evaluated through their `doit` method. `Derivative` is not a `Julia` function, so we must qualify it:

```jldoctest index
julia> out = sympy.Derivative(x^x, x)
d ⎛ x⎞
──⎝x ⎠
dx
julia> out.doit()
x
x ⋅(log(x) + 1)
```

## Using other features of SymPy

By design, along with methods defined for generic functions in `Julia`, only a select number of core SymPy functions are exported; others need to be qualified. Many can be found, as above, from the syntax `sympy.XXX`, where the `XXX` method from the underlying `sympy` module is used. Many more must be imported before being available.

For example, the [Stats](https://docs.sympy.org/latest/modules/stats.html) module provides methods to support the concept of a random variable used in probability and statistics. The following shows how to import all the methods into a session:

```jldoctest Stats
julia> SymPy.PyCall.pyimport_conda("sympy.stats", "sympy")
PyObject <module 'sympy.stats' from '/Users/verzani/.julia/conda/3/lib/python3.7/site-packages/sympy/stats/__init__.py'>
julia> SymPy.import_from(sympy.stats)
julia> p = 1//2
1//2
julia> @vars x integer=true positive=true
(x,)
julia> pdf = p * (1-p)^(x-1);
julia> D = DiscreteRV(x, pdf, set=sympy.S.Naturals)
x
julia> E(D)
2
julia> P(D ≫ 3)
1/8
```

The `import_from` function imports all the functions it can, creating methods specialized on their first argument being symbolic. In this case, `E` and `P` are used above without qualification. `Naturals`, above, is in a different sympy module, and hasn't been imported, so it must be qualified above. The `pyimport_conda` call of `PyCall` will import the module into the specific name, and if necessary install the underlying package.
```@contents
Pages = ["intro.md", "gotchas.md", "basic_operations.md", "simplification.md", "calculus.md",
"solvers.md", "matrices.md", "manipulation.md"]
```

The above works well for interactive usage, but would cause problems were it included in package code, as the assignment within `pyimport_conda` occurs at run time. There are necessary workarounds.
Loading

0 comments on commit ade148c

Please sign in to comment.