📄 sdmobj.m
字号:
function quiz = sdmobj(quiz,Xindex,L,R,name)% SDMPB/SDMOBJ - add term to the linear objective%% quiz = sdmobj(quiz,Xindex,L,R,name);% % adds a term to the linear objective% the solver will maximise the real part of the objective% % <Xindex> specifies the matrix variable% <L> specifies the row vector multiplying the variable from the left% <R> specifies the column vector multiplying the variable from the right% default R=L'% if <L='tr'> the objective is the maximisation of : trace(R*X) % default R=1% <name> is an optional string that describes the added objective term%% SEE ALSO sdmvar, sdmlmi, sdmineq and sdmsol.% This file is part of SeDuMi Interface 1.04 (JUL2002)% Last update 9th Spetember 2002% Copyright (C) 2002 Dimitri Peaucelle & Krysten Taitz% LAAS-CNRS, Toulouse, France% % This program is free software; you can redistribute it and/or modify% it under the terms of the GNU General Public License as published by% the Free Software Foundation; either version 2 of the License, or% (at your option) any later version.% % This program is distributed in the hope that it will be useful,% but WITHOUT ANY WARRANTY; without even the implied warranty of% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the% GNU General Public License for more details.% % You should have received a copy of the GNU General Public License% along with this program; if not, write to the Free Software% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. %%% check inputs if nargin<3 error('not enough input arguments'); elseif nargin>5 error('too many input arguments'); elseif ~isa(quiz,'sdmpb') error('1st input argument must be a SDMPB object'); end; %%% check the input <Xindex> if ( ~isnumeric(Xindex) | (mod(Xindex,2)~=1 & mod(Xindex,2)~=0) | any(size(Xindex)-[1,1])) error('2nd input argument (index of the variable) must be an integer'); elseif Xindex>quiz.var.nb error('2nd input argument (index of the variable) exceeds the number of variables'); elseif Xindex<=0 error('2nd input argument (index of the variable) must be strictly positive'); end; % dimensions of the variable varm=quiz.var.m(Xindex); varM=quiz.var.M(Xindex); varrow=quiz.var.row(Xindex); varcol=quiz.var.col(Xindex); %%% check the inputs <L> and <R> % in the case the objective is a trace if ischar(L) if nargin<4, R=1; elseif isempty(R), R=1; elseif ~isnumeric(R) error('4th input argument (multiplyer of the trace) must be a matrix'); end; % an option due to an old version of SeDuMi Interface if isequal(L,'-tr') L='tr'; R=-R; end; if isequal(L,'tr') if max(size(R))==1 if ~isequal(varrow,varcol) error('The variable (referenced by 2nd input argument) must be a square matrix'); else% dimbloc=varM+1-varm;% nbrow=sqrt(dimbloc);% add=sparse(1,1:(1+nbrow):dimbloc,1)*R; add=sparse(1,1:(1+varrow):(varrow*varcol),1)*R; end; else if ~isequal(size(R,2),varrow) error(['3rd input argument (Right multiplier) must have the same' ... 'number of columns as the number of rows of the' ... ' variable']); end; if ~isequal(size(R,1),varcol) error(['3rd input argument (Right multiplier) must have as many' ... ' rows as the number of columns of the variable']); end; % define the objective Tr(R*X)=vec(R.').'*vec(X) add=sdmvec(R.').'; end% addconj=conj(add); else error('3rd input argument must either be a row vector or the strings ''tr'''); end; % in the case the objective is L*X*R = a scalar else % check <L> if ~isnumeric(L) error(['3rd input argument must either be a row vector or the strings ''tr''']); end; if ~isequal(min(size(L)),1) error('3rd input argument must be a vector'); elseif length(L)~=varrow; error(['3rd input argument must be a vector of length equal to the number of rows' ... ' of the variable']); end; % force <L> to be a row vector L=sdmvec(L).'; % check <R> if nargin<4, R=[]; end; if isempty(R) R=L'; if length(R)~=varcol error(['4th input argument must be specified for non square' ... ' variables']); end; else if ~isnumeric(R) error(['4th input argument must be a vector']); elseif ~isequal(min(size(R)),1) error('4th input argument must be a vector'); elseif length(R)~=varcol error(['4rd input argument must be a vector of length equal to the number of columns' ... ' of the variable']); end; % force <R> to be a column vector R=sdmvec(R); end; %%% define the objective : L*X*R= (R.' kron L)*vec(X) add=kron(R.',L); end; %%% append the objective's name if nargin<5 name=''; elseif ~ischar(name) error('5th input argument must be a string identifying the added objective'); end; quiz.obj.name=[quiz.obj.name,name]; %%% clear the previous solution if necessary quiz = sdmclear(quiz); %%% add the term to the objective %%% we remind that vec(X)=struc*y+strucconj*conj(y) %%% where y is the vector of decision variables %%% therefore the objective writes as %%% real(add*vec(X))=real(add*struc*y+add*strucconj*conj(y) %%% =real(add*struc*y)+real(conj(add)*strucconj*y) %%% add the term that depends on the variable terms (not conjugated) struclocal=quiz.var.struc; if norm(struclocal(varm:varM,:),1) sbt=size(quiz.obj.bt); [ii,jj,s]=find(add); jj=jj+varm-1; quiz.obj.bt=quiz.obj.bt+sparse(ii,jj,s,sbt(1),sbt(2)); end; %%% and those that depend on the conjugate elements of the variable struclocal=quiz.var.strucconj; if norm(struclocal(varm:varM,:),1) sbtc=size(quiz.obj.btconj); [ii,jj,s]=find(conj(add)); jj=jj+varm-1; quiz.obj.btconj=quiz.obj.btconj+sparse(ii,jj,s,sbtc(1),sbtc(2)); end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -