【学习笔记】第三章 Python在高等数学和线性代数中的应用

目录

3.1 Sympy工具库介绍

3.1.1 Sympy工具库介绍(服务于符号运算的工具库)

1.微积分模块(sympy.integrals)

2.离散数学模块(sympy.discrete

3.方程求解模块(sympy.solvers)

4.矩阵模块(sympy.matrices)

6.统计学模块(sympy.stats)

3.1.2 符号运算基础知识

3.2 Scipy工具库简介 

1. 微积分模块 (scipy.integrate)

(1) 给定函数的数值积分

(2)  给定离散点的数值积分

(3) 微分方程的数值解 

2. 线性代数模块 (scipy.linalg)

3. 优化模块 (scipy.optimize)

4. 插值模块 (scipy.interpolate) 

5. 统计学模块 (scipy.stats) 

6. 傅里叶变换模块 (scipy.fftpack)

7. 信号处理模块 (scipy.signal) 

8. 多维图像处理模块 (scipy.cluster) 

9. 空间分析模块 (scipy.spatial) 

10. 聚类模块 (scipy.cluster) 

11. 文件输入/输出模块(scipy.io) 

3.3 用Sympy做符号函数画图 

1. 二维曲线画图

2. 三维曲面画图 

 3. 隐函数画图

3.4 高等数学问题的符号解

1. 求极限 

2. 求导数 

3. 级数的求和 

4. 泰勒展开 

 5. 不定积分和定积分

 6. 求解代数方程(方程组)的符号解

7. 求微分方程(方程组)的符号解 【通解,初值问题,边值问题】

3.5 高等数学问题的数值解 (SciPy工具库求数值解,即近似解)

3.5.1 泰勒级数与数值导数

1. 泰勒级数

2. 数值导数 

 3.5.2 数值积分

1. 一重积分(梯形计算公式和辛普森计算公式)

2. 多重积分 

3.5.3 非线性方程(组)数值解

1. 二分法求根

2. 牛顿迭代法求根 

3. 用Scipy工具库求解非线性方程(方程组) 

4. 用fsolve求非线性方程组的数值解

 3.5.4 函数极值点的数值解

1. 一元函数极值点

2. 多元函数的极值点 

 3.6 线性代数问题的符号解和数值解

3.6.1 线性代数问题的符号解

1. 矩阵的运算 

2. 解线性方程组 

 3. 特征值和特征向量

4. 相似对角化

3.6.2 线性代数问题的数值解(Numpy库)

1. 向量和矩阵的运算 

2. 齐次线性方程组的数值解

3. 非齐次线性方程组的数值解 

3.6.3 求超定线性方程组的最小二乘解


科学运算设计数值运算和符号运算,数值运算可以使用Numpy库和Scipy库,符号运算则可以使用Sympy工具库。

数值计算的表达式、矩阵变量中不允许有未定义的自由变量 , 而符号计算可以含有未定义的符号变量。

3.1 Sympy工具库介绍

3.1.1 Sympy工具库介绍(服务于符号运算的工具库)

常用模块如下:

  • abc:符号变量模块;
  • calculus:积分相关方法;
  • core:基本的加、乘、指数运算等;discrete:离散数学;
  • functions:基本的函数和特殊函数;galgebra:几何代数;
  • geometry:几何实体;integrals:符号积分;
  • interactive:交互会话(如IPython);logic:布尔代数和定理证明;
  • matrices:线性代数和矩阵;ntheory:数论函数;
  • physics:物理学;
  • plotting:用 Pyglet进行二维和三维的画图;polys:多项式代数和因式分解;
  • printing:漂亮的打印和代码生成;series:级数;
  • simplify:化简符号表达式;
  • solvers:方程求解;
  • stats:统计学.

接下来会针对一些模块进行简要描述: 

1.微积分模块(sympy.integrals)

微积分模块支持大量的基础与高级微积分运算功能.例如,支持导数、积分、级数展开、微分方程以及有限差分方程. SymPy还支持积分变换;在微分中,还支持数值微分、复合导数和分数阶导数。

2.离散数学模块(sympy.discrete

离散数学指变量特征是离散的数学分支,与连续变量的数学(微积分)区分开来.它主要处理整数、图形以及逻辑学中的问题.这个模块对二项式系数、乘积与求和运算有完整的支持。

3.方程求解模块(sympy.solvers)

求解器(solvers)是SymPy 中求方程解的模块.这个模块具有解复数多项式以及多项式组的能力.它可以解代数方程、常微分方程、偏微分方程和差分方程。

4.矩阵模块(sympy.matrices)

SymPy具有强大的矩阵与行列式计算的功能.矩阵属于线性代数的分支.SymPy支持矩阵创建,如全0矩阵、全1矩阵、随机矩阵以及矩阵运算.它还支持一些特殊函数,如计算黑塞矩阵(Hessian matrix)的函数、一组向量的格拉姆-施密特(Gram-Schmidt)正交化函数、朗斯基 (Wronskian)行列式计算的函数等。
另外,SymPy还支持特征值和特征向量的计算、矩阵的转置以及矩阵与行列式求解.还支持因式分解算法等.在计算中,还有零空间(null space)计算,行列式、代数余子式展开工具以及伴随矩阵。

5.物理学模块(sympy.physics)

SymPy有一个模块可以解决物理学问题.它支持力学功能,包括经典力学与量子力学以及高能物理学.它还支持一维空间与三维空间的泡利代数与量子谐振子,支持光学相关的功能.它还有一个独立的模块将物理单位集成到SymPy 里.用户可以选择相应的物理单位完成计算和单位转换.

6.统计学模块(sympy.stats)

SymPy的统计学模块支持数学计算中涉及的许多统计函数.除了常见的连续与离散随机分布函数,它还支持符号概率相关功能.SymPy库中的随机分布函数都支持随机数生成功能。

3.1.2 符号运算基础知识

使用Sympy库进行符号计算,首先要建立符号变量和符号表达式。符号变量是构成符号表达式的基本元素。可以通过库中的symbols()函数创建,如下:

>>>from sympy import *

>>>x=symbols('x')        # x是符号变量的名称,'x'是符号变量的值,名称和值可以不相同

>>>y,z=symbols('y z')        #构建多个符号变量时,赋值中间要用空格分隔

#构建多个符号变量还有一种方法,将m0:3传入符号函数,生成如m0,m1,m2的符号序列

在符号运算中,使用evalf()或n()方法来获得任何对象的浮点近似值,默认精度为小数点后15位。

例3.1 符号创建,类型转换以及subs()方法带入值示例:

from sympy import *
x,y,z=symbols('x  y  z')
m0,m1,m2,m3=symbols('m0:4')  #创建多个符号变量的第二种方法
x=sin(1)
print("x=",x); print("x=",x.evalf())
print("x=",x.n(16))  #显示小数点后16位数字
print("pi的两种显示格式:{},{}".format(pi,pi.evalf(3)))  #这里不能使用n()函数
expr1=y*sin(y**2)  #创建第一个符号表达式
expr2=y**2+sin(y)*cos(y)+sin(z)  #创建第二个符号表达式
print("expr1=",expr1)
print("y=5时,expr1=",expr1.subs(y,5))  #代入一个符号变量的值
print("y=2,z=3时,expr2=",expr2.subs({y:2,z:3}))  #代入y=2,z=3
print("y=2,z=3时,expr2=",expr2.subs({y:2,z:3}).n())  #以浮点数显示计算结果

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第1张图片

 Sympy库有很多函数可以用于处理有理数,可以对有理数进行简化,展开,合并等操作。together函数可以用于计算两个有理数的加法,apart函数可以用于处理有理数的除法。

例3.2 符号函数together()和apart()使用示例(化简表达式)

from sympy import *
x1,x2,x3,x4=symbols('m1:5'); x=symbols('x')#两种方法创建符号变量
print(x1/x2+x3/x4)
print(together(x1/x2+x3/x4))
print((2*x**2+3*x+4)/(x+1))
print(simplify((2*x**2+3*x+4)/(x+1)))  #化简没有效果
print(apart((2*x**2+3*x+4)/(x+1)))

 

3.2 Scipy工具库简介 

SciPy是对NumPy的功能扩展,它提供了许多高级数学函数,例如,微分、积分、微分方程、优化算法、数值分析、高级统计函数、方程求解等.SciPy是在NumPy数组框架的基础上实现的,它对 NumPy数组和基本的数组运算进行扩展,满足科学家和工程师解决问题时需要用到的大部分数学计算功能.
SciPy支持的功能包括文件处理、积分、数值分析、优化方法、统计学、信号与图像处理、聚类分析和空间分析等.下面简要介绍部分功能模块.

1. 微积分模块 (scipy.integrate)

微积分模块支持数值积分和微分方程数值解的功能。

注:以下一般不给出函数用法的详细说明,读者可以查看相关函数的帮助信息,例如,看函数romberg的帮助信息,使用命令:
>>>from scipy.integrate import romberg

>>> help(romberg)

(1) 给定函数的数值积分

  • quad:一重数值积分.
  • dblquad:二重数值积分.
  • tplquad:三重数值积分.
  • nquad:通用N重积分.
  • fixed-quad:使用固定阶高斯求积公式求数值积分.
  • quadrature:使用固定误差限的高斯求积公式求数值积分.
  • romberg:求函数的 Romberg数值积分.

(2)  给定离散点的数值积分

  • cumtrapz:用梯形法求数值积分.
  • simps:用辛普森法求数值积分.
  • romb:用 Romberg积分法求自变量均匀间隔离散点的数值积分

(3) 微分方程的数值解 

  • odeint:使用FORTRAN 库中方法求微分方程组的数值解.
  • ode:求一般微分方程组的数值解.
  • complex_ode:求复微分方程组的数值解.

2. 线性代数模块 (scipy.linalg)

与numpy.linalg 相比, scipy.linalg 函数有更高级的特征。

3. 优化模块 (scipy.optimize)

SciPy的优化模块提供了解决单变量和多变量的目标函数最小值问题的功能.它通过大量的算法解决最小化问题.优化模块支持线性回归、搜索函数的最大值与最小值、方程求根、线性规划、拟合等功能.

4. 插值模块 (scipy.interpolate) 

插值模块支持一维和多维插值,例如,泰勒(Taylor)多项式插值,一维和多维样条插值.

5. 统计学模块 (scipy.stats) 

统计模块提供了各种随机变量的分布、统计量的计算、分布拟合、参数检验等功能.

6. 傅里叶变换模块 (scipy.fftpack)

 离散傅里叶变换和离散傅里叶逆变换可以分别用ft和ifft函数来计算.

7. 信号处理模块 (scipy.signal) 

信号处理模块包含一系列滤波函数、滤波器设计函数,以及对一维和二维数据进行B-样条插值的函数.这个模块包含的函数可以进行以下操作:卷积、B-样条、滤波、滤波器设计、MATLAB式的IIR滤波器设计、连续时间的线性系统、离散时间的线性系统、线性时不变系统、信号波形、窗函数、小波分析和光谱分析等.

8. 多维图像处理模块 (scipy.cluster) 

通常图像处理可以看作对二维数组的操作.这个模块提供了图像处理的各种函数,例如,图像几何变换、图像滤波等.

9. 空间分析模块 (scipy.spatial) 

空间分析是一系列用于分析空间数据的算法.空间数据是指和地理空间或垂直空间相关的数据对象.这种数据包括点、线、多边形、其他几何和地理特征信息.
该模块支持 Delaunay三角剖分、Voronoi图、N维凸包等功能,支持KD树(scipy.spatial.kdtree)实现快速近邻查找算法,还可以对初始向量集合进行距离矩阵的计算.

10. 聚类模块 (scipy.cluster) 

聚类是将一个大的集合分成多个组的过程. SciPy 聚类模块包括两个子模块:向量量化(vector quantization,VQ)(scipy.cluster.vq)和层次聚类(scipy.cluster.hierarchy).VQ模块支持    K均值聚类和向量量化,层次聚类模块支持分层聚类和聚合聚类.

11. 文件输入/输出模块(scipy.io) 

SciPy可以使用MATLAB的“.mat”文件格式读取和写入数据,函数为load-mat 和 savemat.如果要加载数据,则可以使用如下语法:
>>>import scipy.io
>>>data=scipy.io.loadmat( 'datafile.mat ')

返回值data为一个字典,该字典包含了与“.mat”文件中保存的变量名相对应的键,对应值为 NumPy数组格式.
保存数据到“.mat”文件涉及创建一个包含要保存的所有变量的字典(变量名和值),函数为savemat,保存数组x和y 的代码如下
>>>data-0;data['x']-x; dataL'y']=y
>>>scipy.io.savemat( 'datafile.mat ' ,data)

3.3 用Sympy做符号函数画图 

(与上一章中numpy利用matplotlib作图相比,sympy更方便)

1. 二维曲线画图

plot的基本使用格式为

plot(表达式,变量取值范围,属性=属性值)

多重绘制的使用格式为

plot(表达式1,表达式2,变量取值范围,属性=属性值)

或者

plot((表达式1,变量取值范围1),(表达式2,变量取值范围2))

例3.3 在同一图形界面上画出y1=2sinx,x属于[-6,6];y2=cos(x+pi/4),x属于[-5,5]。

from sympy.plotting import plot
from sympy.abc import x,pi   #引进符号变量x及常量pi#还记得前面的符号变量的定义方法吗?
from sympy.functions import sin,cos
plot((2*sin(x),(x,-6,6)),(cos(x+pi/4),(x,-5,5)))

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第2张图片

2. 三维曲面画图 

例3.4 画出三维曲面z=sin(\sqrt{x^2+y^2})的图形

from pylab import rc  #pylab为matplotlib的接口
from sympy.plotting import plot3d
from sympy.abc import x,y   #引进符号变量x,y
from sympy.functions import sin,sqrt
rc('font',size=16); rc('text',usetex=True)
plot3d(sin(sqrt(x**2+y**2)),(x,-10,10),(y,-10,10),xlabel='$x$',ylabel='$y$')

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第3张图片

 3. 隐函数画图

例3.5 绘制隐函数(x-1)^2+(y-2)^3-4=0的图形

from pylab import rc
from sympy import plot_implicit as pt,Eq
from sympy.abc import x,y   #引进符号变量x,y
rc('font',size=16); rc('text',usetex=True)
pt(Eq((x-1)**2+(y-2)**3,4),(x,-6,6),(y,-2,4),xlabel='$x$',ylabel='$y$')
#转化成(x-1)^2+(y-2)^3=4的形式,Eq为隐函数画图标志

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第4张图片

也可以使用匿名函数(lamada函数): 

from sympy import plot_implicit as pt
from sympy.abc import x,y   #引进符号变量x,y
ezplot=lambda expr:pt(expr)
ezplot((x-1)**2+(y-2)**3-4)

3.4 高等数学问题的符号解

SymPy包括许多功能,从基本的符号算术到多项式、微积分、求解方程离散数学和统计等.它主要处理三种类型的数据:整型数据、实数和有理数.有理数包括两个部分:分子和分母,可以用Ration类定义有理数.

1. 求极限 

例3.6 验证 \lim_{x\rightarrow 0}\tfrac{sinx}{x}=1,\lim_{x\rightarrow +\infty }(1+\tfrac{1}{x})^x=e

from sympy import *
x=symbols('x')#定义符号变量
print(limit(sin(x)/x,x,0))#limit->取极限函数
print(limit(pow(1+1/x,x),x,oo))  #这里是两个小”o”,表示正无穷

2. 求导数 

例3.7 已知:z=sinx+x^2e^y,求\frac{\partial^2 z}{\partial x^2},\frac{\partial z}{\partial y}

from sympy import *
x,y=symbols('x y')    #定义两个符号变量
z=sin(x)+x**2*exp(y)     #构造符号表达式
#x**2 x的2次方   exp(y) e的y次幂
print("关于x的二阶偏导数为:",diff(z,x,2))#diff函数求一阶或高阶导数
print("关于y的一阶偏导数为:",diff(z,y))

3. 级数的求和 

例3.8 验证 \sum_{k=1}^{n}k^2=\tfrac{n(n+1)(2n+1)}{6},\sum_{k=1}^{\infty }\frac{1}{k^2}=\frac{\pi ^2}{6} 

from sympy import *
k,n=symbols('k  n')
print(summation(k**2,(k,1,n)))#summation函数用于级数求和
print('上式因式分解后结果为:',factor(summation(k**2,(k,1,n))))  #factor函数将计算结果因式分解
print(summation(1/k**2,(k,1,oo)))  #这里是两个小o表示正无穷

4. 泰勒展开 

例3.9 写出sinx在0点处的3,5,7阶泰勒展开式,并在同一图形界面上画出sinx及他的上述各界泰勒展开式在区间[0,2]上的图形。

from pylab import rc#用于画图的pylab接口
from sympy import *
rc('font',size=16); rc('text',usetex=True)
x=symbols('x')#定义符号变量
y=sin(x)
for k in range(3,8,2): print(y.series(x,0,k))  #等价于print(series(y,x,0,k))#series函数用于求泰勒展开式
plot(y,series(y,x,0,3).removeO(),series(y,x,0,5).removeO(),
     series(y,x,0,7).removeO(),(x,0,2),xlabel='$x$',ylabel='$y$')
#在计算泰勒展开式时不需要removeO,但是画图时需要,否则会报错,原因未知

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第5张图片

 5. 不定积分和定积分

例3.10 验证\int_{0}^{\pi}sin(2x)dx=0,\int_{0}^{+\infty }\frac{sinx}{x}dx=\frac{\pi}{2}

from sympy import integrate, symbols, sin, pi, oo#oo为无穷
x=symbols('x')
print(integrate(sin(2*x),(x,0,pi)))#integrate函数计算定积分,对x从0积分到pi
print(integrate(sin(x)/x,(x,0,oo)))

 

 以上为计算定积分示例,若想算不定积分,将integrate函数第二个参数(x,0,pi)只保留(x)即可        eg:

>>>print(integrate(sin(2*x),(x)))

>>>-cos(2*x)/2

 6. 求解代数方程(方程组)的符号解

例3.11 求如下代数方程:

(1)x^3=1

(2)(x-2)^2(x-1)^3=0

from sympy import *
x,y=symbols('x  y')
print(solve(x**3-1,x))#solve函数可以求代数方程的符号解,但是要转化为Ax+B=0的形式
print(solve((x-2)**2*(x-1)**3,x))
print(roots((x-2)**2*(x-1)**3,x))  #roots可以得到根的重数信息,根2为2重根,根1为三重根

例3.12 求如下代数方程组

x^2+y^2=1\bigcap x-y=0

from sympy.abc import x, y
from sympy import solve
s=solve([x**2+y**2-1, x-y], [x, y])
print("方程组的解为:", s)

 #sqrt表示对括号中表达式开平方

例3.13 求函数 f(x)=2x^3-5x^2+x 的驻点,并求函数在[0,1]上的最大值。

from sympy import *
x=symbols('x'); y=2*x**3-5*x**2+x
x0=solve(diff(y,x),x)   #求驻点,diff函数用于求导数,solve用于求代数方程
print("驻点的精确解为",x0)
print("驻点的浮点数表示为:",[x0[i].n() for i in range(len(x0))])  #列表中的符号数无法整体转换为浮点数
#在符号运算中,使用evalf()或n()方法来获得任何对象的浮点近似值,默认精度为小数点后15位。
y0=[y.subs(x,0),y.subs(x,1),y.subs(x,x0[0]).n()] #代入区间端点和一个驻点的值
print("三个点的函数值分别为:",y0)
#连续函数在区间内最值一定在端点或驻点取到

7. 求微分方程(方程组)的符号解 【通解,初值问题,边值问题】

例3.14 求下列微分方程的通解

(1)齐次方程:y''-5y'+6y=0.

(2)非齐次方程:y''-5y'+6y=xe^{2x}.

from sympy import *
x=symbols('x'); y=symbols('y',cls=Function)
eq1=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)
eq2=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)-x*exp(2*x)
print("齐次方程的解为:",dsolve(eq1,y(x)))
print("非齐次方程的解为:",dsolve(eq2,y(x)))

