function [B,C,E]=verrankdec(A) % VERRANKDEC Verified rank decomposition of a rectangular real matrix. % % This is an INTLAB file. It requires to have INTLAB installed under % MATLAB to function properly. % % For a rectangular m-by-n real matrix A, % [B,C,E]=verrankdec(A) % computes a real m-by-r matrix B and an interval r-by-n matrix C % verified to contain a real matrix Co such that % A=B*Co % holds in exact arithmetic. Moreover, r is the verified rank of A, B has % linearly independent columns and Co has linearly independent rows (a % rank decomposition of A). If no verified result is found, then B, C % consist of NaN's. % % The structure E explains reasons for NaN output. % % See also RREF, VERFULLCOLRANK, RANK, VERRANK, VERPINV. % Copyright 2008 Jiri Rohn. % % WARRANTY % % Because the program is licensed free of charge, there is % no warranty for the program, to the extent permitted by applicable % law. Except when otherwise stated in writing the copyright holder % and/or other parties provide the program "as is" without warranty % of any kind, either expressed or implied, including, but not % limited to, the implied warranties of merchantability and fitness % for a particular purpose. The entire risk as to the quality and % performance of the program is with you. Should the program prove % defective, you assume the cost of all necessary servicing, repair % or correction. % % History % % 2008-04-12 first version % 2008-04-18 version for posting % gr=getround; setround(0); [m,n]=size(A); B=repmat(NaN,m,n); C=repmat(NaN,n,n); E.error='verrankdec: none'; E.where='NaN'; E.value='NaN'; if (nargin~=1)||(nargout>3)||~isreal(A)||isintval(A) E.error='verrankdec: wrong data'; setround(gr); return end if issparse(A) A=full(A); % sparse not implemented end [AR,K]=rref(A); % K index set of the expected basis (later B) if isempty(K) % no basis index set found E.error='verrankdec: no basis index set found'; setround(gr); return end % K nonempty B=A(:,K); % expected basis fcr=verfullcolrank(B); if fcr~=1 % columns of B not verified linearly independent B=repmat(NaN,m,n); E.error='verrankdec: columns of expected basis B not verified linearly independent'; setround(gr); return end % columns of B verified linearly independent [Bp,Everpinv]=verpinv(B); if isnan(Bp.inf(1,1)) % pseudoinverse of B not computed B=repmat(NaN,m,n); E=Everpinv; setround(gr); return end % pseudoinverse of B computed (intval quantity) r=length(K); C=repmat(intval(0),r,n); Ir=intval(eye(r,r)); for j=1:n if ~any(K==j) % j not in K fcr=verfullcolrank([B A(:,j)]); if fcr~=0 % columns of [B A(:,j)] not verified linearly dependent B=repmat(NaN,m,n); C=repmat(NaN,n,n); E.error='verrankdec: j-th column of A not verified to belong to the range space of B'; E.where=['j = ',int2str(j)]; setround(gr); return end % A(:,j) verified to belong to the range space of B C(:,j)=Bp*A(:,j); % intval quantity else % j in K i=find(K==j); % j at the i-th place of K C(:,j)=Ir(:,i); end end % first enclosure C found % as a by-product, r is the verified rank of A % second enclosure B0=intval(B); BTBi=inv(B0'*B0); if isnan(BTBi.inf(1,1)) % inverse not computed E.where='only first enclosure outputed'; setround(gr); return % first enclosure outputed end % inverse computed C1=(BTBi*B')*A; % A=B*C implies B'*A=B'*B*C implies C=inv(B'*B)*B'*A C2=intersect(C,C1); % intersection of the two enclosures if any(any(isnan(C2))) % to be sure E.where='only first enclosure outputed'; setround(gr); return % first enclosure outputed else C=C2; % intersection outputed end % verified A=B*Co, Co in C, B having linearly independent columns setround(gr);