function generateUnifyingApprox(pbeDef, targetDimension, caseNameBase, ...
    caseList, runNonlinear)
% generate projection and save it in local database folder
%
% saved data: ./database/<caseName>_<samplePointType>_<approxType>_<targetDim>.matx
% where data contains: dec, cdef, projectionMatrix

% get my location
myPath = fileparts(which(mfilename));

% extended embedding
thisFileName = ['database' filesep caseNameBase '_decExt.matx'];
if exist(thisFileName, 'file')
    data = load(thisFileName, '-mat');
    decExt = data.decExt;
else
    decExt = computeUnifyingDec(pbeDef.dec);
    save(thisFileName, 'decExt');
end

% %% PCA projections for all sample data
% for iCase = 1:length(caseList)
%     % construct file names
%     thisLoadFile = [myPath filesep 'data' filesep ...
%         caseNameBase '_pointSet_' caseList{iCase} '.matx'];
%     thisSaveFile = [myPath filesep 'database' filesep ...
%         caseNameBase '_' num2str(targetDimension) '_uPCA_' ...
%           caseList{iCase} '.matx'];
%       
%     % cancel if the result was already generated
%     if exist(thisSaveFile, 'file')
%         continue
%     end
%     
%     % load point set into variable: data
%     load(thisLoadFile, '-mat');
%     
%     % map to extended embedding
%     heMatrix = mapToExtendedEmbedding(dataPointSet.hcMatrix, decExt);
%     
%     % approximation
%     disp(['Generating approximation for: ' thisSaveFile]);
%     dataApprox = approximateDec(heMatrix, decExt, ...
%         'method', 'PCA', ...
%         'targetDim', targetDimension);
%     disp('..done (approximation).');
%     
%     % projection of decomposition
%     disp(['Projecting decomposition for: ' thisSaveFile]);
%     dec = projectDec(decExt, dataApprox.mappingReducedToFull);
%     disp('..done (projection).');
%     
%     % save new decomposition
%     dataApprox.dec = dec;
%     dataApprox.cdef = pbeDef.dec.cdef;
%     save(thisSaveFile, '-mat', 'dataApprox');
% end

%% Nonlinear projections
if exist('runNonlinear', 'var') && ~isempty(runNonlinear)
% runNonlinear{1} - name descriptor
% runNonlinear{1} - measureList
for iCase = 1:length(caseList)
    % construct file names
    thisLoadFile = [myPath filesep 'data' filesep ...
        caseNameBase '_pointSet_' caseList{iCase} '.matx'];
    thisSaveFile = [myPath filesep 'database' filesep ...
        caseNameBase '_' num2str(targetDimension) 'u_' ...
        runNonlinear{1} '_' ...
          caseList{iCase} '.matx'];
      
    % cancel if the result was already generated
    if exist(thisSaveFile, 'file')
        continue
    end
    
    % load point set into variable: data
    load(thisLoadFile, '-mat');
    heMatrix = mapToExtendedEmbedding(dataPointSet.hcMatrix, decExt)
    
    % approximation
    disp(['Generating approximation for: ' thisSaveFile]);
    dataApprox = approximateDec(heMatrix, decExt, ...
        'method', 'nonlinear', ...
        'targetDim', targetDimension, ...
        'measureList', runNonlinear{2}, ...
        'errorType', 'relativeSquared', ...
        'projectionType', 'true');
    disp('..done (approximation).');
        
    % projection of decomposition
    disp(['Projecting decomposition for: ' thisSaveFile]);
    dec = projectDec(decExt, dataApprox.mappingReducedToFull);
    disp('..done (projection).');
    
    % prepare growth rate mapping
    % ..this first part relies on the construction of the proper embedding
    %   to construct a mean projection from the original representation to
    %   the embedding
    decO = decExt.originalData;
    partitionVector = computePartitionIndexDec(decO, dataPointSet.hcMatrix, [], 1);
    mappingOtoE = zeros(decExt.nC, decO.nC);
    for iPart = 1:decO.nPU
        simplexIndex = decO.unifiedToSimplexVector(iPart);
        lamMapping = zeros(decO.nS, decO.nC);
        lamMapping(decO.simplexPartition{simplexIndex}.seIndexVector, :) = ...
            decO.simplexPartition{simplexIndex}.mappingHcToLam;
        
        mappingOtoE = mappingOtoE + ...
            sum(partitionVector==iPart)/length(partitionVector)*...
            decExt.se' * lamMapping;
    end
    % ..this second part constructs the mean mapping matrix from the
    %   original representation (over the embedding) to the approximation
    dataApprox.mappingMatrixOtoC = dec.properData.mappingProperToNew * mappingOtoE;
    
    % save new decomposition
    dataApprox.dec = dec;
    dataApprox.decExt = decExt;
    dataApprox.cdef = pbeDef.dec.cdef;
    save(thisSaveFile, '-mat', 'dataApprox');
end
end