本系列是使用Ubuntu 64位操作系统上,anaconda环境下,采用jupyter notebook 实现python3科学计算的文章,应用于青岛科技大学信息学院科学计算与数据挖掘等多个课程中python教学。需要安装的模块,numpy ,matplotlib,scipy,sympy,pandas等科学计算常用模块。由于匆忙成稿,个人能力所限,显得粗糙,并且有几个地方是错误的。主要参考了Numerical Python 2nd Edition

科学计算包括数值计算和符号计算两种计算 。计算机能够对数值进行一系列运算是人所共知的事,但计算机也能够对含未知量的式子直接进行推导、演算则并不是人人皆知。数值计算和符号计算本来应该是并存的两种计算,是计算的平行的两个部分,决不能厚此薄彼,因此这两种计算都是一样重要的。利用计算机对一个函数进行求导、积分,这早己成为事实。

import sympy
sympy.init_printing()#调用及时显示系统。但对于jupyter似乎不需要。
x = sympy.Symbol("x")#创建符号

符号名是一个字符串,可以选择包含类似Latex标记

使符号名在ipython的显示系统中显示良好。

符号对象的名称在创建时设置。符号可以采用不同方式创建,

例如,使用sympy.symbol、sympy.symbols和sympy。

通常需要将sympy符号与python变量关联起来

同一个名称或与符号名称紧密对应的名称。例如,

要创建一个名为x的符号,并将其绑定到同名的python变量,

我们可以使用symbol类的构造函数并传递包含该符号的字符串

名称作为第一个参数

y = sympy.Symbol("y", real=True)
y.is_real
True
x.is_real is None
True

另一方面,如果我们要使用is real来查询先前定义的符号

x,它没有显式地指定为real,因此可以同时表示real和

非实变量,结果是没有.但如果被显式定义,则为false

y.is_real is None
False
sympy.Symbol("z", imaginary=True).is_real
False
x = sympy.Symbol("x")
y = sympy.Symbol("y", positive=True)
sympy.sqrt(x ** 2)

Python科学计算 第3版pdf python科学计算第三版_字符串

sympy.sqrt(y ** 2)

Python科学计算 第3版pdf python科学计算第三版_字符串_02

#以上运算可以清晰的发现定义的清晰度,可以影响运算结果。
n1 = sympy.Symbol("n")
n2 = sympy.Symbol("n", integer=True)
n3 = sympy.Symbol("n", odd=True)
import numpy as np
sympy.cos(n1 * np.pi)

Python科学计算 第3版pdf python科学计算第三版_科学计算_03

sympy.cos(n2 * np.pi)

Python科学计算 第3版pdf python科学计算第三版_科学计算_03

sympy.cos(n3 *np.pi)

Python科学计算 第3版pdf python科学计算第三版_科学计算_03

from sympy import I, pi, oo #然而在sympy中不建议采用sympy之外的常数
sympy.cos(n1 * pi)

Python科学计算 第3版pdf python科学计算第三版_字符串_06

sympy.cos(n2 * pi)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_07

sympy.cos(n3 *pi)

Python科学计算 第3版pdf python科学计算第三版_字符串_08

可以看到采用sympy内部的常数,虚数,π,无穷大,更利于公式简化推导。

oo

Python科学计算 第3版pdf python科学计算第三版_科学计算_09

pi

Python科学计算 第3版pdf python科学计算第三版_字符串_10

sympy.E

Python科学计算 第3版pdf python科学计算第三版_科学计算_11

sympy.EulerGamma

Python科学计算 第3版pdf python科学计算第三版_字符串_12

sympy.I

Python科学计算 第3版pdf python科学计算第三版_字符串_13

sympy.oo

Python科学计算 第3版pdf python科学计算第三版_科学计算_09

创建符号时,符号的属性可以用下列属性标定:

real ,imaginary 属性判定 is_real, is_imaginary

positive, negative 属性判定 is_positive, is_negative

integer 属性判定 is_integer

odd, even is_odd, 属性判定 is_even

prime 属性判定 is_prime

finite, infinite 属性判定 is_finite, is_infinite

