%matplotlib inline
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
開始寫程式, 不久之後我們就會發現, 電腦不太會算我們平常的數學。
1/2 + 1/3
0.8333333333333333
交給 sympy
算是這樣。
a = sp.Rational(1, 2) # 1/2
b = sp.Rational(1, 3) # 1/3
a + b
sp.sympify(1)/2 + sp.sympify(1)/3
單獨讀入 sympify
的簡化版指令 S
。
from sympy import S
S(1)/2 + S(1)/3
sympy
真的像數學課的數學¶sp.cos(sp.pi/4)
π = sp.pi
sp.cos(π/4)
π.n(20)
egg = str(π.n(100000))
'1215' in egg
True
print('M', ord('M'))
print('a', ord('a'))
print('c', ord('c'))
M 77 a 97 c 99
'779799' in egg
False
耶, 跟我們廣告的不一樣? 不緊張, 要更多位的 π 試試看!
egg = str(π.n(300000))
'779799' in egg
True
各種運算其實都可以用 n
的技巧。
k = sp.sqrt(2)
k.n(100)
我們可以用 sympy
表示 $\sin(x)$ 等等函數, 而 $x$ 真的是個數學上的變數!
sp.var('x')
expr = x**2
expr
expr.subs(x,2)
x = sp.Symbol('x')
x = sp.symbols('x')
和上次的有何不同呢? 原來是可以同時令兩個變數!
x, y = sp.symbols('x,y')
x
y
a, b = sp.symbols(r'\alpha,\beta')
a
sp.expand((a+b)**3)
from sympy.abc import x, y, z
z**2
sp.expand((x+y)**2)
expr = (x+y+z)**2
expr.subs({x:2,y:3,z:1})
甚至可以做很酷的微積分!
sp.diff(sp.cos(x))
sp.integrate(1/x)
np.arctan(1)*4
3.141592653589793
sp.atan(1)*4
但是誰知 $\arctan$ 怎麼算呢? 是不是有種想法, 如果是多項式就好了...
expr = sp.series(sp.atan(x),x,n=10)
expr
expr = expr.removeO()
(expr.subs(x,1)*4).evalf()
expr = sp.series(sp.atan(x),x,n=200)
expr = expr.removeO()
(expr.subs(x,1)*4).evalf()
方法可行, 但收斂很慢!
π = np.pi
θ = np.linspace(0, π/2, 200)
x = np.cos(θ)
y = np.sin(θ)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(0,1)
plt.ylim(0,1)
plt.plot(x,y,c='k',lw=3)
[<matplotlib.lines.Line2D at 0x7f8d30532090>]
n = 200
x = np.random.rand(n)
y = np.random.rand(n)
egg = x**2 + y**2 <= 1
k = len(x[egg])
k/n * 4
2.98
ham = np.invert(egg)
π = np.pi
θ = np.linspace(0, π/2, 200)
xc = np.cos(θ)
yc = np.sin(θ)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(0,1)
plt.ylim(0,1)
plt.plot(xc,yc,c='k',lw=3)
plt.scatter(x[egg], y[egg], c='r')
plt.scatter(x[ham], y[ham], c='b', alpha=0.6)
<matplotlib.collections.PathCollection at 0x7f8d2f7a1910>