UKF-协方差矩阵分解
在SUT变化中,需要对协方差矩阵进行分解。而matlab自带的chol函数只能分解正定矩阵。为保证求解不被中断,并能提示协方差矩阵的正定、半正定以及负定情况,对常规的Cholesky简单修改。一、Cholesky分解原理
=
[
a
11
a
21
a
31
a
21
a
22
a
23
a
31
a
32
a
33
]
=
(
l
11
0
0
l
21
l
22
0
l
31
l
32
l
33
)
(
l
11
l
21
l
31
0
l
22
l
32
0
0
l
33
)
=
L
L
T
=
(
l
11
2
l
21
l
11
l
31
l
11
l
21
l
11
l
21
2
+
l
22
2
l
31
l
21
+
l
32
l
22
l
31
l
11
l
31
l
21
+
l
32
l
22
l
31
2
+
l
32
2
+
l
33
2
)
\begin{aligned} &=\begin {bmatrix} a_{11} & a_{21} & a_{31} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \\ &= \begin{pmatrix} l_{11} & 0 & 0 \\ l_{21} & l_{22} & 0 \\ l_{31} & l_{32} & l_{33} \end{pmatrix}\begin{pmatrix}l_{11} & l_{21} & l_{31} \\ 0 & l_{22} &l_{32} \\ 0 & 0 & l_{33} \end{pmatrix}=LL^T\\ &=\begin{pmatrix}l^2_{11} & l_{21}l_{11} & l_{31}l_{11} \\ l_{21}l_{11} & l^2_{21}+l^2_{22} & l_{31}l_{21}+l_{32}l_{22} \\ l_{31}l_{11} & l_{31}l_{21} + l_{32}l_{22} & l^2_{31}+l^2_{32}+l^2_{33}\end{pmatrix} \end{aligned}
=⎣⎡a11a21a31a21a22a32a31a23a33⎦⎤=⎝⎛l11l21l310l22l3200l33⎠⎞⎝⎛l1100l21l220l31l32l33⎠⎞=LLT=⎝⎛l112l21l11l31l11l21l11l212+l222l31l21+l32l22l31l11l31l21+l32l22l312+l322+l332⎠⎞
矩阵
L
L
L 对角线上元素计算有如下规律:
l
11
=
a
11
l
22
=
a
22
−
l
21
2
l
33
=
a
33
−
(
l
31
2
+
l
32
2
)
\begin{aligned} l_{11} &= \sqrt{a_{11}} \\ l_{22} &= \sqrt{a_{22}-l^2_{21}} \\ l_{33} &= \sqrt{a_{33}-(l^2_{31}+l^2_{32})} \end{aligned}
l11l22l33=a11=a22−l212=a33−(l312+l322)
一般规律:
l
j
j
=
a
j
j
−
∑
k
=
1
j
−
1
l
j
k
2
l_{jj} = \sqrt{a_{jj}-\sum\limits_{k=1}^{j-1}l^2_{jk}}
ljj=ajj−k=1∑j−1ljk2
对于非对角线元素
l
i
j
l_{ij}
lij,其中
i
>
j
i>j
i>j 计算规律如下:
l
21
=
1
l
11
a
21
l
31
=
1
l
11
a
31
l
32
=
1
l
22
(
a
22
−
l
31
l
21
)
\begin{aligned} l_{21} &= \dfrac{1}{l_{11}}a_{21}\\ l_{31} &= \dfrac{1}{l_{11}}a_{31}\\ l_{32} &=\dfrac{1}{l_{22}}(a_{22}-{l_{31}l_{21}}) \end{aligned}
l21l31l32=l111a21=l111a31=l221(a22−l31l21)
一般规律:
l
i
j
=
1
l
j
j
(
a
i
j
−
∑
k
=
1
j
−
1
l
i
k
l
j
k
)
l_{ij}=\dfrac{1}{l_{jj}}\left(a_{ij}-\sum\limits_{k=1}^{j-1}l_{ik}l_{jk}\right)
lij=ljj1(aij−k=1∑j−1likljk)
二、代码如下(示例):
function [L,flag] = utchol(M)
L = zeros(size(M));
flag = 1;
for i = 1:size(M,1)
for j = 1:i
s = M(i,j);
for k = 1:j-1
s = s - L(i,k)*L(j,k);
end
if j < i
if L(j,j) > eps
L(i,j) = s / L(j,j);
else
L(i,j) = 0;
end
else
if (s < - eps)
s = 0;
flag = -1;
elseif (s < eps)
s = 0;
flag = min(0,flag);
end
L(j,j) = sqrt(s);
end
end
end
if (nargout < 2) && (flag < 0)
warning('Matrix is negative flaginite')
end
end
三、参考博客
参考博客
[1]: https://baimafujinji.blog.csdn.net/article/details/6512460
[2]: https://blog.csdn.net/billbliss/article/details/78559387