monomials with different underlying variables or even different power of those variables must not be added additive inverses of each other should produce the zero monomial zero monomial zero monomial zero monomial coefficient float coefficient 0 so should equal the zero monomial the constant term cannot be added to any monomial that has any variables any literal cannot be added to a monomial however a monomial can be added to any int float fraction or monomial so 2 monomial is raises typeerror but monomial 2 may work fine any constant added to a zero monomial produces a monomial monomials with different underlying variables or even different power of those variables must not be subtracted additive inverses of each other should produce the zero monomial zero monomial zero monomial zero monomial coefficient int coefficient float the constant term cannot be added to any monomial that has any variables any literal cannot be added to a monomial however a monomial can be added to any int float fraction or monomial so 2 monomial is raises typeerror but monomial 2 may work fine any constant added to a zero monomial produces a monomial usual multiplication the positive and negative powers of the same variable should cancel out a coefficient of zero should make the product zero zero monomial any int float fraction or monomial zero monomial test usual float multiplication the zero monomial is not invertible check some inverses doesn t matter if the coefficient is fraction or float both should be treated as same should work fine without variables too any monomial divided by the zero monomial should raise a valueerror test some usual cases test with int test with float test with fraction test with a complete substitution map test with a more than complete substitution map should raise a valueerror if not enough variables are supplied the zero monomial always gives zero upon substitution any variable with zero power should not exist in the set of variables the zero monomial should output empty set a monomial should produce its copy with same underlying variable dictionary and same coefficient the zero monomial is identified and always clones to itself monomials with different underlying variables or even different power of those variables must not be added additive inverses of each other should produce the zero monomial zero monomial zero monomial zero monomial coefficient float coefficient 0 so should equal the zero monomial the constant term cannot be added to any monomial that has any variables any literal cannot be added to a monomial however a monomial can be added to any int float fraction or monomial so 2 monomial is raises typeerror but monomial 2 may work fine any constant added to a zero monomial produces a monomial monomials with different underlying variables or even different power of those variables must not be subtracted additive inverses of each other should produce the zero monomial zero monomial zero monomial zero monomial coefficient int coefficient float the constant term cannot be added to any monomial that has any variables any literal cannot be added to a monomial however a monomial can be added to any int float fraction or monomial so 2 monomial is raises typeerror but monomial 2 may work fine any constant added to a zero monomial produces a monomial usual multiplication the positive and negative powers of the same variable should cancel out a coefficient of zero should make the product zero zero monomial any int float fraction or monomial zero monomial test usual float multiplication the zero monomial is not invertible check some inverses doesn t matter if the coefficient is fraction or float both should be treated as same should work fine without variables too any monomial divided by the zero monomial should raise a valueerror test some usual cases test with int test with float test with fraction test with a complete substitution map test with a more than complete substitution map should raise a valueerror if not enough variables are supplied the zero monomial always gives zero upon substitution any variable with zero power should not exist in the set of variables the zero monomial should output empty set a monomial should produce its copy with same underlying variable dictionary and same coefficient the zero monomial is identified and always clones to itself
from algorithms.maths.polynomial import Monomial
from fractions import Fraction
import math


import unittest


