function y = mpower(x,d) %MPOWER (overloaded) if (numel(d)>1) || (size(x,1) ~= size(x,2)) error('Inputs must be a scalar and a square matrix. To compute elementwise POWER, use POWER (.^) instead.'); end if isa(d,'sdpvar') if numel(x) > 1 if isa(x,'sdpvar') error('x^d not support SDPVARMATRIX^SDPVARSCALAR') else if isnumeric(x) [V,D] = eig(x); if ~isreal(D) error('Matrix power x^d requires x to have real eigenvalues'); end D = real(D); y = V*diag(diag(D).^d)*inv(V); y.extra.createTime = definecreationtime; return else error('Object class not support in x^d'); end end end d = flush(d);d.conicinfo = [0 0]; y = power_internal1(d,x); if isa(y,'sdpvar') y.extra.createTime = definecreationtime; end return end x = flush(x); % Trivial cases if d==0 y = eye(x.dim(1),x.dim(2))^0; return end if d==1 y = x; return end % Check for special case norm(x)^2 which many users try to do if d==2 if length(x)==1 base = getbase(x); if isequal(base,[0 1]) if strcmp(x.extra.opname,'norm') model = yalmip('extstruct',getvariables(x)); z = model.arg{1}; if (isequal(model.arg{2},2) & min(size(z))==1) | isequal(model.arg{2},'fro') z = reshape(model.arg{1},[],1); y = real(z'*z); y.extra.createTime = definecreationtime; return end end end end 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,hashM,hash] = 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 y.extra.createTime = definecreationtime; 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,hashes,hash] = yalmip('monomtable'); var = x.lmi_variables; newmt = mt(var,:)*d; newhash = newmt*hash; previous_var = findhash(hashes , newhash,length(hashes)); if isempty(previous_var) mt = [mt;newmt]; yalmip('setmonomtable',mt,[variabletype newvariabletypegen(newmt)]); 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; case 2 y = x*x; otherwise if even(d) z = mpower(x,d/2); y = z*z; else y = x*mpower(x,d-1); end end end y.extra.createTime = definecreationtime; end