You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* add lite version
* edits
* get many tests working, modify matrix code
* fix matrix, dsolve, tests, examples, travis, appveyor
* cleanup
* priviledge a few sympy function calls; do not import all
[here](http://nbviewer.ipython.org/github/JuliaPy/SymPy.jl/blob/master/examples/tutorial.ipynb). In addition, most of the SymPy tutorial has the `julia` counterparts illustrated starting from [index.html](http://htmlpreview.github.io/?https://github.com/JuliaPy/SymPy.jl/blob/master/examples/index.html)
25
25
26
26
### Installation
27
27
28
-
To use this package, both `Python` and its `SymPy` library must be
28
+
To use this package, both Python and its SymPy library must be
29
29
installed on your system. If `PyCall` is installed using `Conda`
30
30
(which is the default if no system `python` is found), then the
31
-
underlying `SymPy` library will be installed via `Conda` when the
32
-
package is first loaded. Otherwise, installing both `Python` and
33
-
`SymPy`(which also requires `mpmath`) can be done by other means.
31
+
underlying SymPy library will be installed via `Conda` when the
32
+
package is first loaded. Otherwise, installing both Python and the
33
+
SymPy library (which also requires mpmath) can be done by other means.
34
34
In this case, the `Anaconda` distribution is suggested, as it provides a single
35
-
installation of `Python` that includes `SymPy` and many other
35
+
installation of Python that includes SymPy and many other
36
36
scientific libraries that can be profitably accessed within `Julia`
37
-
via `PyCall`. (Otherwise, install `Python` then download the `sympy`
37
+
via `PyCall`. (Otherwise, install Python then download the SymPy
38
38
library from https://github.com/sympy/sympy/releases and install.)
39
39
40
40
## The `PyCall` interface to `SymPy`
41
41
42
42
The only point to this package is that using `PyCall` to access
43
-
`SymPy` is somewhat cumbersome. The following is how one would define
44
-
a symbolic value `x`, take its sine, then evaluate at `pi`, say:
43
+
SymPy is somewhat cumbersome. The following is how one would define
44
+
a symbolic value `x`, take its sine, then evaluate the symboic
45
+
expression for `x` equal `pi`, say:
45
46
46
47
```
47
48
using PyCall
48
-
sympy = pyimport("sympy")
49
-
x = sympy.Symbol("x")
50
-
y = sympy.sin(x)
51
-
z = y.subs(x, sympy.pi)
52
-
convert(Float64, z)
49
+
sympy = pyimport("sympy") #
50
+
x = sympy.Symbol("x") # PyObject x
51
+
y = sympy.sin(x) # PyObject sin(x)
52
+
z = y.subs(x, sympy.pi) # PyObject 0
53
+
convert(Float64, z) # 0.0
53
54
```
54
55
55
-
The `Symbol` and `sin` function of `SymPy` are found within the
56
-
imported `sympy` object. They may be referenced with `Python`'s dot
57
-
notation. Similarly, the `subs` method of the `y` object may be
58
-
accessed with Python's dot nottation using PyCall's `getproperty`
59
-
overload to call the method. The call above substitutes a value of
60
-
`sympy.pi` for `x`. This leaves the object as a `PyObject` storing a
61
-
number which can be brought back into `julia` through conversion, in
56
+
57
+
The `sympy` object imported on the second line provides the access to
58
+
much of SymPy's functionality, allowing access to functions
59
+
(`sympy.sin`), properties, modules (`sympy`), and classes
60
+
(`sympy.Symbol`, `sympy.Pi`). The `Symbol` and `sin` operations are found
61
+
within the imported `sympy` module and, as seen, are referenced with
62
+
`Python`'s dot call syntax, as implemented in `PyCall` through a
63
+
specialized `getproperty` method.
64
+
65
+
SymPy's functionality is also found through methods bound to
66
+
an object of a certain class. The `subs` method of the `y` object is an
67
+
example. Such methods are also accessed with Python's dot-call
68
+
syntax. The call above substitutes a value of `sympy.pi` for the
69
+
symbolic variable `x`. This leaves the object as a `PyObject` storing
70
+
a number which can be brought back into `julia` through conversion, in
62
71
this case through an explicit `convert` call.
63
72
64
73
65
-
Alternatively, `PyCall` now has a `*` method, so this could be done with
74
+
Alternatively, `PyCall` now has a `*` method, so the above could also be done with:
66
75
67
76
```
68
77
x = sympy.Symbol("x")
@@ -71,17 +80,17 @@ z = sympy.sin(y)
71
80
convert(Float64, z.subs(x, 1))
72
81
```
73
82
74
-
With `SymPy` this gets replaced by a more `julia`n syntax:
83
+
With the `SymPy` package this gets replaced by a more `julia`n syntax:
75
84
76
85
```
77
86
using SymPy
78
87
x = symbols("x") # or @vars x, Sym("x"), or Sym(:x)
79
88
y = sin(pi*x)
80
-
y(1) # Does subs(y, x, 1). Use y(x=>1) to be specific as to which symbol to substitute
89
+
y(1) # Does y.subs(x, 1). Use y(x=>1) to be specific as to which symbol to substitute
81
90
```
82
91
83
92
The object `x` we create is of type `Sym`, a simple proxy for the
84
-
underlying `PyObject`. We then overload the familiar math functions so
93
+
underlying `PyObject`. The package overloads the familiar math functions so
85
94
that working with symbolic expressions can use natural `julia`
86
95
idioms. The final result here is a symbolic value of `0`, which
87
96
prints as `0` and not `PyObject 0`. To convert it into a numeric value
@@ -92,48 +101,63 @@ float conversion, only there is an attempt to preserve the variable type.
92
101
`Julia`) is converted to the symbolic `PI`, but in general won't be if
93
102
the math constant is coerced to a floating point value before it
94
103
encounters a symbolic object. It is better to just use the symbolic
95
-
value `PI`, an alias for `sympy.pi` used above. A similar comment
96
-
applies for `e`, where `E` should be used.)
104
+
value `PI`, an alias for `sympy.pi` used above.)
97
105
98
-
However, for some tasks the `PyCall` interface is still needed, as
99
-
only a portion of the `SymPy` interface is exposed. To call an
100
-
underlying SymPy method, the `getproperty` method is overloaded so
101
-
that `ex.meth_name(...)` dispatches the method of the object and
102
-
`sympy.meth_name(...)` calls a function in the SymPy module.
103
106
104
-
For example, we could have been more explicit and used:
107
+
----
105
108
106
-
```
107
-
y = sympy.sin(pi * x)
108
-
y.subs(x, 1)
109
-
```
110
109
111
-
As calling the underlying SymPy function is not difficult, the
112
-
interface exposed through overloading `Julia`'s methods attempts to
113
-
keep similar functionality to the familiar `Julia` method when there is
114
-
a discrepancy between conventions.
110
+
SymPy has a mix of function calls (as in `sin(x)`) and method calls
111
+
(as in `y.subs(x,1)`). The function calls are from objects in the base
112
+
`sympy` module. When the `SymPy` package is loaded, in addition to
113
+
specialized methods for many generic `Julia` functions, such as `sin`,
114
+
a priviledged set of the function calls in `sympy` are imported as
115
+
generic functions narrowed on their first argument being a symbolic
116
+
object, as constructed by `Sym` or `symbols`. (Calling
117
+
`import_from(sympy)` will import all the function calls.)
118
+
119
+
The basic usage follows these points:
120
+
121
+
* generic methods from `Julia` and imported functions in the `sympy`
122
+
namespace are called through `fn(object)`
123
+
124
+
* SymPy methods are called through Python's dot-call syntax:
125
+
`object.fn(...)`
115
126
116
-
## Notes
127
+
* Contructors, like `sympy.Symbol`, and other non-function calls from `sympy` are qualified
128
+
with `sympy.Constructor(...)`. Such qualified calls are also useful
129
+
when the first argument is not symbolic.
117
130
118
-
Some aspects of `SymPy` require more modern versions of `sympy` to be
119
-
installed. For example, the matrix functions rely on features of
120
-
`sympy` that are not exposed in the `sympy` installed with Ubuntu LTS
121
-
12.04.
122
131
123
-
In that particular instance, calls such as
132
+
So, these three calls are different,
124
133
125
134
```
126
-
x = symbols("x")
127
-
a = [x 1; 1 x]
128
-
det(a)
135
+
sin(1), sin(Sym(1)), sympy.sin(1)
129
136
```
130
137
131
-
Can be replaced with
138
+
The first involves no symbolic values. The second and third are
139
+
related and return a symbolic value for `sin(1)`. The second
140
+
dispatches on the symbolic argument `Sym(1)`, the third has no
141
+
dispatch, but refers to a SymPy function from the `sympy` object. Its
142
+
argument, `1`, is converted by `PyCall` into a Python object for the
143
+
function to process.
144
+
145
+
In the initial example, slightly rewritten, we could have written:
132
146
133
147
```
134
-
sympy.det(a)
148
+
x = symbols("x")
149
+
y = sin(pi*x)
150
+
y.subs(x, 1)
135
151
```
136
152
137
-
Similarly for `trace`, `eigenvects`, ... . Note these are `sympy`
138
-
methods, not `Julia` methods that have been ported. (Hence,
139
-
`eigenvects` and not `eigvecs`.)
153
+
The first line calls a provided alias for `sympy.symbols` which is
154
+
defined to allow a string (or a symbol) as an argument. The second,
155
+
dispatches to `sympy.sin`, as `pi*x` is symbolic-- `x` is, and
156
+
multiplication promotes to a symbolic value. The third line uses the
157
+
dot-call syntax of `PyCall` to call the `subs` method of the symbolic
158
+
`y` object.
159
+
160
+
161
+
Not illustrated above, but classes and other objects from SymPy are
162
+
not brought in by default, and can be accessed using qualification, as
163
+
in `sympy.Function` (used to define symbolic functions).
0 commit comments