由上结果可知,齐次方程的通解为:y(x)=(c_{1}+c_{2}e^x)e^{2x}

非齐次方程的通解为:y(x)=(c_{1}+c_{2}e^x-\frac{x^2}{2}-x)e^{2x}

 例3.15 求下列微分方程的解

(1)初值问题:y''-5y'+6y=0,y(0)=1,y'(0)=0

(2)边值问题:y''-5y'+6y=xe^{2x},y(0)=1,y(2)=0

from sympy import *
x=symbols('x'); y=symbols('y',cls=Function)
eq1=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)#先构造微分方程
eq2=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)-x*exp(2*x)
print("初值问题的解为:{}".format(dsolve(eq1,y(x),ics={y(0):1,diff(y(x),x).subs(x,0):0})))#diff函数求导
y2=dsolve(eq2,y(x),ics={y(0):1,y(2):0})
print("边值问题的解为:{}".format(y2))#formate用于搭配{}格式化输出
#初值问题和边值问题格式相同

3.5 高等数学问题的数值解 (SciPy工具库求数值解,即近似解)

3.5.1 泰勒级数与数值导数

1. 泰勒级数

sin x的泰勒级数展开式为:

sinx = \sum_{k=0}^{\infty }\frac{(-1)^kx^{2k+1}}{(2k+1)!},x\in (-\infty ,\infty )

