1 #ifndef STAN_MATH_PRIM_FUN_PROMOTE_ELEMENTS_HPP 2 #define STAN_MATH_PRIM_FUN_PROMOTE_ELEMENTS_HPP 3 4 #include <stan/math/prim/meta.hpp> 5 #include <stan/math/prim/fun/Eigen.hpp> 6 #include <cstddef> 7 #include <vector> 8 9 namespace stan { 10 namespace math { 11 12 /** 13 * Struct with static function for elementwise type promotion. 14 * 15 * <p>This base implementation promotes one scalar value to another. 16 * 17 * @tparam T type of promoted element 18 * @tparam S type of input element, must be assignable to T 19 */ 20 template <typename T, typename S> 21 struct promote_elements { 22 /** 23 * Return input element. 24 * 25 * @param u input of type S, assignable to type T 26 * @returns input as type T 27 */ promotestan::math::promote_elements28 inline static T promote(const S& u) { return u; } 29 }; 30 31 /** 32 * Struct with static function for elementwise type promotion. 33 * 34 * <p>This specialization promotes scalar values of the same type. 35 * 36 * @tparam T type of elements 37 */ 38 template <typename T> 39 struct promote_elements<T, T> { 40 /** 41 * Return input element. 42 * 43 * @param u input of type T 44 * @returns input as type T 45 */ promotestan::math::promote_elements46 inline static const T& promote(const T& u) { return u; } 47 }; 48 49 /** 50 * Struct with static function for elementwise type promotion. 51 * 52 * <p>This specialization promotes vector elements of different types 53 * which must be compatible with promotion. 54 * 55 * @tparam T type of promoted elements 56 * @tparam S type of input elements, must be assignable to T 57 */ 58 template <typename T, typename S> 59 struct promote_elements<std::vector<T>, std::vector<S> > { 60 /** 61 * Return input vector of type S as vector of type T. 62 * 63 * @param u vector of type S, assignable to type T 64 * @returns vector of type T 65 */ promotestan::math::promote_elements66 inline static std::vector<T> promote(const std::vector<S>& u) { 67 std::vector<T> t; 68 t.reserve(u.size()); 69 for (size_t i = 0; i < u.size(); ++i) { 70 t.push_back(promote_elements<T, S>::promote(u[i])); 71 } 72 return t; 73 } 74 }; 75 76 /** 77 * Struct with static function for elementwise type promotion. 78 * 79 * <p>This specialization promotes vector elements of the same type. 80 * 81 * @tparam T type of elements 82 */ 83 template <typename T> 84 struct promote_elements<std::vector<T>, std::vector<T> > { 85 /** 86 * Return input vector. 87 * 88 * @param u vector of type T 89 * @returns vector of type T 90 */ promotestan::math::promote_elements91 inline static const std::vector<T>& promote(const std::vector<T>& u) { 92 return u; 93 } 94 }; 95 96 /** 97 * Struct with static function for elementwise type promotion. 98 * 99 * <p>This specialization promotes matrix elements of different types 100 * which must be compatible with promotion. 101 * 102 * @tparam T type of promoted elements 103 * @tparam S type of input elements, must be assignable to T 104 * @tparam R number of rows, can be Eigen::Dynamic 105 * @tparam C number of columns, can be Eigen::Dynamic 106 */ 107 template <typename T, typename S, int R, int C> 108 struct promote_elements<Eigen::Matrix<T, R, C>, Eigen::Matrix<S, R, C> > { 109 /** 110 * Return input matrix of type S as matrix of type T. 111 * 112 * @param u matrix of type S, assignable to type T 113 * @returns matrix of type T 114 */ promotestan::math::promote_elements115 inline static Eigen::Matrix<T, R, C> promote( 116 const Eigen::Matrix<S, R, C>& u) { 117 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> t(u.rows(), u.cols()); 118 for (int i = 0; i < u.size(); ++i) { 119 t(i) = promote_elements<T, S>::promote(u(i)); 120 } 121 return t; 122 } 123 }; 124 125 /** 126 * Struct with static function for elementwise type promotion. 127 * 128 * <p>This specialization promotes matrix elements of the same type. 129 * 130 * @tparam T type of elements in the matrices 131 * @tparam R number of rows, can be Eigen::Dynamic 132 * @tparam C number of columns, can be Eigen::Dynamic 133 */ 134 template <typename T, int R, int C> 135 struct promote_elements<Eigen::Matrix<T, R, C>, Eigen::Matrix<T, R, C> > { 136 /** 137 * Return input matrix. 138 * 139 * @param u matrix of type T 140 * @returns matrix of type T 141 */ promotestan::math::promote_elements142 inline static const Eigen::Matrix<T, R, C>& promote( 143 const Eigen::Matrix<T, R, C>& u) { 144 return u; 145 } 146 }; 147 148 } // namespace math 149 } // namespace stan 150 151 #endif 152