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...>>
256 CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
259 Flags = evaluator<ArgTypeNestedCleaned>::Flags,
260 Alignment = evaluator<ArgTypeNestedCleaned>::Alignment,
267 : m_argImpl(
std::forward<
XprType>(xpr).m_arg) {}
271 return m_argImpl.coeff(row, col);
274 return m_argImpl.coeff(index);
278 return m_argImpl.coeffRef(row, col);
281 return m_argImpl.coeffRef(index);
284 template <
int LoadMode,
typename PacketType>
285 EIGEN_STRONG_INLINE PacketType
packet(Index row, Index col)
const {
286 return m_argImpl.template packet<LoadMode, PacketType>(row, col);
288 template <
int LoadMode,
typename PacketType>
289 EIGEN_STRONG_INLINE PacketType
packet(Index index)
const {
290 return m_argImpl.template packet<LoadMode, PacketType>(index);
293 template <
int StoreMode,
typename PacketType>
295 const PacketType& x) {
296 return m_argImpl.template writePacket<StoreMode, PacketType>(row, col, x);
298 template <
int StoreMode,
typename PacketType>
299 EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketType& x) {
300 return m_argImpl.template writePacket<StoreMode, PacketType>(index, x);
320template <
typename T,
typename... Ptrs,
321 std::enable_if_t<
sizeof...(Ptrs) >= 1>* =
nullptr>
323 return Holder<T, Ptrs...>(std::forward<T>(
arg), pointers...);
328 if constexpr (std::is_rvalue_reference<T&&>::value) {
329 return std::decay_t<T>(std::forward<T>(
arg));
331 return std::forward<T>(
arg);
349 return std::make_tuple();
352 std::enable_if_t<!(Eigen::internal::traits<std::decay_t<T>>::Flags
353 & Eigen::NestByRefBit)>* =
nullptr>
356 return std::make_tuple();
369template <
typename T, require_t<std::is_rvalue_reference<T&&>>* =
nullptr,
371 static_cast<
bool>(Eigen::
internal::traits<std::decay_t<T>>::Flags&
372 Eigen::NestByRefBit)>* =
nullptr>
374 res =
new T(std::move(a));
375 return std::make_tuple(res);
377template <
typename T, require_t<std::is_rvalue_reference<T&&>>* =
nullptr,
378 require_not_eigen_t<T>* =
nullptr>
379inline auto holder_handle_element(T&& a, T*& res) {
380 res =
new T(std::move(a));
381 return std::make_tuple(res);
395template <
typename T, std::size_t... Is,
typename... Args>
397 T&& expr, std::index_sequence<Is...>,
const std::tuple<Args*...>& ptrs) {
398 return holder(std::forward<T>(expr), std::get<Is>(ptrs)...);
410template <
typename F, std::size_t... Is,
typename... Args>
413 std::tuple<std::remove_reference_t<Args>*...> res;
414 auto ptrs = std::tuple_cat(
417 std::forward<F>(func)(*std::get<Is>(res)...),
418 std::make_index_sequence<std::tuple_size<
decltype(ptrs)>::value>(), ptrs);
435template <
typename F,
typename... Args,
439 std::make_index_sequence<
sizeof...(Args)>(),
440 std::forward<Args>(args)...);
453template <
typename F,
typename... Args,
456 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 expresssions.
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 ...
evaluator< ArgTypeNestedCleaned > m_argImpl
stan::math::Holder< ArgType, Ptrs... > XprType
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
CoeffReturnType coeff(Index row, Index col) const
remove_all< ArgType >::type ArgTypeNestedCleaned
PacketType packet(Index index) const
PacketType packet(Index row, Index col) const
Scalar & coeffRef(Index row, Index col)
XprType::CoeffReturnType CoeffReturnType
evaluator(const XprType &xpr)
ArgType::StorageKind StorageKind
traits< ArgType >::XprKind XprKind
ArgType::StorageIndex StorageIndex