src/Index/LSIndex.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef LSINDEX_H
00012 #define LSINDEX_H
00013 
00014 // include files
00015 #include "Index/SOffset.h"
00016 #include "FieldLayout/Vnode.h"
00017 #include "Utility/RefCounted.h"
00018 #include "Utility/Vec.h"
00019 
00020 #ifdef IPPL_STDSTL
00021 #include <vector>
00022 using std::vector;
00023 #else
00024 #include <vector.h>
00025 #endif // IPPL_STDSTL
00026 
00027 
00028 /***********************************************************************
00029  * 
00030  * LSIndex represents a set of single-point indices for a Field, just
00031  * for a single vnode.  SIndex contains a list of these LSIndex objects.
00032  * Expressions involving sparse indices are constrained to have the same
00033  * number of indices in the corresponding LSIndex objects, even though
00034  * the indices themselves do not have to be the same.
00035  *
00036  ***********************************************************************/
00037 
00038 template<unsigned int Dim>
00039 class LSIndex : public RefCounted {
00040 
00041 public:
00042   // useful typedefs
00043   typedef vector< SOffset<Dim> >             container_t;
00044   typedef typename container_t::iterator     iterator;
00045   typedef typename container_t::const_iterator const_iterator;
00046   typedef typename container_t::size_type    size_type;
00047 #if ( defined(IPPL_KAI) && !defined(__KAI_STRICT) )
00048   typedef container_t::allocator_type        allocator_type;
00049 #endif
00050 
00051 public:
00052   // constructors
00053   LSIndex(Vnode<Dim>* vn)
00054 #if ( defined(IPPL_KAI) && !defined(__KAI_STRICT) )
00055     : compressed(false), VN(vn), IndexList(allocator_type())
00056 #else
00057     : compressed(false), VN(vn)
00058 #endif
00059     {
00060       Strides[0] = 1;
00061       for (unsigned int d=1; d < Dim; ++d)
00062         Strides[d] = Strides[d-1] * vn->getDomain()[d-1].length();
00063     }
00064   LSIndex(const LSIndex<Dim>& lsi)
00065     : compressed(lsi.compressed), IndexList(lsi.IndexList),
00066       VN(lsi.VN), Strides(lsi.Strides) { }
00067 
00068   // destructor
00069   ~LSIndex() { }
00070 
00071   // change this LSIndex to store the values in the given LSIndex instead
00072   LSIndex& operator=(const LSIndex& lsi) {
00073     VN = lsi.VN;
00074     IndexList = lsi.IndexList;
00075     compressed = lsi.compressed;
00076     Strides = lsi.Strides;
00077     return *this;
00078   }
00079 
00080   // are we compressed?
00081   bool IsCompressed() const { return compressed; }
00082 
00083   // compress this list
00084   void Compress(bool docompress) {
00085     clear();
00086     compressed = docompress;
00087   }
00088 
00089   // check to see if the given point would go here
00090   bool contains(const SOffset<Dim> &indx) {
00091     return indx.inside( (VN->getDomain()) );
00092   }
00093 
00094   // add a new point ... to do explicit checking for errors, call contains()
00095   // before adding a point.
00096   void addIndex(const SOffset<Dim> &indx) {
00097     compressed = false;
00098     IndexList.push_back(indx);
00099   }
00100 
00101   // return the Nth index
00102   SOffset<Dim>& getIndex(unsigned int n) {
00103     if (compressed) {
00104       int mval = n;
00105       for (unsigned int d=(Dim-1); d >= 1; --d) {
00106         int dval = mval / Strides[d];
00107         mval -= dval * Strides[d];
00108         CompressedPoint[d] = dval + VN->getDomain()[d].first();
00109       }
00110       CompressedPoint[0] = mval + VN->getDomain()[0].first();
00111 
00112       //Inform dbgmsg("LSIndex::getIndex", INFORM_ALL_NODES);
00113       //dbgmsg << "For dom=" << VN->getDomain() << ": mapped n=" << n;
00114       //dbgmsg << " to SOffset=" << CompressedPoint << endl;
00115 
00116       return CompressedPoint;
00117     }
00118 
00119     // if we're here, not compressed, so just return Nth point
00120     return IndexList[n];
00121   }
00122 
00123   // return a copy of the Nth index
00124   SOffset<Dim> getIndex(unsigned int n) const {
00125     if (compressed) {
00126       SOffset<Dim> retval;
00127       int mval = n;
00128       for (unsigned int d=(Dim-1); d >= 1; --d) {
00129         int dval = mval / Strides[d];
00130         mval -= dval * Strides[d];
00131         retval[d] = dval + VN->getDomain()[d].first();
00132       }
00133       retval[0] = mval + VN->getDomain()[0].first();
00134 
00135       //Inform dbgmsg("LSIndex::getIndex", INFORM_ALL_NODES);
00136       //dbgmsg << "For dom=" << VN->getDomain() << ": mapped n=" << n;
00137       //dbgmsg << " to SOffset=" << retval << endl;
00138 
00139       return retval;
00140     }
00141 
00142     // if we're here, not compressed, so just return Nth point
00143     return IndexList[n];
00144   }
00145 
00146   // remove the given point if we have it.  Just move the last element
00147   // up, the order does not matter
00148   void removeIndex(const SOffset<Dim> &indx) {
00149     iterator loc = (*this).find(indx);
00150     if (loc != end()) {
00151       *loc = IndexList.back();
00152       IndexList.pop_back();
00153     }
00154   }
00155 
00156   // clear out the existing indices
00157   void clear() { IndexList.erase(IndexList.begin(), IndexList.end()); }
00158 
00159   // reserve enough space to hold at least n points
00160   void reserve(size_type n) { IndexList.reserve(n); }
00161 
00162   //
00163   // container methods
00164   //
00165 
00166   // return begin/end iterators
00167   iterator begin() { return IndexList.begin(); }
00168   iterator end() { return IndexList.end(); }
00169   const_iterator begin() const { return IndexList.begin(); }
00170   const_iterator end() const { return IndexList.end(); }
00171 
00172   // return size information about the number of index points here
00173   size_type capacity() const { return IndexList.capacity(); }
00174   size_type size() const {
00175     return (compressed ? VN->getDomain().size() : IndexList.size());
00176   }
00177 
00178   // return an iterator to the given point, if we have it; otherwise
00179   // return the end iterator
00180   iterator find(const SOffset<Dim>& indx) {
00181     for (iterator a = begin(); a != end(); ++a)
00182       if (*a == indx)
00183         return a;
00184     return end();
00185   }
00186 
00187   // just return a boolean indicating if we have the given point
00188   bool hasIndex(const SOffset<Dim>& indx) const {
00189     for (const_iterator a = begin(); a != end(); ++a)
00190       if (*a == indx)
00191         return true;
00192     return false;
00193   }
00194 
00195   //
00196   // vnode information methods
00197   //
00198 
00199   // return the local domain of vnode this LSIndex contains points for
00200   const NDIndex<Dim>& getDomain() const { return VN->getDomain(); }
00201 
00202   // return the local procssor of vnode this LSIndex contains points for
00203   int getNode() const { return VN->getNode(); }
00204 
00205 private:
00206   // vnode on which this LSIndex stores points
00207   Vnode<Dim> *VN;
00208 
00209   // list of points
00210   container_t IndexList;
00211 
00212   // are we compressed?  If so, IndexList should be empty, and all points
00213   // in the domain assumed to be here.
00214   bool compressed;
00215   SOffset<Dim> CompressedPoint;
00216 
00217   // strides for computing mapping from N --> (i,j,k)
00218   vec<int,Dim> Strides;
00219 };
00220 
00221 #endif // LSINDEX_H
00222 
00223 /***************************************************************************
00224  * $RCSfile: LSIndex.h,v $   $Author: adelmann $
00225  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:27 $
00226  * IPPL_VERSION_ID: $Id: LSIndex.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $ 
00227  ***************************************************************************/
00228 

Generated on Mon Jan 16 13:23:48 2006 for IPPL by  doxygen 1.4.6