


determine active facet validity boundaries, corresponding validity projection and applicable region for projection THIS IS NO USER FUNCTION


0001 function data = generateSampleProjectionData(heMatrix, dec, par) 0002 % determine active facet validity boundaries, corresponding validity 0003 % projection and applicable region for projection 0004 % 0005 % THIS IS NO USER FUNCTION 0006 0007 % The elk-library: convex geometry applied to crystallization modeling. 0008 % Copyright (C) 2013 Alexander Reinhold 0009 % 0010 % This program is free software: you can redistribute it and/or modify it 0011 % under the terms of the GNU General Public License as published by the 0012 % Free Software Foundation, either version 3 of the License, or (at your 0013 % option) any later version. 0014 % 0015 % This program is distributed in the hope that it will be useful, but 0016 % WITHOUT ANY WARRANTY; without even the implied warranty of 0017 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0018 % General Public License for more details. 0019 % 0020 % You should have received a copy of the GNU General Public License along 0021 % with this program. If not, see <http://www.gnu.org/licenses/>. 0022 0023 % The input hcMatrix should not contain zero vectors. The approximation 0024 % will never contribute to any error (always perfectly approximated. 0025 % The input does also not contain invalid vectors. But vectors at the 0026 % boundary of the validity cone for which the information in this 0027 % function is actually generated. 0028 0029 %! DEV: This code lines are somewhat badly written, it is sometimes not 0030 % clear what projection index is meant between the different lists 0031 % and purposes (last for loop). 0032 %/ 0033 0034 % For the initialization of the projection data, we already assume that 0035 % some vectors will be valid. But even if this is not the case and the 0036 % index 1 is not used in the end, this is OK. 0037 nE = size(heMatrix, 1); 0038 nSample = size(heMatrix, 2); 0039 0040 data.list.validityProjection = eye(nE); 0041 data.list.facetPresentConstraint = zeros(0, nE); 0042 data.list.projectionApplicableConstraint = zeros(0, nE); 0043 data.assignedProjectionVector = ones(1, nSample); 0044 0045 % shortcut for PCA objective, incomplete representations and valid 0046 % projections 0047 0048 %! DEV: removed options errorType=PCA and ~dec.isComplete, for these cases 0049 % we have to apply the 'true' projection somewhere else. The 0050 % arguments were: 0051 % 1) everey vector stays projected as it is, no fancy things to do 0052 % 2) For an incomplete representation, we can even have invalid vectors 0053 % during measure calculation as we have only one unified partition. 0054 % The aim of extended embeddings (incomplete representations) IS to 0055 % use no shape-dependent stuff like boundaries. 0056 %/ 0057 if strcmpi(par.projectionType, 'true') 0058 return 0059 elseif strcmpi(par.projectionType, 'valid') 0060 % the resulting vectors must be valid 0061 data.list.facetPresentConstraint = dec.validityCone.A; 0062 return 0063 %! DEV: When is that required?? 0064 elseif strcmpi(par.projectionType, 'confined') 0065 % the gibberish below will be executed. ..nothing to do 0066 else 0067 error('elk:approximation:internalError', ['The projection type is ' ... 0068 'unknown. This should not happen.']) 0069 end 0070 0071 % Cycling through all facet groups might save some time, even though the 0072 % handling of new projections seems to be more complicated. 0073 for iGroup = 1:nE 0074 nProjection = max(data.assignedProjectionVector); 0075 0076 % the constraint for this facet group being present 0077 facetPresentConstraint = dec.confinementMappingData.A(... 0078 dec.confinementMappingData.responsibleVector == iGroup, :); 0079 % find vectors with corresponding disappeared facets while they are 0080 % slightly more quickly assumed to be at this boundary 0081 heFilter = any(facetPresentConstraint * heMatrix ... 0082 > -1*par.zerotol, 1); 0083 heIndexVector = find(heFilter); 0084 0085 % if the current facet group is present for all vectors, we make a 0086 % short circuit, here 0087 if all(~heFilter) 0088 for iProjection = 1:nProjection 0089 data.list(iProjection).facetPresentConstraint = [... 0090 data.list(iProjection).facetPresentConstraint; ... 0091 facetPresentConstraint]; 0092 end 0093 continue; 0094 end 0095 0096 % obtain projection matrices and constraints for the applicability of 0097 % the projection - we need to apply some larger zerotol than for 0098 % filtering the initial vectors because this constraint is also 0099 % contained there 0100 [dump projectionIndexVector constraintList] = projectFromData(... 0101 heMatrix(:, heFilter), ... 0102 dec.confinementMappingData.projectionData(iGroup), ... 0103 2*par.zerotol, 1); 0104 groupProjectionVector = unique(projectionIndexVector); 0105 nProjectionNew = length(groupProjectionVector); 0106 0107 % cycle through the original projections and see, if they need to be 0108 % split up 0109 for iProjectionOriginal = 1:nProjection 0110 % copy original projection and constraints 0111 listOriginal = data.list(iProjectionOriginal); 0112 % affected vectors 0113 thisVectorFilter = heFilter & (... 0114 data.assignedProjectionVector == iProjectionOriginal); 0115 0116 if any(~thisVectorFilter) 0117 % no projection is concatenated for this projection since 0118 % all assigned vectors have the current facet group being 0119 % present 0120 0121 % ..projection remains 0122 % ..necessarily present facets are expanded 0123 data.list(iProjectionOriginal).facetPresentConstraint = [... 0124 listOriginal.facetPresentConstraint; ... 0125 facetPresentConstraint]; 0126 % ..no contraint on the applicability of the projection 0127 % ..the assigned vectors change, but this is done when the new 0128 % projections are created 0129 0130 % new projection entries must be created for each new 0131 % projection 0132 thisProjectionIndexVector = nProjection + (1:nProjectionNew); 0133 elseif all(thisVectorFilter) 0134 % this entry can be used to contain the very first projection 0135 thisProjectionIndexVector = [iProjectionOriginal ... 0136 (nProjection + 1:(nProjectionNew-1))]; 0137 end 0138 0139 % expand projection list, but make sure to do this last entry to 0140 % first entry as the first entry overwrites the original data. 0141 for iProjectionNew = nProjectionNew:-1:1 0142 thisProjectionListIndex = thisProjectionIndexVector(iProjectionNew); 0143 thisGroupProjectionIndex = groupProjectionVector(iProjectionNew); 0144 0145 % ..projection is extended 0146 data.list(thisProjectionListIndex).validityProjection = ... 0147 listOriginal.validityProjection * ... 0148 dec.confinementMappingData.projectionData(iGroup... 0149 ).projectionList{thisGroupProjectionIndex}; 0150 % ..necessarily present facets remain (this group is not 0151 % present) 0152 data.list(thisProjectionListIndex).facetPresentConstraint = ... 0153 listOriginal.facetPresentConstraint; 0154 % ..constraints for the applicability of the projection are 0155 % expanded 0156 data.list(thisProjectionListIndex).projectionApplicableConstraint = ... 0157 [listOriginal.projectionApplicableConstraint; ... 0158 constraintList{find(... 0159 projectionIndexVector==thisGroupProjectionIndex, ... 0160 1, 'first')}... 0161 ]; 0162 % ..vectors need to be assigned, here 0163 data.assignedProjectionVector(heIndexVector(... 0164 projectionIndexVector == thisGroupProjectionIndex)) = ... 0165 thisProjectionListIndex; 0166 0167 end 0168 end 0169 end