MathTL
utils/multiindex.h
00001 // -*- c++ -*-
00002 
00003 // +--------------------------------------------------------------------+
00004 // | This file is part of MathTL - the Mathematical Template Library    |
00005 // |                                                                    |
00006 // | Copyright (c) 2002-2009                                            |
00007 // | Thorsten Raasch, Manuel Werner, Ulrich Friedrich                   |
00008 // +--------------------------------------------------------------------+
00009 
00010 #ifndef _MATHTL_MULTIINDEX_H
00011 #define _MATHTL_MULTIINDEX_H
00012 
00013 #include <iostream>
00014 #include <set>
00015 #include <map>
00016 #include <utils/fixed_array1d.h>
00017 
00018 namespace MathTL
00019 {
00026   template <class I, unsigned int DIMENSION>
00027   class MultiIndex
00028     : public FixedArray1D<I, DIMENSION>
00029   {
00030   public:
00034     MultiIndex();
00035 
00039     MultiIndex(const MultiIndex& lambda);
00040 
00044     explicit MultiIndex(const I& i0);
00045 
00049     MultiIndex(const I& i0, const I& i1);
00050   
00052     bool operator == (const MultiIndex& lambda) const;
00053 
00055     inline bool operator != (const MultiIndex& lambda) const
00056     { return !(*this == lambda); }
00057 
00058     /*
00059      * MultiIndices are ordered same as \N^dim is ordered.
00060      * This is not the lexicographic order!
00061      * This does not work for multiindices with negative entries.
00062      * Explicitly: indices are ordered primarily by their 1 norm, secondly lexicographically.
00063      */
00064     bool operator < (const MultiIndex& lambda) const;
00065 
00066     /*
00067      * Lexicographical ordering
00068      */
00069     bool lex (const MultiIndex& lambda) const;
00070 
00072     bool operator <= (const MultiIndex& lambda) const
00073     { return (*this < lambda || *this == lambda); }
00074 
00076     bool operator >= (const MultiIndex& lambda) const
00077     { return (lambda < *this || *this == lambda); }
00078  
00079     /*
00080      * Preincrement. Works only for nonnegative entries!
00081      * Ordering given by numbering of \N^dim, i.e.
00082      * (0,0,0),(0,0,1),(0,1,0),(1,0,0),(0,0,2),(0,1,1),(0,2,0),(1,0,1),(1,1,0),(2,0,0),(0,0,3),...
00083      * This ordering is used for the operator <.
00084      */
00085     MultiIndex& operator ++ ();
00086     
00087         // Postincrement. Works only for nonnegative entries!
00088     MultiIndex operator ++ (int)    
00089     {
00090         MultiIndex temp (*this);
00091         ++*this;
00092         return temp;
00093     };
00094 
00095     /*
00096      * Return Number of MulitiIndex with respect to the ordering "<"
00097      * Counting begins at 0.
00098      */
00099     unsigned long int number();
00100     
00101   };
00102 
00103 
00104   /*
00105    * Returns the mapping from the multiindices to the natural numbers according 
00106    * to the ordering <.
00107    * Output contains multiindices ranging from 0 to lambda, excluding lambda.
00108    */
00109   template <class I, unsigned int DIMENSION>
00110   std::map<MultiIndex<I, DIMENSION>,int>
00111   indexmapping(const MultiIndex<I, DIMENSION>& lambda);
00112 
00119   template <class I, unsigned int DIMENSION>
00120   std::set<MultiIndex<I, DIMENSION> >
00121   cuboid_indices(const MultiIndex<I, DIMENSION>& alpha,
00122                  const MultiIndex<I, DIMENSION>& beta);
00123 
00129   template <class I, unsigned int DIMENSION>
00130   unsigned int multi_degree(const MultiIndex<I, DIMENSION>& alpha);
00131 
00137   template <class I, unsigned int DIMENSION>
00138   unsigned int multi_factorial(const MultiIndex<I, DIMENSION>& alpha);
00139 
00145   template <class I, unsigned int DIMENSION>
00146   int multi_power(const MultiIndex<I, DIMENSION>& alpha,
00147                   const MultiIndex<I, DIMENSION>& beta);
00148   
00153   template <class I, unsigned int DIMENSION>
00154   int multi_binomial(const MultiIndex<I, DIMENSION>& beta,
00155                      const MultiIndex<I, DIMENSION>& alpha);
00156 
00161   template <class I, unsigned int DIMENSION>
00162   std::set<MultiIndex<I, DIMENSION> >
00163   degree_indices(const unsigned int k);  
00164   
00166   template<class I, unsigned int DIMENSION>
00167   inline std::ostream&
00168   operator << (std::ostream& os, const MultiIndex<I, DIMENSION>& lambda)
00169   {
00170     using namespace std;
00171     os << "(";
00172     for (unsigned int i(0); i < DIMENSION; i++)
00173       {
00174         os << lambda[i];
00175         if (i < DIMENSION-1)
00176           os << ",";
00177         else
00178           os << ")";
00179       }
00180     
00181     return os;
00182   }  
00183 
00184 }
00185 
00186 #include <utils/multiindex.cpp>
00187 
00188 #endif
 All Classes Functions Variables Typedefs Enumerations