#ifndef __JGRID__ #define __JGRID__ #include "JLang/JClass.hh" #include "JTools/JGridBounds.hh" #include "JTools/JVector.hh" #include "JTools/JMultiKey.hh" #include "JTools/JMapElement.hh" #include "JTools/JFunctional.hh" #include "JTools/JFunctionalMap.hh" #include "JTools/JFunctionObject1D.hh" namespace JTOOLS { /** * Template definition for implementation of equidistant collection of elements. * This class implements the JAbstractGridBounds<> and JGrid<> interfaces. */ template class JGrid : public JAbstractGridBounds, public JVector { public: typedef JAbstractGridBounds JGridBounds_t; typedef JVector JVector_t; typedef typename JVector_t::key_type key_type; typedef typename JVector_t::mapped_type mapped_type; typedef typename JVector_t::value_type value_type; typedef typename JVector_t::const_iterator const_iterator; typedef typename JVector_t::const_reverse_iterator const_reverse_iterator; typedef typename JVector_t::iterator iterator; typedef typename JVector_t::reverse_iterator reverse_iterator; typedef typename JVector_t::pair pair; /** * Default constructor. */ JGrid() : JGridBounds_t(), JVector_t() {} /** * Get number of keys. * * \return number of keys */ virtual unsigned int getNumberOfKeys() const { return this->size(); } /** * Get lower limit. * * \return lower key */ virtual key_type getLowerKey() const { return this->begin()->getKey(); } /** * Get upper limit. * * \return upper key */ virtual key_type getUpperKey() const { return this->rbegin()->getKey(); } /** * Get bin position (starting at 0). * The bin position could be less than zero or larger than the number of keys. * * \param x key * \return index */ virtual int getPosition(const key_type x) const { return (int) ((this->size() - 1) * (x - this->begin()->getKey()) / (this->rbegin()->getKey() - this->begin()->getKey())); } /** * Get lower edge of bin. * * \param index index of bin * \return key */ virtual key_type getKey(const int index) const { return (this->begin() + index)->getKey(); } /** * Configure grid. * * \param bounds grid bounds */ void configure(const JAbstractGridBounds& bounds) { configure(bounds, mapped_type()); } /** * Configure grid. * * \param bounds grid bounds * \param y value */ void configure(const JAbstractGridBounds& bounds, const mapped_type y) { configure(bounds, JConstantFunction1D(y)); } /** * Configure grid. * * \param bounds grid bounds * \param function function */ void configure(const JAbstractGridBounds& bounds, mapped_type (*function)(const key_type)) { configure(bounds, JExternalFunction1D(function)); } /** * Configure grid. * * \param bounds grid bounds * \param function function */ void configure(const JAbstractGridBounds& bounds, const JFunction1D& function) { this->clear(); for (unsigned int i = 0; i != bounds.getNumberOfKeys(); ++i) { const key_type x = bounds.getKey(i); const mapped_type y = function(x); this->push_back(value_type(x,y)); } } /** * Configure grid. * * \param bounds grid bounds * \param function function */ template void configure(const JAbstractGridBounds& bounds, JFunction1D_t function) { this->clear(); for (unsigned int i = 0; i != bounds.getNumberOfKeys(); ++i) { const key_type x = bounds.getKey(i); const mapped_type y = function(x); this->push_back(value_type(x,y)); } } /** * Get value. * * \param index index * \return value */ virtual const mapped_type& operator[](const int index) const { return (this->begin() + index)->getValue(); } /** * Value assignment. * * \param x key * \return value */ virtual mapped_type& operator[](const key_type& x) { return JVector_t::operator[](x); } /** * Insert element. * * \param element element */ virtual pair insert(const value_type& element) { return JVector_t::insert(element); } /** * Get first position of element i, where x >= i->getKey(). * * \param x key * \return position of corresponding element */ virtual const_iterator lower_bound(const key_type& x) const { int index = getPosition(x) + 1; if (index < 0) index = 0; else if (index > (int) this->size()) index = this->size(); return this->begin() + index; } /** * Get first position of element i, where x >= i->getKey(). * * \param x key * \return position of corresponding element */ virtual iterator lower_bound(const key_type& x) { int index = getPosition(x) + 1; if (index < 0) index = 0; else if (index > (int) this->size()) index = this->size(); return this->begin() + index; } }; /** * Template definition for implementation of equidistant map of elements. */ template class JGridMap : public JGrid< JMapElement > { public: typedef JKey_t key_type; typedef JValue_t mapped_type; typedef JMapElement value_type; typedef JGrid JGrid_t; typedef typename JGrid_t::const_iterator const_iterator; typedef typename JGrid_t::const_reverse_iterator const_reverse_iterator; typedef typename JGrid_t::iterator iterator; typedef typename JGrid_t::reverse_iterator reverse_iterator; friend class JGridConfigureHelper; // helper class for configuration. using JGrid_t::configure; /** * Default constructor. */ JGridMap() : JGrid_t() {} /** * Configure grid. * * \param bounds multi-dimensional grid bounds */ template void configure(const JAbstractMultiGridBounds& bounds) { configure_grid(*this, bounds); } }; /** * Helper class for configuration of multi-dimensional grid. */ class JGridConfigureHelper { public: /** * Default constructor. */ JGridConfigureHelper() {} /** * Function object operator for configuration of multi-dimensional grid. * * \param grid multi-dimensional grid * \param bounds multi-dimensional grid bounds */ template void operator()(JGridMap& grid, const JAbstractMultiGridBounds& bounds) const { for (typename JGridMap::iterator i = grid.begin(); i != grid.end(); ++i) for_each(JMultiKey<1, JKey_t>(i->first), i->second, bounds); } /** * Function object operator for configuration of one dimensional grid. * * \param grid one dimensional grid * \param bounds one dimensional grid bounds */ template void operator()(JGridMap& grid, const JAbstractMultiGridBounds<0, JKey_t>& bounds) const { grid.configure(bounds()); } private: /** * Recursive method for configuration of multi-dimensional grid. * * \param key multi-dimensional key * \param grid multi-dimensional grid * \param bounds multi-dimensional grid bounds */ template void for_each(const JMultiKey& key, JGridMap& grid, const JAbstractMultiGridBounds& bounds) const { for (typename JGridMap::iterator i = grid.begin(); i != grid.end(); ++i) for_each(JMultiKey(key,i->first), i->second, bounds); } /** * Terminator method for configuration of multi-dimensional grid. * * \param key multi-dimensional key * \param grid multi-dimensional grid * \param bounds multi-dimensional grid bounds */ template void for_each(const JMultiKey& key, JGridMap& grid, const JAbstractMultiGridBounds& bounds) const { grid.configure(bounds(key)); } }; namespace { /** * Auxiliary function object for configuration of multi-dimensional grid. */ static const JGridConfigureHelper configure_grid; } /** * Template implementation for fast look-up table. */ template class JGridFunction1D : public JGrid, public JFunction1D { public: typedef typename JElement_t::key_type key_type; typedef typename JElement_t::mapped_type mapped_type; typedef JGrid JGrid_t; typedef JFunction1D JFunction1D_t; typedef typename JFunction1D_t::argument_type argument_type; typedef typename JFunction1D_t::result_type result_type; /** * Default constructor. */ JGridFunction1D() : JGrid_t(), JFunction1D_t() {} /** * Function compilation. */ virtual void compile() { // do nothing. } /** * Grid interpolation method. * * \param x argument value * \return function value */ result_type operator()(const argument_type& x) const { return JGrid_t::operator[](getPosition(x)); } }; /** * Template definition of a JGridMap with look-up interpolation. */ template class JFunctionalGridMap; /** * Template specialisation of a JGridMap with look-up interpolation. */ template class JFunctionalGridMap : public JFunctionalMap { public: typedef JFunctionalMap JFunctionalMap_t; typedef typename JFunctionalMap_t::argument_type argument_type; typedef typename JFunctionalMap_t::result_type result_type; typedef typename JFunctionalMap_t::JCollection_t JCollection_t; typedef typename JFunctionalMap_t::key_type key_type; typedef typename JFunctionalMap_t::mapped_type mapped_type; /** * Default constructor. */ JFunctionalGridMap() : JFunctionalMap_t() {} /** * Function compilation. */ void compile() { this->configure(); JFunctionalMap_t::compile(); } /** * Grid recursive interpolation method implementation. * * \param pX pointer to argument list * \return function value */ result_type evaluate(const argument_type* pX) const { const argument_type x = *pX; return JFunctionalMap_t::operator[](getPosition(x)).evaluate(++pX); } }; } #endif