


Check & create one structure representing one matrix variable Y
The structure will be one element of array vec2Ymap used in vec2Y().
Y ... "pattern" matrix given by user (all nnz in one triangle -> variables)
offset ... gives the last number of the variable (matrix element considered
as variable) so far, so typically obj.NYnnz and 0 at the beggining;
matrix element/variables will start with number (offset+1)
and the returned offset is the last one
mapper ... structure mapping vectorized variable back to Y in a fast way
.dim ... dimxdim dimension of the matrix variable
.nelem ... no of variables (=no of elements in lower triangle)
.dense ... generate as dense (true) or sparse (false)
.xmap ... mapping the (whole) vector of (Yall) elements) -> nnz of one Y
the first one (xmap(1)) is always the same as offset+1, i.e., first
variable (counting 1...NYnnz) in this matrix;
thus this matrix is created by variables xmap(1)..xmap(1)+nelem-1
.irow, .icol ... to generate sparse matrix with xmap (if ~dense),
first nelem refer to the lower triangle, the rest to the upper;
if dense, the length is nelem and they map to the lower triangle,
it could be computed because it'll be 1,1; 2,1; ...dim,1; 2,2; 3,2;...
Note, to see exactly where the given variable maps (= its derivative):
variable with index idx=1..nelem maps to irow(idx),icol(idx) + symmetric
if nondiagonal, absolute number of such a variable (in xall()) is
idx=Nx+xmap(1), ... ,Nx+xmap(1)+nelem-1

0001 % Check & create one structure representing one matrix variable Y 0002 % The structure will be one element of array vec2Ymap used in vec2Y(). 0003 % Y ... "pattern" matrix given by user (all nnz in one triangle -> variables) 0004 % offset ... gives the last number of the variable (matrix element considered 0005 % as variable) so far, so typically obj.NYnnz and 0 at the beggining; 0006 % matrix element/variables will start with number (offset+1) 0007 % and the returned offset is the last one 0008 % mapper ... structure mapping vectorized variable back to Y in a fast way 0009 % .dim ... dimxdim dimension of the matrix variable 0010 % .nelem ... no of variables (=no of elements in lower triangle) 0011 % .dense ... generate as dense (true) or sparse (false) 0012 % .xmap ... mapping the (whole) vector of (Yall) elements) -> nnz of one Y 0013 % the first one (xmap(1)) is always the same as offset+1, i.e., first 0014 % variable (counting 1...NYnnz) in this matrix; 0015 % thus this matrix is created by variables xmap(1)..xmap(1)+nelem-1 0016 % .irow, .icol ... to generate sparse matrix with xmap (if ~dense), 0017 % first nelem refer to the lower triangle, the rest to the upper; 0018 % if dense, the length is nelem and they map to the lower triangle, 0019 % it could be computed because it'll be 1,1; 2,1; ...dim,1; 2,2; 3,2;... 0020 % Note, to see exactly where the given variable maps (= its derivative): 0021 % variable with index idx=1..nelem maps to irow(idx),icol(idx) + symmetric 0022 % if nondiagonal, absolute number of such a variable (in xall()) is 0023 % idx=Nx+xmap(1), ... ,Nx+xmap(1)+nelem-1 0024 function [mapper, offset]=createY1map(Y,offset) 0025 mapper=[]; 0026 0027 % take empty as OK? Yes, such a matrix will be filtered-out from constraints 0028 if (isempty(Y)) 0029 mapper.dim=0; 0030 mapper.nelem=0; 0031 mapper.dense=true; 0032 mapper.xmap=[]; 0033 mapper.irow=[]; 0034 mapper.icol=[]; 0035 else 0036 % does Y look OK? 0037 [dim, dim2] = size(Y); 0038 if (dim~=dim2) 0039 error('Y is not a square??'); 0040 return; 0041 end 0042 0043 if (~issparse(Y) && nnz(Y)==dim*dim) 0044 % Y is really dense and the full lower triangle will create decision vars 0045 nonnz=dim*(dim+1)/2; 0046 % do it better??? 0047 [row,col]=find(tril(Y)); % should be 1,1; 2,1; 3,1; 2,2; 3,2; ... 0048 mat=full(sparse(row,col,[1:nonnz])); 0049 mat=mat+tril(mat,-1)'; 0050 0051 mapper.dim=dim; 0052 mapper.nelem=nonnz; 0053 mapper.dense=true; 0054 mapper.xmap=offset + mat(:); % should be same as reshape(mat,dim*dim,1) 0055 %mapper.irow=[]; 0056 %mapper.icol=[]; 0057 mapper.irow=row; 0058 mapper.icol=col; 0059 offset=offset+nonnz; 0060 0061 else 0062 % work with it as sparse 0063 Y=spones(Y); % to avoid random nullification in Y+Y' 0064 Y=tril(Y+Y'); % or don't symmetrize? or check? 0065 [row, col] = find(Y); 0066 inner=find(row~=col); 0067 nonnz=length(row); 0068 0069 mapper.dim=dim; 0070 mapper.nelem=nonnz; 0071 mapper.dense=false; 0072 mapper.irow=[row; col(inner)]; 0073 mapper.icol=[col; row(inner)]; 0074 mapper.xmap= offset + [[1:nonnz]'; inner]; 0075 offset = offset + nonnz; 0076 end 0077 0078 end 0079