source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/opt/lmirank/lmirank.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 8.3 KB
Line 
1
2function [y,info] = lmirank(At,c,K,pars,y0)
3% [y,info] = lmirank(At,c,K,pars,y0);
4%
5% LMIRANK can be used to try to solve rank constrained LMI problems such as
6%
7%       F(y)>=0,                                (1)
8%       G(y)>=0,  rank G(y)<=r.                 (2)
9%
10% More precisely it can be used to try to solve feasibility problems
11% involving any number of LMI constraints and one or more rank constraints.
12%
13% LMI data is entered in standard SeDuMi format. Rank constraints are entered
14% using K.rank. For example,
15%
16%   K.s=[4 7 6]; K.rank=[4 4 6];
17%
18% specifies 3 LMI constraints with the 2nd LMI constrained to have rank <= 4.
19%
20% LP inequality constraints can also be included.
21%
22% LMIRANK can be called using any of following
23%    [y,info] = lmirank(At,c,K,pars,y0);
24%    [y,info] = lmirank(At,c,K);
25%    [y,info] = lmirank(At,c,K,pars);
26%    [y,info] = lmirank(At,c,K,y0);
27%
28% Inputs:
29%       At,c,K.l,K.s    : data in SeDuMi format
30%       K.rank          : rank constraints
31% Optional Inputs:
32%       pars.maxiter    : max. no. of iterations, default is 1000
33%       pars.eps        : constraint tolerance, default is 1e-9
34%       pars.fid        : set to 0 to suppress on-screen output. The default
35%                         is 1 which displays on-screen output.
36%       pars.itermod    : output results to screen every pars.itermod
37%                         iterations, default is 1   
38%       y0              : initial condition
39%                         (If y0 is not given, the trace heuristic is
40%                          used to initialize the algorithm. SeDuMi is
41%                          used to do this calculation and hence must
42%                          be installed if y0 is not given.)
43% Outputs:
44%       y           : solution
45%       info.solved : 1 if a solution was found, 0 otherwise
46%       info.cpusec : solution time
47%       info.iters  : no. of iterations required to find a solution
48%       info.gap    : constraint gap
49%       info.rank   : ranks (with respect to tolerance pars.eps)
50%
51% The algorithm is described in
52%       R. Orsi, U. Helmke, and J. B. Moore. A Newton-like method for solving
53%       rank constrained linear matrix inequalities. In Proceedings of the
54%       43rd IEEE Conference on Decision and Control, pages 3138-3144,
55%       Paradise Island, Bahamas, 2004. 
56%
57% Algorithm notes
58%   1. Projection onto the set B (see Section V.C of the paper) is now done
59%      in a much simpler manner. (It still results in a linearly constrained
60%      least squares problem.)
61%   2. The above paper describes only the basic case given by (1) and (2)
62%      above, i.e., it does not deal with multiple non-rank constrained LMIs,
63%      multiple rank constrained LMIs, or LP inequality constraints.
64%
65%Feedback should be sent to robert.orsi@anu.edu.au
66
67% Author Robert Orsi
68% Feb 2005
69
70
71t=cputime;
72
73%%%% If no LP ineq. constraints are present, set K.l=0
74if ~isfield(K,'l')
75    K.l=0;
76end
77
78%%%% Set unspecified pars, calculate an initial condition if none given
79if nargin==3
80    pars.fid=1;
81    y = trheuristic(At,c,K);
82end
83if nargin==4
84    if isstruct(pars)
85        y = trheuristic(At,c,K);   
86    else
87        y=pars;
88        pars.fid=1;
89    end
90end
91if nargin==5
92    y=y0;
93end
94if ~isfield(pars,'maxiter') pars.maxiter=1000; end
95if ~isfield(pars,'eps') pars.eps=1e-9; end
96if ~isfield(pars,'fid') pars.fid=1; end
97if ~isfield(pars,'itermod') pars.itermod=1; end
98
99%%%% Initialize X1
100X1=c-At*y;
101         
102%%%% Calculate m
103m=size(At,2);
104
105%%%% Print output header
106fprintf(pars.fid,'\nLMIRank by Robert Orsi, 2005.\n');
107fprintf(pars.fid,'maxiter = %5d  |   rank bounds\n',pars.maxiter);
108fprintf(pars.fid,'eps = %0.2e  | ',pars.eps);
109fprintf(pars.fid,'%5d',K.rank);
110fprintf(pars.fid,'\n iter :     gap      ranks\n');
111
112%%%% MAIN LOOP
113for iters=1:pars.maxiter,
114   
115    %% Calculate DX1        : eigs of X1
116    %%
117    %%           X2LP       : proj. of LP ineq. component of X1
118    %%           X2LPindex  : index of zeroes of X2LP
119    %%           DX2        : eigs of X2.
120    %%                      : Sorted, non-neg., rank constained version of DX1   
121    %%           rankX2     : ranks of X2
122    %%
123    %%           Attrans    : At after transformation
124    %%           ctrans     : c after transformation
125    %%           Attrans2   :
126    %%           ctrans2    :
127    DX1=zeros(sum(K.s),1);
128    %
129    X2LP=max(X1(1:K.l),0);
130    X2LPindex=find(X2LP==0);
131    DX2=zeros(sum(K.s),1);
132    rankX2=zeros(length(K.s),1);
133    %
134    Attrans=zeros(size(At));
135    Attrans(1:K.l,:)=At(1:K.l,:);
136    ctrans=zeros(size(c));
137    ctrans(1:K.l)=c(1:K.l);
138    Attrans2=zeros(size(At)); % incorrect size, truncated later
139    Attrans2(1:length(X2LPindex),:)=Attrans(X2LPindex,:);
140    ctrans2=zeros(size(c)); % incorrect size, truncated later
141    ctrans2(1:length(X2LPindex))=ctrans(X2LPindex);
142    %
143    index=0;
144    index2=0;   
145    index3=length(X2LPindex);
146    for j=1:length(K.s),
147        [V,D]=eig(reshape(X1(K.l+index2+1:K.l+index2+K.s(j)^2),K.s(j),K.s(j)));
148        DX1(index+1:index+K.s(j))=diag(D);
149        [Dsort,I]=sort(-diag(D));
150        Dsort=-Dsort;
151        V=V(:,I);
152        for i=1:K.s(j),   
153            if (rankX2(j)<K.rank(j)) & (Dsort(i)>0)
154                rankX2(j)=rankX2(j)+1;
155                DX2(index+i)=Dsort(i);
156            end   
157        end
158        for k=1:m,
159            Q=V'*reshape(At(K.l+index2+1:K.l+index2+K.s(j)^2,k),K.s(j),K.s(j))*V;
160            Q=(Q+Q')/2;
161            Attrans(K.l+index2+1:K.l+index2+K.s(j)^2,k)=Q(:);
162            Attrans2(index3+1:index3+(K.s(j)-rankX2(j))^2,k)=...
163                reshape(Q(rankX2(j)+1:end,rankX2(j)+1:end),(K.s(j)-rankX2(j))^2,1);
164        end
165        Q=V'*reshape(c(K.l+index2+1:K.l+index2+K.s(j)^2),K.s(j),K.s(j))*V;
166        Q=(Q+Q')/2;
167        ctrans(K.l+index2+1:K.l+index2+K.s(j)^2)=Q(:);
168        ctrans2(index3+1:index3+(K.s(j)-rankX2(j))^2)=...
169            reshape(Q(rankX2(j)+1:end,rankX2(j)+1:end),(K.s(j)-rankX2(j))^2,1);   
170        %
171        index=index+K.s(j);
172        index2=index2+K.s(j)^2;
173        index3=index3+(K.s(j)-rankX2(j))^2;
174    end
175    %% Truncate Attrans2 and ctrans2 to correct sizes
176    q=length(X2LPindex);
177    for j=1:length(K.s),
178        q=q+(K.s(j)-rankX2(j))^2;   
179    end
180    Attrans2=Attrans2(1:q,1:m);
181    ctrans2=ctrans2(1:q,1);
182   
183    %% BREAK if a solution has been found
184    %% Decision is based on X1, not X2
185    bound= (K.l+length(DX1)) * max([abs(X1(1:K.l)); abs(DX1)]) * eps * 10;
186    bound= max(bound,pars.eps);
187    gap=min(DX1);
188    if K.l~=0
189        gap=min([gap; X1(1:K.l)]);
190    end
191    breakflag=(gap >= -bound);
192    rankX1=zeros(1,length(K.s));
193    index=0;
194    for j=1:length(K.s),
195        rankX1(j)=sum(abs(DX1(index+1:index+K.s(j)))>bound);
196        breakflag=breakflag & (rankX1(j) <= K.rank(j));
197        index=index+K.s(j);
198    end 
199    if (pars.fid)&(mod(iters,pars.itermod)==0) %% Output iters, gap & ranks
200        fprintf(pars.fid,'%5d : %0.2e ',iters,gap);
201        fprintf(pars.fid,'%5d',rankX1);
202        fprintf(pars.fid,'\n');
203    end
204    if breakflag
205        break
206    end   
207   
208    %% Calculate SVD and rank of Attrans2
209    [U,S,V]=svd(Attrans2);
210    s=diag(S);
211    tol=max(size(Attrans2))*s(1)*eps;
212    rankAttrans2=sum(s>tol);
213   
214    %% Calculate y
215    if rankAttrans2 == size(Attrans2,2),
216        y=Attrans2\ctrans2;
217    else
218        if size(Attrans2,1)~=size(Attrans2,2)
219            warning off;
220            y0=Attrans2\ctrans2;
221            warning on;
222        else
223            y0=pinv(Attrans2)*ctrans2;   
224        end
225        W=V(:,rankAttrans2+1:end);
226        e=zeros(size(c));
227        e(1:K.l)=X2LP;
228        index=0;
229        index2=K.l;
230        for j=1:length(K.s),
231            P=diag(DX2(index+1:index+K.s(j)));
232            e(index2+1:index2+K.s(j)^2)=P(:);
233            index=index+K.s(j);
234            index2=index2+K.s(j)^2;
235        end
236        q=(Attrans*W)\( ctrans - Attrans*y0 - e );
237        y=y0+W*q;
238    end
239     
240    %% Calculate new X1
241    X1=c-At*y;
242     
243end
244
245info.solved=breakflag;
246info.cpusec=cputime-t;
247info.iters=iters;
248info.gap=gap;           
249info.rank=rankX1;
250
251fprintf(pars.fid,'iters solved   seconds\n');
252fprintf(pars.fid,'%5d %4d %11.1e\n',info.iters,info.solved,info.cpusec);
Note: See TracBrowser for help on using the repository browser.