a, b, c = sympy.symbols("a, b, c", negative=True)
d, e, f = sympy.symbols("d, e, f", positive=True)
i = sympy.Integer(19)
type(i)
sympy.core.numbers.Integer
i.is_Integer, i.is_real, i.is_odd
(True, True, True)
"%.25f" % 0.3  # create a string representation with 25 decimals,把0.3表示成有25个小数的浮点数。
'0.2999999999999999888977698'
sympy.Float(0.3, 25)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_15

sympy.Float('0.3', 25)#请同学们注意的是,这个才是精确的表示浮点数0.3

Python科学计算 第3版pdf python科学计算第三版_科学计算_16

但是,请注意,要正确地将0.3表示为浮点对象,必须

从字符串“0.3”而不是python float 0.3初始化它,后者已经包含

浮点错误。

r1 = sympy.Rational(2, 3)#分式的表示方式
r1

Python科学计算 第3版pdf python科学计算第三版_字符串_17

5/6

Python科学计算 第3版pdf python科学计算第三版_科学计算_18

x/y

Python科学计算 第3版pdf python科学计算第三版_科学计算_19

定义符号函数
x,y,z = sympy.symbols("x,y,z")
f = sympy.Function("f")
type(f)
sympy.core.function.UndefinedFunction
f(x)

Python科学计算 第3版pdf python科学计算第三版_python_20

g = sympy.Function("g")(x,y,z)
g

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_21

g.free_symbols

Python科学计算 第3版pdf python科学计算第三版_字符串_22

g

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_21

定义函数符号,下面可以定义函数的表达式

h = sympy.Lambda(x,x**2+2*x)
h

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_24

#lambda函数定义一类函数只有当你的情况完全满足这四个标准时, 我才会说你可以使用 lambda 表达式:
所谓的匿名函数

你所要做的操作是不重要的:函数不值得一个名称

使用 lambda 表达式比你所能想到的函数名称让代码更容易理解

你很确定还没有一个函数能满足你的需求

你团队的每个人都了解 lambda 表达式, 并且都同意使用它们

如果上述四条中的任何一条都不符合你的情况, 我建议用 def 来写一个新的函数, (如果可能)接受一个在 Python 中已经存在且能满足你需求的函数.

def f(x):
    return x**2+2*x
f(x)

Python科学计算 第3版pdf python科学计算第三版_科学计算_25

#很多时候,我们并不需要函数表示,而是需要如下的表达式的(柄,感觉叫句柄有点意思)
expre = 1+x**2+5*x**3
expre

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_26

#expre,有自己的完善的参数体系,这个体系呈现树形结构。
expre.args

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_27

expre.args[2]

Python科学计算 第3版pdf python科学计算第三版_python_28

expre.args[2].args[1]

Python科学计算 第3版pdf python科学计算第三版_字符串_29

expre.args[2].args[0]

Python科学计算 第3版pdf python科学计算第三版_科学计算_30

#化简操作,是所有表达式运算过程中最常用的函数
expr = 2*(x**2-x) - x*(x+1)
expr

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_31

sympy.simplify(expr)

Python科学计算 第3版pdf python科学计算第三版_字符串_32

expr2 =2*sympy.cos(x)*sympy.sin(x)
expr2

Python科学计算 第3版pdf python科学计算第三版_科学计算_33

sympy.simplify(expr2)

Python科学计算 第3版pdf python科学计算第三版_字符串_34

化简成功的关键是对所有的函数和常数采用sympy定义的函数或常数。

化简函数

sympy.simplify 调用不同的方法得到化简结果

sympy.trigsimp 尝试三角恒等式化简结果

sympy.powsimp 用幂指数化简

sympy.compsimp 通过组合化简多项式

sympy.ratsimp 提取公分母

下面是展开函数的使用说明:
expr=(x+4)*(x+5)
sympy.expand(expr)

Python科学计算 第3版pdf python科学计算第三版_科学计算_35

sympy.sin(x+y).expand()

Python科学计算 第3版pdf python科学计算第三版_科学计算_36

sympy.sin(x+y).expand(trig= True)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_37

a, b = sympy.symbols("a, b", positive=True)# 使用化简必须保证,所有的数学符号,函数都是sympy产生的
sympy.log(a * b).expand(log=True)

