www.gusucode.com > rctlmi 工具箱 matlab源码程序 > rctlmi/lmivar.m
function [varID,ndec,Xdec]=lmivar(type,vstruct) % LMIVAR Create a new matrix-valued variable in LMI system % % X= LMIVAR(TYPE,STRUCT) adds a new matrix variable X to the LMI system % currently specified (see SETLMIS). You can use the identifier X for % subsequent references to the variable X in calls to LMITERM. % % [X,NDEC,XDEC] = LMIVAR(TYPE,STRUCT) also returns the total number of % decision variables associated with X, NDEC, and the entry-wise % dependence of X on these decision variables, XDEC. % % Input: % TYPE Structure of X: % 1 -> symmetric block diagonal % 2 -> full rectangular % 3 -> other % STRUCT Additional data on the structure of X % TYPE=1: the i-th row of STRUCT describes the i-th diagonal block % of X % STRUCT(i,1) -> block size % STRUCT(i,2) -> block type, i.e., % 0 for scalar blocks t*I % 1 for full block % -1 for zero block % TYPE=2: STRUCT = [M,N] if X is a MxN matrix % TYPE=3: STRUCT is a matrix of the same dimension as X % where STRUCT(i,j) is either % 0 if X(i,j) = 0 % +n if X(i,j) = n-th decision variable % -n if X(i,j) = (-1)* n-th decision var % Output: % X Optional: Identifier for the new matrix variable. % Its value is k if k-1 matrix variables have already % been declared. This identifier is not affected by % subsequent modifications of the LMI system % NDEC total number of decision variables so far % XDEC entry-wise dependence of X on the decision variables % (Xdec = STRUCT for Type 3) % % Examples: % % Create a 2x2 full symmetric matrix variable % X=lmivar(1,[2 1]) % % % Create a 2x3 matrix variable Y % Y=lmivar(2,[2 3]) % % % Create a 3x3 diagonal matrix Z % Z=lmivar(1,[3 0]); % % See also SETLMIS, LMITERM, GETLMIS, LMIEDIT, DECINFO. % Authors: P. Gahinet and A. Nemirovski 3/95 % Copyright 1995-2014 The MathWorks, Inc. % Get builder data hLMI = LMI_BUILDER.getInstance(); GLZ_HEAD = hLMI.Header; GLZ_LMIV = hLMI.Variables; if nargin~=2 error('usage: X = lmivar(type,struct)'); elseif ~any(type==[1 2 3]) error('TYPE must be either 1, 2, or 3'); elseif numel(GLZ_HEAD)~=10 error('Use SETLMIS to initialize the LMI system'); end L=GLZ_HEAD(2); % number of variables currently defined % get first dec. var available if L==0, first=0; else first=max(GLZ_LMIV(4,:)); end % label the new variable if isempty(GLZ_LMIV), varID=1; else varID=max(GLZ_LMIV(1,:))+1; end if type==1 % symmetric block diagonal if size(vstruct,2)~=2 error('STRUCT must be a Nx2 matrix when TYPE=1'); end s=vstruct(:,1); % block sizes btype=vstruct(:,2); % block types nblocks=size(vstruct,1); if ~all(btype==0 | btype==1 | btype==-1) error('STRUCT(i,2) must be 0, 1, or -1 when TYPE=1'); elseif nblocks==1 && btype==-1 error('This variable is the zero matrix'); else nfree=sum((btype==0)+(btype==1).*s.*(s+1)/2); ndec=first+nfree; newvar=[varID;type;first;ndec;... sum(s)*[1;1];nblocks;ma2ve(vstruct,2)]; end if nargout==3 Xdec=[]; base=first; for t=vstruct' if ~t(2) % scalar block Xdec=blkdiag(Xdec,(base+1)*eye(t(1))); base=base+1; elseif t(2)==1 % full symmetric bloc nvar=t(1)*(t(1)+1)/2; Xdec=blkdiag(Xdec,ve2ma(base+1:base+nvar,1)); base=base+nvar; else % zero block Xdec=blkdiag(Xdec,zeros(t(1))); end end end elseif type==2 % full rectangular if size(vstruct,1)+size(vstruct,2) ~= 3 error('STRUCT must be a vector of length 2 when TYPE=2'); else m=vstruct(1); n=vstruct(2); ndec=first+m*n; newvar=[varID;type;first;ndec;m;n]; end if nargout==3, Xdec=ve2ma(first+1:ndec,2,[m,n]); end else % other if isempty(vstruct) || max(max(abs(vstruct)))==0, varID=[]; return, end % detect symmetric patterns if isymm(vstruct), type=31; else type=32; end [m,n]=size(vstruct); %%% v4 code % vec(:)=vstruct'; %%% v5 code tmpstruct = vstruct'; vec = tmpstruct(:); first=min(abs(vec(vec~=0)))-1; ndec=max(abs(vec)); newvar=[varID;type;first;ndec;m;n;vec]; Xdec=vstruct; end cdim=size(GLZ_LMIV,2); lnew=length(newvar); if L==cdim % reallocate GLZ_LMIV(max(size(GLZ_LMIV,1),lnew),max(5,2*cdim))=0; end GLZ_LMIV(1:lnew,L+1)=newvar; GLZ_HEAD(2)=GLZ_HEAD(2)+1; hLMI.Header = GLZ_HEAD; hLMI.Variables = GLZ_LMIV;