📄 mpower.m
字号:
function y = mpower(x,d)
%MPOWER (overloaded)
% Author Johan L鰂berg
% $Id: mpower.m,v 1.12 2005/04/14 22:07:38 joloef Exp $
if x.n~=x.m
error('Matrix must be square.')
end
% Trivial cases
if d==0
y = eye(x.n,x.m)^0;
return
end
if d==1
y = x;
return
end
% Fractional and negative powers
if (ceil(d)-d>0) | (d<0)
if x.n>1 | x.m>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);
%previous_var = find((mt(:,var)==d) & (sum(mt~=0,2)==1));
hash = randn(size(mt,2),1);
hashM = mt*hash;
hashV = (mt(var,:)*d)*hash;
previous_var = find(abs(hashM - hashV) < 1e-20);
%previous_var = findrows(mt,mt(var,:)*d)
%previous_var = findrows(mt,mt(var,:)*d);
if isempty(previous_var)
newmt = mt(getvariables(x),:)*d;
mt(end+1,:) = newmt;
%yalmip('setmonomtable',mt);
yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]);
y = recover(size(mt,1));
else
y = recover(previous_var);
end
else % Bummer, something more complex, add an internal equality constraint
y = (yalmip('addextendedvariable','mpower',x))^d;
end
end
return
end
% Integer power of matrix
if x.n>1 | x.m>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;
hash = randn(size(mt,2),1);
mt_hash = mt*hash;
previous_var = find(mt_hash == (d*mt(var,:))*hash);
if isempty(previous_var)
newmt = mt(var,:)*d;
mt(end+1,:) = newmt;
yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]);
% yalmip('setmonomtable',mt);
y = x;
y.lmi_variables = size(mt,1);
else
y = x;
y.lmi_variables = previous_var;
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)
%mt = internal_sdpvarstate.monomtable;
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 + -