Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:19:07

0001 // TRENTO: Reduced Thickness Event-by-event Nuclear Topology
0002 // Copyright 2015 Jonah E. Bernhard, J. Scott Moreland
0003 // TRENTO3D: Three-dimensional extension of TRENTO by Weiyao Ke
0004 // MIT License
0005 
0006 #ifndef FAST_EXP_H
0007 #define FAST_EXP_H
0008 
0009 #include <cmath>
0010 #include <stdexcept>
0011 #include <vector>
0012 
0013 namespace trento {
0014 
0015 /// \rst
0016 /// Fast exponential approximation, to be used as a drop-in replacement for
0017 /// ``std::exp`` when it will be evaluated many times within a fixed range.
0018 /// Works by pre-tabulating exp() values and exploiting the leading-order Taylor
0019 /// expansion; for step size `dx` the error is `\mathcal O(dx^2)`.
0020 ///
0021 /// Example::
0022 ///
0023 ///   FastExp<double> fast_exp{0., 1., 11};  // tabulate at 0.0, 0.1, 0.2, ...
0024 ///   fast_exp(0.50);  // evaluate at table point -> exact result
0025 ///   fast_exp(0.55);  // midway between points -> worst-case error
0026 ///
0027 /// \endrst
0028 template <typename T = double>
0029 class FastExp {
0030  public:
0031   /// Pre-tabulate exp() values from \c xmin to \c xmax in \c nsteps
0032   /// evenly-spaced intervals.
0033   FastExp(T xmin, T xmax, std::size_t nsteps);
0034 
0035   /// Evaluate the exponential at \em x (must be within range).
0036   T operator()(T x) const;
0037 
0038  private:
0039   /// Minimum and maximum.
0040   const T xmin_, xmax_;
0041 
0042   /// Step size.
0043   const T dx_;
0044 
0045   /// Tabulated exp() values.
0046   std::vector<T> table_;
0047 };
0048 
0049 template <typename T>
0050 FastExp<T>::FastExp(T xmin, T xmax, std::size_t nsteps)
0051     : xmin_(xmin),
0052       xmax_(xmax),
0053       dx_((xmax-xmin)/(nsteps-1)),
0054       table_(nsteps) {
0055   // Tabulate evenly-spaced exp() values.
0056   for (std::size_t i = 0; i < nsteps; ++i)
0057     table_[i] = std::exp(xmin_ + i*dx_);
0058 }
0059 
0060 template <typename T>
0061 inline T FastExp<T>::operator()(T x) const {
0062 #ifndef NDEBUG
0063   if (x < xmin_ || x > xmax_)
0064     throw std::out_of_range{"argument must be within [xmin, xmax]"};
0065 #endif
0066 
0067   // Determine the table index of the nearest tabulated value.
0068   auto index = static_cast<std::size_t>((x - xmin_)/dx_ + .5);
0069 
0070   // Compute the leading-order Taylor expansion.
0071   // exp(x) = exp(x0) * exp(x-x0) =~ exp(x0) * (1 + x - x0)
0072   // exp(x0) = table_[index]
0073   // x0 = xmin_ + index*dx_
0074   return table_[index] * (1. + x - xmin_ - index*dx_);
0075 }
0076 
0077 }  // namespace trento
0078 
0079 #endif  // FAST_EXP_H