6.python科學(xué)計算與數(shù)據(jù)處理_第1頁
已閱讀1頁,還剩72頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、1,SymPy,—符號運算庫,目錄,從例子開始?xì)W拉恒等式球體體積數(shù)學(xué)表達(dá)式符號數(shù)值運算符和函數(shù)符號運算表達(dá)式變換和化簡方程,2,目錄,微分微分方程積分其他功能,3,,4,SymPy是一個符號數(shù)學(xué)Python庫。它的目標(biāo)是成為一個全功能的計算機代數(shù)系統(tǒng),同時保持代碼的精簡而易于理解和可擴展。SymPy完全由Python寫成,不需要任何外部庫。 可用SymPy進(jìn)行數(shù)學(xué)表達(dá)式的符號推導(dǎo)和演算???/p>

2、使用isympy運行程序,isympy在 IPython的基礎(chǔ)上添加了數(shù)學(xué)表達(dá)式的直觀顯示功能。啟動時還會自動運行下面的程序:,,這段程序首先將Python的除法操作符“/”從整數(shù)除法改為普通除法。然后從SymPy庫載 入所有符號,并且定義了四個通用的數(shù)學(xué)符號x、y、z 、t,三個表示整數(shù)的符號k、m、n,以及三個表示數(shù)學(xué)函數(shù)的符號f、g、h。,5,from __future__ import division from sympy

3、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)#init_printing(),從例子開始,歐拉恒等式 此公式被稱為歐拉恒等式,其中e是自然常數(shù),i

4、是虛數(shù)單位, 是圓周率。此公式被譽為數(shù)學(xué)中最奇妙的公式,它將5個基本數(shù)學(xué)常數(shù)用加法、乘法和冪運算聯(lián)系起來。 從SymPy庫載入的符號中,E表示自然常數(shù),I表示虛數(shù)單位,pi表示圓周率,因此上面 的公式可以直接如下計算:,6,>>>E**(I*pi)+1?0,從例子開始,SymPy除了可以直接計算公式的值之外,還可以幫助做數(shù)學(xué)公式的推導(dǎo)和證明。歐拉恒等式可以將 代入下面的歐拉公式得到:

5、 在SymPy中可以使用expand()將表達(dá)式展開,用它展幵 試試看: 沒有成功,只是換了一種寫法而已。當(dāng)expand()的complex參數(shù)為True時,表達(dá)式將被分為實數(shù)和虛數(shù)兩個部分:,7,>>> expand( E**(I*x))exp(I*x)? ?,從例子開始,這次將表達(dá)式展開了,但是得到的結(jié)果相當(dāng)復(fù)雜。顯然,expand()將x當(dāng)做復(fù)數(shù)了。為了指定x為實

6、數(shù),需要重新定義x: 終于得到了需要的公式??梢杂锰├斩囗検綄ζ溥M(jìn)行展開:,8,>>> expand(exp(I*x), complex=True) I*exp(-im(x))*sin(re(x)) + exp(-im(x))*cos(re(x)) ?,>>> x = Symbol("x", real=True)>>&

7、gt; expand(exp(I*x), complex=True)Isin(x)+cos(x)?,從例子開始,series()對表達(dá)式進(jìn)行泰勒級數(shù)展開??梢钥吹秸归_之后虛數(shù)項和實數(shù)項交替出現(xiàn)。根據(jù)歐拉公式,虛數(shù)項的和應(yīng)該等于sin(x)的泰勒展開,而實數(shù)項的和應(yīng)該等于cos(x)的泰勒展開。,9,>>>tmp = series(exp(I*x), x, 0, 10)>>> print tmp

8、1 + I*x - x**2/2 - I*x**3/6 + x**4/24 + I*x**5/120 - x**6/720 - I*x**7/5040 + x**8/40320 + I*x**9/362880 + O(x**10)>>>tmp,從例子開始,下面獲得tmp的實部: 下面對cos (x)進(jìn)行泰勒展開,可看到其中各項和上面的結(jié)果是一致的。,10,>>&

9、gt; re(tmp)x**8/40320 - x**6/720 + x**4/24 - x**2/2 + re(O(x**10)) + 1,>>> series(cos(x), x, 0, 10)1 - x**2/2 + x**4/24 - x**6/720 + x**8/40320 + O(x**10),從例子開始,11,下面獲得tmp的虛部: 下面對sin (x)進(jìn)行泰勒展開,其中各項也

