time_series.h Source File

CPP API: time_series.h Source File
time_series.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Daniel Abele
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_UTILS_TIME_SERIES_H
21 #define MIO_UTILS_TIME_SERIES_H
22 
23 #include "memilio/io/io.h"
24 #include "memilio/utils/stl_util.h"
26 
27 #include <algorithm>
28 #include <iterator>
29 #include <vector>
30 #include <ostream>
31 #include <fstream>
32 
33 namespace mio
34 {
35 
36 namespace details
37 {
39 inline Eigen::Index next_pow2(Eigen::Index i);
40 } // namespace details
41 
42 template <class FP, bool IsConstant>
43 class TimeSeriesValueIterator;
44 template <class FP, bool IsConstant>
45 class TimeSeriesTimeIterator;
46 
56 template <class FP>
58 {
59 public:
61  using Matrix = Eigen::Matrix<FP, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
63  using Vector = Eigen::Matrix<FP, Eigen::Dynamic, 1>;
64 
65  using size_type = Eigen::Index;
70  using value_type = typename iterator::value_type;
71  using reference = typename iterator::reference;
73  using reverse_iterator = std::reverse_iterator<iterator>;
74  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
75  using reverse_time_iterator = std::reverse_iterator<time_iterator>;
76  using const_reverse_time_iterator = std::reverse_iterator<const_time_iterator>;
77 
82  TimeSeries(Eigen::Index num_elements)
83  : m_data(num_elements + 1, 0)
85  {
86  assert(num_elements >= 0);
87  }
88 
96  template <typename Expr>
97  TimeSeries(FP t, Expr&& expr)
98  : m_data(expr.rows() + 1, 1)
100  {
101  auto col = m_data.col(0);
102  col(0) = t;
103  col.tail(expr.rows()) = expr;
104  }
105 
111  TimeSeries(std::vector<std::vector<FP>> table)
112  : m_data() // resized in body
113  , m_num_time_points(table.size())
114  {
115  // check table sizes
116  assert(table.size() > 0 && "At least one entry is required to determine the number of elements.");
117  assert(std::all_of(table.begin(), table.end(),
118  [&table](auto&& a) {
119  return a.size() == table.front().size();
120  }) &&
121  "All table entries must have the same size.");
122  // resize data. note that the table entries contain both time and values
123  m_data.resize(table.front().size(), 0); // set columns first so reserve allocates correctly
124  reserve(table.size()); // reserve needs to happen before setting the number of rows
125  m_data.resize(Eigen::NoChange, table.size()); // finalize resize by setting the rows
126  // sort table by time
127  std::sort(table.begin(), table.end(), [](auto&& a, auto&& b) {
128  return a[0] < b[0];
129  });
130  // assign table to data
131  for (Eigen::Index tp = 0; tp < m_data.cols(); tp++) {
132  for (Eigen::Index i = 0; i < m_data.rows(); i++) {
133  m_data(i, tp) = table[tp][i];
134  }
135  }
136  }
137 
139  TimeSeries(const TimeSeries& other)
140  : m_data(other.get_num_elements() + 1, details::next_pow2(other.m_num_time_points))
142  {
143  get_valid_block() = other.get_valid_block();
144  }
145 
152  static TimeSeries zero(Eigen::Index num_time_points, Eigen::Index num_elements)
153  {
154  TimeSeries value_matrix(num_elements);
155  value_matrix.m_data = Matrix::Zero(num_elements + 1, num_time_points);
156  value_matrix.m_num_time_points = num_time_points;
157 
158  return value_matrix;
159  }
160 
163  {
164  if (get_num_elements() == other.get_num_elements()) {
165  //assign with preserved storage if possible
166  reserve(other.m_num_time_points);
168  get_valid_block() = other.get_valid_block();
169  }
170  else {
171  //assign with new storage
173  data.leftCols(other.m_num_time_points) = other.get_valid_block();
174  m_data = std::move(data);
176  }
177  return *this;
178  }
179 
181  TimeSeries(TimeSeries&& other) = default;
182  TimeSeries& operator=(TimeSeries&& other) = default;
183 
186  {
187  const auto times = get_times();
188  auto time_itr = times.begin();
189  return std::all_of(++times.begin(), times.end(), [&](const auto& t) {
190  return *(time_itr++) < t;
191  });
192  }
193 
197  Eigen::Index get_num_time_points() const
198  {
199  return m_num_time_points;
200  }
201 
205  Eigen::Index get_num_elements() const
206  {
207  return get_num_rows() - 1;
208  }
209 
213  Eigen::Index get_num_rows() const
214  {
215  return m_data.rows();
216  }
217 
221  Eigen::Ref<Vector> add_time_point()
222  {
224  return get_last_value();
225  }
226 
231  Eigen::Ref<Vector> add_time_point(FP t)
232  {
234  get_last_time() = t;
235  return get_last_value();
236  }
237 
243  template <class Expr>
244  Eigen::Ref<Vector> add_time_point(FP t, Expr&& expr)
245  {
246  auto value = add_time_point(t);
247  value = expr;
248  return value;
249  }
250 
255  void remove_time_point(Eigen::Index i)
256  {
257  assert(i >= 0 && i < m_num_time_points);
258  m_num_time_points -= 1;
259  for (auto j = i; j < m_num_time_points; ++j) {
260  m_data.col(j) = m_data.col(j + 1);
261  }
262  }
263 
265  {
267  }
268 
272  FP& get_time(Eigen::Index i)
273  {
274  assert(i >= 0 && i < m_num_time_points);
275  return m_data(0, i);
276  }
277  const FP& get_time(Eigen::Index i) const
278  {
279  assert(i >= 0 && i < m_num_time_points);
280  return m_data(0, i);
281  }
282 
287  {
288  return get_time(get_num_time_points() - 1);
289  }
290  const FP& get_last_time() const
291  {
292  return get_time(get_num_time_points() - 1);
293  }
294 
298  Eigen::Ref<const Vector> get_value(Eigen::Index i) const
299  {
300  assert(i >= 0 && i < m_num_time_points);
301  return m_data.col(i).segment(1, get_num_elements());
302  }
303  Eigen::Ref<Vector> get_value(Eigen::Index i)
304  {
305  assert(i >= 0 && i < m_num_time_points);
306  return m_data.col(i).segment(1, get_num_elements());
307  }
308  Eigen::Ref<const Vector> operator[](Eigen::Index i) const
309  {
310  return get_value(i);
311  }
312  Eigen::Ref<Vector> operator[](Eigen::Index i)
313  {
314  return get_value(i);
315  }
316 
320  Eigen::Ref<const Vector> get_last_value() const
321  {
322  return get_value(m_num_time_points - 1);
323  }
324  Eigen::Ref<Vector> get_last_value()
325  {
326  return get_value(m_num_time_points - 1);
327  }
328 
332  void reserve(Eigen::Index n)
333  {
334  assert(n >= 0);
335  if (n > get_capacity()) {
336  m_data.conservativeResize(Eigen::NoChange, details::next_pow2(n));
337  }
338  }
339 
343  Eigen::Index get_capacity() const
344  {
345  return m_data.cols();
346  }
347 
353  FP* data()
354  {
355  assert(m_data.innerStride() == 1);
356  assert(m_data.outerStride() == m_data.rows());
357  return m_data.data();
358  }
359  const FP* data() const
360  {
361  assert(m_data.innerStride() == 1);
362  assert(m_data.outerStride() == m_data.rows());
363  return m_data.data();
364  }
365 
371  auto matrix()
372  {
373  return get_valid_block();
374  }
375  auto matrix() const
376  {
377  return get_valid_block();
378  }
381  /*********************
382  *
383  * Iterator interface to iterate over values.
384  * vector at time point 0 -> vector at time point 1 -> ...
385  *
386  *********************/
388  {
389  return {&m_data, 0};
390  }
391 
393  {
394  return {&m_data, m_num_time_points};
395  }
396 
398  {
399  return {&m_data, 0};
400  }
401 
403  {
404  return {&m_data, m_num_time_points};
405  }
406 
408  {
409  return {&m_data, 0};
410  }
411 
413  {
414  return {&m_data, m_num_time_points};
415  }
416 
418  {
419  return reverse_iterator{end()};
420  }
421 
423  {
424  return reverse_iterator{begin()};
425  }
426 
428  {
429  return crbegin();
430  }
431 
433  {
434  return crend();
435  }
436 
438  {
439  return const_reverse_iterator{cend()};
440  }
441 
443  {
444  return const_reverse_iterator{cbegin()};
445  }
446 
447  /*********************
448  *
449  * Iterator interface to iterate over times.
450  * time at point 0 -> time at point 1 -> ...
451  *
452  *********************/
454  {
456  }
457 
459  {
460  return get_const_times();
461  }
462 
464  {
466  }
467 
469  {
470  auto time_range = get_times();
471  return {reverse_time_iterator{time_range.end()}, reverse_time_iterator{time_range.begin()}};
472  }
473 
475  {
476  return get_const_reverse_times();
477  }
478 
480  {
481  auto time_range = get_const_times();
482  return {const_reverse_time_iterator{time_range.end()}, const_reverse_time_iterator{time_range.begin()}};
483  }
484 
512  void print_table(std::ostream& out, const std::vector<std::string>& column_labels = {}, size_t width = 16,
513  size_t precision = 5, char separator = ' ', const std::string header_prefix = "\n") const
514  {
515  // Note: input manipulators (like std::setw, std::left) are consumed by the first argument written to the stream
516  // print column labels
517  const auto w = width, p = precision;
518  out << header_prefix;
519  set_ostream_format(out, w, p) << std::left << "Time";
520  for (size_t k = 0; k < static_cast<size_t>(get_num_elements()); k++) {
521  out << separator;
522  if (k < column_labels.size()) {
523  set_ostream_format(out, w, p) << std::left << column_labels[k];
524  }
525  else {
526  set_ostream_format(out, w, p) << std::left << "C" + std::to_string(k + 1);
527  }
528  }
529  // print values as table
530  auto num_points = static_cast<size_t>(get_num_time_points());
531  for (size_t i = 0; i < num_points; i++) {
532  out << "\n";
533  set_ostream_format(out, w, p) << std::right << get_time(i);
534  auto res_i = get_value(i);
535  for (size_t j = 0; j < static_cast<size_t>(res_i.size()); j++) {
536  out << separator;
537  set_ostream_format(out, w, p) << std::right << res_i[j];
538  }
539  }
540  out << "\n";
541  }
542 
543  void print_table(const std::vector<std::string>& column_labels = {}, size_t width = 16, size_t precision = 5,
544  char separator = ' ', const std::string header_prefix = "\n") const
545  {
546  print_table(std::cout, column_labels, width, precision, separator, header_prefix);
547  }
564  IOResult<void> export_csv(const std::string& filename, const std::vector<std::string>& column_labels = {},
565  char separator = ',', int precision = 6) const
566  {
567  std::ofstream file(filename);
568  if (!file.is_open()) {
569  return mio::failure(mio::StatusCode::FileNotFound, "Failed to export TimeSeries as CSV to " + filename);
570  }
571 
572  print_table(file, column_labels, 1, precision, separator, "");
573  return mio::success();
574  }
575 
579  friend void PrintTo(const TimeSeries& self, std::ostream* os)
580  {
581  *os << '\n' << self.get_valid_block();
582  }
583 
584  template <class IOContext>
585  void serialize(IOContext& io) const
586  {
587  auto obj = io.create_object("TimeSeries");
588  obj.add_element("NumTimePoints", m_num_time_points);
589  obj.add_element("Data", get_valid_block());
590  }
591 
592  template <class IOContext>
593  static IOResult<TimeSeries> deserialize(IOContext& io)
594  {
595  auto obj = io.expect_object("TimeSeries");
596  auto nt = obj.expect_element("NumTimePoints", Tag<Eigen::Index>{});
597  auto data = obj.expect_element("Data", Tag<Matrix>{});
598  return apply(
599  io,
600  [](auto&& nt_, auto&& data_) {
601  auto ts = TimeSeries(data_.rows() - 1);
602  ts.m_data.resize(data_.rows(), data_.cols());
603  ts.m_data = data_;
604  ts.m_num_time_points = nt_;
605  return ts;
606  },
607  nt, data);
608  }
609 
610 private:
612  {
615  }
618  {
619  return m_data.leftCols(get_num_time_points());
620  }
621  auto get_valid_block() const
622  {
623  return m_data.leftCols(get_num_time_points());
624  }
625 
629  Eigen::Index m_num_time_points;
630 };
631 
632 namespace details
633 {
635 inline Eigen::Index next_pow2(Eigen::Index i)
636 {
637  //https://stackoverflow.com/questions/1322510/given-an-integer-how-do-i-find-the-next-largest-power-of-two-using-bit-twiddlin
638  --i;
639  i |= i >> 1;
640  i |= i >> 2;
641  i |= i >> 4;
642  i |= i >> 8;
643  i |= i >> 16;
644  if constexpr (sizeof(Eigen::Index) == 8) {
645  i |= i >> 32;
646  }
647  ++i;
648  return i;
649 }
650 
654 template <class FP, bool IsConst>
656  static bool is_const()
657  {
658  return IsConst;
659  }
660  using Matrix = typename TimeSeries<FP>::Matrix;
661  using MatrixPtr = std::conditional_t<IsConst, const Matrix, Matrix>*;
662  using VectorValue = typename decltype(std::declval<MatrixPtr>()
663  ->col(std::declval<Eigen::Index>())
664  .tail(std::declval<Eigen::Index>()))::PlainObject;
666  decltype(std::declval<MatrixPtr>()->col(std::declval<Eigen::Index>()).tail(std::declval<Eigen::Index>()));
667  using TimeValue = FP;
668  using TimeReference = std::conditional_t<IsConst, const FP&, FP&>;
669 };
670 
678 template <class Derived, class FP, bool IsConstIter, class ValueType, class ReferenceType>
680 {
681 protected:
683  using MatrixPtr = typename Traits::MatrixPtr;
685  Eigen::Index m_col_idx = -1;
686 
687 public:
689 
690  TimeSeriesIteratorBase(MatrixPtr m, Eigen::Index col_idx = 0)
691  : m_matrix(m)
692  , m_col_idx(col_idx)
693  {
694  assert(m_matrix != nullptr);
695  }
696 
697  using difference_type = std::ptrdiff_t;
698  using iterator_category = std::random_access_iterator_tag;
699  using reference = ReferenceType;
700  using value_type = ValueType;
701 
706  struct pointer {
708  auto operator->()
709  {
710  return &m_ref;
711  }
712  };
713 
715  {
716  assert(m_col_idx >= 0 && m_col_idx < m_matrix->cols());
717  return static_cast<const Derived&>(*this).get_reference();
718  }
719 
721  {
722  return *(*this);
723  }
724 
726  {
727  return *((*this) + i);
728  }
729 
731  {
732  m_col_idx += i;
733  return static_cast<Derived&>(*this);
734  }
735 
736  Derived operator+(difference_type i) const
737  {
738  auto tmp = static_cast<const Derived&>(*this);
739  tmp += i;
740  return tmp;
741  }
742 
744  {
745  auto tmp = static_cast<const Derived&>(b);
746  tmp += i;
747  return tmp;
748  }
749 
751  {
752  m_col_idx -= i;
753  return static_cast<Derived&>(*this);
754  }
755 
756  Derived operator-(difference_type i) const
757  {
758  auto tmp = static_cast<const Derived&>(*this);
759  tmp -= i;
760  return tmp;
761  }
762 
764  {
765  return m_col_idx - other.m_col_idx;
766  }
767 
768  Derived& operator++()
769  {
770  ++m_col_idx;
771  return static_cast<Derived&>(*this);
772  }
773 
774  Derived operator++(int)
775  {
776  auto tmp = static_cast<Derived&>(*this);
777  ++(*this);
778  return tmp;
779  }
780 
781  Derived& operator--()
782  {
783  --m_col_idx;
784  return static_cast<Derived&>(*this);
785  }
786 
787  Derived operator--(int)
788  {
789  auto tmp = static_cast<Derived&>(*this);
790  --(*this);
791  return tmp;
792  }
793 
794  bool operator==(const TimeSeriesIteratorBase& other) const
795  {
796  assert(m_matrix == other.m_matrix);
797  return m_col_idx == other.m_col_idx;
798  }
799 
800  bool operator!=(const TimeSeriesIteratorBase& other) const
801  {
802  assert(m_matrix == other.m_matrix);
803  return !(*this == other);
804  }
805 
806  bool operator<(const TimeSeriesIteratorBase& other) const
807  {
808  assert(m_matrix == other.m_matrix);
809  return m_col_idx < other.m_col_idx;
810  }
811 
812  bool operator>(const TimeSeriesIteratorBase& other) const
813  {
814  assert(m_matrix == other.m_matrix);
815  return m_col_idx > other.m_col_idx;
816  }
817 
818  bool operator<=(const TimeSeriesIteratorBase& other) const
819  {
820  assert(m_matrix == other.m_matrix);
821  return m_col_idx <= other.m_col_idx;
822  }
823 
824  bool operator>=(const TimeSeriesIteratorBase& other) const
825  {
826  assert(m_matrix == other.m_matrix);
827  return m_col_idx >= other.m_col_idx;
828  }
829 };
830 } // namespace details
831 
833 template <class FP, bool IsConstIter>
835  : public details::TimeSeriesIteratorBase<TimeSeriesValueIterator<FP, IsConstIter>, FP, IsConstIter,
836  typename details::TimeSeriesIterTraits<FP, IsConstIter>::VectorValue,
837  typename details::TimeSeriesIterTraits<FP, IsConstIter>::VectorReference>
838 {
839 private:
840  using Base =
844 
845  using Base::m_col_idx;
846  using Base::m_matrix;
847 
848 public:
850  using Base::Base;
851 
854  using reference = typename Base::reference;
855  using value_type = typename Base::value_type;
856  using pointer = typename Base::pointer;
857 
859  {
860  return m_matrix->col(m_col_idx).tail(m_matrix->rows() - 1);
861  }
862 };
863 
865 template <class FP, bool IsConstIter>
867  : public details::TimeSeriesIteratorBase<TimeSeriesTimeIterator<FP, IsConstIter>, FP, IsConstIter,
868  typename details::TimeSeriesIterTraits<FP, IsConstIter>::TimeValue,
869  typename details::TimeSeriesIterTraits<FP, IsConstIter>::TimeReference>
870 {
871 private:
872  using Base =
876 
877  using Base::m_col_idx;
878  using Base::m_matrix;
879 
880 public:
882  using Base::Base;
883 
886  using reference = typename Base::reference;
887  using value_type = typename Base::value_type;
888  using pointer = typename Base::pointer;
889 
891  {
892  return m_matrix->coeffRef(0, m_col_idx);
893  }
894 };
895 
904 template <class FP, class TS>
905 decltype(std::declval<TS>().rend()) find_value_reverse(TS&& ts, FP t_search, FP abs_tol = 0, FP rel_tol = 0)
906 {
907  auto iter_t = find_if(ts.get_reverse_times().begin(), ts.get_reverse_times().end(), [=](auto t) {
908  return floating_point_equal<FP>(t, t_search, abs_tol, rel_tol);
909  });
910  if (iter_t != ts.get_reverse_times().end()) {
911  return ts.rbegin() + (iter_t - ts.get_reverse_times().begin());
912  }
913  return ts.rend();
914 }
915 
916 } // namespace mio
917 
918 #endif // MIO_UTILS_TIME_SERIES_H
A range of items defined by two iterators.
Definition: stl_util.h:99
Iterate over vector values of a time series by time point.
Definition: time_series.h:870
typename Base::value_type value_type
Definition: time_series.h:887
typename Base::iterator_category iterator_category
Definition: time_series.h:884
typename Base::difference_type difference_type
Definition: time_series.h:885
typename Base::pointer pointer
Definition: time_series.h:888
reference get_reference() const
Definition: time_series.h:890
Eigen::Index m_col_idx
Definition: time_series.h:685
typename Base::reference reference
Definition: time_series.h:886
MatrixPtr m_matrix
Definition: time_series.h:684
Iterate over vector values of a time series by time point.
Definition: time_series.h:838
typename Base::iterator_category iterator_category
Definition: time_series.h:852
reference get_reference() const
Definition: time_series.h:858
typename Base::reference reference
Definition: time_series.h:854
Eigen::Index m_col_idx
Definition: time_series.h:685
typename Base::value_type value_type
Definition: time_series.h:855
MatrixPtr m_matrix
Definition: time_series.h:684
typename Base::difference_type difference_type
Definition: time_series.h:853
typename Base::pointer pointer
Definition: time_series.h:856
stores vectors of values at time points (or some other abstract variable) the value at each time poin...
Definition: time_series.h:58
void reserve(Eigen::Index n)
reserve capacity for n time points
Definition: time_series.h:332
const_iterator cbegin() const
Definition: time_series.h:407
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: time_series.h:74
auto matrix() const
Matrix expression that contains one time point per column.
Definition: time_series.h:375
Matrix m_data
data storage
Definition: time_series.h:627
TimeSeries & operator=(const TimeSeries &other)
copy assignment
Definition: time_series.h:162
const_iterator end() const
Definition: time_series.h:402
Range< const_reverse_time_iterator > get_const_reverse_times() const
Definition: time_series.h:479
iterator begin()
Definition: time_series.h:387
void remove_last_time_point()
Definition: time_series.h:264
Eigen::Ref< Vector > get_value(Eigen::Index i)
Definition: time_series.h:303
Eigen::Index m_num_time_points
number of time points (i.e.
Definition: time_series.h:629
typename iterator::value_type value_type
Definition: time_series.h:70
Eigen::Ref< Vector > add_time_point(FP t, Expr &&expr)
add one time point.
Definition: time_series.h:244
Eigen::Ref< const Vector > get_value(Eigen::Index i) const
reference to value vector at time point i
Definition: time_series.h:298
typename iterator::difference_type difference_type
Definition: time_series.h:72
const FP & get_last_time() const
Definition: time_series.h:290
void serialize(IOContext &io) const
Definition: time_series.h:585
void print_table(const std::vector< std::string > &column_labels={}, size_t width=16, size_t precision=5, char separator=' ', const std::string header_prefix="\n") const
Print out the TimeSeries as a table.
Definition: time_series.h:543
const_reverse_iterator rbegin() const
Definition: time_series.h:427
void remove_time_point(Eigen::Index i)
remove time point.
Definition: time_series.h:255
TimeSeries(std::vector< std::vector< FP >> table)
Initialize a TimeSeries with a table.
Definition: time_series.h:111
Range< const_reverse_time_iterator > get_reverse_times() const
Definition: time_series.h:474
static IOResult< TimeSeries > deserialize(IOContext &io)
Definition: time_series.h:593
Eigen::Matrix< FP, Eigen::Dynamic, 1 > Vector
base type of expressions of vector values at a time point
Definition: time_series.h:63
TimeSeries(Eigen::Index num_elements)
initialize empty TimeSeries.
Definition: time_series.h:82
const_iterator cend() const
Definition: time_series.h:412
Eigen::Index get_capacity() const
current capacity
Definition: time_series.h:343
Eigen::Ref< Vector > get_last_value()
Definition: time_series.h:324
reverse_iterator rend()
Definition: time_series.h:422
const_iterator begin() const
Definition: time_series.h:397
void add_time_point_noinit()
Definition: time_series.h:611
TimeSeries(FP t, Expr &&expr)
initialize TimeSeries with one time point.
Definition: time_series.h:97
friend void PrintTo(const TimeSeries &self, std::ostream *os)
print this object (googletest)
Definition: time_series.h:579
Eigen::Ref< const Vector > operator[](Eigen::Index i) const
Definition: time_series.h:308
static TimeSeries zero(Eigen::Index num_time_points, Eigen::Index num_elements)
constructs TimeSeries instance and initializes it with zeros
Definition: time_series.h:152
const_reverse_iterator crbegin() const
Definition: time_series.h:437
const FP * data() const
Definition: time_series.h:359
reverse_iterator rbegin()
Definition: time_series.h:417
Eigen::Index get_num_elements() const
number of elements of vector at each time point
Definition: time_series.h:205
Eigen::Matrix< FP, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
type that stores the data
Definition: time_series.h:61
std::reverse_iterator< iterator > reverse_iterator
Definition: time_series.h:73
std::reverse_iterator< time_iterator > reverse_time_iterator
Definition: time_series.h:75
bool is_strictly_monotonic() const
Check if the time is strictly monotonic increasing.
Definition: time_series.h:185
TimeSeries & operator=(TimeSeries &&other)=default
Eigen::Ref< Vector > operator[](Eigen::Index i)
Definition: time_series.h:312
TimeSeries(TimeSeries &&other)=default
move ctor and assignment
Range< time_iterator > get_times()
Definition: time_series.h:453
const_reverse_iterator rend() const
Definition: time_series.h:432
auto get_valid_block() const
Definition: time_series.h:621
const FP & get_time(Eigen::Index i) const
Definition: time_series.h:277
TimeSeries(const TimeSeries &other)
copy ctor
Definition: time_series.h:139
FP & get_last_time()
time of time point at index num_time_points - 1
Definition: time_series.h:286
Range< const_time_iterator > get_const_times() const
Definition: time_series.h:463
FP * data()
raw data storage.
Definition: time_series.h:353
void print_table(std::ostream &out, const std::vector< std::string > &column_labels={}, size_t width=16, size_t precision=5, char separator=' ', const std::string header_prefix="\n") const
Print out the TimeSeries as a table.
Definition: time_series.h:512
iterator end()
Definition: time_series.h:392
auto matrix()
Matrix expression that contains one time point per column.
Definition: time_series.h:371
const_reverse_iterator crend() const
Definition: time_series.h:442
Eigen::Index get_num_time_points() const
number of time points in the series
Definition: time_series.h:197
IOResult< void > export_csv(const std::string &filename, const std::vector< std::string > &column_labels={}, char separator=',', int precision=6) const
Exports a TimeSeries object into a CSV file.
Definition: time_series.h:564
FP & get_time(Eigen::Index i)
time of time point at index i
Definition: time_series.h:272
Eigen::Index size_type
Definition: time_series.h:65
Eigen::Index get_num_rows() const
number of rows in data storage (includes time)
Definition: time_series.h:213
Eigen::Ref< Vector > add_time_point(FP t)
add one time point.
Definition: time_series.h:231
Eigen::Ref< Vector > add_time_point()
add one uninitialized time point
Definition: time_series.h:221
Range< const_time_iterator > get_times() const
Definition: time_series.h:458
std::reverse_iterator< const_time_iterator > const_reverse_time_iterator
Definition: time_series.h:76
typename iterator::reference reference
Definition: time_series.h:71
Range< reverse_time_iterator > get_reverse_times()
Definition: time_series.h:468
Eigen::Ref< const Vector > get_last_value() const
reference to value vector at time point (num_timepoints - 1)
Definition: time_series.h:320
auto get_valid_block()
currently occupied block of storage
Definition: time_series.h:617
base class for TimeSeries iterators that iterate by time point (i.e.
Definition: time_series.h:680
bool operator>=(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:824
Derived & operator++()
Definition: time_series.h:768
Derived operator+(difference_type i) const
Definition: time_series.h:736
std::ptrdiff_t difference_type
Definition: time_series.h:697
Derived & operator--()
Definition: time_series.h:781
Derived & operator+=(difference_type i)
Definition: time_series.h:730
Derived operator-(difference_type i) const
Definition: time_series.h:756
ReferenceType reference
Definition: time_series.h:699
bool operator>(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:812
bool operator!=(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:800
bool operator<=(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:818
reference operator*() const
Definition: time_series.h:714
pointer operator->() const
Definition: time_series.h:720
typename Traits::MatrixPtr MatrixPtr
Definition: time_series.h:683
reference operator[](difference_type i) const
Definition: time_series.h:725
bool operator==(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:794
Eigen::Index m_col_idx
Definition: time_series.h:685
std::random_access_iterator_tag iterator_category
Definition: time_series.h:698
Derived operator--(int)
Definition: time_series.h:787
friend Derived operator+(difference_type i, const TimeSeriesIteratorBase &b)
Definition: time_series.h:743
TimeSeriesIteratorBase(MatrixPtr m, Eigen::Index col_idx=0)
Definition: time_series.h:690
Derived & operator-=(difference_type i)
Definition: time_series.h:750
bool operator<(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:806
Derived operator++(int)
Definition: time_series.h:774
ValueType value_type
Definition: time_series.h:700
MatrixPtr m_matrix
Definition: time_series.h:684
difference_type operator-(const TimeSeriesIteratorBase &other) const
Definition: time_series.h:763
trait_value< T >::RETURN_TYPE & value(T &x)
Definition: ad.hpp:3308
Eigen::Index next_pow2(Eigen::Index i)
round an integer to the nearest greater power of 2
Definition: time_series.h:635
int size(Comm comm)
Return the size of the given communicator.
Definition: miompi.cpp:75
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
auto failure(const IOStatus &s)
Create an object that is implicitly convertible to an error IOResult<T>.
Definition: io.h:380
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
auto i
Definition: io.h:809
decltype(std::declval< TS >().rend()) find_value_reverse(TS &&ts, FP t_search, FP abs_tol=0, FP rel_tol=0)
find the value in the time series at time t_search starting from the end.
Definition: time_series.h:905
details::ApplyResultT< F, T... > apply(IOContext &io, F f, const IOResult< T > &... rs)
Evaluate a function with zero or more unpacked IOResults as arguments.
Definition: io.h:481
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
std::ostream & set_ostream_format(std::ostream &out, size_t width, size_t precision, char fill=' ')
Adds manipulators for width, (fixed) precision and fill character to an ostream.
Definition: stl_util.h:49
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353
type traits for time series iterators
Definition: time_series.h:655
typename decltype(std::declval< MatrixPtr >() ->col(std::declval< Eigen::Index >()) .tail(std::declval< Eigen::Index >()))::PlainObject VectorValue
Definition: time_series.h:664
FP TimeValue
Definition: time_series.h:667
static bool is_const()
Definition: time_series.h:656
decltype(std::declval< MatrixPtr >() ->col(std::declval< Eigen::Index >()).tail(std::declval< Eigen::Index >())) VectorReference
Definition: time_series.h:666
typename TimeSeries< FP >::Matrix Matrix
Definition: time_series.h:660
std::conditional_t< IsConst, const Matrix, Matrix > * MatrixPtr
Definition: time_series.h:661
std::conditional_t< IsConst, const FP &, FP & > TimeReference
Definition: time_series.h:668
Dereferencable type with a copy of a reference.
Definition: time_series.h:706
reference m_ref
Definition: time_series.h:707
auto operator->()
Definition: time_series.h:708