source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/opt/yalmip/extras/@ncvar/ncvar.m @ 37

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

Added original make3d

File size: 21.4 KB
Line 
1function sys = sdpvar(varargin)
2%SDPVAR Create symbolic decision variable
3%
4%   You can create a sdpvar variable by:
5%     X = SDPVAR(n)               Symmetric nxn matrix
6%     X = SDPVAR(n,n)             Symmetric nxn matrix
7%     X = SDPVAR(n,m)             Full nxm matrix (n~=m)
8%
9%   Definition of multiple scalars can be simplified
10%     SDPVAR x y z w
11%
12%   The parametrizations supported are
13%     X = SDPVAR(n,n,'full')      Full nxn matrix
14%     X = SDPVAR(n,n,'symmetric') Symmetric nxn matrix
15%     X = SDPVAR(n,n,'toeplitz')  Symmetric Toeplitz
16%     X = SDPVAR(n,n,'hankel')    Symmetric Hankel
17%     X = SDPVAR(n,n,'skew')      Skew-symmetric
18%
19%   The letters 'sy','f','ha', 't' and 'sk' are searched for in the third argument
20%   hence sdpvar(n,n,'toeplitz') gives the same result as sdpvar(n,n,'t')
21%
22%   Only square Toeplitz and Hankel matries are supported
23%
24%   A scalar is defined as a 1x1 matrix
25%
26%   Higher-dimensional matrices are also supported, although this currently
27%   is an experimental feature with limited use. The type flag applies to
28%   the lowest level slice.
29%
30%     X = SDPVAR(n,n,n,'full')      Full nxnxn matrix
31%
32%   In addition to the matrix type, a fourth argument
33%   can be used to obtain a complex matrix. All the
34%   matrix types above apply to a complex matrix, and
35%   in addition a Hermitian type is added
36%
37%     X = SDPVAR(n,n,'hermitian','complex') Complex Hermitian nxn matrix (X=X'=conj(X.'))
38%
39%   The other types are obtained as above
40%     X = SDPVAR(n,n,'symmetric','complex') Complex symmetric nxn matrix (X=X.')
41%     X = SDPVAR(n,n,'full','complex')      Complex full nxn matrix
42%     ... and the same for Toeplitz, Hankel and skew-symmetric
43%
44%   See also @SDPVAR/SET, INTVAR, BINVAR, methods('sdpvar'), SEE
45
46% Author Johan Löfberg
47% $Id: ncvar.m,v 1.4 2006/08/28 13:48:38 joloef Exp $
48
49superiorto('sdpvar');
50if nargin==0   
51    return
52end
53
54if isstruct(varargin{1})
55    sys = class(varargin{1},'ncvar');
56    return
57end
58
59% To speed up dualization, we keep track of primal SDP cones
60% [0 0] :  Nothing known (cleared in some operator, or none-cone to start with)
61% [1 0] :  Primal cone
62% [1 1] :  Primal cone + DOUBLE
63% [1 2 x] :  Primal cone + SDPVAR
64% [-1 1] : -Primal cone + DOUBLE
65% [-1 2 x] : -Primal cone + SDPVAR
66
67conicinfo = [0 0];
68
69if ischar(varargin{1})
70    switch varargin{1}
71        case 'clear'
72            disp('Obsolete comand');
73            return
74        case 'nvars'
75            sys = yalmip('nvars');%THIS IS OBSAOLETE AND SHOULD NOT BE USED
76            return
77        otherwise
78            n = length(varargin);
79            varnames = varargin;
80            for k = 1:n
81                varcmd{k}='(1,1)';
82                lp=findstr(varargin{k},'(');
83                rp=findstr(varargin{k},')');
84                if isempty(lp) & isempty(rp)
85                    if ~isvarname(varargin{k})
86                        error('Not a valid variable name.')
87                    end
88                else
89                    if (~isempty(lp))&(~isempty(rp))
90                        if min(lp)<max(rp)
91                            varnames{k} = varargin{k}(1:lp-1);
92                            varcmd{k}=varargin{k}(lp:rp);
93                        else
94                            error('Not a valid variable name.')
95                        end
96                    else
97                        error('Not a valid variable name.')
98                    end
99                end
100            end
101            for k = 1:n
102                if isequal(varnames{k},'i') | isequal(varnames{k},'j')
103                    if length(dbstack) == 1
104                        assignin('caller',varnames{k},eval(['sdpvar' varcmd{k}]));
105                    else
106                        error(['Due to a bug in MATLAB, use ' varnames{k} ' = sdpvar' varcmd{k} ' instead.']);
107                    end
108                else                   
109                    assignin('caller',varnames{k},eval(['ncvar' varcmd{k}]));
110                end
111            end
112            return
113    end
114end
115
116% *************************************************************************
117% Maybe new NDSDPVAR syntax
118% *************************************************************************
119if nargin > 2 & isa(varargin{3},'double') & ~isempty(varargin{3})
120    sys = ndsdpvar(varargin{:});
121    return
122end
123
124
125% Supported matrix types
126% - symm
127% - full
128% - skew
129% - hank
130% - toep
131switch nargin
132    case 1 %Bug in MATLAB 5.3!! sdpvar called from horzcat!!!!????
133        if isempty(varargin{1})
134            sys = varargin{1};
135            return
136        end
137        if isa(varargin{1},'sdpvar')
138            sys = varargin{1};
139            sys.typeflag = 0;
140            return
141        end
142        n = varargin{1};
143        m = varargin{1};
144        if sum(n.*m)==0
145            sys = zeros(n,m);
146            return
147        end
148        if (n==m)
149            matrix_type = 'symm';
150            nvar = sum(n.*(n+1)/2);
151            conicinfo = [1 0];
152        else
153            matrix_type = 'full';
154            nvar = sum(n.*m);
155        end
156    case 2
157        n = varargin{1};
158        m = varargin{2};
159        if length(n)~=length(m)
160            error('The dimensions must have the same lengths')
161        end
162        if sum(n.*m)==0
163            sys = zeros(n,m);
164            return
165        end
166        if (n==m)
167            matrix_type = 'symm';
168            nvar = sum(n.*(n+1)/2);
169            conicinfo = [1 0];
170        else
171            matrix_type = 'full';
172            nvar = sum(n.*m);
173        end
174    case {3,4}
175        n = varargin{1};
176        m = varargin{2};
177        if sum(n.*m)==0
178            sys = zeros(n,m);
179            return
180        end
181
182        % Check for complex or real
183        if (nargin == 4)
184            if isempty(varargin{4})
185                varargin{4} = 'real';
186            else
187                if ~ischar(varargin{4})
188                    help sdpvar
189                    error('Fourth argument should be ''complex'' or ''real''')
190                end
191            end
192            index_cmrl = strmatch(varargin{4},{'real','complex'});
193            if isempty(index_cmrl)
194                error('Fourth argument should be ''complex'' or ''real''. See help above')
195            end
196        else
197            if ~ischar(varargin{3})
198                help sdpvar
199                error('Third argument should be ''symmetric'', ''full'', ''hermitian'',...See help above')
200            end
201            index_cmrl = 1;
202        end;
203
204        if isempty(varargin{3})
205            if n==m
206                index_type = 7; %Default symmetric
207            else
208                index_type = 4;
209            end
210        else
211            if ~isempty(strmatch(varargin{3},{'complex','real'}))
212                % User had third argument as complex or real
213                error(['Third argument should be ''symmetric'', ''full'', ''toeplitz''... Maybe you meant sdpvar(n,n,''full'',''' varargin{3} ''')'])
214            end
215            index_type = strmatch(varargin{3},{'toeplitz','hankel','symmetric','full','rhankel','skew','hermitian'});
216        end
217
218        if isempty(index_type)
219            error(['Matrix type "' varargin{3} '" not supported'])
220        else
221            switch index_type+100*(index_cmrl-1)
222                case 1
223                    if n~=m
224                        error('Toeplitz matrix must be square')
225                    else
226                        matrix_type = 'toep';
227                        nvar = n;
228                    end
229
230                case 2
231                    if n~=m
232                        error('Hankel matrix must be square')
233                    else
234                        matrix_type = 'hank';
235                        nvar = n;
236                    end
237
238                case 3
239                    if n~=m
240                        error('Symmetric matrix must be square')
241                    else
242                        matrix_type = 'symm';
243                        nvar = sum(n.*(n+1)/2);
244                    end
245
246                case 4
247                    matrix_type = 'full';
248                    nvar = sum(n.*m);
249                    if nvar==1
250                        matrix_type = 'symm';
251                    end
252
253                case 5
254                    if n~=m
255                        error('Hankel matrix must be square')
256                    else
257                        matrix_type = 'rhankel';
258                        nvar = 2*n-1;
259                    end
260
261                case 6
262                    if n~=m
263                        error('Skew symmetric matrix must be square')
264                    else
265                        matrix_type = 'skew';
266                        nvar = (n*(n+1)/2)-n;
267                    end
268
269                case 7
270                    if n~=m
271                        error('Symmetric matrix must be square')
272                    else
273                        matrix_type = 'symm';
274                        nvar = n*(n+1)/2;
275                    end
276
277                case 101
278                    if n~=m
279                        error('Toeplitz matrix must be square')
280                    else
281                        matrix_type = 'toep complex';
282                        nvar = 2*n;
283                    end
284
285                case 102
286                    if n~=m
287                        error('Hankel matrix must be square')
288                    else
289                        matrix_type = 'hank complex';
290                        nvar = (2*n);
291                    end
292
293                case 103
294                    if n~=m
295                        error('Symmetric matrix must be square')
296                    else
297                        matrix_type = 'symm complex';
298                        nvar = 2*n*(n+1)/2;
299                    end
300
301                case 104
302                    matrix_type = 'full complex';
303                    nvar = 2*n*m;
304                    if nvar==1
305                        matrix_type = 'symm complex';
306                    end
307
308                case 105
309                    if n~=m
310                        error('Hankel matrix must be square')
311                    else
312                        matrix_type = 'rhankel complex';
313                        nvar = 2*(2*n-1);
314                    end
315
316                case 106
317                    if n~=m
318                        error('Skew symmetric matrix must be square')
319                    else
320                        matrix_type = 'skew complex';
321                        nvar = 2*((n*(n+1)/2)-n);
322                    end
323
324                case 107
325                    if n~=m
326                        error('Hermitian matrix must be square')
327                    else
328                        matrix_type = 'herm complex';
329                        nvar = n*(n+1)/2+(n*(n+1)/2-n);
330                    end
331
332
333                otherwise
334                    error('Bug! Report!');
335            end
336
337        end
338
339    case 5 % Fast version for internal use
340        sys.basis = varargin{5};
341        sys.lmi_variables=varargin{4};
342        sys.dim(1) = varargin{1};
343        sys.dim(2) = varargin{2};
344        sys.typeflag = 0;
345        sys.savedata = [];
346        sys.extra = [];
347        sys.extra.expanded = [];
348        sys.conicinfo = 0;
349        % Find zero-variables
350        constants = find(sys.lmi_variables==0);
351        if ~isempty(constants);
352            sys.lmi_variables(constants)=[];
353            sys.basis(:,1) = sys.basis(:,1) + sum(sys.basis(:,1+constants),2);
354            sys.basis(:,1+constants)=[];
355        end
356        if isempty(sys.lmi_variables)
357            sys = full(reshape(sys.basis(:,1),sys.dim(1),sys.dim(2)));
358        else
359            sys = class(sys,'sdpvar');
360        end
361        return
362    case 6 % Fast version for internal use
363        sys.basis = varargin{5};
364        sys.lmi_variables=varargin{4};
365        sys.dim(1) = varargin{1};
366        sys.dim(2) = varargin{2};
367        sys.typeflag = varargin{6};
368        sys.savedata = [];
369        sys.extra = [];
370        sys.extra.expanded = [];       
371        sys.conicinfo = 0;
372        % Find zero-variables
373        constants = find(sys.lmi_variables==0);
374        if ~isempty(constants);
375            sys.lmi_variables(constants)=[];
376            sys.basis(:,1) = sys.basis(:,1) + sum(sys.basis(:,1+constants),2);
377            sys.basis(:,1+constants)=[];
378        end
379        if isempty(sys.lmi_variables)
380            sys = full(reshape(sys.basis(:,1),sys.dim(1),sys.dim(2)));
381        else
382            sys = class(sys,'sdpvar');
383        end
384        return
385    case 7 % Fast version for internal use
386        sys.basis = varargin{5};
387        sys.lmi_variables=varargin{4};
388        sys.dim(1) = varargin{1};
389        sys.dim(2) = varargin{2};
390        sys.typeflag = varargin{6};
391        sys.savedata = [];
392        sys.extra = varargin{7};
393        sys.extra.expanded = [];       
394        sys.conicinfo = varargin{7};
395        % Find zero-variables
396        constants = find(sys.lmi_variables==0);
397        if ~isempty(constants);
398            sys.lmi_variables(constants)=[];
399            sys.basis(:,1) = sys.basis(:,1) + sum(sys.basis(:,1+constants),2);
400            sys.basis(:,1+constants)=[];
401        end
402        if isempty(sys.lmi_variables)
403            sys = full(reshape(sys.basis(:,1),sys.dim(1),sys.dim(2)));
404        else
405            sys = class(sys,'sdpvar');
406        end
407        return
408
409    otherwise
410        error('Wrong number of arguments in sdpvar creation');
411end
412
413if isempty(n) | isempty(m)
414    error('Size must be integer valued')
415end;
416if ~((abs((n-ceil(n)))+ abs((m-ceil(m))))==0)
417    error('Size must be integer valued')
418end
419
420nonCommutingTable = yalmip('nonCommutingTable');
421[monomtable,variabletype] = yalmip('monomtable');
422lmi_variables = (1:nvar)+max(size(nonCommutingTable,1),size(monomtable,1));
423
424for blk = 1:length(n)
425    switch matrix_type
426
427        case 'full'
428            basis{blk} = [spalloc(n(blk)*m(blk),1,0) speye(n(blk)*m(blk))];%speye(nvar)];
429
430        case 'full complex'
431            basis = [spalloc(n*m,1,0) speye(nvar/2) speye(nvar/2)*sqrt(-1)];
432
433        case 'symm'
434            if 0
435                basis = spalloc(n^2,1+nvar,n^2);
436                l = 2;
437                an_empty = spalloc(n,n,2);
438                for i=1:n
439                    temp = an_empty;
440                    temp(i,i)=1;
441                    basis(:,l)=temp(:);
442                    l = l+1;
443                    for j=i+1:n,
444                        temp = an_empty;
445                        temp(i,j)=1;
446                        temp(j,i)=1;
447                        basis(:,l)=temp(:);
448                        l = l+1;
449                    end
450                end
451            else
452                % Hrm...fast but completely f*d up
453
454                Y = reshape(1:n(blk)^2,n(blk),n(blk));
455                Y = tril(Y);
456                Y = (Y+Y')-diag(sparse(diag(Y)));
457                [uu,oo,pp] = unique(Y(:));
458                if 1
459                    basis{blk} = sparse(1:n(blk)^2,pp+1,1);
460                else                   
461                    basis{blk} = lazybasis(n^2,1+(n*(n+1)/2),1:n(blk)^2,pp+1,ones(n(blk)^2,1));
462                end
463             
464            end
465           
466        case 'symm complex'
467            basis = spalloc(n^2,1+nvar,2);
468            l = 2;
469            an_empty = spalloc(n,n,2);
470            for i=1:n
471                temp = an_empty;
472                temp(i,i)=1;
473                basis(:,l)=temp(:);
474                l = l+1;
475                for j=i+1:n,
476                    temp = an_empty;
477                    temp(i,j)=1;
478                    temp(j,i)=1;
479                    basis(:,l)=temp(:);
480                    l = l+1;
481                end
482            end
483            for i=1:n
484                temp = an_empty;
485                temp(i,i)=sqrt(-1);
486                basis(:,l)=temp(:);
487                l = l+1;
488                for j=i+1:n,
489                    temp = an_empty;
490                    temp(i,j)=sqrt(-1);
491                    temp(j,i)=sqrt(-1);
492                    basis(:,l)=temp(:);
493                    l = l+1;
494                end
495            end
496
497        case 'herm complex'
498            basis = spalloc(n^2,1+nvar,2);
499            l = 2;
500            an_empty = spalloc(n,n,2);
501            for i=1:n
502                temp = an_empty;
503                temp(i,i)=1;
504                basis(:,l)=temp(:);
505                l = l+1;
506                for j=i+1:n,
507                    temp = an_empty;
508                    temp(i,j)=1;
509                    temp(j,i)=1;
510                    basis(:,l)=temp(:);
511                    l = l+1;
512                end
513            end
514            for i=1:n
515                for j=i+1:n,
516                    temp = an_empty;
517                    temp(i,j)=sqrt(-1);
518                    temp(j,i)=-sqrt(-1);
519                    basis(:,l)=temp(:);
520                    l = l+1;
521                end
522            end
523
524        case 'skew'
525            basis = spalloc(n^2,1+nvar,2);
526            l = 2;
527            an_empty = spalloc(n,n,2);
528            for i=1:n
529                for j=i+1:n,
530                    temp = an_empty;
531                    temp(i,j)=1;
532                    temp(j,i)=-1;
533                    basis(:,l)=temp(:);
534                    l = l+1;
535                end
536            end
537
538        case 'skew complex'
539            basis = spalloc(n^2,1+nvar,2);
540            l = 2;
541            an_empty = spalloc(n,n,2);
542            for i=1:n
543                for j=i+1:n,
544                    temp = an_empty;
545                    temp(i,j)=1;
546                    temp(j,i)=-1;
547                    basis(:,l)=temp(:);
548                    l = l+1;
549                end
550            end
551            for i=1:n
552                for j=i+1:n,
553                    temp = an_empty;
554                    temp(i,j)=sqrt(-1);
555                    temp(j,i)=-sqrt(-1);
556                    basis(:,l)=temp(:);
557                    l = l+1;
558                end
559            end
560
561        case 'toep'
562            basis = spalloc(n^2,1+nvar,2);
563            an_empty = spalloc(n,1,1);
564            for i=1:n,
565                v = an_empty;
566                v(i)=1;
567                temp = sparse(toeplitz(v));
568                basis(:,i+1) = temp(:);
569            end
570
571            % Notice, complex Toeplitz not Hermitian
572        case 'toep complex'
573            basis = spalloc(n^2,1+nvar,2);
574            an_empty = spalloc(n,1,1);
575            for i=1:n,
576                v = an_empty;
577                v(i)=1;
578                temp = sparse(toeplitz(v));
579                basis(:,i+1) = temp(:);
580            end
581            for i=1:n,
582                v = an_empty;
583                v(i)=sqrt(-1);
584                temp = sparse(toeplitz(v));
585                basis(:,n+i+1) = temp(:);
586            end
587
588        case 'hank'
589            basis = spalloc(n^2,1+nvar,2);
590            an_empty = spalloc(n,1,1);
591            for i=1:n,
592                v = an_empty;
593                v(i)=1;
594                temp = sparse(hankel(v));
595                basis(:,i+1) = temp(:);
596            end
597
598        case 'hank complex'
599            basis = spalloc(n^2,1+nvar,2);
600            an_empty = spalloc(n,1,1);
601            for i=1:n,
602                v = an_empty;
603                v(i)=1;
604                temp = sparse(hankel(v));
605                basis(:,i+1) = temp(:);
606            end
607            for i=1:n,
608                v = an_empty;
609                v(i)=sqrt(-1);
610                temp = sparse(hankel(v));
611                basis(:,n+i+1) = temp(:);
612            end
613
614        case 'rhankel'
615            basis = spalloc(n^2,1+nvar,2);
616            an_empty = spalloc(2*n-1,1,1);
617            for i=1:nvar,
618                v = an_empty;
619                v(i)=1;
620                temp = sparse(hankel(v(1:n),[v(n);v(n+1:2*n-1)]));
621                basis(:,i+1) = temp(:);
622            end
623
624        case 'rhankel complex'
625            basis = spalloc(n^2,1+nvar,2);
626            an_empty = spalloc(2*n-1,1,1);
627            for i=1:nvar/2,
628                v = an_empty;
629                v(i)=1;
630                temp = sparse(hankel(v(1:n),[v(n);v(n+1:2*n-1)]));
631                basis(:,i+1) = temp(:);
632            end
633            for i=1:nvar/2,
634                v = an_empty;
635                v(i)=sqrt(-1);
636                temp = sparse(hankel(v(1:n),[v(n);v(n+1:2*n-1)]));
637                basis(:,nvar/2+i+1) = temp(:);
638            end
639
640        otherwise
641            error('Bug! Report')
642    end
643
644end
645
646% Update noncommuting table and monomtables
647nonCommutingTable(lmi_variables,1) = nan;
648nonCommutingTable(lmi_variables,2) = lmi_variables;
649yalmip('nonCommutingTable',nonCommutingTable);
650variabletype(lmi_variables) = 0;
651monomtable(lmi_variables(end),lmi_variables(end)) = 0;
652yalmip('setmonomtable',monomtable,variabletype);
653
654
655% Create an object
656if isa(basis,'cell')
657    top = 1;
658    for blk = 1:length(n)
659        sys{blk}.basis=basis{blk};
660        nn = size(sys{blk}.basis,2)-1;
661        sys{blk}.lmi_variables = lmi_variables(top:top+nn-1);
662        top = top + nn;
663        sys{blk}.dim(1) = n(blk);
664        sys{blk}.dim(2) = m(blk);
665        sys{blk}.typeflag = 0;
666        sys{blk}.savedata = [];
667        sys{blk}.extra = [];
668        sys{blk}.extra.expanded = [];       
669        sys{blk}.conicinfo = conicinfo;
670        sys{blk} = class(sys{blk},'ncvar');
671    end
672    if length(n)==1
673        sys = sys{1};
674    end
675else
676    sys.basis=basis;
677    sys.lmi_variables = lmi_variables;
678    sys.dim(1) = n;
679    sys.dim(2) = m;
680    sys.typeflag = 0;
681    sys.savedata = [];
682    sys.extra = [];
683    sys.extra.expanded = [];   
684    sys.conicinfo = conicinfo;
685    sys = class(sys,'ncvar');
686    if ~isreal(basis)
687        % Add internal information about complex pairs
688        complex_elements = find(any(imag(basis),2));
689        complex_pairs = [];
690        for i = 1:length(complex_elements)
691            complex_pairs = [complex_pairs;lmi_variables(find(basis(complex_elements(i),:))-1)];
692        end
693        complex_pairs = uniquesafe(complex_pairs,'rows');
694        yalmip('addcomplexpair',complex_pairs);
695    end
696end
Note: See TracBrowser for help on using the repository browser.