NAME
    Algorithm::RandomMatrixGeneration - Perl module to generate matrix given
    the marginals.

SYNOPSIS
      use Algorithm::RandomMatrixGeneration;
      generateMatrix(\@row_marginals, \@col_marginals, 10, 3);
      OR
      generateMatrix(\@row_marginals, \@col_marginals, 10);

      Example: If @row_marginals = (3,2,3,2) and @col_marginals = (2,2,2,2,2);
      The following output matrix could be generated by the module:
      0    0    0    1    2
      1    0    1    0    0
      1    0    1    1    0
      0    2    0    0    0

DESCRIPTION
    This module generates matrix given the row and the column marginals in
    such a way that the row and the column marginals of the resultant matrix
    are same as the given marginals. For example, given the following
    marginals this module would generate the appropriate values for "x"s
    such that the row and the column marginals are held fixed. 
	x x x x x | 3
    x x x x x | 2 
	x x x x x | 3 
	x x x x x | 2 
	---------------
    2 2 2 2 2 | 10

    The algorithm we have used here: For each cell while traversing the
    matrix in in row-major interpretation. 1. Generate random number using
    the steps given below. 2. Reduce row and column marginals by value of
    generated value. End for. Done.

    Random number generation algorithm: for each cell C(i,j) { # Find the
    range (min, max) for the random number generation max = MIN(row_marg[i],
    col_marg[j])

        # If max !=0 then decide the min.
        # To decide min value sum together the col_marginals for all
        # the columns past the current column - this sum gives the total
        # of the column marginals yet to be satisfied beyond the current col.
        # Subtract this sum from the current row_marginal to compute
        # the lower bound on the random number. We do this because if we
        # do not set this lower bound and thus a number smaller than this
        # bound is generated then we will have a situation where satisfying
        # both row_marginal and column marginals will be impossible.

        if(max != 0)
        {
            2_term = 0
            for each col k > j
            {
                2_term = 2_term + col_marg[k]
            }
            min = row_marg[i] - 2_term
            if(min < 0)
            {
                min = 0
            }
        }
        else
        {
            min = max = 0   # If max = 0 then min = 0
        }

        # Generate random number between the range   
        random_num = rand(min, max)
    }

    Example: 
	  Cell 0: 
	  max = MIN(3,2) = 2 
	  2_term = 2 + 2 + 2 + 2 = 8 
	  min = 3 - 8 = -5 
	  therefore: min = 0 
	  (min, max) = (0,2) = 0 
	  0	x x x x | 3 
	  x x x x x | 2 
	  x x x x x | 3 
	  x x x x x | 2
      -------------- 
	  2 2 2 2 2 |

      Cell 1:
      max = MIN(3,2) = 2
      2_term = 2 + 2 + 2 = 6
      min = 3 - 6 = -3
      therefore: min = 0
      (min, max) = (0,2) = 0
      0    0    x    x    x    |  3
      x    x    x    x    x    |  2
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      2    2    2    2    2    |

      Cell 2:
      max = MIN(3,2) = 2
      2_term = 2 + 2 = 4
      min = 3 - 4 = -1
      therefore: min = 0
      (min, max) = (0,2) = 0
      0    0    0    x    x    |  3
      x    x    x    x    x    |  2
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      2    2    2    2    2    |

      Cell 3:
      max = MIN(3,2) = 2
      2_term = 2
      min = 3 - 2 = 1
      (min, max) = (1,2) = 1
      0    0    0    1    x    |  2
      x    x    x    x    x    |  2
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      2    2    2    1    2    |

      Cell 4:
      max = MIN(2,2) = 2
      2_term = 0
      min = 2 - 0 = 2
      (min, max) = (2,2) = 2
      0    0    0    1    2    |  0
      x    x    x    x    x    |  2
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      2    2    2    1    0    |

      Cell 5:
      max = MIN(2,2) = 2
      2_term = 2 + 2 + 1 + 0 = 5
      min = 3 - 5 = -2
      therefore, min = 0
      (min, max) = (0,2) = 1
      0    0    0    1    2    |  0
      1    x    x    x    x    |  1
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      1    2    2    1    0    |

      Cell 6:
      max = MIN(1,2) = 1
      2_term = 2 + 1 + 0 = 3
      min = 1 - 3 = -2
      therefore, min = 0
      (min, max) = (0,1) = 0
      0    0    0    1    2    |  0
      1    0    x    x    x    |  1
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      1    2    2    1    0    |

      Cell 7:
      max = MIN(1,2) = 1
      2_term = 1 + 0 = 1
      min = 1 - 1 = 0
      (min, max) = (0,1) = 1
      0    0    0    1    2    |  0
      1    0    1    x    x    |  0
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      1    2    1    1    0    |

      Cell 8:
      max = MIN(0,1) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    x    |  0
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      1    2    1    1    0    |

      Cell 9:
      max = MIN(0,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      x    x    x    x    x    |  3
      x    x    x    x    x    |  2
      ----------------------------------------------
      1    2    1    1    0    |

      Cell 10:
      max = MIN(3,1) = 1
      2_term = 2 + 1 + 1 + 0 = 4
      min = 3 - 4 = -1
      therefore, min = 0
      (min, max) = (0,1) = 1
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    x    x    x    x    |  2
      x    x    x    x    x    |  2
      ----------------------------------------------
      0    2    1    1    0    |

      Cell 11:
      max = MIN(2,2) = 2
      2_term = 1 + 1 + 0 = 2
      min = 2 - 2 = 0
      (min, max) = (0,2) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    x    x    x    |  2
      x    x    x    x    x    |  2
      ----------------------------------------------
      0    2    1    1    0    |

      Cell 12:
      max = MIN(2,1) = 1
      2_term = 1 + 0 = 1
      min = 2 - 1 = 1
      (min, max) = (1,1) = 1
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    x    x    |  1
      x    x    x    x    x    |  2
      ----------------------------------------------
      0    2    0    1    0    |

      Cell 13:
      max = MIN(1,1) = 1
      2_term = 0 = 0
      min = 1 - 0 = 1
      (min, max) = (1,1) = 1
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    x    |  0
      x    x    x    x    x    |  2
      ----------------------------------------------
      0    2    0    0    0    |

      Cell 14:
      max = MIN(0,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      x    x    x    x    x    |  2
      ----------------------------------------------
      0    2    0    0    0    |

      Cell 15:
      max = MIN(2,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      0    x    x    x    x    |  2
      ----------------------------------------------
      0    2    0    0    0    |

      Cell 16:
      max = MIN(2,2) = 2
      2_term = 0 + ... = 0
      min = 2 - 0 = 2
      (min, max) = (2,2) = 2
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      0    2    x    x    x    |  0
      ----------------------------------------------
      0    0    0    0    0    |

      Cell 17:
      max = MIN(0,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      0    2    0    x    x    |  0
      ----------------------------------------------
      0    0    0    0    0    |

      Cell 18:
      max = MIN(0,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      0    2    0    0    x    |  0
      ----------------------------------------------
      0    0    0    0    0    |

      Cell 19:
      max = MIN(0,0) = 0
      min = 0
      (min, max) = (0,0) = 0
      0    0    0    1    2    |  0
      1    0    1    0    0    |  0
      1    0    1    1    0    |  0
      0    2    0    0    0    |  0
      ----------------------------------------------
      0    0    0    0    0    |

      Done!!

  EXPORT
    generateMatrix

AUTHOR
     Anagha Kulkarni, E<lt>kulka020@d.umn.eduE<gt>
     Ted Pedersen, E<lt.tpederse@d.umn.eduE<gt> 

COPYRIGHT AND LICENSE
    Copyright (C) 2006 by Anagha Kulkarni, Ted Pedersen

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version. This program is distributed in the hope that
    it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.