Member 11638763
Для расчета Intel TBB-класса:
#include "Calculation.h"
using namespace std;
/*
* Constructor
* @param dbPath - database file
* @param typeInterpolation - type interpolation
* @param useTBB - true to use TBB for parallel computation
*/
Calculation::Calculation(char* inDbPath, string inTypeInterpolation, bool inUseTBB){
dbPath = inDbPath;
typeInterpolation = inTypeInterpolation;
useTBB = inUseTBB;
}
/*
* Destructor
*/
Calculation::~Calculation()
{
}
/*
* Run the calculation cubic interpolation
*/
void Calculation::run(){
Database database;
database.open(dbPath);
vector<SSubjectSegment> segments = database.getSubjects();
const int sizeMask = 254;
tbb::mutex instanceMutex;
for (size_t i = 0; i < segments.size(); i++){
IGlucoseLevels* level = database.getGlucoseLevels(segments[i].segmentId);
CubicSplineApprox* cubic = new CubicSplineApprox(level);
if (useTBB){
tbb::tick_count tbbProcessingStart = tbb::tick_count::now();
std::cout << "# Proces: " << "0" << std::endl;
std::cout << " Message: " << "Calculation using Intel Threading Building Blocks started." << std::endl;
//calculate of the given equations for all ist values from database, use TBB library for parallelism
tbb::parallel_for(0, sizeMask, 1, [&](int j) {
TApproximationParams* params = new TApproximationParams();
params->ApproximationMethod = 2;
params->Mask = j;
cubic->Approximate(params);
// Print statistics
instanceMutex.lock();
cubic->printStatistics();
instanceMutex.unlock();
});
}
else {
for (char j = 1; j < 254; j++) {
TApproximationParams* params = new TApproximationParams();
params->ApproximationMethod = 2;
params->Mask = j;
cubic->Approximate(params);
cubic->printStatistics();
}
}
}
// close connection to database
database.close();
}
Для Intel TBB-класса CubicSplineApprox:
#include "CubicSplineApprox.h"
/*
* Constructor derived class from base class CommonApprox
*/
CubicSplineApprox::CubicSplineApprox(IGlucoseLevels *levels):CCommonApprox(levels){
}
/*
* Destructor
*/
CubicSplineApprox::~CubicSplineApprox()
{
}
/*
* Instance derived classes IApproximatedGlucoseLevels, calling method Approximate
*/
HRESULT IfaceCalling CubicSplineApprox::Approximate(TApproximationParams *params) {
segmentId = params->segmentId;
subjectId = params->subjectId;
lastUsedMask = params->Mask;
size_t count = 0;
TGlucoseLevel* levels;
CCommonApprox::mEnumeratedLevels->GetLevelsCount(&count);
CCommonApprox::mEnumeratedLevels->GetLevels(&levels);
std::vector<double> xVector;
std::vector<double> yVector;
std::vector<double> nonXVector;
std::vector<double> nonYVector;
/*
* Creating vectors datetime and measured values by mask for calculation
* @param x vector of interpolated parameters datetime values by mask
* @param y vector of interpolated parameters measured values ist by mask
*/
for (size_t i = 0; i < count; i++){
if (isInterpolated(i, params->Mask)){
xVector.push_back(levels[i].datetime);
yVector.push_back(levels[i].level);
}
else {
nonXVector.push_back(levels[i].datetime);
nonYVector.push_back(levels[i].level);
}
}
// Initialize spline - interpolation
spline.set_points(xVector, yVector, true);
// Included measurements are part of the spline function
// Absolute errors
absoluteIncluded.AverageError = 0;
absoluteIncluded.MaximalError = 0;
absoluteIncluded.MinimalError = 0;
absoluteIncluded.StandardDeviation = 0;
absoluteIncluded.Median = 0;
absoluteIncluded.FirstQuartil = 0;
absoluteIncluded.ThirdQuartil = 0;
// Relative errors
relativeIncluded.AverageError = 0;
relativeIncluded.MaximalError = 0;
relativeIncluded.MinimalError = 0;
relativeIncluded.StandardDeviation = 0;
relativeIncluded.Median = 0;
relativeIncluded.FirstQuartil = 0;
relativeIncluded.ThirdQuartil = 0;
// All measurement will have minimal error 0, because at leas one point is in the interpolation method
absolute.MinimalError = 0;
relative.MinimalError = 0;
// Definitions limit parameters for statistics and vector statistic errors
absoluteExcluded.MinimalError = 100000000; //todo - find some const
absoluteExcluded.MaximalError = 0;
relativeExcluded.MinimalError = 100000000; //todo - find some const
relativeExcluded.MaximalError = 0;
absolute.MaximalError = 0;
relative.MaximalError = 0;
std::vector<double> absoluteErr;
std::vector<double> relativeErr;
double absoluteSum = 0;
double absoluteQuadSum = 0;
double relativeSum = 0;
double relativeQuadSum = 0;
/*
* Calculate statistics interpolated values, absolute error and relative error
* @param ∆x = x0 - x, absolute error is difference between absolute value and interpolated value
* @param δr = ∆X / Xo, relative error is quotient between absolute error and value of thing measured
*
*/
for (size_t i = 0; i < nonXVector.size(); i++){
double interVal = spline(nonXVector[i]);
double measVal = nonYVector[i];
double absErr = std::abs(nonYVector[i] - interVal);
double relErr = measVal == 0 ? 0 : std::abs(absErr / measVal);
absoluteErr.push_back(absErr);
absoluteSum += absErr;
absoluteQuadSum += absErr * absErr;
relativeErr.push_back(relErr);
relativeSum += relErr;
relativeQuadSum += relErr * relErr;
if (absoluteExcluded.MinimalError > absErr)
absoluteExcluded.MinimalError = absErr;
if (absoluteExcluded.MaximalError < absErr)
absoluteExcluded.MaximalError = absErr;
if (absolute.MaximalError < absErr)
absolute.MaximalError = absErr;
if (relativeExcluded.MinimalError > relErr && measVal != 0)
relativeExcluded.MinimalError = relErr;
if (relativeExcluded.MaximalError < relErr)
relativeExcluded.MaximalError = relErr;
if (relative.MaximalError < relErr)
relative.MaximalError = relErr;
}
// Calculate average errors
absoluteExcluded.AverageError = absoluteSum / absoluteErr.size();
absolute.AverageError = absoluteSum / (xVector.size() + nonXVector.size());
relativeExcluded.AverageError = relativeSum / relativeErr.size();
relative.AverageError = relativeSum / (xVector.size() + nonXVector.size());
// Calculate standard deviation errors
absoluteExcluded.StandardDeviation = (absoluteQuadSum - 2 * absoluteExcluded.AverageError * absoluteSum) / absoluteErr.size() + absoluteExcluded.AverageError * absoluteExcluded.AverageError;
relativeExcluded.StandardDeviation = (relativeQuadSum - 2 * relativeExcluded.AverageError * relativeSum) / relativeErr.size() + relativeExcluded.AverageError * relativeExcluded.AverageError;
absolute.StandardDeviation = (absoluteQuadSum - 2 * absolute.AverageError * absoluteSum) / (xVector.size() + nonXVector.size()) + absolute.AverageError * absolute.AverageError;
relative.StandardDeviation = (relativeQuadSum - 2 * relative.AverageError * relativeSum) / (xVector.size() + nonXVector.size()) + relative.AverageError * relative.AverageError;
// Calculate median, first quartile and third quartile
std::sort(absoluteErr.begin(), absoluteErr.end());
std::sort(relativeErr.begin(), relativeErr.end());
int calcFromTwo = absoluteErr.size() % 2;
int indexOfMedian = absoluteErr.size() / 2;
int indexFirstQuartil = indexOfMedian / 2;
int indexOfThirdQuartil = indexOfMedian + indexFirstQuartil;
absoluteExcluded.Median = calcFromTwo > 0 ? (absoluteErr[indexOfMedian] + absoluteErr[indexOfMedian + 1]) / 2 : absoluteErr[indexOfMedian];
absoluteExcluded.FirstQuartil = absoluteErr[indexFirstQuartil]; // it is not clear what to do if median are two numbers!
absoluteExcluded.ThirdQuartil = absoluteErr[indexOfThirdQuartil]; // it is not clear what to do if median are two numbers!
relativeExcluded.Median = calcFromTwo > 0 ? (relativeErr[indexOfMedian] + relativeErr[indexOfMedian + 1]) / 2 : relativeErr[indexOfMedian];
relativeExcluded.FirstQuartil = relativeErr[indexFirstQuartil]; // it is not clear what to do if median are two numbers!
relativeExcluded.ThirdQuartil = relativeErr[indexOfThirdQuartil]; // it is not clear what to do if median are two numbers!
// Calculate median for all data
calcFromTwo = (xVector.size() + nonXVector.size()) % 2;
indexOfMedian = (xVector.size() + nonXVector.size()) / 2;
indexFirstQuartil = indexOfMedian / 2;
indexOfThirdQuartil = indexOfMedian + indexFirstQuartil;
absolute.Median = indexOfMedian < xVector.size() ? 0 : calcFromTwo > 0 ? (absoluteErr[indexOfMedian - xVector.size()] + absoluteErr[indexOfMedian - xVector.size() + 1]) / 2 : absoluteErr[indexOfMedian - xVector.size()];
absolute.FirstQuartil = indexFirstQuartil < xVector.size()? 0: absoluteErr[indexFirstQuartil - xVector.size()];
absolute.ThirdQuartil = indexOfThirdQuartil < xVector.size() ? 0 : absoluteErr[indexOfThirdQuartil - xVector.size()];
relative.Median = indexOfMedian < xVector.size() ? 0 : calcFromTwo > 0 ? (relativeErr[indexOfMedian - xVector.size()] + relativeErr[indexOfMedian - xVector.size() + 1]) / 2 : relativeErr[indexOfMedian - xVector.size()];
relative.FirstQuartil = indexFirstQuartil < xVector.size() ? 0 : relativeErr[indexFirstQuartil - xVector.size()];
relative.ThirdQuartil = indexOfThirdQuartil < xVector.size() ? 0 : relativeErr[indexOfThirdQuartil - xVector.size()];
return S_OK;
}
/*
* Method print statistics data
*/
void CubicSplineApprox::printStatistics(){
std::cout << subjectId << ";" << segmentId << ";" << lastUsedMask << ";" <<\
absolute.MinimalError << ";" << absolute.AverageError << ";" << absolute.MaximalError << ";" << absolute.Median << ";" << absolute.FirstQuartil << ";" << absolute.ThirdQuartil << ";" << absolute.StandardDeviation << \
absoluteIncluded.MinimalError << ";" << absoluteIncluded.Ave