104 lines
2.5 KiB
Matlab
Executable File
104 lines
2.5 KiB
Matlab
Executable File
function varargout = slog(varargin)
|
|
%ENTROPY
|
|
%
|
|
% y = SLOG(x)
|
|
%
|
|
% Computes/declares concave shifted logarithm log(1+x)
|
|
%
|
|
% Implemented as evalutation based nonlinear operator. Hence, the concavity
|
|
% of this function is exploited to perform convexity analysis and rigorous
|
|
% modelling. Implemented in order to avoid singularities in logarithm
|
|
% evaluation.
|
|
|
|
switch class(varargin{1})
|
|
case 'double'
|
|
x = varargin{1};
|
|
varargout{1} = log(abs(1+x)+sqrt(eps));
|
|
|
|
case 'sdpvar'
|
|
varargout{1} = check_for_special_cases(varargin{:});
|
|
if isempty(varargout{1})
|
|
varargout{1} = InstantiateElementWise(mfilename,varargin{:});
|
|
end
|
|
|
|
case 'char'
|
|
|
|
X = varargin{3};
|
|
F = (X >= -1+eps);
|
|
|
|
operator = struct('convexity','concave','monotonicity','increasing','definiteness','none','model','callback');
|
|
operator.convexhull = @convexhull;
|
|
operator.range = [-inf inf];
|
|
operator.domain = [-1 inf];
|
|
operator.derivative = @(x) (1./(abs(1+x)+sqrt(eps)));
|
|
operator.inverse = @(x)(exp(x)-1);
|
|
|
|
varargout{1} = F;
|
|
varargout{2} = operator;
|
|
varargout{3} = X;
|
|
|
|
otherwise
|
|
error('SDPVAR/SLOG called with CHAR argument?');
|
|
end
|
|
|
|
|
|
function f = check_for_special_cases(g);
|
|
f = [];
|
|
% Check for slog(1+a(x)/y)
|
|
vars = getvariables(g);
|
|
[mt,variabletype] = yalmip('monomtable');
|
|
% All signomials
|
|
if all(variabletype(vars)==4)
|
|
% All xi/yi
|
|
local_mt = mt(vars,:);
|
|
for i = 1:size(local_mt,1)
|
|
if nnz(local_mt(i,:) < 0) ~= 1
|
|
return
|
|
end
|
|
if nnz(local_mt(i,:)) >2
|
|
return
|
|
end
|
|
if ~all(ismember(local_mt(i,:),[-1 0 1]))
|
|
return
|
|
end
|
|
end
|
|
% OK, everything is xi/yi
|
|
for i = 1:length(g)
|
|
gi = extsubsref(g,i);
|
|
[~,common] = find(mt(getvariables(gi),:) < 0);
|
|
y = recover(common(1));
|
|
x = gi*y;
|
|
if length(g)==1
|
|
% Testing some display issues
|
|
f =slogfrac([x;y]);
|
|
else
|
|
f = [f;slogfrac([x;y])];
|
|
end
|
|
end
|
|
else
|
|
return
|
|
end
|
|
|
|
|
|
function [Ax, Ay, b, K] = convexhull(xL,xU)
|
|
K = [];
|
|
if 1+xL <= 0
|
|
fL = inf;
|
|
else
|
|
fL = log(1+xL);
|
|
end
|
|
fU = log(1+xU);
|
|
dfL = 1/(1+xL);
|
|
dfU = 1/(1+xU);
|
|
xM = (xU + xL)/2;
|
|
fM = log(1+xM);
|
|
dfM = 1/(1+xM);
|
|
|
|
[Ax,Ay,b] = convexhullConcave(xL,xM,xU,fL,fM,fU,dfL,dfM,dfU);
|
|
remove = isinf(b) | isinf(Ax) | isnan(b);
|
|
if any(remove)
|
|
remove = find(remove);
|
|
Ax(remove)=[];
|
|
b(remove)=[];
|
|
Ay(remove)=[];
|
|
end |