9#ifndef CROCODDYL_UTILS_CONVERSIONS_HPP_ 10#define CROCODDYL_UTILS_CONVERSIONS_HPP_ 15#ifdef CROCODDYL_WITH_CODEGEN 16#include <cppad/cg/support/cppadcg_eigen.hpp> 17#include <cppad/cppad.hpp> 20#include "crocoddyl/core/mathbase.hpp" 24template <
typename Scalar>
26 typedef typename std::conditional<std::is_floating_point<Scalar>::value,
27 Scalar,
double>::type type;
31template <
typename NewScalar,
typename Scalar>
32static typename std::enable_if<std::is_floating_point<NewScalar>::value &&
33 std::is_floating_point<Scalar>::value,
35scalar_cast(
const Scalar& x) {
36 return static_cast<NewScalar
>(x);
39#ifdef CROCODDYL_WITH_CODEGEN 42template <
typename NewScalar,
typename Scalar>
43static typename std::enable_if<
44 std::is_floating_point<Scalar>::value &&
45 (std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<double>>>::value ||
46 std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<float>>>::value),
48scalar_cast(
const Scalar& x) {
49 return static_cast<NewScalar
>(x);
53template <
typename NewScalar,
typename Scalar>
54static inline typename std::enable_if<std::is_floating_point<Scalar>::value,
56scalar_cast(
const CppAD::AD<CppAD::cg::CG<Scalar>>& x) {
57 return static_cast<NewScalar
>(CppAD::Value(x).getValue());
62template <
typename NewScalar,
typename Scalar>
63std::vector<NewScalar> vector_cast(
const std::vector<Scalar>& in) {
64 std::vector<NewScalar> out;
65 out.reserve(in.size());
66 for (
const auto& obj : in) {
67 out.push_back(scalar_cast<NewScalar>(obj));
72template <
typename NewScalar,
typename Scalar,
int Rows,
int Cols,
int Options,
73 int MaxRows,
int MaxCols>
74std::vector<Eigen::Matrix<NewScalar, Rows, Cols, Options, MaxRows, MaxCols>>
75vector_cast(
const std::vector<
76 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>& in) {
77 std::vector<Eigen::Matrix<NewScalar, Rows, Cols, Options, MaxRows, MaxCols>>
79 out.reserve(in.size());
80 for (
const auto& obj : in) {
81 out.push_back(obj.template cast<NewScalar>());
86template <
typename NewScalar,
typename Scalar,
87 template <
typename>
class ItemTpl>
88std::vector<ItemTpl<NewScalar>> vector_cast(
89 const std::vector<ItemTpl<Scalar>>& in) {
90 std::vector<ItemTpl<NewScalar>> out;
91 out.reserve(in.size());
92 for (
const auto& obj : in) {
93 out.push_back(obj.template cast<NewScalar>());
98template <
typename NewScalar,
typename Scalar,
99 template <
typename>
class ItemTpl>
100std::vector<std::shared_ptr<ItemTpl<NewScalar>>> vector_cast(
101 const std::vector<std::shared_ptr<ItemTpl<Scalar>>>& in) {
102 std::vector<std::shared_ptr<ItemTpl<NewScalar>>> out;
103 out.reserve(in.size());
104 for (
const auto& obj : in) {
105 out.push_back(std::static_pointer_cast<ItemTpl<NewScalar>>(
106 obj->template cast<NewScalar>()));
111template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
113Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> matrix_random_cast(
114 const Eigen::Index rows,
const Eigen::Index cols) {
116 Eigen::Matrix<double, Rows, Cols, Options, MaxRows, MaxCols>;
117 return MatrixDouble::Random(rows, cols).template cast<Scalar>();
120template <
typename Scalar,
int Rows,
int Options,
int MaxRows>
121Eigen::Matrix<Scalar, Rows, 1, Options, MaxRows, 1> vector_random_cast(
122 const Eigen::Index size) {
123 using VectorDouble = Eigen::Matrix<double, Rows, 1, Options, MaxRows, 1>;
124 return VectorDouble::Random(size).template cast<Scalar>();
129#ifdef CROCODDYL_WITH_CODEGEN 136struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, float> {
137 EIGEN_DEVICE_FUNC
static inline float run(
138 const CppAD::AD<CppAD::cg::CG<double>>& x) {
142 return static_cast<float>(CppAD::Value(x).getValue());
147struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, double> {
148 EIGEN_DEVICE_FUNC
static inline double run(
149 const CppAD::AD<CppAD::cg::CG<double>>& x) {
150 return CppAD::Value(x).getValue();
155struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, float> {
156 EIGEN_DEVICE_FUNC
static inline float run(
157 const CppAD::AD<CppAD::cg::CG<float>>& x) {
158 return CppAD::Value(x).getValue();
163struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, double> {
164 EIGEN_DEVICE_FUNC
static inline double run(
165 const CppAD::AD<CppAD::cg::CG<float>>& x) {
169 return static_cast<float>(CppAD::Value(x).getValue());
176struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>,
177 CppAD::AD<CppAD::cg::CG<double>>> {
178 EIGEN_DEVICE_FUNC
static inline CppAD::AD<CppAD::cg::CG<double>> run(
179 const CppAD::AD<CppAD::cg::CG<float>>& x) {
180 return CppAD::AD<CppAD::cg::CG<double>>(
181 CppAD::cg::CG<double>(CppAD::Value(x).getValue()));
188struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>,
189 CppAD::AD<CppAD::cg::CG<float>>> {
190 EIGEN_DEVICE_FUNC
static inline CppAD::AD<CppAD::cg::CG<float>> run(
191 const CppAD::AD<CppAD::cg::CG<double>>& x) {
192 return CppAD::AD<CppAD::cg::CG<float>>(
193 CppAD::cg::CG<float>(
static_cast<float>(CppAD::Value(x).getValue())));