Last active
August 29, 2015 14:27
-
-
Save ubnt-intrepid/fc158d1b1a6045ad7b1b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include "time_series.hpp" | |
template <typename T = double, typename Duration = std::chrono::seconds> | |
my::time_series<T, Duration> load_series(std::string const& file_path) | |
{ | |
// load datasets. | |
std::vector<T> data; | |
std::ostream ifs(file_path, std::ios::in); | |
for (std::string line; ifs && std::getline(ifs, line);) | |
{ | |
data.push_back(boost::lexical_cast<T>(line)); | |
} | |
return my::time_series<T, Duration>(std::move(data)); | |
} | |
int main(int argc, char const* argv[]) | |
{ | |
using namespace std; | |
using namespace std::chrono; | |
auto series1 = load_series<double, seconds>("hogehoge_sec.csv"); | |
// => time_series<double, seconds> | |
// upsampling | |
auto series2 = series1.resample<milliseconds>(); | |
auto series2 = series1.resample<milliseconds>(my::upsampling_mode::FILTERED); | |
auto series2 = series1.resample<milliseconds>(my::upsampling_mode::HOLDED); | |
// => time_series<double, chrono::milliseconds> | |
// downsampling | |
auto series3 = series1.resample<minutes>(); | |
auto series3 = series1.resample<minutes>(my::downsampling_mode::FILTERED); | |
auto series3 = series1.resample<minutes>(my::downsampling_mode::AVERAGE); | |
// => time_series<double, chrono::minutes> | |
// remove duration informations. | |
vector<double> values3 = series3.values(); | |
vector<double> hogehoge_min | |
= load_series("hogehoge_sec.csv") | |
.resample<minutes>(my::downsampling_mode::AVERAGE) | |
.values(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <chrono> | |
#include <vector> | |
#include <ratio> | |
#include <type_traits> | |
namespace my { | |
enum class downsampling_mode { | |
DEFAULT, // 間引きのみ(フィルタをかけない) | |
FILTERED, // 変換前にデシメーションフィルタに通す | |
AVERAGE, // 直前のサンプリングまでのデータの移動平均を取る | |
}; | |
enum class upsampling_mode { | |
DEFAULT, // 周期の変更のみ(補完なし) | |
FILTERED, // 変換後にインターポレーションフィルタに通す | |
HOLDED, // 0次ホールド | |
}; | |
namespace detail { | |
template <class D1, class D2> | |
struct is_downsampling { | |
using ratio_t = std::ratio_divide<typename D1::period, typename D2::period>; | |
static constexpr value = ratio_t::num < ratio_t::den; | |
}; | |
template <typename T, typename Ratio> | |
std::vector<T> upsample_default(std::vector<T> const& src) | |
{ | |
constexpr uintmax_t span = Ratio::num; // 整数倍のみ | |
std::vector<T> dest; | |
dest.reserve(src.size() * span); | |
for (auto const& item : src) { | |
dest.push_back(item); | |
dest.resize(dest.size() + span - 1, T(0)); | |
} | |
return dest; | |
} | |
template <typename T, typename Ratio> | |
std::vector<T> upsample_filtered(std::vector<T> const& src) | |
{ | |
/* ... */ | |
} | |
template <typename T> | |
std::vector<T> upsample_holded(std::vector<T> const& src) | |
{ | |
constexpr uintmax_t span = Ratio::num; // 整数倍のみ | |
std::vector<T> dest; | |
dest.reserve(src.size() * span); | |
for (auto const& item : src) { | |
dest.resize(dest.size() + span, item); | |
} | |
return dest; | |
} | |
template <class D1, class D2> | |
struct upsampling | |
{ | |
using ratio_t = std::ratio_divide<typename D1::period, typename D2::period>; | |
template <typename T> | |
static std::vector<T> apply(std::vector<T> const& src, upsampling_mode mode) | |
{ | |
switch (mode) { | |
case upsampling_mode::DEFAULT: return upsample_default<ratio_t>(src); | |
case upsampling_mode::FILTERED: return upsample_filtered<ratio_t>(src); | |
case upsampling_mode::HOLDED: return upsample_holded<ratio_t>(src); | |
} | |
} | |
}; | |
template <class D> | |
struct upsampling<D, D> | |
{ | |
template <typename T> | |
inline static std::vector<T> apply(std::vector<T> const& src, upsampling_mode) { | |
return src; // do nothing. | |
} | |
}; | |
template <class D1, class D2> | |
struct downsampling | |
{ | |
using ratio_t = std::ratio_divide<typename D1::period, typename D2::period>; | |
template <typename T> | |
static std::vector<T> apply(std::vector<T> const& src, downsampling_mode mode) | |
{ | |
switch (mode) { | |
case upsampling_mode::DEFAULT: { | |
// hogehoge. | |
return ...; | |
} | |
case upsampling_mode::FILTERED: { | |
// hogehoge. | |
return ... | |
} | |
case upsampling_mode::AVERAGE: { | |
// hogehoge. | |
return ... | |
} | |
} | |
} | |
}; | |
} // namespace detail; | |
template <class D1, class D2> | |
using is_downsampling = std::integral_constant<bool, detail::is_downsampling<D1, D2>::value>; | |
template <typename T, class D1, class D2> | |
std::vector<T> upsample(std::vector<T> const& src, upsampling_mode mode) { | |
return detail::upsampling<D1, D2>::apply(src, mode); | |
} | |
template <typename T, class D1, class D2> | |
std::vector<T> downsample(std::vector<T> const& src, downsampling_mode mode) { | |
return detail::downsampling<D1, D2>::apply(src, mode); | |
} | |
template <typename T, | |
typename Duration = std::chrono::seconds> | |
class time_series | |
{ | |
std::vector<T> body_; | |
public: | |
using value_type = T; | |
using duration_type = Duration; | |
public: | |
time_series() = delete; | |
time_series(time_series const&) = default; | |
time_series(time_series &&) = default; | |
time_series& operator=(time_series const&) = default; | |
time_series& operator=(time_series &&) = default; | |
time_series(std::vector<T> const& src) | |
: body_(src) | |
{ | |
} | |
time_series(std::vector<T> && src) | |
: body_(std::move(src)) | |
{ | |
} | |
template <typename SrcDuration> | |
time_series(time_series<T, SrcDuration> const& other, downsampling_mode mode) | |
: body_(other.resample<Duration>(mode).values()) | |
{ | |
} | |
template <typename SrcDuration> | |
time_series(time_series<T, SrcDuration> const& other, upsampling_mode mode) | |
: body_(other.resample<Duration>(mode).values()) | |
{ | |
} | |
public: | |
inline std::vector<T> const& values() const noexcept { return body_; } | |
inline std::size_t size() const noexcept { return body_.size(); } | |
public: | |
template <typename ToDuration> | |
time_series<T, ToDuration> resample(downsampling_mode mode) const | |
{ | |
static_assert(is_downsampling<Duration, ToDuration>::value, "cannot upsample"); | |
std::vector<T> downsampled = downsample<Duration, ToDuration>(body_, mode); | |
return time_series<T, ToDuration>(std::move(downsampled)); | |
} | |
template <typename ToDuration> | |
time_series<T, ToDuration> resample(upsampling_mode mode) const | |
{ | |
static_assert(!is_downsampling<Duration, ToDuration>::value, "cannot downsample"); | |
std::vector<T> upsampled = upsample<Duration, ToDuration>(body_, mode); | |
return time_series<T, ToDuration>(std::move(upsampled)); | |
} | |
}; | |
} // namespace my; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment