Hi
I am the original poster, and as Valeri has implied, I've had to do a
lot of thinking about what I mean by random. The problem that I am
working with is generating composite genotypes where total numbers are
specified for separate parts of the genotype. The column totals
represent genotype totals for a subset of genes, and the row totals are
genotype totals for another subset of genes. The resulting matrix is
totals for possible combined genotypes. The method that I have been
working with is shown in the following function definition. (I
appologise for its procedural style and for the sparse form of the
output (the next function translates the sparse form back into an
ordinary table form)). It starts with row 1 and column 1 and treats it
as a problem of selection without replacement. It then goes to column
2 and chooses from what is left. The ends of the rows and columns just
get whatever is left over. This method sometimes makes impossible
choices, in which case I have it try again. Some solutions are found
much more often than others, but it is now clear to me that for my
problem, some of them are, in fact, much more probable than others.
For my original example of {7,3,2} and {2,9,1}, in 10000 tries all 17
possibilities occurred but I got {{0, 7, 0}, {0, 2, 1}, {2, 0, 0}} 47
times and {{1, 5, 1}, {1, 2, 0}, {0, 2, 0}} 1897 times. I'd like to
thank all of the posters for the light that they have shed on the
problem. It has been very educational for me. Of course I'd
appreciate any further tips on how to make things more efficient or
correct now that I've expressed my problem more thoroughly.
Thanks
Art
<< Statistics`DiscreteDistributions`;
distributeRowAndColumnSums[rowSums_, columnSums_] := Module[
{totalCount = Plus @@ rowSums,
matrix = {},
numberOfRows = Length[rowSums],
numberOfColumns = Length[columnSums],
remainingInColumns = columnSums,
totalRemaining, remainingInRow, toChooseFrom, selected},
totalRemaining = totalCount;
Do[
remainingInRow = rowSums[[r]];
toChooseFrom = totalRemaining;
Do[selected = Random[HypergeometricDistribution[remainingInRow,
remainingInColumns[[c]], toChooseFrom]];
toChooseFrom -= remainingInColumns[[c]];
If[selected > 0,
AppendTo[matrix, {selected, {r, c}}];
totalRemaining -= selected;
remainingInRow -= selected;
remainingInColumns[[c]] -= selected,
Null],
{c, numberOfColumns - 1}];
If[
remainingInRow > 0,
AppendTo[matrix, {remainingInRow, {r, numberOfColumns}}];
totalRemaining -= remainingInRow,
Null],
{r, numberOfRows - 1}];
Do[
If[remainingInColumns[[c]] > 0,
AppendTo[matrix, {remainingInColumns[[c]], {numberOfRows, c}}];
totalRemaining -= remainingInColumns[[c]],
Null],
{c, numberOfColumns - 1}];
Which[
totalRemaining > 0,
AppendTo[matrix, {totalRemaining, {numberOfRows,
numberOfColumns}}];
matrix,
totalRemaining == 0,
matrix,
totalRemaining < 0,
Print["row and column distribution failure"];
distributeRowAndColumnSums[rowSums, columnSums, totalCount]]
];
matrixFromSparse[numberOfRows_Integer, numberOfColumns_Integer,
sparseMatrix_] := Module[{matrix = Table[0, {numberOfRows},
{numberOfColumns}]},
Do[matrix[[sparseMatrix[[i, 2, 1]], sparseMatrix[[i, 2, 2]]]] =
sparseMatrix[[i, 1]],
{i, Length[sparseMatrix]}];
matrix]