Dynamic-Calibration/utils/YALMIP-master/extras/fmincon_con.m

152 lines
4.6 KiB
Matlab
Executable File

function [g,geq,dg,dgeq,xevaled] = fmincon_con(x,model,xevaled)
global latest_xevaled
global latest_x_xevaled
% Early bail for linear problems
g = [];
geq = [];
dg = [];
dgeq = [];
if model.linearconstraints
xevaled = [];
return
end
if nargin<3
if isequal(x,latest_x_xevaled)
xevaled = latest_xevaled;
else
xevaled = zeros(1,length(model.c));
xevaled(model.linearindicies) = x;
xevaled = apply_recursive_evaluation(model,xevaled);
latest_x_xevaled = x;
latest_xevaled = xevaled;
end
end
if model.nonlinearinequalities
g = full(model.Anonlinineq*xevaled(:)-model.bnonlinineq);
end
if nnz(model.K.q) > 0
top = 1;
for i = 1:length(model.K.q)
z = model.F_struc(top:top+model.K.q(i)-1,:)*[1;xevaled];
% g = [g;-(z(1)^2 - z(2:end)'*z(2:end))];
g = [g;-(z(1) - sqrt(z(2:end)'*z(2:end)))];
top = top + model.K.q(i);
end
end
if model.nonlinearequalities
geq = full(model.Anonlineq*xevaled(:)-model.bnonlineq);
end
dgAll_test = [];
if nargout == 2 || ~model.derivative_available
return
elseif ~isempty(dgAll_test) & isempty(model.evalMap)
dgAll = dgAll_test;
elseif isempty(model.evalMap) & (model.nonlinearinequalities==0) & (model.nonlinearequalities==0) & (model.nonlinearcones==0) & any(model.K.q)
dg = computeConeDeriv(model,xevaled);
elseif isempty(model.evalMap) & (model.nonlinearinequalities | model.nonlinearequalities | model.nonlinearcones)
n = length(model.c);
linearindicies = model.linearindicies;
% xevaled = zeros(1,n);
% xevaled(linearindicies) = x;
% FIXME: This should be vectorized
news = model.fastdiff.news;
allDerivemt = model.fastdiff.allDerivemt;
c = model.fastdiff.c;
if model.fastdiff.univariateDifferentiates
zzz = c.*(x(model.fastdiff.univariateDiffMonom).^model.fastdiff.univariateDiffPower);
else
% X = repmat(x(:)',length(c),1);
O = ones(length(c),length(x));
nz = find(allDerivemt);
% O(nz) = X(nz).^allDerivemt(nz);
O(nz) = x(ceil(nz/length(c))).^allDerivemt(nz);
zzz = c.*prod(O,2);
end
newdxx = model.fastdiff.newdxx;
newdxx(model.fastdiff.linear_in_newdxx) = zzz;
%newdxx = newdxx';
if ~isempty(model.Anonlineq)
dgeq = model.Anonlineq*newdxx;
end
if ~isempty(model.Anonlinineq)
dg = model.Anonlinineq*newdxx;
end
if nnz(model.K.q)>0
dg = [dg;computeConeDeriv(model,xevaled,newdxx);];
end
else
requested = model.fastdiff.requested;
dx = apply_recursive_differentiation(model,xevaled,requested,model.Crecursivederivativeprecompute);
conederiv = computeConeDeriv(model,xevaled,dx);
if ~isempty(model.Anonlineq)
dgeq = [model.Anonlineq*dx];
end
if ~isempty(model.Anonlinineq)
dg = [model.Anonlinineq*dx];
end
if ~isempty(conederiv)
dg = [dg;conederiv];
end
end
if model.nonlinearequalities
dgeq = dgeq';
end
if model.nonlinearinequalities | any(model.K.q)
dg = dg';
end
function conederiv = computeConeDeriv(model,z,dzdx)
conederiv = [];
z = z(:);
if any(model.K.q)
top = 1 + model.K.f + model.K.l;
for i = 1:length(model.K.q)
d = model.F_struc(top,1);
c = model.F_struc(top,2:end)';
b = model.F_struc(top+1:top+model.K.q(i)-1,1);
A = model.F_struc(top+1:top+model.K.q(i)-1,2:end);
if nargin == 2
% No inner derivative
A = A(:,model.linearindicies);
c = c(model.linearindicies);
% -c'*x - d + ||Ax+b||>=0
e = A*z(model.linearindicies) + b;
smoothed = sqrt(10^-10 + e'*e);
conederiv = [conederiv;-c'+(A'*b + A'*A*z(model.linearindicies))'/smoothed];
% conederiv = [conederiv;(2*A(:,model.linearindicies)'*(A(:,model.linearindicies)*z(model.linearindicies)+b)-2*c(model.linearindicies)*(c(model.linearindicies)'*z(model.linearindicies)+d))'];
else
% -c'*x - d + ||Ax+b||>=0
e = A*z + b;
smoothed = sqrt(10^-10 + e'*e);
% conederiv = [conederiv;-c'+(dzdx'*A'*b + dzdx'*A'*A*z(model.linearindicies))'/smoothed];
aux = z'*(A'*A-c*c')*dzdx+(b'*A-d*c')*dzdx;
conederiv = [conederiv;(-dzdx'*c+aux'/smoothed)'];
% inner derivative
% aux = 2*z'*(A'*A-c*c')*dzdx+2*(b'*A-d*c')*dzdx;
% conederiv = [conederiv;aux];
end
top = top + model.K.q(i);
end
end