# Path: pyhull/simplex.py
# class Simplex(object):
#     """
#     A generalized simplex object. See http://en.wikipedia.org/wiki/Simplex.
# 
#     .. attribute: space_dim
# 
#         Dimension of the space.
# 
#     .. attribute: simplex_dim
# 
#         Dimension of the simplex. Usually, this is 1 more than the space_dim.
#         E.g. you need four vertices to define a tetrahedon in 3D space.
#     """
# 
#     def __init__(self, coords):
#         """
#         Initializes a Simplex from vertex coordinates.
# 
#         Args:
#             coords ([[float]]): Coords of the vertices of the simplex. E.g.,
#                 [[1, 2, 3], [2, 4, 5], [6, 7, 8], [8, 9, 10].
#         """
#         self._coords = np.array(coords)
#         self.simplex_dim, self.space_dim = self._coords.shape
#         self.origin = self._coords[-1]
#         if self.simplex_dim == self.space_dim + 1:
#             # precompute attributes for calculating bary_coords
#             self.T = self._coords[:-1] - self.origin
#             self.T_inv = np.linalg.inv(self.T)
# 
#     @property
#     def volume(self):
#         """
#         Volume of the simplex.
#         """
#         return abs(np.linalg.det(self.T)) / math.factorial(self.space_dim)
# 
#     def bary_coords(self, point):
#         try:
#             c = np.dot((point - self.origin), self.T_inv)
#             return np.concatenate([c, [1 - np.sum(c)]])
#         except AttributeError:
#             raise ValueError('Simplex is not full-dimensional')
# 
#     def in_simplex(self, point, tolerance=1e-8):
#         """
#         Checks if a point is in the simplex using the standard barycentric
#         coordinate system algorithm.
# 
#         Taking an arbitrary vertex as an origin, we compute the basis for the
#         simplex from this origin by subtracting all other vertices from the
#         origin. We then project the point into this coordinate system and
#         determine the linear decomposition coefficients in this coordinate
#         system.  If the coeffs satisfy that all coeffs >= 0, the composition
#         is in the facet.
# 
#         Args:
#             point ([float]): Point to test
#             tolerance (float): Tolerance to test if point is in simplex.
#         """
#         return (self.bary_coords(point) >= -tolerance).all()
# 
#     def __eq__(self, other):
#         for p in itertools.permutations(self._coords):
#             if np.allclose(p, other.coords):
#                 return True
#         return False
# 
#     def __hash__(self):
#         return len(self._coords)
# 
#     def __repr__(self):
#         output = ["{}-simplex in {}D space".format(self.space_dim,
#                                                    self.simplex_dim),
#                   "Vertices:"]
#         for coord in self._coords:
#             output.append("\t({})".format(", ".join(map(str, coord))))
#         return "\n".join(output)
# 
#     def __str__(self):
#         return self.__repr__()
# 
#     @property
#     def coords(self):
#         """
#         Returns a copy of the vertex coordinates in the simplex.
#         """
#         return self._coords.copy()


import unittest
import numpy as np
from pyhull.simplex import Simplex
__email__ = "shyue@mit.edu"
__date__ = "May 15, 2012"




class SimplexTest(unittest.TestCase):

    def setUp(self):
        coords = []
        coords.append([0, 0, 0])
        coords.append([0, 1, 0])
        coords.append([0, 0, 1])
        coords.append([1, 0, 0])
        self.simplex = Simplex(coords)

    def test_in_simplex(self):
        self.assertTrue(self.simplex.in_simplex([0.1, 0.1, 0.1]))
        self.assertFalse(self.simplex.in_simplex([0.6, 0.6, 0.6]))
        for i in range(10):
            coord = np.random.random_sample(size=3) / 3
            self.assertTrue(self.simplex.in_simplex(coord))

    def test_2dtriangle(self):
        s = Simplex([[0, 1], [1, 1], [1, 0]])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 0.5]), [0.5, 0, 0.5])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 1]), [0.5, 0.5, 0])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 0.75]), [0.5, 0.25, 0.25])
        np.testing.assert_almost_equal(s.bary_coords([0.75, 0.75]), [0.25, 0.5, 0.25])


