Example #1
0
 def test_non_unique_indices_query_offset(self):
     states = [[0, 0, 1, 1, 2, 7, 2],
               [0, 1, 0, 1, 1, 0, 2]]
     
     goal_order = [0, 2, 5, 1, 3, 4, 6]
     assert_array_equal(numpy.lexsort(states),
                        goal_order)
     
     enum = state_enum.create(states)
     
     # apply offset
     offset = 42
     enum.offset = offset
     
     # verify that looking up the indices
     # for a collection of non-unique query states
     # returns a correctly sized index array with the correct
     # corresponding indices
     
     query_states = [[7, 2, 1, 2, 1, 7, 7, 2, 1],
                     [0, 1, 0, 2, 0, 0, 0, 2, 1]]
     
     indices = enum.indices(query_states)
     
     assert_array_equal(indices - offset,
                        [2, 5, 1, 6, 1, 2, 2, 6, 4])
Example #2
0
 def test_simple_init(self):
     
     states = [[0, 0, 1, 1, 2, 1, 2],
               [0, 1, 0, 1, 1, 2, 2]]
     
     enum = state_enum.create(states)
     
     enum.indices(states)
     enum.states([6, 5, 4, 3, 2, 1, 0])
     
     # verify that ordered_states are the same as manually sorting
     # with lexsort
     
     sorted_states = numpy.array(states)
     order = numpy.lexsort(sorted_states)
     sorted_states = sorted_states[:, order]
     assert_array_equal(enum.ordered_states,
                        sorted_states)
     
     # verify that the states have been enumerated with
     # respect to lexical ordering
     
     assert_array_equal(enum.states(order), states)
     
     assert_array_equal(enum.indices(states), order)
Example #3
0
 def test_non_unique_contains_query(self):
     states = [[0, 0, 1, 1, 2, 7, 2],
               [0, 1, 0, 1, 1, 0, 2]]
     
     enum = state_enum.create(states)
     
     query_states = [[-1, 7, 2, 1, 2, 9, 1, 7, 7, 2, -1, 1],
                     [-1, 0, 1, 0, 2, 9, 0, 0, 0, 2, -1, 1]]
     
     member_flags = enum.contains(query_states)
     
     goal_member_flags = [False,
                          True,
                          True,
                          True,
                          True,
                          False,
                          True,
                          True,
                          True,
                          True,
                          False,
                          True]
     
     assert_array_equal(member_flags,
                        goal_member_flags)
Example #4
0
    def test_non_unique_contains_query(self):
        states = [[0, 0, 1, 1, 2, 7, 2], [0, 1, 0, 1, 1, 0, 2]]

        enum = state_enum.create(states)

        query_states = [[-1, 7, 2, 1, 2, 9, 1, 7, 7, 2, -1, 1],
                        [-1, 0, 1, 0, 2, 9, 0, 0, 0, 2, -1, 1]]

        member_flags = enum.contains(query_states)

        goal_member_flags = [
            False, True, True, True, True, False, True, True, True, True,
            False, True
        ]

        assert_array_equal(member_flags, goal_member_flags)
Example #5
0
    def test_pack_unpack_distributions(self):
        states = [[0, 0, 1, 1, 2, 7, 2], [0, 1, 0, 1, 1, 0, 2]]

        enum = state_enum.create(states)

        p_sparse = {(1, 1): 0.3, (7, 0): 0.2, (1, 0): 0.5}

        p_dense = enum.pack_distribution(p_sparse)

        assert_array_equal(p_dense, [0.0, 0.5, 0.2, 0.0, 0.3, 0.0, 0.0])

        q_sparse = enum.unpack_distribution(p_dense)

        for state in p_sparse:
            assert state in q_sparse
            assert p_sparse[state] == q_sparse[state]
        for state in q_sparse:
            assert state in p_sparse
            assert p_sparse[state] == q_sparse[state]
Example #6
0
    def test_non_unique_indices_query(self):
        states = [[0, 0, 1, 1, 2, 7, 2], [0, 1, 0, 1, 1, 0, 2]]

        goal_order = [0, 2, 5, 1, 3, 4, 6]
        assert_array_equal(numpy.lexsort(states), goal_order)

        enum = state_enum.create(states)

        # verify that looking up the indices
        # for a collection of non-unique query states
        # returns a correctly sized index array with the correct
        # corresponding indices

        query_states = [[7, 2, 1, 2, 1, 7, 7, 2, 1],
                        [0, 1, 0, 2, 0, 0, 0, 2, 1]]

        indices = enum.indices(query_states)

        assert_array_equal(indices, [2, 5, 1, 6, 1, 2, 2, 6, 4])
Example #7
0
 def test_pack_unpack_distributions(self):
     states = [[0, 0, 1, 1, 2, 7, 2],
               [0, 1, 0, 1, 1, 0, 2]]
     
     enum = state_enum.create(states)
     
     p_sparse = {(1, 1) : 0.3,
                 (7, 0) : 0.2,
                 (1, 0) : 0.5}
     
     p_dense = enum.pack_distribution(p_sparse)
     
     assert_array_equal(p_dense,
                        [0.0, 0.5, 0.2, 0.0, 0.3, 0.0, 0.0])
     
     q_sparse = enum.unpack_distribution(p_dense)
     
     for state in p_sparse:
         assert state in q_sparse
         assert p_sparse[state] == q_sparse[state]
     for state in q_sparse:
         assert state in p_sparse
         assert p_sparse[state] == q_sparse[state]