Python科学计算 第3版pdf python科学计算第三版_字符串_38

sympy.exp(I*a + b).expand(complex=True)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_39

sympy.expand((a * b)**x, power_base=True)

Python科学计算 第3版pdf python科学计算第三版_字符串_40

sympy.exp((a-b)*x).expand(power_exp=True)

Python科学计算 第3版pdf python科学计算第三版_python_41

因子、汇集和组合
sympy.factor(x**2 - 1)

Python科学计算 第3版pdf python科学计算第三版_科学计算_42

sympy.factor(x * sympy.cos(y) + sympy.sin(z) * x)

Python科学计算 第3版pdf python科学计算第三版_科学计算_43

sympy.logcombine(sympy.log(a) - sympy.log(b))

Python科学计算 第3版pdf python科学计算第三版_python_44

sympy.trigsimp, sympy.powsimp, and sympy.logcombine,都可以产生简单的化简

expr = x + y + x**2 * y * z
expr.collect(x) #按照x的指数大小排列

Python科学计算 第3版pdf python科学计算第三版_字符串_45

expr = sympy.cos(x + y) + sympy.sin(x - y)
expr.expand(trig=True).collect([sympy.cos(x), 
                                 sympy.sin(x)]).collect(sympy.cos(y) - sympy.sin(y))

Python科学计算 第3版pdf python科学计算第三版_科学计算_46

expr.expand(trig=True).
collect([sympy.cos(x), sympy.sin(x)]).collect(sympy.cos(y) - sympy.sin(y))
File "<ipython-input-96-fefb96c05190>", line 1
    expr.expand(trig=True).
                           ^
SyntaxError: invalid syntax
expr.expand(trig=True).collect([
    sympy.cos(x), sympy.sin(x)]).collect(sympy.cos(y) - sympy.sin(y))

Python科学计算 第3版pdf python科学计算第三版_科学计算_46

事实上,在那个地方回车是有讲究的,如果愿意全部试试。

sympy.apart(1/(x**2 + 3*x + 2), x)#非常有用的分解

Python科学计算 第3版pdf python科学计算第三版_python_48

sympy.together(1 / (y * x + y) + 1 / (1+x))

Python科学计算 第3版pdf python科学计算第三版_python_49

sympy.cancel(y / (y * x + y)) #约分化简

Python科学计算 第3版pdf python科学计算第三版_python_50

sympy.cancel(y / (y * x + 4))

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_51

sympy.cancel(y / (y * x + 4*y**2))

Python科学计算 第3版pdf python科学计算第三版_python_52

代换 Substitutions
(x + y).subs(x, y)

Python科学计算 第3版pdf python科学计算第三版_python_53

sympy.sin(x * sympy.exp(x)).subs(x, y)

Python科学计算 第3版pdf python科学计算第三版_python_54

sympy.sin(x * z).subs({z: sympy.exp(y), x: y, sympy.sin: sympy.cos})

Python科学计算 第3版pdf python科学计算第三版_科学计算_55

当然也可以带入值

expr = x * y + z**2 *x
values = {x: 1.25, y: 0.4, z: 3.2}
expr.subs(values)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_56

赋值过程中,追求精度,必须要采用,sympy.N()函数,或者用evalf()函数、

sympy.N(pi, 50)

Python科学计算 第3版pdf python科学计算第三版_字符串_57

(x + 1/pi).evalf(10)

Python科学计算 第3版pdf python科学计算第三版_字符串_58

f = sympy.Function('f')(x)
sympy.diff(f, x)               # equivalent to f.diff(x)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_59

sympy.diff(f, x, x)

Python科学计算 第3版pdf python科学计算第三版_字符串_60

sympy.diff(f, x, 3)   # equivalent to sympy.diff(f, x, x, x)

Python科学计算 第3版pdf python科学计算第三版_科学计算_61

g = sympy.Function('g')(x, y)
g.diff(x, y)          # equivalent to sympy.diff(g, x, y)

Python科学计算 第3版pdf python科学计算第三版_科学计算_62

g.diff(x, 3, y, 2)    # equivalent to sympy.diff(g, x, x, x, y, y)

Python科学计算 第3版pdf python科学计算第三版_科学计算_63

