How to use fmincon in for loop

I am trying to use fmincon in a for loop but am not sure how to incorporate function handles with the iterations required. I am essentially developing a Monte Carlo simulation (hence all the distributions) that solves for x = [x(1) x(2)], Np amount of times. All I need to do is perform the fmincon operation many times and have a list of the results for x. The way I tried did not work because of the combination of function handles and iterations.
clear all
m_tlife = 33;
std_tlife = 11;
dist_tlife = makedist('Normal', m_tlife, std_tlife);
a_drate = 2;
b_drate = 0.006;
dist_drate = makedist('Gamma', a_drate, b_drate);
a_OM = 8;
b_OM = 10;
c_OM = 20;
dist_OM = makedist('Triangular', a_OM, b_OM, c_OM);
m_Ee = 4.56;
std_Ee = 0.27;
dist_Ee = makedist('Normal', m_Ee, std_Ee);
a_pi20 = 1.50;
b_pi20 = 2.25;
c_pi20 = 3;
dist_pi20 = makedist('Triangular', a_pi20, b_pi20, c_pi20);
m = 34;
ITC = 0.3;
e = 0.8;
pi08 = 8.50; % $/W
Pmod = 2.05; % kW
Np = 10;
for i = 1:Np
tlife = random(dist_tlife);
drate = random(dist_drate);
OM = random(dist_OM);
Ee = random(dist_Ee);
pi20 = random(dist_pi20);
dpi(i) = (pi20 - pi08)/(12*pi08);
pi_t(i) = @(x)(-dpi(i)*x(1)*pi08 - pi08);
Ci0 = pi08*Pmod*m;
Ci_t(i) = @(x)pi_t(i)(x)*Pmod*x(2);
P(i) = @(x)(Pmod - Pmod*drate*x(1))*(m - x(2)) + Pmod*x(2);
Com(i) = @(x)OM*P(i)(x)*tlife;
fun(i) = @(x)((Ci0 + Ci_t(i)(x))*(1 - ITC) + Com(i)(x))/(Ee*P*365*tlife*e);
x0 = [0,0];
lb = [0,0];
up = [];
A = [0 1; 1 0];
b = [tlife m];
Aeq = [];
beq = [];
x = fmincon(fun, x0, A, b, Aeq, beq, lb, up);
end

 Risposta accettata

Matt J
Matt J il 26 Apr 2017
Modificato: Matt J il 26 Apr 2017
If you are only trying to develop a list of x, why are you indexing with 'i' everything in the loop except for x?
for i = 1:Np
tlife = random(dist_tlife);
drate = random(dist_drate);
OM = random(dist_OM);
Ee = random(dist_Ee);
pi20 = random(dist_pi20);
dpi = (pi20 - pi08)/(12*pi08);
pi_t = @(x)(-dpi*x(1)*pi08 - pi08);
Ci0 = pi08*Pmod*m;
Ci_t = @(x)pi_t(x)*Pmod*x(2);
P = @(x)(Pmod - Pmod*drate*x(1))*(m - x(2)) + Pmod*x(2);
Com = @(x)OM*P(x)*tlife;
fun = @(x)((Ci0 + Ci_t(x))*(1 - ITC) + Com(x))/(Ee*P*365*tlife*e);
x0 = [0,0];
lb = [0,0];
up = [];
A = [0 1; 1 0];
b = [tlife m];
Aeq = [];
beq = [];
x(i,:) = fmincon(fun, x0, A, b, Aeq, beq, lb, up);
end

5 Commenti

Andrew Poissant
Andrew Poissant il 26 Apr 2017
Modificato: Andrew Poissant il 26 Apr 2017
Ah, your approach makes sense. However, when I run the code I get an error in the fmincon line saying "index exceeds matrix dimensions" caused by "failure in initial objective function evaluation. FMINCON cannot continue." Could this be because it is not updating the initial conditions? Do I need to update these?
Matt J
Matt J il 26 Apr 2017
Did you pre-allocate x? In any case, we'll need to see copy/pastes of the error messages.
I thought I initiate x as part of x0. Or at least that's what I thought x0 does in fmincon. here is the error message: Index exceeds matrix dimensions.
Error in MonteCarlo_project>@(x)(-dpi(i)*x(1)*pi08-pi08)
Error in MonteCarlo_project>@(x)pi_t(x)*Pmod*x(2)
Error in MonteCarlo_project>@(x)((Ci0+Ci_t(x))*(1-ITC)+Com(x))/(Ee*P(x)*365*tlife*e)
Error in fmincon (line 536) initVals.f = feval(funfcn{3},X,varargin{:});
Error in MonteCarlo_project (line 46) x(i,:) = fmincon(fun, x0, A, b, Aeq, beq, lb, up);
Caused by: Failure in initial objective function evaluation. FMINCON cannot continue.
Matt J
Matt J il 26 Apr 2017
You still have dpi(i). Do not index any function handles with "i". Only index x(i,:).
Oh wow, my mistake. Thanks for the assistance!

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

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

Start Hunting!

Translated by