test_printing.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. # -*- coding: utf-8 -*-
  2. from sympy.core.function import Function
  3. from sympy.core.symbol import symbols
  4. from sympy.functions.elementary.miscellaneous import sqrt
  5. from sympy.functions.elementary.trigonometric import (asin, cos, sin)
  6. from sympy.physics.vector import ReferenceFrame, dynamicsymbols, Dyadic
  7. from sympy.physics.vector.printing import (VectorLatexPrinter, vpprint,
  8. vsprint, vsstrrepr, vlatex)
  9. a, b, c = symbols('a, b, c')
  10. alpha, omega, beta = dynamicsymbols('alpha, omega, beta')
  11. A = ReferenceFrame('A')
  12. N = ReferenceFrame('N')
  13. v = a ** 2 * N.x + b * N.y + c * sin(alpha) * N.z
  14. w = alpha * N.x + sin(omega) * N.y + alpha * beta * N.z
  15. ww = alpha * N.x + asin(omega) * N.y - alpha.diff() * beta * N.z
  16. o = a/b * N.x + (c+b)/a * N.y + c**2/b * N.z
  17. y = a ** 2 * (N.x | N.y) + b * (N.y | N.y) + c * sin(alpha) * (N.z | N.y)
  18. x = alpha * (N.x | N.x) + sin(omega) * (N.y | N.z) + alpha * beta * (N.z | N.x)
  19. xx = N.x | (-N.y - N.z)
  20. xx2 = N.x | (N.y + N.z)
  21. def ascii_vpretty(expr):
  22. return vpprint(expr, use_unicode=False, wrap_line=False)
  23. def unicode_vpretty(expr):
  24. return vpprint(expr, use_unicode=True, wrap_line=False)
  25. def test_latex_printer():
  26. r = Function('r')('t')
  27. assert VectorLatexPrinter().doprint(r ** 2) == "r^{2}"
  28. r2 = Function('r^2')('t')
  29. assert VectorLatexPrinter().doprint(r2.diff()) == r'\dot{r^{2}}'
  30. ra = Function('r__a')('t')
  31. assert VectorLatexPrinter().doprint(ra.diff().diff()) == r'\ddot{r^{a}}'
  32. def test_vector_pretty_print():
  33. # TODO : The unit vectors should print with subscripts but they just
  34. # print as `n_x` instead of making `x` a subscript with unicode.
  35. # TODO : The pretty print division does not print correctly here:
  36. # w = alpha * N.x + sin(omega) * N.y + alpha / beta * N.z
  37. expected = """\
  38. 2
  39. a n_x + b n_y + c*sin(alpha) n_z\
  40. """
  41. uexpected = """\
  42. 2
  43. a n_x + b n_y + c⋅sin(α) n_z\
  44. """
  45. assert ascii_vpretty(v) == expected
  46. assert unicode_vpretty(v) == uexpected
  47. expected = 'alpha n_x + sin(omega) n_y + alpha*beta n_z'
  48. uexpected = 'α n_x + sin(ω) n_y + α⋅β n_z'
  49. assert ascii_vpretty(w) == expected
  50. assert unicode_vpretty(w) == uexpected
  51. expected = """\
  52. 2
  53. a b + c c
  54. - n_x + ----- n_y + -- n_z
  55. b a b\
  56. """
  57. uexpected = """\
  58. 2
  59. a b + c c
  60. ─ n_x + ───── n_y + ── n_z
  61. b a b\
  62. """
  63. assert ascii_vpretty(o) == expected
  64. assert unicode_vpretty(o) == uexpected
  65. def test_vector_latex():
  66. a, b, c, d, omega = symbols('a, b, c, d, omega')
  67. v = (a ** 2 + b / c) * A.x + sqrt(d) * A.y + cos(omega) * A.z
  68. assert vlatex(v) == (r'(a^{2} + \frac{b}{c})\mathbf{\hat{a}_x} + '
  69. r'\sqrt{d}\mathbf{\hat{a}_y} + '
  70. r'\cos{\left(\omega \right)}'
  71. r'\mathbf{\hat{a}_z}')
  72. theta, omega, alpha, q = dynamicsymbols('theta, omega, alpha, q')
  73. v = theta * A.x + omega * omega * A.y + (q * alpha) * A.z
  74. assert vlatex(v) == (r'\theta\mathbf{\hat{a}_x} + '
  75. r'\omega^{2}\mathbf{\hat{a}_y} + '
  76. r'\alpha q\mathbf{\hat{a}_z}')
  77. phi1, phi2, phi3 = dynamicsymbols('phi1, phi2, phi3')
  78. theta1, theta2, theta3 = symbols('theta1, theta2, theta3')
  79. v = (sin(theta1) * A.x +
  80. cos(phi1) * cos(phi2) * A.y +
  81. cos(theta1 + phi3) * A.z)
  82. assert vlatex(v) == (r'\sin{\left(\theta_{1} \right)}'
  83. r'\mathbf{\hat{a}_x} + \cos{'
  84. r'\left(\phi_{1} \right)} \cos{'
  85. r'\left(\phi_{2} \right)}\mathbf{\hat{a}_y} + '
  86. r'\cos{\left(\theta_{1} + '
  87. r'\phi_{3} \right)}\mathbf{\hat{a}_z}')
  88. N = ReferenceFrame('N')
  89. a, b, c, d, omega = symbols('a, b, c, d, omega')
  90. v = (a ** 2 + b / c) * N.x + sqrt(d) * N.y + cos(omega) * N.z
  91. expected = (r'(a^{2} + \frac{b}{c})\mathbf{\hat{n}_x} + '
  92. r'\sqrt{d}\mathbf{\hat{n}_y} + '
  93. r'\cos{\left(\omega \right)}'
  94. r'\mathbf{\hat{n}_z}')
  95. assert vlatex(v) == expected
  96. # Try custom unit vectors.
  97. N = ReferenceFrame('N', latexs=(r'\hat{i}', r'\hat{j}', r'\hat{k}'))
  98. v = (a ** 2 + b / c) * N.x + sqrt(d) * N.y + cos(omega) * N.z
  99. expected = (r'(a^{2} + \frac{b}{c})\hat{i} + '
  100. r'\sqrt{d}\hat{j} + '
  101. r'\cos{\left(\omega \right)}\hat{k}')
  102. assert vlatex(v) == expected
  103. expected = r'\alpha\mathbf{\hat{n}_x} + \operatorname{asin}{\left(\omega ' \
  104. r'\right)}\mathbf{\hat{n}_y} - \beta \dot{\alpha}\mathbf{\hat{n}_z}'
  105. assert vlatex(ww) == expected
  106. expected = r'- \mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} - ' \
  107. r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_z}'
  108. assert vlatex(xx) == expected
  109. expected = r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} + ' \
  110. r'\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_z}'
  111. assert vlatex(xx2) == expected
  112. def test_vector_latex_arguments():
  113. assert vlatex(N.x * 3.0, full_prec=False) == r'3.0\mathbf{\hat{n}_x}'
  114. assert vlatex(N.x * 3.0, full_prec=True) == r'3.00000000000000\mathbf{\hat{n}_x}'
  115. def test_vector_latex_with_functions():
  116. N = ReferenceFrame('N')
  117. omega, alpha = dynamicsymbols('omega, alpha')
  118. v = omega.diff() * N.x
  119. assert vlatex(v) == r'\dot{\omega}\mathbf{\hat{n}_x}'
  120. v = omega.diff() ** alpha * N.x
  121. assert vlatex(v) == (r'\dot{\omega}^{\alpha}'
  122. r'\mathbf{\hat{n}_x}')
  123. def test_dyadic_pretty_print():
  124. expected = """\
  125. 2
  126. a n_x|n_y + b n_y|n_y + c*sin(alpha) n_z|n_y\
  127. """
  128. uexpected = """\
  129. 2
  130. a n_x⊗n_y + b n_y⊗n_y + c⋅sin(α) n_z⊗n_y\
  131. """
  132. assert ascii_vpretty(y) == expected
  133. assert unicode_vpretty(y) == uexpected
  134. expected = 'alpha n_x|n_x + sin(omega) n_y|n_z + alpha*beta n_z|n_x'
  135. uexpected = 'α n_x⊗n_x + sin(ω) n_y⊗n_z + α⋅β n_z⊗n_x'
  136. assert ascii_vpretty(x) == expected
  137. assert unicode_vpretty(x) == uexpected
  138. assert ascii_vpretty(Dyadic([])) == '0'
  139. assert unicode_vpretty(Dyadic([])) == '0'
  140. assert ascii_vpretty(xx) == '- n_x|n_y - n_x|n_z'
  141. assert unicode_vpretty(xx) == '- n_x⊗n_y - n_x⊗n_z'
  142. assert ascii_vpretty(xx2) == 'n_x|n_y + n_x|n_z'
  143. assert unicode_vpretty(xx2) == 'n_x⊗n_y + n_x⊗n_z'
  144. def test_dyadic_latex():
  145. expected = (r'a^{2}\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_y} + '
  146. r'b\mathbf{\hat{n}_y}\otimes \mathbf{\hat{n}_y} + '
  147. r'c \sin{\left(\alpha \right)}'
  148. r'\mathbf{\hat{n}_z}\otimes \mathbf{\hat{n}_y}')
  149. assert vlatex(y) == expected
  150. expected = (r'\alpha\mathbf{\hat{n}_x}\otimes \mathbf{\hat{n}_x} + '
  151. r'\sin{\left(\omega \right)}\mathbf{\hat{n}_y}'
  152. r'\otimes \mathbf{\hat{n}_z} + '
  153. r'\alpha \beta\mathbf{\hat{n}_z}\otimes \mathbf{\hat{n}_x}')
  154. assert vlatex(x) == expected
  155. assert vlatex(Dyadic([])) == '0'
  156. def test_dyadic_str():
  157. assert vsprint(Dyadic([])) == '0'
  158. assert vsprint(y) == 'a**2*(N.x|N.y) + b*(N.y|N.y) + c*sin(alpha)*(N.z|N.y)'
  159. assert vsprint(x) == 'alpha*(N.x|N.x) + sin(omega)*(N.y|N.z) + alpha*beta*(N.z|N.x)'
  160. assert vsprint(ww) == "alpha*N.x + asin(omega)*N.y - beta*alpha'*N.z"
  161. assert vsprint(xx) == '- (N.x|N.y) - (N.x|N.z)'
  162. assert vsprint(xx2) == '(N.x|N.y) + (N.x|N.z)'
  163. def test_vlatex(): # vlatex is broken #12078
  164. from sympy.physics.vector import vlatex
  165. x = symbols('x')
  166. J = symbols('J')
  167. f = Function('f')
  168. g = Function('g')
  169. h = Function('h')
  170. expected = r'J \left(\frac{d}{d x} g{\left(x \right)} - \frac{d}{d x} h{\left(x \right)}\right)'
  171. expr = J*f(x).diff(x).subs(f(x), g(x)-h(x))
  172. assert vlatex(expr) == expected
  173. def test_issue_13354():
  174. """
  175. Test for proper pretty printing of physics vectors with ADD
  176. instances in arguments.
  177. Test is exactly the one suggested in the original bug report by
  178. @moorepants.
  179. """
  180. a, b, c = symbols('a, b, c')
  181. A = ReferenceFrame('A')
  182. v = a * A.x + b * A.y + c * A.z
  183. w = b * A.x + c * A.y + a * A.z
  184. z = w + v
  185. expected = """(a + b) a_x + (b + c) a_y + (a + c) a_z"""
  186. assert ascii_vpretty(z) == expected
  187. def test_vector_derivative_printing():
  188. # First order
  189. v = omega.diff() * N.x
  190. assert unicode_vpretty(v) == 'ω̇ n_x'
  191. assert ascii_vpretty(v) == "omega'(t) n_x"
  192. # Second order
  193. v = omega.diff().diff() * N.x
  194. assert vlatex(v) == r'\ddot{\omega}\mathbf{\hat{n}_x}'
  195. assert unicode_vpretty(v) == 'ω̈ n_x'
  196. assert ascii_vpretty(v) == "omega''(t) n_x"
  197. # Third order
  198. v = omega.diff().diff().diff() * N.x
  199. assert vlatex(v) == r'\dddot{\omega}\mathbf{\hat{n}_x}'
  200. assert unicode_vpretty(v) == 'ω⃛ n_x'
  201. assert ascii_vpretty(v) == "omega'''(t) n_x"
  202. # Fourth order
  203. v = omega.diff().diff().diff().diff() * N.x
  204. assert vlatex(v) == r'\ddddot{\omega}\mathbf{\hat{n}_x}'
  205. assert unicode_vpretty(v) == 'ω⃜ n_x'
  206. assert ascii_vpretty(v) == "omega''''(t) n_x"
  207. # Fifth order
  208. v = omega.diff().diff().diff().diff().diff() * N.x
  209. assert vlatex(v) == r'\frac{d^{5}}{d t^{5}} \omega\mathbf{\hat{n}_x}'
  210. assert unicode_vpretty(v) == ' 5\n d\n───(ω) n_x\n 5\ndt'
  211. assert ascii_vpretty(v) == ' 5\n d\n---(omega) n_x\n 5\ndt'
  212. def test_vector_str_printing():
  213. assert vsprint(w) == 'alpha*N.x + sin(omega)*N.y + alpha*beta*N.z'
  214. assert vsprint(omega.diff() * N.x) == "omega'*N.x"
  215. assert vsstrrepr(w) == 'alpha*N.x + sin(omega)*N.y + alpha*beta*N.z'
  216. def test_vector_str_arguments():
  217. assert vsprint(N.x * 3.0, full_prec=False) == '3.0*N.x'
  218. assert vsprint(N.x * 3.0, full_prec=True) == '3.00000000000000*N.x'
  219. def test_issue_14041():
  220. import sympy.physics.mechanics as me
  221. A_frame = me.ReferenceFrame('A')
  222. thetad, phid = me.dynamicsymbols('theta, phi', 1)
  223. L = symbols('L')
  224. assert vlatex(L*(phid + thetad)**2*A_frame.x) == \
  225. r"L \left(\dot{\phi} + \dot{\theta}\right)^{2}\mathbf{\hat{a}_x}"
  226. assert vlatex((phid + thetad)**2*A_frame.x) == \
  227. r"\left(\dot{\phi} + \dot{\theta}\right)^{2}\mathbf{\hat{a}_x}"
  228. assert vlatex((phid*thetad)**a*A_frame.x) == \
  229. r"\left(\dot{\phi} \dot{\theta}\right)^{a}\mathbf{\hat{a}_x}"