例3.16 画出sin x及它在0点处的1,3,5阶泰勒展开式在 x\in [-2\pi,2\pi]  时的图形

import numpy as np
import matplotlib.pyplot as plt
def fac(n): return (1 if n<1 else n*fac(n-1))#定义fac函数做阶乘运算
def item(n,x): return (-1)**n*x**(2*n+1)/fac(2*n+1)#定义item函数返回k=n时的单个展开项
def mysin(n,x): return (0 if n<0 else mysin(n-1,x)+item(n,x))#计算多项递归求和,表示n阶泰勒展开
x=np.linspace(-2*np.pi,2*np.pi,101)#在[-2pi,2pi]取101个点
plt.plot(x,np.sin(x),'*-')#画出sin x标准图像
str=['v-','H--','-.']#设置三种不同的图像格式
for n in [1,2,3]: plt.plot(x,mysin(2*n-1,x),str[n-1])#画出1,3,5阶泰勒级数图像
plt.legend(['sin','n=1','n=3','n=5'])#图例
plt.savefig('figure3_16.png',dpi=500); plt.show()

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第6张图片

2. 数值导数 

利用泰勒级数可以给出近似计算函数导数的方法.例如,若f(x)存在一阶导数,则由泰勒级数:

f(x+\Delta x)=f(x)+f'(x)\Delta x+\circ (\Delta x)