Example #8
0
    def test_simple_init(self):

        states = [[0, 0, 1, 1, 2, 1, 2], [0, 1, 0, 1, 1, 2, 2]]

        enum = state_enum.create(states)

        enum.indices(states)
        enum.states([6, 5, 4, 3, 2, 1, 0])

        # verify that ordered_states are the same as manually sorting
        # with lexsort

        sorted_states = numpy.array(states)
        order = numpy.lexsort(sorted_states)
        sorted_states = sorted_states[:, order]
        assert_array_equal(enum.ordered_states, sorted_states)

        # verify that the states have been enumerated with
        # respect to lexical ordering

        assert_array_equal(enum.states(order), states)

        assert_array_equal(enum.indices(states), order)
Example #9
0
def create(model, sink, p_0=None, t_0=None, sink_0=None, time_dependencies=None, domain_states=None):
    """
    Returns a solver for the Chemical Master Equation of the given model.
    
    arguments:
    
        model : the CME model to solve
        
        sink : If sink is True, the solver will include a 'sink' state used
            to accumulate any probability that may flow outside the domain.
            This can be used to measure the error in the solution due to
            truncation of the domain. If sink is False, the solver will not
            include a 'sink' state, and probability will be artificially
            prevented from flowing outside of the domain.
        
        p_0 : (optional) mapping from states in the domain to probabilities,
            for the initial probability distribution. If not specified,
            and the initial state of the state space is given by the model,
            defaults to all probability concentrated at the initial state,
            otherwise, a ValueError will be raised.
        
        t_0 : (optional) initial time, defaults to 0.0
        
        sink_0 : (optional) initial sink probability, defaults to 0.0
            Only a valid argument if sink is set to True.
        
        time_dependencies : (optional) By default, reaction propensities are
            time independent. If specified, time_dependencies must be of the
            form { s_1 : phi_1, ..., s_n : phi_n }, where each (s_j, phi_j)
            item satisifes :
            
                s_j : set of reaction indices
                phi_j : phi_j(t) -> time dependent coefficient 
            
            The propensities of the reactions with indicies contained in s_j
            will all be multiplied by the coefficient phi_j(t), at time t.
            Reactions are indexed according to the ordering of the propensities
            in the model.
            
            The reaction index sets s_j must be *disjoint*. It is not necessary
            for the union of the s_j to include all the reaction indices.
            If a reaction's index is not contained in any s_j then the reaction
            is treated as time-independent. 
        
        mapping of time dependent coefficient
            functions keyed by subsets of reaction indices, with respect to the
            ordering of reactions determined by the order of the propensity
            functions inside the model. The propensities of the reactions
            with indices included in each subset are multiplied by the time
            dependent coefficient function. By default, no time dependent
            coefficient functions are specified, that is, the CME has
            time-independent propensities.
        
        domain_states : (optional) array of states in the domain.
            By default, generate the rectangular lattice of states defined by
            the 'shape' entry of the model. A ValueError is raised if both
            domain_states and 'shape' are unspecified.
    """

    mdl.validate_model(model)

    if sink_0 is not None:
        if not sink:
            raise ValueError("sink_0 may not be specified if sink is False")
        sink_0 = float(sink_0)
    else:
        sink_0 = 0.0

    # determine states in domain, then construct an enumeration of the
    # domain states
    if domain_states is None:
        if mdl.SHAPE not in model:
            lament = "if no states given, model must contain key '%s'"
            raise KeyError(lament % mdl.SHAPE)
        else:
            domain_states = domain.from_rect(shape=model.shape)

    domain_enum = state_enum.create(domain_states)

    # determine p_0, then construct a dense representation with respect to
    # the domain enumeration
    initial_state = model.get(mdl.INITIAL_STATE, None)
    if p_0 is None:
        if initial_state is None:
            lament = "if no p_0 given, model must contain key '%s'"
            raise ValueError(lament % mdl.INITIAL_STATE)
        else:
            p_0 = {initial_state: 1.0}

    if t_0 is None:
        t_0 = 0.0

    member_flags = domain_enum.contains(domain.from_iter(p_0))
    if not numpy.logical_and.reduce(member_flags):
        raise ValueError("support of p_0 is not a subset of domain_states")

    # compute reaction matrices and use them to define differential equations
    gen_matrices = cme_matrix.gen_reaction_matrices(model, domain_enum, sink, cme_matrix.non_neg_states)
    reaction_matrices = list(gen_matrices)
    dy_dt = cme_matrix.create_diff_eqs(reaction_matrices, phi=time_dependencies)

    # construct and initialise solver
    if sink:
        cme_solver = ode_solver.Solver(dy_dt, y_0=(p_0, sink_0), t_0=t_0)
        pack, unpack = create_packing_functions(domain_enum)
        cme_solver.set_packing(pack, unpack, transform_dy_dt=False)
    else:
        pack = domain_enum.pack_distribution
        unpack = domain_enum.unpack_distribution
        cme_solver = ode_solver.Solver(dy_dt, y_0=p_0, t_0=t_0)
        cme_solver.set_packing(pack, unpack, transform_dy_dt=False)
    return cme_solver
