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

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

Added original make3d

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