SundanceCombinatorialUtils.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #ifndef SUNDANCE_COMBINATORIALUTILS_H
00032 #define SUNDANCE_COMBINATORIALUTILS_H
00033 
00034 #include "SundanceDefs.hpp"
00035 #include "Teuchos_Array.hpp"
00036 #include "SundanceMultiSet.hpp"
00037 #include "SundanceMap.hpp"
00038 #include "SundanceOrderedTuple.hpp"
00039 
00040 namespace Sundance
00041 {
00042 using Teuchos::Array;
00043 /**
00044  * Return partitions of an integer
00045  * @author Kevin Long
00046  */
00047 Array<Array<int> > partitionInteger(int n);
00048 
00049 /** 
00050  * Return compositions of an integer
00051  */
00052 Array<Array<Array<int> > > compositions(int n);
00053 
00054 
00055 /** 
00056  * Return the non-negative compositions of an integer into J terms
00057  */
00058 Array<Array<int> > nonNegCompositions(int n, int J);
00059 
00060 
00061 
00062 /** 
00063  * Return the s-term compositions of a multiset. These are the permutations
00064  * of the s-term partitions. 
00065  */
00066 Array<Array<MultiSet<int> > > multisetCompositions(int s,
00067   const MultiSet<int>& x);
00068 
00069 
00070 
00071 /** Return all subsets of a multiset. */
00072 Set<MultiSet<int> > multisetSubsets(const MultiSet<int>& x);
00073 
00074 /** Return all N-tuples of subsets of a multisets such that the
00075  * union of tuple entries is a subset of the original multiset. 
00076  * For example, if the input multiset is {a,b,b}, the subsets are
00077  * \pre
00078  * {a}, {b}, {a,b}, {a, b, b}, {b, b}.
00079  * \pre
00080  * The 2-tuples are all pairs drawn from that collection. Of these, only
00081  * \pre
00082  * ({a}, {b})
00083  * ({a}, {b, b})
00084  * \pre 
00085  * satisfy the requirement that the union of tuple entries is a subset
00086  * of {a,b,b}.
00087  */
00088 Array<Array<MultiSet<int> > > multisetSubsetNTuples(int n, 
00089   const MultiSet<int>& x);
00090 
00091 
00092 /** 
00093  * Generate the (n-choose-m) distinct index combinations for
00094  * choosing m entries from an array of n elements.
00095  */
00096 Array<Array<int> > distinctIndexTuples(int m, int n);
00097 
00098 /** 
00099  * For a given integer vector of length N, find all combinations 
00100  * of integers (i_1, 1_2, ... i_N) such that
00101  * \f$0 \le i_j < s_j\f$. 
00102  * For example, if \f$ s = (2,3) \f$, return
00103  * \code
00104  * { {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {1,2} }
00105  * \endcode
00106  */
00107 Array<Array<int> > indexCombinations(const Array<int>& s);
00108 
00109 /** Compute the n-th power of 2 */
00110 int pow2(int n);
00111 
00112 /** Compute the n bits of an integer x < 2^n. The bits are ordered
00113  * least-to-most significant.
00114  */
00115 Array<int> bitsOfAnInteger(int x, int n);
00116 
00117 
00118 /** 
00119  *
00120  */
00121 template <class T> 
00122 class Pair: public OrderedPair<T, T>
00123 {
00124 public:
00125   Pair(const T& a, const T& b)
00126     : OrderedPair<T, T>(a, b)
00127     {;}
00128 };
00129 
00130 template <class T> inline
00131 std::ostream& operator<<(std::ostream& os, const Pair<T>& p)
00132 {
00133   os << "Pair(" << p.first() << ", " << p.second() << ")";
00134   return os;
00135 }
00136 
00137 /** 
00138  *
00139  */
00140 template <class T> 
00141 class SortedPair: public OrderedPair<T, T>
00142 {
00143 public:
00144   SortedPair(const T& a, const T& b)
00145     : OrderedPair<T, T>(std::min(a, b), std::max(a,b))
00146     {;}
00147 };
00148 
00149 template <class T> inline
00150 std::ostream& operator<<(std::ostream& os, const SortedPair<T>& p)
00151 {
00152   os << "Pair(" << p.first() << ", " << p.second() << ")";
00153   return os;
00154 }
00155 
00156 
00157 /** 
00158  * Form all pairs of multisets that can be generated from an 
00159  * initial pair by adding n copies of entry x. This is used in the
00160  * partitioning of multisets.
00161  */
00162 Set<Pair<MultiSet<int> > >
00163 loadPartitions(int x, int n, 
00164   const MultiSet<int>& left, 
00165   const MultiSet<int>& right);
00166 
00167 
00168 /** 
00169  * Return the size-2 partitions of a multiset. This is used in a recursive
00170  * algorithm to determine all partitions of a multset. 
00171  */
00172 Set<Pair<MultiSet<int> > >
00173 binaryPartition(const MultiSet<int>& m);
00174 
00175 /** 
00176  * Return the partitions of a multiset. The partitions are sets
00177  * of subsets such that the union of the members equals the original
00178  * multiset. 
00179  */
00180 Set<MultiSet<MultiSet<int> > >
00181 multisetPartitions(const MultiSet<int>& m);
00182 
00183 /** 
00184  * Given a multiset, create a mapping from entry to number of repetitions
00185  * in the multisets.
00186  */
00187 Map<int, int> countMap(const MultiSet<int>& m);
00188 
00189 
00190 /** */
00191 template <class T> inline
00192 Array<Array<Array<T> > > indexArrangements(const MultiSet<T>& mu,
00193   const Array<int>& k)
00194 {
00195   int nBins = k.size();
00196     
00197   int M = 0;
00198   for (int i=0; i<nBins; i++)
00199   {
00200     M += k[i];
00201   }
00202     
00203   Array<T> I;
00204   typename MultiSet<T>::const_iterator iter;
00205   for (iter=mu.begin(); iter!=mu.end(); iter++)
00206   {
00207     I.append(*iter);
00208   }
00209 
00210   Array<Array<Array<T> > > rtn;
00211     
00212   do
00213   {
00214     Array<Array<T> > bins(nBins);
00215     int count = 0;
00216     for (int i=0; i<nBins; i++)
00217     {
00218       for (int j=0; j<k[i]; j++)
00219       {
00220         bins[i].append(I[count++]);
00221       }
00222     }
00223     rtn.append(bins);
00224   }
00225   while (std::next_permutation(I.begin(), I.end()));
00226   return rtn;
00227 }
00228 
00229 /** 
00230  * Return the distinct arrangements of the given multiset into n bins
00231  */
00232 template <class T> inline
00233 Array<Array<Array<T> > > binnings(const MultiSet<T>& mu, int n)
00234 {
00235   int N = mu.size();
00236   Array<Array<int> > c = compositions(N)[n-1];
00237   Array<Array<Array<T> > > rtn;
00238 
00239   for (int i=0; i<c.size(); i++)
00240   {
00241     Array<Array<Array<T> > > a = indexArrangements(mu, c[i]);
00242     for (int j=0; j<a.size(); j++)
00243     {
00244       rtn.append(a[j]);
00245     }
00246   }
00247   return rtn;
00248 }
00249 
00250 
00251 inline int factorial(const MultiSet<int>& ms)
00252 {
00253   Sundance::Map<int, int> counts;
00254     
00255   for (MultiSet<int>::const_iterator i=ms.begin(); i!=ms.end(); i++)
00256   {
00257     if (counts.containsKey(*i)) counts[*i]++;
00258     else counts.put(*i, 1);
00259   }
00260 
00261   int rtn = 1;
00262   for (Sundance::Map<int, int>::const_iterator
00263          i=counts.begin(); i!=counts.end(); i++)
00264   {
00265     int f = 1;
00266     for (int j=1; j<=i->second; j++) f *= j;
00267     rtn *= f;
00268   }
00269   return rtn;
00270 }
00271 
00272 
00273 }
00274 
00275 
00276 
00277 #endif
00278 
00279 
00280 

Site Contact