# objective and constraint functions definition using fmincon

9 views (last 30 days)
Dear All,
I have a vector of five unknown parameters (P=[P1 P2 P3 P4 P5]) and a matrix of N by 6 variables. (X=[Xij], i=1,...,N, j=1,..,6). (N is a large number).
The five unknown parameters are related nonlinearly to matrix entries X(i,j). As seen below, the const is a function of P vector, X matrix, where K and W are known constant matrices. ceq and X has the same dimensions.)
function [c,ceq] = const(P,X,W,K)
c = [];
ceq(:,1) = K(1)*P(2)*X(:,1)-K(2)*(W(:,1)*sin(X(:,1))+(W(:,3)-W(:,2))*cos(X(:,1)))*(P(1)- 1)-W(:,5);
ceq(:,2) = K(1)*P(3)*X(:,2)-K(2)*sin(X(:,2))*(P(1) - 1)*W(:,1)-W(:,6);
ceq(:,3) = K(1)*P(4)*X(:,3)+.5*K(2)*(sin(X(:,3))*W(:,1)-(W(:,2)-W(:,3))*cos(X(:,3)))- W(:,5);
ceq(:,4) = K(1)*P(5)*X(:,4)+.5*K(2)*sin(X(:,4))-W(:,6);
ceq(:,5) = K(1)*P(2)*X(:,5)+K(2)*P(1)*(sin(X(:,5))*W(:,1)-(W(:,2)-W(:,3))*cos(X(:,5)))-W(:,5);
ceq(:,6) = K(1)*P(3)*X(:,6)+K(2)*P(1)*sin(X(:,6))-W(:,6);
end
The objective is to calculate the vector P (just five parameters) by minimizing the objective function obj. However, the obj(P1, X) is a function of just one of the unknown parameters and all the Xi,j variables.
obj =(25*(((2*P(1) - 1)*(cos(X(1,1))*cos(X(1,4))*sin(X(1,3))+……-cos(X(N,1))*cos(X(N,2))*(2*P(1)- 1))^2)^(1/2))/N);
In solving the optimization problem by fmincon function, I am not sure how to define the obj and how to call fmincon.
In defining the obj, what is the correct format? obj = @(?) (...)
Since we are only interested in finding the optimal values for P, how should I call the fmincon function? fmincon(obj,P0, [],[],[],[],[],[],@(?) const(P, X, W, K)) where P0 is the initial guess for the P vector.
Afsoon Nejati Aghdam on 17 Mar 2021
function cost = parameterfun(P,X)
cost = 2*P(1) - 2*P(1)*(sin(X(1,5))*(cos(X(1,1))* ........(all the variables of X(i,j) but just P(1))..........sin(X(9,5))))^2)^(1/2);
end
After initialization of the following known constants:
W = [ Nx6]; K = [1x2]; lb = zeros(1,5); x0 = zeros(1,5);
When I am running the following piece of code:
connL = @(P,X) const(P,X,W,K);
obj = @(P) parameterfun(P,X);
[Popt, fval] = fmincon(obj,x0,[],[],[],[],lb,[],connL);
Unrecognized function or variable 'X'. Error in @(P)parameterfun(P,X) , Error in fmincon (line 566) initVals.f = feval(funfcn{3},X,varargin{:}); Caused by: Failure in initial objective function evaluation. FMINCON cannot continue.

