@@ -30,3 +30,4 def qdump__DateTimeRange(d , value): | |||
|
30 | 30 | d.putValue(tstop) |
|
31 | 31 | with SubItem(d, "delta"): |
|
32 | 32 | d.putValue(delta) |
|
33 |
@@ -1,1 +1,1 | |||
|
1 | Subproject commit f5f4debc597b41ab1849dfc02b6e092bf58c32d2 | |
|
1 | Subproject commit 22e3e4553178230053aac40131b4fdb36c163075 |
@@ -1,29 +1,37 | |||
|
1 | 1 | #ifndef CPP_UTILS_H |
|
2 | 2 | #define CPP_UTILS_H |
|
3 | 3 | |
|
4 | #include <functional> | |
|
5 | #include <tuple> | |
|
4 | 6 | #include <type_traits> |
|
5 | 7 | |
|
6 |
template< |
|
|
7 | using void_t = void; | |
|
8 | template<class...> using void_t = void; | |
|
8 | 9 | |
|
9 | #define HAS_METHOD(method)\ | |
|
10 | template <class T, class=void>\ | |
|
11 | struct _has_##method : std::false_type{};\ | |
|
12 | \ | |
|
13 | template <class T>\ | |
|
14 | struct _has_##method<T, void_t<std::is_member_function_pointer<decltype(&T::method)>>>\ | |
|
15 | : std::true_type{};\ | |
|
16 | \ | |
|
17 | template< class T>\ | |
|
18 | static inline constexpr bool has_##method = _has_##method<T>::value; | |
|
10 | #define HAS_METHOD(method) \ | |
|
11 | template<class T, class = void> struct _has_##method : std::false_type \ | |
|
12 | {}; \ | |
|
13 | \ | |
|
14 | template<class T> \ | |
|
15 | struct _has_##method< \ | |
|
16 | T, void_t<std::is_member_function_pointer<decltype(&T::method)>>> \ | |
|
17 | : std::true_type \ | |
|
18 | {}; \ | |
|
19 | \ | |
|
20 | template<class T> \ | |
|
21 | static inline constexpr bool has_##method = _has_##method<T>::value; | |
|
19 | 22 | |
|
20 | //taken from here https://www.fluentcpp.com/2017/10/27/function-aliases-cpp/ | |
|
21 |
#define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) |
|
|
22 |
|
|
|
23 | inline auto highLevelF(Args &&... args)->decltype(lowLevelF(std::forward<Args>(args)...)) \ | |
|
24 | { \ | |
|
25 |
|
|
|
26 | } | |
|
23 | // taken from here https://www.fluentcpp.com/2017/10/27/function-aliases-cpp/ | |
|
24 | #define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) \ | |
|
25 | template<typename... Args> \ | |
|
26 | inline auto highLevelF(Args&&... args) \ | |
|
27 | ->decltype(lowLevelF(std::forward<Args>(args)...)) \ | |
|
28 | { \ | |
|
29 | return lowLevelF(std::forward<Args>(args)...); \ | |
|
30 | } | |
|
27 | 31 | |
|
32 | template<typename T> constexpr T diff(const std::pair<T, T>& p) | |
|
33 | { | |
|
34 | return p.second - p.first; | |
|
35 | } | |
|
28 | 36 | |
|
29 | 37 | #endif // CPP_UTILS_H |
@@ -18,10 +18,10 public: | |||
|
18 | 18 | .begin()); |
|
19 | 19 | |
|
20 | 20 | SpectrogramTimeSerie() {} |
|
21 | SpectrogramTimeSerie(SpectrogramTimeSerie::axis_t& t, | |
|
22 | SpectrogramTimeSerie::axis_t& y, | |
|
21 | SpectrogramTimeSerie(SpectrogramTimeSerie::axis_t&& t, | |
|
22 | SpectrogramTimeSerie::axis_t&& y, | |
|
23 | 23 | SpectrogramTimeSerie::container_type< |
|
24 | SpectrogramTimeSerie::raw_value_type>& values, | |
|
24 | SpectrogramTimeSerie::raw_value_type>&& values, | |
|
25 | 25 | std::vector<std::size_t>& shape) |
|
26 | 26 | : TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>(t, values, shape) |
|
27 | 27 | { |
@@ -6,6 +6,7 | |||
|
6 | 6 | #include "VectorTimeSerie.h" |
|
7 | 7 | |
|
8 | 8 | #include <TimeSeries.h> |
|
9 | #include <cmath> | |
|
9 | 10 | #include <memory> |
|
10 | 11 | |
|
11 | 12 | namespace TimeSeriesUtils |
@@ -36,6 +37,47 namespace TimeSeriesUtils | |||
|
36 | 37 | } |
|
37 | 38 | return nullptr; |
|
38 | 39 | } |
|
40 | ||
|
41 | struct axis_properties | |
|
42 | { | |
|
43 | double range; | |
|
44 | double max_resolution; | |
|
45 | bool is_log; | |
|
46 | }; | |
|
47 | ||
|
48 | constexpr auto IsLog = true; | |
|
49 | constexpr auto IsLinear = false; | |
|
50 | ||
|
51 | constexpr auto CheckMedian = true; | |
|
52 | constexpr auto DontCheckMedian = false; | |
|
53 | ||
|
54 | template<bool is_log, bool check_median> | |
|
55 | axis_properties axis_analysis( | |
|
56 | typename std::conditional<is_log, std::vector<double>&, | |
|
57 | const std::vector<double>&>::type axis) | |
|
58 | { | |
|
59 | std::vector<double> axis_diff(axis.size()); | |
|
60 | if constexpr(is_log) | |
|
61 | { | |
|
62 | std::transform(std::cbegin(axis), std::cend(axis), std::begin(axis), | |
|
63 | [](const auto v) { return std::log10(v); }); | |
|
64 | } | |
|
65 | auto range = *(std::cend(axis) - 1) - *(std::begin(axis)); | |
|
66 | std::adjacent_difference(std::cbegin(axis), std::cend(axis), | |
|
67 | std::begin(axis_diff)); | |
|
68 | auto min_diff = | |
|
69 | (*std::min_element(std::cbegin(axis_diff) + 1, std::cend(axis_diff))); | |
|
70 | if constexpr(check_median) | |
|
71 | { | |
|
72 | std::nth_element(std::begin(axis_diff) + 1, | |
|
73 | std::begin(axis_diff) + axis_diff.size() / 2, | |
|
74 | std::end(axis_diff)); | |
|
75 | auto median_diff = *(std::begin(axis_diff) + axis_diff.size() / 2); | |
|
76 | if(median_diff > (4 * min_diff)) min_diff = median_diff; | |
|
77 | } | |
|
78 | return {range, min_diff, is_log}; | |
|
79 | } | |
|
80 | ||
|
39 | 81 | } // namespace TimeSeriesUtils |
|
40 | 82 | |
|
41 | 83 | #endif |
@@ -193,6 +193,16 _merge(std::vector<TimeSeries::ITimeSerie*> source, const DateTimeRange& range) | |||
|
193 | 193 | std::back_inserter(*std::dynamic_pointer_cast<T>(dest))); |
|
194 | 194 | } |
|
195 | 195 | }); |
|
196 | if(source.size()) | |
|
197 | { | |
|
198 | const auto& first = *source.begin(); | |
|
199 | for(std::size_t ax_index = 1; ax_index < first->shape().size(); ax_index++) | |
|
200 | { | |
|
201 | const auto& ax = first->axis(ax_index); | |
|
202 | std::copy(std::cbegin(ax), std::cend(ax), | |
|
203 | std::back_inserter(dest->axis(ax_index))); | |
|
204 | } | |
|
205 | } | |
|
196 | 206 | return dest; |
|
197 | 207 | } |
|
198 | 208 |
@@ -232,7 +232,10 PYBIND11_MODULE(pysciqlopcore, m) | |||
|
232 | 232 | .def(py::init<const std::vector<std::size_t>>()) |
|
233 | 233 | .def(py::init([](py::array_t<double> t, py::array_t<double> y, |
|
234 | 234 | py::array_t<double> values) { |
|
235 | assert(t.size() < values.size()); // TODO check geometry | |
|
235 | auto t_s = t.size(); | |
|
236 | auto v_s = values.size(); | |
|
237 | assert(t.size() < values.size() or | |
|
238 | t.size() == 0); // TODO check geometry | |
|
236 | 239 | assert(y.size() == values.shape(1)); |
|
237 | 240 | SpectrogramTimeSerie::axis_t _t(t.size()); |
|
238 | 241 | SpectrogramTimeSerie::axis_t _y(y.size()); |
@@ -243,7 +246,8 PYBIND11_MODULE(pysciqlopcore, m) | |||
|
243 | 246 | std::vector<std::size_t> shape; |
|
244 | 247 | shape.push_back(values.shape(0)); |
|
245 | 248 | shape.push_back(values.shape(1)); |
|
246 |
return SpectrogramTimeSerie(_t, _y, |
|
|
249 | return SpectrogramTimeSerie(std::move(_t), std::move(_y), | |
|
250 | std::move(_values), shape); | |
|
247 | 251 | })) |
|
248 | 252 | .def("__getitem__", |
|
249 | 253 | [](SpectrogramTimeSerie& ts, |
General Comments 0
You need to be logged in to leave comments.
Login now