How to speed up this for loop containing kronecker product?

11 ビュー (過去 30 日間)
DS L
DS L 2021 年 4 月 8 日
コメント済み: DS L 2021 年 4 月 9 日
I want to speed up the following for loop.
% x is n by N. S is k by N and nonnegative.
% Use random matrices for testing.
% Elapsed time of the following code is around 19 seconds.
% So, when N is large, it's very slow.
n= 800; N =100; k =10;
x = rand(n,N); S = rand(k,N); H = 0;
for i = 1: size(x,2)
X = x(:,i)*x(:,i)' ;
DW = diag( S(:,i) ) - S(:,i)*S(:,i)' ;
H = H + kron(X,DW);
end
My attempt:
kron(X, DW) = kron(x(:,i)*x(:,i)' ,diag(S(:,i))) - kron(x(:,i)*x(:,i)', S(:,i)*S(:,i)');
We can use and to rewrite the above equation.
kron(x(:,i)*x(:,i)',diag(S(:,i))) = kron(x(:,i), sqrt( diag(S(:,i))))* kron(x(:,i)*x(:,i)',diag(S(:,i)))' ; (since S is nonnegative then we can take sqrt )
kron(x(:,i)*x(:,i)', S(:,i)*S(:,i)') = kron( x(:,i), S(:,i))*kron( x(:,i), S(:,i))'.
Therefore, we only need to compute kron(x(:,i), sqrt( diag(S(:,i)))) and kron(x(:,i), S(:,i)).
Here are the codes:
n = 800; N = 100; k = 10;
x = rand(n,N); S = rand(k,N);
H1= 0; K_D= zeros(n*k, k*1, N); K_S = zeros(n*k,N);
%K_D records kron( x(:,i), sqrt (diag(S(:,i)) ) ) ,
% K_S records kron(x(:,i), S(:,i));
for i = 1:N
D_half = sqrt( diag(S(:,i)));
K_D(:,:,i) = kron( x(:,i),D_half);
K_S(:,i) = reshape (S(:,i)*x(:,i)',[],1);
end
K_D = reshape(K_D,n*k,[]);
H = K_D*K_D' - K_S*K_S';
The new codes save much time. Elapsed time is around 1 second. But I still want to speed up it.
Can someone help me speed up the above code (my attempt)? Or do someone have a new idea/method to speed up my original problem?
Thank you very much!

回答 (2 件)

Jan
Jan 2021 年 4 月 8 日
I get a measureable speedup with reducing the number of sqrt() calls:
% Replace
D_half = sqrt( diag(S(:,i)));
% by
D_half = diag(sqrt(S(:, i)));
  5 件のコメント
Jan
Jan 2021 年 4 月 9 日
I assume, this is a missunderstanding. I did not get significant improvements compared with your last version including the SQRT reordering:
n = 800;
N = 100;
k = 10;
x = rand(n,N);
S = rand(k,N);
K_D = zeros(n*k, k*1, N);
K_S = zeros(n*k, N);
for i = 1:N
D_half = diag(sqrt(S(:,i)));
K_D(:, :, i) = kron(x(:,i), D_half);
K_S(:, i) = reshape(S(:, i) * x(:, i).', [], 1);
end
K_D = reshape(K_D, n*k, []);
H = K_D * K_D' - K_S * K_S'; % <- Bottleneck
Replacing kron() by an inlined version or a BSXFUN appraoch does not change the speed sufficiently. It should be possible to squeeze some time here, because D_half is almost empty. But the bottleneck is in the last line.
DS L
DS L 2021 年 4 月 9 日
Yes. I use this line
H = K_D * K_D' - K_S * K_S';
to replace the following sum. The sum is much slower.
for i = 1:N
DW = diag(S(:,i)) - S(:,i)*S(:,i)';
H = H + kron(x(:,i)*x(:,i)',DW);
end

サインインしてコメントする。


Bruno Luong
Bruno Luong 2021 年 4 月 9 日
編集済み: Bruno Luong 2021 年 4 月 9 日
Yesterday I profile your code and the majority of time is eaten by
H = K_D*K_D' - K_S*K_S';
not by Kronecker.
The question is what is your intention of using H? If it can reduce to (matrix-vector) product (including some EIG,SVD algorithms), then you should leave the low rank decomposition (K_D/K_S), rather than storing explicitly H.
Just like using BFGS formula, no one stores the matrix B, they rather store a sequence of vectors (y,s).
Similarly, most of the time Kroneker matrix can be avoid to group the state vectors, rather using linear operators.
  5 件のコメント
Bruno Luong
Bruno Luong 2021 年 4 月 9 日
編集済み: Bruno Luong 2021 年 4 月 9 日
Your H has rank < size(H) so there exists no inverse.
For newton method you perhaps need to compute
-pinv(H)*g
meaning solving
H*y = g
projected on the image of H. You do not need to compute H, you can use the projection or in some iterative methode you only required to evaluate H*v.
Just wonder if you are aware of quasi-Newton method, BFGS formula and limited memory variant of such formula.
Those are intensively studied and well known, why reinvent the wheel?
DS L
DS L 2021 年 4 月 9 日
Thank you. The Hessian is nonsingular because H is not the "final Hessian" and the approximation is SPD.
Because I want to try something new.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeBoundary Conditions についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by