multi array vectorization problem (reformulated)

2 ビュー (過去 30 日間)
Michal
Michal 2022 年 5 月 18 日
編集済み: Michal 2022 年 5 月 19 日
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 件のコメント
Jan
Jan 2022 年 5 月 18 日
(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.
Michal
Michal 2022 年 5 月 19 日
編集済み: Michal 2022 年 5 月 19 日
@Jan I just completely reformulated my question ...

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

採用された回答

Matt J
Matt J 2022 年 5 月 19 日
編集済み: Matt J 2022 年 5 月 19 日
runtest(1e2)
Elapsed time is 0.002075 seconds. Elapsed time is 0.000805 seconds.
function runtest(N)
A = [ -0.8013 -0.4981; -0.2278 -0.9009];
t = 0:0.01:N;
b = [2;3];
[V,d]=eig(A,'vector');
tic;
E=exp(d*t);
expmAtb=repmat(eye(size(V)),1,1,numel(t));
expmAtb(logical(expmAtb))=E(:);
expmAtb3=squeeze(pagemtimes( pagemtimes(V,expmAtb), V\b));
toc
tic;
expmAtb4=V*(exp(d*t).*(V\b));
toc
end
  1 件のコメント
Michal
Michal 2022 年 5 月 19 日
編集済み: Michal 2022 年 5 月 19 日
expmAtb4=V*(exp(d*t).*(V\b));
Simple, nice and fast!

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

その他の回答 (2 件)

Bruno Luong
Bruno Luong 2022 年 5 月 19 日
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
expmAt =
expmAt(:,:,1) = 1 0 0 1 expmAt(:,:,2) = 0.4736 -0.2168 -0.0991 0.4303 expmAt(:,:,3) = 0.2458 -0.1960 -0.0896 0.2066 expmAt(:,:,4) = 0.1358 -0.1376 -0.0629 0.1083
expmAt2 = pagemrdivide(V.*exp(D.*reshape(t,1,1,[])),V)
expmAt2 =
expmAt2(:,:,1) = 1 0 0 1 expmAt2(:,:,2) = 0.4736 -0.2168 -0.0991 0.4303 expmAt2(:,:,3) = 0.2458 -0.1960 -0.0896 0.2066 expmAt2(:,:,4) = 0.1358 -0.1376 -0.0629 0.1083
  5 件のコメント
Bruno Luong
Bruno Luong 2022 年 5 月 19 日
編集済み: Bruno Luong 2022 年 5 月 19 日
"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.
Michal
Michal 2022 年 5 月 19 日
編集済み: Michal 2022 年 5 月 19 日
@Bruno Luong I am sorry, you are obviously right. Thanks for help. Your final solution is good!

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


Catalytic
Catalytic 2022 年 5 月 19 日
編集済み: Catalytic 2022 年 5 月 19 日
% 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
Elapsed time is 0.057550 seconds.
tic
out=theTask(A,t);
toc
Elapsed time is 0.007411 seconds.
[lb,ub]=bounds(expmAt-out,'all')
lb = -1.3878e-16
ub = 1.1102e-16
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 件のコメント
Michal
Michal 2022 年 5 月 19 日
Your result array expmAtb3 has the size (2,1,length(t)) so you need to add squeeze command:
expmAt=squeeze(pagemtimes( pagemtimes(V,expmAtb__), V\b));
Matt J
Matt J 2022 年 5 月 19 日
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.

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

カテゴリ

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

タグ

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by