Walter Roberson on 17 Mar 2021
W = [ Nx6]; K = [1x2]; lb = zeros(1,5); x0 = zeros(1,5);
those initialize variables W and K (and lb and x0)
connL = @(P,X) const(P,X,W,K);
That creates an anonymous function . MATLAB sees the @(P,X) and takes note of the variable names listed there, P and X. It then scans the body of the anonymous function, and whereever it sees those variables it replaces them with references to parameters to be passed in, much like
connL = @(varargin) const(varargin{1}, varargin{2}, W, K)
As it encounters variables that are not on the parameter list, then at the time it builds the function it looks up the variables in scope, and copies them in to the function it is building, giving you something sort of like
global anon678735155_internal
anon678735155_internal.workspace{1}.W = W; %copy as of time function is built
anon678735155_internal.workspace{1}.K = K; %copy as of time function is built
anon678735155_internal.function = '@(P,X) const(P,X,W,K)';
connL = @anon678735155
function output = anon678735155(varargin)
output = const(varargin{1}, varargin{2}, anon678735155_internal.workspace{1}.W, anon678735155_internal.workspace{1}.K);
end
(Not actual code, but works like this, if MATLAB offered a way to mark variables as read-only)
Then when connL is called upon, the values for W and K that were stored away are retrieved in order to execute the function call. And notice that assignments to W or K or P or X made in the body of the code after defining the anonymous function, have no effect on the execution of the anonymous function, which only relies on the the parameters passed in and the copies of the variables that it stored away.
obj = @(P) parameterfun(P,X);
That creates an anonymous function . MATLAB sees the @(P) and takes note of the variable name listed there, P. It then scans the body of the anonymous function, and whereever it sees that variable it replaces it with a eference to a parameter to be passed in, much like
obj = @(varargin) parameterfun(varargin{1},X)
As it encounters variables that are not on the parameter list, then at the time it builds the function it looks up the variables in scope, and copies them in to the function it is building, giving you something sort of like
global anon757740131_internal
anon757740131_internal.workspace{1}.X = X; %copy as of time function is built
anon757740131_internal.function = '@(P) parameterfun(P,X)';
obj = @anon757740131
function output = anon757740131(varargin)
output = parameterfun(varargin{1},anon678735155_internal.workspace{1}.X);
end
But -- there is no variable X in scope at the time that obj is being built, so it is not possible to store away a copy of the current X for later use.
When this happens, that the variable to be copied in is not defined in scope, then the effect is like
global anon757740131_internal
%no variables copied in
anon757740131_internal.function = '@(P) parameterfun(P,X)';
obj = @anon757740131
function output = anon757740131(varargin)
output = parameterfun(varargin{1},anon678735155_internal.workspace{1}.X);
end
and then when you invoke obj and it gets to the point in execution that it needs X, it looks for anon678735155_internal.workspace{1}.X and sees that it does not exist, and complains about X not existing.
Remember that assignments in the code to the variable X made after the anonymous function is defined will not have an effect on the execution of the anonymous function: anonymous functions only rely on parameters passed in and stored copies of variables. In particular, if the anonymous function obj is later executed in a context that defined X then that X is ignored for this purpose. For example,
X = 5;
obj(73)
then when MATLAB executes anon757740131 it will not go looking in the calling environment to notice the X that was just defined. If a referenced variable in the body of an anonymous function does not exist then it gets marked as undefined, and the execution of the anonymous function fails as soon as the value is needed.
Please do not treat my code outline above as being exact: there are some complications having to do with global variables and shared variables.
[Popt, fval] = fmincon(obj,x0,[],[],[],[],lb,[],connL);
When the non-linear constraint function, connL, is invoked, it will be passed the vector of current values. For example the first time, it would be invoked as connL(x0) . But you defined
connL = @(P,X) const(P,X,W,K);
which expects two parameters, not one.
If your X is known to your code, such as based on data read in, then you should define it in your code and then be using
X = appropriate value
W = [ Nx6]; K = [1x2]; lb = zeros(1,5); P0 = zeros(1,5);
connL = @(P) const(P,X,W,K);
obj = @(P) parameterfun(P,X);
[Popt, fval] = fmincon(obj, P0, [], [], [], [], lb, [], connL);
This then invokes the behaviour that the known X, W, K are copied into the anonymous function definitions . It differs from what you had in that X is defined ahead of time, and that X is no longer a parameter to the nonlinear constraint function connL. Also notice that I renamed x0 to P0 to emphasize that it is P that is being varied, not X.
Afsoon Nejati Aghdam on 20 Mar 2021
Thanks for the comment. Just to add, I think using the connL is trivial. Since we calculate Xi for each trial from the nonlinear constraints, then there is no point in calling the connL again. It should be okay to go on with obj (no connL is needed!) and calling calculate_X inside obj.