Why is the following code working fine when executed with a for loop but showing an error when it comes to parfor?

1 view (last 30 days)
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 Comments
ADragon
ADragon on 20 Aug 2018
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.

Sign in to comment.

Answers (0)

Categories

Find more on Parallel Computing Fundamentals 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!