[37] | 1 | function varargout = yalmip(varargin) |
---|
| 2 | %YALMIP Returns various information about YALMIP |
---|
| 3 | % |
---|
| 4 | % YALMIP can be used to check version numbers and |
---|
| 5 | % find the SDPVAR and SET objects available in workspace |
---|
| 6 | % |
---|
| 7 | % EXAMPLES |
---|
| 8 | % [V,D] = YALMIP('version') % Returns version and release date |
---|
| 9 | % YALMIP('nvars') % Returns total number of declared variables |
---|
| 10 | % YALMIP('info') % Display basic info. |
---|
| 11 | % YALMIP('solver','tag') % Sets the solver 'solvertag' (see sdpsettings) as default solver |
---|
| 12 | % |
---|
| 13 | % See also YALMIPTEST, YALMIPDEMO |
---|
| 14 | |
---|
| 15 | % Author Johan Löfberg |
---|
| 16 | % $Id: yalmip.m,v 1.70 2006/10/24 15:16:24 joloef Exp $ |
---|
| 17 | |
---|
| 18 | persistent prefered_solver internal_sdpvarstate internal_setstate |
---|
| 19 | |
---|
| 20 | if nargin==0 |
---|
| 21 | help yalmip |
---|
| 22 | return |
---|
| 23 | end |
---|
| 24 | |
---|
| 25 | if isempty(internal_sdpvarstate) |
---|
| 26 | internal_sdpvarstate.monomtable = spalloc(0,0,0); % Polynomial powers table |
---|
| 27 | internal_sdpvarstate.hashedmonomtable = []; % Hashed polynomial powers table |
---|
| 28 | internal_sdpvarstate.hash = []; |
---|
| 29 | internal_sdpvarstate.boundlist = []; |
---|
| 30 | internal_sdpvarstate.variabletype = spalloc(0,0,0); % Pre-calc linear/quadratic/polynomial/sigmonial |
---|
| 31 | internal_sdpvarstate.intVariables = []; % ID of integer variables |
---|
| 32 | internal_sdpvarstate.binVariables = []; % ID of binary variables |
---|
| 33 | internal_sdpvarstate.uncVariables = []; % ID of uncertain variables (not used) |
---|
| 34 | internal_sdpvarstate.parVariables = []; % ID of parametric variables (not used) |
---|
| 35 | internal_sdpvarstate.extVariables = []; % ID of extended variables (for max,min,norm,sin, etc) |
---|
| 36 | internal_sdpvarstate.logicVariables = []; % ID of extended logic variables (for or, nnz, alldifferent etc) |
---|
| 37 | internal_sdpvarstate.evalVariables = []; % ID of variables that require nonlinear maps |
---|
| 38 | internal_sdpvarstate.complexpair = []; |
---|
| 39 | internal_sdpvarstate.internalconstraints = []; |
---|
| 40 | internal_sdpvarstate.ExtendedMap = []; |
---|
| 41 | internal_sdpvarstate.sosid = 0; |
---|
| 42 | internal_sdpvarstate.sos_index = []; |
---|
| 43 | internal_sdpvarstate.sos_data = []; |
---|
| 44 | internal_sdpvarstate.sos_ParV = []; |
---|
| 45 | internal_sdpvarstate.sos_Q = []; |
---|
| 46 | internal_sdpvarstate.sos_v = []; |
---|
| 47 | internal_sdpvarstate.optSolution.info = 'Initialized by YALMIP'; |
---|
| 48 | internal_sdpvarstate.optSolution.variables = []; |
---|
| 49 | internal_sdpvarstate.optSolution.optvar =[]; |
---|
| 50 | internal_sdpvarstate.optSolution.values =[]; |
---|
| 51 | |
---|
| 52 | internal_sdpvarstate.nonCommutingTable = []; |
---|
| 53 | end |
---|
| 54 | if isempty(internal_setstate) |
---|
| 55 | internal_setstate.LMIid = 0; |
---|
| 56 | internal_setstate.duals_index = []; |
---|
| 57 | internal_setstate.duals_data = []; |
---|
| 58 | internal_setstate.duals_associated_index = []; |
---|
| 59 | internal_setstate.duals_associated_data = []; |
---|
| 60 | end |
---|
| 61 | |
---|
| 62 | switch varargin{1} |
---|
| 63 | |
---|
| 64 | case 'evalVariables' |
---|
| 65 | varargout{1} = internal_sdpvarstate.evalVariables; |
---|
| 66 | |
---|
| 67 | case 'monomtable' |
---|
| 68 | varargout{1} = internal_sdpvarstate.monomtable; |
---|
| 69 | if nargout == 2 |
---|
| 70 | varargout{2} = internal_sdpvarstate.variabletype; |
---|
| 71 | elseif nargout == 4 |
---|
| 72 | varargout{2} = internal_sdpvarstate.variabletype; |
---|
| 73 | varargout{3} = internal_sdpvarstate.hashedmonomtable; |
---|
| 74 | varargout{4} = internal_sdpvarstate.hash; |
---|
| 75 | end |
---|
| 76 | % |
---|
| 77 | % varargout{1} = internal_sdpvarstate.monomtable; |
---|
| 78 | % if nargout >= 2 |
---|
| 79 | % varargout{2} = internal_sdpvarstate.variabletype; |
---|
| 80 | % if nargout == 4 |
---|
| 81 | % varargout{3} = internal_sdpvarstate.hashedmonomtable; |
---|
| 82 | % varargout{4} = internal_sdpvarstate.hash; |
---|
| 83 | % end |
---|
| 84 | % end |
---|
| 85 | |
---|
| 86 | |
---|
| 87 | case 'setmonomtable' |
---|
| 88 | % New monom table |
---|
| 89 | internal_sdpvarstate.monomtable = varargin{2}; |
---|
| 90 | if nargin>=4 |
---|
| 91 | % User has up-dated the hash tables him self. |
---|
| 92 | internal_sdpvarstate.hashedmonomtable=varargin{4}; |
---|
| 93 | internal_sdpvarstate.hash = varargin{5}; |
---|
| 94 | end |
---|
| 95 | if size(internal_sdpvarstate.monomtable,2)>length(internal_sdpvarstate.hash) |
---|
| 96 | need_new = size(internal_sdpvarstate.monomtable,1) - length(internal_sdpvarstate.hash); |
---|
| 97 | internal_sdpvarstate.hash = [internal_sdpvarstate.hash ; 3*rand_hash(size(internal_sdpvarstate.monomtable,1),need_new,1)]; |
---|
| 98 | end |
---|
| 99 | if size(internal_sdpvarstate.monomtable,1)>size(internal_sdpvarstate.hashedmonomtable,1) |
---|
| 100 | % Need to add some hash values |
---|
| 101 | need_new = size(internal_sdpvarstate.monomtable,1) - size(internal_sdpvarstate.hashedmonomtable,1); |
---|
| 102 | internal_sdpvarstate.hashedmonomtable = [internal_sdpvarstate.hashedmonomtable;internal_sdpvarstate.monomtable(end-need_new+1:end,:)*internal_sdpvarstate.hash]; |
---|
| 103 | end |
---|
| 104 | if nargin >= 3 |
---|
| 105 | internal_sdpvarstate.variabletype = varargin{3}; |
---|
| 106 | if length(internal_sdpvarstate.variabletype) ~=size(internal_sdpvarstate.monomtable,1) |
---|
| 107 | error('ASSERT') |
---|
| 108 | end |
---|
| 109 | else |
---|
| 110 | internal_sdpvarstate.variabletype = zeros(size(internal_sdpvarstate.monomtable,1),1)'; |
---|
| 111 | nonlinear = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); |
---|
| 112 | if ~isempty(nonlinear) |
---|
| 113 | %mt = internal_sdpvarstate.monomtable; |
---|
| 114 | internal_sdpvarstate.variabletype(nonlinear) = 3; |
---|
| 115 | quadratic = sum(internal_sdpvarstate.monomtable,2)==2; |
---|
| 116 | internal_sdpvarstate.variabletype(quadratic) = 2; |
---|
| 117 | bilinear = max(internal_sdpvarstate.monomtable,[],2)<=1; |
---|
| 118 | internal_sdpvarstate.variabletype(bilinear & quadratic) = 1; |
---|
| 119 | sigmonial = any(0>internal_sdpvarstate.monomtable,2) | any(internal_sdpvarstate.monomtable-fix(internal_sdpvarstate.monomtable),2); |
---|
| 120 | internal_sdpvarstate.variabletype(sigmonial) = 4; |
---|
| 121 | end |
---|
| 122 | end |
---|
| 123 | % |
---|
| 124 | % if length((internal_sdpvarstate.hash)) ~= length(unique(internal_sdpvarstate.hash)) |
---|
| 125 | % error('Report ASSERT HASH') |
---|
| 126 | % end |
---|
| 127 | % |
---|
| 128 | % |
---|
| 129 | % if any(sum( abs(internal_sdpvarstate.monomtable),2)==0) |
---|
| 130 | % error('Report ASSERT HASH') |
---|
| 131 | % end |
---|
| 132 | |
---|
| 133 | |
---|
| 134 | |
---|
| 135 | case 'variabletype' |
---|
| 136 | varargout{1} = internal_sdpvarstate.variabletype; |
---|
| 137 | |
---|
| 138 | case 'addextendedvariable' |
---|
| 139 | |
---|
| 140 | varargin{2} = strrep(varargin{2},'sdpvar/',''); % Clean due to different behaviour of the function mfilename in ML 5,6 and 7 |
---|
| 141 | |
---|
| 142 | % Is this operator variable already defined |
---|
| 143 | if ~isempty(internal_sdpvarstate.ExtendedMap) |
---|
| 144 | i = 1; |
---|
| 145 | correct_operator = strcmp(varargin{2},{internal_sdpvarstate.ExtendedMap(:).fcn}); |
---|
| 146 | arg1 = varargin{2}; |
---|
| 147 | arg2 = {varargin{3:end}}; |
---|
| 148 | this_hash = create_trivial_hash(varargin{3}); |
---|
| 149 | for i = find(correct_operator) |
---|
| 150 | if this_hash == internal_sdpvarstate.ExtendedMap(i).Hash |
---|
| 151 | if isequal(arg2, internal_sdpvarstate.ExtendedMap(i).arg); |
---|
| 152 | varargout{1} = internal_sdpvarstate.ExtendedMap(i).var; |
---|
| 153 | return |
---|
| 154 | end |
---|
| 155 | end |
---|
| 156 | end |
---|
| 157 | else |
---|
| 158 | this_hash = create_trivial_hash(varargin{3}); |
---|
| 159 | end |
---|
| 160 | |
---|
| 161 | switch varargin{2} |
---|
| 162 | |
---|
| 163 | case {'max'} |
---|
| 164 | % MAX is a bit special since we need one |
---|
| 165 | % new variable for each element... |
---|
| 166 | % (can be implemented standard way, but this is better |
---|
| 167 | % for performance, and since MAX is so common... |
---|
| 168 | X = varargin{3:end}; |
---|
| 169 | [n,m] = size(X); |
---|
| 170 | if min([n m]) == 1 |
---|
| 171 | y = sdpvar(1,1); |
---|
| 172 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 173 | internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end}}; |
---|
| 174 | internal_sdpvarstate.ExtendedMap(end).var = y; |
---|
| 175 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 176 | |
---|
| 177 | else |
---|
| 178 | y = sdpvar(1,m); |
---|
| 179 | for i = 1:m |
---|
| 180 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 181 | internal_sdpvarstate.ExtendedMap(end).arg = {X(:,i)}; |
---|
| 182 | internal_sdpvarstate.ExtendedMap(end).var = y(i); |
---|
| 183 | end |
---|
| 184 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 185 | end |
---|
| 186 | |
---|
| 187 | |
---|
| 188 | case {'abs'} |
---|
| 189 | % ABS is a bit special since we need one |
---|
| 190 | % new variable for each element... |
---|
| 191 | X = varargin{3:end}; |
---|
| 192 | y = sdpvar(numel(X),1); |
---|
| 193 | if numel(X)==1 |
---|
| 194 | y = sdpvar(1,1); |
---|
| 195 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 196 | internal_sdpvarstate.ExtendedMap(end).arg = {X}; |
---|
| 197 | internal_sdpvarstate.ExtendedMap(end).var = y; |
---|
| 198 | else |
---|
| 199 | for i = 1:numel(X) |
---|
| 200 | yi = y(i); |
---|
| 201 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 202 | internal_sdpvarstate.ExtendedMap(end).arg = {X(i)}; |
---|
| 203 | internal_sdpvarstate.ExtendedMap(end).var = yi; |
---|
| 204 | end |
---|
| 205 | end |
---|
| 206 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 207 | y = reshape(y,size(X,1),size(X,2)); |
---|
| 208 | |
---|
| 209 | otherwise |
---|
| 210 | % This is the standard operators. INPUTS -> 1 scalar output |
---|
| 211 | y = sdpvar(1,1); |
---|
| 212 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 213 | internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end}}; |
---|
| 214 | internal_sdpvarstate.ExtendedMap(end).var = y; |
---|
| 215 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 216 | end |
---|
| 217 | internal_sdpvarstate.ExtendedMap(end).Hash = this_hash; |
---|
| 218 | varargout{1} = y; |
---|
| 219 | return |
---|
| 220 | |
---|
| 221 | case 'addEvalVariable' |
---|
| 222 | % This code essentially the same as the addextended code. The only |
---|
| 223 | % difference is that we have to remove the last element in the |
---|
| 224 | % saved argument list when we compare to the current argument, |
---|
| 225 | % since we always append an extra argument to the argument list in |
---|
| 226 | % order to convert f(a'x+b) to f(z), z==a'x+b |
---|
| 227 | |
---|
| 228 | varargin{2} = strrep(varargin{2},'sdpvar/',''); |
---|
| 229 | this_hash = create_trivial_hash(varargin{3}); |
---|
| 230 | % Is this operator variable already defined |
---|
| 231 | if ~isempty(internal_sdpvarstate.ExtendedMap) |
---|
| 232 | i = 1; |
---|
| 233 | while i<=length(internal_sdpvarstate.ExtendedMap) |
---|
| 234 | if isequal(varargin{2},internal_sdpvarstate.ExtendedMap(i).fcn) & isequal({varargin{3:end}}, {internal_sdpvarstate.ExtendedMap(i).arg{1:end-1}}) |
---|
| 235 | varargout{1} = internal_sdpvarstate.ExtendedMap(i).var; |
---|
| 236 | return |
---|
| 237 | end |
---|
| 238 | i = i + 1; |
---|
| 239 | end |
---|
| 240 | end |
---|
| 241 | |
---|
| 242 | % This is the standard operators. INPUTS -> 1 scalar output |
---|
| 243 | y = sdpvar(1,1); % Models the function y=f(arg) |
---|
| 244 | % z = sdpvar(1,1); % Standard format y=f(z),z==arg |
---|
| 245 | z = sdpvar(size(varargin{3},1),size(varargin{3},2),'full'); % Standard format y=f(z),z==arg |
---|
| 246 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 247 | internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end},z}; |
---|
| 248 | internal_sdpvarstate.ExtendedMap(end).var = y; |
---|
| 249 | internal_sdpvarstate.ExtendedMap(end).Hash = this_hash; |
---|
| 250 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 251 | internal_sdpvarstate.evalVariables = [internal_sdpvarstate.evalVariables getvariables(y)]; |
---|
| 252 | varargout{1} = y; |
---|
| 253 | return |
---|
| 254 | |
---|
| 255 | case 'extvariables' |
---|
| 256 | varargout{1} = internal_sdpvarstate.extVariables; |
---|
| 257 | |
---|
| 258 | case 'extstruct' |
---|
| 259 | if nargin == 1 |
---|
| 260 | varargout{1} = internal_sdpvarstate.ExtendedMap; |
---|
| 261 | elseif length(varargin{2})==1 |
---|
| 262 | found = 0; |
---|
| 263 | varargout{1} = []; |
---|
| 264 | i = 1; |
---|
| 265 | while ~found & i <=length(internal_sdpvarstate.ExtendedMap) |
---|
| 266 | if varargin{2} == getvariables(internal_sdpvarstate.ExtendedMap(i).var) |
---|
| 267 | found = 1; |
---|
| 268 | varargout{1} = internal_sdpvarstate.ExtendedMap(i); |
---|
| 269 | end |
---|
| 270 | i = i + 1; |
---|
| 271 | end |
---|
| 272 | else |
---|
| 273 | % If requests several extended variables, returns as cell |
---|
| 274 | found = zeros(1,length(varargin{2})); |
---|
| 275 | varargout{1} = cell(0,length(varargin{2})); |
---|
| 276 | i = 1; |
---|
| 277 | while ~all(found) & i <=length(internal_sdpvarstate.ExtendedMap) |
---|
| 278 | j = find(varargin{2} == getvariables(internal_sdpvarstate.ExtendedMap(i).var)); |
---|
| 279 | if ~isempty(j) |
---|
| 280 | found(j) = 1; |
---|
| 281 | varargout{1}{j} = internal_sdpvarstate.ExtendedMap(i); |
---|
| 282 | end |
---|
| 283 | i = i + 1; |
---|
| 284 | end |
---|
| 285 | end |
---|
| 286 | |
---|
| 287 | case 'rankvariables' |
---|
| 288 | i = 1; |
---|
| 289 | rankvariables = []; |
---|
| 290 | dualrankvariables = []; |
---|
| 291 | for i = 1:length(internal_sdpvarstate.ExtendedMap) |
---|
| 292 | if strcmpi('rank',internal_sdpvarstate.ExtendedMap(i).fcn) |
---|
| 293 | rankvariables = [rankvariables getvariables(internal_sdpvarstate.ExtendedMap(i).var)]; |
---|
| 294 | end |
---|
| 295 | if strcmpi('dualrank',internal_sdpvarstate.ExtendedMap(i).fcn) |
---|
| 296 | dualrankvariables = [dualrankvariables getvariables(internal_sdpvarstate.ExtendedMap(i).var)]; |
---|
| 297 | end |
---|
| 298 | end |
---|
| 299 | varargout{1} = rankvariables; |
---|
| 300 | varargout{2} = dualrankvariables; |
---|
| 301 | |
---|
| 302 | % case 'dualrankvariables' |
---|
| 303 | % i = 1; |
---|
| 304 | % rankvariables = []; |
---|
| 305 | % for i = 1:length(internal_sdpvarstate.ExtendedMap) |
---|
| 306 | % if isequal('dualrank',internal_sdpvarstate.ExtendedMap(i).fcn) |
---|
| 307 | % rankvariables = [rankvariables getvariables(internal_sdpvarstate.ExtendedMap(i).var)]; |
---|
| 308 | % end |
---|
| 309 | % end |
---|
| 310 | % varargout{1} = rankvariables; |
---|
| 311 | |
---|
| 312 | case 'lmiid' |
---|
| 313 | if not(isempty(internal_setstate.LMIid)) |
---|
| 314 | internal_setstate.LMIid = internal_setstate.LMIid+1; |
---|
| 315 | varargout{1}=internal_setstate.LMIid; |
---|
| 316 | else |
---|
| 317 | internal_setstate.LMIid=1; |
---|
| 318 | varargout{1}=internal_setstate.LMIid; |
---|
| 319 | end |
---|
| 320 | |
---|
| 321 | case 'setnonlinearvariables' |
---|
| 322 | error('Internal error (ref. setnonlinearvariables). Report please.') |
---|
| 323 | |
---|
| 324 | case {'clear'} |
---|
| 325 | W = evalin('caller','whos'); |
---|
| 326 | for i = 1:size(W,1) |
---|
| 327 | if strcmp(W(i).class,'sdpvar') | strcmp(W(i).class,'lmi') |
---|
| 328 | evalin('caller', ['clear ' W(i).name ';']); |
---|
| 329 | end |
---|
| 330 | end |
---|
| 331 | |
---|
| 332 | internal_setstate.LMIid = 0; |
---|
| 333 | internal_setstate.duals_index = []; |
---|
| 334 | internal_setstate.duals_data = []; |
---|
| 335 | internal_setstate.duals_associated_index = []; |
---|
| 336 | internal_setstate.duals_associated_data = []; |
---|
| 337 | |
---|
| 338 | |
---|
| 339 | internal_sdpvarstate.sosid = 0; |
---|
| 340 | internal_sdpvarstate.sos_index = []; |
---|
| 341 | internal_sdpvarstate.sos_data = []; |
---|
| 342 | internal_sdpvarstate.sos_ParV = []; |
---|
| 343 | internal_sdpvarstate.sos_Q = []; |
---|
| 344 | internal_sdpvarstate.sos_v = []; |
---|
| 345 | |
---|
| 346 | internal_sdpvarstate.monomtable = spalloc(0,0,0); |
---|
| 347 | internal_sdpvarstate.hashedmonomtable = []; |
---|
| 348 | internal_sdpvarstate.hash = []; |
---|
| 349 | internal_sdpvarstate.boundlist = []; |
---|
| 350 | internal_sdpvarstate.variabletype = spalloc(0,0,0); |
---|
| 351 | internal_sdpvarstate.intVariables = []; |
---|
| 352 | internal_sdpvarstate.binVariables = []; |
---|
| 353 | internal_sdpvarstate.uncVariables = []; |
---|
| 354 | internal_sdpvarstate.parVariables = []; |
---|
| 355 | internal_sdpvarstate.extVariables = []; |
---|
| 356 | internal_sdpvarstate.evalVariables = []; |
---|
| 357 | internal_sdpvarstate.logicVariables = []; |
---|
| 358 | ;internal_sdpvarstate.complexpair = []; |
---|
| 359 | internal_sdpvarstate.internalconstraints = []; |
---|
| 360 | internal_sdpvarstate.ExtendedMap = []; |
---|
| 361 | internal_sdpvarstate.optSolution.info = 'Initialized by YALMIP'; |
---|
| 362 | internal_sdpvarstate.optSolution.variables = []; |
---|
| 363 | internal_sdpvarstate.optSolution.optvar = []; |
---|
| 364 | internal_sdpvarstate.optSolution.values = []; |
---|
| 365 | |
---|
| 366 | internal_sdpvarstate.nonCommutingTable = []; |
---|
| 367 | |
---|
| 368 | case 'cleardual' |
---|
| 369 | if nargin==1 |
---|
| 370 | internal_setstate.duals_index = []; |
---|
| 371 | internal_setstate.duals_data = []; |
---|
| 372 | internal_setstate.duals_associated_index = []; |
---|
| 373 | internal_setstate.duals_associated_data = []; |
---|
| 374 | else |
---|
| 375 | if ~isempty(internal_setstate.duals_index) |
---|
| 376 | internal_setstate.lmiid = varargin{2}; |
---|
| 377 | for i = 1:length(varargin{2}) |
---|
| 378 | j = find(internal_setstate.duals_index==internal_setstate.lmiid(i)); |
---|
| 379 | if ~isempty(j) |
---|
| 380 | internal_setstate.duals_index = internal_setstate.duals_index([1:1:j-1 j+1:1:length(internal_setstate.duals_index)]); |
---|
| 381 | internal_setstate.duals_data = {internal_setstate.duals_data{[1:1:j-1 j+1:1:length(internal_setstate.duals_data)]}}; |
---|
| 382 | end |
---|
| 383 | end |
---|
| 384 | end |
---|
| 385 | end |
---|
| 386 | |
---|
| 387 | case 'associatedual' |
---|
| 388 | internal_setstate.duals_associated_index = [internal_setstate.duals_associated_index varargin{2}]; |
---|
| 389 | internal_setstate.duals_associated_data{end+1} = varargin{3}; |
---|
| 390 | |
---|
| 391 | case 'addcomplexpair' |
---|
| 392 | internal_sdpvarstate.complexpair = [internal_sdpvarstate.complexpair;varargin{2}]; |
---|
| 393 | |
---|
| 394 | case 'getcomplexpair' |
---|
| 395 | varargout{1} = internal_sdpvarstate.complexpair; |
---|
| 396 | return |
---|
| 397 | |
---|
| 398 | case 'setallsolution' |
---|
| 399 | internal_sdpvarstate.optSolution.optvar = varargin{2}.optvar; |
---|
| 400 | internal_sdpvarstate.optSolution.variables = varargin{2}.variables; |
---|
| 401 | internal_sdpvarstate.optSolution.values = []; |
---|
| 402 | return |
---|
| 403 | |
---|
| 404 | case 'setvalues' |
---|
| 405 | internal_sdpvarstate.optSolution.values = varargin{2}; |
---|
| 406 | |
---|
| 407 | case 'setsolution' |
---|
| 408 | if isempty(internal_sdpvarstate.optSolution.variables) |
---|
| 409 | internal_sdpvarstate.optSolution = varargin{2}; |
---|
| 410 | else |
---|
| 411 | % Just save some stuff first |
---|
| 412 | newSolution = varargin{2}; |
---|
| 413 | oldSolution = internal_sdpvarstate.optSolution; |
---|
| 414 | optSolution = varargin{2}; |
---|
| 415 | keep_these = find(~ismember(oldSolution.variables,newSolution.variables)); |
---|
| 416 | internal_sdpvarstate.optSolution.optvar = [oldSolution.optvar(keep_these);newSolution.optvar(:)]; |
---|
| 417 | internal_sdpvarstate.optSolution.variables = [oldSolution.variables(keep_these);newSolution.variables(:)]; |
---|
| 418 | end |
---|
| 419 | % clear evaluated values (only used cache-wise) |
---|
| 420 | internal_sdpvarstate.optSolution.values = []; |
---|
| 421 | return |
---|
| 422 | |
---|
| 423 | case 'getsolution' |
---|
| 424 | varargout{1} = internal_sdpvarstate.optSolution; |
---|
| 425 | return |
---|
| 426 | |
---|
| 427 | case 'setdual' |
---|
| 428 | internal_setstate.duals_index = varargin{2}; |
---|
| 429 | internal_setstate.duals_data = varargin{3}; |
---|
| 430 | |
---|
| 431 | if ~isempty(internal_setstate.duals_associated_index) |
---|
| 432 | if ~isempty(intersect(internal_setstate.duals_index,internal_setstate.duals_associated_index)) |
---|
| 433 | for i = 1:length(internal_setstate.duals_index) |
---|
| 434 | itshere = find(internal_setstate.duals_associated_index==internal_setstate.duals_index(i)); |
---|
| 435 | if ~isempty(itshere) |
---|
| 436 | assign(internal_setstate.duals_associated_data{itshere},internal_setstate.duals_data{i}); |
---|
| 437 | end |
---|
| 438 | end |
---|
| 439 | end |
---|
| 440 | end |
---|
| 441 | |
---|
| 442 | case 'dual' |
---|
| 443 | if isempty(internal_setstate.duals_index) |
---|
| 444 | varargout{1}=[]; |
---|
| 445 | else |
---|
| 446 | LMIid = varargin{2}; |
---|
| 447 | index_to_dual = find(LMIid==internal_setstate.duals_index); |
---|
| 448 | if isempty(index_to_dual) |
---|
| 449 | varargout{1}=[]; |
---|
| 450 | else |
---|
| 451 | varargout{1} = internal_setstate.duals_data{index_to_dual}; |
---|
| 452 | end |
---|
| 453 | end |
---|
| 454 | |
---|
| 455 | case 'clearsos' |
---|
| 456 | if nargin==1 |
---|
| 457 | internal_sdpvarstate.sos_index = []; |
---|
| 458 | internal_sdpvarstate.sos_data = []; |
---|
| 459 | internal_sdpvarstate.sos_ParV = []; |
---|
| 460 | internal_sdpvarstate.sos_Q = []; |
---|
| 461 | internal_sdpvarstate.sos_v = []; |
---|
| 462 | |
---|
| 463 | end |
---|
| 464 | |
---|
| 465 | case 'setsos' |
---|
| 466 | if ~isempty(internal_sdpvarstate.sos_index) |
---|
| 467 | where = find(internal_sdpvarstate.sos_index==varargin{2}); |
---|
| 468 | if ~isempty(where) |
---|
| 469 | internal_sdpvarstate.sos_index(where) = varargin{2}; |
---|
| 470 | internal_sdpvarstate.sos_data{where} = varargin{3}; |
---|
| 471 | internal_sdpvarstate.sos_ParV{where} = varargin{4}; |
---|
| 472 | internal_sdpvarstate.sos_Q{where} = varargin{5}; |
---|
| 473 | internal_sdpvarstate.sos_v{where} = varargin{6}; |
---|
| 474 | |
---|
| 475 | else |
---|
| 476 | internal_sdpvarstate.sos_index(end+1) = varargin{2}; |
---|
| 477 | internal_sdpvarstate.sos_data{end+1} = varargin{3}; |
---|
| 478 | internal_sdpvarstate.sos_ParV{end+1} = varargin{4}; |
---|
| 479 | internal_sdpvarstate.sos_Q{end+1} = varargin{5}; |
---|
| 480 | internal_sdpvarstate.sos_v{end+1} = varargin{6}; |
---|
| 481 | |
---|
| 482 | end |
---|
| 483 | else |
---|
| 484 | internal_sdpvarstate.sos_index(end+1) = varargin{2}; |
---|
| 485 | internal_sdpvarstate.sos_data{end+1} = varargin{3}; |
---|
| 486 | internal_sdpvarstate.sos_ParV{end+1} = varargin{4}; |
---|
| 487 | internal_sdpvarstate.sos_Q{end+1} = varargin{5}; |
---|
| 488 | internal_sdpvarstate.sos_v{end+1} = varargin{6}; |
---|
| 489 | end |
---|
| 490 | |
---|
| 491 | case 'sosid' |
---|
| 492 | if not(isempty(internal_sdpvarstate.sosid)) |
---|
| 493 | internal_sdpvarstate.sosid = internal_sdpvarstate.sosid+1; |
---|
| 494 | varargout{1}=internal_sdpvarstate.sosid; |
---|
| 495 | else |
---|
| 496 | internal_sdpvarstate.sosid=1; |
---|
| 497 | varargout{1}=internal_sdpvarstate.sosid; |
---|
| 498 | end |
---|
| 499 | |
---|
| 500 | case 'getsos' |
---|
| 501 | if isempty(internal_sdpvarstate.sos_index) |
---|
| 502 | varargout{1}=[]; |
---|
| 503 | varargout{2}=[]; |
---|
| 504 | varargout{3}=[]; |
---|
| 505 | varargout{4}=[]; |
---|
| 506 | else |
---|
| 507 | SOSid = varargin{2}; |
---|
| 508 | index_to_sos = find(SOSid==internal_sdpvarstate.sos_index); |
---|
| 509 | if isempty(index_to_sos) |
---|
| 510 | varargout{1}=[]; |
---|
| 511 | varargout{2}=[]; |
---|
| 512 | varargout{3}=[]; |
---|
| 513 | varargout{4}=[]; |
---|
| 514 | else |
---|
| 515 | varargout{1} = internal_sdpvarstate.sos_data{index_to_sos}; |
---|
| 516 | varargout{2} = internal_sdpvarstate.sos_ParV{index_to_sos}; |
---|
| 517 | varargout{3} = internal_sdpvarstate.sos_Q{index_to_sos}; |
---|
| 518 | varargout{4} = internal_sdpvarstate.sos_v{index_to_sos}; |
---|
| 519 | % FIX |
---|
| 520 | end |
---|
| 521 | end |
---|
| 522 | |
---|
| 523 | |
---|
| 524 | case 'getinternalsetstate' |
---|
| 525 | varargout{1} = internal_setstate; % Get internal state, called from saveobj |
---|
| 526 | |
---|
| 527 | case 'setinternalsetstate' |
---|
| 528 | internal_setstate = varargin{2}; % Set internal state, called from loadobj |
---|
| 529 | |
---|
| 530 | case 'getinternalsdpvarstate' |
---|
| 531 | varargout{1} = internal_sdpvarstate; % Get internal state, called from saveobj |
---|
| 532 | |
---|
| 533 | case 'setinternalsdpvarstate' |
---|
| 534 | internal_sdpvarstate = varargin{2}; % Set internal state, called from loadobj |
---|
| 535 | |
---|
| 536 | % Back-wards compability.... |
---|
| 537 | if ~isfield(internal_sdpvarstate,'extVariables') |
---|
| 538 | internal_sdpvarstate.extVariables = []; |
---|
| 539 | end |
---|
| 540 | if ~isfield(internal_sdpvarstate,'ExtendedMap') |
---|
| 541 | internal_sdpvarstate.ExtendedMap = []; |
---|
| 542 | end |
---|
| 543 | if ~isfield(internal_sdpvarstate,'variabletype') |
---|
| 544 | internal_sdpvarstate.variabletype = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); |
---|
| 545 | end |
---|
| 546 | if ~isfield(internal_sdpvarstate,'hash') |
---|
| 547 | internal_sdpvarstate.hash=[]; |
---|
| 548 | internal_sdpvarstate.hashedmonomtable=[]; |
---|
| 549 | end |
---|
| 550 | |
---|
| 551 | % Re-compute some stuff for safety |
---|
| 552 | internal_sdpvarstate.variabletype = internal_sdpvarstate.variabletype(:)'; |
---|
| 553 | internal_sdpvarstate.variabletype = spalloc(size(internal_sdpvarstate.monomtable,1),1,0)'; |
---|
| 554 | nonlinear = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); |
---|
| 555 | if ~isempty(nonlinear) |
---|
| 556 | mt = internal_sdpvarstate.monomtable; |
---|
| 557 | internal_sdpvarstate.variabletype(nonlinear) = 3; |
---|
| 558 | quadratic = sum(internal_sdpvarstate.monomtable,2)==2; |
---|
| 559 | internal_sdpvarstate.variabletype(quadratic) = 2; |
---|
| 560 | bilinear = max(internal_sdpvarstate.monomtable,[],2)<=1; |
---|
| 561 | internal_sdpvarstate.variabletype(bilinear & quadratic) = 1; |
---|
| 562 | sigmonial = any(0>internal_sdpvarstate.monomtable,2) | any(internal_sdpvarstate.monomtable-fix(internal_sdpvarstate.monomtable),2); |
---|
| 563 | internal_sdpvarstate.variabletype(sigmonial) = 4; |
---|
| 564 | end |
---|
| 565 | |
---|
| 566 | [n,m] = size(internal_sdpvarstate.monomtable); |
---|
| 567 | if n>m |
---|
| 568 | internal_sdpvarstate.monomtable(n,n) = 0; |
---|
| 569 | end |
---|
| 570 | |
---|
| 571 | if size(internal_sdpvarstate.monomtable,2)>length(internal_sdpvarstate.hash) |
---|
| 572 | % Need new hash-keys |
---|
| 573 | internal_sdpvarstate.hash = [internal_sdpvarstate.hash ; 3*rand_hash(size(internal_sdpvarstate.monomtable,1),need_new,1)]; |
---|
| 574 | end |
---|
| 575 | if size(internal_sdpvarstate.monomtable,1)>size(internal_sdpvarstate.hashedmonomtable,1) |
---|
| 576 | % Need to add some hash values |
---|
| 577 | need_new = size(internal_sdpvarstate.monomtable,1) - size(internal_sdpvarstate.hashedmonomtable,1); |
---|
| 578 | internal_sdpvarstate.hashedmonomtable = [internal_sdpvarstate.hashedmonomtable;internal_sdpvarstate.monomtable(end-need_new+1:end,:)*internal_sdpvarstate.hash]; |
---|
| 579 | end |
---|
| 580 | |
---|
| 581 | |
---|
| 582 | |
---|
| 583 | case {'version','ver'} |
---|
| 584 | varargout{1}=3; |
---|
| 585 | if nargout==2 |
---|
| 586 | varargout{2} = '20061024'; |
---|
| 587 | end |
---|
| 588 | |
---|
| 589 | case 'setintvariables' |
---|
| 590 | internal_sdpvarstate.intVariables = varargin{2}; |
---|
| 591 | |
---|
| 592 | case 'intvariables' |
---|
| 593 | varargout{1} = internal_sdpvarstate.intVariables; |
---|
| 594 | |
---|
| 595 | case 'setbinvariables' |
---|
| 596 | internal_sdpvarstate.binVariables = varargin{2}; |
---|
| 597 | |
---|
| 598 | case 'binvariables' |
---|
| 599 | varargout{1} = internal_sdpvarstate.binVariables; |
---|
| 600 | |
---|
| 601 | case 'setuncvariables' |
---|
| 602 | internal_sdpvarstate.uncVariables = varargin{2}; |
---|
| 603 | |
---|
| 604 | case 'uncvariables' |
---|
| 605 | varargout{1} = internal_sdpvarstate.uncVariables; |
---|
| 606 | |
---|
| 607 | case 'setparvariables' |
---|
| 608 | internal_sdpvarstate.parVariables = varargin{2}; |
---|
| 609 | |
---|
| 610 | case 'parvariables' |
---|
| 611 | varargout{1} = internal_sdpvarstate.parVariables; |
---|
| 612 | |
---|
| 613 | case 'nonCommutingTable' |
---|
| 614 | if nargin == 2 |
---|
| 615 | internal_sdpvarstate.nonCommutingTable = varargin{2}; |
---|
| 616 | else |
---|
| 617 | varargout{1} = internal_sdpvarstate.nonCommutingTable; |
---|
| 618 | end |
---|
| 619 | |
---|
| 620 | case 'nonlinearvariables' |
---|
| 621 | error('Internal error (ref. nonlinear variables). Report!') |
---|
| 622 | varargout{1} = internal_sdpvarstate.nonlinearvariables; |
---|
| 623 | if nargout==2 |
---|
| 624 | varargout{2} = internal_sdpvarstate.nonlinearvariablesCompressed; |
---|
| 625 | end |
---|
| 626 | % |
---|
| 627 | case {'addinternal'} |
---|
| 628 | internal_sdpvarstate.internalconstraints{end+1} = varargin{1}; |
---|
| 629 | |
---|
| 630 | % case {'setnvars'} |
---|
| 631 | % sdpvar('setnvars',varargin{2}); |
---|
| 632 | |
---|
| 633 | case {'nvars'} |
---|
| 634 | varargout{1} = size(internal_sdpvarstate.monomtable,1); |
---|
| 635 | % varargout{1} = sdpvar('nvars'); |
---|
| 636 | |
---|
| 637 | case {'info'} |
---|
| 638 | [version,release] = yalmip('version'); |
---|
| 639 | currentversion = num2str(version(1)); |
---|
| 640 | i = 1; |
---|
| 641 | while i<length(version) |
---|
| 642 | i = i+1; |
---|
| 643 | currentversion = [currentversion '.' num2str(version(i))]; |
---|
| 644 | end |
---|
| 645 | |
---|
| 646 | info_str = ['- - - - YALMIP ' currentversion ' ' num2str(release) ' - - - -']; |
---|
| 647 | |
---|
| 648 | disp(' '); |
---|
| 649 | disp(char(repmat(double('*'),1,length(info_str)))); |
---|
| 650 | disp(info_str) |
---|
| 651 | disp(char(repmat(double('*'),1,length(info_str)))); |
---|
| 652 | disp(' '); |
---|
| 653 | disp(['Variable Size']) |
---|
| 654 | spaces = [' ']; |
---|
| 655 | ws = evalin('caller','whos'); |
---|
| 656 | n = 0; |
---|
| 657 | for i = 1:size(ws,1) |
---|
| 658 | if strcmp(ws(i).class,'sdpvar') |
---|
| 659 | n = n+1; |
---|
| 660 | wsname = ws(i).name; |
---|
| 661 | wssize = [num2str(ws(i).size(1)) 'x' num2str(ws(i).size(2))]; |
---|
| 662 | disp([wsname spaces(1:13-length(wsname)) wssize]); |
---|
| 663 | end |
---|
| 664 | end |
---|
| 665 | if n == 0 |
---|
| 666 | disp('No SDPVAR objects found'); |
---|
| 667 | end |
---|
| 668 | disp(' '); |
---|
| 669 | disp(['LMI']); |
---|
| 670 | n = 0; |
---|
| 671 | for i = 1:size(ws,1) |
---|
| 672 | if strcmp(ws(i).class,'lmi') |
---|
| 673 | n = n+1; |
---|
| 674 | wsname = ws(i).name; |
---|
| 675 | disp([wsname]); |
---|
| 676 | end |
---|
| 677 | end |
---|
| 678 | if n == 0 |
---|
| 679 | disp('No SET objects found'); |
---|
| 680 | end |
---|
| 681 | |
---|
| 682 | case 'getbounds' |
---|
| 683 | if ~isfield(internal_sdpvarstate,'boundlist') |
---|
| 684 | internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); |
---|
| 685 | elseif isempty(internal_sdpvarstate.boundlist) |
---|
| 686 | internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); |
---|
| 687 | end |
---|
| 688 | indicies = varargin{2}; |
---|
| 689 | if max(indicies)>size(internal_sdpvarstate.boundlist,1) |
---|
| 690 | need_new = max(indicies)-size(internal_sdpvarstate.boundlist,1); |
---|
| 691 | internal_sdpvarstate.boundlist = [internal_sdpvarstate.boundlist;inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1)]; |
---|
| 692 | end |
---|
| 693 | varargout{1} = internal_sdpvarstate.boundlist(indicies,:); |
---|
| 694 | varargout{2} = internal_sdpvarstate.boundlist(indicies,:); |
---|
| 695 | |
---|
| 696 | case 'setbounds' |
---|
| 697 | if ~isfield(internal_sdpvarstate,'boundlist') |
---|
| 698 | internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); |
---|
| 699 | elseif isempty(internal_sdpvarstate.boundlist) |
---|
| 700 | internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); |
---|
| 701 | end |
---|
| 702 | indicies = varargin{2}; |
---|
| 703 | if size(internal_sdpvarstate.boundlist,1)<min(indicies) |
---|
| 704 | internal_sdpvarstate.boundlist = [internal_sdpvarstate.boundlist;repmat([-inf inf],max(indicies)-size(internal_sdpvarstate.boundlist,1),1)]; |
---|
| 705 | end |
---|
| 706 | internal_sdpvarstate.boundlist(indicies,1) = -inf ; |
---|
| 707 | internal_sdpvarstate.boundlist(indicies,2) = inf; |
---|
| 708 | |
---|
| 709 | internal_sdpvarstate.boundlist(indicies(:),1) = varargin{3}; |
---|
| 710 | internal_sdpvarstate.boundlist(indicies(:),2) = varargin{4}; |
---|
| 711 | varargout{1}=0; |
---|
| 712 | |
---|
| 713 | case 'logicextvariables' |
---|
| 714 | logicextvariables = []; |
---|
| 715 | for i = 1:length(internal_sdpvarstate.ExtendedMap) |
---|
| 716 | % if ismember(internal_sdpvarstate.ExtendedMap(i).fcn,{'or','and'}) |
---|
| 717 | if isequal(internal_sdpvarstate.ExtendedMap(i).fcn,'or') | isequal(internal_sdpvarstate.ExtendedMap(i).fcn,'and') |
---|
| 718 | logicextvariables = [logicextvariables internal_sdpvarstate.extVariables(i)]; |
---|
| 719 | end |
---|
| 720 | end |
---|
| 721 | varargout{1} = logicextvariables; |
---|
| 722 | |
---|
| 723 | case 'logicVariables' |
---|
| 724 | varargout{1} = internal_sdpvarstate.logicVariables; |
---|
| 725 | |
---|
| 726 | case 'addlogicvariable' |
---|
| 727 | % This code essentially the same as the addextended code. The only |
---|
| 728 | % difference is that we keep track of logic variables in order to |
---|
| 729 | % know when we have to collect bounds for the big-M relaxations. |
---|
| 730 | |
---|
| 731 | varargin{2} = strrep(varargin{2},'sdpvar/',''); |
---|
| 732 | |
---|
| 733 | % Is this operator variable already defined |
---|
| 734 | if ~isempty(internal_sdpvarstate.ExtendedMap) |
---|
| 735 | i = 1; |
---|
| 736 | while i<=length(internal_sdpvarstate.ExtendedMap) |
---|
| 737 | if isequal(varargin{2},internal_sdpvarstate.ExtendedMap(i).fcn) & isequal({varargin{3:end}}, {internal_sdpvarstate.ExtendedMap(i).arg{1:end-1}}) |
---|
| 738 | varargout{1} = internal_sdpvarstate.ExtendedMap(i).var; |
---|
| 739 | return |
---|
| 740 | end |
---|
| 741 | i = i + 1; |
---|
| 742 | end |
---|
| 743 | end |
---|
| 744 | |
---|
| 745 | % This is the standard operators. INPUTS -> 1 scalar output |
---|
| 746 | y = sdpvar(1,1); |
---|
| 747 | internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; |
---|
| 748 | internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end}}; |
---|
| 749 | internal_sdpvarstate.ExtendedMap(end).var = y; |
---|
| 750 | internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; |
---|
| 751 | internal_sdpvarstate.logicVariables = [internal_sdpvarstate.logicVariables getvariables(y)]; |
---|
| 752 | varargout{1} = y; |
---|
| 753 | return |
---|
| 754 | |
---|
| 755 | case 'solver' |
---|
| 756 | if (nargin==2) |
---|
| 757 | if isa(varargin{2},'char') |
---|
| 758 | solver = varargin{2}; |
---|
| 759 | prefered_solver = solver; |
---|
| 760 | else |
---|
| 761 | error('Second argument should be a string with solver name'); |
---|
| 762 | end |
---|
| 763 | else |
---|
| 764 | if isempty(prefered_solver) |
---|
| 765 | varargout{1}=''; |
---|
| 766 | else |
---|
| 767 | varargout{1} = prefered_solver; |
---|
| 768 | end |
---|
| 769 | end |
---|
| 770 | otherwise |
---|
| 771 | if isa(varargin{1},'char') |
---|
| 772 | disp(['The command ''' varargin{1} ''' is not valid in YALMIP.m']); |
---|
| 773 | else |
---|
| 774 | disp('The first argument should be a string'); |
---|
| 775 | end |
---|
| 776 | end |
---|
| 777 | |
---|
| 778 | function r = rand_hash(k,n,m); |
---|
| 779 | |
---|
| 780 | s = rand('state'); |
---|
| 781 | rand('state',k) |
---|
| 782 | r = rand(n,m); |
---|
| 783 | rand('state',s); |
---|
| 784 | |
---|
| 785 | function h = create_trivial_hash(x) |
---|
| 786 | try |
---|
| 787 | h = sum(getvariables(x)) + sum(sum(getbase(x))); |
---|
| 788 | catch |
---|
| 789 | h = 0; |
---|
| 790 | end |
---|
| 791 | |
---|