expr = x**4 + x**3 + x**2 + x + 1
expr.diff(x)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_64

expr = sympy.sin(x * y) * sympy.cos(x / 2)
expr.diff(x)

Python科学计算 第3版pdf python科学计算第三版_字符串_65

expr2 = sympy.special.polynomials.hermite(x, 0)
expr.diff(x).doit()

Python科学计算 第3版pdf python科学计算第三版_科学计算_66

d = sympy.Derivative(sympy.exp(sympy.cos(x)), x)
d

Python科学计算 第3版pdf python科学计算第三版_字符串_67

d.doit()#执行上一步运算

Python科学计算 第3版pdf python科学计算第三版_python_68

a, b, x, y = sympy.symbols("a, b, x, y")
f = sympy.Function("f")(x)
sympy.integrate(f)

Python科学计算 第3版pdf python科学计算第三版_科学计算_69

sympy.integrate(f, (x, a, b))

Python科学计算 第3版pdf python科学计算第三版_python_70

sympy.integrate(sympy.exp(-x**2), (x, 0, oo))

Python科学计算 第3版pdf python科学计算第三版_字符串_71

级数
x, y = sympy.symbols("x, y")
f = sympy.Function("f")(x)
sympy.series(f, x)

KaTeX parse error: Undefined control sequence: \substack at position 87: …ght)} \right|_{\̲s̲u̲b̲s̲t̲a̲c̲k̲{ x=0 }} + \fra…

x0 = sympy.Symbol("{x_0}")
f.series(x, x0, n=3)

