How to speed up this for loop containing kronecker product?

조회 수: 13 (최근 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 CenterFile Exchange에서 Boundary Conditions에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by