移项并舍弃高阶无穷小,得 f'(x)\approx \frac{f(x+\Delta x)-f(x-\Delta x)}{2\Delta x}

当函数具有更高阶导数时,如利用:f(x+\Delta x)=f(x)+f'(x)\Delta x+\frac{f''(x)}{2!}(\Delta x)^2+\circ ((\Delta x)^2)

以及:f(x-\Delta x)=f(x)-f'(x)\Delta x+\frac{f''(x)}{2!}(\Delta x)^2+\circ ((\Delta x)^2)

可得二阶导数的计算公式:f''(x)\approx \frac{f(x+\Delta x)-2f(x)+f(x-\Delta x)}{(\Delta x)^2}

 下面以运动学中的问题来展示数值导数的应用

例3.17 甲、乙、丙、丁4个人分别位于起始位置(一200, 200),(200, 200),(200,-200)以及(-200,—200)处(单位: m),并且以恒定的速率1m/s行走.在行走过程中,甲始终朝向乙的当前位置;同样,乙朝向丙、丙朝向丁、丁朝向甲.试绘制4人行走过程的近似轨迹.

分析:在运动学中,速度是位移相对于时间的导数,即:v(t)=\frac{d}{dt}r(t)

因此,在一段很短的时间 \Delta t 内,近似的有:r(t+\Delta t)\approx r(t)+v(t)\cdot \Delta t 成立,又由于位移,速度均是矢量,因此在 xOy 平面内,又有

        r_{x}(t+\Delta t)\approx r_{x}(t)+v(t)\cdot \Delta t\cdot cos\theta (t)

        r_{y}(t+\Delta t)\approx r_{y}(t)+v(t)\cdot \Delta t\cdot sin\theta (t)

联立二式,其中 \theta (t) 为t时刻与x轴正向的夹角

以两个二维数组xy, xyn分别存储4个人的当前位置和下一时刻的位置,具体地说,第i个人的当前位置为xy[i],下一时刻的位置为xyn[i],其中i取0,1,2,3时分别对应甲、乙、丙、丁。

下面语句
j=(i+1)%4;dxy=xy[j]-xy[i]
dd=dxy/ng.norm(dxy)        #单位化向量

就完成了对夹角余弦值、正弦值的计算.
二维数组Txy存放4个人的所有位置信息,其中 Txyl]存放第i个人所有时刻的位置信息.具体程序代码如下:

#该例较难,注释已经说的比较明白,注意学习领悟: 

import numpy as np, numpy.linalg as ng
import matplotlib.pyplot as plt
N=4; v=1.0; d=200.0; time=400.0; divs=201#time的值是随机设定的,后面可以用二分法估计time的值以估计四人汇聚的时间
xy=np.array([[-d,d],[d,d],[d,-d],[-d,-d]])#存储最开始四人的初始位置
T=np.linspace(0,time,divs); dt=T[1]-T[0]#等分时间为200份,求出时间间隔
xyn=np.empty((4,2))#生成一个4*2的空矩阵,用于储存四个人下一时刻的位置(每个人两个坐标)
Txy=xy#将xy中数据保存到Txy中(Txy的作用是储存最终的坐标数据)
for n in range(1,len(T)):#对每一个时间间隔进行操作
    for i in [0,1,2,3]:#四个人