KaTeX parse error: Undefined control sequence: \substack at position 124: …ght)} \right|_{\̲s̲u̲b̲s̲t̲a̲c̲k̲{ \xi_{1}={x_0}…

f.series(x, x0, n=2).removeO() #移除掉截断项,参与后续运算。

KaTeX parse error: Undefined control sequence: \substack at position 99: …ght)} \right|_{\̲s̲u̲b̲s̲t̲a̲c̲k̲{ \xi_{1}={x_0}…

f.series(x, x0, n=3).removeO()

KaTeX parse error: Undefined control sequence: \substack at position 117: …ght)} \right|_{\̲s̲u̲b̲s̲t̲a̲c̲k̲{ \xi_{1}={x_0}…

sympy.cos(x).series()

Python科学计算 第3版pdf python科学计算第三版_字符串_72

(1/(1+x)).series()

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_73

expr = sympy.cos(x) / (1 + sympy.sin(x * y))
expr.series(x, n=4)

Python科学计算 第3版pdf python科学计算第三版_python_74

expr.series(y, n=4)

Python科学计算 第3版pdf python科学计算第三版_科学计算_75

sympy.limit(sympy.sin(x) / x, x, 0) #极限

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_76

f = sympy.Function('f')
x, h = sympy.symbols("x, h")
diff_limit = (f(x + h) - f(x))/h
sympy.limit(diff_limit.subs(f, sympy.cos), h, 0)

Python科学计算 第3版pdf python科学计算第三版_python_77

sympy.limit(diff_limit.subs(f, sympy.sin), h, 0)

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_78

以上代码用于说名sin函数的极限由来,没有太强的意义

expr = (x**2 - 3*x) / (2*x - 2)
p = sympy.limit(expr/x, x, sympy.oo)
q = sympy.limit(expr - p*x, x, sympy.oo)
p,q

Python科学计算 第3版pdf python科学计算第三版_字符串_79

n = sympy.symbols("n", integer=True)
x = sympy.Sum(1/(n**2), (n, 1, oo))
n

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_80

x

Python科学计算 第3版pdf python科学计算第三版_python_81

x.doit() #有的函数必须用doit()函数来完成,最终的运算

Python科学计算 第3版pdf python科学计算第三版_python_82

x = sympy.Symbol("x")
sympy.Sum((x)**n/(sympy.factorial(n)), (n, 1, oo)).doit().simplify()

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_83

wz = sympy.Sum((x)**n/(sympy.factorial(n)), (n, 1, oo))
wz.doit()

Python科学计算 第3版pdf python科学计算第三版_字符串_84

wz.doit().simplify()

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_83

涉及到各类化简,再加上doit()命令,在函数化简的路上,要多尝试!

方程

x = sympy.Symbol("x")
sympy.solve(x**2 + 2*x - 3)

Python科学计算 第3版pdf python科学计算第三版_python_86

a, b, c = sympy.symbols("a, b, c")
sympy.solve(a * x**2 + b * x + c, x)

Python科学计算 第3版pdf python科学计算第三版_字符串_87

eq1 = x + 2 * y - 1
eq2 = x - y + 1
sympy.solve([eq1, eq2], [x, y], dict=True)

Python科学计算 第3版pdf python科学计算第三版_字符串_88

#也可以获取结果
sols = sympy.solve([eq1, eq2], [x, y], dict=True)
[eq1.subs(sol).simplify() == 0 and eq2.subs(sol).simplify() == 0 for sol in sols]
[True]

线性代数

sympy.Matrix([1,2])

Python科学计算 第3版pdf python科学计算第三版_python_89

np.array([1,2])
array([1, 2])
a, b, c, d = sympy.symbols("a, b, c, d")
M = sympy.Matrix([[a, b], [c, d]])
M

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_90

M * M

Python科学计算 第3版pdf python科学计算第三版_字符串_91

M.norm()

Python科学计算 第3版pdf python科学计算第三版_python_92

M.rank()

Python科学计算 第3版pdf python科学计算第三版_字符串_93

M.trace()

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_94

M.transpose()

Python科学计算 第3版pdf python科学计算第三版_python_95

M^T
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-193-0be5c4114203> in <module>
----> 1 M^T


NameError: name 'T' is not defined
M.T

Python科学计算 第3版pdf python科学计算第三版_python_95

M.H

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_97

transpose/T 转置
adjoint/H 转置加共轭
trace 求迹
det 行列式
inv 矩阵的逆
LUdecomposition LU分解
LUsolve LU求解方程
QRdecomposition 分解
diagonalize 对角化 D = P^(-1) MP
norm 范数
nullspace Compute a set of vectors that span the null space of a Matrix.
rank 计算矩阵的秩
singular_values 奇异值
solve Solve a linear system of equations in the form Mx = b.

example: $ x+py = b_{1} Python科学计算 第3版pdf python科学计算第三版_字符串_98 qx+y = b_{2} $
我们可以把上面的方程用矩阵表示为
$ MX =b $

p, q = sympy.symbols("p, q")
M = sympy.Matrix([[1, p], [q, 1]])
b = sympy.Matrix(sympy.symbols("b_1, b_2"))
x = M.LUsolve(b)
x

Python科学计算 第3版pdf python科学计算第三版_科学计算_99

x1 = M.inv() * b
x1

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_100

x ==x1
False
rt = x.T*x1
rt

Python科学计算 第3版pdf python科学计算第三版_Python科学计算 第3版pdf_101

rt.collect(p)#调用化简函数都会报错,原因在于多变量矩阵没有该类化简的属性
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-232-b3d07a6ec5ae> in <module>
----> 1 rt.collect(p)


~/.conda/envs/qutip-env/lib/python3.7/site-packages/sympy/matrices/matrices.py in __getattr__(self, attr)
   2139         else:
   2140             raise AttributeError(
-> 2141                 "%s has no attribute %s." % (self.__class__.__name__, attr))
   2142 
   2143     def __len__(self):


AttributeError: MutableDenseMatrix has no attribute collect.
ics={b[0]:3,b[1]:4,p:7,q:11}
x.subs(ics)

Python科学计算 第3版pdf python科学计算第三版_字符串_102

b

Python科学计算 第3版pdf python科学计算第三版_字符串_103

b[0]

Python科学计算 第3版pdf python科学计算第三版_科学计算_104

b[1]

Python科学计算 第3版pdf python科学计算第三版_字符串_105

x1.subs(ics)

Python科学计算 第3版pdf python科学计算第三版_字符串_102

由此可以看到,直接比较是会得到荒谬的答案的,然而带入数据后,发现其实是相等的。

然而,如果解方程mx=b是目标,计算矩阵的逆比执行LU分解的难度更大,

那么使用lu分解更有效。这对于较大的方程系统,尤其重要