simply I want to partition a n*n positive definite matrix into an identical n*r matrix B where r is arbitrary, in the other word:

B*B^T=A
(n*r)*(n*r)^T=(n*n)

Edit: I think it was my fault ill-describing my problem. let B be a matrix with dimension (n*r). give it to a function A=f(B^T*B) where A is (n*n). I know that this function will keep the rank of matrix, in the other word rank(A)=rank(B'*B). now i want to extract new B. so the new B has (n*r) again.

有帮助吗?

解决方案

Suppose that you have the following example:

n = 4;
rng(0)
A = rand(n,n);
B = A * A';

If the matrix B is full rank, you can not exactly cover the original matrix using fewer dimensions. So, you can only approximate it. The key idea here is to minimize the reconstruction error.

You can decompose B into its eigenvectors using eigenvalue decomposition. You can use eig in MATLAB, but you need to sort the eigenvalues and corresponding eigenvectors afterwards. Instead, I prefer Singular Value Decomposition and use svd in MATLAB. Note that SVD gives the optimal solution for the reconstruction error in low-rank matrix approximation.

[U,S,~] = svd(B);
U = U * sqrt(S);

We know that B = U * U' now. See relation between SVD and eigenvalue decomposition here.

As I stated, we need to approximate it. I choose the dimensions covering 99% of the total variance as follows:

coverage =  cumsum(diag(S.^2));
coverage = coverage ./ norm(S,'fro')^2;
[~, nEig] = max(coverage > 0.99);
U2 = U(:,1:nEig);

U2 has 2 columns instead of 4 in this case. If the data is correlated, the gain will be even less. The results are as follows:

B
B1 = U*U'
B2 = U2*U2'

B =

    2.8966    2.1881    1.1965    2.1551
    2.1881    1.9966    0.6827    1.8861
    1.1965    0.6827    0.7590    0.5348
    2.1551    1.8861    0.5348    2.0955


B1 =

    2.8966    2.1881    1.1965    2.1551
    2.1881    1.9966    0.6827    1.8861
    1.1965    0.6827    0.7590    0.5348
    2.1551    1.8861    0.5348    2.0955


B2 =

    2.8896    2.2134    1.1966    2.1385
    2.2134    1.9018    0.6836    1.9495
    1.1966    0.6836    0.7586    0.5339
    2.1385    1.9495    0.5339    2.0528

That seems to be a good approximation.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top