Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:17:12

0001 //
0002 // APFEL++ 2017
0003 //
0004 // Author: Valerio Bertone: valerio.bertone@cern.ch
0005 //
0006 
0007 #pragma once
0008 
0009 #include "apfel/tools.h"
0010 
0011 #include <functional>
0012 #include <iostream>
0013 
0014 namespace apfel
0015 {
0016   /**
0017    * @brief The term structure that contains all the objects of a
0018    * single term of a double object.
0019    */
0020   template <class V, class U = V>
0021   struct term
0022   {
0023     double coefficient;
0024     V      object1;
0025     U      object2;
0026   };
0027 
0028   /**
0029    * @brief The DoubleObject class is a collection of pairs of single
0030    * objects (Distributions or Operators) accompained by a
0031    * multiplicative constant. This mother class provides the basic
0032    * ingredients for the computation double convolutions required in
0033    * SIDIS and DY.
0034    */
0035   template<class T, class U = T>
0036   class DoubleObject
0037   {
0038   public:
0039     /**
0040      * @name Constructors
0041      * List of constructors.
0042      */
0043     ///@{
0044     /**
0045      * @brief The DoubleObject constructor.
0046      */
0047     DoubleObject();
0048 
0049     /**
0050      * @brief The DoubleObject constructor.
0051      * @param terms: vector of term objects of the T kind
0052      */
0053     DoubleObject(std::vector<term<T, U>> const& terms);
0054     ///@}
0055 
0056     /**
0057      * @brief Function to add more terms.
0058      * @param newterm: new term to be appended to the vector of terms
0059      */
0060     void AddTerm(term<T, U> const& newterm);
0061 
0062     /**
0063      * @brief Function to get the terms.
0064      * @return The vector of terms
0065      */
0066     std::vector<term<T, U>> GetTerms() const { return _terms; };
0067 
0068     /**
0069      * @brief Function that evaluates the double distribution.
0070      * @param x: value of the first variable
0071      * @param z: value of the second variable
0072      * @return The value of the double distribution in (x, z)
0073      */
0074     double Evaluate(double const& x, double const& z) const;
0075 
0076     /**
0077      * @brief Function that evaluates the double object in the first
0078      * variable leaving the second undetermined.
0079      * @param x: value of the first variable
0080      */
0081     T Evaluate1(double const& x) const;
0082 
0083     /**
0084      * @brief Function that evaluates the double object in the second
0085      * variable leaving the first undetermined.
0086      * @param z: value of the second variable
0087      */
0088     U Evaluate2(double const& z) const;
0089 
0090     /**
0091      * @brief Function that evaluates the derivative of the double
0092      * distribution.
0093      * @param x: value of the first variable
0094      * @param z: value of the second variable
0095      * @return The value of the derivative of the double distribution
0096      * in (x, z)
0097      */
0098     double Derive(double const& x, double const& z) const;
0099 
0100     /**
0101      * @brief Function that evaluates the derivative of the double
0102      * object in the first variable leaving the second undetermined.
0103      * @param x: value of the first variable
0104      */
0105     T Derive1(double const& x) const;
0106 
0107     /**
0108      * @brief Function that evaluates the derivative of the double
0109      * object in the second variable leaving the first undetermined.
0110      * @param z: value of the second variable
0111      */
0112     U Derive2(double const& z) const;
0113 
0114     /**
0115      * @brief Function that evaluates the integral of the double
0116      * distribution.
0117      * @param xl: value of the lower bound of the of the first variable
0118      * @param xu: value of the upper bound of the of the first variable
0119      * @param zl: value of the lower bound of the of the second variable
0120      * @param zu: value of the upper bound of the of the second variable
0121      * @return The value of the integral of the double distribution
0122      */
0123     double Integrate(double const& xl, double const& xu, double const& zl, double const& zu) const;
0124 
0125     /**
0126      * @brief Function that evaluates the integral of the double
0127      * object in the first variable leaving the second undetermined.
0128      * @param xl: value of the lower bound of the of the first variable
0129      * @param xu: value of the upper bound of the of the first variable
0130      */
0131     T Integrate1(double const& xl, double const& xu) const;
0132 
0133     /**
0134      * @brief Function that evaluates the derivative of the double
0135      * object in the second variable leaving the first undetermined.
0136      * @param zl: value of the lower bound of the of the second variable
0137      * @param zu: value of the upper bound of the of the second variable
0138      */
0139     U Integrate2(double const& zl, double const& zu) const;
0140 
0141     /**
0142      * @brief Function that evaluates the integral of the double
0143      * distribution.
0144      * @param xl: value of the lower bound of the of the first variable
0145      * @param xu: value of the upper bound of the of the first variable
0146      * @param zlx: function that delimits the lower bound of the integral in z as a function of x
0147      * @param zux: function that delimits the upper bound of the integral in z as a function of x
0148      * @return The value of the integral of the double distribution
0149      */
0150     double Integrate(double const& xl, double const& xu, std::function<double(double const&)> zlx, std::function<double(double const&)> zux) const;
0151 
0152     /**
0153      * @brief Function that evaluates the integral of the double
0154      * distribution.
0155      * @param xlz: function that delimits the lower bound of the integral in x as a function of z
0156      * @param xuz: function that delimits the upper bound of the integral in x as a function of z
0157      * @param zl: value of the lower bound of the of the second variable
0158      * @param zu: value of the upper bound of the of the seconf variable
0159      * @return The value of the integral of the double distribution
0160      */
0161     double Integrate(std::function<double(double const&)> xlz, std::function<double(double const&)> xuz, double const& zl, double const& zu) const;
0162 
0163     /**
0164      * @brief This function multiplies the objects of the single terms
0165      * of the DoubleObject by a respective function.
0166      * @param fx: that function that multiplies the first distribution
0167      * @param fz: that function that multiplies the second distribution
0168      */
0169     DoubleObject<T, U>& MultiplyBy(std::function<double(double const&)> const& fx, std::function<double(double const&)> const& fz);
0170 
0171     /**
0172      * @name Binary operators
0173      */
0174     ///@{
0175     template<class V> DoubleObject<V> operator *= (DoubleObject<V> const& o) const;
0176     DoubleObject<T, U>& operator *= (double const& s);                               //!< this *= scalar
0177     DoubleObject<T, U>& operator *= (DoubleObject<T, U> const& o);                   //!< this *= DoubleObject
0178     DoubleObject<T, U>& operator *= (std::function<double(double const&)> const& f); //!< this *= Function of the integration variable
0179     DoubleObject<T, U>& operator /= (double const& s);                               //!< this /= scalar
0180     DoubleObject<T, U>& operator += (DoubleObject<T, U> const& o);                   //!< this += DoubleObject
0181     DoubleObject<T, U>& operator -= (DoubleObject<T, U> const& o);                   //!< this -= DoubleObject
0182     ///@}
0183 
0184     /**
0185      * @brief Print the Operator object
0186      */
0187     void Print() const { std::cout << *this << std::endl; }
0188 
0189   private:
0190     std::vector<term<T, U>> _terms;
0191 
0192     template<class V, class W>
0193     friend std::ostream& operator << (std::ostream& os, DoubleObject<V, W> const& dob);
0194   };
0195 
0196   /**
0197    * @name Ternary operators
0198    */
0199   ///@{
0200   template<class A, class B>
0201   DoubleObject<B> operator * (DoubleObject<A> lhs, DoubleObject<B> const& rhs) { return lhs *= rhs; }
0202 
0203   template<class T, class U>
0204   DoubleObject<T, U> operator * (double const& s, DoubleObject<T, U> rhs) { return rhs *= s; }
0205 
0206   template<class T, class U>
0207   DoubleObject<T, U> operator * (DoubleObject<T, U> lhs, double const& s) { return lhs *= s; }
0208 
0209   template<class T, class U>
0210   DoubleObject<T, U> operator / (DoubleObject<T, U> lhs, double const& s) { return lhs /= s; }
0211 
0212   template<class T, class U>
0213   DoubleObject<T, U> operator * (DoubleObject<T, U> lhs, DoubleObject<T, U> const& rhs) { return lhs *= rhs; }
0214 
0215   template<class T, class U>
0216   DoubleObject<T, U> operator + (DoubleObject<T, U> lhs, DoubleObject<T, U> const& rhs) { return lhs += rhs; }
0217 
0218   template<class T, class U>
0219   DoubleObject<T, U> operator - (DoubleObject<T, U> lhs, DoubleObject<T, U> const& rhs) { return lhs -= rhs; }
0220   ///@}
0221 
0222   /**
0223    * @brief Method which prints DoubleObject with cout <<.
0224    */
0225   template<class T, class U>
0226   std::ostream& operator << (std::ostream& os, DoubleObject<T, U> const& dob);
0227 }