Tutoriál

Úvod

SymPy je knihovna jazyka Python pro symbolickou matematiku. Má za cíl stát se kompletním počítačovým algebraickým systémem (CAS, Computer algebra system) a zároveň být co nejjednodušší, aby byla pochopitelná a jednoduše rozšiřitelná. SymPy je napsaná kompletně v jazyce Python a nepotřebuje žádné externí knihovny.

Tento tutoriál je úvodem do SymPy a zároveň ukazuje, co SymPy umí. Přečtěte si ho, aby jste zjistili, jak pro vás může být SymPy užitečná a pokud budete chtít vědět víc, přečtěte si Uživatelskou příručku SymPy, Přehled modulů SymPy, nebo přímo zdrojové kódy.

První kroky se SymPy

Nejjednodušší způsob, jak stáhnout SymPy je jít na http://code.google.com/p/sympy/ a stáhnout nejnovější verzi z doporučených zdrojů:

../_images/featured-downloads.png

Rozbalit ji:

$ tar xzf sympy-0.5.12.tar.gz

a vyzkoušet jí v interpretru Pythonu:

$ cd sympy-0.5.12
$ python
Python 2.4.4 (#2, Jan  3 2008, 13:36:28)
[GCC 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import Symbol, cos
>>> x = Symbol("x")
>>> (1/cos(x)).series(x, 0, 10)
1 + x**2/2 + 5*x**4/24 + 61*x**6/720 + 277*x**8/8064 + O(x**10)

Můžete používat SymPy, jak vidíte výše, což je doporučený způsob pokud jí používate ve svém programu. Můžete si jí také nainstalovat pomocí ./setup.py install jako každý modul Pythonu nebo si jednoduše nainstalovat balíček do vaší oblíbené distribuce Linuxu. Například:

Installing SymPy in Debian

$ sudo apt-get install python-sympy
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  python-sympy
0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.
Need to get 991kB of archives.
After this operation, 5976kB of additional disk space will be used.
Get:1 http://ftp.cz.debian.org unstable/main python-sympy 0.5.12-1 [991kB]
Fetched 991kB in 2s (361kB/s)
Selecting previously deselected package python-sympy.
(Reading database ... 232619 files and directories currently installed.)
Unpacking python-sympy (from .../python-sympy_0.5.12-1_all.deb) ...
Setting up python-sympy (0.5.12-1) ...

For other means how to install SymPy, consult the wiki page Download and Installation.

isympy konzole

For experimenting with new features, or when figuring out how to do things, you can use our special wrapper around IPython called isympy (located in bin/isympy if you are running from the source directory) which is just a standard Python shell that has already imported the relevant SymPy modules and defined the symbols x, y, z and some other things:

$ cd sympy
$ ./bin/isympy
IPython console for SymPy 0.7.2-git (Python 2.7.1) (ground types: gmpy)

These commands were executed:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)

Documentation can be found at http://www.sympy.org

In [1]: (1/cos(x)).series(x, 0, 10)
Out[1]:
     2      4       6        8
    x    5*x    61*x    277*x     / 10\
1 + -- + ---- + ----- + ------ + O\x  /
    2     24     720     8064

Poznámka

Vámi zadané příkazy jsou tučně. Vidíme, že to, co bychom udělali ve 3 řádcích v běžném interpretru Pythonu, lze udělat v isympy v 1 řádku.

SymPy jako kalkulačka

SymPy has three built-in numeric types: Float, Rational and Integer.

Třída Rational reprezentuje racionální čísla jako dvojici Integerů: čitatel a jmenovatel Takže Rational(1, 2) reprezentuje 1/2, Rational(5, 2) reprezentuje 5/2, a tak dále.

>>> from sympy import Rational
>>> a = Rational(1, 2)

>>> a
1/2

>>> a*2
1

>>> Rational(2)**50/Rational(10)**50
1/88817841970012523233890533447265625

Postupujte opatrně, když pracujete s Inty a Floaty v Pythonu, obzvlášť při dělení, jelikož můžete vytvořit číslo Pythonu místo SymPy. Podíl dvou Intů v Pythonu může vytvořit Float – “pravé dělení”, standard Pythonu 3 a defaultní chování isympy, které vkládá dělení z __future__:

>>> 1/2 
0.5

Ale v dřívějších verzích Pythonu, kde nebylo dělení zakomponováno, vyšel oříznutý int:

>>> 1/2 
0

V obou případech se nejedná o číslo SymPy, protože Python vytvořil své vlastní číslo. Většinu času budete pravděpodobně pracovat s čísly Rational, takže dávejte pozor, abyste používali Rational a dostali tak výsledek SymPy. Někomu může připadat příhodné používat místo dlouhého Rational krátké R:

>>> R = Rational
>>> R(1, 2)
1/2
>>> R(1)/2 # R(1) is a SymPy Integer and Integer/int gives a Rational
1/2

Také máme k dispozici několik konstant, jak e nebo pí, se kterými se pracuje jako se symboly (1 + pi se nevypočítá jako numerická hodnota, ale ponechá se 1 + pi) a mají libovolnou přesnost:

>>> from sympy import pi, E
>>> pi**2
pi**2

>>> pi.evalf()
3.14159265358979

>>> (pi + E).evalf()
5.85987448204884

jak vidíte, evalf vyhodnotí výraz na číslo s pohyblivou desetinnou čárkou.

Symbol oo se používá pro třídu definující matematické nekonečno:

>>> from sympy import oo
>>> oo > 99999
True
>>> oo + 1
oo

Symboly

Narozdíl od jiných počítačových algebraických systémů, v SymPy je třeba explicitně deklarovat symbolické proměnné:

>>> from sympy import Symbol
>>> x = Symbol('x')
>>> y = Symbol('y')

On the left is the normal Python variable which has been assigned to the SymPy Symbol class. Predefined symbols (including those for symbols with Greek names) are available for import from abc:

>>> from sympy.abc import x, theta

Symboly mohou být vytvořeny pomocí funkcí symbols nebo var, kde funkce var automaticky přídá vytvořené symboly do namespace, a jak symbols, tak var podporují range notaci:

>>> from sympy import symbols, var
>>> a, b, c = symbols('a,b,c')
>>> d, e, f = symbols('d:f')
>>> var('g:h')
(g, h)
>>> var('g:2')
(g0, g1)

Instances of the Symbol class “play well together” and are the building blocks of expresions:

>>> x + y + x - y
2*x

>>> (x + y)**2
(x + y)**2

>>> ((x + y)**2).expand()
x**2 + 2*x*y + y**2

Mohou být nahrazeny jinými čísly, symboly nebo výrazy použitím subs(stary, novy):

>>> ((x + y)**2).subs(x, 1)
(y + 1)**2

>>> ((x + y)**2).subs(x, y)
4*y**2

>>> ((x + y)**2).subs(x, 1 - y)
1

Pro celý zbytek tutoriálu předpokládejme, že jsme zadali:

>>> from sympy import init_printing
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)

