#ifndef __JTOOLS__JTOOLSTOOLKIT__ #define __JTOOLS__JTOOLSTOOLKIT__ #include "JLang/JException.hh" #include "JLang/JBool.hh" #include "JMath/JZero.hh" #include "JTools/JAssembler.hh" #include "JTools/JElement.hh" #include "JTools/JCollection.hh" #include "JTools/JGarbageCollection.hh" #include "JTools/JMultiFunction.hh" #include "JTools/JMultiHistogram.hh" #include "JTools/JFunctionalMap.hh" /** * \file * * This include file contains various recursive methods to operate on multi-dimensional collections. * \author mdejong */ namespace JTOOLS {} namespace JPP { using namespace JTOOLS; } /** * Auxiliary classes and methods for multi-dimensional interpolations and histograms. */ namespace JTOOLS { using JLANG::JException; using JLANG::JEmptyCollection; using JLANG::JDivisionByZero; using JLANG::JBool; /** * Conversion of data points to cumulative probability distribition (CDF). * * Note that the data type of the input container should be preserved * so that the corresponding method integrate() is used. * * \param input collection * \param output mappable collection * \param eps minimal step size * \return integral value */ template inline typename JContainer_t::ordinate_type makeCDF(const JContainer_t& input, JMappableCollection& output, const typename JContainer_t::ordinate_type eps = JMATH::zero) { typedef typename JContainer_t::ordinate_type ordinate_type; typedef typename JContainer_t::abscissa_type abscissa_type; typedef JElement2D element_type; typedef JCollection buffer_type; if (input.getSize() > 1) { buffer_type buffer; const ordinate_type V = integrate(input, buffer); if (V == ordinate_type(JMATH::zero)) { THROW(JDivisionByZero, "Method makeCDF(): integral equals zero."); } output.clear(); typename buffer_type::const_iterator i = buffer.begin(); for ( ; i != buffer.end() && i->getY() <= 0.5 * eps * V; ++i) {} if (i != buffer.end()) { // force first point at (0, ymin) JKey_t x = 0.0; JValue_t y = i->getX(); output.put(x, y); JKey_t xmax = x; JValue_t ymax = y; for (++i; i != buffer.end(); ++i) { x = i->getY() / V; y = i->getX(); if (x > xmax) { ymax = y; if (x > xmax + eps) { output.put(x, y); xmax = x; } } } // force last point at (1, ymax) x = 1.0; y = ymax; output.put(x,y); } else { THROW(JDivisionByZero, "Method makeCDF(): no remaining data."); } return V; } else { THROW(JEmptyCollection, "Method makeCDF(): not sufficient input data."); } } /** * Get integral of input data points. * * \param input input data * \return integral value */ template inline typename JContainer_t::ordinate_type getIntegral(const JContainer_t& input) { JGarbageCollection garbage; return integrate(input, garbage); } /** * Auxiliary method to get integral of input data points. * * \param input input data * \return integral value */ template class JMap_t, class JTail_t> inline typename JFunction_t::ordinate_type getIntegral(const JMultiMap, typename JFunction_t::distance_type>& input) { typedef typename JFunction_t::abscissa_type abscissa_type; typedef typename JFunction_t::ordinate_type ordinate_type; typedef typename JFunction_t::distance_type distance_type; typedef typename JFunctionalMap::template function_type buffer_type; typedef JMultiMap, distance_type> multimap_type; static buffer_type buffer; buffer.configure(input); typename buffer_type::iterator out = buffer.begin(); for (typename multimap_type::const_iterator in = input.begin(); in != input.end(); ++in, ++out) { out->getY() = getIntegral(in->getY()); } buffer.compile(); return getIntegral(buffer); } /** * Get integral of input data points. * * \param input input data * \return integral value */ template class JMap_t, class JTail_t> inline typename JFunction_t::ordinate_type getIntegral(const JMultiFunction, typename JFunction_t::distance_type>& input) { typedef typename JFunction_t::abscissa_type abscissa_type; typedef typename JFunction_t::ordinate_type ordinate_type; typedef typename JFunction_t::distance_type distance_type; typedef typename JFunctionalMap::template function_type buffer_type; typedef JMultiFunction, distance_type> multifunction_type; buffer_type buffer; for (typename multifunction_type::const_iterator i = input.begin(); i != input.end(); ++i) { buffer.put(i->getX(), getIntegral(i->getY())); } buffer.compile(); return getIntegral(buffer); } /** * Reset value. * * The value is set to (the equivalent of) zero, see method JMATH::getZero. * * \param value value */ template inline void reset(T& value) { value = JMATH::getZero(); } /** * Recursive reset of collection. * * \param collection collection */ template inline void reset(JCollection& collection) { typedef typename JCollection::iterator iterator; for (iterator i = collection.begin(); i != collection.end(); ++i) { reset(i->getY()); } } /** * Copy of input to output. * * The output value is set to the input value. * * \param input input * \param output output */ template inline void copy(const T& input, T& output) { output = input; } /** * Recursive copy of input collection to output collection. * * \param input input * \param output output */ template inline void copy(const JCollection& input, JMappableCollection& output) { typedef typename JCollection::const_iterator const_iterator; output.clear(); for (const_iterator i = input.begin(); i != input.end(); ++i) { copy(i->getY(), output.get(i->getX())); } } /** * Configuration of value. * * This is a fall-back method; it does nothing. * * \param value value * \param bounds bounds * \param option false */ template inline void configure(const T& value, const JAbstractCollection& bounds, JBool option) {} /** * Recursive configuration of collection. * * \param collection collection * \param bounds bounds * \param option true */ template inline void configure(JCollection& collection, const JAbstractCollection& bounds, JBool option = JBool()) { typedef typename JCollection::iterator iterator; typedef typename JCollection::ordinate_type ordinate_type; collection.configure(bounds); for (iterator i = collection.begin(); i != collection.end(); ++i) { configure(i->getY(), bounds, JBool::is_collection>()); } } /** * Accumulation of value. * * This is a fall-back method; it does nothing. * * \param value value * \param option false */ template inline void accumulate(T& value, JBool option) {} /** * Recursive accumulation of collection. * * \param collection collection * \param option true */ template inline void accumulate(JCollection& collection, JBool option = JBool()) { typedef typename JCollection::iterator iterator; typedef typename JCollection::ordinate_type ordinate_type; for (iterator i = collection.begin(); i != collection.end(); ++i) { accumulate(i->getY(), JBool::is_collection>()); } if (collection.getSize() > 1) { for (iterator j = collection.begin(), i = j++; j != collection.end(); ++i, ++j) { j->getY() += i->getY(); } reset(collection.begin()->getY()); } } } #endif