10、和上面的結(jié)果一致。 由于 展開式的實部和虛部分別等于cos(x)和sin(x),因此驗證了歐拉公式的正確性。,>>> im(tmp)x**9/362880 - x**7/5040 + x**5/120 - x**3/6 + x + im(O(x**10)),>>>series(sin(x), x, 0, 10)x - x**3/6 + x**5/120

11、 - x**7/5040 + x**9/362880 + O(x**10),從例子開始,球體體積 Scipy介紹了如何使用數(shù)值定積分計算球體的體積,SymPy中的integrate()則可以進(jìn)行符號積分。用integrate()進(jìn)行不定積分運算:  如果指定變量x的取值范圍,integrate()就能進(jìn)行定積分運算:,12,>>> integrate(x*sin(x

12、), x) -x*cos(x) + sin(x),>>> integrate(x*sin(x), (x, 0,2*pi))- 2*pi,從例子開始,為了計算球體體積,首先看看如何計算圓的面積,假設(shè)圓的半徑為r,則圓上任意一點的Y坐標(biāo)函數(shù)為: 因此可以直接對函數(shù)y(x)在-r到r區(qū)間上進(jìn)行定積分得到半圓面積。,13,>>> x, y, r =symbols('x,y,r&

13、#39;)>>> f=2 * integrate(sqrt(r*r-x**2), (x, -r, r))>>> print f2*Integral(sqrt(r**2 - x**2), (x, -r, r)),從例子開始,首先需要定義運算中所需的符號,這里用symbols()一次創(chuàng)建多個符號。Integrate()沒有計算出積分結(jié)果,而是直接返冋了輸入的算式。這是因為SymPy不知道r是大于0的

14、,重新 定義r,就可以得到正確答案了: 接下來對此面積公式進(jìn)行定積分,就可以得到球體的體積,但是隨著X軸坐標(biāo)的變化,對應(yīng)切面的半徑也會發(fā)生變化。,14,>>> r = symbols( 'r', positive=True)>>> circle_area = 2 * integrate(sqrt(r**2-x**2), (x, -r, r))>>

15、;> print circle_areapi*r**2,從例子開始,假設(shè)X軸的坐標(biāo)為x,球體的半徑為r,那么x處球的切面半徑可以使用前面的公式y(tǒng)(x)計算出。因此需要對圓的面積公式circle_area中的變量r進(jìn)行替代: 然后對circle_area中的變量x在區(qū)間-r到r上進(jìn)行定積分,就可以得到球體的體積公式:,15,>>> circle_area = circ

16、le_area.subs(r, sqrt(r**2-x**2))>>> print circle_areapi*(r**2 - x**2),>>>print integrate(circle_area, (x, -r, r))4*pi*r**3/3,從例子開始,16,用subs進(jìn)行算式替換: subs()可以將算式中的符號進(jìn)行替換,它有3種調(diào)用方式:expression.

17、subs(x, y):將算式中的 x 替換成 y.expression.subs({x:y,u:v}):使用字典進(jìn)行多次替換.expression.subs([(x,y),(u,v)]):使用列表進(jìn)行多次替換. 請注意多次替換是順序執(zhí)行的,因此: expression.subs([(x,y),(y,x)]) 并不能對符號x和y進(jìn)行交換。,數(shù)學(xué)表達(dá)式,符號 創(chuàng)建一個符號使用sym

18、bols(),此函數(shù)會返回一個Symbol對象,用于表示符號變量,其有name屬性,這是符號名,如: 其中左邊的x是一個符號對象,而右邊括號中用引號包著的x是符號對象的name屬性,兩個x不要求一樣,但是為了易于理解,通常將符號對象和name屬性顯示成一樣,另外name屬性是引號包起來的。如要同時配置多個符號對象,symbols()中多個name屬性可以以,17,>>> x0=symbo

19、ls('x0‘),數(shù)學(xué)表達(dá)式,空格或者逗號分隔,然后用引號包住,如下: 一次配置三個符號,由于符號對象名和name屬性名經(jīng)常一致,所以可以使用var()函數(shù),如: 這語句和上個語句功能一致,在當(dāng)前環(huán)境中創(chuàng)建了4個同名的Symbol對象(為了防止誤會,使用symbols其實更好)。,18,>>> var("x0,y0,x1,y1")(x0, y

20、0, x1, y1),>>> x0,y0,x1,y1=symbols('x0,y0,x1,y1'),數(shù)學(xué)表達(dá)式,上面的語句創(chuàng)建了名為x0、y0、x1、y1的4個Symbol對象,同時還在當(dāng)前的環(huán)境中創(chuàng)建 了 4個同名的變量來分別表示這4個Symbol對象。因為符號對象在轉(zhuǎn)換為字符串時直接使用它的name 屬性,因此在交互式環(huán)境中看到變量,x0的值就是x0,但是査看變量x0的類型時就可以發(fā)現(xiàn),它實際上是一

21、個Symbol對象。,19,>>> x0x0>>> type(x0)sympy.core.symbol.Symbol>>> x0.name'x0'>>> type(x0.name)str,數(shù)學(xué)表達(dá)式,變量名和符號名當(dāng)然也可以是不一樣的,例如: 數(shù)學(xué)公式中的符號一般都有特定的假設(shè),例如m、n通常是整數(shù),而z經(jīng)常表示復(fù)

22、數(shù)。在用var()、symbols()或Symbol()創(chuàng)建Symbol對象時,可以通過關(guān)鍵字參數(shù)指定所創(chuàng)建符號的假 設(shè)條件,這些假設(shè)條件會影響到它們所參與的計算。,20,>>> a, b = symbols ("alpha, beta")>>> a, b (alpha, beta),數(shù)學(xué)表達(dá)式,例如,下面創(chuàng)建了兩個整數(shù)符號m和n, 以及一個正數(shù)符號x:

23、 每個符號都有許多is_*屬性,用以判斷符號的各種假設(shè)條件。在IPython中,使用自動完 成功能可以快速査看這些假設(shè)的名稱。注意下劃線后為大寫字母的屬性,用來判斷對象的類型; 而全小寫字母的屬性,則用來判斷符號的假設(shè)條件。,21,>>> m, n = symbols("m,n", integer=True)>>> x = Symbol("x", positi

24、ve=True),數(shù)學(xué)表達(dá)式,,22,>>> x.is_ #按了tab鍵自動完成 >>> x.is_Symbol # x 是一個符號 True>>> x.is_positive # x 是一個正數(shù) True>>> x.is_imaginary #因為x可以比較大小,所以它不是虛數(shù) False>>> x.is_comple

25、x # x是一個復(fù)數(shù),因為復(fù)數(shù)包括實數(shù),而實數(shù)包括正數(shù) True,數(shù)學(xué)表達(dá)式,23,使用assumptions0 屬性可以快速査看所有的假設(shè)條件,其中commutative為True表示此符號滿足交換律,其余的假設(shè)條件根據(jù)英文名很容易知道它們的含義。 在SymPy中,所有的對象都從Basic類繼承,實際上這些is_*屬性和assumptions0屬性都是在Basic類中定義的:,>>> x.a

26、ssumptions0,>>> Symbol.mro(),數(shù)學(xué)表達(dá)式,數(shù)值 為了實現(xiàn)符號運算,在SymPy內(nèi)部有一整套數(shù)值運算系統(tǒng)。因此SymPy的數(shù)值和Python 的整數(shù)、浮點數(shù)是完全不同的對象。為了使用方便,SymPy會盡量自動將Python的數(shù)值類型轉(zhuǎn)換為SymPy的數(shù)值類型。此外,SymPy提供了一個S對象用于進(jìn)行這種轉(zhuǎn)換。在下面的例子中,當(dāng)有SymPy的數(shù)值參與計算時,結(jié)果將是SymPy

27、的數(shù)值對象。,24,數(shù)學(xué)表達(dá)式,“5/6”在SymPy中使用Rational對象表示,它由兩個整數(shù)的商表示,數(shù)學(xué)上稱之為有理數(shù)。也可以直接通過Rational創(chuàng)建:,25,>>> 1/2 + 1/3 #結(jié)果為浮點數(shù) 0.8333333333333333 >>> S(1)/2 + 1/S(3) #結(jié)果為SymPy的數(shù)值對象 5/6,>>> Rational(5, 10) #有理數(shù)

28、會自動進(jìn)行約分處理 1/2,數(shù)學(xué)表達(dá)式,26,運算符和函數(shù) SymPy重新定義了所有的數(shù)學(xué)運算符和數(shù)學(xué)函數(shù)。例如Add類表示加法,Mul類表示乘法,而Pow類表示指數(shù)運算,sin類表示正弦函數(shù)。和Symbol對象一樣,這些運算符和函數(shù)都從Basic類繼承,可在IPython中查看它們的繼承列表(例如:Add.mro())??梢允褂眠@些類創(chuàng)建復(fù)雜的表達(dá)式:,>>> var("x,y,z,n

29、")>>> Add(x,y,z) x + y + z >>> Add(Mul(x,y,z), Pow(x,y), sin(z))x*y*z + x**y + sin(z),數(shù)學(xué)表達(dá)式,由于在Basic類中重新定義了__add__()等用于創(chuàng)建表達(dá)式的方法,因此可以使用和Python表達(dá)式相同的方式創(chuàng)建SymPy的表達(dá)式: 在Basic類中定義了兩個很重要的屬性

30、:func和args。func屬性得到對象的類,而args得到其參數(shù)。使用這兩個屬性可以觀察SymPy所創(chuàng)建的表達(dá)式。 SymPy沒有減法運算類,下面看看減法運算所得到的表達(dá)式:,27,>>> x*y*z + sin(z) + x**y x*y*z + x**y + sin(z),數(shù)學(xué)表達(dá)式,通過上面的例子可以看出,表達(dá)式“x-y”在SymPy中實際上是用“Add(x, Mul(-1, y))”表示的。同樣,SymP

31、y中沒有除法類,可使用和上面相同的方法觀察“x/y”在SymPy中是如何表示的。,28,>>> t = x - y>>> t.func # 減法運算用加法類Add表示 sympy.core.add.Add >>> t.args # 兩個加數(shù)一個是x,一個是-y (x, -y) >>> t.args[1].func # -y是用Mul表示的 sympy.c

32、ore.mul.Mul >>> t.args[1].args (-1, y),數(shù)學(xué)表達(dá)式,SymPy的表達(dá)式實際上是一個由Basic類的各種對象進(jìn)行多層嵌套所得到的樹狀結(jié)構(gòu)。下面的函數(shù)使用遞歸顯示這種樹狀結(jié)構(gòu): 由于fsolve函數(shù)在調(diào)用函數(shù)f時,傳遞的參數(shù)為數(shù)組,因此如果直接使用數(shù)組中的元素計算的話,計算速度將會有所降低,因此這里先用float函數(shù)將數(shù)組中的元素轉(zhuǎn)換為Python中的標(biāo)準(zhǔn)浮

33、點數(shù),然后調(diào)用標(biāo)準(zhǔn)math庫中的函數(shù)進(jìn)行運算。,29,def print_expression(e, level=0): spaces = " "*level if isinstance(e, (Symbol, Number)): print spaces + str(e) return if len(e.args) > 0: pri

34、nt spaces + e.func.__name__ for arg in e.args: print_expression(arg, level+1) else: print spaces + e.func.__name__,數(shù)學(xué)表達(dá)式,例如 在SymPy中使用下面的樹表示: 由于其中的各個對象的args屬性類型是

35、元組,因此表達(dá)式一旦創(chuàng)建就不能再改變。使用不可變的結(jié)構(gòu)表示表達(dá)式有很多優(yōu)點,例如可以用表達(dá)式作為字典的鍵。,30,>>>print_expression(sqrt(x**2+y**2))Pow Add Pow x 2 Pow y 2 1/2,數(shù)學(xué)表達(dá)式,除了使用SymPy中

36、預(yù)先定義好的具有特殊運算含義的數(shù)學(xué)函數(shù)之外,還可以使用Function()創(chuàng)建自定義的數(shù)學(xué)函數(shù): 請注意Function雖然是一個類,但是上面的語句所得到的f并不是Function類的實例。和預(yù)定義的數(shù)學(xué)函數(shù)一樣,f是一個類,它從Function類繼承:,31,>>> f = Function("f"),>>> f.__base__ sympy.core.f

37、unction.AppliedUndef >>> isinstance(f, Function) False,數(shù)學(xué)表達(dá)式,當(dāng)我使用f創(chuàng)建一個表達(dá)式時,就相當(dāng)于創(chuàng)建它的一個實例: f的實例t可以參與表達(dá)式運算:,32,>>> t = f(x,y)>>>isinstance(t, Function)True>>>

38、; type(t) f >>> t.func # (其中func和args是Basic類的兩個非常重要的屬性,分別表示對象的類和對象的參數(shù))f >>> t.args (x, y),>>> t+t*tf(x, y)**2 + f(x, y),符號運算,表達(dá)式變換和化簡 simplify()可以對數(shù)學(xué)表達(dá)式進(jìn)行化簡,例如:

39、 simplify()調(diào)用SymPy內(nèi)部的多種表達(dá)式變換函數(shù)對表達(dá)式進(jìn)行化簡運算。但是數(shù)學(xué)表達(dá)式的化簡是一件非常復(fù)雜的工作,并且對于同一個表達(dá)式,根據(jù)其使用目的可以有多種化簡方案。,33,>>> simplify((x+2)**2 - (x+1)**2) 2*x + 3,符號運算,34,radsimp()對表達(dá)式的分母進(jìn)行有理化,它所得到的表達(dá)式的分母部分將不含無理數(shù)。例如: 它也可以

40、對帶符號的表達(dá)式進(jìn)行處理:,>>> radsimp(1/(sqrt(5)+2*sqrt(2)))(-sqrt(5) + 2*sqrt(2))/3,>>>radsimp(1/(y*sqrt(x)+x*sqrt(y)))(-sqrt(x)*y + x*sqrt(y))/(x*y*(x - y)),符號運算,ratsimp()對表達(dá)式中的分母進(jìn)行通分運算,即將表達(dá)式轉(zhuǎn)換為分子除分母的形式:

41、 fraction()返回一個包含表達(dá)式的分子和分母的元組,用它可以獲得ratsimp()通分之后的分 子或分母: 注意fraction()不會自動對表達(dá)式進(jìn)行通分運算,因此:,35,>>> ratsimp(x/(x+y)+y/(x-y))2*y**2/(x**2 - y**2) + 1,>>> fraction(ratsimp(1/x+1/y))(x + y,

42、 x*y),>>> fraction(1/x+1/y)(1/y + 1/x, 1),符號運算,cancel()對分式表達(dá)式的分子分母進(jìn)行約分運算,可以對純符號的分式表達(dá)式以及自定義函數(shù)表達(dá)式進(jìn)行約分,但是不能對內(nèi)部函數(shù)的表達(dá)式進(jìn)行約分。,36,>>>cancel((x**2-1)/(1+x))x-1>>> cancel(sin((x**2-1)/(1+x))) # cancel

43、不能對函數(shù)內(nèi)部的表達(dá)式進(jìn)行約分 sin(x**2/(x + 1) - 1/(x + 1))>>> cancel((f(x)**2-1)/(f(x)+1)) #  #能對自定義函數(shù)表達(dá)式進(jìn)行約分f(x) - 1,符號運算,trigsimp()對表達(dá)式中的三角函數(shù)進(jìn)行化簡。它有兩個可選參數(shù)--deep和recursive,默認(rèn) 值都為False。當(dāng)deep參數(shù)為True時,將對表達(dá)式中的所有子表達(dá)式

44、進(jìn)行簡化運算;當(dāng)recursive 參數(shù)為True時,將遞歸使用trigsimp()進(jìn)行最大限度的化簡:,37,>>> trigsimp(sin(x)**2+2*sin(x)*cos(x)+cos(x)**2)sin(2*x) + 1 >>> trigsimp(f(sin(x)**2+2*sin(x)*cos(x)+cos(x)**2)) #也能對自定義函數(shù)中的三角函數(shù)化簡,至今不知道deep和

45、recursive是干嘛的 f(sin(2*x) + 1),符號運算,38,expand_trig()可以對三角函數(shù)的表達(dá)式進(jìn)行展開。它實際上是對expand()的封裝,通過將 expand()的trig參數(shù)設(shè)置為True,實現(xiàn)三角函數(shù)的展開計算。輸入“expand_trig??” 來査看它調(diào)用expand()時的參數(shù)。 expand()通用的展開運算,根據(jù)用戶設(shè)置的標(biāo)志參數(shù)對表達(dá)式進(jìn)行展幵。默認(rèn)情況下,以下的標(biāo)

46、志參數(shù)為 True。   mul:展開乘法,>>> expand_trig(sin(2*x+y))(2*cos(x)**2 - 1)*sin(y) + 2*sin(x)*cos(x)*cos(y),符號運算,log:展開對數(shù)函數(shù)參數(shù)中的乘積和冪運算 multinomial:展開加法式的整數(shù)次冪 power_base:展開冪函數(shù)的底數(shù)乘積,39,>>

47、;> x,y=symbols("x,y",positive=True) >>>expand(log(x*y**2))log(x) + 2*log(y),>>> expand((x+y)**3)x**3 + 3*x**2*y + 3*x*y**2 + y**3,>>>expand(x**(y+z)) x**y*x**z,符號運算,可以將默認(rèn)為True的

48、標(biāo)志參數(shù)設(shè)置為False,強制不展開對應(yīng)的表達(dá)式。在下面的例子中, 將mul設(shè)置為False,因此不對乘法進(jìn)行展開: expand()的以下標(biāo)志參數(shù)默認(rèn)為False。 complex:展開復(fù)數(shù)的實部和虛部,默認(rèn)不展開復(fù)數(shù)的實部和虛部:,40,>>> x,y,z=symbols("x,y,z", positive=True)>>> exp

49、and(x*log(y*z), mul=False) x*(log(y) + log(z)),>>> x,y=symbols("x,y",complex=True)>>> expand(x*y, complex=True)re(x)*re(y) + I*re(x)*im(y) + I*re(y)*im(x) - im(x)*im(y),符號運算,func:對一些特殊函數(shù)進(jìn)行展

50、開 trig:展開三角函數(shù) expand_log()、expand mul()、expand_complex()、expand_trig()、expand_func()等函數(shù)則通過將相應(yīng)的標(biāo)志參數(shù)設(shè)置為True,對expand()進(jìn)行封裝。,41,>>> expand (gamma (1+x),func=True)x*gamma(x),>>> expand(sin(x+

51、y), trig=True) sin(x)*cos(y) + sin(y)*cos(x),符號運算,42,factor()可以對多項式表達(dá)式進(jìn)行因式分解: collect()收集表達(dá)式中指定符號的有理指數(shù)次冪的系數(shù)。例如,希望獲得如下表達(dá)式中x的各次冪的系數(shù):,>>> factor(15*x**2+2*y-3*x-10*x*y) (3*x - 2*y)*(5*x - 1) >>

52、;> factor(expand((x+y)**20))(x + y)**20,>>> a,b=symbols('a,b')>>> eq = (1+a*x)**3 + (1+b*x)**2,符號運算,首先需要對表達(dá)式eq進(jìn)行展開,得到的表達(dá)式eq2是一系列乘式的和: 然后調(diào)用collect(),對表達(dá)式eq2中x的冪的系數(shù)進(jìn)行收集:,43,>&

53、gt;>eq2 = expand (eq) >>>eq2a**3*x**3 + 3*a**2*x**2 + 3*a*x + b**2*x**2 + 2*b*x + 2,>>> collect(eq2,x)a**3*x**3 + x**2*(3*a**2 + b**2) + x*(3*a + 2*b) + 2,符號運算,默認(rèn)情況下,collect()返回的是一個整理之后的表達(dá)式,如果我們希望

54、得到x的各次冪的系數(shù),可以設(shè)置evaluate參數(shù)為False,讓它返回一個以x的冪為鍵、值為系數(shù)的字典:,44,>>> p = collect(eq2, x, evaluate=False)>>> p[S(1)] #常數(shù)項,注意需要用SymPy中的數(shù)值1,或者使用p[x**0]2>>> p[x**2] # x的2次項系數(shù) b**2 + 3*a**2,符號運算,45,coll

55、ect()也可以收集表達(dá)式的各次冪的系數(shù),例如下面的程序收集表達(dá)式“sin(2*x)”的系數(shù):,>>> collect(a*sin(2*x) + b*sin(2*x), sin(2*x)) (a + b)*sin(2*x),符號運算,46,方程 在SymPy中,表達(dá)式可以直接表示值為0的方程。也可以使用Eq()創(chuàng)建方程。solve()可以對方程進(jìn)行符號求解,它的第一個參數(shù)是表示方程的表達(dá)式,其后的參

56、數(shù)是表示方程中未知變量的符號。下面的例子使用solve()對一元二次方程進(jìn)行求解:,>>> a,b,c = symbols("a,b,c") >>> solve(a*x**2+b*x+c, x)[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)],符號運算,使用Eq創(chuàng)建一個方程對象并求解:,47

57、,>>> my_eq=Eq(a*x**2+b*x+c,0)>>> solve(my_eq,x)[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)],符號運算,由于方程的解可能有多組,因此solve()返回一個列表保存所有的解??梢詡鬟f包含多個表達(dá)式的元組或列表,讓solve()對方程組進(jìn)行求解,得到的解是兩層嵌套的

