@@ -64,6 +64,13 @@ inline auto as_column_vector_or_scalar(T&& a) {
6464/* *
6565 * Converts `std::vector` to a column vector.
6666 *
67+ * @note The math library's reverse mode assumes that `Eigen::Map`
68+ * types are allocated and owned elsewhere so we cannot just return
69+ * back a map here else the reverse mode library
70+ * may try to access into a dangling pointer. Instead we wrap
71+ * the `Eigen::Map` in a `Holder` to trick the reverse mode library
72+ * into not thinking this is a map. The `.array().matrix()` inside the
73+ * holder is so that the holder thinks it is returning an expression.
6774 * @tparam T `std::vector` type.
6875 * @param a Specified vector.
6976 * @return input converted to a column vector.
@@ -74,13 +81,10 @@ inline auto as_column_vector_or_scalar(T&& a) {
7481 using optionally_const_vector
7582 = std::conditional_t <std::is_const<std::remove_reference_t <T>>::value,
7683 const plain_vector, plain_vector>;
84+
7785 using T_map = Eigen::Map<optionally_const_vector>;
78- if constexpr (std::is_rvalue_reference_v<T&&>) {
79- return make_holder ([](auto && x) { return T_map (x.data (), x.size ()); },
80- std::forward<T>(a));
81- } else {
82- return plain_vector (T_map (a.data (), a.size ()));
83- }
86+ return make_holder ([](auto && x) { return T_map (x.data (), x.size ()).array ().matrix (); },
87+ std::forward<T>(a));
8488}
8589
8690} // namespace math
0 commit comments