To nám zajistí hezčí výstup. Koukněte do sekce níže Výpis. Pokud máte nainstalovaný font unicode, volbou use_unicode=True dostanete o něco hezčí výstup.

Algebra

Pro rozklad na parciální zlomky, použijte apart(expr, x):

>>> from sympy import apart
>>> from sympy.abc import x, y, z

>>> 1/( (x + 2)*(x + 1) )
       1
---------------
(x + 1)*(x + 2)

>>> apart(1/( (x + 2)*(x + 1) ), x)
    1       1
- ----- + -----
  x + 2   x + 1

>>> (x + 1)/(x - 1)
x + 1
-----
x - 1

>>> apart((x + 1)/(x - 1), x)
      2
1 + -----
    x - 1

Pro zpětné sdružení věcí dohromady, použijte together(expr, x):

>>> from sympy import together
>>> together(1/x + 1/y + 1/z)
x*y + x*z + y*z
---------------
     x*y*z

>>> together(apart((x + 1)/(x - 1), x), x)
x + 1
-----
x - 1

>>> together(apart(1/( (x + 2)*(x + 1) ), x), x)
       1
---------------
(x + 1)*(x + 2)

Analýza

Limity

Limits are easy to use in SymPy, they follow the syntax limit(function, variable, point), so to compute the limit of f(x) as x -> 0, you would issue limit(f, x, 0):