#第12,14,15行为精华所在,注意学习!!!        
        j=(i+1)%4; dxy=xy[j]-xy[i]#计算结果是一个向量,表示两个人的相对位置。如甲向乙的方向走,则求乙相对于甲的位置
        dd=dxy/ng.norm(dxy) #单位化向量  #norm求向量的范数,相当于向量的模。
#范数(norm)是数学中的一种基本概念。在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即①非负性;②齐次性;③三角不等式。它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小。
        xyn[i]=xy[i]+v*dt*dd; #计算下一步的位置 #应该是广播机制
    Txy=np.c_[Txy,xyn]#Txy表就是把所有坐标记录下来
    xy=xyn#把刚才的下一步位置更新到这一步
for i in range(N):plt.plot(Txy[i,::2],Txy[i,1::2])
#[x,y,x,y,x,y,,,,]这样的表,从0按2步长取x,从1按2步长取y
plt.savefig("figure3_17.png",dpi=500); plt.show()

 

 3.5.2 数值积分

1. 一重积分(梯形计算公式和辛普森计算公式)

在实际问题中,利用牛顿-莱布尼茨公式通过求原函数计算定积分是十分复杂的。公式如下:

\int_{a}^{b}f(x)dx=F(x)|_{a}^{b}=F(b)-F(a)

我们一般选择运用微元思想的梯形法和辛普森法:

下面我们直接给出 \int_{a}^{b}f(x)dx 的梯形计算公式和辛普森计算公式:

使用梯形公式时,把整个区间[a,b]进行n等分(此时步长h= (b-a)/n),分点为 x_{i} (i=0,1,… ,n),对应的函数值 f_{i}=f(x_{i}),这里 x_i=a+i\cdot h,i=0,1,\cdots ,n.积分 \int_{a}^{b}f(x)dx 的数值解:

I_{1}=\frac{h}{2}(f_{0}+2\sum_{i=1}^{n-1}f_{i}+f_{n})

使用辛普森公式时,将区间[a,b]讲行2n等分,步长h=\frac{b-a}{2n},分点x_i=a+i\cdot h,i=0,1,\cdots ,2n对应的函数值 f_{i}=f(x_{i}).积分\int_{a}^{b}f(x)dx的数值解:

 I_{2}=\frac{h}{3}(f_{0}+2\sum_{i=1}^{n-1}f_{2i}+4\sum_{i=1}^{n}f_{2i-1}+f_{2n})

例3.18 分别使用梯形公式、辛普森公式和SciPy库中的函数quad(求给定函数的一重积分,见本章前面的讲述)求定积分 \int_{0}^{1}sin(\sqrt{cos x+x^2})dx

import numpy as np
from scipy.integrate import quad
#定义梯形公式函数和辛普森公式函数,可以当作模板使用,无需更改
def trapezoid(f,n,a,b):    #定义梯形公式的函数
    xi=np.linspace(a,b,n); h=(b-a)/(n-1)
    return h*(np.sum(f(xi))-(f(a)+f(b))/2)

def simpson(f,n,a,b):     #定义辛普森公式的函数
    xi, h=np.linspace(a,b,2*n+1), (b-a)/(2.0*n)
    xe=[f(xi[i]) for i in range(len(xi)) if i%2==0]
    xo=[f(xi[i]) for i in range(len(xi)) if i%2!=0]
    return h*(2*np.sum(xe)+4*np.sum(xo)-f(a)-f(b))/3.0
#构造被积函数
a=0; b=1; n=1000#n为分的分数,n越大越接近真实,但时间成本提高,尤其是辛普森方法时间成本很大
f=lambda x: np.sin(np.sqrt(np.cos(x)+x**2))

print("梯形积分I1=",trapezoid(f,n,a,b))
print("辛普森积分I2=",simpson(f,n,a,b))
print("SciPy积分I3=",quad(f,a,b))

2. 多重积分 

关于多重积分使用SciPy库中的函数dblquad, tplquad直接求数值解。dblquad的调用格式为:(double,所以dblquad函数用于二重积分)

dblquad(func, a, b,gfun,hfun,args=(),epsabs=1. 49e-08,epsrel=1.49e-08)
其中,被积函数func的格式为func(y, x),最外层x的积分区间为[a, b],内层y的积分区间为[gfun(x),hfun(x)].
tplquad的调用格式为:(triple,所以tplquad函数用于三重积分)

tplquad(func,a,b, gfun,hfun,qfun,rfun,args=(),epsabs=1.49e-08,epsrel=1.49e-o8)
其中,被积函数func的格式为func(z,y,x),最外层x的积分区间为[a, b],中间层y的积分区间为[gfun(x),hfun(x)],最内层z的积分区间为[qfun(x, y), rfun(x, y)].

例3.19 分别求下列积分的数值解:

(1)\int_{0}^{2}dx\int_{0}^{1}xy^2dy

(2)I=\iint_{x^2+y^2\leqslant 1}e^{-\frac{x^2}{2}}sin(x^2+y)dy

对于(2)中的二重积分,要先化成累次积分: \int_{-1}^{1}dx\int_{-\sqrt{1-x^2}}^{\sqrt{1-x^2}}d^{-\frac{x^2}{2}}sin(x^2+y)dy

import numpy as np
from scipy.integrate import dblquad

f1=lambda y, x: x*y**2  #第一个被积函数
print("I1:",dblquad(f1, 0, 2, 0, 1))#先是外层的下限和上限,后是内层的下限和上限

f2=lambda y, x: np.exp(-x**2/2)*np.sin(x**2+y)
bd=lambda x: np.sqrt(1-x**2)
print("I2:",dblquad(f2, -1, 1, lambda x: -bd(x), bd))#与上同理,两个返回值分别为积分值和误差值

 因此,第一个积分值为0.6667,第二个积分值为0.5369(后面的返回值为误差值)

例3.20 计算 \iiint_{\Omega }z\sqrt{x^2+y^2+1}dxdydz ,其中 \Omega 为柱面 x^2+y^2-2x=0 与 z=0,z=6两平面所围成的空间区域

先把三重积分化为累次积分:I=\int_{0}^{2}dx\int_{-\sqrt{2x-x^2}}^{\sqrt{2x-x^2}}dy\int_{0}^{6}z\sqrt{x^2+y^2+1}dz

import numpy as np
from scipy.integrate import tplquad
f=lambda z, y, x: z*np.sqrt(x**2+y**2+1)
ybd=lambda x: np.sqrt(2*x-x**2)
print("I=",tplquad(f, 0, 2, lambda x: -ybd(x),ybd, 0, 6))

 

 因此,积分值为87.4502

3.5.3 非线性方程(组)数值解

1. 二分法求根

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第7张图片

采用二分法对方程求根时,第n 次迭代对应的区间长度为 (b-a)/2^n,收敛速度是较快的. 

