function varargout = yalmip(varargin) %YALMIP Returns various information about YALMIP % % YALMIP can be used to check version numbers and find the SDPVAR and SET % objects available in workspace % % EXAMPLES % V = YALMIP('version') % Returns version % YALMIP('nvars') % Returns total number of declared variables % % If you want information on how to use YALMIP % http://yalmip.github.io % % See also YALMIPTEST persistent prefered_solver internal_sdpvarstate internal_setstate if nargin==0 help yalmip return end if isempty(internal_sdpvarstate) if exist('OCTAVE_VERSION', 'builtin') more off end internal_sdpvarstate.monomtable = spalloc(0,0,0); % Polynomial powers table internal_sdpvarstate.hashedmonomtable = []; % Hashed polynomial powers table internal_sdpvarstate.hash = []; internal_sdpvarstate.boundlist = []; internal_sdpvarstate.variabletype = spalloc(0,0,0); % Pre-calc linear/quadratic/polynomial/sigmonial internal_sdpvarstate.intVariables = []; % ID of integer variables internal_sdpvarstate.binVariables = []; % ID of binary variables internal_sdpvarstate.tempintVariables = []; % ID of integer variables internal_sdpvarstate.tempbinVariables = []; % ID of binary variables internal_sdpvarstate.semicontVariables = []; internal_sdpvarstate.uncVariables = []; % ID of uncertain variables (not used) internal_sdpvarstate.parVariables = []; % ID of parametric variables (not used) internal_sdpvarstate.extVariables = []; % ID of extended variables (for max,min,norm,sin, etc) internal_sdpvarstate.auxVariables = []; % ID of auxilliary variables (introduced when modelling extended variables) internal_sdpvarstate.auxVariablesW = []; % ID of uncertain auxilliary variables (introduced when modelling uncertain extended variables) internal_sdpvarstate.logicVariables = []; % ID of extended logic variables (for or, nnz, alldifferent etc) internal_sdpvarstate.complexpair = []; internal_sdpvarstate.internalconstraints = []; internal_sdpvarstate.ExtendedMap = []; internal_sdpvarstate.ExtendedMapHashes = []; internal_sdpvarstate.DependencyMap = sparse(0); internal_sdpvarstate.DependencyMap_i = []; internal_sdpvarstate.DependencyMap_j = []; internal_sdpvarstate.DependencyMapUser = sparse(0); internal_sdpvarstate.sosid = 0; internal_sdpvarstate.sos_index = []; internal_sdpvarstate.sos_data = []; internal_sdpvarstate.sos_ParV = []; internal_sdpvarstate.sos_Q = []; internal_sdpvarstate.sos_v = []; internal_sdpvarstate.optSolution{1}.info = 'Initialized by YALMIP'; internal_sdpvarstate.optSolution{1}.variables = []; internal_sdpvarstate.optSolution{1}.optvar =[]; internal_sdpvarstate.optSolution{1}.values =[]; internal_sdpvarstate.activeSolution = 1; internal_sdpvarstate.nonCommutingTable = []; internal_sdpvarstate.nonHermitiannonCommutingTable = []; internal_sdpvarstate.containsSemivar = false; try warning off Octave:possible-matlab-short-circuit-operator catch end end if isempty(internal_setstate) internal_setstate.LMIid = 0; internal_setstate.duals_index = []; internal_setstate.duals_data = []; internal_setstate.duals_associated_index = []; internal_setstate.duals_associated_data = []; end switch varargin{1} case 'clearsolution' internal_sdpvarstate.optSolution{1}.variables = []; internal_sdpvarstate.optSolution{1}.optvar =[]; internal_sdpvarstate.optSolution{1}.values =[]; internal_sdpvarstate.activeSolution = 1; internal_sdpvarstate.tempintVariables = []; internal_sdpvarstate.tempbinVariables = []; internal_sdpvarstate.intVariables = []; internal_sdpvarstate.binVariables = []; case 'monomtable' varargout{1} = internal_sdpvarstate.monomtable; n = size(internal_sdpvarstate.monomtable,1); if size(internal_sdpvarstate.monomtable,2) < n % Normalize the monomtalbe. Some external functions presume the % table is square varargout{1}(n,n) = 0; internal_sdpvarstate.monomtable = varargout{1}; need_new = size(internal_sdpvarstate.monomtable,1) - length(internal_sdpvarstate.hash); internal_sdpvarstate.hash = [internal_sdpvarstate.hash ; 3*gen_rand_hash(size(internal_sdpvarstate.monomtable,1),need_new,1)]; internal_sdpvarstate.hashedmonomtable = internal_sdpvarstate.monomtable*internal_sdpvarstate.hash; end if nargout == 2 varargout{2} = internal_sdpvarstate.variabletype; elseif nargout == 4 varargout{2} = internal_sdpvarstate.variabletype; varargout{3} = internal_sdpvarstate.hashedmonomtable; varargout{4} = internal_sdpvarstate.hash; end case 'setmonomtable' % New monom table internal_sdpvarstate.monomtable = varargin{2}; if nargin>=4 % User has up-dated the hash tables him self. internal_sdpvarstate.hashedmonomtable=varargin{4}; internal_sdpvarstate.hash = varargin{5}; end if size(internal_sdpvarstate.monomtable,2)>length(internal_sdpvarstate.hash) need_new = size(internal_sdpvarstate.monomtable,1) - length(internal_sdpvarstate.hash); internal_sdpvarstate.hash = [internal_sdpvarstate.hash ; 3*gen_rand_hash(size(internal_sdpvarstate.monomtable,1),need_new,1)]; end if size(internal_sdpvarstate.monomtable,1)>size(internal_sdpvarstate.hashedmonomtable,1) % Need to add some hash values need_new = size(internal_sdpvarstate.monomtable,1) - size(internal_sdpvarstate.hashedmonomtable,1); temp = internal_sdpvarstate.monomtable(end-need_new+1:end,:); internal_sdpvarstate.hashedmonomtable = [internal_sdpvarstate.hashedmonomtable;temp*internal_sdpvarstate.hash]; end if nargin >= 3 && ~isempty(varargin{3}) internal_sdpvarstate.variabletype = varargin{3}; if length(internal_sdpvarstate.variabletype) ~=size(internal_sdpvarstate.monomtable,1) error('ASSERT') end else internal_sdpvarstate.variabletype = zeros(size(internal_sdpvarstate.monomtable,1),1)'; nonlinear = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); if ~isempty(nonlinear) %mt = internal_sdpvarstate.monomtable; internal_sdpvarstate.variabletype(nonlinear) = 3; quadratic = sum(internal_sdpvarstate.monomtable,2)==2; internal_sdpvarstate.variabletype(quadratic) = 2; bilinear = max(internal_sdpvarstate.monomtable,[],2)<=1; internal_sdpvarstate.variabletype(bilinear & quadratic) = 1; sigmonial = any(0>internal_sdpvarstate.monomtable,2) | any(internal_sdpvarstate.monomtable-fix(internal_sdpvarstate.monomtable),2); internal_sdpvarstate.variabletype(sigmonial) = 4; end end case 'variabletype' varargout{1} = internal_sdpvarstate.variabletype; case {'addextendedvariable','addEvalVariable'} varargin{2} disp('Obsolete use of the terms addextendedvariable and addEvalVariable'); error('Obsolete use of the terms addextendedvariable and addEvalVariable'); case 'defineVectorizedUnitary' varargin{2} = strrep(varargin{2},'sdpvar/',''); % Clean due to different behaviour of the function mfilename in ML 5,6 and 7 % Is this operator variable already defined correct_operator = []; if ~isempty(internal_sdpvarstate.ExtendedMap) OperatorName = varargin{2}; Arguments = {varargin{3:end}}; this_hash = create_trivial_hash(firstSDPVAR(Arguments)); correct_operator = find([internal_sdpvarstate.ExtendedMapHashes == this_hash]); if ~isempty(correct_operator) correct_operator = correct_operator(strcmp(OperatorName,{internal_sdpvarstate.ExtendedMap(correct_operator).fcn})); end for i = correct_operator if this_hash == internal_sdpvarstate.ExtendedMap(i).Hash if isequalwithequalnans(Arguments, {internal_sdpvarstate.ExtendedMap(i).arg{1:end-1}}); if length(internal_sdpvarstate.ExtendedMap(i).computes)>1 varargout{1} = recover(internal_sdpvarstate.ExtendedMap(i).computes); else varargout{1} = internal_sdpvarstate.ExtendedMap(i).var; end varargout{1} = setoperatorname(varargout{1},varargin{2}); return end end end else this_hash = create_trivial_hash(firstSDPVAR({varargin{3:end}})); end X = varargin{3:end}; if is(X,'unitary') allXunitary = 1; else allXunitary = 0; end y = sdpvar(numel(X),1); allNewExtended = []; allNewExtendedIndex = []; allPreviouslyDefinedExtendedToIndex = []; allPreviouslyDefinedExtendedFromIndex = []; if ~isempty(internal_sdpvarstate.ExtendedMap) correct_operator = find(strcmp(varargin{2},{internal_sdpvarstate.ExtendedMap(:).fcn})); end z = sdpvar(numel(X),1); % Standard format y=f(z),z==arg internal_sdpvarstate.auxVariables = [ internal_sdpvarstate.auxVariables getvariables(z)]; internal_sdpvarstate.auxVariables = [ internal_sdpvarstate.auxVariables getvariables(y)]; vec_hashes = create_trivial_vechash(X); vec_isdoubles = create_vecisdouble(X); if isempty(correct_operator) availableHashes = []; else availableHashes = [internal_sdpvarstate.ExtendedMap(correct_operator).Hash]; end if isempty(availableHashes) && length(vec_hashes)>1 && all(diff(sort(vec_hashes))>0) simpleAllDifferentNew = 1; else simpleAllDifferentNew = 0; end for i = 1:numel(X) % we have to search through all scalar operators % to find this single element found = 0; Xi = []; if ~simpleAllDifferentNew if vec_isdoubles(i) found = 1; y(i) = X(i); else if ~isempty(correct_operator) this_hash = vec_hashes(i); correct_hash = correct_operator(find(this_hash == availableHashes)); if ~isempty(correct_hash) Xi = X(i); end for j = correct_hash(:)' if isequal(Xi,internal_sdpvarstate.ExtendedMap(j).arg{1},1) allPreviouslyDefinedExtendedToIndex = [allPreviouslyDefinedExtendedToIndex i]; allPreviouslyDefinedExtendedFromIndex = [allPreviouslyDefinedExtendedFromIndex j]; found = 1; break end end end end end if ~found yi = y(i); if isempty(Xi) Xi = X(i); end internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; if allXunitary internal_sdpvarstate.ExtendedMap(end).arg = {Xi,[]}; else if is(Xi,'unitary') internal_sdpvarstate.ExtendedMap(end).arg = {Xi,[]}; else internal_sdpvarstate.ExtendedMap(end).arg = {Xi,z(i)}; end end internal_sdpvarstate.ExtendedMap(end).var = yi; internal_sdpvarstate.ExtendedMap(end).computes = getvariables(yi); new_hash = create_trivial_hash(Xi); internal_sdpvarstate.ExtendedMap(end).Hash = new_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes new_hash]; internal_sdpvarstate.containsSemivar = internal_sdpvarstate.containsSemivar | strcmp(varargin{2}, 'semivar'); allNewExtendedIndex = [allNewExtendedIndex i]; availableHashes = [availableHashes new_hash]; correct_operator = [correct_operator length( internal_sdpvarstate.ExtendedMap)]; end end y(allPreviouslyDefinedExtendedToIndex) = [internal_sdpvarstate.ExtendedMap(allPreviouslyDefinedExtendedFromIndex).var]; allNewExtended = y(allNewExtendedIndex); y_vars = getvariables(allNewExtended); internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables y_vars]; y = reshape(y,size(X,1),size(X,2)); y = setoperatorname(y,varargin{2}); varargout{1} = y; yV = getvariables(y); yB = getbase(y);yB = yB(:,2:end); xV = getvariables(X); xB = getbase(X);xB = xB(:,2:end); %internal_sdpvarstate.DependencyMap(max(yV),max(xV))=sparse(0); for i = 1:length(yV) ii = yV(find(yB(i,:))); jj = xV(find(xB(i,:))); internal_sdpvarstate.DependencyMap_i = [internal_sdpvarstate.DependencyMap_i repmat(ii,1,length(jj))]; internal_sdpvarstate.DependencyMap_j = [internal_sdpvarstate.DependencyMap_j jj(:)']; % internal_sdpvarstate.DependencyMap(yV(find(yB(i,:))),xV(find(xB(i,:))))=1; end return case {'define','definemulti'} if strcmpi(varargin{1},'define') multioutput = 0; nout = [1 1]; else multioutput = 1; nout = varargin{end}; varargin = {varargin{1:end-1}}; end for i = 1:length(varargin) if isa(varargin{i},'sdpvar') varargin{i} = clearcreationtime(varargin{i}); end end varargin{2} = strrep(varargin{2},'sdpvar/',''); % Clean due to different behaviour of the function mfilename in ML 5,6 and 7 % Is this operator variable already defined correct_operator = []; if ~isempty(internal_sdpvarstate.ExtendedMap) OperatorName = varargin{2}; Arguments = {varargin{3:end}}; this_hash = create_trivial_hash(firstSDPVAR(Arguments)); correct_operator = find([internal_sdpvarstate.ExtendedMapHashes == this_hash]); if ~isempty(correct_operator) correct_operator = correct_operator(strcmp(OperatorName,{internal_sdpvarstate.ExtendedMap(correct_operator).fcn})); end for i = correct_operator % if this_hash == internal_sdpvarstate.ExtendedMap(i).Hash if isequalwithequalnans(Arguments, {internal_sdpvarstate.ExtendedMap(i).arg{1:end-1}}); if length(internal_sdpvarstate.ExtendedMap(i).computes)>1 varargout{1} = recover(internal_sdpvarstate.ExtendedMap(i).computes); else varargout{1} = internal_sdpvarstate.ExtendedMap(i).var; end varargout{1} = setoperatorname(varargout{1},varargin{2}); return end % end end else this_hash = create_trivial_hash(firstSDPVAR({varargin{3:end}})); end switch varargin{2} case {'max_internal'} % MAX is a bit special since we need one % new variable for each column... % (can be implemented standard way, but this is better % for performance, and since MAX is so common... X = varargin{3:end}; [n,m] = size(X); if min([n m]) == 1 y = sdpvar(1,1); internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end},[]}; internal_sdpvarstate.ExtendedMap(end).var = y; internal_sdpvarstate.ExtendedMap(end).computes = getvariables(y); internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; internal_sdpvarstate.ExtendedMap(end).Hash = this_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes this_hash]; else y = sdpvar(1,m); for i = 1:m if isa(X(:,i),'double') y(i) = max(X(:,i)); else internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {X(:,i),[]}; internal_sdpvarstate.ExtendedMap(end).var = y(i); internal_sdpvarstate.ExtendedMap(end).computes = getvariables(y(i)); new_hash = create_trivial_hash(X(:,i)); internal_sdpvarstate.ExtendedMap(end).Hash = new_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes new_hash]; end end internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; end y = setoperatorname(y,varargin{2}); case {'abs'} % ABS is a bit special since we need one % new variable for each element... X = varargin{3:end}; y = sdpvar(numel(X),1); allNewExtended = []; allNewExtendedIndex = []; allPreviouslyDefinedExtendedToIndex = []; allPreviouslyDefinedExtendedFromIndex = []; if ~isempty(internal_sdpvarstate.ExtendedMap) correct_operator = find(strcmp(varargin{2},{internal_sdpvarstate.ExtendedMap(:).fcn})); end if numel(X)==1 found = 0; if ~isempty(correct_operator) this_hash = create_trivial_hash(X); for j = correct_operator;% find(correct_operator) if this_hash == internal_sdpvarstate.ExtendedMap(j).Hash if isequal(X,internal_sdpvarstate.ExtendedMap(j).arg{1},1) % y = internal_sdpvarstate.ExtendedMap(j).var; allPreviouslyDefinedExtendedToIndex = [1]; allPreviouslyDefinedExtendedFromIndex = [j]; found = 1; break end end end end if ~found internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {X,binvar(1),[]}; internal_sdpvarstate.ExtendedMap(end).var = y; internal_sdpvarstate.ExtendedMap(end).computes = getvariables(y); new_hash = create_trivial_hash(X); internal_sdpvarstate.ExtendedMap(end).Hash = new_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes new_hash]; allNewExtended = y; allNewExtendedIndex = 1; end else aux_bin = binvar(numel(X),1); vec_hashes = create_trivial_vechash(X); vec_isdoubles = create_vecisdouble(X); for i = 1:numel(X) % This is a bummer. If we scalarize the abs-operator, % we have to search through all scalar abs-operators % to find this single element found = 0; Xi = X(i); if vec_isdoubles(i)%isa(Xi,'double') found = 1; y(i) = abs(X(i)); else if ~isempty(correct_operator) this_hash = vec_hashes(i); for j = correct_operator if this_hash == internal_sdpvarstate.ExtendedMap(j).Hash if isequal(Xi,internal_sdpvarstate.ExtendedMap(j).arg{1},1) allPreviouslyDefinedExtendedToIndex = [allPreviouslyDefinedExtendedToIndex i]; allPreviouslyDefinedExtendedFromIndex = [allPreviouslyDefinedExtendedFromIndex j]; found = 1; break end end end end end if ~found yi = y(i); internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {Xi,aux_bin(i),[]}; internal_sdpvarstate.ExtendedMap(end).var = yi; internal_sdpvarstate.ExtendedMap(end).computes = getvariables(yi); new_hash = create_trivial_hash(Xi); internal_sdpvarstate.ExtendedMap(end).Hash = new_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes new_hash]; allNewExtendedIndex = [allNewExtendedIndex i]; % Add this to the list of possible matches. % Required for repeated elements in argument % (such as a symmetric matrix) correct_operator = [correct_operator length(internal_sdpvarstate.ExtendedMap)]; end end end y(allPreviouslyDefinedExtendedToIndex) = [internal_sdpvarstate.ExtendedMap(allPreviouslyDefinedExtendedFromIndex).var]; allNewExtended = y(allNewExtendedIndex); y_vars = getvariables(allNewExtended); internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables y_vars]; y = reshape(y,size(X,1),size(X,2)); y = setoperatorname(y,varargin{2}); otherwise % This is the standard operators. INPUTS -> 1 scalar output if isequal(varargin{2},'or') || isequal(varargin{2},'xor') || isequal(varargin{2},'and') || isequal(varargin{2},'not') y = binvar(1,1); elseif isequal(varargin{2},'sign') y = intvar(nout(1),nout(2)); else y = sdpvar(nout(1),nout(2)); end if ~strcmpi({'sort'},varargin{2}) % Oh fuck is this ugly. Sort assumes ordering on some % variables, and thus assumes no z in between. This % will be generalized when R^n -> R^m is supported for % real % Actually, we can skip these normalizing variables for % everything which isn't based on callbacks. This saves % a lot of setup time on huge models if ~(strcmp(varargin{2},'norm') || strcmp(varargin{2},'abs')) z = sdpvar(size(varargin{3},1),size(varargin{3},2),'full'); % Standard format y=f(z),z==arg internal_sdpvarstate.auxVariables = [ internal_sdpvarstate.auxVariables getvariables(z)]; else z = []; end internal_sdpvarstate.auxVariables = [ internal_sdpvarstate.auxVariables getvariables(y)]; else z = []; end for i = 1:nout % Avoid subsref to save time if nout == 1 yi = y; else yi = y(i); end internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end},z}; internal_sdpvarstate.ExtendedMap(end).var = yi; internal_sdpvarstate.ExtendedMap(end).computes = getvariables(y); internal_sdpvarstate.ExtendedMap(end).Hash = this_hash; internal_sdpvarstate.ExtendedMapHashes = [internal_sdpvarstate.ExtendedMapHashes this_hash]; internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(yi)]; internal_sdpvarstate.containsSemivar = internal_sdpvarstate.containsSemivar | strcmp(varargin{2}, 'semivar'); end y = setoperatorname(y,varargin{2}); end for i = 3:length(varargin) if isa(varargin{i},'sdpvar') yalmip('setdependence',getvariables(y),getvariables(varargin{i})); end end varargout{1} = flush(clearconic(y)); return case 'setdependence' if ~isempty(varargin{2}) && ~isempty(varargin{3}) if isa(varargin{2},'sdpvar') varargin{2} = getvariables(varargin{2}); end if isa(varargin{3},'sdpvar') varargin{3} = getvariables(varargin{3}); end % This dies not work since the arguments have different % ordering. Try for instance x=sdpvar(2),[x>=0,abs(x)>=0] % nx = max(size(internal_sdpvarstate.DependencyMap,1),max(varargin{2})); % ny = max(size(internal_sdpvarstate.DependencyMap,2),max(varargin{3})); % index = sub2ind([nx ny], varargin{2},varargin{3}); % if size(internal_sdpvarstate.DependencyMap,1) < nx || size(internal_sdpvarstate.DependencyMap,2) < ny % internal_sdpvarstate.DependencyMap(nx,ny) = 0; % end temp1 = repmat(varargin{2},size(varargin{3},2),1);temp1 = temp1(:)'; temp2 = repmat(varargin{3},1,size(varargin{2},2));temp2 = temp2(:)'; internal_sdpvarstate.DependencyMap_i = [internal_sdpvarstate.DependencyMap_i temp1]; internal_sdpvarstate.DependencyMap_j = [internal_sdpvarstate.DependencyMap_j temp2]; n = size(internal_sdpvarstate.monomtable,1); if size(internal_sdpvarstate.DependencyMap,1) < n internal_sdpvarstate.DependencyMap(n,1)=0; end if size(internal_sdpvarstate.DependencyMap,2) < n internal_sdpvarstate.DependencyMap(end,n)=0; end end case 'setdependenceUser' if ~isempty(varargin{2}) && ~isempty(varargin{3}) if isa(varargin{2},'sdpvar') varargin{2} = getvariables(varargin{2}); end if isa(varargin{3},'sdpvar') varargin{3} = getvariables(varargin{3}); end internal_sdpvarstate.DependencyMapUser(varargin{2},varargin{3}) = 1; n = size(internal_sdpvarstate.monomtable,1); if size(internal_sdpvarstate.DependencyMapUser,1) < n internal_sdpvarstate.DependencyMapUser(n,1)=0; end if size(internal_sdpvarstate.DependencyMapUser,2) < n internal_sdpvarstate.DependencyMapUser(end,n)=0; end end case 'getdependence' %varargout{1} = internal_sdpvarstate.DependencyMap; if isempty(internal_sdpvarstate.DependencyMap_i) varargout{1} = sparse(0); else try varargout{1} = sparse(internal_sdpvarstate.DependencyMap_i,internal_sdpvarstate.DependencyMap_j,1); catch 1 end end n = size(internal_sdpvarstate.monomtable,1); if size(varargout{1},1) < n || size(varargout{1},2)=varargin{2} internal_sdpvarstate.activeSolution = varargin{2}; else error('Solution not available'); end case 'setsolution' if nargin < 3 solutionIndex = 1; else solutionIndex = varargin{3}; end internal_sdpvarstate.activeSolution = 1; % Clear trailing solutions if solutionIndex < length(internal_sdpvarstate.optSolution) internal_sdpvarstate.optSolution = {internal_sdpvarstate.optSolution{1:solutionIndex}}; elseif solutionIndex > length(internal_sdpvarstate.optSolution)+1 for j = length(internal_sdpvarstate.optSolution)+1:solutionIndex internal_sdpvarstate.optSolution{j}.optvar=[]; internal_sdpvarstate.optSolution{j}.variables=[]; internal_sdpvarstate.optSolution{j}.values=[]; end elseif solutionIndex == length(internal_sdpvarstate.optSolution)+1 internal_sdpvarstate.optSolution{solutionIndex}.optvar=[]; internal_sdpvarstate.optSolution{solutionIndex}.variables=[]; internal_sdpvarstate.optSolution{solutionIndex}.values=[]; end if isempty(internal_sdpvarstate.optSolution{solutionIndex}.variables) internal_sdpvarstate.optSolution{solutionIndex} = varargin{2}; else % Just save some stuff first newSolution = varargin{2}; oldSolution = internal_sdpvarstate.optSolution{solutionIndex}; optSolution = varargin{2}; keep_these = find(~ismember(oldSolution.variables,newSolution.variables)); internal_sdpvarstate.optSolution{solutionIndex}.optvar = [oldSolution.optvar(keep_these);newSolution.optvar(:)]; internal_sdpvarstate.optSolution{solutionIndex}.variables = [oldSolution.variables(keep_these);newSolution.variables(:)]; end % clear evaluated values (only used cache-wise) internal_sdpvarstate.optSolution{solutionIndex}.values = []; return % case 'setsolution' % % if isempty(internal_sdpvarstate.optSolution.variables) % internal_sdpvarstate.optSolution = varargin{2}; % else % % Just save some stuff first % newSolution = varargin{2}; % oldSolution = internal_sdpvarstate.optSolution; % optSolution = varargin{2}; % keep_these = find(~ismember(oldSolution.variables,newSolution.variables)); % internal_sdpvarstate.optSolution.optvar = [oldSolution.optvar(keep_these);newSolution.optvar(:)]; % internal_sdpvarstate.optSolution.variables = [oldSolution.variables(keep_these);newSolution.variables(:)]; % end % % clear evaluated values (only used cache-wise) % internal_sdpvarstate.optSolution.values = []; % return case 'addauxvariables' internal_sdpvarstate.auxVariables = [internal_sdpvarstate.auxVariables varargin{2}(:)']; case 'addauxvariablesW' internal_sdpvarstate.auxVariablesW = [internal_sdpvarstate.auxVariablesW varargin{2}(:)']; case 'getsolution' varargout{1} = internal_sdpvarstate.optSolution{internal_sdpvarstate.activeSolution}; return case 'setdual' internal_setstate.duals_index = varargin{2}; internal_setstate.duals_data = varargin{3}; if ~isempty(internal_setstate.duals_associated_index) if ~isempty(intersect(internal_setstate.duals_index,internal_setstate.duals_associated_index)) for i = 1:length(internal_setstate.duals_index) itshere = find(internal_setstate.duals_associated_index==internal_setstate.duals_index(i)); if ~isempty(itshere) assign(internal_setstate.duals_associated_data{itshere},internal_setstate.duals_data{i}); end end end end case 'dual' if isempty(internal_setstate.duals_index) varargout{1}=[]; else LMIid = varargin{2}; index_to_dual = find(LMIid==internal_setstate.duals_index); if isempty(index_to_dual) varargout{1}=[]; else varargout{1} = internal_setstate.duals_data{index_to_dual}; end end case 'clearsos' if nargin==1 internal_sdpvarstate.sos_index = []; internal_sdpvarstate.sos_data = []; internal_sdpvarstate.sos_ParV = []; internal_sdpvarstate.sos_Q = []; internal_sdpvarstate.sos_v = []; end case 'setsos' if ~isempty(internal_sdpvarstate.sos_index) where = find(internal_sdpvarstate.sos_index==varargin{2}); if ~isempty(where) internal_sdpvarstate.sos_index(where) = varargin{2}; internal_sdpvarstate.sos_data{where} = varargin{3}; internal_sdpvarstate.sos_ParV{where} = varargin{4}; internal_sdpvarstate.sos_Q{where} = varargin{5}; internal_sdpvarstate.sos_v{where} = varargin{6}; else internal_sdpvarstate.sos_index(end+1) = varargin{2}; internal_sdpvarstate.sos_data{end+1} = varargin{3}; internal_sdpvarstate.sos_ParV{end+1} = varargin{4}; internal_sdpvarstate.sos_Q{end+1} = varargin{5}; internal_sdpvarstate.sos_v{end+1} = varargin{6}; end else internal_sdpvarstate.sos_index(end+1) = varargin{2}; internal_sdpvarstate.sos_data{end+1} = varargin{3}; internal_sdpvarstate.sos_ParV{end+1} = varargin{4}; internal_sdpvarstate.sos_Q{end+1} = varargin{5}; internal_sdpvarstate.sos_v{end+1} = varargin{6}; end case 'sosid' if not(isempty(internal_sdpvarstate.sosid)) internal_sdpvarstate.sosid = internal_sdpvarstate.sosid+1; varargout{1}=internal_sdpvarstate.sosid; else internal_sdpvarstate.sosid=1; varargout{1}=internal_sdpvarstate.sosid; end case 'getsos' if isempty(internal_sdpvarstate.sos_index) varargout{1}=[]; varargout{2}=[]; varargout{3}=[]; varargout{4}=[]; else SOSid = varargin{2}; index_to_sos = find(SOSid==internal_sdpvarstate.sos_index); if isempty(index_to_sos) varargout{1}=[]; varargout{2}=[]; varargout{3}=[]; varargout{4}=[]; else varargout{1} = internal_sdpvarstate.sos_data{index_to_sos}; varargout{2} = internal_sdpvarstate.sos_ParV{index_to_sos}; varargout{3} = internal_sdpvarstate.sos_Q{index_to_sos}; varargout{4} = internal_sdpvarstate.sos_v{index_to_sos}; % FIX end end case 'getinternalsetstate' varargout{1} = internal_setstate; % Get internal state, called from saveobj case 'setinternalsetstate' internal_setstate = varargin{2}; % Set internal state, called from loadobj case 'getinternalsdpvarstate' varargout{1} = internal_sdpvarstate; % Get internal state, called from saveobj case 'setinternalsdpvarstate' internal_sdpvarstate = varargin{2}; % Set internal state, called from loadobj % Back-wards compability.... if ~isfield(internal_sdpvarstate,'extVariables') internal_sdpvarstate.extVariables = []; end if ~isfield(internal_sdpvarstate,'ExtendedMap') internal_sdpvarstate.ExtendedMap = []; internal_sdpvarstate.containsSemivar = false; end if ~isfield(internal_sdpvarstate,'ExtendedMapHashes') internal_sdpvarstate.ExtendedMapHashes = []; end if ~isfield(internal_sdpvarstate,'variabletype') internal_sdpvarstate.variabletype = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); end if ~isfield(internal_sdpvarstate,'hash') internal_sdpvarstate.hash=[]; internal_sdpvarstate.hashedmonomtable=[]; end % Re-compute some stuff for safety internal_sdpvarstate.variabletype = internal_sdpvarstate.variabletype(:)'; internal_sdpvarstate.variabletype = spalloc(size(internal_sdpvarstate.monomtable,1),1,0)'; nonlinear = ~(sum(internal_sdpvarstate.monomtable,2)==1 & sum(internal_sdpvarstate.monomtable~=0,2)==1); if ~isempty(nonlinear) mt = internal_sdpvarstate.monomtable; internal_sdpvarstate.variabletype(nonlinear) = 3; quadratic = sum(internal_sdpvarstate.monomtable,2)==2; internal_sdpvarstate.variabletype(quadratic) = 2; bilinear = max(internal_sdpvarstate.monomtable,[],2)<=1; internal_sdpvarstate.variabletype(bilinear & quadratic) = 1; sigmonial = any(0>internal_sdpvarstate.monomtable,2) | any(internal_sdpvarstate.monomtable-fix(internal_sdpvarstate.monomtable),2); internal_sdpvarstate.variabletype(sigmonial) = 4; end [n,m] = size(internal_sdpvarstate.monomtable); if n>m internal_sdpvarstate.monomtable(n,n) = 0; end if size(internal_sdpvarstate.monomtable,2)>length(internal_sdpvarstate.hash) % Need new hash-keys internal_sdpvarstate.hash = [internal_sdpvarstate.hash ; 3*gen_rand_hash(size(internal_sdpvarstate.monomtable,1),need_new,1)]; end if size(internal_sdpvarstate.monomtable,1)>size(internal_sdpvarstate.hashedmonomtable,1) % Need to add some hash values need_new = size(internal_sdpvarstate.monomtable,1) - size(internal_sdpvarstate.hashedmonomtable,1); internal_sdpvarstate.hashedmonomtable = [internal_sdpvarstate.hashedmonomtable;internal_sdpvarstate.monomtable(end-need_new+1:end,:)*internal_sdpvarstate.hash]; end case {'version','ver'} varargout{1} = '20181012'; case 'setintvariables' internal_sdpvarstate.intVariables = varargin{2}; case 'intvariables' varargout{1} = internal_sdpvarstate.intVariables; case 'setbinvariables' internal_sdpvarstate.binVariables = varargin{2}; case 'binvariables' varargout{1} = internal_sdpvarstate.binVariables; case 'settempintvariables' internal_sdpvarstate.tempintVariables = varargin{2}; case 'tempintvariables' varargout{1} = internal_sdpvarstate.tempintVariables; case 'settempbinvariables' internal_sdpvarstate.tempbinVariables = varargin{2}; case 'tempbinvariables' varargout{1} = internal_sdpvarstate.tempbinVariables; case 'quantvariables' varargout{1} = [internal_sdpvarstate.binVariables internal_sdpvarstate.intVariables]; case 'setsemicontvariables' internal_sdpvarstate.semicontVariables = varargin{2}; case 'semicontvariables' varargout{1} = internal_sdpvarstate.semicontVariables; case 'setuncvariables' internal_sdpvarstate.uncVariables = varargin{2}; case 'uncvariables' varargout{1} = internal_sdpvarstate.uncVariables; case 'setparvariables' internal_sdpvarstate.parVariables = varargin{2}; case 'parvariables' varargout{1} = internal_sdpvarstate.parVariables; case 'nonCommutingVariables' if isempty(internal_sdpvarstate.nonCommutingTable) varargout{1} = []; else varargout{1} = find(isnan(internal_sdpvarstate.nonCommutingTable(:,1))); end case 'nonCommutingTable' if nargin == 2 internal_sdpvarstate.nonCommutingTable = varargin{2}; else varargout{1} = internal_sdpvarstate.nonCommutingTable; end case 'nonlinearvariables' error('Internal error (ref. nonlinear variables). Report!') varargout{1} = internal_sdpvarstate.nonlinearvariables; if nargout==2 varargout{2} = internal_sdpvarstate.nonlinearvariablesCompressed; end % case {'addinternal'} internal_sdpvarstate.internalconstraints{end+1} = varargin{1}; % case {'setnvars'} % sdpvar('setnvars',varargin{2}); case {'nvars'} varargout{1} = size(internal_sdpvarstate.monomtable,1); % varargout{1} = sdpvar('nvars'); case {'info'} [version,release] = yalmip('version'); currentversion = num2str(version(1)); i = 1; while isize(internal_sdpvarstate.boundlist,1) need_new = max(indicies)-size(internal_sdpvarstate.boundlist,1); internal_sdpvarstate.boundlist = [internal_sdpvarstate.boundlist;inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1)]; end varargout{1} = internal_sdpvarstate.boundlist(indicies,:); varargout{2} = internal_sdpvarstate.boundlist(indicies,:); case 'setbounds' if ~isfield(internal_sdpvarstate,'boundlist') internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); elseif isempty(internal_sdpvarstate.boundlist) internal_sdpvarstate.boundlist = inf*repmat([-1 1],size(internal_sdpvarstate.monomtable,1),1); end indicies = varargin{2}; if size(internal_sdpvarstate.boundlist,1) 1 scalar output y = sdpvar(1,1); internal_sdpvarstate.ExtendedMap(end+1).fcn = varargin{2}; internal_sdpvarstate.ExtendedMap(end).arg = {varargin{3:end}}; internal_sdpvarstate.ExtendedMap(end).var = y; internal_sdpvarstate.extVariables = [internal_sdpvarstate.extVariables getvariables(y)]; internal_sdpvarstate.logicVariables = [internal_sdpvarstate.logicVariables getvariables(y)]; internal_sdpvarstate.containsSemivar = internal_sdpvarstate.containsSemivar | strcmp(varargin{2}, 'semivar'); varargout{1} = y; return case 'setNonHermitianNonCommuting' internal_sdpvarstate.nonHermitiannonCommutingTable(varargin{2}) = 1; case 'solver' if (nargin==2) if isa(varargin{2},'char') solver = varargin{2}; prefered_solver = solver; else error('Second argument should be a string with solver name'); end else if isempty(prefered_solver) varargout{1}=''; else varargout{1} = prefered_solver; end end case 'containsSemivar' varargout = {internal_sdpvarstate.containsSemivar}; otherwise if isa(varargin{1},'char') disp(['The command ''' varargin{1} ''' is not valid in YALMIP.m']); else disp('The first argument should be a string'); end end function h = create_vecisdouble(x) B = getbase(x); h = ~any(B(:,2:end),2); function h = create_trivial_hash(x) try h = sum(getvariables(x)) + sum(sum(getbase(x))); catch h = 0; end function h = create_trivial_vechash(x) try B = getbase(x); h = sum(B')'+(B | B)*[0;getvariables(x)']; catch h = 0; end function X = firstSDPVAR(List) X = []; for i = 1:length(List) if isa(List{i},'sdpvar') X = List{i}; break end end