TimeSeriesUtils.h
93 lines
| 3.0 KiB
| text/x-c
|
CLexer
r74 | #ifndef TIMESERIESUTILS_H | |||
#define TIMESERIESUTILS_H | ||||
r76 | #include "MultiComponentTimeSerie.h" | |||
r74 | #include "ScalarTimeSerie.h" | |||
#include "SpectrogramTimeSerie.h" | ||||
r76 | #include "VectorTimeSerie.h" | |||
r74 | ||||
r76 | #include <TimeSeries.h> | |||
r84 | #include <cmath> | |||
r76 | #include <memory> | |||
r74 | ||||
r76 | namespace TimeSeriesUtils | |||
r74 | { | |||
r76 | template<typename T> TimeSeries::ITimeSerie* copy(T input_ts) | |||
{ | ||||
if constexpr(std::is_base_of_v<TimeSeries::ITimeSerie, T>) | ||||
r74 | { | |||
r76 | if(auto ts = dynamic_cast<VectorTimeSerie*>(input_ts)) | |||
{ return new VectorTimeSerie(*ts); } | ||||
if(auto ts = dynamic_cast<ScalarTimeSerie*>(input_ts)) | ||||
{ return new ScalarTimeSerie(*ts); } | ||||
if(auto ts = dynamic_cast<MultiComponentTimeSerie*>(input_ts)) | ||||
{ return new MultiComponentTimeSerie(*ts); } | ||||
if(auto ts = dynamic_cast<SpectrogramTimeSerie*>(input_ts)) | ||||
{ return new SpectrogramTimeSerie(*ts); } | ||||
r74 | } | |||
else | ||||
{ | ||||
r76 | if(auto ts = std::dynamic_pointer_cast<VectorTimeSerie>(input_ts)) | |||
{ return new VectorTimeSerie(*ts); } | ||||
if(auto ts = std::dynamic_pointer_cast<ScalarTimeSerie>(input_ts)) | ||||
{ return new ScalarTimeSerie(*ts); } | ||||
if(auto ts = std::dynamic_pointer_cast<SpectrogramTimeSerie>(input_ts)) | ||||
{ return new SpectrogramTimeSerie(*ts); } | ||||
if(auto ts = std::dynamic_pointer_cast<MultiComponentTimeSerie>(input_ts)) | ||||
{ return new MultiComponentTimeSerie(*ts); } | ||||
r74 | } | |||
return nullptr; | ||||
r76 | } | |||
r84 | ||||
struct axis_properties | ||||
{ | ||||
double range; | ||||
double max_resolution; | ||||
bool is_log; | ||||
r85 | double min; | |||
double max; | ||||
r84 | }; | |||
constexpr auto IsLog = true; | ||||
constexpr auto IsLinear = false; | ||||
constexpr auto CheckMedian = true; | ||||
constexpr auto DontCheckMedian = false; | ||||
template<bool is_log, bool check_median> | ||||
axis_properties axis_analysis( | ||||
typename std::conditional<is_log, std::vector<double>&, | ||||
r85 | const std::vector<double>&>::type axis, | |||
double given_max_resolution = std::nan("")) | ||||
r84 | { | |||
std::vector<double> axis_diff(axis.size()); | ||||
if constexpr(is_log) | ||||
{ | ||||
std::transform(std::cbegin(axis), std::cend(axis), std::begin(axis), | ||||
[](const auto v) { return std::log10(v); }); | ||||
} | ||||
r85 | auto min = *std::begin(axis); | |||
auto max = *(std::cend(axis) - 1); | ||||
auto range = max - min; | ||||
auto min_diff = given_max_resolution; | ||||
if(std::isnan(min_diff)) | ||||
r84 | { | |||
r85 | std::adjacent_difference(std::cbegin(axis), std::cend(axis), | |||
std::begin(axis_diff)); | ||||
min_diff = | ||||
(*std::min_element(std::cbegin(axis_diff) + 1, std::cend(axis_diff))); | ||||
if constexpr(check_median) | ||||
{ | ||||
std::nth_element(std::begin(axis_diff) + 1, | ||||
std::begin(axis_diff) + axis_diff.size() / 2, | ||||
std::end(axis_diff)); | ||||
auto median_diff = *(std::begin(axis_diff) + axis_diff.size() / 2); | ||||
if(median_diff > (4 * min_diff)) min_diff = median_diff; | ||||
} | ||||
r84 | } | |||
r85 | ||||
return {range, min_diff, is_log, min, max}; | ||||
r84 | } | |||
r76 | } // namespace TimeSeriesUtils | |||
r74 | ||||
#endif | ||||