2. 牛顿迭代法求根 

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第8张图片

3. 用Scipy工具库求解非线性方程(方程组) 

例3.21 求 x^3+1.1x^2+0.9x-1.4=0 实根的近似值,使误差不超过 10^{-6}。要求使用三种方法:1.二分法 2.牛顿迭代法 3.直接调用Scipy库求解

import numpy as np
from scipy.optimize import fsolve

def binary_search(f, eps, a, b):  #二分法函数
    c=(a+b)/2
    while np.abs(f(c))>eps:
        if f(a)*f(c)<0: b=c
        else: a=c
        c=(a+b)/2
    return c

def newton_iter(f, eps, x0, dx=1E-8):  #牛顿迭代法函数
    def diff(f, dx=dx):   #求数值导数函数
        return lambda x: (f(x+dx)-f(x-dx))/(2*dx)
    df=diff(f,dx)
    x1=x0-f(x0)/df(x0)
    while np.abs(x1-x0)>=eps:
        x1, x0=x1-f(x1)/df(x1), x1
    return x1

f=lambda x: x**3+1.1*x**2+0.9*x-1.4
print("二分法求得的根为:", binary_search(f,1E-6,0,1))
print("牛顿迭代法求得的根为:",newton_iter(f,1E-6,0))
print("直接调用SciPy求得的根为:",fsolve(f,0))

 (个人比较喜欢使用Scipy库求解,比较方便)

4. 用fsolve求非线性方程组的数值解

例3.22 求下列非线性方程组的数值解

5x_{2}+3=0|4x_1^2-2sin(x_2x_3)=0|x_2x_3-1.5=0

from numpy import sin
from scipy.optimize import fsolve
f=lambda x: [5*x[1]+3, 4*x[0]**2-2*sin(x[1]*x[2]), x[1]*x[2]-1.5]#使用匿名函数,将三个方程表示出来
print("result=",fsolve(f, [1.0,1.0,1.0]))

上面的程序使用的是匿名函数,但是python下标从0开始,不太方便。下面利用函数定义方程组,使用起来更加方便一点: 

from numpy import sin
from scipy.optimize import fsolve
def Pfun(x):
    x1,x2,x3=x.tolist()  #x转换成列表
    return 5*x2+3, 4*x1**2-2*sin(x2*x3), x2*x3-1.5
print("result=",fsolve(Pfun, [1.0, 1.0, 1.0]))

 3.5.4 函数极值点的数值解

1. 一元函数极值点

例3.23 求函数 f(x)=e^xcos(2x) 在区间[0,3]上的极小点

from numpy import exp,cos
from scipy.optimize import fminbound
f=lambda x: exp(x)*cos(2*x)
x0=fminbound(f,0,3)
print("极小点为:{},极小值为:{}".format(x0,f(x0)))

例3.24 求函数 f(x)=e^xcos(2x)在0附近的一个极小点

from numpy import exp,cos
from scipy.optimize import fmin
f=lambda x: exp(x)*cos(2*x)
x0=fmin(f,0)
print("极小点为:{},极小值为:{}".format(x0,f(x0)))

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第9张图片

2. 多元函数的极值点 

例3.25 求函数 f(x)=100(x_2-x_1^2)^2+(1-x_1)^2 的极小值

from scipy.optimize import minimize
f=lambda x: 100*(x[1]-x[0]**2)**2+(1-x[0])**2; 
x0=minimize(f,[2.0, 2.0])
print("极小点为:{},极小值为:{}".format(x0.x,x0.fun))

 3.6 线性代数问题的符号解和数值解

3.6.1 线性代数问题的符号解

SymPy 线性代数模块的函数和矩阵操作都非常简单易学。它包括对矩阵的各种操作,例如,求矩阵行列式的值,特殊矩阵的构建,求矩阵的特征值、特征向量、转置和逆阵等。如利用eye,zeros和ones等函数,可以快速构造特殊矩阵。如果需要的话,可以删除矩阵中某些选中的行和列.基本算术运算,如+,一,*和**,也可以用于矩阵.
在符号矩阵运算中*表示矩阵乘积,**表示矩阵的幂运算。

1. 矩阵的运算 

基础知识:

已知 \alpha =[a_1,a_2,a_3]^{T},\beta =[b_1,b_2,b_3]^T ,则\alpha \cdot \beta =a_1b_1+a_2b_2+a_3b_3\alpha \times \beta =\begin{vmatrix} i& j &k \\ a_1& a_2 & a_3\\ b_1&b_2 & b_3 \end{vmatrix} (T为矩阵的转置)

例3.26 已知 \alpha = [1,2,3]^T,\beta =[4,5,6]^T,求 \left \| \alpha \right \|_2(向量\alpha的长度),\alpha ^T,\alpha \cdot \beta ,\alpha \times \beta 

import sympy as sp
A=sp.Matrix([[1],[2],[3]])  #列向量,即3×1矩阵
B=sp.Matrix([[4],[5],[6]])  
print("A的模为:",A.norm())
print("A的模的浮点数为:",A.norm().evalf())
print("A的转置矩阵为:",A.T)
print("A和B的点乘为:",A.dot(B))
print("A和B的叉乘为:",A.cross(B))

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第10张图片

 例3.27 已知 A=\begin{bmatrix} 1 & 2 & 3 &4 \\ 5& 6 &7 &8 \\ 9& 10 & 11 & 12\\ 13& 14 & 15 & 16 \end{bmatrix}B=\begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 &0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix},求 \left | A \right | ,A的秩R(A),A^T , (A+10E)^{-1},A^2,AB ,构造分块矩阵[A,B],\begin{bmatrix} A\\ B \end{bmatrix},A_1=\begin{bmatrix} 1 & 2\\ 5 & 6 \end{bmatrix} (提出A的 左上角子块构成的矩阵),A_2=\begin{bmatrix} 1 & 2 & 3 & 4\\ 5& 6 & 7 &8 \\ 9 & 10 & 11 & 12 \end{bmatrix} (删除A的第四行得到的矩阵)

import sympy as sp
import numpy as np
A=sp.Matrix(np.arange(1,17).reshape(4,4))
B=sp.eye(4)
print("A的行列式为:",sp.det(A))
print("A的秩为:",A.rank())
print("A的转置矩阵为:",A.transpose())  #等价于A.T
print("所求的逆阵为:",(A+10*B).inv())
print("A的平方为:",A**2)
print("A,B的乘积为:",A*B)
print("横连矩阵为:",A.row_join(B))
print("纵连矩阵为:",A.col_join(B))
print("A1为:",A[0:2,0:2])
A2=A.copy(); A2.row_del(3)
print("A2为:",A2)

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第11张图片