>>> from sympy import limit, Symbol, sin, oo
>>> x = Symbol("x")
>>> limit(sin(x)/x, x, 0)
1

také můžete spočítat limitu v nekonečnu:

>>> limit(x, x, oo)
oo

>>> limit(1/x, x, oo)
0

>>> limit(x**x, x, 0)
1

pro některé netriviální příklady limit si můžete přečíst testovací soubor test_demidovich.py

Derivace

Můžete derivovat libovolný výraz v SymPy pomocí diff(func, var). Například:

>>> from sympy import diff, Symbol, sin, tan
>>> x = Symbol('x')
>>> diff(sin(x), x)
cos(x)
>>> diff(sin(2*x), x)
2*cos(2*x)

>>> diff(tan(x), x)
   2
tan (x) + 1

Výsledek si můžete zkontrolovat:

>>> from sympy import limit
>>> from sympy.abc import delta
>>> limit((tan(x + delta) - tan(x))/delta, delta, 0)
   2
tan (x) + 1

Vyšší derivace můžete spočítat pomocí diff(func, var, n):

>>> diff(sin(2*x), x, 1)
2*cos(2*x)

>>> diff(sin(2*x), x, 2)
-4*sin(2*x)

>>> diff(sin(2*x), x, 3)
-8*cos(2*x)

Rozvoj v řady

Použijte .series(var, point, order):

>>> from sympy import Symbol, cos
>>> x = Symbol('x')
>>> cos(x).series(x, 0, 10)
     2    4     6      8
    x    x     x      x      / 10\
1 - -- + -- - --- + ----- + O\x  /
    2    24   720   40320
>>> (1/cos(x)).series(x, 0, 10)
     2      4       6        8
    x    5*x    61*x    277*x     / 10\
1 + -- + ---- + ----- + ------ + O\x  /
    2     24     720     8064

Další jednoduchý příklad:

>>> from sympy import Integral, pprint

>>> y = Symbol("y")
>>> e = 1/(x + y)
>>> s = e.series(x, 0, 5)

>>> print(s)
1/y - x/y**2 + x**2/y**3 - x**3/y**4 + x**4/y**5 + O(x**5)
>>> pprint(s)
          2    3    4
1   x    x    x    x     / 5\
- - -- + -- - -- + -- + O\x /
y    2    3    4    5
    y    y    y    y

Summation

Compute the summation of f with respect to the given summation variable over the given limits.

summation(f, (i, a, b)) computes the sum of f with respect to i from a to b, i.e.,

                            b
                          ____
                          \   `
summation(f, (i, a, b)) =  )    f
                          /___,
                          i = a

If it cannot compute the sum, it prints the corresponding summation formula. Repeated sums can be computed by introducing additional limits:

>>> from sympy import summation, oo, symbols, log
>>> i, n, m = symbols('i n m', integer=True)

>>> summation(2*i - 1, (i, 1, n))
 2
n
>>> summation(1/2**i, (i, 0, oo))
2
>>> summation(1/log(n)**n, (n, 2, oo))
  oo
 ___
 \  `
  \     -n
  /   log (n)
 /__,
n = 2
>>> summation(i, (i, 0, n), (n, 0, m))
      3    2
