Why is the following code working fine when executed with a for loop but showing an error when it comes to parfor?
1 次查看(过去 30 天)
显示 更早的评论
The following code shows an "Index exceeds matrix dimensions error when run with parfor but runs okay when executed with just a for loop. mpc is a struct, in the code.
What am I doing wrong here and how do I fix it?
%Beginning
[F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
[PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
mpc = loadcase('case9');
refbus = find(REF == mpc.bus(:,BUS_TYPE),1);
nb = size(mpc.bus,BUS_I);
ng = size(mpc.gen,GEN_BUS);
nl = size(mpc.branch,F_BUS);
[Vx_idx,Vy_idx,Pf_idx,Qf_idx,Pt_idx,Qt_idx,Pg_idx,Qg_idx,Pf1_idx,Qf1_idx,Pt1_idx,Qt1_idx] = assign_idx(nb, nl, ng);
[gamma, theta, alpha1, alpha2, ~, termcrit] = flexa_constants;
Aeq = [];
beq = [];
lb = [];
ub = [];
Ev_idx =0;
Evv_idx =0;
Ef_idx = 0;
Et_idx = 0;
optimval = 5216.028;
count = 1;
rel_val = 0;
relerror = 1;
tempx0 = 0;
cost_final = 0;
exitflag = 0;
output = 0;
ef = 0;
costs = zeros(nb,1);
Mtemp = 0;
Mvector = 0;
c = 0;
ceq = 0;
xsol = 0;
ef = zeros(nb,1);
X = cell(nb,1);
posf = 0;
post = 0;
pos = 0;
x_ii = 0;
%%Initial Guess for x
x_l = 2*nb+8*nl+4*ng;
Ev_idx = x_l+1:x_l+4*nb;
x_l = Ev_idx(end);
Evv_idx = x_l+1:x_l+nb;
x_l = Evv_idx(end);
Ef_idx = x_l+1:x_l+4*nl;
x_l = Ef_idx(end);
Et_idx = x_l+1:x_l+4*nl;
x_l = Et_idx(end);
x0 = zeros(x_l,1);
x0(Vx_idx) = 1;
x0(Pg_idx) = 1.05;
%%fmincon
% while relerror >= termcrit
while count == 1
tempx0 = x0;
H = sparse(x_l,x_l); %Quadratic term coefficient
h = sparse(x_l,1); %Linear term coefficient
g1_idx = Pg_idx(1:3);
g2_idx = Pg_idx(4:6);
q1_idx = Qg_idx(1:3);
q2_idx = Qg_idx(4:6);
A0 = [-eye(nb) zeros(nb, x_l-nb)];
b0 = zeros(nb,1);
A1 = zeros(2,x_l);
A1(1,g1_idx) = -1;
A1(2,g2_idx) = -1;
A = [A0;A1];
b1 = [-sum(mpc.bus(:,PD))/100;-sum(mpc.bus(:,PD))/100];
b = [b0;b1];
%
Vlb = zeros(x_l,1);
Vub = zeros(x_l,1);
Vlb(1:x_l) = -Inf;
Vub(1:x_l) = Inf;
Vlb(Vx_idx) = 0.9;
Vub(Vx_idx) = 1.1;
for gg = 1:ng
Vlb(Pg_idx(gg)) = mpc.gen(gg,PMIN)/100;
Vlb(Pg_idx(ng+gg)) = Vlb(Pg_idx(gg));
Vub(Pg_idx(gg)) = mpc.gen(gg,PMAX)/100;
Vub(Pg_idx(ng+gg)) = Vub(Pg_idx(gg));
Vlb(Qg_idx(gg)) = mpc.gen(gg,QMIN)/100;
Vlb(Qg_idx(ng+gg)) = Vlb(Qg_idx(gg));
Vub(Qg_idx(gg)) = mpc.gen(gg,QMAX)/100;
Vub(Qg_idx(ng+gg)) = Vub(Qg_idx(gg));
end
lb = Vlb;
ub = Vub;
const = 0;
for i = 1:ng
H(Pg_idx(i),Pg_idx(i)) = mpc.gencost(i,COST);
h(Pg_idx(i),1) = mpc.gencost(i,COST+1);
const(i) = mpc.gencost(i,COST+2);
end
gradF = 2*H*100*x0 + h*100;
mag = norm(gradF);
epsilon = gamma*alpha1*min(alpha2,1/mag);
Aslack = zeros(1,x_l);
Aslack(1,Vy_idx(refbus)) = 1;
Aeq = [Aslack]; beq = 0;
% epsilon = 1e-3;
fun = @(x)(100*x)'*H*(100*x) + (100*x)'*h + sum(const)...
+ power(norm(x(g1_idx)-x(g2_idx)),2)...
+ power(norm(x(g1_idx)-x(g2_idx)),2)...
+ power(norm(x(Pf_idx)-x(Pf1_idx)),2) + power(norm(x(Pt_idx)-x(Pt1_idx)),2)...
+ power(norm(x(Qf_idx)-x(Qf1_idx)),2) + power(norm(x(Qt_idx)-x(Qt1_idx)),2)...
+ power(norm(x(Ev_idx)),2) + power(norm(x(Evv_idx)),2) + power(norm(x(Ef_idx)),2) + power(norm(x(Et_idx)),2);
options = optimoptions(@fmincon,'Algorithm','interior-point','ConstraintTolerance', 1e-4,'MaxIterations',1e6,'MaxFunctionEvaluations',1e6,'StepTolerance',epsilon);
g = zeros(nb,1);
g(mpc.gen(:,GEN_BUS)) = mpc.gen(:,GEN_BUS);
parfor bus_idx = 1:nb
[x{bus_idx},fval(bus_idx),exitflag(bus_idx),output(bus_idx),lambda,grad,hessian] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,@(x)nonlconstraints_editpar1(x,x0,Ev_idx,Evv_idx,Ef_idx,Et_idx,bus_idx),options);
ef(bus_idx) = exitflag(bus_idx);
costs(bus_idx) = fval(bus_idx);
posf = find(bus_idx==mpc.branch(:,1));
post = find(bus_idx==mpc.branch(:,2));
pos = union(posf,post);
if g(bus_idx)~=0
x_ii = [Vx_idx(bus_idx);Vy_idx(bus_idx);Pf_idx(pos);...
Qf_idx(pos);Pt_idx(pos);Qt_idx(pos);Pg_idx(bus_idx);...
Qg_idx(bus_idx);Pf1_idx(pos);Qf1_idx(pos);Pt1_idx(pos);...
Qt1_idx(pos)];
else
x_ii = [Vx_idx(bus_idx);Vy_idx(bus_idx);Pf_idx(pos);...
Qf_idx(pos);Pt_idx(pos);Qt_idx(pos);...
Pf1_idx(pos);Qf1_idx(pos);Pt1_idx(pos);...
Qt1_idx(pos)];
end
xsol = x0(x_ii) + gamma*(x{bus_idx}(x_ii) - x0(x_ii));
X{bus_idx} = xsol;
end
count = count + 1;
end
Error:
>> optim_par_nogrp
Error using optim_par_nogrp>(parfor supply)
Index exceeds matrix dimensions.
Error in optim_par_nogrp (line 137)
parfor bus_idx = 1:nb
3 个评论
ADragon
2018-8-20
Hi Viswanath, I would take everything inside of the parfor loop and create a function. Then call that function using the indexer.
parfor bus_idx = 1:nb
X{bus_idx} = myfunction(bus_idx,...);
end
Do you get the same behavior? I have found that the parfor loop does really well to populate a single array given the index as the looping variable. Since you have multiple arrays inside parfor, it may mess up how the parfor function sets up the different threads. If you isolate the array you want to parallel compute for (as the above code) it may help solve this problem.
回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!