# Path: distributions/util.py
# def scores_to_probs(scores):
#     scores = numpy.array(scores)
#     scores -= scores.max()
#     probs = numpy.exp(scores, out=scores)
#     probs /= probs.sum()
#     return probs
# 
# def bin_samples(samples, k=10, support=[]):
#     """
#     Bins a collection of univariate samples into k bins of equal
#     fill via the empirical cdf, to be used in goodness of fit testing.
# 
#     Returns
#     counts : array k x 1
#     bin_ranges : arrary k x 2
# 
#     each count is the number of samples in [bin_min, bin_max)
#     except for the last bin which is [bin_min, bin_max]
# 
#     list partitioning algorithm adapted from Mark Dickinson:
#     http://stackoverflow.com/questions/2659900
#     """
#     samples = sorted(samples)
# 
#     N = len(samples)
#     q, r = divmod(N, k)
#     #we need to distribute the remainder relatively evenly
#     #tests will be inaccurate if we have small bins at the end
#     indices = [i * q + min(r, i) for i in range(k + 1)]
#     bins = [samples[indices[i]: indices[i + 1]] for i in range(k)]
#     bin_ranges = []
#     counts = []
#     for i in range(k):
#         bin_min = bins[i][0]
#         try:
#             bin_max = bins[i + 1][0]
#         except IndexError:
#             bin_max = bins[i][-1]
#         bin_ranges.append([bin_min, bin_max])
#         counts.append(len(bins[i]))
#     if support:
#         bin_ranges[0][0] = support[0]
#         bin_ranges[-1][1] = support[1]
#     return numpy.array(counts), numpy.array(bin_ranges)
# 
# def multinomial_goodness_of_fit(
#         probs,
#         counts,
#         total_count,
#         truncated=False,
#         plot=False):
#     """
#     Pearson's chi^2 test, on possibly truncated data.
#     http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test
# 
#     Returns:
#         p-value of truncated multinomial sample.
#     """
#     assert len(probs) == len(counts)
#     assert truncated or total_count == sum(counts)
#     chi_squared = 0
#     dof = 0
#     if plot:
#         print_histogram(probs, counts)
#     for p, c in zip(probs, counts):
#         if p == 1:
#             return 1 if c == total_count else 0
#         assert p < 1, 'bad probability: %g' % p
#         if p > 0:
#             mean = total_count * p
#             variance = total_count * p * (1 - p)
#             assert variance > 1,\
#                 'WARNING goodness of fit is inaccurate; use more samples'
#             chi_squared += (c - mean) ** 2 / variance
#             dof += 1
#         else:
#             print 'WARNING zero probability in goodness-of-fit test'
#             if c > 0:
#                 return float('inf')
# 
#     if not truncated:
#         dof -= 1
# 
#     survival = scipy.stats.chi2.sf(chi_squared, dof)
#     return survival
# 
# Path: distributions/tests/util.py
# def seed_all(s):
#     import distributions.dbg.random
#     distributions.dbg.random.seed(s)
#     try:
#         import distributions.hp.random
#         distributions.hp.random.seed(s)
#     except ImportError:
#         pass


import numpy
from nose.tools import (
    assert_less,
    assert_less_equal,
    assert_greater,
    assert_list_equal,
)
from distributions.util import (
    scores_to_probs,
    bin_samples,
    multinomial_goodness_of_fit,
)
from distributions.tests.util import seed_all
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



def test_scores_to_probs():
    scores = [-10000, 10000, 10001, 9999, 0, 5, 6, 6, 7]
    probs = scores_to_probs(scores)
    assert_less(abs(sum(probs) - 1), 1e-6)
    for prob in probs:
        assert_less_equal(0, prob)
        assert_less_equal(prob, 1)


def test_multinomial_goodness_of_fit():
    for dim in range(2, 20):
        yield _test_multinomial_goodness_of_fit, dim


def _test_multinomial_goodness_of_fit(dim):
    seed_all(0)
    thresh = 1e-3
    sample_count = int(1e5)
    probs = numpy.random.dirichlet([1] * dim)

    counts = numpy.random.multinomial(sample_count, probs)
    p_good = multinomial_goodness_of_fit(probs, counts, sample_count)
    assert_greater(p_good, thresh)

    unif_counts = numpy.random.multinomial(sample_count, [1. / dim] * dim)

