0001 function dec = computeMappingAndConstraint(dec, zerotol, allowFixPosition)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 if ~isempty(dec.mappingReducedToFull) && ...
0034 size(dec.mappingReducedToFull, 1) ~= dec.nH
0035 error('elk:decomposition:wrongInput', ...
0036 ['the provided mapping matrix must have the same number ' ...
0037 'of rows like the matrix of facet normals A']);
0038 end
0039 if ~isempty(dec.constraintMatrix) && (...
0040 size(dec.constraintMatrix, 2) ~= dec.nH )
0041 error('elk:decomposition:wrongInput', ...
0042 ['the provided constraint matrix must be square and must' ...
0043 'have the size of the row number of the matrix of facet normals A']);
0044 end
0045
0046 if isempty(dec.constraintMatrix) && isempty(dec.mappingReducedToFull)
0047
0048 if allowFixPosition == 0
0049 error('elk:decomposition:fixPosition', ['you need to provide a ' ...
0050 'mapping or constraint matrix, or set allowFixPosition to -1']);
0051 elseif allowFixPosition == 1
0052 warning('elk:decomposition:fixPosition', ['Mapping and constraint ' ...
0053 'matrices are generated to fix the position of represented ' ...
0054 'polytopes, use allowFixPosition option with (-1) to supress ' ...
0055 'this warning']);
0056 end
0057
0058 dec.constraintMatrix = fixPosition(dec.A, zeros(0, size(dec.A, 1)), zerotol);
0059
0060 [~, s, v] = svd(dec.constraintMatrix);
0061 s = diag(s);
0062 s(isZero(s, zerotol)) = 0;
0063 dec.mappingReducedToFull = trimColumns(v(:, s==0), zerotol);
0064
0065 elseif isempty(dec.constraintMatrix)
0066
0067
0068 dec.constraintMatrix = eye(dec.nH) - dec.mappingReducedToFull * ...
0069 pinv(dec.mappingReducedToFull);
0070
0071 additionalConstraintMatrix = fixPosition(dec.A, dec.constraintMatrix, zerotol);
0072 if rank(additionalConstraintMatrix) ~= 0
0073
0074 if allowFixPosition == 0
0075 error('elk:decomposition:fixPosition', ['polytopes in the given ' ...
0076 'representation are not fixed in their position. change ' ...
0077 'allowFixPosition to 1 to automatically modify the ' ...
0078 'mapping matrix.']);
0079 elseif allowFixPosition == 1
0080 warning('elk:decomposition:fixPosition', ['Mapping matrix ' ...
0081 'is modified to fix the position of represented ' ...
0082 'polytopes. use allowFixPosition option with (-1) to supress ' ...
0083 'this warning']);
0084 end
0085
0086 dec.mappingReducedToFull = [];
0087 dec.constraintMatrix = [dec.constraintMatrix; additionalConstraintMatrix];
0088 dec = computeMappingAndConstraint(dec, zerotol, allowFixPosition);
0089
0090
0091
0092
0093
0094
0095
0096
0097 end
0098
0099 else
0100
0101
0102 additionalConstraintMatrix = fixPosition(dec.A, dec.constraintMatrix, zerotol);
0103 if rank(additionalConstraintMatrix) ~= 0
0104
0105 if allowFixPosition == 0
0106 error('elk:decomposition:fixPosition', ['polytopes in the given ' ...
0107 'representation are not fixed in their position. change' ...
0108 'allowFixPosition to 1 to automatically modify the ' ...
0109 'constraint matrix.']);
0110 elseif allowFixPosition == 1
0111 warning('elk:decomposition:fixPosition', ['Constraint matrix ' ...
0112 'is modified to fix the position of represented ' ...
0113 'polytopes. use allowFixPosition option with (-1) to supress ' ...
0114 'this warning']);
0115 end
0116
0117 dec.constraintMatrix = [dec.constraintMatrix; additionalConstraintMatrix];
0118 end
0119
0120 [~, s, v] = svd(dec.constraintMatrix);
0121 s = diag(s);
0122 s(isZero(s, zerotol)) = 0;
0123 dec.mappingReducedToFull = trimColumns(v(:, s==0), zerotol);
0124
0125 end
0126
0127
0128 if ~all(isZero(dec.constraintMatrix * dec.mappingReducedToFull, zerotol))
0129 error('elk:decomposition:wrongInput', ...
0130 ['the provided constraint matrix is not consistent with the ' ...
0131 'provided mapping matrix: constraint*mapping should result ' ...
0132 'in a matrix with all elements close to zero. This should not ' ...
0133 'happen.']);
0134 end
0135
0136
0137 dec.mappingFullToReduced = pinv(dec.mappingReducedToFull);
0138
0139 end