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 class IntVec;
00044 
00045 
00046 /**
00047  * Return partitions of an integer
00048  * @author Kevin Long
00049  */
00050 Array<Array<int> > partitionInteger(int n);
00051 
00052 /**
00053  * Get the weighted partitions of an integer
00054  */
00055 void weightedPartitions(int n, const Array<int>& w, 
00056   Array<Array<int> >& parts);
00057 
00058 /** */
00059 void weightedOrderedPartitions(const IntVec& v, const Array<int>& w,
00060   Array<Array<IntVec> >& parts);
00061 
00062 
00063 /** */
00064 void pSet(const IntVec& lambda, const IntVec& nu, int s,
00065   Array<Array<IntVec> >& K, Array<Array<IntVec> >& L);
00066 
00067 /** 
00068  * Get the compositions of length M of an integer n.
00069  */
00070 void restrictedCompositions(int n, int M, Array<Array<int> >& rComps);
00071 
00072 /** Get the next mixed-radix number */
00073 bool nextNum(Array<int>& digits, const Array<int>& radix);
00074 
00075 
00076 
00077 /** 
00078  * Return compositions of an integer
00079  */
00080 Array<Array<Array<int> > > compositions(int n);
00081 
00082 
00083 /** 
00084  * Return the non-negative compositions of an integer into J terms
00085  */
00086 Array<Array<int> > nonNegCompositions(int n, int J);
00087 
00088 
00089 
00090 /** 
00091  * Return the s-term compositions of a multiset. These are the permutations
00092  * of the s-term partitions. 
00093  */
00094 Array<Array<MultiSet<int> > > multisetCompositions(int s,
00095   const MultiSet<int>& x);
00096 
00097 
00098 
00099 /** Return all subsets of a multiset. */
00100 Set<MultiSet<int> > multisetSubsets(const MultiSet<int>& x);
00101 
00102 /** Return all N-tuples of subsets of a multisets such that the
00103  * union of tuple entries is a subset of the original multiset. 
00104  * For example, if the input multiset is {a,b,b}, the subsets are
00105  * \pre
00106  * {a}, {b}, {a,b}, {a, b, b}, {b, b}.
00107  * \pre
00108  * The 2-tuples are all pairs drawn from that collection. Of these, only
00109  * \pre
00110  * ({a}, {b})
00111  * ({a}, {b, b})
00112  * \pre 
00113  * satisfy the requirement that the union of tuple entries is a subset
00114  * of {a,b,b}.
00115  */
00116 Array<Array<MultiSet<int> > > multisetSubsetNTuples(int n, 
00117   const MultiSet<int>& x);
00118 
00119 
00120 /** 
00121  * Generate the (n-choose-m) distinct index combinations for
00122  * choosing m entries from an array of n elements.
00123  */
00124 Array<Array<int> > distinctIndexTuples(int m, int n);
00125 
00126 /** 
00127  * For a given integer vector of length N, find all combinations 
00128  * of integers (i_1, 1_2, ... i_N) such that
00129  * \f$0 \le i_j < s_j\f$. 
00130  * For example, if \f$ s = (2,3) \f$, return
00131  * \code
00132  * { {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {1,2} }
00133  * \endcode
00134  */
00135 Array<Array<int> > indexCombinations(const Array<int>& s);
00136 
00137 /** Compute the n-th power of 2 */
00138 int pow2(int n);
00139 
00140 /** Compute the n bits of an integer x < 2^n. The bits are ordered
00141  * least-to-most significant.
00142  */
00143 Array<int> bitsOfAnInteger(int x, int n);
00144 
00145 
00146 /** 
00147  *
00148  */
00149 template <class T> 
00150 class Pair: public OrderedPair<T, T>
00151 {
00152 public:
00153   Pair(const T& a, const T& b)
00154     : OrderedPair<T, T>(a, b)
00155     {;}
00156 };
00157 
00158 template <class T> inline
00159 std::ostream& operator<<(std::ostream& os, const Pair<T>& p)
00160 {
00161   os << "Pair(" << p.first() << ", " << p.second() << ")";
00162   return os;
00163 }
00164 
00165 /** 
00166  *
00167  */
00168 template <class T> 
00169 class SortedPair: public OrderedPair<T, T>
00170 {
00171 public:
00172   SortedPair(const T& a, const T& b)
00173     : OrderedPair<T, T>(std::min(a, b), std::max(a,b))
00174     {;}
00175 };
00176 
00177 template <class T> inline
00178 std::ostream& operator<<(std::ostream& os, const SortedPair<T>& p)
00179 {
00180   os << "Pair(" << p.first() << ", " << p.second() << ")";
00181   return os;
00182 }
00183 
00184 
00185 /** 
00186  * Form all pairs of multisets that can be generated from an 
00187  * initial pair by adding n copies of entry x. This is used in the
00188  * partitioning of multisets.
00189  */
00190 Set<Pair<MultiSet<int> > >
00191 loadPartitions(int x, int n, 
00192   const MultiSet<int>& left, 
00193   const MultiSet<int>& right);
00194 
00195 
00196 /** 
00197  * Return the size-2 partitions of a multiset. This is used in a recursive
00198  * algorithm to determine all partitions of a multset. 
00199  */
00200 Set<Pair<MultiSet<int> > >
00201 binaryPartition(const MultiSet<int>& m);
00202 
00203 /** 
00204  * Return the partitions of a multiset. The partitions are sets
00205  * of subsets such that the union of the members equals the original
00206  * multiset. 
00207  */
00208 Set<MultiSet<MultiSet<int> > >
00209 multisetPartitions(const MultiSet<int>& m);
00210 
00211 /** 
00212  * Given a multiset, create a mapping from entry to number of repetitions
00213  * in the multisets.
00214  */
00215 Map<int, int> countMap(const MultiSet<int>& m);
00216 
00217 
00218 /** */
00219 template <class T> inline
00220 Array<Array<Array<T> > > indexArrangements(const MultiSet<T>& mu,
00221   const Array<int>& k)
00222 {
00223   int nBins = k.size();
00224     
00225   int M = 0;
00226   for (int i=0; i<nBins; i++)
00227   {
00228     M += k[i];
00229   }
00230     
00231   Array<T> I;
00232   typename MultiSet<T>::const_iterator iter;
00233   for (iter=mu.begin(); iter!=mu.end(); iter++)
00234   {
00235     I.append(*iter);
00236   }
00237 
00238   Array<Array<Array<T> > > rtn;
00239     
00240   do
00241   {
00242     Array<Array<T> > bins(nBins);
00243     int count = 0;
00244     for (int i=0; i<nBins; i++)
00245     {
00246       for (int j=0; j<k[i]; j++)
00247       {
00248         bins[i].append(I[count++]);
00249       }
00250     }
00251     rtn.append(bins);
00252   }
00253   while (std::next_permutation(I.begin(), I.end()));
00254   return rtn;
00255 }
00256 
00257 /** 
00258  * Return the distinct arrangements of the given multiset into n bins
00259  */
00260 template <class T> inline
00261 Array<Array<Array<T> > > binnings(const MultiSet<T>& mu, int n)
00262 {
00263   int N = mu.size();
00264   Array<Array<int> > c = compositions(N)[n-1];
00265   Array<Array<Array<T> > > rtn;
00266 
00267   for (int i=0; i<c.size(); i++)
00268   {
00269     Array<Array<Array<T> > > a = indexArrangements(mu, c[i]);
00270     for (int j=0; j<a.size(); j++)
00271     {
00272       rtn.append(a[j]);
00273     }
00274   }
00275   return rtn;
00276 }
00277 
00278 
00279 inline int factorial(const MultiSet<int>& ms)
00280 {
00281   Sundance::Map<int, int> counts;
00282     
00283   for (MultiSet<int>::const_iterator i=ms.begin(); i!=ms.end(); i++)
00284   {
00285     if (counts.containsKey(*i)) counts[*i]++;
00286     else counts.put(*i, 1);
00287   }
00288 
00289   int rtn = 1;
00290   for (Sundance::Map<int, int>::const_iterator
00291          i=counts.begin(); i!=counts.end(); i++)
00292   {
00293     int f = 1;
00294     for (int j=1; j<=i->second; j++) f *= j;
00295     rtn *= f;
00296   }
00297   return rtn;
00298 }
00299 
00300 
00301 }
00302 
00303 
00304 
00305 #endif
00306 
00307 
00308 

Site Contact