def _generate_prob_profiles(num_items, num_slots):
    """Another implementation of `distribution` for test purposes.

  This function is the original implementation from Karl. jblespiau@ find it
  useful to add it here as: 1) an additional test of our function 2) a check
  that the initial code is correct too.

  Args:
    num_items: The number of items to distribute.
    num_slots: The number of slots.

  Returns:
    A numpy array of shape [num_distributions, num_slots].
  """
    if num_slots == 1:
        return np.array([num_items])

    num_rows = utils.n_choose_k(num_items + num_slots - 1, num_items)
    distributions = np.empty([num_rows, num_slots])

    ind = 0
    for i in range(0, num_items + 1):
        n_tmp = num_items - i
        k_tmp = num_slots - 1
        distributions_tmp = _generate_prob_profiles(n_tmp, k_tmp)
        distributions[ind:ind +
                      np.shape(distributions_tmp)[0], :] = np.column_stack(
                          (np.array(
                              (np.ones(np.shape(distributions_tmp)[0]) * i)),
                           distributions_tmp))
        ind = ind + np.shape(distributions_tmp)[0]

    return distributions
 def test_construction(self, num_players, num_strategies):
     logging.info("Testing payoff table construction.")
     table = heuristic_payoff_table.PayoffTable(num_players, num_strategies)
     num_rows = utils.n_choose_k(num_players + num_strategies - 1,
                                 num_players)
     distributions = np.array(
         list(utils.distribute(num_players, num_strategies)))
     payoffs = np.full([int(num_rows), num_strategies], np.nan)
     np.testing.assert_array_equal(
         np.concatenate([distributions, payoffs], axis=1), table())
 def test_distribution(self, num_items, num_slots, normalize):
     distribution = list(utils.distribute(num_items, num_slots, normalize))
     # Correct length.
     # See https://en.wikipedia.org/wiki/Stars_and_bars_%28combinatorics%29.
     self.assertLen(distribution,
                    utils.n_choose_k(num_items + num_slots - 1, num_items))
     # No duplicates.
     self.assertLen(distribution, len(set(distribution)))
     sum_distribution = num_items if not normalize else 1
     for d in distribution:
         self.assertTrue(sum_distribution, sum(d))
         self.assertTrue((np.asarray(d) >= 0).all())