58、列表,其中每個元組表示方程組的一組解:,48,#對方程組求解(用元組將幾個方程組成一個組)>>> solve ((x**2+x*y+1, y ** 2+x*y+2 ), x, y )[(-sqrt(3)*I/3, -2*sqrt(3)*I/3), (sqrt(3)*I/3, 2*sqrt(3)*I/3)] #有兩組解,符號運算,微分 Derivative是表示導(dǎo)函數(shù)的類,它的第一個參數(shù)是需要進(jìn)

59、行求導(dǎo)的數(shù)學(xué)函數(shù),第二個參數(shù) 是求導(dǎo)的自變量.注意Derivative所得到的是一個導(dǎo)函數(shù),它并不會進(jìn)行求導(dǎo)運算: 如果希望它進(jìn)行實際的運算,計算出導(dǎo)函數(shù),可以調(diào)用其doit()方法:,49,>>> t = Derivative(sin(x),x)  #創(chuàng)建了一個導(dǎo)函數(shù)對象>>> tDerivative(sin(x), x),>>> t.doit

60、()cos(x),符號運算,50,也可以直接使用diff()函數(shù)或表達(dá)式的diff()方法來計算導(dǎo)函數(shù): 使用Derivative對象可以表示自定義的數(shù)學(xué)函數(shù)的導(dǎo)函數(shù),例如:,>>> diff(sin(2*x), x)2*cos(2*x)>>> sin(2*x).diff(x)2*cos(2*x)>>> diff(sin(2*

61、x), x, 2)-4*sin(2*x)>>> diff(sin(2*x), x, 3) -8*cos(2*x),>>> Derivative(f(x), x)Derivative(f(x), x),符號運算,由于SymPy不知道如何對自定義的數(shù)學(xué)函數(shù)進(jìn)行求導(dǎo),因此它的diff()方法會返回和上面相同的結(jié)果: 添加更多的符號參數(shù)可以表示高階導(dǎo)函數(shù),例如:,51,>

