Since you mention that you want to compute the total number of possibilities with multiple conditions, and that the conditions consist of equality conditions and total conditions, you might want to try using SatisfiabilityCount
. Since the particles have 4 states, each particle state can be represented by a pair of booleans. For example:
$$\begin{array}{l}
0\leftrightarrow \{F,F\} \\
1\leftrightarrow \{F,T\} \\
2\leftrightarrow \{T,F\} \\
3\leftrightarrow \{T,T\} \\
\end{array}$$
So, with no conditions we have:
vars = Join[Array[a, 19], Array[b, 19]];
SatisfiabilityCount[True, vars]
274877906944
or
4^19
274877906944
as expected. For the condition that the last three states are identical:
SatisfiabilityCount[
Equivalent[a[17], a[18], a[19]] && Equivalent[b[17], b[18], b[19]],
vars
]
17179869184
For the condition that the sum of the first 4 particle states is 5:
SatisfiabilityCount[
Or[
And[
BooleanCountingFunction[{1}, 4][a[1], a[2], a[3], a[4]],
BooleanCountingFunction[{2}, 4][b[1], b[2], b[3], b[4]]
],
And[
BooleanCountingFunction[{3}, 4][a[1], a[2], a[3], a[4]],
BooleanCountingFunction[{1}, 4][b[1], b[2], b[3], b[4]]
]
],
vars
]
42949672960
In order to combine conditions, it will be convenient to have a function that converts equality and total conditions into the equivalent boolean versions. Let each particle be given the name p[n]
. Then, a function that converts conditions to equivalent boolean versions is:
toBool[Verbatim[Equal][x__p]] := Equivalent @@ apart[{x}] && Equivalent @@ bpart[{x}]
toBool[Verbatim[Plus][x__p] == i_Integer] := With[
{len = Length[{x}], ap = Sequence@@apart[{x}], bp = Sequence@@bpart[{x}]},
Or @@ Table[
BooleanCountingFunction[{j}, len][ap] &&
BooleanCountingFunction[{(i-j)/2}, len][bp],
{j, Mod[i,2], i, 2}
]
]
apart[{x__p}] := Apply[a, {x}, {1}]
bpart[{x__p}] := Apply[b, {x}, {1}]
It is possible to add other kinds of conditions (e.g., p[1] + 2 p[2] + 3 p[3] == 6
) if desired.
Repeating my previous examples:
SatisfiabilityCount[toBool[p[17] == p[18] == p[19]], vars]
SatisfiabilityCount[toBool[p[1] + p[2] + p[3] + p[4] == 5], vars]
17179869184
42949672960
Here's a more complicated version, designed to produce a low enough count that I can show each of the instances:
SatisfiabilityCount[
toBool[Sum[p[i], {i, 1, 19, 2}] == 4] &&
toBool[Sum[p[i], {i, 2, 18, 2}] == 2] &&
toBool[p[1] == p[2] == p[3] == p[4] == p[5] == p[6]] &&
toBool[p[10] == p[11] == p[12] == p[13] == p[14] == p[15]] &&
toBool[p[16] + p[17] + p[18] + p[19] == 6],
vars
]
9
If you want to find the set of values for the p[n]
corresponding to the above counts you can use:
bools = SatisfiabilityInstances[
toBool[Sum[p[i], {i, 1, 19, 2}] == 4] &&
toBool[Sum[p[i], {i, 2, 18, 2}] == 2] &&
toBool[p[1] == p[2] == p[3] == p[4] == p[5] == p[6]] &&
toBool[p[10] == p[11] == p[12] == p[13] == p[14] == p[15]] &&
toBool[p[16] + p[17] + p[18] + p[19] == 6],
vars,
All
];
Check that we get the same number of instances:
Length @ bools
9
And a function to convert the booleans into p
values:
toP[bools_] := Table[Boole[bools[[i]]] + 2 Boole[bools[[i+19]]], {i, 19}]
So, the following are the instances:
toP /@ bools //Column //TeXForm
$\begin{array}{l}
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,1,1\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,3\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,1,2\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,0,1\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,3\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,1\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2\} \\
\{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2\} \\
\end{array}$
Tuples
that satisfy the condition, rather than selecting from the entire list those that match the condition. And that requires much more information about what exactly you are trying to do $\endgroup$