private void CheckPartitions(int n) { // Some sets to make sure partition and conjugate only appear once. // Also tests equality, hash set. HashSet <IntegerPartition> set = new HashSet <IntegerPartition>(); HashSet <IntegerPartition> conjugateSet = new HashSet <IntegerPartition>(); foreach (IntegerPartition partition in AdvancedIntegerMath.Partitions(n)) { Assert.IsTrue(partition != null); // Values should add to number. int vCount = 0; foreach (int v in partition.Values) { Assert.IsTrue(v > 0); vCount += v; } Assert.IsTrue(vCount == n); // Elements should add to number. int eCount = 0; foreach (Element e in partition.Elements) { Assert.IsTrue(e.Value > 0); Assert.IsTrue(e.Multiplicity > 0); eCount += e.Value * e.Multiplicity; } Assert.IsTrue(eCount == n); // Partition should be generated only once Assert.IsTrue(!set.Contains(partition)); set.Add(partition); IntegerPartition conjugate = partition.Conjugate(); // Conjugate values should add to same number int cCount = 0; foreach (int c in conjugate.Values) { Assert.IsTrue(c > 0); cCount += c; } Assert.IsTrue(cCount == n); // Conujate should be generated only once Assert.IsTrue(!conjugateSet.Contains(conjugate)); conjugateSet.Add(conjugate); // Rank should fulfill inequality and be related to conjugate rank Assert.IsTrue((-n < partition.Rank) && (partition.Rank < n)); Assert.IsTrue(conjugate.Rank == -partition.Rank); // Double-conjugating should return us to the original Assert.IsTrue(conjugate.Conjugate() == partition); } }
public void IntegerPartitionCounts() { // these counts are from Table 21.5 of Abromowitz & Stegun Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(1)) == 1); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(2)) == 2); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(3)) == 3); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(4)) == 5); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(5)) == 7); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(6)) == 11); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(7)) == 15); Assert.IsTrue(CountValues(AdvancedIntegerMath.Partitions(8)) == 22); }
public void IntegerPartitionSums() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 100, 5)) { foreach (int[] partition in AdvancedIntegerMath.Partitions(n)) { int s = 0; foreach (int i in partition) { s += i; } Assert.IsTrue(s == n); } } }
// Faa di Bruno's formula expresses raw moments in terms of cumulants. // M_r = \sum_{m_1 + \cdots + m_k = r} \frac{r!}{m_1 \cdots m_k} K_1 \cdots K_k // That is: take all partitions of r. (E.g. for r = 4, thre are 5 partitions: 1 + 1 + 1 + 1 = 4, 1 + 1 + 2 = 4, 2 + 2 = 4, 1 + 3 = 4, and 4 = 4). // Each partition will contribute one term. Each appearance of an integer k in the partition will contribute one factor of the kth cumulant // to that term. (E.g. K_1^4, K_1^2 K_2, K_2^2, K_1 K_3, and K_4.) // Each term has a combinatoric factor of r! divided by the product of all the integers in the partition. (E.g. 1^4, 1^2 * 2, 2^2, 1 * 3, and 4.) internal static double CumulantToMoment(double[] K, int r, bool central) { double M = 0.0; foreach (int[] partition in AdvancedIntegerMath.Partitions(r)) { double dM = AdvancedIntegerMath.Factorial(r); int u = 0; // tracks the last observed partition member int m = 1; // tracks the multiplicity of the current partition member foreach (int v in partition) { // if we are computing central moments, ignore all terms with a factor of K_1 if (central && (v == 1)) { dM = 0.0; break; } if (v == u) { m++; } else { m = 1; } dM *= K[v] / AdvancedIntegerMath.Factorial(v) / m; u = v; } M += dM; } return(M); // This method of reading out a partition is a bit klunky. We really want to know the multiplicity of each element, // but that isn't straightforwardly available. In fact, this method will break if identical elements are not adjacent // in the array (e.g. 4 = 1 + 2 + 1 + 1). Would be nice to address this, perhaps by actually returning a multiplicity // representation of parititions. }
private long PartitionFunction(int n) { return(AdvancedIntegerMath.Partitions(n).LongCount()); }