62、>> f(x).diff(x) #方法中的x表示對x符號進(jìn)行求導(dǎo)Derivative(f(x), x),>>> Derivative(f(x), x, 3) #表示f(x)對x求三階導(dǎo)數(shù)(或者偏導(dǎo)) Derivative(f(x),x,x,x) #也可以寫作,符號運算,也可以表示多個變量的導(dǎo)函數(shù),例如: diff()求解的格式和Derivative聲明的格式類似,例如下面的語句計算si

63、n(xy)對x兩次求導(dǎo)、對y三次求導(dǎo)的結(jié)果:,52,>>> Derivative(f(x,y), x,2,y,3) #對x求二階導(dǎo)且對y求三階導(dǎo)數(shù)(5階數(shù))Derivative(f(x, y), x, x, y, y, y),>>> diff(sin(x*y), x,2,y,3)x*(x**2*y**2*cos(x*y) + 6*x*y*sin(x*y) - 6*cos(x*y)),符號運算,微分

64、方程 dsolve()可以對微分方程進(jìn)行符號求解。它的第一個參數(shù)是一個帶未知函數(shù)的表達(dá)式,第 二個參數(shù)是需要進(jìn)行求解的未知函數(shù)。例如下面的程序?qū)ξ⒎址匠?進(jìn)行求解。 得到的結(jié)果是一個自然指數(shù)函數(shù),它有一個待定系數(shù)c1。,53,>>>f=Function("f")>>> dsolve(Derivative(f(x),x) -

65、f(x), f(x)) f(x) == C1*exp(x),符號運算,用dsolve()解微分方程時可以傳遞一個hint參數(shù),指定微分方程的解法。該參數(shù)的默認(rèn)值為“default”,表示由SymPy自動挑選解法??梢詫int參數(shù)設(shè)置為“best”,讓dsolve()嘗試所有己知解法,并返回最簡單的解,例如下面對微分方程 : 進(jìn)行求解。得到的結(jié)果是一個一般方程,它描述了f

