Előadás: Damásdi Gábor damasdigabor@caesar.elte.com
Gyakorlat:
Lesznek meghívott előadók
import sympy as sym
import math
import numpy as np
import matplotlib.pyplot as plt
A python alapból kerekítve tárolja a float
-okat
math.log(16), math.log(16, 2), math.exp(2), math.exp(math.log(10)),math.sqrt(8)
$$=?$$ $$e^6$$
np.pi**4+np.pi**5-np.e**6
A szimbolikus számítások célja, hogy a matematikai objektumokat precízen kezelje, kerekítések nélkül, és hogy formális objektumokkal is tudjunk számolni, mint például polinomok vagy függvények.
Előnyök:
Hátrányok:
A SymPy három új típust vezet be a számoknak: Real, Rational és Integer.
a = sym.Rational(1, 2)
a
sym.Rational(7)**(sym.Rational(1,2))
(sym.Rational(7)**(sym.Rational(1,2)))**2
sym.pi**2
Tetszőleges pontossággal kiértékelhetőek a valós számok:
sym.pi.evalf()
sym.pi.evalf(2000)
Itt is van végtelen!
sym.oo > 99999
sym.oo+1
1/-sym.oo
print(sym.Rational(1, 2)+sym.Rational(3, 4))
print(sym.Rational(1, 2)*sym.Rational(3, 4))
print(sym.Rational(1, 2)/sym.Rational(3, 4))
a=sym.real_root((sym.Rational(8)+sym.real_root(sym.Rational(21),2)*sym.Rational(3)),3)+sym.real_root((sym.Rational(8)-sym.real_root(sym.Rational(21),2)*sym.Rational(3)),3)-1
a
a.evalf(20)
A Python változóival szemben itt deklarálni kell a változókat!
x = sym.Symbol('x')
y = sym.Symbol('y')
alma=sym.Symbol('z') #nem kell hogy passzoljanak
type(x)
2*x+x**2
(x+y)**2
Expand
Kifejti az kifejezést
sym.expand((x + y) ** 3)
sym.expand(x + y, complex=True)
sym.expand(sym.cos(x + y),trig=True)
Simplify
Egyszerűsíti a kifejezést
(x + x * y) / x
sym.simplify((x + x * y) / x)
sym.simplify(sym.sin(x)/sym.cos(x))
sym.trigsimp(sym.sin(x)**2 + sym.cos(x)**2)
Behelyettesítés, kiértékelés
f=sym.cos(x)+7
f.subs(x,y)
f # A SymPy objektumai immutableök!! (kivéve a mátrixokat)
f.subs(x,0)
Szorzattá alakítás
f = x ** 4 - 3 * x ** 2 + 1
sym.factor(f)
f = x ** 42 -1
sym.factor(f)
Egyebek
expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
expr
sym.apart(expr)
expr = x*y + x - 3 + 2*x**2*y**2 - y*x**2 + y**2+x**3
collected_expr = sym.collect(expr, y)
collected_expr
collected_expr = sym.collect(expr, x)
collected_expr
Határérték limit
print(sym.limit(x, x, sym.oo))
print(sym.limit((2*x+3) / x, x, sym.oo))
print(sym.limit(x ** x, x, 0))
A sym.diff(func, var, n)
kiszámolja az n. deriváltat.
sym.diff(sym.sin(2 * x), x, 2)
sym.diff(sym.log(x), x, 1)
Taylor sorfejtés
sym.series(sym.cos(x), x, 0)
sym.integrate(6 * x ** 5, x)
sym.integrate(sym.sin(x), x)
sym.integrate(sym.exp(-x ** 2) * sym.erf(x), x)
sym.integrate(sym.exp(-x**2 - y**2), (x, -sym.oo, sym.oo), (y, -sym.oo, sym.oo))
Határozott integrál
sym.integrate(sym.sin(x), (x, 0, sym.pi / 2))
Improprius integrál
sym.integrate(sym.exp(-x ** 2), (x, -sym.oo, sym.oo))
Az első paraméter az egyenlet, aminek a gyökeit keresi, a második a változó.
sym.solveset(x ** 4 - 1, x)
a = sym.Symbol('a')
b = sym.Symbol('b')
c = sym.Symbol('c')
d = sym.Symbol('d')
e = sym.Symbol('e')
f = sym.Symbol('f')
sym.solveset(a*x ** 2 + b*x +c , x)
sym.solveset(a*x ** 3 + b*x**2 +c*x+d , x)
sym.solveset(a*x ** 4 + b*x**3 +c*x**2+d*x+e , x)
sym.solveset(a*x ** 5 + b*x**4 +c*x**3+d*x**2+e*x+f , x)
Ezzel szemben a Numpy simán megold nekünk magasabb rendű polinomokat numerikusan:
coeff = [1, 2, 1,2,7,9,10,11]
np.roots(coeff)
Lineáris egyenletrendszer
A solve
parancsot használhatjuk, ami egy dict-el tér vissza.
solution = sym.solve((x + 5 * y - 2, -3 * x + 6 * y - 15), (x, y))
solution[x], solution[y]
z=sym.Symbol('z')
sym.linsolve([x + y + z - 1, x + y + 2*z - 3 ], (x, y, z))
sym.Matrix([[1, 0], [0, 1]])
A nagy különbség a Numpy tömbjeivel szemben, hogy szimbólumokat is tehetünk bele!
A = sym.Matrix([[1, x], [y, 1]])
A
A.det()
A.eigenvals()
A.eigenvects() ## sajátérték, multiplicitás, sajátvetor hármasokat ad vissza
P, D = A.diagonalize()
print(P)
print(D)
P*D*(P**-1)
sym.simplify( P*D*P**-1)
Bonyolultabb kifejezéseknél olyan problémába is futhatunk, hogy a program nem tudja eldönteni a kifejezésről, hogy 0-e, és elrontja a Gauss-eliminációt. (Ez sajnos elkerülhetetlen: https://en.wikipedia.org/wiki/Constant_problem)
f, g = sym.symbols('f g', cls=sym.Function)
2*f(x)
f(x).diff(x) + f(x)
Differenciálegyenletek
$f'(x)=f(x)$
sym.dsolve(f(x).diff(x) - f(x), f(x))
sym.dsolve(sym.sin(x) * sym.cos(f(x)) + sym.cos(x) * sym.sin(f(x)) * f(x).diff(x), f(x), hint='separable')
sym.isprime(4332221111)
sym.isprime(314159)
sym.sieve._list
120121 in sym.sieve
sym.sieve._list
sym.ntheory.generate.prime(100)
sym.ntheory.factorint(120)
Minden szám előáll legfeljebb 4 négyzetszám összegeként.
from sympy.solvers.diophantine import diop_general_sum_of_squares
from sympy.abc import a, b, c, d, e
diop_general_sum_of_squares(a**2 + b**2 + c**2 + d**2 - 2345)
[(i,diop_general_sum_of_squares(a**2 + b**2 + c**2 + d**2 - i)) for i in range (20)]
Teljes lista: https://docs.sympy.org/latest/modules/functions/index.html#functions-contents
print(sym.binomial(20,3))
print(sym.factorial(5))
print(sym.gamma(4.5))
print(sym.fibonacci(10))
Létezik-e négy pont a síkon, hogy bármely kettő távolsága páratlan?
Tegyük fel, hogy létezik, legyen az egyik pont az origó a másik három pedig $(A_x,A_y),(B_x,B_y),(C_x,C_y)$. Legyen $N=\begin{pmatrix} A_y & B_x & C_x\\ A_y & B_y & C_y \end{pmatrix} $
és $M=2NN^T=\begin{pmatrix} 2|A|^2 & 2<A,B> & 2<A,C>\\ 2<A,B> & 2|B|^2 & 2<B,C> \\ 2<A,C> & 2<B,C> & 2|C|^2 \\ \end{pmatrix} =\begin{pmatrix} 2|A|^2 & |A|^2+|B|^2-|AB|^2 & |A|^2+|C|^2-|AC|^2\\ |A|^2+|B|^2-|AB|^2 & 2|B|^2 & |B|^2+|C|^2-|BC|^2 \\ |A|^2+|C|^2-|AC|^2 & |B|^2+|C|^2-|BC|^2 & 2|C|^2 \\ \end{pmatrix} $
Világos hogy $det(M)=0$ mivel $rank(M)\le rank(N)\le 2$
a = sym.Symbol('a')
b = sym.Symbol('b')
c = sym.Symbol('c')
d = sym.Symbol('d')
e = sym.Symbol('e')
f = sym.Symbol('f')
ma=2*a+1
mb=2*b+1
mc=2*c+1
md=2*d+1
me=2*e+1
mf=2*f+1
M=sym.Matrix([[2*ma**2, ma**2+mb**2-md**2,ma**2+mc**2-me**2],[ ma**2+mb**2-md**2,2*mb**2,mb**2+mc**2-mf**2],[ ma**2+mc**2-me**2,mb**2+mc**2-mf**2,2*mc**2] ])
M
expr=sym.simplify(sym.expand(M.det()))
expr
expr.as_coefficients_dict()
[a%8 for a in expr.as_coefficients_dict().values()]
Mivel minden együttható osztható 8-al kivéve a konstans tag, a determináns nem lehet osztható 8-al. Tehát nem lehet 0, ellentmondásra jutottunk.