| Signature | Description | Parameters |
|---|---|---|
#include <DataFrame/DataFrameTransformVisitors.h> template<typename T, typename I = unsigned long> struct ExpoSmootherVisitor; // ------------------------------------- template<typename T, typename I = unsigned long> using exs_v = ExpoSmootherVisitor<T, I>; |
This is a "single action visitor", meaning it is passed the whole data vector in one call and you must use the single_act_visit() interface. This is a transformer visitor. It means the column(s) passed to this visitor is not read-only and its values may change This functor does exponential smoothing of the time-series by Y0 = X0 Yt = aXt + (1 - a)Yt-1 This works with both scalar and multidimensional (i.e. vectors and arrays) datasets.
explicit
ExpoSmootherVisitor(value_type alfa,
// You can do multiple smoothing in one call
std::size_t repeat_count = 1);
alfa is the smoothing factor, and 0 < alfa < 1. Factor of 1 will not change the data. In case of multidimensional input, alfa is a vector of the same size as the dimension.
|
T: Column data type. I: Index type. |
#include <DataFrame/DataFrameTransformVisitors.h> template<typename T, typename I = unsigned long> struct HWExpoSmootherVisitor; // ------------------------------------- template<typename T, typename I = unsigned long> using hwexp_v = HWExpoSmootherVisitor<T, I>; |
This is a "single action visitor", meaning it is passed the whole data vector in one call and you must use the single_act_visit() interface. This is a transformer visitor. It means the column(s) passed to this visitor is not read-only and its values may change This functor does double exponential smoothing by Holt-Winters method. The advantage for this over the above visitor is that HW takes care of trends in the data Y0 = X0 B0 = X1 - X0 And for t > 0: Yt = aXt + (1 - a) (Yt-1 + Bt-1) Bt = b(Yt - Yt-1) + (1 - b)Bt-1 This works with both scalar and multidimensional (i.e. vectors and arrays) datasets.
HWExpoSmootherVisitor(value_type alfa, value_type beta);
alfa is the data smoothing factor, 0 < a < 1, and beta is the trend smoothing factor, 0 < b < 1. In case of multidimensional input, alfa/beta are vectors of the same size as the dimension.
|
T: Column data type. I: Index type. |
static void test_ExpoSmootherVisitor() { std::cout << "\nTesting ExpoSmootherVisitor{ } ..." << std::endl; StlVecType<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466, 123467, 123468, 123469, 123470, 123471, 123472, 123473, 123467, 123468, 123469, 123470, 123471, 123472, 123473, 123467, 123468, 123469, 123470, 123471, 123472, 123473, }; StlVecType<double> d1 = { 2.5, 2.45, -1.65, -0.1, -1.1, 1.87, 0.98, 0.34, 1.56, -12.34, 2.3, -0.34, -1.9, 0.387, 0.123, 1.06, -0.65, 2.03, 0.4, -1.0, 0.59, 0.125, 1.9, -0.68, 2.0045, 50.8, -1.0, 0.78, 0.48, 1.99, -0.97, 1.03, 8.678, -1.4, 1.59, }; StlVecType<double> d1_copy = d1; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("dbl_col", d1)); MyDataFrame df2 = df; ExpoSmootherVisitor<double> es_v1(1); df.single_act_visit<double>("dbl_col", es_v1); const auto &col1 = df.get_column<double>("dbl_col"); auto actual = StlVecType<double> { 2.5, 2.5, 2.45, -1.65, -0.1, -1.1, 1.87, 0.98, 0.34, 1.56, -12.34, 2.3, -0.34, -1.9, 0.387, 0.123, 1.06, -0.65, 2.03, 0.4, -1, 0.59, 0.125, 1.9, -0.68, 2.0045, 50.8, -1, 0.78, 0.48, 1.99, -0.97, 1.03, 8.678, -1.4 }; for (size_t i = 0; i < col1.size(); ++i) assert((fabs(col1[i] - d1_copy[i]) < 0.00001) || (fabs(col1[i] - actual[i]) < 0.0001)); ExpoSmootherVisitor<double> es_v2(0.3); df.single_act_visit<double>("dbl_col", es_v2); auto actual2 = StlVecType<double> { 2.5, 2.485, 1.2445, 0.84115, 0.258805, 0.742163, 0.813514, 0.67146, 0.938022, -3.04538, -1.44177, -1.11124, -1.34787, -0.827407, -0.542285, -0.0615993, -0.23812, 0.442316, 0.429621, 0.000734997, 0.177514, 0.16176, 0.683232, 0.274262, 0.793334, 15.7953, 10.7567, 7.76371, 5.5786, 4.50202, 2.86041, 2.31129, 4.2213, 2.53491, 2.25144 }; for (size_t i = 0; i < col1.size(); ++i) assert((std::fabs(col1[i] - actual2[i]) < 0.0001)); df.get_column<double>("dbl_col") = d1_copy; ExpoSmootherVisitor<double> es_v3(0.8); df.single_act_visit<double>("dbl_col", es_v3); auto actual3 = StlVecType<double> { 2.5, 2.46, -0.828, -0.2456, -0.92912, 1.31018, 1.04604, 0.481207, 1.34424, -9.60315, -0.0806303, -0.288126, -1.57763, -0.00592504, 0.097215, 0.867443, -0.346511, 1.5547, 0.63094, -0.673812, 0.337238, 0.167448, 1.55349, -0.233302, 1.55694, 40.9514, 7.39028, 2.10206, 0.804411, 1.75288, -0.425424, 0.738915, 7.09018, 0.298037, 1.33161 }; for (size_t i = 0; i < col1.size(); ++i) assert((std::fabs(col1[i] - actual3[i]) < 0.0001)); ExpoSmootherVisitor<double> es_v3_4 (0.8, 4); const auto &col21 = df2.get_column<double>("dbl_col"); df2.single_act_visit<double>("dbl_col", es_v3_4); auto actual4 = StlVecType<double> { 2.5, 2.47952, 0.783776, 0.066976, -0.509741, 0.363199, 0.815194, 0.687833, 1.00603, -4.38921, -2.79003, -1.28679, -1.28013, -0.639015, -0.190314, 0.396383, 0.0781416, 0.793802, 0.793116, 0.0362468, 0.10559, 0.151083, 0.873655, 0.387457, 0.925997, 21.4832, 16.5657, 8.44511, 3.6629, 2.21433, 0.738794, 0.585184, 3.91034, 2.43449, 1.67792 }; for (size_t i = 0; i < col21.size(); ++i) assert((std::fabs(col21[i] - actual4[i]) < 0.0001)); // Now multidimensional data // constexpr std::size_t dim { 3 }; using ary_col_t = std::array<double, dim>; using vec_col_t = std::vector<double>; StlVecType<ary_col_t> ary_col { { 2.5, 2.45, -1.65 }, { -0.1, -1.1, 1.87 }, { 0.98, 0.34, 1.56 }, { -12.34, 2.3, -0.34 }, { -1.9, 0.387, 0.123 }, { 1.06, -0.65, 2.03 }, { 0.4, -1.0, 0.59 }, { 0.125, 1.9, -0.68 }, { 2.0045, 50.8, -1.0 }, { 0.78, 0.48, 1.99 }, { -0.97, 1.03, 8.678 }, { -1.4, 1.59, 0.7 } }; StlVecType<vec_col_t> vec_col { { 2.5, 2.45, -1.65 }, { -0.1, -1.1, 1.87 }, { 0.98, 0.34, 1.56 }, { -12.34, 2.3, -0.34 }, { -1.9, 0.387, 0.123 }, { 1.06, -0.65, 2.03 }, { 0.4, -1.0, 0.59 }, { 0.125, 1.9, -0.68 }, { 2.0045, 50.8, -1.0 }, { 0.78, 0.48, 1.99 }, { -0.97, 1.03, 8.678 }, { -1.4, 1.59, 0.7 } }; df2.load_column<ary_col_t>("ARY COL", std::move(ary_col), nan_policy::dont_pad_with_nans); df2.load_column<vec_col_t>("VEC COL", std::move(vec_col), nan_policy::dont_pad_with_nans); const ary_col_t ary_alfa = { 0.8, 0.8, 0.8 }; ExpoSmootherVisitor<ary_col_t> ary_es (ary_alfa, 4); const vec_col_t vec_alfa = { 0.8, 0.8, 0.8 }; ExpoSmootherVisitor<vec_col_t> vec_es (vec_alfa, 4); df2.single_act_visit<ary_col_t>("ARY COL", ary_es); df2.single_act_visit<vec_col_t>("VEC COL", vec_es); const auto &ary_col_ref { df2.get_column<ary_col_t>("ARY COL") }; const auto &vec_col_ref { df2.get_column<vec_col_t>("VEC COL") }; assert(ary_es.get_result() == 12); assert(vec_es.get_result() == 12); assert(std::abs(ary_col_ref[0][0] - 2.5) < 0.00001); assert(std::abs(ary_col_ref[0][2] - -1.65) < 0.00001); assert(std::abs(ary_col_ref[3][0] - -4.50252) < 0.00001); assert(std::abs(ary_col_ref[3][1] - 1.11552) < 0.00001); assert(std::abs(ary_col_ref[8][1] - 21.2502) < 0.0001); assert(std::abs(ary_col_ref[8][2] - -0.398169) < 0.000001); assert(std::abs(ary_col_ref[11][0] - -0.627266) < 0.000001); assert(std::abs(ary_col_ref[11][2] - 3.38414) < 0.00001); assert(std::abs(vec_col_ref[0][0] - 2.5) < 0.00001); assert(std::abs(vec_col_ref[0][2] - -1.65) < 0.00001); assert(std::abs(vec_col_ref[3][0] - -4.50252) < 0.00001); assert(std::abs(vec_col_ref[3][1] - 1.11552) < 0.00001); assert(std::abs(vec_col_ref[8][1] - 21.2502) < 0.0001); assert(std::abs(vec_col_ref[8][2] - -0.398169) < 0.000001); assert(std::abs(vec_col_ref[11][0] - -0.627266) < 0.000001); assert(std::abs(vec_col_ref[11][2] - 3.38414) < 0.00001); } // ----------------------------------------------------------------------------- static void test_HWExpoSmootherVisitor() { std::cout << "\nTesting HWExpoSmootherVisitor{ } ..." << std::endl; StlVecType<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466, 123467, 123468, 123469, 123470, 123471, 123472, 123473, 123467, 123468, 123469, 123470, 123471, 123472, 123473, 123467, 123468, 123469, 123470, 123471, 123472, 123473, }; StlVecType<double> d1 = { 2.5, 2.45, -1.65, -0.1, -1.1, 1.87, 0.98, 0.34, 1.56, -12.34, 2.3, -0.34, -1.9, 0.387, 0.123, 1.06, -0.65, 2.03, 0.4, -1.0, 0.59, 0.125, 1.9, -0.68, 2.0045, 50.8, -1.0, 0.78, 0.48, 1.99, -0.97, 1.03, 8.678, -1.4, 1.59, }; StlVecType<double> d1_copy = d1; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("dbl_col", d1)); HWExpoSmootherVisitor<double> es_v1(1, 1); df.single_act_visit<double>("dbl_col", es_v1); const auto &col1 = df.get_column<double>("dbl_col"); for (size_t i = 0; i < col1.size(); ++i) assert(fabs(col1[i] - d1_copy[i]) < 0.00001); HWExpoSmootherVisitor<double> es_v2(0.3, 0.4); df.single_act_visit<double>("dbl_col", es_v2); auto actual2 = StlVecType<double> { 2.5, 2.45, 1.185, 0.4243, -0.471106, -0.282357, -0.158951, -0.127892, 0.315996, -3.394, -2.67252, -2.36278, -2.37123, -1.6345, -0.955403, -0.0695294, 0.173125, 1.04821, 1.28958, 0.931793, 0.926526, 0.742956, 1.0728, 0.628958, 0.966542, 15.9661, 15.1058, 13.1049, 10.1353, 7.35094, 3.87058, 1.45345, 2.00505, 0.168523, -0.408269 }; for (size_t i = 0; i < col1.size(); ++i) assert(fabs(col1[i] - actual2[i]) < 0.0001); df.get_column<double>("dbl_col") = d1_copy; HWExpoSmootherVisitor<double> es_v3(0.8, 0.8); df.single_act_visit<double>("dbl_col", es_v3); auto actual3 = StlVecType<double> { 2.5, 2.45, -0.84, -0.7764, -1.13078, 1.19404, 1.37962, 0.648979, 1.2811, -9.53398, -1.78085, 0.26952, -0.958499, 0.0229365, 0.241024, 0.958706, -0.200929, 1.42374, 0.832679, -0.682447, 0.0832937, 0.188734, 1.58903, 0.00411128, 1.3969, 41.1007, 13.809, 0.296909, -2.33634, 0.14747, -0.54455, 0.644758, 7.24757, 1.42121, 0.842363 }; for (size_t i = 0; i < col1.size(); ++i) assert(fabs(col1[i] - actual3[i]) < 0.0001); // Now multidimensional data // constexpr std::size_t dim { 3 }; using ary_col_t = std::array<double, dim>; using vec_col_t = std::vector<double>; StlVecType<ary_col_t> ary_col { { 2.5, 2.45, -1.65 }, { -0.1, -1.1, 1.87 }, { 0.98, 0.34, 1.56 }, { -12.34, 2.3, -0.34 }, { -1.9, 0.387, 0.123 }, { 1.06, -0.65, 2.03 }, { 0.4, -1.0, 0.59 }, { 0.125, 1.9, -0.68 }, { 2.0045, 50.8, -1.0 }, { 0.78, 0.48, 1.99 }, { -0.97, 1.03, 8.678 }, { -1.4, 1.59, 0.7 } }; StlVecType<vec_col_t> vec_col { { 2.5, 2.45, -1.65 }, { -0.1, -1.1, 1.87 }, { 0.98, 0.34, 1.56 }, { -12.34, 2.3, -0.34 }, { -1.9, 0.387, 0.123 }, { 1.06, -0.65, 2.03 }, { 0.4, -1.0, 0.59 }, { 0.125, 1.9, -0.68 }, { 2.0045, 50.8, -1.0 }, { 0.78, 0.48, 1.99 }, { -0.97, 1.03, 8.678 }, { -1.4, 1.59, 0.7 } }; df.load_column<ary_col_t>("ARY COL", std::move(ary_col), nan_policy::dont_pad_with_nans); df.load_column<vec_col_t>("VEC COL", std::move(vec_col), nan_policy::dont_pad_with_nans); const ary_col_t ary_alfa = { 0.8, 0.8, 0.8 }; const ary_col_t ary_beta = { 0.8, 0.8, 0.8 }; HWExpoSmootherVisitor<ary_col_t> ary_es (ary_alfa, ary_beta); const vec_col_t vec_alfa = { 0.8, 0.8, 0.8 }; const vec_col_t vec_beta = { 0.8, 0.8, 0.8 }; HWExpoSmootherVisitor<vec_col_t> vec_es (vec_alfa, vec_beta); df.single_act_visit<ary_col_t>("ARY COL", ary_es); df.single_act_visit<vec_col_t>("VEC COL", vec_es); assert(ary_es.get_result() == 12); assert(vec_es.get_result() == 12); const auto &ary_col_ref { df.get_column<ary_col_t>("ARY COL") }; const auto &vec_col_ref { df.get_column<vec_col_t>("VEC COL") }; assert(std::abs(ary_col_ref[0][0] - 2.5) < 0.00001); assert(std::abs(ary_col_ref[0][2] - -1.65) < 0.00001); assert(std::abs(ary_col_ref[3][0] - -9.87216) < 0.00001); assert(std::abs(ary_col_ref[3][1] - 1.63712) < 0.00001); assert(std::abs(ary_col_ref[8][1] - 41.1924) < 0.0001); assert(std::abs(ary_col_ref[8][2] - -1.10146) < 0.00001); assert(std::abs(ary_col_ref[11][0] - -1.53468) < 0.00001); assert(std::abs(ary_col_ref[11][2] - 3.14189) < 0.00001); assert(std::abs(vec_col_ref[0][0] - 2.5) < 0.00001); assert(std::abs(vec_col_ref[0][2] - -1.65) < 0.00001); assert(std::abs(vec_col_ref[3][0] - -9.87216) < 0.00001); assert(std::abs(vec_col_ref[3][1] - 1.63712) < 0.00001); assert(std::abs(vec_col_ref[8][1] - 41.1924) < 0.0001); assert(std::abs(vec_col_ref[8][2] - -1.10146) < 0.00001); assert(std::abs(vec_col_ref[11][0] - -1.53468) < 0.00001); assert(std::abs(vec_col_ref[11][2] - 3.14189) < 0.00001); }