How can I Minimize this function with MATLAB? - matlab

I wrote the following function in MATLAB:
function EX_EFFICIENCY=EXERGY_EFFICIENCY_FUNCTION(CR,ER,PC,T0,P0)
I used the following order (ga):
x = ga(#EXERGY_EFFICIENCY_FUNCTION,5)
But it gets the error:
Not enough input arguments.
Error in EXERGY_EFFICIENCY_FUNCTION (line 22)
T7p=T0.*(PC.^((k-1)./k));
Error in createAnonymousFcn>#(x)fcn(x,FcnArgs{:}) (line 11) fcn_handle
= #(x) fcn(x,FcnArgs{:});
Error in makeState (line 47)
firstMemberScore = FitnessFcn(state.Population(initScoreProvided+1,:));
Error in gaunc (line 40) state =
makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);
Error in ga (line 398)
[x,fval,exitFlag,output,population,scores] = gaunc(FitnessFcn,nvars, ...
Caused by:
Failure in initial user-supplied fitness function evaluation. GA cannot continue.
How can I minimize this function?

What are the variables you want to minimize over? All five CR,ER,PC,T0,P0? Then you need to tell ga to use a length-5-vector and deal its elements to the input arguments of the function. Like this:
xopt = ga(#(x) EXERGY_EFFICIENCY_FUNCTION(x(1),x(2),x(3),x(4),x(5)), 5);
You can also fix some and optimize over the others of course, like this:
xopt = ga(#(x) EXERGY_EFFICIENCY_FUNCTION(x(1),x(2),PC,T0,P0), 2);
optimizes CR, ER for fixed values of PC,T0, and P0.

Related

Why not enough input arguments in nlcon in MATLAB?

I am trying to solve an optimization problem in MATLAB with the function fmincon, but there appears a problem with the nonlinear constraints, as MATLAB tells that there are not enough input arguments.
This is my nlcon funtion:
function [c,ceq] = nlcon(w_md2,std)
c =[];
ceq = w_md2'*std-1;
end
that's the execution of fmincon:
covMat = cov(mon_ret) ;
[corMat, std] = corrcov(covMat);
w0 = repmat(n1, port_size, 1);
md2function = #(w_md2) md2(covMat, w_md2);
nonlincon = #nlcon;
w_md_2 = fmincon(md2function, w0, [], [], Aeq, Beq, lbnds, ubnds, nonlincon)
and that`s the error:
Not enough input arguments.
Error in nlcon (line 3)
ceq = w_md2'*std-1;
Error in fmincon (line 639)
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
Error in main (line 60)
w_md_2 = fmincon(md2function, w0, ...
Caused by:
Failure in initial nonlinear constraint function evaluation. FMINCON cannot continue.
Would be really glad if someone could help as I am at total newby to MATLAB.
Best regards
The documentation says that the function passed as argument nonlincon should take one input argument. That means that it is called with only one input argument, and std remains undefined.
You probably want to do
nonlincon = #(x)nlcon(x,std);
That way you create an anonymous function that takes one input argument, and calls your function with the value of std you computed earlier.

"Unable to prove literally" error when trying to create a symbolic function based on an existing function

I need to find inverse of virtual value function of lognormal random variables. This is what I tried to do:
syms flogn(x,p1,p2)
% assume(p2<=0); %Adding this doesn't change the error
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
glogn = finverse(flogn,x);
But I got the error:
Error using symengine
Unable to prove 'p2 <= 0' literally. Use 'isAlways' to test the statement mathematically.
Error in sym/subsindex (line 810)
X = find(mupadmex('symobj::logical',A.s,9)) - 1;
Error in sym/privsubsasgn (line 1085)
L_tilde2 = builtin('subsasgn',L_tilde,struct('type','()','subs',{varargin}),R_tilde);
Error in sym/subsasgn (line 922)
C = privsubsasgn(L,R,inds{:});
Error in logncdf>locallogncdf (line 73)
sigma(sigma <= 0) = NaN;
Error in logncdf (line 47)
[varargout{1:max(1,nargout)}] = locallogncdf(uflag,x,varargin{:});
Error in Untitled5 (line 3)
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
I also tried with beta distribution, and got a similar error. How can I use logncdf with symbolic variables?
Note that you could have minimalize your sample code even more, like this:
syms flogn(x,p1,p2)
flogn(x,p1,p2) = logncdf(x,p1,p2);
It's shorter, produces the same error and helps us to focus on the source of the error message.
So, the error doesn't come from trying to inverse a function, but from trying to use an existing function for numerical calculations with symbolic variables.
The error comes from the fact that you want to create a symbolic function flogn based on existing function logncdf, and logncdf has a multiple comparisons.
With the command edit logncdf, you can read the source code of the function and see comparison at lines 73 and 76.
% Return NaN for out of range parameters.
sigma(sigma <= 0) = NaN;
% Negative data would create complex values, which erfc cannot handle.
x(x < 0) = 0;
Matlab cannot compare symbols so it throws errors.
Depending on what you really need, you can have different solutions.
Do you really need to symbolize the function flogn? Couldn't you just write it as a function then calculate the inverse of it (if it can be inversed...)?
If you really want to keep the symbolization, you can also rewrite your own function logncdf (with another name) so it does not have the comparisons. But it's still not guaranteed that you will find an inverse.

How to use fmincon to optimize two control vectors of a function

I have a function of 2 different vector. These are the control vector (decision variables) of the function. I want to use fmincon to optimize this function and also get the both control vector results separately.
I have tried to use handle ,#, but I got an error.
The function is:
function f = myFS(x,sv) % x is a vector (5,1)
f = norm(x)^2-sigma*(sv(1)+sv(2));
end
%% I tried to write fmincone to consider both control vectors (x and sv)
[Xtemp(:,h2),Fval, fiasco] = fmincon(#(x,sv)myFS(x,sv)...
,xstart,[],[],[],[],VLB,VUB,#(x,sv)myCon(sv),options);
Here is the error I get:
Error using myFS (line 12) Not enough input arguments.
Error in fmincon (line 564)
initVals.f =
feval(funfcn{3},X,varargin{:});
Error in main_Econstraint (line 58) [Xtemp(:,h2),Fval, fiasco] =
fmincon('myFS',xstart,[],[],[],[],VLB,VUB,#(x,sv)myCon(sv),options);
Thanks
fmincon expects your function to be of a single variable, there is no getting around that, but see:
http://se.mathworks.com/help/optim/ug/passing-extra-parameters.html
for example, if both x, cv are variables of the optimization you can combine them and then split them in the actual objective
for example
x_cv = vertcat(x, cv) and then x = x_cv(1:5); cv = x_cv(6:end)'
if cv is not a variable of the optimization, then 'freeze it' as the link above suggests

Getting points from an anonymous function after integration in MATLAB

I want to get value of v(U,n0) for various points in MATLAB
eq = #(q,U,n0) 2*(1-cos(2*pi*q));
hq = #(q,U,n0) ((eq)^2+2*U*n0*(eq))^(1/2);
y = #(q,U,n0) (((eq)+(U*n0))/hq)-1;
a = -0.5;
b = 0.5;
v = #(U,n0) quad(#(q) y(q,U,n0),a,b);
But I get lots of errors like
>> v(1,2)
Undefined function 'plus' for input arguments of type 'function_handle'.
Error in #(q,U,n0)(((eq)+(U*n0))/hq)-1
Error in #(q)y(q,U,n0)
Error in quad (line 72) y = f(x, varargin{:});
Error in #(U,n0)quad(#(q)y(q,U,n0),a,b)
Can anybody help me out with the errors?
You are using function handles without specifying their arguments. For example, after you define eq(q,U,n0), you use it in hq like a variable (eq) without any inputs. Whenever you use a function, you must give it inputs, so use eq(q,U,n0), not just eq.

Using fgoalattain() or solve() for Matlab

I am trying to solve a problem (think excel "goal seek") where given a specific rate of return, matlab can solve for the variable "y" (which is used to multiply a matrix).
I've tried using fgoalattain (i don't understand it) and solve
here is the function which basically adds some arrays together to make a cashflow with y being a double. ppam_gen is a n*1 matrix. other_tot is a n*1 matrix.
down_pmt is a double.
function ansirr = cirr(y)
cf_gen_oth = y*ppam_gen + oth_tot
dp = [-down_pmt]
cashflow = [dp;cf_gen_oth]
ansirr = irr(cashflow)
%ansirr = irr([dp; y*ppam_gen + oth_tot])
end
x = fgoalattain(#cirr,0.001,.15,abs(.15))
does not work, the following error is given:
Error using roots (line 28)
Input to ROOTS must not contain NaN or Inf.
Error in irr (line 134)
coeff = roots(fliplr(cf(:,loop)')); % Find roots of polynomial
Error in ppa_model/cirr (line 139)
ansirr = irr(cashflow)
Error in goalcon (line 26)
f = feval(funfcn{3},x,varargin{:});
Error in
fgoalattain>#(y,varargin)feval(cfun{3},y,neqgoals,funfcn,confcn,WEIGHT,GOAL,x,errCheck,varargin{:})
(line 473)
cfun{3} = #(y,varargin)
feval(cfun{3},y,neqgoals,funfcn,confcn,WEIGHT,GOAL,x,errCheck,varargin{:});
Error in nlconst (line 746)
[nctmp,nceqtmp] = feval(confcn{3},x,varargin{:});
Error in fgoalattain (line 519)
[xnew,ATTAINFACTOR,LAMBDA,EXITFLAG,OUTPUT]=...
Error in ppa_model (line 152)
r = fgoalattain(#cirr,0.001,.15,abs(.15))
and using symbolic toolbox doesn't work either.
syms y
solve(irr([-down_pmt ; y*ppam_gen + oth_tot]) == 0.15)
throws the error:
Error using assignin
Attempt to add "y" to a static workspace.
See MATLAB Programming, Restrictions on Assigning to Variables for details.
Error in syms (line 66)
assignin('caller',x,sym(x));
Error in ppa_model (line 152)
syms y