SundanceCombinatorialUtils.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef SUNDANCE_COMBINATORIALUTILS_H
00043 #define SUNDANCE_COMBINATORIALUTILS_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "Teuchos_Array.hpp"
00047 #include "SundanceMultiSet.hpp"
00048 #include "SundanceMap.hpp"
00049 #include "SundanceOrderedTuple.hpp"
00050 
00051 namespace Sundance
00052 {
00053 using Teuchos::Array;
00054 class IntVec;
00055 
00056 
00057 /**
00058  * Return partitions of an integer
00059  * @author Kevin Long
00060  */
00061 Array<Array<int> > partitionInteger(int n);
00062 
00063 /**
00064  * Get the weighted partitions of an integer
00065  */
00066 void weightedPartitions(int n, const Array<int>& w, 
00067   Array<Array<int> >& parts);
00068 
00069 /** */
00070 void weightedOrderedPartitions(const IntVec& v, const Array<int>& w,
00071   Array<Array<IntVec> >& parts);
00072 
00073 
00074 /** */
00075 void pSet(const IntVec& lambda, const IntVec& nu, int s,
00076   Array<Array<IntVec> >& K, Array<Array<IntVec> >& L);
00077 
00078 /** 
00079  * Get the compositions of length M of an integer n.
00080  */
00081 void restrictedCompositions(int n, int M, Array<Array<int> >& rComps);
00082 
00083 /** Get the next mixed-radix number */
00084 bool nextNum(Array<int>& digits, const Array<int>& radix);
00085 
00086 
00087 
00088 /** 
00089  * Return compositions of an integer
00090  */
00091 Array<Array<Array<int> > > compositions(int n);
00092 
00093 
00094 /** 
00095  * Return the non-negative compositions of an integer into J terms
00096  */
00097 Array<Array<int> > nonNegCompositions(int n, int J);
00098 
00099 
00100 
00101 /** 
00102  * Return the s-term compositions of a multiset. These are the permutations
00103  * of the s-term partitions. 
00104  */
00105 Array<Array<MultiSet<int> > > multisetCompositions(int s,
00106   const MultiSet<int>& x);
00107 
00108 
00109 
00110 /** Return all subsets of a multiset. */
00111 Set<MultiSet<int> > multisetSubsets(const MultiSet<int>& x);
00112 
00113 /** Return all N-tuples of subsets of a multisets such that the
00114  * union of tuple entries is a subset of the original multiset. 
00115  * For example, if the input multiset is {a,b,b}, the subsets are
00116  * \pre
00117  * {a}, {b}, {a,b}, {a, b, b}, {b, b}.
00118  * \pre
00119  * The 2-tuples are all pairs drawn from that collection. Of these, only
00120  * \pre
00121  * ({a}, {b})
00122  * ({a}, {b, b})
00123  * \pre 
00124  * satisfy the requirement that the union of tuple entries is a subset
00125  * of {a,b,b}.
00126  */
00127 Array<Array<MultiSet<int> > > multisetSubsetNTuples(int n, 
00128   const MultiSet<int>& x);
00129 
00130 
00131 /** 
00132  * Generate the (n-choose-m) distinct index combinations for
00133  * choosing m entries from an array of n elements.
00134  */
00135 Array<Array<int> > distinctIndexTuples(int m, int n);
00136 
00137 /** 
00138  * For a given integer vector of length N, find all combinations 
00139  * of integers (i_1, 1_2, ... i_N) such that
00140  * \f$0 \le i_j < s_j\f$. 
00141  * For example, if \f$ s = (2,3) \f$, return
00142  * \code
00143  * { {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {1,2} }
00144  * \endcode
00145  */
00146 Array<Array<int> > indexCombinations(const Array<int>& s);
00147 
00148 /** Compute the n-th power of 2 */
00149 int pow2(int n);
00150 
00151 /** Compute the n bits of an integer x < 2^n. The bits are ordered
00152  * least-to-most significant.
00153  */
00154 Array<int> bitsOfAnInteger(int x, int n);
00155 
00156 
00157 /** 
00158  *
00159  */
00160 template <class T> 
00161 class Pair: public OrderedPair<T, T>
00162 {
00163 public:
00164   Pair(const T& a, const T& b)
00165     : OrderedPair<T, T>(a, b)
00166     {;}
00167 };
00168 
00169 template <class T> inline
00170 std::ostream& operator<<(std::ostream& os, const Pair<T>& p)
00171 {
00172   os << "Pair(" << p.first() << ", " << p.second() << ")";
00173   return os;
00174 }
00175 
00176 /** 
00177  *
00178  */
00179 template <class T> 
00180 class SortedPair: public OrderedPair<T, T>
00181 {
00182 public:
00183   SortedPair(const T& a, const T& b)
00184     : OrderedPair<T, T>(std::min(a, b), std::max(a,b))
00185     {;}
00186 };
00187 
00188 template <class T> inline
00189 std::ostream& operator<<(std::ostream& os, const SortedPair<T>& p)
00190 {
00191   os << "Pair(" << p.first() << ", " << p.second() << ")";
00192   return os;
00193 }
00194 
00195 
00196 /** 
00197  * Form all pairs of multisets that can be generated from an 
00198  * initial pair by adding n copies of entry x. This is used in the
00199  * partitioning of multisets.
00200  */
00201 Set<Pair<MultiSet<int> > >
00202 loadPartitions(int x, int n, 
00203   const MultiSet<int>& left, 
00204   const MultiSet<int>& right);
00205 
00206 
00207 /** 
00208  * Return the size-2 partitions of a multiset. This is used in a recursive
00209  * algorithm to determine all partitions of a multset. 
00210  */
00211 Set<Pair<MultiSet<int> > >
00212 binaryPartition(const MultiSet<int>& m);
00213 
00214 /** 
00215  * Return the partitions of a multiset. The partitions are sets
00216  * of subsets such that the union of the members equals the original
00217  * multiset. 
00218  */
00219 Set<MultiSet<MultiSet<int> > >
00220 multisetPartitions(const MultiSet<int>& m);
00221 
00222 /** 
00223  * Given a multiset, create a mapping from entry to number of repetitions
00224  * in the multisets.
00225  */
00226 Map<int, int> countMap(const MultiSet<int>& m);
00227 
00228 
00229 /** */
00230 template <class T> inline
00231 Array<Array<Array<T> > > indexArrangements(const MultiSet<T>& mu,
00232   const Array<int>& k)
00233 {
00234   int nBins = k.size();
00235     
00236   int M = 0;
00237   for (int i=0; i<nBins; i++)
00238   {
00239     M += k[i];
00240   }
00241     
00242   Array<T> I;
00243   typename MultiSet<T>::const_iterator iter;
00244   for (iter=mu.begin(); iter!=mu.end(); iter++)
00245   {
00246     I.append(*iter);
00247   }
00248 
00249   Array<Array<Array<T> > > rtn;
00250     
00251   do
00252   {
00253     Array<Array<T> > bins(nBins);
00254     int count = 0;
00255     for (int i=0; i<nBins; i++)
00256     {
00257       for (int j=0; j<k[i]; j++)
00258       {
00259         bins[i].append(I[count++]);
00260       }
00261     }
00262     rtn.append(bins);
00263   }
00264   while (std::next_permutation(I.begin(), I.end()));
00265   return rtn;
00266 }
00267 
00268 /** 
00269  * Return the distinct arrangements of the given multiset into n bins
00270  */
00271 template <class T> inline
00272 Array<Array<Array<T> > > binnings(const MultiSet<T>& mu, int n)
00273 {
00274   int N = mu.size();
00275   Array<Array<int> > c = compositions(N)[n-1];
00276   Array<Array<Array<T> > > rtn;
00277 
00278   for (int i=0; i<c.size(); i++)
00279   {
00280     Array<Array<Array<T> > > a = indexArrangements(mu, c[i]);
00281     for (int j=0; j<a.size(); j++)
00282     {
00283       rtn.append(a[j]);
00284     }
00285   }
00286   return rtn;
00287 }
00288 
00289 
00290 inline int factorial(const MultiSet<int>& ms)
00291 {
00292   Sundance::Map<int, int> counts;
00293     
00294   for (MultiSet<int>::const_iterator i=ms.begin(); i!=ms.end(); i++)
00295   {
00296     if (counts.containsKey(*i)) counts[*i]++;
00297     else counts.put(*i, 1);
00298   }
00299 
00300   int rtn = 1;
00301   for (Sundance::Map<int, int>::const_iterator
00302          i=counts.begin(); i!=counts.end(); i++)
00303   {
00304     int f = 1;
00305     for (int j=1; j<=i->second; j++) f *= j;
00306     rtn *= f;
00307   }
00308   return rtn;
00309 }
00310 
00311 
00312 }
00313 
00314 
00315 
00316 #endif
00317 
00318 
00319 

Site Contact