Skip to content

Commit

Permalink
Improve IntegerPartitions
Browse files Browse the repository at this point in the history
  • Loading branch information
axkr committed Nov 3, 2024
1 parent cf039b6 commit b0a383b
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.Map;
import java.util.Set;
import org.matheclipse.core.basic.Config;
import org.matheclipse.core.basic.OperationSystem;
import org.matheclipse.core.combinatoric.KPartitionsIterable;
import org.matheclipse.core.combinatoric.KPartitionsList;
import org.matheclipse.core.combinatoric.KSubsetsIterable;
Expand Down Expand Up @@ -821,7 +820,39 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
max = range.maximum();
}
if (ast.isAST3()) {
return frobeniusPartition(ast, engine);
IExpr kspec = ast.arg2();
if (ast.arg3().equals(S.All)) {
// IntegerPartitions(n_Integer, kspec_, All) := IntegerPartitions(n, kspec)
return F.IntegerPartitions(F.ZZ(n), kspec);
}
if (ast.arg3().isList()) {
IAST s = (IAST) ast.arg3();
if (kspec.isList1() && kspec.first().isInteger()) {
IInteger k = (IInteger) kspec.first();
// "IntegerPartitions(n_Integer, {k_Integer}, s_List) :=
// ReverseSort@Select(Union(ReverseSort /@ Tuples(s, k)), Total(#) == n &),
return F.ReverseSort(F.Select(F.Union(F.Map(S.ReverseSort, F.Tuples(s, k))),
F.Function(F.Equal(F.Total(F.Slot1), n))));
}
if (!s.forAll(x -> x.isInteger() && x.isPositive())) {
return F.NIL;
}
}
IExpr frobeniusPartition = frobeniusPartition(ast, engine);
if (frobeniusPartition.isList()) {
IASTMutable mutableList = ((IAST) frobeniusPartition).copy();
EvalAttributes.sort(mutableList,
Comparators.reversedComparator(Comparators.LEXICAL_COMPARATOR));
return mutableList;
}
return F.NIL;
} else if (ast.argSize() == 4) {
IExpr kspec = ast.arg2();
IExpr sspec = ast.arg3();
IExpr m = ast.arg4();
// "IntegerPartitions(n_Integer, kspec_, sspec_, m_) := Take(IntegerPartitions(n, k,
// sspec), m)",
return F.Take(F.IntegerPartitions(F.ZZ(n), kspec, sspec), m);
}

if (n == 0) {
Expand Down Expand Up @@ -979,10 +1010,11 @@ private static boolean createFrobeniusSolution(IInteger[] frobeniusSolution,

@Override
public int[] expectedArgSize(IAST ast) {
return ARGS_1_3;
return ARGS_1_4;
}
}


/**
*
*
Expand Down Expand Up @@ -1055,6 +1087,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}


private static final class KOrderlessPartitions extends AbstractFunctionEvaluator {

/** {@inheritDoc} */
Expand Down Expand Up @@ -1157,6 +1190,7 @@ private IAST createSinglePartition(final IAST listArg0, final ISymbol symbol,
}
}