2. 解线性方程组 

例3.28 求下列线性方程组的符号解

\left\{\begin{matrix} 2x_1+x_2-5x_3+x_4=8\\ x_1-3x_2-6x_4=6 \\ 2x_2-x_3+2x_4=-2\\ x_1+4x_2-7x_3+6x_4=2 \end{matrix}\right.

记上述线性方程组为Ax=b,可以验证系数矩阵A的秩R(A)=4,所以线性方程组有唯一解x=A^{-1}b,求解代码如下:

import sympy as sp
A=sp.Matrix([[2, 1, -5, 1],[1, -3, 0, -6],[0, 2, -1, 2],[1, 4, -7, 6]])
b=sp.Matrix([8, 6, -2, 2]); b.transpose()
print("系数矩阵A的秩为:",A.rank())
print("线性方程组的唯一解为:",A.inv()*b)

例3.29 求下列齐次线性方程组的基础解系(齐次线性方程组:常数项全为0)

\left\{\begin{matrix} x_1-5x_2+2x_3-3x_4=0\\ 5x_1+3x_2+6x_3-x_4=0\\ 2x_1+4x_2+2x_3+x_4=0 \end{matrix}\right.

import sympy as sp
A=sp.Matrix([[1, -5, 2, -3],[5, 3, 6, -1], [2, 4, 2, 1]])
print("A的零空间(即基础解系)为:",A.nullspace())

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第12张图片

例3.30 求下列非齐次线性方程组的通解 

\left\{\begin{matrix} x_1+x_2-3x_3-x_4=1\\ 3x_1-x_2-3x_3+4x_4=4\\ x_1+5x_2-9x_3-8x_4=0 \end{matrix}\right.

求通解首先要用rref()方法把增广阵化成行最简形:

import sympy as sp
A=sp.Matrix([[1, 1, -3, -1],[3, -1, -3, 4], [1, 5, -9, -8]])
b=sp.Matrix([1, 4, 0]); b.transpose()
C=A.row_join(b)  #构造增广矩阵
print("增广阵的行最简形为:\n",C.rref())

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第13张图片

 通过上述返回值可以看出,增广阵的列向量组的最大无关组由第1列,第2列组成,对应的行最简形的列是单位坐标向量。求得的行最简形矩阵为:\begin{bmatrix} 1 & 0 &-\frac{3}{2} & \frac{3}{4} &\frac{5}{4} \\ 0 & 1& -\frac{3}{2} & -\frac{7}{4} &-\frac{1}{4} \\ 0 & 0 & 0 & 0 & 0 \end{bmatrix} ,通过行最简形可以写出原方程组的等价方程组为:

\begin{Bmatrix} x_1=\frac{3}{2}x_3-\frac{3}{4}x_4+\frac{5}{4}\\ x_2=\frac{3}{2}x_3+\frac{7}{4}x_4-\frac{1}{4} \end{Bmatrix} 所以,方程组的通解为:

\begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4 \end{bmatrix}=c_1\begin{bmatrix} \frac{3}{2}\\ \frac{3}{2}\\ 1\\ 0 \end{bmatrix}+c_2\begin{bmatrix} -\frac{3}{4}\\ \frac{7}{4}\\ 0\\ 1 \end{bmatrix}+\begin{bmatrix} \frac{5}{4}\\ -\frac{1}{4}\\ 0\\ 0 \end{bmatrix}

 3. 特征值和特征向量

例3.31 求下列矩阵的特征值和特征向量

A=\begin{bmatrix} 0 & -2 & 2\\ -2 & -3 & 4\\ 2 & 4 & -3 \end{bmatrix}

import sympy as sp
A=sp.Matrix([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
print("A的特征值为:",A.eigenvals())
print("A的特征向量为:",A.eigenvects())

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第14张图片

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第15张图片

4. 相似对角化

例3.32 把下列矩阵相似对角化,即求可逆矩阵P,使得P^{-1}AP=D 为对角阵

A=\begin{bmatrix} 0 & -2 & 2\\ -2 & -3 &4 \\ 2& 4 & -3 \end{bmatrix}

from sympy import Matrix, diag
A=Matrix([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
if A.is_diagonalizable(): print("A的对角化矩阵为:",A.diagonalize())
else: print("A不能对角化")

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第16张图片

3.6.2 线性代数问题的数值解(Numpy库)

 

 

 注意:

Numpy库中的array数组中,*和multiply运算等价,表述矩阵诸葛元素相乘,@和dot()函数表示矩阵乘法

1. 向量和矩阵的运算 

例3.33 已知 \alpha = [1,2,3]^T,\beta =[4,5,6]^T,求 \left \| \alpha \right \|_2(向量\alpha的长度),\alpha ^T,\alpha \cdot \beta ,\alpha \times \beta 

from numpy import arange, cross, inner 
from numpy.linalg import norm
a=arange(1,4); b=arange(4,7)       #创建数组
print("a的二范数为:",norm(a))
print("a点乘b=", a.dot(b))      #行向量a乘以列向量b
print("a,b的内积=",inner(a,b))  #a,b的内积,这里与dot(a,b)等价
print("a叉乘b=", cross(a,b))

 

  例3.34 已知 A=\begin{bmatrix} 1 & 2 & 3 &4 \\ 5& 6 &7 &8 \\ 9& 10 & 11 & 12\\ 13& 14 & 15 & 16 \end{bmatrix}B=\begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 &0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix},求 \left | A \right | ,A的秩R(A),A^T , (A+10E)^{-1},A^2,AB ,构造分块矩阵[A,B],\begin{bmatrix} A\\ B \end{bmatrix},A_1=\begin{bmatrix} 1 & 2\\ 5 & 6 \end{bmatrix} (提出A的 左上角子块构成的矩阵),A_2=\begin{bmatrix} 1 & 2 & 3 & 4\\ 5& 6 & 7 &8 \\ 9 & 10 & 11 & 12 \end{bmatrix} (删除A的第四行得到的矩阵)

import numpy as np
import numpy.linalg as LA
A=np.arange(1,17).reshape(4,4)
B=np.eye(4)
print("A的行列式为:", LA.det(A))
print("A的秩为:",LA.matrix_rank(A))
print("A的转置矩阵为:\n",A.transpose())  #等价于A.T
print("所求的逆阵为:\n",LA.inv(A+10*B))
print("A的平方为:\n",A.dot(A))
print("A,B的乘积为:\n",A.dot(B))
print("横连矩阵为:",np.c_[A,B])
print("纵连矩阵为:",np.r_[A,B])
print("A1为:",A[0:2,0:2])
A2=A.copy(); A2=np.delete(A2,3,axis=0)
print("A2为:",A2)

【学习笔记】第三章 Python在高等数学和线性代数中的应用_第17张图片

2. 齐次线性方程组的数值解

例3.35 求下列齐次线性方程组的基础解系(齐次线性方程组:常数项全为0)

\left\{\begin{matrix} x_1-5x_2+2x_3-3x_4=0\\ 5x_1+3x_2+6x_3-x_4=0\\ 2x_1+4x_2+2x_3+x_4=0 \end{matrix}\right.

import numpy as np
from scipy.linalg import null_space
A=np.array([[1, -5, 2, -3],[5, 3, 6, -1], [2, 4, 2, 1]])
print("A的零空间(即基础解系)为:",null_space(A))

 

所以基础解系为:

\xi _1=[-0.3546,0.4118,-0.0501,-0.8380]^T,\xi _2=[0.7151,0.0309,-0.6527,-0.2483]^T

3. 非齐次线性方程组的数值解 

(1)唯一解情形

例3.36 求下列线性方程组的符号解

\left\{\begin{matrix} 2x_1+x_2-5x_3+x_4=8\\ x_1-3x_2-6x_4=6 \\ 2x_2-x_3+2x_4=-2\\ x_1+4x_2-7x_3+6x_4=2 \end{matrix}\right.

import numpy as np
import numpy.linalg as LA
A=np.array([[2, 1, -5, 1],[1, -3, 0, -6],[0, 2, -1, 2],[1, 4, -7, 6]])
b=np.array([[8, 6, -2, 2]]); b=b.reshape(4,1)
print("系数矩阵A的秩为:",LA.matrix_rank(A))
print("线性方程组的唯一解为:",LA.inv(A).dot(b))   #使用逆矩阵
print("线性方程组的唯一解为:",LA.pinv(A).dot(b))  #使用伪逆
print("线性方程组的唯一解为:",LA.solve(A,b))  #利用solve求解

(2)多解情形

例3.37 下列非齐次线性方程组有无穷多解,求它的最小范数解

\left\{\begin{matrix} x_1+x_2-3x_3-x_4=1\\ 3x_1-x_2-3x_3+4x_4=4\\ x_1+5x_2-9x_3-8x_4=0 \end{matrix}\right.

from numpy import array
from numpy.linalg import pinv
A=array([[1, 1, -3, -1],[3, -1, -3, 4], [1, 5, -9, -8]])
b=array([1, 4, 0]); b.resize(3,1)
x=pinv(A).dot(b)  #求最小范数解
print("最小范数解为:",x)

(3)无解情况 

例3.38 求下列矛盾方程组的最小二乘解

\left\{\begin{matrix} x_1+x_2=1\\ 2x_1+2x_2=3\\ x_1+2x_2=2 \end{matrix}\right.

from numpy import array
from numpy.linalg import pinv
A=array([[1, 1],[2, 2], [1, 2]])
b=array([1, 3, 2]); b.resize(3,1)
x=pinv(A).dot(b)  #求最小二乘解
print("最小二乘解为:",x)

(4)特征值与特征向量

例3.39 求下列矩阵的特征值和特征向量

A=\begin{bmatrix} 0 & -2 & 2\\ -2 & -3 & 4\\ 2 & 4 & -3 \end{bmatrix}

import numpy as np
from numpy.linalg import eig
A=np.array([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
values, vectors=eig(A)
print("A的特征值为:",values)
print("A的特征向量为:",vectors)

 例3.40 对于矩阵A=\begin{bmatrix} 0 & -2 & 2\\ -2 & -3 & 4\\ 2& 4 & -3 \end{bmatrix},P=\begin{bmatrix} 0.9428 &-0.3333 &-0.4254 \\ -0.2357 & -0.6667 &0.7454 \\ 0.2357 & 0.6667 &0.5247 \end{bmatrix},\Lambda =\begin{bmatrix} 1 & 0 &0 \\ 0 & -8 &0 \\ 0 & 0 & 1 \end{bmatrix} ,验证P^{-1}AP=\Lambda

from numpy import array, dot
from numpy.linalg import eig,inv
A=array([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
values, vectors=eig(A)
check=dot(inv(vectors),A).dot(vectors)
print("check=\n", check)

3.6.3 求超定线性方程组的最小二乘解

 例3.41 求超定线性方程组\begin{bmatrix} 0 & 1\\ 1& 1\\ 2 &1 \\ 3 & 1 \end{bmatrix}\begin{bmatrix} m\\ c \end{bmatrix}=\begin{bmatrix} -1\\ 0.2\\ 0.9\\ 2.1 \end{bmatrix}的最小二乘解,相当于给定x的观测值 x=[0,1,2,3]^T,y的观测值y=[-1,0.2,0.9,2.1]^T,拟合经验函数y=mx+c

import numpy as np
import numpy.linalg as LA
from matplotlib.pyplot import plot, rc, legend, show, savefig
x = np.array([0, 1, 2, 3])
y = np.array([-1, 0.2, 0.9, 2.1])
A = np.c_[x, np.ones_like(x)]
m, c = LA.lstsq(A, y, rcond=None)[0]
print(m,c); rc('font',size=16)
plot(x, y, 'o', label='原始数据', markersize=5)
plot(x, m*x + c, 'r', label='拟合直线')
rc('font',family='SimHei') #用来正常显示中文标签
rc('axes',unicode_minus=False) #用来正常显示负号
legend(); savefig("figure3_41.png",dpi=500); show()

求得的最小二乘解为m=1,c=-0.95 

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第18张图片

例3.42  为了测量刀具的磨损速度,做这样的实验:经过一定时间(如每隔一小时),测量一次刀具的厚度,得到一组实验数据 (t_i,y_i)(i = 1,2,… ,8)如表3.3所示.试用实验数据拟合经验公式y = at+b. 

import numpy as np
import numpy.linalg as LA
import matplotlib.pyplot as plt
t = np.arange(8)
y=np.array([27.0,26.8,26.5,26.3,26.1,25.7,25.3,24.8]) 
A = np.c_[t, np.ones_like(t)]
ab = LA.lstsq(A, y, rcond=None)[0]  #返回值为向量
print(ab); plt.rc('font',size=16)
plt.plot(t, y, 'o', label='Original data', markersize=5)
plt.plot(t, A.dot(ab), 'r', label='Fitted line')
plt.legend(); plt.savefig("figure3_42.png",dpi=500); plt.show()

a=-0.3036  b=27.125

 【学习笔记】第三章 Python在高等数学和线性代数中的应用_第19张图片

你可能感兴趣的:(司守奎老师,python数学建模,python,线性代数,开发语言)