test_composition.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import unittest
  2. import numpy as np
  3. from swiftt.taylor import taylor_map, factory_taylor
  4. from swiftt.math_algebra import cos, sin, atan2, sqrt
  5. tol_coeff = 1.e-12
  6. null_expansion_2var_order2 = factory_taylor.zero_expansion(2, 2)
  7. null_expansion_2var_order3 = factory_taylor.zero_expansion(2, 3)
  8. null_expansion_3var_order2 = factory_taylor.zero_expansion(3, 2)
  9. null_expansion_4var_order5 = factory_taylor.zero_expansion(4, 5)
  10. class TestComposition(unittest.TestCase):
  11. def test_comp_expansion_univariate(self):
  12. expansion1 = factory_taylor.zero_expansion(n_var=1, order=3)
  13. coeff1 = [2., -3., 5., 4]
  14. expansion1.coeff = coeff1
  15. expansion2 = factory_taylor.zero_expansion(n_var=1, order=3)
  16. coeff2 = [0., 7., -6., 0.]
  17. expansion2.coeff = coeff2
  18. comp = expansion1(expansion2)
  19. coeff = comp.coeff
  20. if coeff[0] != 2. or coeff[1] != -21. or coeff[2] != 263. or coeff[3] != 952.:
  21. self.fail()
  22. def test_inverted_map_univariate(self):
  23. expansion1 = factory_taylor.zero_expansion(1, 5)
  24. coeff1 = [0., 2., 1., 7., -4., 5.]
  25. expansion1.coeff = coeff1
  26. inverted = taylor_map.RealTaylorMap([expansion1]).compo_inverse()[0]
  27. composed = inverted(expansion1)
  28. coeff = composed.coeff
  29. if coeff[0] != 0. or coeff[1] != 1.:
  30. self.fail()
  31. if not np.array_equal(coeff[2:], np.zeros(len(coeff) - 2)):
  32. self.fail()
  33. def test_inverted_polar_coord(self):
  34. x1 = null_expansion_2var_order3.copy()
  35. coeff1 = [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.]
  36. x1.coeff = coeff1
  37. x2 = null_expansion_2var_order3.copy()
  38. coeff2 = [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.]
  39. x2.coeff = coeff2
  40. a = 0.5
  41. b = -1.
  42. expansion1 = x1 + a
  43. expansion2 = x2 + b
  44. radius = sqrt(expansion1**2 + expansion2**2)
  45. theta = atan2(expansion2, expansion1)
  46. polar_coord = taylor_map.RealTaylorMap([radius, theta])
  47. inverted = polar_coord.get_nilpo_part().compo_inverse()
  48. inverted[0] += a
  49. inverted[1] += b
  50. expansion1 = x1 + sqrt(a**2 + b**2)
  51. expansion2 = x2 + atan2(b, a)
  52. analytical = taylor_map.RealTaylorMap([expansion1 * cos(expansion2), expansion1 * sin(expansion2)])
  53. for i in range(0, 2):
  54. if not np.allclose(inverted[i].coeff, analytical[i].coeff):
  55. self.fail()
  56. def test_inverted_map_bivariate(self):
  57. x1 = null_expansion_2var_order3.copy()
  58. coeff1 = [0., 1., 4., -5., 3.5, 1., -2., 3., 0., 7.]
  59. x1.coeff = coeff1
  60. x2 = null_expansion_2var_order3.copy()
  61. coeff2 = [0., -3., 0., 6., -1.5, 2., 3., -4., 8., 1.]
  62. x2.coeff = coeff2
  63. map_origin = taylor_map.RealTaylorMap([x1, x2])
  64. inverted = map_origin.compo_inverse()
  65. composed = map_origin.compose(inverted)
  66. for i in range(0, 2):
  67. coeff = composed[i].coeff
  68. if coeff[i + 1] != 1.:
  69. self.fail()
  70. for j in range(3, len(coeff)):
  71. if np.fabs(coeff[j]) > tol_coeff:
  72. self.fail()
  73. def test_truncated_inverse_univariate(self):
  74. old_order = 5
  75. expansion = factory_taylor.zero_expansion(1, old_order)
  76. coeff = np.random.random(old_order + 1)
  77. coeff[0] = 0.
  78. expansion.coeff = coeff
  79. new_order = 4
  80. trunc = expansion.compo_inverse().truncated(new_order)
  81. same = expansion.truncated(new_order).compo_inverse()
  82. coeff1 = trunc.coeff
  83. coeff2 = same.coeff
  84. if not np.array_equal(coeff1[:new_order + 1], coeff2[:new_order + 1]):
  85. self.fail()
  86. def test_comp_map_1(self):
  87. expansion1 = factory_taylor.zero_expansion(1, 2)
  88. coeff1 = [3., -1., 2.]
  89. expansion1.coeff = coeff1
  90. expansion2 = factory_taylor.zero_expansion(1, 2)
  91. coeff2 = [-2., 5., 1.]
  92. expansion2.coeff = coeff2
  93. lhs = taylor_map.RealTaylorMap([expansion1, expansion2])
  94. expansion = null_expansion_2var_order2.copy()
  95. coeff_rhs = [0., 3., 4., -5., -1., -3.]
  96. expansion.coeff = coeff_rhs
  97. rhs = taylor_map.RealTaylorMap([expansion])
  98. composed = lhs(rhs)
  99. coeff = composed[0].coeff
  100. if not np.array_equal(coeff, [3., -3., -4., 23., 49., 35.]):
  101. self.fail()
  102. def test_comp_map_2(self):
  103. expansion = null_expansion_2var_order2.copy()
  104. coeff = [3., -1., 0., 2., 0., 1.]
  105. expansion.coeff = coeff
  106. lhs = taylor_map.RealTaylorMap([expansion])
  107. expansion1 = factory_taylor.zero_expansion(1, 2)
  108. coeff1 = [0., 3., 4.]
  109. expansion1.coeff = coeff1
  110. expansion2 = factory_taylor.zero_expansion(1, 2)
  111. coeff2 = [0., -1., 2.]
  112. expansion2.coeff = coeff2
  113. rhs = taylor_map.RealTaylorMap([expansion1, expansion2])
  114. composed = lhs(rhs)
  115. coeff = composed[0].coeff
  116. if not np.array_equal(coeff, [3., -3., 15.]):
  117. self.fail()
  118. def test_comp_expansion(self):
  119. expansion = null_expansion_2var_order2.copy()
  120. coeff = [3., -1., 0., 2., 0., 1.]
  121. expansion.coeff = coeff
  122. lhs = expansion
  123. expansion1 = factory_taylor.zero_expansion(1, 2)
  124. coeff1 = [0., 3., 4.]
  125. expansion1.coeff = coeff1
  126. expansion2 = factory_taylor.zero_expansion(1, 2)
  127. coeff2 = [0., -1., 2.]
  128. expansion2.coeff = coeff2
  129. rhs = taylor_map.RealTaylorMap([expansion1, expansion2])
  130. composed = lhs(rhs)
  131. coeff = composed.coeff
  132. if not np.array_equal(coeff, [3., -3., 15.]):
  133. self.fail()
  134. def test_real_root_coeff(self):
  135. order = 4
  136. root1_nominal = 2.
  137. root2_nominal = -3.
  138. real_map = factory_taylor.create_unknown_map(order, [root1_nominal, root2_nominal])
  139. root1 = real_map[0]
  140. root2 = real_map[1]
  141. bc = taylor_map.RealTaylorMap([-(root1 + root2), root1 * root2])
  142. roots_from_inversion = bc.get_nilpo_part().compo_inverse()
  143. roots_from_inversion.const = [root1_nominal, root2_nominal]
  144. root1_from_inversion = roots_from_inversion[0]
  145. root2_from_inversion = roots_from_inversion[1]
  146. b = real_map[0].copy()
  147. b.const = -(root2_nominal + root1_nominal)
  148. c = real_map[1].copy()
  149. c.const = root2_nominal * root1_nominal
  150. sqrt_delta = sqrt(b**2 - 4. * c)
  151. root1_formula = 0.5 * (sqrt_delta - b)
  152. root2_formula = (-0.5) * (b + sqrt_delta)
  153. coeff1_formula = root1_formula.coeff
  154. coeff1_from_inversion = root1_from_inversion.coeff
  155. coeff2_formula = root2_formula.coeff
  156. coeff2_from_inversion = root2_from_inversion.coeff
  157. if not np.allclose(coeff1_formula, coeff1_from_inversion):
  158. self.fail()
  159. if not np.allclose(coeff2_formula, coeff2_from_inversion):
  160. self.fail()
  161. def test_complex_root_coeff(self):
  162. order = 4
  163. root1_nominal = complex(0., 1.)
  164. root2_nominal = complex(0., -1.)
  165. complex_map = factory_taylor.create_unknown_map(order, [root1_nominal, root2_nominal])
  166. root1 = complex_map[0].copy()
  167. root2 = complex_map[1].copy()
  168. bc = taylor_map.ComplexTaylorMap([-(root1 + root2), root1 * root2])
  169. roots_from_inversion = bc.get_nilpo_part().compo_inverse()
  170. root1_from_inversion = roots_from_inversion[0] + root1_nominal
  171. root2_from_inversion = roots_from_inversion[1] + root2_nominal
  172. b = complex_map[0].copy()
  173. b.const = -(root2_nominal + root1_nominal)
  174. c = complex_map[1].copy()
  175. c.const = root2_nominal * root1_nominal
  176. delta = b ** 2 - 4. * c
  177. sqrt_delta = sqrt(delta)
  178. root1_formula = 0.5 * (sqrt_delta - b)
  179. root2_formula = (-0.5) * (b + sqrt_delta)
  180. if root1_from_inversion != root1_formula:
  181. self.fail()
  182. if root2_from_inversion != root2_formula:
  183. self.fail()
  184. if __name__ == '__main__':
  185. unittest.main()