m    m    m
-- + -- + -
6    2    3
>>> from sympy.abc import x
>>> from sympy import factorial
>>> summation(x**n/factorial(n), (n, 0, oo))
 x
e

Integrály

SymPy umí počítat neurčité a určité integrály elementárních a speciálních transcendentních funkcí pomocí fuknce integrate(), která využívá silného rozšířeného Risch-Normanova algoritmu, některých heuristik a porovnávání vzorků:

>>> from sympy import integrate, erf, exp, sin, log, oo, pi, sinh, symbols
>>> x, y = symbols('x,y')

Můžete integrovat elementární funkce:

>>> integrate(6*x**5, x)
 6
x
>>> integrate(sin(x), x)
-cos(x)
>>> integrate(log(x), x)
x*log(x) - x
>>> integrate(2*x + sinh(x), x)
 2
x  + cosh(x)

Také speciální funkce lze jednoduše integrovat:

>>> integrate(exp(-x**2)*erf(x), x)
  ____    2
\/ pi *erf (x)
--------------
      4

It is possible to compute definite integrals:

>>> integrate(x**3, (x, -1, 1))
0
>>> integrate(sin(x), (x, 0, pi/2))
1
>>> integrate(cos(x), (x, -pi/2, pi/2))
2

Also, improper integrals are supported as well:

>>> integrate(exp(-x), (x, 0, oo))
1
>>> integrate(log(x), (x, 0, 1))
-1

Komplexní čísla

Kromě imaginárního čísla, I, symboly mohou být vytvořeny s atributy (například real, positive, complex, atd...), a to ovlivní jak se budou chovat:

>>> from sympy import Symbol, exp, I
>>> x = Symbol("x") # a plain x with no attributes
>>> exp(I*x).expand()
 I*x
e
>>> exp(I*x).expand(complex=True)
   -im(x)               -im(x)
I*e      *sin(re(x)) + e      *cos(re(x))
>>> x = Symbol("x", real=True)
>>> exp(I*x).expand(complex=True)
I*sin(x) + cos(x)

Funkce

trigonometrické

>>> from sympy import asin, asinh, cos, sin, sinh, symbols, I
>>> x, y = symbols('x,y')

>>> sin(x + y).expand(trig=True)
sin(x)*cos(y) + sin(y)*cos(x)

>>> cos(x + y).expand(trig=True)
-sin(x)*sin(y) + cos(x)*cos(y)

>>> sin(I*x)
I*sinh(x)

>>> sinh(I*x)
I*sin(x)

>>> asinh(I)
I*pi
----
 2

>>> asinh(I*x)
I*asin(x)

>>> sin(x).series(x, 0, 10)
     3     5     7       9
    x     x     x       x       / 10\
x - -- + --- - ---- + ------ + O\x  /
    6    120   5040   362880

>>> sinh(x).series(x, 0, 10)
     3     5     7       9
    x     x     x       x       / 10\
x + -- + --- + ---- + ------ + O\x  /
    6    120   5040   362880

>>> asin(x).series(x, 0, 10)
     3      5      7       9
    x    3*x    5*x    35*x     / 10\
x + -- + ---- + ---- + ----- + O\x  /
    6     40    112     1152

>>> asinh(x).series(x, 0, 10)
     3      5      7       9
    x    3*x    5*x    35*x     / 10\
x - -- + ---- - ---- + ----- + O\x  /
    6     40    112     1152

Sférické funkce

>>> from sympy import Ylm
>>> from sympy.abc import theta, phi

>>> Ylm(1, 0, theta, phi)
  ___
\/ 3 *cos(theta)
----------------
        ____
    2*\/ pi

>>> Ylm(1, 1, theta, phi)
   ___  I*phi
-\/ 6 *e     *sin(theta)
------------------------
            ____
        4*\/ pi

>>> Ylm(2, 1, theta, phi)
   ____  I*phi
-\/ 30 *e     *sin(theta)*cos(theta)
------------------------------------
                  ____
              4*\/ pi

