How can I optimize two variables with fmincon?
7 views (last 30 days)
Show older comments
Aim is to minimize variable Z with optimizing S and N. There are two separable files, fieldmodel.m and opt_fieldmodel.m. Running the opt_fieldmodel gives error "Not enough input arguments. Error in fieldmodel (line 28) n(t+1) = n(t)-0.00384*n(t)+0.0243* N(t)-0.000677*Y(t)+0.368*deposit;" How to solve the error and the optimization problem with 2 variables?
_________________________
function [Z] = fieldmodel(X,N);
% parameters
per = 100; %years
a = 3.5; %Price of phosphorus, €/kg
b = 1.2; %Price of nitrogen, €/kg
p = 0.12; %Price of wheat, €/kg
r = 0.05; %Interest rate
g = 0; %Inclination
d = 0; %Marginal damage
deposit = 4.46; %deposit
%Variables
Y = zeros(1,per); %Wheat yield
S = zeros(1,per); %Soil test phosphorus
n = zeros(1,per); %Soil test nitrogen
Profit = zeros(1,per); %Annual profit (€/kg/a)
%Initial state
S(1,1) = 10;
n(1,1) = 200;
%Loop
for t=1:per
Y(t) = max(0, 837.2 + 73*S(t) + 47.12*n(t) + -2.413*S(t)^2 + 0.0127*S(t)*n(t) + -0.1813*n(t)^2);
S(t+1) = 0.9816*S(t) + (0.0032+0.00084*S(t))*(X(t)-(3+0.19*log(S(t))*Y(t)/1000));
n(t+1) = n(t)-0.00384*n(t)+0.0243* N(t)-0.000677*Y(t)+0.368*deposit;
D(t) = 15*exp(-0.7+0.7*(0.6*X(t)+0.4*N(t))/100);
end
%Profit and NPV
damage = D*70;
Profit = p*Y-a*X - b*N- damage;
Z = - exp(-r*(1:1:per))* Profit;
end
___________________________
opt_fieldmodel.m
clear all
X0 = 10*ones(1,100); %Initial guess for phosphorus
N0 = 10*ones(1,100); %Initial guess for nitrogen
LB = zeros(1,100); %Lower bound
UB = 100*ones(1,100); %Upper bound
options = optimoptions(@fmincon,'MaxFunEvals',100000,'Display','iter','MaxIter',8000);
[X,N,FVAL,EXITFLAG] = fmincon(@fieldmodel,[X0,N0],[],[],[],[],LB,UB,[],options)
__________________________
0 Comments
Answers (1)
Ameer Hamza
on 17 May 2020
fmincon accepts a function handle with only one input. I have made few modifications to your code and marked those locations. Compare it with your code to see the difference
% clear all
X0 = 10*ones(1,100); %Initial guess for phosphorus
N0 = 10*ones(1,100); %Initial guess for nitrogen
LB = zeros(1,200); %Lower bound <<===== 200 variables
UB = 100*ones(1,200); %Upper bound <<===== 200 variables
options = optimoptions(@fmincon,'MaxFunEvals',100000,'Display','iter','MaxIter',8000);
[X_sol,FVAL,EXITFLAG] = fmincon(@(x) fieldmodel(x(1:100),x(101:200)),[X0,N0],[],[],[],[],LB,UB,[],options)
X = X_sol(1:100);
N = X_sol(101:200);
function [Z] = fieldmodel(X,N)
% parameters
per = 100; %years
a = 3.5; %Price of phosphorus, €/kg
b = 1.2; %Price of nitrogen, €/kg
p = 0.12; %Price of wheat, €/kg
r = 0.05; %Interest rate
g = 0; %Inclination
d = 0; %Marginal damage
deposit = 4.46; %deposit
%Variables
Y = zeros(1,per); %Wheat yield
S = zeros(1,per); %Soil test phosphorus
n = zeros(1,per); %Soil test nitrogen
Profit = zeros(1,per); %Annual profit (€/kg/a)
%Initial state
S(1,1) = 10;
n(1,1) = 200;
%Loop
for t=1:per
Y(t) = max(0, 837.2 + 73*S(t) + 47.12*n(t) + -2.413*S(t)^2 + 0.0127*S(t)*n(t) + -0.1813*n(t)^2);
S(t+1) = 0.9816*S(t) + (0.0032+0.00084*S(t))*(X(t)-(3+0.19*log(S(t))*Y(t)/1000));
n(t+1) = n(t)-0.00384*n(t)+0.0243* N(t)-0.000677*Y(t)+0.368*deposit;
D(t) = 15*exp(-0.7+0.7*(0.6*X(t)+0.4*N(t))/100);
end
%Profit and NPV
damage = D*70;
Profit = p*Y-a*X - b*N- damage;
Z = norm(- exp(-r*(1:1:per)).*Profit); % <==== It should return a scalar value, not a vector
end
0 Comments
See Also
Categories
Find more on Optimization Toolbox 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!