multi array vectorization problem (reformulated)
Show older comments
How to vectorize (for-loop elimination) the following code?
% init
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:0.01:1e2;
% eigen space
[V,D]=eig(A,'vector');
D = reshape(D,1,[]);
% computing
expmAt = zeros([size(A),length(t)]);
for i = 1:length(t)
expmAt(:,:,i) = V.*(exp(D*t(i)))/V;
end
8 Comments
Jan
on 18 May 2022
Which code do you want to accelerate? What are typical inputs? Das "many" mean 25 or 10e6 ?
Matt J
on 18 May 2022
Is A positive definite? How do you know V is non-singular?
Matt J
on 18 May 2022
But not symmetric?
Michal
on 18 May 2022
Jan
on 18 May 2022
(V.*exp(D*t))/V, Typical size of V is ~ 3 x 3, Typical size of D.*t' is ~ (1e4 x 3)
I'm confused. Does "D.*t' is [1e4 x 3]" mean, that D*t is [3 x 1e4] ? Why is it .* in one case and * in the other?
The best idea is to provide Matlab code, which creates the typical input data. This avoids ambiguities.
Accepted Answer
More Answers (2)
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:3;
% eigen space
[V,D]=eig(A,'vector');
D = reshape(D,1,[]);
% computing
expmAt = zeros([size(A),length(t)]);
for i = 1:length(t)
expmAt(:,:,i) = V.*(exp(D*t(i)))/V;
end
expmAt
expmAt2 = pagemrdivide(V.*exp(D.*reshape(t,1,1,[])),V)
5 Comments
How much it accelerates? Result on TMW online server:
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:0.01:1e2;
% eigen space
[V,D]=eig(A,'vector');
D = reshape(D,1,[]);
% computing
tic
expmAt = zeros([size(A),length(t)]);
for i = 1:length(t)
expmAt(:,:,i) = V.*(exp(D*t(i)))/V;
end
toc
tic
expmAt2 = pagemrdivide(V.*exp(D.*reshape(t,1,1,[])),V);
toc
Bruno Luong
on 19 May 2022
Only one pagemtimes is enough. Also never use squeeze if you want a predictable code.
expmAtb2 = reshape(pagemtimes(V.*exp(D.*reshape(t,1,1,[])) ,V\b),[size(V,1),length(t)]);
Bruno Luong
on 19 May 2022
Edited: Bruno Luong
on 19 May 2022
"In a case of further generalization"
That's why one should not ask too simplified question at the first place.
The best solution always depends on the detail/size of the problem, and the MATLAB version one is using.
% init
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:0.01:1e2;
tic;
% eigen space
[V,D]=eig(A,'vector');
D = reshape(D,1,[]);
% computing
expmAt = zeros([size(A),length(t)]);
for i = 1:length(t)
expmAt(:,:,i) = V.*(exp(D*t(i)))/V;
end
toc
tic
out=theTask(A,t);
toc
[lb,ub]=bounds(expmAt-out,'all')
function expmAt=theTask(A,t)
[V,d]=eig(A,'vector');
E=exp(d*t);
expmAt=repmat(eye(size(A)),1,1,numel(t));
expmAt(logical(expmAt))=E(:);
expmAt=pagemtimes( pagemtimes(V,expmAt), inv(V));
end
3 Comments
In a case of further generalization ...is the following code the "optimal" solution?
No. It wasn't optimal before the generalization either -
% init
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:0.01:1e2;
b = [2;3];
tic;
% eigen space
[V,D]=eig(A,'vector');
D = reshape(D,1,[]);
% computing
expmAtb2 = squeeze(pagemtimes(pagemrdivide(V.*exp(D.*reshape(t,1,1,[])),V),b));
toc
tic
expmAtb3=theTask(A,t,b);
toc
[lb,ub]=bounds(expmAtb2(:)-expmAtb3(:),'all')
function expmAt=theTask(A,t,b)
[V,d]=eig(A,'vector');
E=exp(d*t);
expmAt=repmat(eye(size(A)),1,1,numel(t));
expmAt(logical(expmAt))=E(:);
expmAt=pagemtimes( pagemtimes(V,expmAt), V\b);
end
Michal
on 19 May 2022
Matt J
on 19 May 2022
I wouldn't expect the addition of squeeze() to impact timing significantly.
Also, I find it strange that pagemrdivide(A,B) is not optimized for the case where B has only one page.
Categories
Find more on Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!