# Path: pyinform/error.py
# class InformError(Exception):
#     """
#     InformError signifies an error occurred in a call to inform.
#     """
# 
#     def __init__(self, e=-1, func=None):
#         msg = error_string(e)
# 
#         if func is None:
#             msg = "an inform error occurred - \"{}\"".format(msg)
#         else:
#             msg = "an inform error occurred in `{}` - \"{}\"".format(func, msg)
# 
#         super(InformError, self).__init__(msg)
# 
#         self.error_code = e if isinstance(e, ErrorCode) else ErrorCode(e)
# 
# Path: pyinform/mutualinfo.py
# def mutual_info(xs, ys, local=False):
#     """
#     Compute the (local) mutual information between two time series.
# 
#     This function explicitly takes the logarithmic base *b* as an argument.
# 
#     :param xs: a time series
#     :type xs: a sequence or ``numpy.ndarray``
#     :param ys: a time series
#     :type ys: a sequence or ``numpy.ndarray``
#     :param bool local: compute the local mutual information
#     :return: the local or average mutual information
#     :rtype: float or ``numpy.ndarray``
#     :raises ValueError: if the time series have different shapes
#     :raises InformError: if an error occurs within the ``inform`` C call
#     """
#     us = np.ascontiguousarray(xs, dtype=np.int32)
#     vs = np.ascontiguousarray(ys, dtype=np.int32)
#     if us.shape != vs.shape:
#         raise ValueError("timeseries lengths do not match")
# 
#     series = np.ascontiguousarray([us.flatten(), vs.flatten()], dtype=np.int32)
# 
#     bx = max(2, np.amax(us) + 1)
#     by = max(2, np.amax(vs) + 1)
# 
#     bs = np.ascontiguousarray([bx, by], dtype=np.int32)
# 
#     seriesdata = series.ctypes.data_as(POINTER(c_int))
#     bsdata = bs.ctypes.data_as(POINTER(c_int))
#     l, n = series.shape
# 
#     e = ErrorCode(0)
# 
#     if local is True:
#         mi = np.empty(us.shape, dtype=np.float64)
#         out = mi.ctypes.data_as(POINTER(c_double))
#         _local_mutual_info(seriesdata, c_ulong(l), c_ulong(n), bsdata, out, byref(e))
#     else:
#         mi = _mutual_info(seriesdata, c_ulong(l), c_ulong(n), bsdata, byref(e))
# 
#     error_guard(e)
# 
#     return mi


import unittest
import numpy as np
from pyinform.error import InformError
from pyinform.mutualinfo import mutual_info

        self.assertAlmostEqual(expect, got)


class TestLocalMutualInfo(unittest.TestCase):
    def test_mutual_info_empty(self):
        with self.assertRaises(ValueError):
            mutual_info([], [], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1, 2, 3], [], local=True)

        with self.assertRaises(ValueError):
            mutual_info([], [1, 2, 3], local=True)

    def test_mutual_info_dimensions(self):
        with self.assertRaises(ValueError):
            mutual_info([[1]], [1], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1], [[1]], local=True)

    def test_mutual_info_size(self):
        with self.assertRaises(ValueError):
            mutual_info([1, 2, 3], [1, 2], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1, 2], [1, 2, 3], local=True)

    def test_mutual_info_negative_states(self):

# Path: pyinform/error.py
# class InformError(Exception):
#     """
#     InformError signifies an error occurred in a call to inform.
#     """
# 
#     def __init__(self, e=-1, func=None):
#         msg = error_string(e)
# 
#         if func is None:
#             msg = "an inform error occurred - \"{}\"".format(msg)
#         else:
#             msg = "an inform error occurred in `{}` - \"{}\"".format(func, msg)
# 
#         super(InformError, self).__init__(msg)
# 
#         self.error_code = e if isinstance(e, ErrorCode) else ErrorCode(e)
# 
# Path: pyinform/mutualinfo.py
# def mutual_info(xs, ys, local=False):
#     """
#     Compute the (local) mutual information between two time series.
# 
#     This function explicitly takes the logarithmic base *b* as an argument.
# 
#     :param xs: a time series
#     :type xs: a sequence or ``numpy.ndarray``
#     :param ys: a time series
#     :type ys: a sequence or ``numpy.ndarray``
#     :param bool local: compute the local mutual information
#     :return: the local or average mutual information
#     :rtype: float or ``numpy.ndarray``
#     :raises ValueError: if the time series have different shapes
#     :raises InformError: if an error occurs within the ``inform`` C call
#     """
#     us = np.ascontiguousarray(xs, dtype=np.int32)
#     vs = np.ascontiguousarray(ys, dtype=np.int32)
#     if us.shape != vs.shape:
#         raise ValueError("timeseries lengths do not match")
# 
#     series = np.ascontiguousarray([us.flatten(), vs.flatten()], dtype=np.int32)
# 
#     bx = max(2, np.amax(us) + 1)
#     by = max(2, np.amax(vs) + 1)
# 
#     bs = np.ascontiguousarray([bx, by], dtype=np.int32)
# 
#     seriesdata = series.ctypes.data_as(POINTER(c_int))
#     bsdata = bs.ctypes.data_as(POINTER(c_int))
#     l, n = series.shape
# 
#     e = ErrorCode(0)
# 
#     if local is True:
#         mi = np.empty(us.shape, dtype=np.float64)
#         out = mi.ctypes.data_as(POINTER(c_double))
#         _local_mutual_info(seriesdata, c_ulong(l), c_ulong(n), bsdata, out, byref(e))
#     else:
#         mi = _mutual_info(seriesdata, c_ulong(l), c_ulong(n), bsdata, byref(e))
# 
#     error_guard(e)
# 
#     return mi


# Path: test/test_mutualinfo.py
import unittest
import numpy as np
from pyinform.error import InformError
from pyinform.mutualinfo import mutual_info


        self.assertAlmostEqual(expect, got)


class TestLocalMutualInfo(unittest.TestCase):
    def test_mutual_info_empty(self):
        with self.assertRaises(ValueError):
            mutual_info([], [], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1, 2, 3], [], local=True)

        with self.assertRaises(ValueError):
            mutual_info([], [1, 2, 3], local=True)

    def test_mutual_info_dimensions(self):
        with self.assertRaises(ValueError):
            mutual_info([[1]], [1], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1], [[1]], local=True)

    def test_mutual_info_size(self):
        with self.assertRaises(ValueError):
            mutual_info([1, 2, 3], [1, 2], local=True)

        with self.assertRaises(ValueError):
            mutual_info([1, 2], [1, 2, 3], local=True)

    def test_mutual_info_negative_states(self):

        with self.assertRaises(InformError):