Directory: | ./ |
---|---|
File: | include/crocoddyl/core/utils/conversions.hpp |
Date: | 2025-03-26 19:23:43 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 8 | 15 | 53.3% |
Branches: | 5 | 16 | 31.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // BSD 3-Clause License | ||
3 | // | ||
4 | // Copyright (C) 2024-2025, Heriot-Watt University | ||
5 | // Copyright note valid unless otherwise stated in individual files. | ||
6 | // All rights reserved. | ||
7 | /////////////////////////////////////////////////////////////////////////////// | ||
8 | |||
9 | #ifndef CROCODDYL_UTILS_CONVERSIONS_HPP_ | ||
10 | #define CROCODDYL_UTILS_CONVERSIONS_HPP_ | ||
11 | |||
12 | #include <vector> | ||
13 | |||
14 | #include "crocoddyl/core/mathbase.hpp" | ||
15 | |||
16 | namespace crocoddyl { | ||
17 | |||
18 | template <typename Scalar> | ||
19 | struct ScalarSelector { | ||
20 | typedef typename std::conditional<std::is_floating_point<Scalar>::value, | ||
21 | Scalar, double>::type type; | ||
22 | }; | ||
23 | |||
24 | // Casting between floating-point types | ||
25 | template <typename NewScalar, typename Scalar> | ||
26 | static typename std::enable_if<std::is_floating_point<NewScalar>::value && | ||
27 | std::is_floating_point<Scalar>::value, | ||
28 | NewScalar>::type | ||
29 | 423 | scalar_cast(const Scalar& x) { | |
30 | 423 | return static_cast<NewScalar>(x); | |
31 | } | ||
32 | |||
33 | template <typename NewScalar, typename Scalar, | ||
34 | template <typename> class ItemTpl> | ||
35 | 5 | std::vector<ItemTpl<NewScalar>> vector_cast( | |
36 | const std::vector<ItemTpl<Scalar>>& in) { | ||
37 | 5 | std::vector<ItemTpl<NewScalar>> out; | |
38 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | out.reserve(in.size()); // Optimize allocation |
39 |
2/2✓ Branch 4 taken 20 times.
✓ Branch 5 taken 5 times.
|
25 | for (const auto& obj : in) { |
40 |
2/4✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
|
20 | out.push_back(obj.template cast<NewScalar>()); |
41 | } | ||
42 | 5 | return out; | |
43 | } | ||
44 | |||
45 | template <typename NewScalar, typename Scalar, | ||
46 | template <typename> class ItemTpl> | ||
47 | ✗ | std::vector<std::shared_ptr<ItemTpl<NewScalar>>> vector_cast( | |
48 | const std::vector<std::shared_ptr<ItemTpl<Scalar>>>& in) { | ||
49 | ✗ | std::vector<std::shared_ptr<ItemTpl<NewScalar>>> out; | |
50 | ✗ | out.reserve(in.size()); // Optimize allocation | |
51 | ✗ | for (const auto& obj : in) { | |
52 | ✗ | out.push_back(std::static_pointer_cast<ItemTpl<NewScalar>>( | |
53 | ✗ | obj->template cast<NewScalar>())); | |
54 | } | ||
55 | ✗ | return out; | |
56 | } | ||
57 | |||
58 | } // namespace crocoddyl | ||
59 | |||
60 | #ifdef CROCODDYL_WITH_CODEGEN | ||
61 | |||
62 | // Specialize Eigen's internal cast_impl for your specific types | ||
63 | namespace Eigen { | ||
64 | namespace internal { | ||
65 | |||
66 | template <> | ||
67 | struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, float> { | ||
68 | EIGEN_DEVICE_FUNC static inline float run( | ||
69 | const CppAD::AD<CppAD::cg::CG<double>>& x) { | ||
70 | // Perform the conversion. This example extracts the value from the AD type. | ||
71 | // You might need to adjust this depending on the specific implementation of | ||
72 | // CppAD::cg::CG<double>. | ||
73 | return static_cast<float>(CppAD::Value(x).getValue()); | ||
74 | } | ||
75 | }; | ||
76 | |||
77 | template <> | ||
78 | struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, double> { | ||
79 | EIGEN_DEVICE_FUNC static inline double run( | ||
80 | const CppAD::AD<CppAD::cg::CG<double>>& x) { | ||
81 | return CppAD::Value(x).getValue(); | ||
82 | } | ||
83 | }; | ||
84 | |||
85 | template <> | ||
86 | struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, float> { | ||
87 | EIGEN_DEVICE_FUNC static inline float run( | ||
88 | const CppAD::AD<CppAD::cg::CG<float>>& x) { | ||
89 | return CppAD::Value(x).getValue(); | ||
90 | } | ||
91 | }; | ||
92 | |||
93 | template <> | ||
94 | struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, double> { | ||
95 | EIGEN_DEVICE_FUNC static inline double run( | ||
96 | const CppAD::AD<CppAD::cg::CG<float>>& x) { | ||
97 | // Perform the conversion. This example extracts the value from the AD type. | ||
98 | // You might need to adjust this depending on the specific implementation of | ||
99 | // CppAD::cg::CG<float>. | ||
100 | return static_cast<float>(CppAD::Value(x).getValue()); | ||
101 | } | ||
102 | }; | ||
103 | |||
104 | // Convert from CppAD::AD<CppAD::cg::CG<float>> to | ||
105 | // CppAD::AD<CppAD::cg::CG<double>> | ||
106 | template <> | ||
107 | struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, | ||
108 | CppAD::AD<CppAD::cg::CG<double>>> { | ||
109 | EIGEN_DEVICE_FUNC static inline CppAD::AD<CppAD::cg::CG<double>> run( | ||
110 | const CppAD::AD<CppAD::cg::CG<float>>& x) { | ||
111 | return CppAD::AD<CppAD::cg::CG<double>>( | ||
112 | CppAD::cg::CG<double>(CppAD::Value(x).getValue())); | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | // Convert from CppAD::AD<CppAD::cg::CG<double>> to | ||
117 | // CppAD::AD<CppAD::cg::CG<float>> | ||
118 | template <> | ||
119 | struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, | ||
120 | CppAD::AD<CppAD::cg::CG<float>>> { | ||
121 | EIGEN_DEVICE_FUNC static inline CppAD::AD<CppAD::cg::CG<float>> run( | ||
122 | const CppAD::AD<CppAD::cg::CG<double>>& x) { | ||
123 | return CppAD::AD<CppAD::cg::CG<float>>( | ||
124 | CppAD::cg::CG<float>(static_cast<float>(CppAD::Value(x).getValue()))); | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | } // namespace internal | ||
129 | } // namespace Eigen | ||
130 | |||
131 | namespace crocoddyl { | ||
132 | |||
133 | // Casting to CppAD types from floating-point types | ||
134 | template <typename NewScalar, typename Scalar> | ||
135 | static typename std::enable_if< | ||
136 | std::is_floating_point<Scalar>::value && | ||
137 | (std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<double>>>::value || | ||
138 | std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<float>>>::value), | ||
139 | NewScalar>::type | ||
140 | scalar_cast(const Scalar& x) { | ||
141 | return static_cast<NewScalar>(x); | ||
142 | } | ||
143 | |||
144 | // Casting to floating-point types from CppAD types | ||
145 | template <typename NewScalar, typename Scalar> | ||
146 | static inline typename std::enable_if<std::is_floating_point<Scalar>::value, | ||
147 | NewScalar>::type | ||
148 | scalar_cast(const CppAD::AD<CppAD::cg::CG<Scalar>>& x) { | ||
149 | return static_cast<NewScalar>(CppAD::Value(x).getValue()); | ||
150 | } | ||
151 | |||
152 | } // namespace crocoddyl | ||
153 | |||
154 | #endif | ||
155 | |||
156 | #endif // CROCODDYL_UTILS_CONVERSIONS_HPP_ | ||
157 |