66、(x)和自變量之間的關(guān)系。一般把這種函數(shù)稱為隱函數(shù):,54,符號運算,55,如果設(shè)置hint參數(shù)為“best”,就能得到更簡單的顯函數(shù)表達(dá)式:,>>> x = symbols("x", real=True) # 定義符號x 為實數(shù) >>>eq1 = dsolve(f(x).diff(x) + f(x)**2 + f(x), f(x))>>>eq1f(x) =

67、= -C1/(C1 - exp(x)),>>> eq2 = dsolve(f(x).diff(x) + f(x)**2 + f(x), f(x), hint="best")>>> eq2f(x) == -C1/(C1 - exp(x)),符號運算,積分 integrate()可以計算定積分和不定積分:integrate(f,x):計算不定積分integrate

68、(f,(x,a,b)):計算定積分 如果要對多個變量計算多重積分,只需要將被積分的變量依次列出即可:Integrate(f,x,y):計算雙重不定積分Integrate(f,(x,a,b),(y,c,d)):計算雙重定積分,56,符號運算,和Derivative對象表示微分表達(dá)式類似,Integral對象表示積分表達(dá)式,它的參數(shù)和integrate() 類似,例如: 調(diào)用積分對象的doit()方法可以

69、對其進(jìn)行求值計算:,57,>>> e = Integral(x*sin(x), x)>>> eIntegral(x*sin(x), x),>>> e.doit()-x*cos(x) + sin(x)),符號運算,有些積分表達(dá)式無法進(jìn)行符號化簡,這時可以調(diào)用其evalf()方法或用求值函數(shù)N()對其進(jìn) 行數(shù)值運算: 由于無法進(jìn)行符號定積分,可用evalf()和N(

70、)對其 進(jìn)行數(shù)值運算:,58,>>> e2 = Integral(sin(x)/x, (x, 0, 1)) >>> e2.doit()Si(1) #Si,>>> e2.evalf()0.946083070367183 >>> N(e2)0.946083070367183 >>> N(e2, 100) #可以指定精度0.946083

