(This question emerged from discussions in this post.)
Context and code sample:
I am trying to figure out if there is a way to generate two $a$ and $b,$ comprised of $n_a$ and $n_b$ integers which are sampled from a given discrete distribution dist
, such that the sums of the two lists are equal (i.e. Total@a == Total@b
).
For the sake of discussion, the distribution can either be a custom one, such as:
distcustom = {0.17525, 0.329672, 0.2882, 0.14761, 0.04771, 0.0101, 0.001362, \
0.0001141, 0.0000001}
which can be histogram of the integers, here 1
has a probability 0.17525
, 2
has a probability 0.329672
etc.
Or a more common one, such as a Poisson distribution:
dist = Table[N@PDF[PoissonDistribution[3], i], {i, 9}]
{0.149361, 0.224042, 0.224042, 0.168031, 0.100819, 0.0504094, \ 0.021604, 0.00810151, 0.0027005}
Sampling integers from given distribution:
To sample lists of desired number of integers from such dists without imposing the sum condition, in other words creating sequences of integers from a distribution, we can do:
Say we want a list of 10 elements:
For a built-in distribution such as PoissonDistribution
we can use:
sequence = {};
sequence = RandomVariate[PoissonDistribution[3], 10]
from an input custom distribution/histogram such as distcustom
we can use:
repeat[m_, n_Integer?Positive] := Sequence @@ ConstantArray[m, n]
sequence = {};
(*we generate a long list of integers sampled from distcustom, then later we randomsample from it*)
For[i = 1, i <= Length[distcustom], i++,
tmpval = IntegerPart[Round[10000*distcustom[[i]]]];
If[tmpval == 0, tmpval = 1];
sequence = Join[sequence, {repeat[i, tmpval]}];
];
Two approaches come to mind:
Generating the
a
andb
lists separately: We could e.g. generate a long list of integerssampledls
sampled according todist
, this could for example be a list of a million integers for higher accuracy. Then to create saya
, we keep trying to extractn_a
element sublists fromsampledls
and similarly for listb
, until we find two sublists that satisfyTotal@a == Total@b
.Partitioning a larger list into the smaller lists of
a
andb
: We generate a list of $n_a+n_b$ integers sampled from dist, let’s denote byab
, then we try various partitions ofab
into two lists ofa
andb
having $n_a$ and $n_b$ elements respectively, until we find a partition which satisfiesTotal@a == Total@b
.
Intuitively, the second one seems to be a more efficient approach (as we sample once from the dist, then the computation boils down to creating partitions/pairs of given sizes).
Do any of these approaches seem sound? would an approach similar to the second one be indeed the more efficient one to opt for?
Is there possibly a simpler way to go about solving this problem by better exploiting the built-in functionalities of Mathematica? To re-iterate the problem again:
Generating two lists $a$ and $b,$ comprised of given $n_a$ and $n_b$ integers which are sampled from a given discrete distribution
dist
, such that the sums of the two lists are equal (i.e.Total@a ==Total@b
).