# Path: distributions/util.py
# def scores_to_probs(scores):
#     scores = numpy.array(scores)
#     scores -= scores.max()
#     probs = numpy.exp(scores, out=scores)
#     probs /= probs.sum()
#     return probs
# 
# def bin_samples(samples, k=10, support=[]):
#     """
#     Bins a collection of univariate samples into k bins of equal
#     fill via the empirical cdf, to be used in goodness of fit testing.
# 
#     Returns
#     counts : array k x 1
#     bin_ranges : arrary k x 2
# 
#     each count is the number of samples in [bin_min, bin_max)
#     except for the last bin which is [bin_min, bin_max]
# 
#     list partitioning algorithm adapted from Mark Dickinson:
#     http://stackoverflow.com/questions/2659900
#     """
#     samples = sorted(samples)
# 
#     N = len(samples)
#     q, r = divmod(N, k)
#     #we need to distribute the remainder relatively evenly
#     #tests will be inaccurate if we have small bins at the end
#     indices = [i * q + min(r, i) for i in range(k + 1)]
#     bins = [samples[indices[i]: indices[i + 1]] for i in range(k)]
#     bin_ranges = []
#     counts = []
#     for i in range(k):
#         bin_min = bins[i][0]
#         try:
#             bin_max = bins[i + 1][0]
#         except IndexError:
#             bin_max = bins[i][-1]
#         bin_ranges.append([bin_min, bin_max])
#         counts.append(len(bins[i]))
#     if support:
#         bin_ranges[0][0] = support[0]
#         bin_ranges[-1][1] = support[1]
#     return numpy.array(counts), numpy.array(bin_ranges)
# 
# def multinomial_goodness_of_fit(
#         probs,
#         counts,
#         total_count,
#         truncated=False,
#         plot=False):
#     """
#     Pearson's chi^2 test, on possibly truncated data.
#     http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test
# 
#     Returns:
#         p-value of truncated multinomial sample.
#     """
#     assert len(probs) == len(counts)
#     assert truncated or total_count == sum(counts)
#     chi_squared = 0
#     dof = 0
#     if plot:
#         print_histogram(probs, counts)
#     for p, c in zip(probs, counts):
#         if p == 1:
#             return 1 if c == total_count else 0
#         assert p < 1, 'bad probability: %g' % p
#         if p > 0:
#             mean = total_count * p
#             variance = total_count * p * (1 - p)
#             assert variance > 1,\
#                 'WARNING goodness of fit is inaccurate; use more samples'
#             chi_squared += (c - mean) ** 2 / variance
#             dof += 1
#         else:
#             print 'WARNING zero probability in goodness-of-fit test'
#             if c > 0:
#                 return float('inf')
# 
#     if not truncated:
#         dof -= 1
# 
#     survival = scipy.stats.chi2.sf(chi_squared, dof)
#     return survival
# 
# Path: distributions/tests/util.py
# def seed_all(s):
#     import distributions.dbg.random
#     distributions.dbg.random.seed(s)
#     try:
#         import distributions.hp.random
#         distributions.hp.random.seed(s)
#     except ImportError:
#         pass


# Path: distributions/tests/test_util.py
import numpy
from nose.tools import (
    assert_less,
    assert_less_equal,
    assert_greater,
    assert_list_equal,
)
from distributions.util import (
    scores_to_probs,
    bin_samples,
    multinomial_goodness_of_fit,
)
from distributions.tests.util import seed_all

# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



def test_scores_to_probs():
    scores = [-10000, 10000, 10001, 9999, 0, 5, 6, 6, 7]
    probs = scores_to_probs(scores)
    assert_less(abs(sum(probs) - 1), 1e-6)
    for prob in probs:
        assert_less_equal(0, prob)
        assert_less_equal(prob, 1)


def test_multinomial_goodness_of_fit():
    for dim in range(2, 20):
        yield _test_multinomial_goodness_of_fit, dim


def _test_multinomial_goodness_of_fit(dim):
    seed_all(0)
    thresh = 1e-3
    sample_count = int(1e5)
    probs = numpy.random.dirichlet([1] * dim)

    counts = numpy.random.multinomial(sample_count, probs)
    p_good = multinomial_goodness_of_fit(probs, counts, sample_count)
    assert_greater(p_good, thresh)

    unif_counts = numpy.random.multinomial(sample_count, [1. / dim] * dim)

    p_bad = multinomial_goodness_of_fit(probs, unif_counts, sample_count)