# Path: cmepy/model.py
# PROPENSITIES = 'propensities'
# TRANSITIONS = 'transitions'
# NAME = 'name'
# INITIAL_STATE = 'initial_state'
# SHAPE = 'shape'
# SPECIES_NAMES = 'species'
# SPECIES_COUNTS = 'species_counts'
# REACTION_NAMES = 'reactions'
# ENTRIES = frozenset([
#     PROPENSITIES,
#     TRANSITIONS,
#     NAME,
#     INITIAL_STATE,
#     SHAPE,
#     SPECIES_NAMES,
#     SPECIES_COUNTS,
#     REACTION_NAMES,
# ])
# class Model(dict):
#     def __init__(self, **entries):
#     def _ensure_shape_invariance(self, x):
#     def __getattribute__(self, attrname):
#     def validate(self):
# def create(**entries):
# def raise_error(error_type, descr, value, message):
# def must_be_within_range(value, descr=None, min_value=None, max_value=None):
# def must_have_length(value, descr=None, min_len=None, max_len=None):
# def must_be_callable(value, descr=None):
# def must_be_string_like(value, descr=None):
# def must_be_int_like(value, descr=None, min_value=None, max_value=None):
# def must_be_mapping(value, descr=None):
# def must_contain_item(value, descr, item):
# def validate_name(value):
# def validate_propensities(value):
# def validate_species_names(value):
# def validate_species_counts(value):
# def validate_transitions(value):
# def validate_initial_state(value):
# def validate_shape(value):
# def validate_model(m):


import unittest
import numpy
import cmepy.recorder
import cmepy.solver
from scipy.stats import binom, poisson
from itertools import izip
from numpy.testing import assert_almost_equal
from cmepy import model
        from cmepy.models.mono_molecular import A2B2A as m
        from cmepy.models.mono_molecular import A2B2C as m
        poissons.append(poisson(rate).pmf(numpy.arange(dim)))
    exact = reduce(numpy.multiply.outer, poissons)
    return exact

def exact_binomial(rate, size):
    return binom(size, 1.0 - numpy.exp(-rate)).pmf(numpy.arange(size))

def exact_monomolecular_aba(t, size):
    pi_0 = (1.0 + numpy.exp(-2.0 * t))/2.0
    return binom(size, pi_0).pmf(numpy.arange(size+1))

def exact_monomolecular_abc(t, size):
    pi_1  = t * numpy.exp(-t)
    return binom(size, pi_1).pmf(numpy.arange(size+1))

def compare_against_exact(model, t, f, p_exact):
    solver = cmepy.solver.create(model, sink = True)
    for t_prime in numpy.linspace(0.0, t, 11):
        solver.step(t_prime)
    p, p_sink = solver.y
    assert_almost_equal(f(p), p_exact)

def compare_against_poisson(rates, shape):
    # generate model & create a solver for it
    size = len(shape)
    def constant_propensity(rate):
        return lambda *x : rate
    props = tuple(constant_propensity(r) for r in rates)
    transitions = tuple((0,)*i + (1,) + (0,)*(size-1-i) for i in xrange(size))
    

# Path: cmepy/model.py
# PROPENSITIES = 'propensities'
# TRANSITIONS = 'transitions'
# NAME = 'name'
# INITIAL_STATE = 'initial_state'
# SHAPE = 'shape'
# SPECIES_NAMES = 'species'
# SPECIES_COUNTS = 'species_counts'
# REACTION_NAMES = 'reactions'
# ENTRIES = frozenset([
#     PROPENSITIES,
#     TRANSITIONS,
#     NAME,
#     INITIAL_STATE,
#     SHAPE,
#     SPECIES_NAMES,
#     SPECIES_COUNTS,
#     REACTION_NAMES,
# ])
# class Model(dict):
#     def __init__(self, **entries):
#     def _ensure_shape_invariance(self, x):
#     def __getattribute__(self, attrname):
#     def validate(self):
# def create(**entries):
# def raise_error(error_type, descr, value, message):
# def must_be_within_range(value, descr=None, min_value=None, max_value=None):
# def must_have_length(value, descr=None, min_len=None, max_len=None):
# def must_be_callable(value, descr=None):
# def must_be_string_like(value, descr=None):
# def must_be_int_like(value, descr=None, min_value=None, max_value=None):
# def must_be_mapping(value, descr=None):
# def must_contain_item(value, descr, item):
# def validate_name(value):
# def validate_propensities(value):
# def validate_species_names(value):
# def validate_species_counts(value):
# def validate_transitions(value):
# def validate_initial_state(value):
# def validate_shape(value):
# def validate_model(m):


# Path: cmepy/tests/solver_tests.py
import unittest
import numpy
import cmepy.recorder
import cmepy.solver
from scipy.stats import binom, poisson
from itertools import izip
from numpy.testing import assert_almost_equal
from cmepy import model
        from cmepy.models.mono_molecular import A2B2A as m
        from cmepy.models.mono_molecular import A2B2C as m

        poissons.append(poisson(rate).pmf(numpy.arange(dim)))
    exact = reduce(numpy.multiply.outer, poissons)
    return exact

def exact_binomial(rate, size):
    return binom(size, 1.0 - numpy.exp(-rate)).pmf(numpy.arange(size))

def exact_monomolecular_aba(t, size):
    pi_0 = (1.0 + numpy.exp(-2.0 * t))/2.0
    return binom(size, pi_0).pmf(numpy.arange(size+1))

def exact_monomolecular_abc(t, size):
    pi_1  = t * numpy.exp(-t)
    return binom(size, pi_1).pmf(numpy.arange(size+1))

def compare_against_exact(model, t, f, p_exact):
    solver = cmepy.solver.create(model, sink = True)
    for t_prime in numpy.linspace(0.0, t, 11):
        solver.step(t_prime)
    p, p_sink = solver.y
    assert_almost_equal(f(p), p_exact)

def compare_against_poisson(rates, shape):
    # generate model & create a solver for it
    size = len(shape)
    def constant_propensity(rate):
        return lambda *x : rate
    props = tuple(constant_propensity(r) for r in rates)
    transitions = tuple((0,)*i + (1,) + (0,)*(size-1-i) for i in xrange(size))
    

    m = model.create(