Dynamic-Calibration/utils/YALMIP-master/modules/global/update_one_eval_bound.m

67 lines
2.6 KiB
Matlab
Executable File

function p = update_one_eval_bound(p,i);
% This function computes upper and lower bounds on the scalar nonlinear
% nonlinear functions modelled using nonlinear evaluation-based operators.
% Given a lower bound xL and upper bound xU on x, find upper and lower
% bounds on f(x)
arg = p.evalMap{i}.variableIndex;
xL = p.lb(arg);
xU = p.ub(arg);
L = -inf;
U = inf;
if ~isempty(p.evalMap{i}.properties.bounds)
% A bound generator is available!
[L,U] = feval(p.evalMap{i}.properties.bounds,xL,xU,p.evalMap{i}.arg{2:end-1});
elseif strcmpi(p.evalMap{i}.properties.monotonicity,'increasing')
% No generator is available, but bound follows from monotinicity
arg = p.evalMap{i}.arg;
if length(arg{1}) > 1
disp(['The ' p.evalMap{i}.fcn ' operator does not have a bound operator'])
disp('This is required for multi-input single output operators');
disp('Sampling approximation does not work in this case.');
error('Missing bound operator');
end
arg{1} = xL;
L = feval(p.evalMap{i}.fcn,arg{1:end-1});
arg{1} = xU;
U = feval(p.evalMap{i}.fcn,arg{1:end-1});
elseif strcmpi(p.evalMap{i}.properties.monotonicity,'decreasing')
arg = p.evalMap{i}.arg;
arg{1} = xL;
U = feval(p.evalMap{i}.fcn,arg{1:end-1});
arg{1} = xU;
L = feval(p.evalMap{i}.fcn,arg{1:end-1});
else
% To get some kind of bounds, we just sample the function
% and pick the min and max from there. This only works for
% simple functions with limited variation...
% We assume it is f(x,parameters)
if length(xL)>1
% We can only sample if it is a scalar function
disp([p.evalMap{i}.fcn ' is not supported in the global solver (only scalar functions support)'])
error([p.evalMap{i}.fcn ' is not supported in the global solver'])
end
if ~isinf(xL) & ~isinf(xU)
xtest = linspace(xL,xU,100);
arg = p.evalMap{i}.arg;
arg{1} = xtest;
values = feval(p.evalMap{i}.fcn,arg{1:end-1});
[minval,minpos] = min(values);
[maxval,maxpos] = max(values);
xtestmin = linspace(xtest(max([1 minpos-5])),xtest(min([100 minpos+5])),100);
xtestmax = linspace(xtest(max([1 maxpos-5])),xtest(min([100 maxpos+5])),100);
arg{1} = xtestmin;
values1 = feval(p.evalMap{i}.fcn,arg{1:end-1});
arg{1} = xtestmax;
values2 = feval(p.evalMap{i}.fcn,arg{1:end-1});
L = min([values1 values2]);
U = max([values1 values2]);
end
end
p.lb(p.evalVariables(i)) = max([p.lb(p.evalVariables(i)) L],[],2);
p.ub(p.evalVariables(i)) = min([p.ub(p.evalVariables(i)) U],[],2);