Automatic Differentiation
 
Loading...
Searching...
No Matches
stan::math::internal::lazy_select_evaluator< TernaryOp, Arg1, Arg2, Arg3 > Struct Template Reference

Detailed Description

template<typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
struct stan::math::internal::lazy_select_evaluator< TernaryOp, Arg1, Arg2, Arg3 >

Evaluator for .select() expressions that evaluates only the branch chosen by the condition, restoring the Eigen 3.x Select semantics.

Eigen 5 implements select as a CwiseTernaryOp whose evaluator computes the then-branch, else-branch, and condition coefficients eagerly before applying the cond == 0 ? b : a functor. For plain arithmetic scalars the discarded branch is dead arithmetic, but for reverse-mode autodiff scalars evaluating a branch has a side effect: it allocates varis on the autodiff stack. chain() runs on every vari during the reverse pass, including orphans whose adjoint is zero, so an orphan whose chain rule multiplies its adjoint by a value-derived quantity (e.g. exp: adj * exp(val) with val = +INF) injects 0 * INF = NaN into the adjoint of a live input. Distribution code throughout stan/math/prim/prob relies on .select() to guard exactly such numerically dangerous expressions.

This base class provides the lazy coefficient access; the Eigen::internal::ternary_evaluator partial specializations for scalar_boolean_select_op on var (rev/core/Eigen_NumTraits.hpp) and fvar<T> (fwd/fun/Eigen_NumTraits.hpp) derive from it. Specializing ternary_evaluator also intercepts Eigen's fused (a < b).select(c, d) evaluator, which derives from ternary_evaluator after rebuilding the expression.

The packet (vectorized) path needs no override: for autodiff scalars functor_traits<scalar_boolean_select_op>::PacketAccess is false, and Flags below additionally masks out PacketAccessBit.

Template Parameters
TernaryOpthe select functor, Eigen::internal::scalar_boolean_select_op<Scalar, Scalar, CondScalar>
Arg1type of the then-branch expression
Arg2type of the else-branch expression
Arg3type of the condition expression

Definition at line 46 of file lazy_select_evaluator.hpp.

#include <lazy_select_evaluator.hpp>

+ Inheritance diagram for stan::math::internal::lazy_select_evaluator< TernaryOp, Arg1, Arg2, Arg3 >:

Classes

struct  Data
 

Public Types

enum  {
  CoeffReadCost ,
  Arg1Flags = Eigen::internal::evaluator<Arg1>::Flags ,
  Arg2Flags = Eigen::internal::evaluator<Arg2>::Flags ,
  Arg3Flags = Eigen::internal::evaluator<Arg3>::Flags ,
  StorageOrdersAgree ,
  Flags0 ,
  Flags = (Flags0 & ~Eigen::RowMajorBit) | (Arg1Flags & Eigen::RowMajorBit) ,
  Alignment
}
 
using XprType = Eigen::CwiseTernaryOp< TernaryOp, Arg1, Arg2, Arg3 >
 
using CoeffReturnType = typename XprType::CoeffReturnType
 
using CondScalar = typename Arg3::Scalar
 

Public Member Functions

 lazy_select_evaluator (const XprType &xpr)
 
CoeffReturnType coeff (Eigen::Index row, Eigen::Index col) const
 
CoeffReturnType coeff (Eigen::Index index) const
 

Protected Attributes

Data m_d
 

The documentation for this struct was generated from the following file: