Title: | Permutations of Multisets in Cool-Lex Order |
---|---|
Description: | A set of tools to permute multisets without loops or hash tables and to generate integer partitions. The permutation functions are based on C code from Aaron Williams. Cool-lex order is similar to colexicographical order. The algorithm is described in Williams, A. Loopless Generation of Multiset Permutations by Prefix Shifts. SODA 2009, Symposium on Discrete Algorithms, New York, United States. The permutation code is distributed without restrictions. The code for stable and efficient computation of multinomial coefficients comes from Dave Barber. The code can be download from <http://tamivox.org/dave/multinomial/index.html> and is distributed without conditions. The package also generates the integer partitions of a positive, non-zero integer n. The C++ code for this is based on Python code from Jerome Kelleher which can be found here <https://jeromekelleher.net/category/combinatorics.html>. The C++ code and Python code are distributed without conditions. |
Authors: | James Curran, Aaron Williams, Jerome Kelleher, Dave Barber |
Maintainer: | James Curran <[email protected]> |
License: | GPL-2 |
Version: | 1.0.1 |
Built: | 2024-11-10 03:59:02 UTC |
Source: | https://github.com/jmcurran/multicool |
This function will return all permutations of a multiset
allPerm(mcObj)
allPerm(mcObj)
mcObj |
an object of class mc - usually generated by |
This function will return all permutations of a multiset. It makes no check
to see if this is a sensible thing to do. Users are advised to check how
many permutations are possible using the multinom
function in this
package.
A matrix with each row being a different permutation of the multiset
This function does not warn the user that the requested set of permutations may be very large. In addition, all working is handled entirely in memory, and so this may cause it to crash if the request is execeptionally large.
James M. Curran
## a small numeric example with 6 permuations x = c(1,1,2,2) m = initMC(x) allPerm(m) ## a large character example - 60 possibilities x = rep(letters[1:3], 3:1) multinom(x) ## calculate the number of permutations m = initMC(x) allPerm(m)
## a small numeric example with 6 permuations x = c(1,1,2,2) m = initMC(x) allPerm(m) ## a large character example - 60 possibilities x = rep(letters[1:3], 3:1) multinom(x) ## calculate the number of permutations m = initMC(x) allPerm(m)
This function computes the Bell numbers, which is the summ of Stirling
numbers of the second kind, , over
, i.e.
Bell(n) B(n)
Bell(n) B(n)
n |
A vector of one or more non-zero positive integers |
An vector of Bell numbers
B()
: Compute the Bell numbers
James Curran
https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind#Recurrence_relation
Stirling2
## returns B(6) Bell(6) ## returns B(1), B(2), ..., B(6) B(1:6)
## returns B(6) Bell(6) ## returns B(1), B(2), ..., B(6) B(1:6)
This function will return either all, or a length restricted subset of the integer partitions of an integer n. The method works by considering compositions rather than partions, hence the name.
genComp(n, len = TRUE, addZeros = FALSE)
genComp(n, len = TRUE, addZeros = FALSE)
n |
A positive non-zero integer |
len |
Either logical |
addZeros |
If true then the empty partitions are added to the list of partitions. |
This function will return all partions, or a subset, of an integer n. It
makes no check to see if this is a sensible thing to do. It also does it in
a lazy way in that in the restricted case it generates all partitions and
then only returns those that satistfy the length constraint. Users are
advised to check how many partitions are possible using partition number
function which is implemented the P
function in the partions
package. Having said this P(50) is approximately 200 thousand, and P(100)
around 190 million, so the function should work well for smallish n.
A list with each list element representing an integer partition
This function does not warn the user that the requested set of partitions may be very large. In addition, all working is handled entirely in memory, and so this may cause it to crash if the request is execeptionally large.
Jerome Kelleher (algorithm and Python version) and James M. Curran (C++ version/R interface)
Kelleher, J. (2005), Encoding Partitions As Ascending Compositions, PhD thesis, University College Cork.
Kelleher, J. and O'Sullivan, B. (2009), Generating All Partitions: A Comparison Of Two Encodings, https://arxiv.org/abs/0909.2331.
Kelleher, J. (2010) Generating Integer Partitions,https://jeromekelleher.net/tag/integer-partitions.html.
## a small numeric example with all 11 partitions of 6 genComp(6) ## a small example with the integer partitions of 6 of length 3 with empty partitions added genComp(6, 3, TRUE) ## a larger example - 627 partions of 20, but restricted to those of length 3 or smaller genComp(20, 3)
## a small numeric example with all 11 partitions of 6 genComp(6) ## a small example with the integer partitions of 6 of length 3 with empty partitions added genComp(6, 3, TRUE) ## a larger example - 627 partions of 20, but restricted to those of length 3 or smaller genComp(20, 3)
This function initialises the permutation object. It must be called before
nextPerm
can be called
initMC(x)
initMC(x)
x |
a vector of integers, reals, logicals or characters |
a object of class mc
which is a list containing elements
mode |
- the mode of the original data in |
set |
- either the multiset being permuted if |
elements |
- if |
length |
- the length of the multiset |
mc |
- a pointer to the internal C++ Multicool object. Users should not use this unless they really know what they are doing |
James M. Curran
nextPerm
x = c(1,1,2,2) m1 = initMC(x) m1 ## a non-integer example x = rep(letters[1:4],c(2,1,2,2)) m2 = initMC(x) m2
x = c(1,1,2,2) m1 = initMC(x) m1 ## a non-integer example x = rep(letters[1:4],c(2,1,2,2)) m2 = initMC(x) m2
This function calculates the number of permutations of a multiset, this
being the multinomial coefficient. If a set contains
unique
elements
with associate counts (or
multiplicities) of
, then this function returns
where .
multinom(x, counts = FALSE, useDouble = FALSE)
multinom(x, counts = FALSE, useDouble = FALSE)
x |
Either a multiset (with one or more potentially non-unique
elements), or if |
counts |
if |
useDouble |
if |
multinom depends on C++ code written by Dave Barber which can be found at http://tamivox.org/dave/multinomial/code.html. The code may require the STL algorithm library to be included in order to compile it.
A single integer representing the multinomial coefficient for the given multiset, or given set of multiplicities.
James M. Curran, Dave Barber
http://tamivox.org/dave/multinomial/code.html
## An example with a multiset X = (a,a,a,b,b,c) ## There are 3 a s, 2 b s and 1 c, so the answer should be ## (3+2+1)!/(3!2!1!) = 6!/3!2!1! = 60 x = rep(letters[1:3],3:1) multinom(x) ## in this example x is a vector of counts ## the answer should be the same as above as x = c(3,2,1) x = rep(letters[1:3],3:1) x = as.vector(table(x)) #coerce x into a vector of counts multinom(x, counts = TRUE) ## An example of integer overflow. x is a vector of counts ## c(12,11,8,8,6,5). The true answer from Maple is ## 11,324,718,121,789,252,764,532,876,767,840,000 ## The error in the integer based answer is obvious. ## The error using floating point is not, but from Maple is ## 0.705057123232160000e+10 ## Thanks to Lev Dashevskiy for calling my attention to this. ## Not run: x = c(12,11,8,8,6,5) multinom(x, counts = TRUE, useDouble = FALSE) multinom(x, counts = TRUE, useDouble = TRUE) ## End(Not run)
## An example with a multiset X = (a,a,a,b,b,c) ## There are 3 a s, 2 b s and 1 c, so the answer should be ## (3+2+1)!/(3!2!1!) = 6!/3!2!1! = 60 x = rep(letters[1:3],3:1) multinom(x) ## in this example x is a vector of counts ## the answer should be the same as above as x = c(3,2,1) x = rep(letters[1:3],3:1) x = as.vector(table(x)) #coerce x into a vector of counts multinom(x, counts = TRUE) ## An example of integer overflow. x is a vector of counts ## c(12,11,8,8,6,5). The true answer from Maple is ## 11,324,718,121,789,252,764,532,876,767,840,000 ## The error in the integer based answer is obvious. ## The error using floating point is not, but from Maple is ## 0.705057123232160000e+10 ## Thanks to Lev Dashevskiy for calling my attention to this. ## Not run: x = c(12,11,8,8,6,5) multinom(x, counts = TRUE, useDouble = FALSE) multinom(x, counts = TRUE, useDouble = TRUE) ## End(Not run)
This function returns the next permuation of the multiset if there is one.
initMC
called before nextPerm
can be called.
nextPerm(mcObj)
nextPerm(mcObj)
mcObj |
an S3 object of class |
either a vector with the next permutation of the multiset or
FALSE
when all permutations have been returned
James M. Curran
nextPerm
x = c(1,1,2,2) m1 = initMC(x) for(i in 1:6){ cat(paste(paste(nextPerm(m1),collapse=","),"\n")) } ## an example with letters x = letters[1:4] m2 = initMC(x) nextPerm(m2) nextPerm(m2) ## and so on
x = c(1,1,2,2) m1 = initMC(x) for(i in 1:6){ cat(paste(paste(nextPerm(m1),collapse=","),"\n")) } ## an example with letters x = letters[1:4] m2 = initMC(x) nextPerm(m2) nextPerm(m2) ## and so on
This function computes Stirling numbers of the second kind, , which count the number of ways of partitioning n distinct
objects in to k non-empty sets.
Stirling2(n, k) S2(n, k)
Stirling2(n, k) S2(n, k)
n |
A vector of one or more positive integers |
k |
A vector of one or more positive integers |
The implementation on this function is a simple recurrence relation which defines
for
with the inital conditions
and
. If
n
and n
have different lengths then expand.grid
is used to construct a vector of (n, k) pairs
An vector of Stirling numbers of the second kind
S2()
: Compute Stirling numbers of the second kind
James Curran
https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind#Recurrence_relation
## returns S(6, 3) Stirling2(6, 3) ## returns S(6,1), S(6,2), ..., S(6,6) S2(6, 1:6) ## returns S(6,1), S(5, 2), S(4, 3) S2(6:4, 1:3)
## returns S(6, 3) Stirling2(6, 3) ## returns S(6,1), S(6,2), ..., S(6,6) S2(6, 1:6) ## returns S(6,1), S(5, 2), S(4, 3) S2(6:4, 1:3)