Faktoriály a gamma funkce

>>> from sympy import factorial, gamma, Symbol
>>> x = Symbol("x")
>>> n = Symbol("n", integer=True)

>>> factorial(x)
x!

>>> factorial(n)
n!

>>> gamma(x + 1).series(x, 0, 3) # i.e. factorial(x)
                      /          2     2\
                    2 |EulerGamma    pi |    / 3\
1 - EulerGamma*x + x *|----------- + ---| + O\x /
                      \     2         12/

Zeta funkce

>>> from sympy import zeta
>>> zeta(4, x)
zeta(4, x)

>>> zeta(4, 1)
  4
pi
---
 90

>>> zeta(4, 2)
       4
     pi
-1 + ---
      90

>>> zeta(4, 3)
         4
  17   pi
- -- + ---
  16    90

Polynomy

>>> from sympy import assoc_legendre, chebyshevt, legendre, hermite
>>> chebyshevt(2, x)
   2
2*x  - 1

>>> chebyshevt(4, x)
   4      2
8*x  - 8*x  + 1

>>> legendre(2, x)
   2
3*x    1
---- - -
 2     2

>>> legendre(8, x)
      8         6         4        2
6435*x    3003*x    3465*x    315*x     35
------- - ------- + ------- - ------ + ---
  128        32        64       32     128

>>> assoc_legendre(2, 1, x)
        __________
       /    2
-3*x*\/  - x  + 1

>>> assoc_legendre(2, 2, x)
     2
- 3*x  + 3

>>> hermite(3, x)
   3
8*x  - 12*x

Diferenciální rovnice

V isympy:

>>> from sympy import Function, Symbol, dsolve
>>> f = Function('f')
>>> x = Symbol('x')
>>> f(x).diff(x, x) + f(x)
        2
       d
f(x) + ---(f(x))
         2
       dx

>>> dsolve(f(x).diff(x, x) + f(x), f(x))
f(x) = C1*sin(x) + C2*cos(x)

Algebraické rovnice

V isympy:

>>> from sympy import solve, symbols
>>> x, y = symbols('x,y')
>>> solve(x**4 - 1, x)
[-1, 1, -I, I]

>>> solve([x + 5*y - 2, -3*x + 6*y - 15], [x, y])
{x: -3, y: 1}

Lineární algebra

Matice

Matice jsou vytvořeny jako instance třídy Matrix:

>>> from sympy import Matrix, Symbol
>>> Matrix([[1, 0], [0, 1]])
[1  0]
[    ]
[0  1]

They can also contain symbols:

>>> x = Symbol('x')
>>> y = Symbol('y')
>>> A = Matrix([[1, x], [y, 1]])
>>> A
[1  x]
[    ]
[y  1]

>>> A**2
[x*y + 1    2*x  ]
[                ]
[  2*y    x*y + 1]

For more about Matrices, see the Linear Algebra tutorial.

Porovnávání vzorků

Použijte metodu .match() spolu s třídou Wild pro porovnávání výrazů. Metoda vrátí slovník s požadovanými substitucemi, jako vidíme zde:

>>> from sympy import Symbol, Wild
>>> x = Symbol('x')
>>> p = Wild('p')
>>> (5*x**2).match(p*x**2)
{p: 5}

>>> q = Wild('q')
>>> (x**2).match(p*x**q)
{p: 1, q: 2}

Pokud je porovnání neúspěšné, vrátí None:

>>> print (x + 1).match(p**x)
None

Lze také použít parametr exclude třídy Wild, aby se určité věci nezobrazily ve výsledku:

>>> p = Wild('p', exclude=[1, x])
>>> print (x + 1).match(x + p) # 1 is excluded
None
>>> print (x + 1).match(p + 1) # x is excluded
None
>>> print (x + 1).match(x + 2 + p) # -1 is not excluded
{p_: -1}

Výpis

