📄 mpower.m
字号:
function y = mpower(x,d)
%MPOWER (overloaded)
% Author Johan L鰂berg
% $Id: mpower.m,v 1.24 2007/08/07 21:02:50 joloef Exp $
%Sanity check
if isa(d,'sdpvar')
y = power_internal1(d,x);
return
end
if prod(size(d))>1
error('The power must be scalar.');
end
if x.dim(1)~=x.dim(2)
error('Matrix must be square.')
end
% Trivial cases
if d==0
y = eye(x.dim(1),x.dim(2))^0;
return
end
if d==1
y = x;
return
end
% Fractional and negative powers
if (ceil(d)-d>0) | (d<0)
if x.dim(1)>1 | x.dim(2)>1
error('Only scalars can have negative or non-integer powers');
else
base = getbase(x);
if isequal(base,sparse([0 1])) % Simple unit scalar
[mt,variabletype] = yalmip('monomtable');
var = getvariables(x);
hash = randn(size(mt,2),1);
hashM = mt*hash;
hashV = (mt(var,:)*d)*hash;
previous_var = find(abs(hashM - hashV) < 1e-20);
if isempty(previous_var)
newmt = mt(getvariables(x),:)*d;
mt(end+1,:) = newmt;
yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]);
y = recover(size(mt,1));
else
y = recover(previous_var);
end
elseif (size(base,2) == 2) & base(1)==0
% Something like a*t^-d
y = base(2)^d*recover(getvariables(x))^d;
else
% Bummer, something more complex, add an internal equality constraint
y = (yalmip('define','mpower_internal',x))^d;
end
end
return
end
% Integer power of matrix
if x.dim(1)>1 | x.dim(2)>1
switch d
case 0
y = 1;
case 1
y = x;
otherwise
y = x*mpower(x,d-1);
end
else %Integer power of scalar
base = x.basis;
if isequal(base,[0 1]) % Unit scalar can be done fast
[mt,variabletype] = yalmip('monomtable');
%var = getvariables(x);
var = x.lmi_variables;
if var > size(mt,2)
nl_var = find(mt(var,:));
possible = find(any(mt(:,nl_var),2));
% possible = 1:size(mt,1);
else
possible = find(mt(:,var));
end
if length(possible)==1
% Even faster, we don't need to search, cannot have been
% definded earlier, since only the linear terms is in monom
% table
newmt = mt(var,:)*d;
mt = [mt;newmt];
% mt(end,size(mt,1))=0;
yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]);
y = x;
y.lmi_variables = size(mt,1);
else
hash = randn(size(mt,2),1);
mt_hash = mt*hash;
mt_hash = mt_hash(possible);
previous_var = findhash(mt_hash , (d*mt(var,:))*hash);
if isempty(previous_var)
newmt = mt(var,:)*d;
% mt(end+1,:) = newmt;
mt = [mt;newmt];
yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]);
y = x;
y.lmi_variables = size(mt,1);
else
previous_var = possible(previous_var);
y = x;
y.lmi_variables = previous_var;
end
end
else % General scalar
switch d
case 0
y = 1;
case 1
y = x;
otherwise
y = x*mpower(x,d-1);
end
end
end
function newvariabletype = newvariabletypegen(newmt)
newvariabletype = spalloc(size(newmt,1),1,0)';
nonlinear = ~(sum(newmt,2)==1 & sum(newmt~=0,2)==1);
if ~isempty(nonlinear)
newvariabletype(nonlinear) = 3;
quadratic = sum(newmt,2)==2;
newvariabletype(quadratic) = 2;
bilinear = max(newmt,[],2)<=1;
newvariabletype(bilinear & quadratic) = 1;
sigmonial = any(0>newmt,2) | any(newmt-fix(newmt),2);
newvariabletype(sigmonial) = 4;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -