可记作A = L L*。其中A是正定矩阵。L是下三角矩阵。L*是L的共轭转置矩阵。(共轭不记得啥意思了。)
举例来说:
那么我们需要求得的L是:
通过wiki查到了计算公式及其推导。非常简单。
以A为[3,3]大小的矩阵为例。
上面这个Li,j其实很简单,比如i=3,j=1的时候式子就是: L(3,1) = ((A(3,1) - 0) / L(1,1)。其它的类似
计算顺序是先求左上角的那个L11,然后利用L11的值顺序得求出下面一行行的数值。
测试代码如下。测试的矩阵就是上面例子中的矩阵。代码利用了OpenCV
#include "stdio.h" #include <opencv2/opencv.hpp> using namespace std; using namespace cv; static void cholesky_decomposition( const Mat& A, Mat& L ) { L = Mat::zeros( A.size(), CV_32F ); int rows = A.rows; for( int i = 0; i < rows; ++i ) { int j; float sum; for(j=0; j < i; ++j)//只求下三角 (i>j) { sum = 0; for(int k=0; k<j; ++k) { sum += L.at<float>(i,k) * L.at<float>(j,k); } L.at<float>(i,j) = (A.at<float>(i,j) - sum) / L.at<float>(j,j); } sum = 0; assert(i == j); for (int k=0; k<j; ++k)//i == j { sum += L.at<float>(j,k) * L.at<float>(j,k); } L.at<float>(j,j) = sqrt(A.at<float>(j,j) - sum); } } void print_mat(Mat &m) { float sum = 0.; for(int r=0; r<m.rows; r++) { for(int c=0; c<m.cols; c++) { printf("%.2lf ", m.at<float>(r,c)); sum += m.at<float>(r,c); } printf("\n"); } printf("\n"); } int main(int argc, char* argv[]) { float f[4][4] = { {16., 4., 4., -4.}, {4., 10., 4., 2.}, {4., 4., 6., -2.}, {-4., 2., -2., 4.}, }; Mat A; A = Mat(4,4,CV_32F, f); printf("Matrix A = \n"); print_mat(A); Mat L; cholesky_decomposition(A, L); printf("After cholesky decomposition, L = \n"); print_mat(L); Mat p; p = L * L.t(); printf("Confirm: L * L_t = \n"); print_mat(p); return 0; }