4 nested for loops -- how to shorten computing time

2 ビュー (過去 30 日間)
Andrew Logan
Andrew Logan 2020 年 6 月 19 日
回答済み: Karthik Malisetty 2020 年 6 月 19 日
I would like my Matlab to process the following code. Unfortunately, it has been running for about 10 hours now and still hasn't returned a solution. Would someone please provide any feedback on bottlenecks or other solutions to shorten computing time?
The problem I am trying to solve is this:
-I have a system with 3 more unknowns than equations
-To solve the system, I need to guess what those 3 unknowns could be. Unfortunately, many guesses are incorrect, as they give negative numbers for the variables y21 and y22 (in the true solution, these values should be positive). The program is coded such that it will stop when positive values of y21 and y22 are given (indicating a correct solution).
-Currently, I have a for loop nested inside of a for loop nested inside of a for loop to do so. The idea is that all possible values of the third for loop are tested for the first value of the first and second for loops. The fourth for loop runs inside those three to refine the guess. It iterates on up from there. Below is my code:
for n = .0001:.0001:10
M1_o = n;
for k = .0001:.0001:10
M2_o = k;
for r = .0001:.0001:10
N2_o = r;
for iter = 1: itermax
if (iter <= itermax) && (dist > crit1)
M(1) = M1_o;
M(2) = M2_o;
NS(2) = N2_o;
%solve:
Y(1) = cu(1)^((1-alpha)*mu) * sKM(1)^((1-alpha)*mu) * NS(1)^(alpha*mu) * M(1)^(1-alpha*mu);
Y(2) = cu(2)^((1-alpha)*mu) * sKM(2)^((1-alpha)*mu) * NS(2)^(alpha*mu) * M(2)^(1-alpha*mu);
%solve:
P(1) = M(1)/((1-mu)*Y(1));
P(2) = (1 - (omega(1)^(1/psi))*(P(1)^((psi-1)/psi)))^(psi/(psi-1))/((1+taxd.d(1))*(1-omega(1))^(1/(psi-1)));
%Solve:
C(1) = sCM(1)*M(1);
X(1) = sXM(1)*M(1);
K(1) = sKM(1)*M(1);
YC(1) = sYM(1)*M(1);
B(1) = sBM(1)*M(1);
%Solve:
y11 = omega(1)^(1/psi) * P(1)^(-1/psi) * YC(1);
y12 = (1-omega(1))^(1/psi) * (P(2)*(1+taxd.d(1)))^(-1/psi) * YC(1);
%Solve:
y21 = Y(1) - y11;
if y21 < 0
warning('y21 is negative')
end
y22 = Y(2) - y12;
if y22 < 0
warning('y22 is negative')
end
YC(2) = ((1-omega(2))*y21^(1-psi) + omega(2)*y22^(1-psi))^(1/(1-psi));
%Solve:
PC(2) = ((1-omega(2))^(1/psi)*(P(1)*(1+taxd.d(2)))^((psi-1)/psi) + omega(2)^(1/psi) * P(2)^((psi-1)/psi) )^(psi/(psi-1));
%Solve:
C(2) = (M(2)/a(2)) * ((1-NS(2))/NS(2)) * (mu*alpha/(1-mu)) * ((1-taxd.n(2))/(1+taxd.c(2)));
sCM(2) = C(2)/M(2);
%Compute:
sBM(2) = (1/(1-mu) - sCM(2) - sXM(2) - 1 - sGM(1) )*PC(2)/(gammax*q -1);
sB(2) = (1-mu)*sBM(2);
%B1 = -B2
sB(1) = -sB(2);
%Update:
M1_n = (C(1)+X(1)+sG(1,1)+ (gammax*q-1)*sB(1))*((mu-1)/mu);
%Update:
M2_n = (YC(2) + (gammax*q-1)*sB(2)*(1/PC(2)))*(1-mu);
%Update:
N2_n = (cu(2)^((1-alpha)*mu) * (sKM(2))^((1-alpha)*mu)* M(2)^(1-alpha*mu) * Y(2)^(-1) )^(-1/(alpha*mu));
%repeat until M1, M2, N2 converge:
dist = max(max(abs(M1_o - M1_n), abs(M2_o - M2_n)), abs(N2_o-N2_n));
%refine guess
M1_o = 0.8 .* M(1) + 0.2 .* M1_n;
M2_o = 0.8 .* M(2) + 0.2 .* M2_n;
N2_o = 0.8 .* N2_o + 0.2 .* N2_n;
end
end
if y21 > 0 && y22 > 0
disp(n)
disp(k)
disp(r)
break
end
end
end
end

採用された回答

Karthik Malisetty
Karthik Malisetty 2020 年 6 月 19 日
Hi,
From my understanding, the first three for loops you implemented run the fourth for loop times, which will take years to run on using single thread
So, the general suggestions would be
  1. Implement other efficient algorithms on finding those values (If there are any)
  2. Using Parallel Computing Toolbox where you can use parfor loops. Since you are trail and erroring the values this would be more helpful toolbox
Refer to this link if you are interested in using parallel computing toolbox.

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

製品


リリース

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by