Je spousta způsobů, jak mohou být výrazy vypisovány.

Standardní

To je to, co vrátí str(expression) a vypadá to takto:

>>> from sympy import Integral
>>> from sympy.abc import x
>>> print x**2
x**2
>>> print 1/x
1/x
>>> print Integral(x**2, x)
Integral(x**2, x)

Pěkný výpis

Nice ascii-art printing is produced by the pprint function:

>>> from sympy import Integral, pprint
>>> from sympy.abc import x
>>> pprint(x**2)
 2
x
>>> pprint(1/x)
1
-
x
>>> pprint(Integral(x**2, x))
  /
 |
 |  2
 | x  dx
 |
/

If you have a unicode font installed, the pprint function will use it by default. You can override this using the use_unicode option.:

>>> pprint(Integral(x**2, x), use_unicode=True)

⎮  2
⎮ x  dx

Pro více příkladů pěkného unicode výstupu koukněte na wiki na Pretty Printing

Tip: To make pretty printing the default in the Python interpreter, use:

$ python
Python 2.5.2 (r252:60911, Jun 25 2008, 17:58:32)
[GCC 4.3.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import init_printing, var, Integral
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
>>> var("x")
x
>>> x**3/3
 3
x
--
3
>>> Integral(x**2, x) #doctest: +NORMALIZE_WHITESPACE
  /
 |
 |  2
 | x  dx
 |
/

Python výstup

>>> from sympy.printing.python import python
>>> from sympy import Integral
>>> from sympy.abc import x
>>> print python(x**2)
x = Symbol('x')
e = x**2
>>> print python(1/x)
x = Symbol('x')
e = 1/x
>>> print python(Integral(x**2, x))
x = Symbol('x')
e = Integral(x**2, x)

LaTeX výstup

>>> from sympy import Integral, latex
>>> from sympy.abc import x
>>> latex(x**2)
x^{2}
>>> latex(x**2, mode='inline')
$x^{2}$
>>> latex(x**2, mode='equation')
\begin{equation}x^{2}\end{equation}
>>> latex(x**2, mode='equation*')
\begin{equation*}x^{2}\end{equation*}
>>> latex(1/x)
\frac{1}{x}
>>> latex(Integral(x**2, x))
\int x^{2}\, dx

MathML

>>> from sympy.printing.mathml import mathml
>>> from sympy import Integral, latex
>>> from sympy.abc import x
>>> print mathml(x**2)
<apply><power/><ci>x</ci><cn>2</cn></apply>
>>> print mathml(1/x)
<apply><power/><ci>x</ci><cn>-1</cn></apply>

Pyglet

>>> from sympy import Integral, preview
>>> from sympy.abc import x
>>> preview(Integral(x**2, x)) 

If pyglet is installed, a pyglet window will open containing the LaTeX rendered expression:

../_images/pngview1.png

Poznámky

isympy volá pprint automaticky, proto standardně vidíte pěkný výpis.

Všimněte si, že je přístupný modul pro výpisy, sympy.printing. Další metody dostupné díky tomuto modulu jsou:

  • pretty(expr), pretty_print(expr), pprint(expr): Return or print, respectively, a pretty representation of expr. This is the same as the second level of representation described above.
  • latex(expr), print_latex(expr): Vrací, respektive vypisuje, LaTeX reprezentaci expr
  • mathml(expr), print_mathml(expr): Return or print, respectively, a MathML representation of expr.
  • print_gtk(expr): Print expr to Gtkmathview, a GTK widget that displays MathML code. The Gtkmathview program is required.

Další dokumentace

Nyní je čas dozvědět se více o SymPy. Pročtěte si Uživatelskou příručku SymPy a Přehled modulů SymPy.

Be sure to also browse our public wiki.sympy.org, that contains a lot of useful examples, tutorials, cookbooks that we and our users contributed, and feel free to edit it.

Překlady

Tento tutoriál je také k dispozici v těchto jazycích: