[37] | 1 | function 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 | |
---|
| 49 | superiorto('sdpvar'); |
---|
| 50 | if nargin==0 |
---|
| 51 | return |
---|
| 52 | end |
---|
| 53 | |
---|
| 54 | if isstruct(varargin{1}) |
---|
| 55 | sys = class(varargin{1},'ncvar'); |
---|
| 56 | return |
---|
| 57 | end |
---|
| 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 | |
---|
| 67 | conicinfo = [0 0]; |
---|
| 68 | |
---|
| 69 | if 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 |
---|
| 114 | end |
---|
| 115 | |
---|
| 116 | % ************************************************************************* |
---|
| 117 | % Maybe new NDSDPVAR syntax |
---|
| 118 | % ************************************************************************* |
---|
| 119 | if nargin > 2 & isa(varargin{3},'double') & ~isempty(varargin{3}) |
---|
| 120 | sys = ndsdpvar(varargin{:}); |
---|
| 121 | return |
---|
| 122 | end |
---|
| 123 | |
---|
| 124 | |
---|
| 125 | % Supported matrix types |
---|
| 126 | % - symm |
---|
| 127 | % - full |
---|
| 128 | % - skew |
---|
| 129 | % - hank |
---|
| 130 | % - toep |
---|
| 131 | switch 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'); |
---|
| 411 | end |
---|
| 412 | |
---|
| 413 | if isempty(n) | isempty(m) |
---|
| 414 | error('Size must be integer valued') |
---|
| 415 | end; |
---|
| 416 | if ~((abs((n-ceil(n)))+ abs((m-ceil(m))))==0) |
---|
| 417 | error('Size must be integer valued') |
---|
| 418 | end |
---|
| 419 | |
---|
| 420 | nonCommutingTable = yalmip('nonCommutingTable'); |
---|
| 421 | [monomtable,variabletype] = yalmip('monomtable'); |
---|
| 422 | lmi_variables = (1:nvar)+max(size(nonCommutingTable,1),size(monomtable,1)); |
---|
| 423 | |
---|
| 424 | for 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 | |
---|
| 644 | end |
---|
| 645 | |
---|
| 646 | % Update noncommuting table and monomtables |
---|
| 647 | nonCommutingTable(lmi_variables,1) = nan; |
---|
| 648 | nonCommutingTable(lmi_variables,2) = lmi_variables; |
---|
| 649 | yalmip('nonCommutingTable',nonCommutingTable); |
---|
| 650 | variabletype(lmi_variables) = 0; |
---|
| 651 | monomtable(lmi_variables(end),lmi_variables(end)) = 0; |
---|
| 652 | yalmip('setmonomtable',monomtable,variabletype); |
---|
| 653 | |
---|
| 654 | |
---|
| 655 | % Create an object |
---|
| 656 | if 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 |
---|
| 675 | else |
---|
| 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 |
---|
| 696 | end |
---|