# Path: molmod/test/common.py
# class BaseTestCase(unittest.TestCase):
#     def assertArraysEqual(self, a, b):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         assert (a==b).all(), "The array values do not match."
# 
#     def assertArrayConstant(self, arr, const):
#         assert (arr==const).all(), "Some/All array values do not match the constant."
# 
#     def assertArraysAlmostEqual(self, a, b, threshold=1e-6, mean=False, doabs=False):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         if a.shape == (0,):
#             return
#         if mean:
#             abserr = abs(a-b).mean()
#             oom = 0.5*(abs(a).mean()+abs(b).mean())
#         else:
#             abserr = abs(a-b).max()
#             oom = 0.5*(abs(a).max()+abs(b).max())
#         if doabs:
#             assert abserr <= threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, threshold)
#         else:
#             relerr = abserr/oom
#             assert relerr <= threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, threshold)
# 
#     def assertArrayAlmostConstant(self, arr, const, relerr_threshold):
#         error = abs(arr-const).max()
#         oom = const
#         relerr = error/oom
#         assert relerr <= relerr_threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, relerr_threshold)
# 
#     def assertArrayAlmostZero(self, arr, abserr_threshold):
#         abserr = abs(arr).max()
#         assert abserr <= abserr_threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, abserr_threshold)


from builtins import range
from molmod.test.common import BaseTestCase
from molmod import *
import numpy as np
        import copy
        for r in self.iter_random_rotations():
            self.assertArraysAlmostEqual(r.matrix, Complete.cast(r).matrix)

    def test_cast_complete(self):
        for c in self.iter_random_completes():
            self.assertArraysAlmostEqual(c.matrix, Complete.cast(c).matrix)


    def test_rotation_about_axis(self):
        x = np.array([2,0,0])
        c = Complete.about_axis(np.array([1,0,0]), np.pi, np.array([1,1,0]), False)
        self.assertArraysAlmostEqual(c*x, np.array([1,1,0]))

    def test_superpose(self):
        # create a few test sets with random data points, including degenerate
        # situations. (e.g. one point, two points, linear points)
        references = [ # a list of 2-tuples: (points, degenerate)
            (np.random.normal(0, 5, (n, 3)), False) for n in range(4, 40)
        ] + [
            (np.array([[0,0,1]], float), True),
            (np.array([[0,0,0],[0,0,1]], float), True),
            (np.array([[0,0,0],[0,0,1],[0,0,2]], float), True),
            (np.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True),
            (np.random.normal(0, 5, (3, 3)), True)
        ]

        # Do a random transformation on the points
        randomized = []
        for points, degenerate in references:
            #points[:] -= points.mean(axis=0)

# Path: molmod/test/common.py
# class BaseTestCase(unittest.TestCase):
#     def assertArraysEqual(self, a, b):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         assert (a==b).all(), "The array values do not match."
# 
#     def assertArrayConstant(self, arr, const):
#         assert (arr==const).all(), "Some/All array values do not match the constant."
# 
#     def assertArraysAlmostEqual(self, a, b, threshold=1e-6, mean=False, doabs=False):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         if a.shape == (0,):
#             return
#         if mean:
#             abserr = abs(a-b).mean()
#             oom = 0.5*(abs(a).mean()+abs(b).mean())
#         else:
#             abserr = abs(a-b).max()
#             oom = 0.5*(abs(a).max()+abs(b).max())
#         if doabs:
#             assert abserr <= threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, threshold)
#         else:
#             relerr = abserr/oom
#             assert relerr <= threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, threshold)
# 
#     def assertArrayAlmostConstant(self, arr, const, relerr_threshold):
#         error = abs(arr-const).max()
#         oom = const
#         relerr = error/oom
#         assert relerr <= relerr_threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, relerr_threshold)
# 
#     def assertArrayAlmostZero(self, arr, abserr_threshold):
#         abserr = abs(arr).max()
#         assert abserr <= abserr_threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, abserr_threshold)


# Path: molmod/test/test_transformations.py
from builtins import range
from molmod.test.common import BaseTestCase
from molmod import *
import numpy as np
        import copy

        for r in self.iter_random_rotations():
            self.assertArraysAlmostEqual(r.matrix, Complete.cast(r).matrix)

    def test_cast_complete(self):
        for c in self.iter_random_completes():
            self.assertArraysAlmostEqual(c.matrix, Complete.cast(c).matrix)


    def test_rotation_about_axis(self):
        x = np.array([2,0,0])
        c = Complete.about_axis(np.array([1,0,0]), np.pi, np.array([1,1,0]), False)
        self.assertArraysAlmostEqual(c*x, np.array([1,1,0]))

    def test_superpose(self):
        # create a few test sets with random data points, including degenerate
        # situations. (e.g. one point, two points, linear points)
        references = [ # a list of 2-tuples: (points, degenerate)
            (np.random.normal(0, 5, (n, 3)), False) for n in range(4, 40)
        ] + [
            (np.array([[0,0,1]], float), True),
            (np.array([[0,0,0],[0,0,1]], float), True),
            (np.array([[0,0,0],[0,0,1],[0,0,2]], float), True),
            (np.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True),
            (np.random.normal(0, 5, (3, 3)), True)
        ]

        # Do a random transformation on the points
        randomized = []
        for points, degenerate in references:
            #points[:] -= points.mean(axis=0)

            axis = random_unit()