# Path: pyhull/simplex.py
# class Simplex(object):
#     """
#     A generalized simplex object. See http://en.wikipedia.org/wiki/Simplex.
# 
#     .. attribute: space_dim
# 
#         Dimension of the space.
# 
#     .. attribute: simplex_dim
# 
#         Dimension of the simplex. Usually, this is 1 more than the space_dim.
#         E.g. you need four vertices to define a tetrahedon in 3D space.
#     """
# 
#     def __init__(self, coords):
#         """
#         Initializes a Simplex from vertex coordinates.
# 
#         Args:
#             coords ([[float]]): Coords of the vertices of the simplex. E.g.,
#                 [[1, 2, 3], [2, 4, 5], [6, 7, 8], [8, 9, 10].
#         """
#         self._coords = np.array(coords)
#         self.simplex_dim, self.space_dim = self._coords.shape
#         self.origin = self._coords[-1]
#         if self.simplex_dim == self.space_dim + 1:
#             # precompute attributes for calculating bary_coords
#             self.T = self._coords[:-1] - self.origin
#             self.T_inv = np.linalg.inv(self.T)
# 
#     @property
#     def volume(self):
#         """
#         Volume of the simplex.
#         """
#         return abs(np.linalg.det(self.T)) / math.factorial(self.space_dim)
# 
#     def bary_coords(self, point):
#         try:
#             c = np.dot((point - self.origin), self.T_inv)
#             return np.concatenate([c, [1 - np.sum(c)]])
#         except AttributeError:
#             raise ValueError('Simplex is not full-dimensional')
# 
#     def in_simplex(self, point, tolerance=1e-8):
#         """
#         Checks if a point is in the simplex using the standard barycentric
#         coordinate system algorithm.
# 
#         Taking an arbitrary vertex as an origin, we compute the basis for the
#         simplex from this origin by subtracting all other vertices from the
#         origin. We then project the point into this coordinate system and
#         determine the linear decomposition coefficients in this coordinate
#         system.  If the coeffs satisfy that all coeffs >= 0, the composition
#         is in the facet.
# 
#         Args:
#             point ([float]): Point to test
#             tolerance (float): Tolerance to test if point is in simplex.
#         """
#         return (self.bary_coords(point) >= -tolerance).all()
# 
#     def __eq__(self, other):
#         for p in itertools.permutations(self._coords):
#             if np.allclose(p, other.coords):
#                 return True
#         return False
# 
#     def __hash__(self):
#         return len(self._coords)
# 
#     def __repr__(self):
#         output = ["{}-simplex in {}D space".format(self.space_dim,
#                                                    self.simplex_dim),
#                   "Vertices:"]
#         for coord in self._coords:
#             output.append("\t({})".format(", ".join(map(str, coord))))
#         return "\n".join(output)
# 
#     def __str__(self):
#         return self.__repr__()
# 
#     @property
#     def coords(self):
#         """
#         Returns a copy of the vertex coordinates in the simplex.
#         """
#         return self._coords.copy()


# Path: pyhull/tests/test_simplex.py
import unittest
import numpy as np
from pyhull.simplex import Simplex

__email__ = "shyue@mit.edu"
__date__ = "May 15, 2012"




class SimplexTest(unittest.TestCase):

    def setUp(self):
        coords = []
        coords.append([0, 0, 0])
        coords.append([0, 1, 0])
        coords.append([0, 0, 1])
        coords.append([1, 0, 0])
        self.simplex = Simplex(coords)

    def test_in_simplex(self):
        self.assertTrue(self.simplex.in_simplex([0.1, 0.1, 0.1]))
        self.assertFalse(self.simplex.in_simplex([0.6, 0.6, 0.6]))
        for i in range(10):
            coord = np.random.random_sample(size=3) / 3
            self.assertTrue(self.simplex.in_simplex(coord))

    def test_2dtriangle(self):
        s = Simplex([[0, 1], [1, 1], [1, 0]])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 0.5]), [0.5, 0, 0.5])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 1]), [0.5, 0.5, 0])
        np.testing.assert_almost_equal(s.bary_coords([0.5, 0.75]), [0.5, 0.25, 0.25])
        np.testing.assert_almost_equal(s.bary_coords([0.75, 0.75]), [0.25, 0.5, 0.25])


        s = Simplex([[1, 1], [1, 0]])