44 _time.reserve(time_dim);
45 _values.reserve(time_dim * value_dim);
50 if (values.empty())
return true;
58 _time.push_back(time);
73 _time.push_back(time);
81 if (values_matrix.cols() != time.size())
83 PRINT_ERROR(
"TimeSeries::set(): time.size() != values_matrix.cols()");
90 _time.assign(time.data(), time.data() + time.size());
91 if (values_matrix.IsRowMajor)
96 target = values_matrix;
100 const int size = values_matrix.rows() * values_matrix.cols();
101 _values.assign(values_matrix.data(), values_matrix.data() +
size);
106 bool TimeSeries::set(
const std::vector<double>& time,
const std::vector<Eigen::VectorXd>& values_vector,
double time_from_start)
108 if (values_vector.size() != time.size())
129 for (
const Eigen::VectorXd& vec : values_vector)
132 _values.insert(
_values.end(), vec.data(), vec.data() + vec.size());
137 PRINT_ERROR_NAMED(
"Vectors in values_vector must be of equal size. Clearing time series object.");
153 assert(time_idx <
_time.size());
154 std::vector<double> temp;
155 const int value_idx_begin =
_value_dim * time_idx;
156 const int value_idx_end = value_idx_begin +
_value_dim;
157 temp.assign(
_values.begin() + value_idx_begin,
_values.begin() + value_idx_end);
163 assert(time_idx <
_time.size());
164 const int value_idx_begin =
_value_dim * time_idx;
169 double tolerance)
const
171 if (
_time.empty())
return false;
173 auto it = std::find_if(
_time.begin(),
_time.end(), [time](
double val) { return val >= time; });
174 if (it ==
_time.end())
176 switch (extrapolation)
189 PRINT_ERROR(
"TimeSeries::valuesInterpolate(): desired extrapolation method not implemented.");
196 int idx = (
int)std::distance(
_time.begin(), it);
206 PRINT_ERROR(
"accessing a time idx in the past which is not this time series");
209 double dt = time -
_time[idx - 1];
212 switch (interpolation)
216 if (idx < 1) idx = 1;
229 double dt_frac = dt / dt_data;
236 PRINT_ERROR(
"TimeSeries::valuesInterpolate(): desired interpolation method not implemented.");
249 PRINT_ERROR(
"TimeSeries::computeMeanCwise(): provided mean_values vector does not match value dimension");
269 double first_value =
_values.front();
270 if (first_value != 0)
305 PRINT_ERROR(
"TimeSeries::normalize(): selected method not implemented.");
316 PRINT_ERROR(
"TimeSeries::normalize(): specified value_idx does not match getValueDimension().");
324 double first_value =
getValues(0)[value_idx];
325 if (first_value != 0)
360 PRINT_ERROR(
"TimeSeries::normalize(): selected method not implemented.");
366 #ifdef MESSAGE_SUPPORT
367 bool TimeSeries::toMessage(corbo::messages::TimeSeries& message)
const
373 google::protobuf::RepeatedField<double> time(
_time.begin(),
_time.end());
374 message.mutable_time()->Swap(&time);
378 message.mutable_values()->set_rows(
_value_dim);
379 message.mutable_values()->set_row_major(
false);
380 google::protobuf::RepeatedField<double> values(
_values.begin(),
_values.end());
381 message.mutable_values()->mutable_data()->Swap(&values);
387 message.clear_value_labels();
388 for (
const std::string& label :
_value_labels) message.add_value_labels(label);
391 bool TimeSeries::fromMessage(
const corbo::messages::TimeSeries& message, std::stringstream* issues)
394 _time.assign(message.time().begin(), message.time().end());
400 PRINT_ERROR(
"TimeSeries::fromMessage(): Dimension mismatch: values raw data does not match rows*cols: "
402 if (issues) *issues <<
"Dimension mismatch: values raw data does not match rows*cols.\n";
406 if (message.values().row_major())
417 _values.assign(message.values().data().begin(), message.values().data().end());
425 for (
int i = 0; i < message.value_labels_size(); ++i)
_value_labels.push_back(message.value_labels(i));
432 std::ostream&
operator<<(std::ostream& out,
const TimeSeries& ts)
436 out <<
"TimeSeries is empty." << std::endl;
439 for (
int i = 0; i < ts.getTimeDimension(); ++i)
442 out <<
"time: " << ts.getTime()[i] <<
"\t values: " << ts.getValuesMap(i).transpose() << std::endl;
458 if (!ts)
return false;
464 else if (ts->getValueDimension() !=
_value_dim)
466 PRINT_ERROR(
"TimeSeriesSequence::add(): cannot add TimeSeries since its dimension differs with previously added ones.");
485 #ifdef MESSAGE_SUPPORT
486 bool TimeSeriesSequence::toMessage(corbo::messages::TimeSeriesSequence& message)
const
489 message.clear_ts_sequence();
492 ts->toMessage(*message.add_ts_sequence());
500 bool TimeSeriesSequence::fromMessage(
const corbo::messages::TimeSeriesSequence& message, std::stringstream* issues)
510 for (
int i = 0; i < message.ts_sequence_size(); ++i)
513 new_ts->fromMessage(message.ts_sequence(i));
514 if (new_ts->getValueDimension() !=
_value_dim)
517 *issues <<
"Imported TimeSeries object has a value dimension other than specified: " << new_ts->getValueDimension() <<
"/"