MATLAB Answers

decrease calculation accuracy to speed up running time

5 ビュー (過去 30 日間)
f4r3in
f4r3in 2019 年 11 月 12 日
Commented: f4r3in 2019 年 11 月 12 日
hi, I want to write script but I have huge input and I know if I run this script I have to wait long time to get output.
so I want from MATLAB to calculate all data with medium accuracy to speed up my program.
for example MATLAB calculate pi to 32 digits and I want to calculate it for example only to 10 digits to speed up in calculation.
look! I dont want to display a number with low digits by "format" command.
so , what should I do to decrease calculation accuracy ???

  4 件のコメント

表示 1 件の古いコメント
f4r3in
f4r3in 2019 年 11 月 12 日
here it is my code. I point where the most time waste.
clc
clear;
tic;
Input = [ 5 12 0.02
4 20 0.1
6 50 0.01
4 76 0.02
3 100 0.04
4 155 0.04
3 197 0.05
1 350 0.08
2 400 0.12];
n=Input(:,1);
cap=Input(:,2);
FOR=Input(:,3);
d=10^(-10);
Prob=zeros;
for i=1:size(cap,1)
for j=0:n(i)
Prob(i,1)=cap(i);
Prob(i,j+2)=nchoosek(n(i),j)*((FOR(i))^j)*((1-FOR(i))^(n(i)-j));
end
end
all_in=prod(Prob(:,2));
COPT_c1(1,1)=0;
COPT_c2(1,1)=all_in;
l=2;
for i=1:n(1)
temp=(all_in/Prob(1,2))*Prob(1,i+2);
if temp>d
COPT_c1(l,1) = cap(1)*i;
COPT_c2(l,1) = temp;
l=l+1;
end
end
l=size(COPT_c1,1)+1;
m=size(COPT_c2,1);
for i=2:size(cap,1)
a=size(COPT_c1,1);
for j=1:n(i)
temp=(all_in/Prob(i,2))*Prob(i,j+2);
if temp>d
COPT_c1(l,1)=cap(i)*j;
COPT_c2(l,1)=temp;
m=l;
l=l+1;
end
for k=2:a
temp=COPT_c2(m,1)*COPT_c2(k,1)/all_in;
if temp>d
COPT_c1(l,1)=COPT_c1(m,1) + COPT_c1(k,1);
COPT_c2(l,1)=temp;
l=l+1;
end
end
end
end
COPT = [COPT_c1 COPT_c2];
COPT=sortrows(COPT);
%most time waste here
u=1;
while u<=size(COPT,1)-1
if COPT(u,1)==COPT(u+1,1)
COPT(u,2)= COPT(u,2)+COPT(u+1,2);
COPT(u+1,:)=[];
u=u-1;
end
u=u+1;
end
toc;
Would you please improve my code to run faster?
Daniel M
Daniel M 2019 年 11 月 12 日
This takes 0.5 seconds on my system. How long does it take for you and what are your requirements?
f4r3in
f4r3in 2019 年 11 月 12 日
oh sorry I forgot to put large scale Input.
here it is large scale input :
Input = [ 20 120 0.02
30 160 0.1
20 250 0.01
8 320 0.02
6 450 0.04
10 480 0.04
30 185 0.05
10 350 0.08
1 1020 0.1];

サインイン to comment.

採用された回答

Daniel M
Daniel M 2019 年 11 月 12 日
編集済み: Daniel M 2019 年 11 月 12 日
The reason your algorithm is taking so much time is because of the line
COPT(u+1,:)=[];
What happens when you delete an entry to an array is MATLAB has to create an entirely new array in memory. Since you are deleting tens of thousands of entries, you are creating tens of thousands of arrays. The improved way to perform this loop is to simply mark an entry for deletion within the loop, and then delete all the invalid rows in one fell swoop outside the loop.
There may even be a way to vectorize this operation, but I think the following loop method is sufficient and, importantly, instructive. Replace the while loop at the bottom with the following
u = 1;
tbd = false(length(COPT),1); % "to be deleted"
while u <= size(COPT,1)-1
s = 1; % this is the "next" spot
while u+s <= size(COPT,1) && COPT(u,1) == COPT(u+s,1)
COPT(u,2) = COPT(u,2) + COPT(u+s,2);
tbd(u + s) = true; % mark this spot for deletion later
% increment s, and check again until it no longer equals
s = s + 1;
end
u = u + s; % increment u
end
% delete invalid entries in COPT
COPT(tbd,:) = [];
Now even with the large scale input, this takes 0.6 seconds to run on my machine, whereas before it was 10 minutes before I stopped execution (and it was only on iteration 476 out of 451817).
I also ran it on a small scale and ensured that the two algorithms produced the same result.

  1 件のコメント

f4r3in
f4r3in 2019 年 11 月 12 日
thanks a lot.
it is a perfect way that I learn form you today.
thank you again.

サインイン to comment.

More Answers (1)

John D'Errico
John D'Errico 2019 年 11 月 12 日
編集済み: John D'Errico 2019 年 11 月 12 日
You essentially cannot do what you want, with one small caveat. That is, you canot arbitrarily tell MATLAB to do all computations using say 10 digits of precision.
MATLAB works using doubles, for the most part. However, you can use reduced precision, such as single, uint8, int8. For some computations, these lower precision numeric classes will be faster. So you can specify that a variable has that specific class. You cannot tell MATLAB that from now on, ALL computaitons will be done using single precision or int8..
What you would need to do is make sure that all variables that you create are SINGLEs, so roughly 8 significant digits in floating point arithmetic. Most computations support singles (although I cannot claim that ALL computations will work there. There is always an exception, so it seems.) Once that is done, then you will find things work somewhat faster. And since you claim this is a large problem, it will take half as much memory, so that in itself may make your code run more quickly.
However, I would point out that not all computations can be done well in lower precision. It is easy to write poor code that will fail in any precision. Good use of numerical methods is important. In fact, if you look at Cleve Moler's blogs, you will see he has talked about very low precision floating point arithmetic. But the difference is Cleve also knows when what he is doing will fail in low precision, and he knows what signs to look for when it would/did fail. Anyway, if you are asking these questions, that means you are not Cleve.
So you CAN use singles, or perhaps int8 arithmetic, if you are using integers.
D = rand(4000);
S = single(D);
timeit(@() qr(D))
ans =
0.36242
timeit(@() qr(S))
ans =
0.16466
You can gain some speed, as you can see. Knowing what you are doing will be highly important though.

  0 件のコメント

サインイン to comment.

サインイン してこの質問に回答します。


Translated by