1#ifndef STAN_MATH_PRIM_FUN_HOLDER_HPP
2#define STAN_MATH_PRIM_FUN_HOLDER_HPP
69template <
class ArgType,
typename... Ptrs>
78template <
class ArgType,
typename... Ptrs>
83 typedef typename ArgType::Scalar
Scalar;
87 Flags = (ArgType::Flags
88 & (RowMajorBit | LvalueBit | LinearAccessBit | DirectAccessBit
89 | PacketAccessBit | NoPreferredStorageOrderBit))
91 RowsAtCompileTime = ArgType::RowsAtCompileTime,
92 ColsAtCompileTime = ArgType::ColsAtCompileTime,
93 MaxRowsAtCompileTime = ArgType::MaxRowsAtCompileTime,
94 MaxColsAtCompileTime = ArgType::MaxColsAtCompileTime,
95 InnerStrideAtCompileTime = ArgType::InnerStrideAtCompileTime,
96 OuterStrideAtCompileTime = ArgType::OuterStrideAtCompileTime
107template <
typename ArgType,
typename... Ptrs>
123 typename F,
typename... Args,
137template <
typename F,
typename... Args,
147template <
typename ArgType,
typename... Ptrs>
149 :
public Eigen::internal::dense_xpr_base<Holder<ArgType, Ptrs...>>::type {
151 typedef typename Eigen::internal::ref_selector<
Holder<ArgType, Ptrs...>>::type
153 typename Eigen::internal::ref_selector<ArgType>::non_const_type
m_arg;
177 template <
typename T, require_eigen_t<T>* =
nullptr>
191 m_arg = std::move(other.m_arg);
196template <
typename T, require_holder_t<T>* =
nullptr>
200template <
typename T, require_holder_t<T>* =
nullptr>
205template <
typename T,
typename Other, require_holder_t<T>* =
nullptr,
206 require_holder_t<Other>* =
nullptr>
209 [](
auto&&
arg,
auto&& other_) {
210 return arg - std::forward<decltype(other_)>(other_);
212 std::forward<T>(h).m_arg, std::forward<Other>(other));
214template <
typename T,
typename Other, require_holder_t<T>* =
nullptr,
215 require_holder_t<Other>* =
nullptr>
218 [](
auto&&
arg,
auto&& other_) {
219 return arg + std::forward<decltype(other_)>(other_);
221 std::forward<T>(h).m_arg, std::forward<Other>(other));
223template <
typename T,
typename Other, require_holder_t<T>* =
nullptr,
224 require_holder_t<Other>* =
nullptr>
227 [](
auto&&
arg,
auto&& other_) {
228 return arg * std::forward<decltype(other_)>(other_);
230 std::forward<T>(h).m_arg, std::forward<Other>(other));
232template <
typename T,
typename Other, require_holder_t<T>* =
nullptr,
233 require_holder_t<Other>* =
nullptr>
236 [](
auto&&
arg,
auto&& other_) {
237 return arg / std::forward<decltype(other_)>(other_);
239 std::forward<T>(h).m_arg, std::forward<Other>(other));
248template <
typename ArgType,
typename... Ptrs>
249struct evaluator<
stan::math::Holder<ArgType, Ptrs...>>
250 : evaluator_base<stan::math::Holder<ArgType, Ptrs...>> {
257 IsRowMajor = XprType::IsRowMajor,
258 IsColMajor = !IsRowMajor,
259 IsVectorAtCompileTime = XprType::IsVectorAtCompileTime,
260 RowsAtCompileTime = XprType::RowsAtCompileTime,
261 ColsAtCompileTime = XprType::ColsAtCompileTime,
263 CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
264 Flags = evaluator<ArgTypeNestedCleaned>::Flags,
265 Alignment = evaluator<ArgTypeNestedCleaned>::Alignment,
269 OuterStrideAtCompileTime
270 = IsVectorAtCompileTime
272 : (IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime)
279 : m_argImpl(
std::forward<
XprType>(xpr).m_arg) {}
284 return m_argImpl.coeff(row, col);
286 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType
288 return m_argImpl.coeff(index);
292 return m_argImpl.coeffRef(row, col);
295 return m_argImpl.coeffRef(index);
298 template <
int LoadMode,
typename PacketType>
299 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType
packet(Index row,
301 return m_argImpl.template packet<LoadMode, PacketType>(row, col);
303 template <
int LoadMode,
typename PacketType>
304 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType
packet(Index index)
const {
305 return m_argImpl.template packet<LoadMode, PacketType>(index);
308 template <
int StoreMode,
typename PacketType>
309 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
310 const PacketType& x) {
311 return m_argImpl.template writePacket<StoreMode, PacketType>(row, col, x);
313 template <
int StoreMode,
typename PacketType>
314 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index,
315 const PacketType& x) {
316 return m_argImpl.template writePacket<StoreMode, PacketType>(index, x);
319 template <
int LoadMode,
typename PacketType>
320 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType
322 return m_argImpl.template packetSegment<LoadMode, PacketType>(row, col,
326 template <
int LoadMode,
typename PacketType>
327 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType
329 return m_argImpl.template packetSegment<LoadMode, PacketType>(index, begin,
333 template <
int StoreMode,
typename PacketType>
335 Index row, Index col,
const PacketType& x, Index begin, Index count) {
336 return m_argImpl.template writePacketSegment<StoreMode, PacketType>(
337 row, col, x, begin, count);
340 template <
int StoreMode,
typename PacketType>
342 Index index,
const PacketType& x, Index begin, Index count) {
343 return m_argImpl.template writePacketSegment<StoreMode, PacketType>(
344 index, x, begin, count);
364template <
typename T,
typename... Ptrs,
365 std::enable_if_t<
sizeof...(Ptrs) >= 1>* =
nullptr>
367 return Holder<T, Ptrs...>(std::forward<T>(
arg), pointers...);
372 if constexpr (std::is_rvalue_reference<T&&>::value) {
373 return std::decay_t<T>(std::forward<T>(
arg));
375 return std::forward<T>(
arg);
393 return std::make_tuple();
396 std::enable_if_t<!(Eigen::internal::traits<std::decay_t<T>>::Flags
397 & Eigen::NestByRefBit)>* =
nullptr>
400 return std::make_tuple();
413template <
typename T, require_t<std::is_rvalue_reference<T&&>>* =
nullptr,
415 static_cast<
bool>(Eigen::
internal::traits<std::decay_t<T>>::Flags&
416 Eigen::NestByRefBit)>* =
nullptr>
418 res =
new T(std::move(a));
419 return std::make_tuple(res);
421template <
typename T, require_t<std::is_rvalue_reference<T&&>>* =
nullptr,
422 require_not_eigen_t<T>* =
nullptr>
423inline auto holder_handle_element(T&& a, T*& res) {
424 res =
new T(std::move(a));
425 return std::make_tuple(res);
439template <
typename T, std::size_t... Is,
typename... Args>
441 T&& expr, std::index_sequence<Is...>,
const std::tuple<Args*...>& ptrs) {
442 return holder(std::forward<T>(expr), std::get<Is>(ptrs)...);
454template <
typename F, std::size_t... Is,
typename... Args>
457 std::tuple<std::remove_reference_t<Args>*...> res;
458 auto ptrs = std::tuple_cat(
461 std::forward<F>(func)(*std::get<Is>(res)...),
462 std::make_index_sequence<std::tuple_size<
decltype(ptrs)>::value>(), ptrs);
479template <
typename F,
typename... Args,
483 std::make_index_sequence<
sizeof...(Args)>(),
484 std::forward<Args>(args)...);
497template <
typename F,
typename... Args,
500 return std::forward<F>(func)(std::forward<Args>(args)...);
Eigen::internal::ref_selector< Holder< ArgType, Ptrs... > >::type Nested
Holder< ArgType, Ptrs... > & operator=(const Holder< ArgType, Ptrs... > &other)
Eigen::Index outerStride() const
Eigen::Index rows() const
Eigen::Index innerStride() const
Holder< ArgType, Ptrs... > & operator=(Holder< ArgType, Ptrs... > &&other)
Holder(const Holder< ArgType, Ptrs... > &)=default
Holder< ArgType, Ptrs... > & operator=(const T &other)
Assignment operator assigns expressions.
Eigen::Index cols() const
std::tuple< std::unique_ptr< Ptrs >... > m_unique_ptrs
const auto * data() const
Eigen::internal::ref_selector< ArgType >::non_const_type m_arg
Holder(Holder< ArgType, Ptrs... > &&)=default
Holder(ArgType &&arg, Ptrs *... pointers)
require_not_t< is_plain_type< std::decay_t< T > > > require_not_plain_type_t
Require type does not satisfy is_plain_type.
require_t< is_plain_type< std::decay_t< T > > > require_plain_type_t
Require type satisfies is_plain_type.
(Expert) Numerical traits for algorithmic differentiation variables.
auto make_holder_impl_construct_object(T &&expr, std::index_sequence< Is... >, const std::tuple< Args *... > &ptrs)
Second step in implementation of construction holder from a functor.
auto holder_handle_element(T &a, T *&res)
Handles single element (moving rvalue non-expressions to heap) for construction of holder or holder_c...
auto make_holder_impl(F &&func, std::index_sequence< Is... >, Args &&... args)
Implementation of construction holder from a functor.
fvar< T > operator/(const fvar< T > &x1, const fvar< T > &x2)
Return the result of dividing the first argument by the second.
fvar< T > operator-(const fvar< T > &x1, const fvar< T > &x2)
Return the difference of the specified arguments.
fvar< T > operator*(const fvar< T > &x, const fvar< T > &y)
Return the product of the two arguments.
fvar< T > arg(const std::complex< fvar< T > > &z)
Return the phase angle of the complex argument.
auto make_holder(F &&func, Args &&... args)
Calls given function with given arguments.
fvar< T > operator+(const fvar< T > &x1, const fvar< T > &x2)
Return the sum of the specified forward mode addends.
Ptrs holder(T &&arg, Ptrs *... pointers)
require_t< is_holder< T > > require_holder_t
constexpr bool is_holder_v
std::enable_if_t< Check::value > require_t
If condition is true, template is enabled.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
typename XprType::CoeffReturnType CoeffReturnType
evaluator< ArgTypeNestedCleaned > m_argImpl
void writePacket(Index row, Index col, const PacketType &x)
void writePacket(Index index, const PacketType &x)
Scalar & coeffRef(Index index)
CoeffReturnType coeff(Index index) const
typename XprType::Scalar Scalar
CoeffReturnType coeff(Index row, Index col) const
typename remove_all< ArgType >::type ArgTypeNestedCleaned
void writePacketSegment(Index row, Index col, const PacketType &x, Index begin, Index count)
void writePacketSegment(Index index, const PacketType &x, Index begin, Index count)
PacketType packet(Index index) const
PacketType packetSegment(Index row, Index col, Index begin, Index count) const
PacketType packetSegment(Index index, Index begin, Index count) const
PacketType packet(Index row, Index col) const
Scalar & coeffRef(Index row, Index col)
evaluator(const XprType &xpr)
ArgType::StorageKind StorageKind
traits< ArgType >::XprKind XprKind
ArgType::StorageIndex StorageIndex