# Path: cmepy/cme_matrix.py
# def non_neg_states(state_array):
#     """
#     non_neg_states(state_array) -> bool_array
#     
#     Returns a boolean array of flags corresponding to those states in
#     state_array that have no negative coordinate.
#     """
#     return numpy.logical_and.reduce(state_array >= 0, axis=0)
# 
# Path: cmepy/lexarrayset.py
# def unique(las, return_inverse=False):
# def nonunique_member(arr1, las2):
# def member(las1, las2):
# def split(las1, las2):
# def difference(las1, las2):
# def intersection(las1, las2):
# def union(las1, las2):
# def shift(las, offset):
# def empty(dim):
# def create(data, unique_data=False):
#     def __init__(self, data, unique_data=False):
#     def size(self):
#     def member(self, rhs):
#     def split(self, rhs):
#     def difference(self, rhs):
#     def intersection(self, rhs):
#     def union(self, rhs):
#     def shift(self, offset):
#     def difference_update(self, rhs):
#     def intersection_update(self, rhs):
#     def union_update(self, rhs):
#     def shift_update(self, shift):
# class LexArraySet(object):


import numpy
from cmepy.cme_matrix import non_neg_states
from cmepy import lexarrayset
"""
Common utility routines for Finite State Projection.
"""


def grow_domain(domain_states, transitions, depth, validity_test = None):
    """
    Returns domain_states grown by depth along transitions.
    
    Resulting states are filtered by the validity_test. By default,
    only states without a negative coordinate are valid.
    """
    if numpy.size(domain_states) == 0:
        raise ValueError('there must be at least one state to expand')
    
    if validity_test is None:
        validity_test = non_neg_states
    
    expanded_states = domain_states
    for _ in xrange(depth):
        # expand support states by one along each state transition
        for transition in transitions:
            shifted_states = lexarrayset.shift(domain_states, transition)
            # filter invalid states (ie states with a negative coord)
            valid = validity_test(shifted_states)
            shifted_states = shifted_states[:, valid]

# Path: cmepy/cme_matrix.py
# def non_neg_states(state_array):
#     """
#     non_neg_states(state_array) -> bool_array
#     
#     Returns a boolean array of flags corresponding to those states in
#     state_array that have no negative coordinate.
#     """
#     return numpy.logical_and.reduce(state_array >= 0, axis=0)
# 
# Path: cmepy/lexarrayset.py
# def unique(las, return_inverse=False):
# def nonunique_member(arr1, las2):
# def member(las1, las2):
# def split(las1, las2):
# def difference(las1, las2):
# def intersection(las1, las2):
# def union(las1, las2):
# def shift(las, offset):
# def empty(dim):
# def create(data, unique_data=False):
#     def __init__(self, data, unique_data=False):
#     def size(self):
#     def member(self, rhs):
#     def split(self, rhs):
#     def difference(self, rhs):
#     def intersection(self, rhs):
#     def union(self, rhs):
#     def shift(self, offset):
#     def difference_update(self, rhs):
#     def intersection_update(self, rhs):
#     def union_update(self, rhs):
#     def shift_update(self, shift):
# class LexArraySet(object):


# Path: cmepy/fsp/util.py
import numpy
from cmepy.cme_matrix import non_neg_states
from cmepy import lexarrayset

"""
Common utility routines for Finite State Projection.
"""


def grow_domain(domain_states, transitions, depth, validity_test = None):
    """
    Returns domain_states grown by depth along transitions.
    
    Resulting states are filtered by the validity_test. By default,
    only states without a negative coordinate are valid.
    """
    if numpy.size(domain_states) == 0:
        raise ValueError('there must be at least one state to expand')
    
    if validity_test is None:
        validity_test = non_neg_states
    
    expanded_states = domain_states
    for _ in xrange(depth):
        # expand support states by one along each state transition
        for transition in transitions:
            shifted_states = lexarrayset.shift(domain_states, transition)
            # filter invalid states (ie states with a negative coord)
            valid = validity_test(shifted_states)
            shifted_states = shifted_states[:, valid]

            expanded_states = lexarrayset.union(