/**
* Generate a list of all all k-partitions for a given list with N elements. <br>
* See <a href="http://en.wikipedia.org/wiki/Partition_of_a_set">Wikipedia - Partition of a
Expand Down Expand Up @@ -1189,6 +1223,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1256,6 +1291,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}


/**
*
*
Expand Down Expand Up @@ -1352,6 +1388,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1474,6 +1511,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1540,6 +1578,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1595,6 +1634,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1699,6 +1739,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1754,6 +1795,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -1852,6 +1894,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -2068,6 +2111,7 @@ private IAST createPermutationsWithNParts(final IAST list, int parts,
}
}


private static final class PolygonalNumber extends AbstractFunctionEvaluator {

@Override
Expand All @@ -2093,6 +2137,7 @@ public void setUp(final ISymbol newSymbol) {
}
}


/**
*
*
Expand Down Expand Up @@ -2174,6 +2219,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}


/**
*
*
Expand Down Expand Up @@ -2250,6 +2296,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}


/**
*
*
Expand Down Expand Up @@ -2316,6 +2363,7 @@ public int[] expectedArgSize(IAST ast) {
}
}


/**
*
*
Expand Down Expand Up @@ -2397,6 +2445,7 @@ public void setUp(final ISymbol newSymbol) {
}
}


/**
*
*
Expand Down Expand Up @@ -2585,6 +2634,7 @@ public static KSubsetsList createKSubsets(final IAST list, final int k, IAST res
}
}


/**
*
*
Expand Down Expand Up @@ -2734,6 +2784,7 @@ private void tuplesOfListsRecursive(final IAST originalList, final int k, IASTAp
}
}


/**
*
*
Expand Down Expand Up @@ -2815,6 +2866,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}


/**
* Generate an <code>java.lang.Iterable</code> for (multiset) permutations
*
Expand Down Expand Up @@ -2965,6 +3017,7 @@ public KPermutationsIterable(final int[] data, final int len, final int parts) {
public Iterator<int[]> iterator() {
return new KPermutationsIterator();
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5318,6 +5318,10 @@ public static IAST IntegerPart(final IExpr a0) {
return new AST1(IntegerPart, a0);
}

public static IAST IntegerPartitions(final IExpr n, final IExpr k) {
return new AST2(IntegerPartitions, n, k);
}

public static IAST IntegerPartitions(final IExpr n, final IExpr k, final IExpr p) {
return new AST3(IntegerPartitions, n, k, p);
}
Expand Down Expand Up @@ -9017,6 +9021,10 @@ public static IAST Reverse(final IExpr a) {
return new AST1(Reverse, a);
}

public static IAST ReverseSort(final IExpr a) {
return new AST1(ReverseSort, a);
}

public static IAST RomanNumeral(final IExpr a) {
return new AST1(RomanNumeral, a);
}
Expand Down Expand Up @@ -9808,6 +9816,11 @@ public static IExpr subst(IExpr expr, IExpr subExpr, IExpr replacementExpr) {
.orElse(expr);
}

public static IAST SubsetQ(IExpr x, IExpr y) {
return new AST2(S.SubsetQ, x, y);
}


/**
* Return <code>x + (-1)*y</code>
*
Expand Down Expand Up @@ -10648,6 +10661,10 @@ public static IAST TrueQ(final IExpr expr) {
return new AST1(TrueQ, expr);
}

public static IAST Tuples(final IExpr x, final IExpr y) {
return new AST2(Tuples, x, y);
}

/**
* Create a function <code>head(arg)</code> with 1 argument without evaluation.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,80 @@ public void testFindPermutation() {
"Cycles({{2,3},{4,6,5}})");
}

@Test
public void testIntegerPartitions() {
// TODO
check("IntegerPartitions(1,7,{-1,-2,3})", //
"IntegerPartitions(1,7,{-1,-2,3})");

check("IntegerPartitions(8, All, {1, 2, 5})", //
"{{5,2,1},{5,1,1,1},{2,2,2,2},{2,2,2,1,1},{2,2,1,1,1,1},{2,1,1,1,1,1,1},{1,1,1,1,\n" //
+ "1,1,1,1}}");

check("IntegerPartitions(5)", //
"{{5},{4,1},{3,2},{3,1,1},{2,2,1},{2,1,1,1},{1,1,1,1,1}}");
check("IntegerPartitions(8,3)", //
"{{8},{7,1},{6,2},{6,1,1},{5,3},{5,2,1},{4,4},{4,3,1},{4,2,2},{3,3,2}}");
check("IntegerPartitions(8,{3})", //
"{{6,1,1},{5,2,1},{4,3,1},{4,2,2},{3,3,2}}");
check("IntegerPartitions(8, All, {1, 2, 5})", //
"{{5,2,1},{5,1,1,1},{2,2,2,2},{2,2,2,1,1},{2,2,1,1,1,1},{2,1,1,1,1,1,1},{1,1,1,1,\n" //
+ "1,1,1,1}}");
check("IntegerPartitions(8, All, All, 3)", //
"{{8},{7,1},{6,2}}");
check("IntegerPartitions(4, {2}, {-1, 0, 1, 4, 5})", //
"{{5,-1},{4,0}}");

// message Maximum AST dimension 2147483647 exceededs
check("IntegerPartitions(2147483647)", //
"IntegerPartitions(2147483647)");

// TODO improve performance
// check("IntegerPartitions(1009,2)", //
// "{{1009}}");
check("IntegerPartitions(1009,1)", //
"{{1009}}");
check("IntegerPartitions(1009,0)", //
"{}");

check("IntegerPartitions(50, All, {6, 9, 20})", //
"{{20,9,9,6,6},{20,6,6,6,6,6}}");
// https://oeis.org/A214772 - McNugget partitions - Number of partitions of n into parts 6, 9 or
// 20.
check("Table(Length(IntegerPartitions(i, All, {6, 9, 20})), {i,0, 100, 1})", //
"{1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,2,0,1,1,0,0,2,0,1,2,0,1,2,0,1,2,0,1,3,0,2,2,\n"
+ "1,1,3,0,2,3,1,2,3,1,2,3,1,2,4,1,3,3,2,2,5,1,3,4,2,3,5,2,3,5,2,3,6,2,4,5,3,3,7,2,\n"
+ "5,6,3,4,7,3,5,7,3,5,8,3,6,7,4,5,9,3,7,8,5}");

// check("IntegerPartitions(50, All, {6, 9, 20})", //
// "{{20,9,9,6,6},{20,6,6,6,6,6}}");
check("IntegerPartitions(156, {9,10}, {1, 5, 10, 25})", //
"{{25,25,25,25,25,10,10,10,1},{25,25,25,25,25,10,10,5,5,1}}");
check("IntegerPartitions(156, 10, {1, 5, 10, 25})", //
"{{25,25,25,25,25,25,5,1},{25,25,25,25,25,10,10,10,1},{25,25,25,25,25,10,10,5,5,1}}");
check("IntegerPartitions(4)", //
"{{4},{3,1},{2,2},{2,1,1},{1,1,1,1}}");
check("IntegerPartitions(6)", //
"{{6},{5,1},{4,2},{4,1,1},{3,3},{3,2,1},{3,1,1,1},{2,2,2},{2,2,1,1},{2,1,1,1,1},{\n" //
+ "1,1,1,1,1,1}}");
check("IntegerPartitions(6, {3,4})", //
"{{4,1,1},{3,2,1},{3,1,1,1},{2,2,2},{2,2,1,1}}");
check("IntegerPartitions(10,2)", //
"{{10},{9,1},{8,2},{7,3},{6,4},{5,5}}");
check("IntegerPartitions(10,{2})", //
"{{9,1},{8,2},{7,3},{6,4},{5,5}}");
check("IntegerPartitions(0)", //
"{{}}");
check("IntegerPartitions(1)", //
"{{1}}");
check("IntegerPartitions(-1)", //
"{}");
check("IntegerPartitions(.5)", //
"IntegerPartitions(0.5)");
check("IntegerPartitions(1/2)", //
"{}");
}

@Test
public void testPermute() {
check("Permute(CharacterRange(\"v\", \"z\"), Cycles({{1, 5, 3}}))", //
Expand Down

0 comments on commit b0a383b

Please sign in to comment.