#include "stdafx.h" #include "Transformation.h" #include "Median.h" #include #include #include #include Transformation::Transformation(vector ts) { setTimeSeries(ts); INFINITY = std::numeric_limits::infinity(); } Transformation::~Transformation() { } void Transformation::setTimeSeries(vector ts){ TimeSeries = ts; tsSizeValue = ts.size(); tsShiftValue = 0; GeometricAverage = 1; valueMean = 0; double min = 0; for (int i = 0; i < tsSizeValue; i++) { if ((TimeSeries[i] < 0) && (TimeSeries[i] < min)) { min = TimeSeries[i]; } GeometricAverage = GeometricAverage * TimeSeries[i]; valueMean += TimeSeries[i]; } if (min != 0) { tsShiftValue = abs(min) + 1; } if (tsSizeValue != 0) { GeometricAverage = pow(GeometricAverage, 1 / tsSizeValue); valueMean /= tsSizeValue; } } int Transformation::sign(double value) { if (value >= 0) return 1; else return -1; } double Transformation::lambdaEstimationGuerrero(double param){ double result; int begin; // iterator int end; // iterator double sumRow; // sum row matrix double sumSd; // sum for estimation standard deviation double meanRat; int lengthPeriod = 2; if (seasonalPeriod > lengthPeriod) { lengthPeriod = seasonalPeriod; } int amtlengthPeriod = floor((double)tsSizeValue / lengthPeriod); int shift = tsSizeValue - floor((double)amtlengthPeriod * lengthPeriod); vector mean(amtlengthPeriod); // mean row matrix vector sd(amtlengthPeriod); // standard deviation vector rat(amtlengthPeriod); for (int i = 0; i < amtlengthPeriod; i++) { begin = shift + i * lengthPeriod; end = begin + lengthPeriod; sumRow = 0; for (int row = begin; row < end; row++) { sumRow += TimeSeries[row]; } mean[i] = sumRow / lengthPeriod; sumSd = 0; for (int row = begin; row < end; row++) { sumSd += pow(TimeSeries[row] - mean[i], 2); } sd[i] = sqrt(sumSd / (lengthPeriod - 1)); } for (int i = 0; i < amtlengthPeriod; i++) { rat[i] = sd[i] / (pow(mean[i], 1 - param)); } meanRat = 0; for (int i = 0; i < amtlengthPeriod; i++) { meanRat += rat[i]; } meanRat /= amtlengthPeriod; sumSd = 0; for (int i = 0; i < amtlengthPeriod; i++) { sumSd += pow(rat[i] - meanRat, 2); } result = sqrt(sumSd / (amtlengthPeriod - 1)) / meanRat; return result; } void Transformation::lambdaEstimation(){ double cv = INFINITY; //cv - coefficient of variation for (double i = -1; i <= 2; i += 0.01) { //double i = 0.7; double result = lambdaEstimationGuerrero(i); if (result < cv) { cv = result; lambda = i; } } } vector Transformation::BoxCox(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = log(TimeSeries[i] + tsShiftValue); } } else { for (int i = 0; i < TimeSeries.size(); i++) { tsTransformation[i] = (pow(TimeSeries[i] + tsShiftValue, lambda) - 1) / lambda; } } return tsTransformation; } vector Transformation::invBoxCox(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = exp(TimeSeries[i]) - tsShiftValue; } } else { for (int i = 0; i < TimeSeries.size(); i++) { tsTransformation[i] = pow((lambda * TimeSeries[i] + 1), 1 / lambda) - tsShiftValue; } } return tsTransformation; } vector Transformation::ExponentialTransformation(){ vector tsTransformation(tsSizeValue); if (lambda != 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = (exp(TimeSeries[i] * lambda) - 1) / lambda; } } return tsTransformation; } vector Transformation::invExponentialTransformation(){ vector tsTransformation(tsSizeValue); if (lambda != 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = log(1 + TimeSeries[i] * lambda) / lambda; } } return tsTransformation; } vector Transformation::ModulusTransformation(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = sign(TimeSeries[i]) * log(abs(TimeSeries[i]) + 1); } } else { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = sign(TimeSeries[i]) * (pow(abs(TimeSeries[i]) + 1, lambda) - 1) / lambda; } } return tsTransformation; } vector Transformation::invModulusTransformation(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = sign(TimeSeries[i]) * (exp(abs(TimeSeries[i])) - 1); } } else { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = pow(TimeSeries[i] * lambda / sign(TimeSeries[i]) + 1, 1 / lambda) - 1; } } return tsTransformation; } vector Transformation::AsymptoticBoxCox(){ vector tsTransformation(tsSizeValue); if (lambda > 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = (sign(TimeSeries[i]) * pow(abs(TimeSeries[i]), lambda) - 1) / lambda; } } return tsTransformation; } vector Transformation::invAsymptoticBoxCox(){ vector tsTransformation(tsSizeValue); if (lambda > 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = pow((TimeSeries[i] * lambda - 1) / sign(TimeSeries[i]), 1 / lambda); } } return tsTransformation; } vector Transformation::ModifiedBoxCox(){ vector tsTransformation(tsSizeValue); for (int i = 0; i < tsSizeValue; i++) { if ((TimeSeries[i] >= 0) && (lambda != 0)) { tsTransformation[i] = (pow(TimeSeries[i] + 1, lambda) - 1) / lambda; } else if ((TimeSeries[i] >= 0) && (lambda == 0)) { tsTransformation[i] = log(TimeSeries[i] + 1); } else if ((TimeSeries[i] < 0) && (lambda != 0)) { tsTransformation[i] = -(pow(-TimeSeries[i] + 1, 2 - lambda) - 1) / (2 - lambda); } else if ((TimeSeries[i] < 0) && (lambda == 0)) { tsTransformation[i] = -log(-TimeSeries[i] + 1); } } return tsTransformation; } vector Transformation::invModifiedBoxCox(){ vector tsTransformation(tsSizeValue); for (int i = 0; i < tsSizeValue; i++) { if ((TimeSeries[i] >= 0) && (lambda != 0)) { tsTransformation[i] = pow(TimeSeries[i] * lambda + 1, 1 / lambda) - 1; } else if ((TimeSeries[i] >= 0) && (lambda == 0)) { tsTransformation[i] = exp(TimeSeries[i]) - 1; } else if ((TimeSeries[i] < 0) && (lambda != 2)) { tsTransformation[i] = -(pow(-(TimeSeries[i] * (2 - lambda) - 1), 1 / (2 - lambda)) - 1); } else if ((TimeSeries[i] < 0) && (lambda == 2)) { tsTransformation[i] = -exp(-TimeSeries[i]) + 1; } } return tsTransformation; } vector Transformation::NormalizedBoxCox(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = GeometricAverage * log(TimeSeries[i]); } } else { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = (pow(TimeSeries[i], lambda) - 1) / (lambda * pow(GeometricAverage, lambda - 1)); } } return tsTransformation; } vector Transformation::invNormalizedBoxCox(){ vector tsTransformation(tsSizeValue); if (lambda == 0) { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = exp(TimeSeries[i] / GeometricAverage); } } else { for (int i = 0; i < tsSizeValue; i++) { tsTransformation[i] = pow(TimeSeries[i] * lambda * pow(GeometricAverage, lambda - 1) + 1, 1 / lambda); } } return tsTransformation; } vector Transformation::Deseasonalization(int seasonalPeriod){ vector tsDeseasonalization(tsSizeValue); SeasonalIndex.resize(seasonalPeriod - 1); int tsShift = 0; int amtSeasonalPeriod = tsSizeValue / seasonalPeriod; if (tsSizeValue % seasonalPeriod != 0) { tsShift = tsSizeValue - amtSeasonalPeriod * seasonalPeriod; } // считаем средние сезоанальные индексы Median *est = new Median(); SeasonalIndex = est->getValue(TimeSeries, seasonalPeriod); // получаем итог for (int i = 0; i < amtSeasonalPeriod; i++) { int begin = tsShift + i * seasonalPeriod; int end = begin + seasonalPeriod; for (int ii = begin; ii < end; ii++) { tsDeseasonalization[ii] = TimeSeries[ii] / SeasonalIndex[i]; } } return tsDeseasonalization; } vector Transformation::invDeseasonalization(){ vector tsDeseasonalization(tsSizeValue); int tsShift = 0; int amtSeasonalPeriod = tsSizeValue / seasonalPeriod; if (tsSizeValue % seasonalPeriod != 0) { tsShift = tsSizeValue - amtSeasonalPeriod * seasonalPeriod - 1; } for (int i = 0; i < amtSeasonalPeriod; i++) { int begin = tsShift + i * seasonalPeriod; int end = begin + seasonalPeriod; for (int ii = begin; ii < end; ii++) { tsDeseasonalization[ii] = TimeSeries[ii] * SeasonalIndex[i]; } } return tsDeseasonalization; } vector Transformation::getSeasonalIndex(){ return SeasonalIndex; } vector Transformation::Aggregation(int seasonalPeriod){ int tsShift = 0; int amtSeasonalPeriod = tsSizeValue / seasonalPeriod; vector tsAggregation(amtSeasonalPeriod); if (tsSizeValue % seasonalPeriod != 0) { tsShift = tsSizeValue - amtSeasonalPeriod * seasonalPeriod; } // получаем итог for (int i = 0; i < amtSeasonalPeriod; i++) { int begin = tsShift + i * seasonalPeriod; int end = begin + seasonalPeriod; for (int ii = begin; ii < end; ii++) { tsAggregation[i] += TimeSeries[ii]; } } return tsAggregation; } vector Transformation::invAggregation(){ int sumSeasonalPeriod = tsSizeValue * seasonalPeriod; vector tsDeaggregation(sumSeasonalPeriod); // получаем итог for (int i = 0; i < tsSizeValue; i++) { int begin = i * seasonalPeriod; int end = begin + seasonalPeriod; for (int ii = begin; ii < end; ii++) { tsDeaggregation[ii] = TimeSeries[i] / seasonalPeriod; } } return tsDeaggregation; } vector Transformation::Normalization(){ vector tsNormalization(tsSizeValue); valueSd = 0; for (int i = 0; i < tsSizeValue; i++) { valueSd += pow(TimeSeries[i] - valueMean, 2); } valueSd = sqrt(valueSd / (tsSizeValue - 1)); for (int i = 0; i < tsSizeValue; i++) { tsNormalization[i] = (TimeSeries[i] - valueMean) / valueSd; } return tsNormalization; } vector Transformation::invNormalization() { vector tsNormalization(tsSizeValue); for (int i = 0; i < tsSizeValue; i++) { tsNormalization[i] = TimeSeries[i] * valueSd + valueMean; } return tsNormalization; }