数模竞赛-线性代数模型

特征值&特征向量

差分方程-Fibonacci数列

化为一阶差分方程组:

{Fk+1=Fk+1,Fk+2=Fk+1+Fk,k=0,1,2,

写成矩阵形式:

αk+1=Aαk

其中:

A=[0111],αk=[FkFk+1],α0=[11]

由递推式得:

αk=Akα0,k=1,2,3,

设特征值为λ1,λ2,矩阵P为特征向量矩阵,即:

Ak=P[λ1k00λ2k]P1

则:

ak=Ak[11]

代码:

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import sympy
sympy.var('k',positive=True,integer=True)
a=sympy.Matrix([[0,1],[1,1]])
val=a.eigenvals() #求特征值 无用
vec=a.eigenvects() #求特征向量 无用
P,D=a.diagonalize() #相似对角化
ak=P@(D**k)@(P.inv())
F=ak@sympy.Matrix([1,1])
s=sympy.simplify(F[0])
print(s) #输出递推式
sm=[]
for i in range(20):
sm.append(s.subs(k,i).n())
print(sm)

求特征根:

|λEA|=λ2λ1

俩根互异,特征根可知,通解为:

Fk=c1λ1k+c2λ2k

c1,c2,即:

{c1+c2=1,c1λ1+c2λ2=1

代码:

python
1
2
3
4
5
6
7
import sympy
sympy.var('t c1 c2')
t0=sympy.solve(t**2-t-1)
eq1=c1+c2-1
eq2=c1*t0[0]+c2*t0[1]-1
s=sympy.solve([eq1,eq2])
print(s[c1],s[c2])

或者直接尝试求解通项公式:

python
1
2
3
4
5
6
import sympy
sympy.var('k')
y=sympy.Function('y')
f=y(k+2)-y(k+1)-y(k)
s=sympy.rsolve(f,y(k),{y(0):1,y(1):1})
print(s)

Leslie种群模型

在某动物种群中,仅考查雌性动物的年龄和数量,设雌性动物的最大生存年龄为L,把[0,L]等分为n个年龄组:

[0,Ln),[Ln,2Ln),,[n1nL,L]

设第i个年龄组的生育率为ai,存活率为bi,记xi0t=0时第i个年龄组雌性动物的数量,得到初始时刻种群数量分布向量:

x(0)=[x1(0),x2(0),,xn(0)]T

则第1个年龄组为:

x1(k)=i=1naixi(k1)

其他年龄组则生存率:

xi+1(k)=bixi(k1)

记Leslie矩阵:

L=[a1a2an1anb10000b20000bn10]

一般有x(k)=Lx(k1)=Lkx(0)

例题:某动物雌性最大年龄为15年,5年为一间隔,分成3个年龄组,已知a1=0,a2=4,a3=3,b1=0.5,b2=0.25,在t=0时雌性动物数量为500,1000,500

即:

x(0)=[500,1000,500]T,L=[0430.50000.250]

于是有x(i)=Lx(i1),求特征值λEL∣=0λ1,λ2,λ3,对应特征向量为α1,α2,α3,记矩阵P=[α1,α2,α3],Λ=diag(λ1,λ2,λ3),则L=PΛP1,于是有x(k)=Lkx(0),即

1λ1kx(k)=P[1000(λ2λ1)k000(λ3λ1)k]

|λ2λ1|<1,|λ3λ1|<1,有:

limk1λ1k=Pdiag(1,0,0)P1x(0)

于是当k充分大,近似成立:

x(k)=225019(32)k[1861]

其中c=225019为列向量P1x(0)的第一个元素。

代码:

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy,sympy
X0=numpy.array([500,1000,500])
L=numpy.array([[0,4,3],[0.5,0,0],[0,0.25,0]])
X1=L@X0
X2=L@X1
X3=L@X2
Ls=sympy.Matrix([[0,4,3],[sympy.Rational(1,2),0,0],[0,sympy.Rational(1,4),0]])
sympy.var('lmbda')
p=Ls.charpoly(lmbda) #计算特征多项式
w1=sympy.roots(p) #计算特征值
w2=Ls.eigenvals() #直接计算特征值
v=Ls.eigenvects() #特征向量
print(w2,v)
P,D=Ls.diagonalize() #相似对角化
Pinv=P.inv()
Pinv=sympy.simplify(Pinv)
cc=Pinv@X0
print(P,cc[0])

奇异值分解

A=(aij)m×n,rank(A)=r,存在正交矩阵U,V,使得:

UTAV=[Σ000]

其中Σ=diagσ1,σ2,,σr,σ1σ2σr>0,且σ12,σ22,,σr2为矩阵ATA的正特征值。

称下式为A的奇异值分解,σi,i=1,2,,rA的奇异值。

A=U[Σ000]VT

矩阵的F范数定义为:

AF2=tr(ATA)=i=1mj=1naij2=i=1rσi2

例题1:

求矩阵A的奇异值分解。

A=[101011000]

代码:

python
1
2
3
4
import numpy
a=numpy.array([[1,0,1],[0,1,1],[0,0,0]])
u,s,vt=numpy.linalg.svd(a) #即a=u@numpy.diag(s)@vt
print(u,s,vt)