61 static const std::vector<double> ACC_MATRIX_DIAGONAL_VALUES = { -1.0 / 12.0, 16.0 / 12.0, -30.0 / 12.0, 16.0 / 12.0,
63 static const std::vector<int> ACC_MATRIX_DIAGONAL_INDICES = { -2, -1, 0, 1, 2 };
65 auto fill_diagonal = [](Eigen::MatrixXd& m,
double coeff,
int diag_index) {
66 std::size_t size = m.rows() - std::abs(diag_index);
67 m.diagonal(diag_index) = Eigen::VectorXd::Constant(size, coeff);
71 Eigen::MatrixXd acceleration = Eigen::MatrixXd::Zero(num_timesteps, num_timesteps);
72 for (
auto i = 0u; i < ACC_MATRIX_DIAGONAL_INDICES.size(); i++)
74 fill_diagonal(acceleration, ACC_MATRIX_DIAGONAL_VALUES[i], ACC_MATRIX_DIAGONAL_INDICES[i]);
78 Eigen::MatrixXd covariance = Eigen::MatrixXd::Identity(num_timesteps, num_timesteps);
79 covariance = acceleration.transpose() * acceleration;
80 covariance = covariance.fullPivLu().inverse();
81 covariance /= covariance.array().abs().matrix().maxCoeff();
84 std::vector<math::MultivariateGaussianPtr> rand_generators(stddev.size());
85 for (
auto& r : rand_generators)
87 r = std::make_shared<math::MultivariateGaussian>(Eigen::VectorXd::Zero(num_timesteps), covariance);
90 auto raw_noise = std::make_shared<Eigen::VectorXd>(num_timesteps);
91 NoiseGeneratorFn noise_generator_fn = [=](
const Eigen::MatrixXd& values, Eigen::MatrixXd& noisy_values,
92 Eigen::MatrixXd& noise) {
93 for (
int i = 0; i < values.rows(); ++i)
95 rand_generators[i]->sample(*raw_noise);
96 raw_noise->head(1).setZero();
97 raw_noise->tail(1).setZero();
98 noise.row(i).transpose() = stddev.at(i) * (*raw_noise);
99 noisy_values.row(i) = values.row(i) + noise.row(i);
103 return noise_generator_fn;