class TestSuite(unittest.TestCase):

	def setUp(self):
		self.m1 = Monomial({})
		self.m2 = Monomial({1: 1}, 2)
		self.m3 = Monomial({1: 2, 2: -1}, 1.5)
		self.m4 = Monomial({1: 1, 2: 2, 3: -2}, 3)
		self.m5 = Monomial({2: 1, 3: 0}, Fraction(2, 3))
		self.m6 = Monomial({1: 0, 2: 0, 3: 0}, -2.27)
		self.m7 = Monomial({1: 2, 7: 2}, -math.pi)
		self.m8 = Monomial({150: 5, 170: 2, 10000: 3}, 0)
		self.m9 = 2
		self.m10 = math.pi
		self.m11 = Fraction(3, 8)
		self.m12 = 0
		self.m13 = Monomial({1: 1}, -2)
		self.m14 = Monomial({1: 2}, 3)
		self.m15 = Monomial({1: 1}, 3)
		self.m16 = Monomial({1: 2, 7: 2}, math.pi)
		self.m17 = Monomial({1: -1})

	def test_monomial_addition(self):

		
		
		self.assertRaises(ValueError, lambda x, y: x + y, self.m1, self.m2)
		self.assertRaises(ValueError, lambda x, y: x + y, self.m2, self.m3)
		self.assertRaises(ValueError, lambda x, y: x + y, self.m2, self.m14)

		
		self.assertEqual(self.m13 + self.m2, self.m1)

		
		self.assertEqual(self.m1 + self.m1, self.m1)

		
		self.assertEqual(self.m7 + self.m7, Monomial({1: 2, 7: 2},
		                                             -2 * math.pi))

		
		self.assertEqual(self.m8, self.m1)

		
		
		self.assertRaises(ValueError, lambda x, y: x + y, self.m2, self.m9)

		
		

		
		self.assertRaises(TypeError, lambda x, y: x + y, self.m9, self.m2)

		
		
		self.assertEqual(self.m1 + self.m9, Monomial({}, 2))
		self.assertEqual(self.m1 + self.m12, Monomial({}, 0))

		return

	def test_monomial_subtraction(self):

		
		
		self.assertRaises(ValueError, lambda x, y: x - y, self.m1, self.m2)
		self.assertRaises(ValueError, lambda x, y: x - y, self.m2, self.m3)
		self.assertRaises(ValueError, lambda x, y: x - y, self.m2, self.m14)

		
		self.assertEqual(self.m2 - self.m2, self.m1)
		self.assertEqual(self.m2 - self.m2, Monomial({}, 0))

		
		self.assertEqual(self.m1 - self.m1, self.m1)

		
		self.assertEqual(self.m2 - self.m15, Monomial({1: 1}, -1))

		
		self.assertEqual(self.m16 - self.m7, Monomial({1: 2, 7: 2},
		                                              2 * math.pi))

		
		
		self.assertRaises(ValueError, lambda x, y: x - y, self.m2, self.m9)

		
		

		
		self.assertRaises(TypeError, lambda x, y: x - y, self.m9, self.m2)

		
		
		self.assertEqual(self.m1 - self.m9, Monomial({}, -2))
		self.assertEqual(self.m1 - self.m12, Monomial({}, 0))

		return

	def test_monomial_multiplication(self):

		
		
		
		self.assertEqual(self.m2 * self.m13, Monomial({1: 2}, -4))
		self.assertEqual(self.m2 * self.m17, Monomial({}, 2))

		
		
		self.assertEqual(self.m8 * self.m5, self.m1)
		self.assertEqual(self.m1 * self.m2, self.m1)

		
		self.assertEqual(self.m7 * self.m3, Monomial({1: 4, 2: -1, 7: 2},
		                                             -1.5*math.pi))

		return

	def test_monomial_inverse(self):

		
		self.assertRaises(ValueError, lambda x: x.inverse(), self.m1)
		self.assertRaises(ValueError, lambda x: x.inverse(), self.m8)
		self.assertRaises(ValueError, lambda x: x.inverse(),
		                  Monomial({}, self.m12))

		
		self.assertEqual(self.m7.inverse(), Monomial({1: -2, 7: -2}, -1 / math.pi))

		
		
		self.assertEqual(self.m5.inverse(), Monomial({2: -1}, Fraction(3, 2)))
		self.assertEqual(self.m5.inverse(), Monomial({2: -1}, 1.5))

		
		self.assertTrue(self.m6.inverse(), Monomial({}, Fraction(-100, 227)))
		self.assertEqual(self.m6.inverse(), Monomial({}, -1/2.27))
		return

	def test_monomial_division(self):
		
		self.assertRaises(ValueError, lambda x, y: x.__truediv__(y),
		                  self.m2, self.m1)
		self.assertRaises(ValueError, lambda x, y: x.__truediv__(y),
		                  self.m2, self.m8)
		self.assertRaises(ValueError, lambda x, y: x.__truediv__(y),
		                  self.m2, self.m12)

		
		self.assertEqual(self.m7 / self.m3, Monomial({2: 1, 7: 2},
		                                             -2 * math.pi / 3))
		self.assertEqual(self.m14 / self.m13, Monomial({1: 1}) * Fraction(-3, 2))

		return

	def test_monomial_substitution(self):
		
		self.assertAlmostEqual(self.m7.substitute(2), -16 * math.pi, delta=1e-9)
		
		self.assertAlmostEqual(self.m7.substitute(1.5), (1.5 ** 4) * -math.pi,
		                       delta=1e-9)
		
		self.assertAlmostEqual(self.m7.substitute(Fraction(-1, 2)),
		                       (Fraction(-1, 2) ** 4)*-math.pi, delta=1e-9)
		
		self.assertAlmostEqual(self.m7.substitute({1: 3, 7: 0}),
		                       (3 ** 2) * (0 ** 2) * -math.pi, delta=1e-9)
		
		self.assertAlmostEqual(self.m7.substitute({1: 3, 7: 0, 2: 2}),
		                       (3 ** 2) * (0 ** 2) * -math.pi, delta=1e-9)

		
		self.assertRaises(ValueError, lambda x, y: x.substitute(y), self.m7,
		                  {1: 3, 2: 2})
		self.assertRaises(ValueError, lambda x, y: x.substitute(y), self.m7,
		                  {2: 2})

		
		self.assertEqual(self.m8.substitute(2), 0)
		self.assertEqual(self.m8.substitute({1231: 2, 1: 2}), 0)

		return

	def test_monomial_all_variables(self):

		
		
		self.assertEqual(self.m5.all_variables(), {2})
		self.assertEqual(self.m6.all_variables(), set())

		
		self.assertEqual(self.m8.all_variables(), set())

		return

	def test_monomial_clone(self):

		
		
		
		self.assertEqual(self.m3, self.m3.clone())

		
		
		self.assertEqual(self.m1, self.m8.clone())
		self.assertEqual(self.m1, self.m1.clone())
		self.assertEqual(self.m8, self.m1.clone())
		self.assertEqual(self.m8, self.m8.clone())
		return


if __name__ == '__main__':
	unittest.main()