How can I optimize two variables with fmincon?

7 views (last 30 days)
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)
__________________________

Answers (1)

Ameer Hamza
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

Categories

Find more on Optimization Toolbox in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!