Dynamic-Calibration/utils/YALMIP-master/operators/huber.m

87 lines
2.2 KiB
Matlab
Executable File

function varargout = huber(varargin)
% HUBER Returns the Hüber function (convex operator)
%
% p = HUBER(x,M)
%
% Returns sum_i h(x_i,M) where h(x) is the scalar Hüber function
% h(x) = x^2 if |x|<=M
% M(2*|x|-M) otherwise
%
% The Hüber functions is convex and non-monotonic.
switch class(varargin{1})
case 'double'
if nargin < 2
M = repmat(1,size(varargin{1}));
else
M = varargin{2};
end
x = varargin{1};
if isscalar(M) && ~isscalar(x)
M = repmat(M,size(x));
end
y = x.^2;
r = find(abs(x) > M);
y(r) = M(r).*(2*abs(x(r)) - M(r));
varargout{1} = sum(y);
case 'sdpvar' % Pass on args and save them.
if nargin < 2
M = 1;
varargin{end+1} = 1;
else
M = varargin{2};
end
X = varargin{1};
[n,m] = size(X);
if min(n,m) == 1
X = X(:);
end
if ~isequal(size(M),size(X))
M = repmat(M,size(X));
if ~isequal(size(M),size(X))
error('M must be scalar or same size as x')
end
varargin{2} = M;
end
y = [];
for i = 1:size(X,2)
varargin{1} = X(:,i);
varargin{2} = M(:,i);
y = [y yalmip('define',mfilename,varargin{:})];
end
varargout{1} = y;
case 'char' % YALMIP send 'model' when it wants the epigraph or hypograph
if isequal(varargin{1},'graph')
t = varargin{2};
X = varargin{3};
M = varargin{4};
u = sdpvar(length(X),1);
v = sdpvar(length(X),1);
% From Boyd & Vandenberghe
% E = [v>=0, 0 <= u <= M, -u-v <= X <= u + v, u'*u + 2*M*sum(v) <= t];
% From Mangasarian & Musicant
E = [-v <= X-u <= v, u'*u + 2*M*sum(v) <= t];
varargout{1} = E;
varargout{2} = struct('convexity','convex','monotonicity','none','definiteness','positive','model','graph');
varargout{3} = X;
else
varargout{1} = [];
varargout{2} = [];
varargout{3} = [];
end
otherwise
end