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 | |
---|