Example #10
0
def create(model,
           sink,
           p_0=None,
           t_0=None,
           sink_0=None,
           time_dependencies=None,
           domain_states=None,
           solver=ode_solver.Solver,
           outflow=False,
           **solver_args):
    """
    Returns a solver for the Chemical Master Equation of the given model.
    
    arguments:
    
        model : the CME model to solve
        
        sink : If sink is True, the solver will include a 'sink' state used
            to accumulate any probability that may flow outside the domain.
            This can be used to measure the error in the solution due to
            truncation of the domain. If sink is False, the solver will not
            include a 'sink' state, and probability will be artificially
            prevented from flowing outside of the domain.
        
        p_0 : (optional) mapping from states in the domain to probabilities,
            for the initial probability distribution. If not specified,
            and the initial state of the state space is given by the model,
            defaults to all probability concentrated at the initial state,
            otherwise, a ValueError will be raised.
        
        t_0 : (optional) initial time, defaults to 0.0
        
        sink_0 : (optional) initial sink probability, defaults to 0.0
            Only a valid argument if sink is set to True.
        
        time_dependencies : (optional) By default, reaction propensities are
            time independent. If specified, time_dependencies must be of the
            form { s_1 : phi_1, ..., s_n : phi_n }, where each (s_j, phi_j)
            item satisifes :
            
                s_j : set of reaction indices
                phi_j : phi_j(t) -> time dependent coefficient 
            
            The propensities of the reactions with indicies contained in s_j
            will all be multiplied by the coefficient phi_j(t), at time t.
            Reactions are indexed according to the ordering of the propensities
            in the model.
            
            The reaction index sets s_j must be *disjoint*. It is not necessary
            for the union of the s_j to include all the reaction indices.
            If a reaction's index is not contained in any s_j then the reaction
            is treated as time-independent. 
        
        mapping of time dependent coefficient
            functions keyed by subsets of reaction indices, with respect to the
            ordering of reactions determined by the order of the propensity
            functions inside the model. The propensities of the reactions
            with indices included in each subset are multiplied by the time
            dependent coefficient function. By default, no time dependent
            coefficient functions are specified, that is, the CME has
            time-independent propensities.
        
        domain_states : (optional) array of states in the domain.
            By default, generate the rectangular lattice of states defined by
            the 'shape' entry of the model. A ValueError is raised if both
            domain_states and 'shape' are unspecified.
    """

    mdl.validate_model(model)

    if sink and outflow:
        raise ValueError('sink and outflow cannot be both True')

    if sink_0 is not None:
        if not sink:
            raise ValueError('sink_0 may not be specified if sink is False')
        sink_0 = float(sink_0)
    else:
        sink_0 = 0.0

    # determine states in domain, then construct an enumeration of the
    # domain states
    if domain_states is None:
        if mdl.SHAPE not in model:
            lament = 'if no states given, model must contain key \'%s\''
            raise KeyError(lament % mdl.SHAPE)
        else:
            domain_states = domain.from_rect(shape=model.shape)

    domain_enum = state_enum.create(domain_states)

    # determine p_0, then construct a dense representation with respect to
    # the domain enumeration
    initial_state = model.get(mdl.INITIAL_STATE, None)
    if p_0 is None:
        if initial_state is None:
            lament = 'if no p_0 given, model must contain key \'%s\''
            raise ValueError(lament % mdl.INITIAL_STATE)
        else:
            p_0 = {initial_state: 1.0}

    if t_0 is None:
        t_0 = 0.0

    member_flags = domain_enum.contains(domain.from_iter(p_0))
    if not numpy.logical_and.reduce(member_flags):
        raise ValueError('support of p_0 is not a subset of domain_states')

    # compute reaction matrices and use them to define differential equations
    gen_matrices = cme_matrix.gen_reaction_matrices(model,
                                                    domain_enum,
                                                    sink,
                                                    cme_matrix.non_neg_states,
                                                    outflow=outflow)
    reaction_matrices = list(gen_matrices)
    dy_dt = cme_matrix.create_diff_eqs(reaction_matrices,
                                       phi=time_dependencies)

    if solver_args:
        solver_args['reaction_matrices'] = reaction_matrices

    # construct and initialise solver
    if sink:
        cme_solver = solver(dy_dt, y_0=(p_0, sink_0), t_0=t_0, **solver_args)
        pack, unpack = create_packing_functions(domain_enum)
        cme_solver.set_packing(pack, unpack, transform_dy_dt=False)
    else:
        pack = domain_enum.pack_distribution
        unpack = domain_enum.unpack_distribution
        cme_solver = solver(dy_dt, y_0=p_0, t_0=t_0, **solver_args)
        cme_solver.set_packing(pack, unpack, transform_dy_dt=False)
    return cme_solver