I want to speed up the following for loop.
% 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:
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!