71、070367183014941353313823…,符號運算,SymPy的數(shù)值計算功能還不夠強大,不能對應(yīng)如下這種情況的無限積分: 將積分上限修改為10000也沒能計算出近似結(jié)果,上限為1000時得到了 π/2的近似值, 不過還遠(yuǎn)遠(yuǎn)不夠精確:,59,>>> N(Integral(sin(x)/x, (x, 0, oo))) # oo表示正無窮-0.e+0,>>> N

72、(Integral(sin(x)/x, (x, 0, 10000))) 0.e+0>>>N(Integral(sin(x)/x, (x, 0, 1000))) 1.57023312196877,符號運算,as_sum()方法可以將定積分轉(zhuǎn)換為近似求和公式,它將積分區(qū)域分割成n個小矩形的面積之和:,60,>>> e=Integral(sin(x)/x,(x,0,1))>>>e.

73、as_sum(5)2*sin(9/10)/9 + 2*sin(7/10)/7 + 2*sin(1/2)/5 + 2*sin(3/10)/3 + 2*sin(1/10)>>> N(e.as_sum(5)) 0.946585362780408,其他功能,用SymPy做計算器 SymPy有三種內(nèi)建的數(shù)值類型:浮點數(shù)、有理數(shù)和整數(shù)。 有理數(shù)類用一對整數(shù)表示一個有理數(shù):分子和分母,所

74、以Rational(1,2)代表1/2, Rational(5,2) 代表5/2等等。 有些特殊的常數(shù),像e和pi,它們被視為符號(1+pi將不被數(shù)值求解,它將保持為1+pi),并且可以有任意精度:,61,>>> pi**2pi**2,其他功能,evalf將表達(dá)式求解為浮點數(shù)。 這還有一個類表示數(shù)學(xué)上的無限,叫作oo:,62,>>> pi.evalf() 3.141

75、59265358979 >>> (pi+exp(1)).evalf(50)5.8598744820488384738229308546321653819544164930751,>>> oo > 99999True>>> oo + 10000oo,其他功能,極限 極限在sympy中使用很簡單,它們的語法是limit(function, variabl

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論