from sympy.core import (pi, oo, symbols, Rational, Integer, GoldenRatio, EulerGamma, Catalan, Lambda, Dummy, S, Eq, Ne, Le, Lt, Gt, Ge, Mod) from sympy.functions import (Piecewise, sin, cos, Abs, exp, ceiling, sqrt, sinh, cosh, tanh, asin, acos, acosh, Max, Min) from sympy.testing.pytest import raises from sympy.printing.jscode import JavascriptCodePrinter from sympy.utilities.lambdify import implemented_function from sympy.tensor import IndexedBase, Idx from sympy.matrices import Matrix, MatrixSymbol from sympy.printing.jscode import jscode x, y, z = symbols('x,y,z') def test_printmethod(): assert jscode(Abs(x)) == "Math.abs(x)" def test_jscode_sqrt(): assert jscode(sqrt(x)) == "Math.sqrt(x)" assert jscode(x**0.5) == "Math.sqrt(x)" assert jscode(x**(S.One/3)) == "Math.cbrt(x)" def test_jscode_Pow(): g = implemented_function('g', Lambda(x, 2*x)) assert jscode(x**3) == "Math.pow(x, 3)" assert jscode(x**(y**3)) == "Math.pow(x, Math.pow(y, 3))" assert jscode(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \ "Math.pow(3.5*2*x, -x + Math.pow(y, x))/(Math.pow(x, 2) + y)" assert jscode(x**-1.0) == '1/x' def test_jscode_constants_mathh(): assert jscode(exp(1)) == "Math.E" assert jscode(pi) == "Math.PI" assert jscode(oo) == "Number.POSITIVE_INFINITY" assert jscode(-oo) == "Number.NEGATIVE_INFINITY" def test_jscode_constants_other(): assert jscode( 2*GoldenRatio) == "var GoldenRatio = %s;\n2*GoldenRatio" % GoldenRatio.evalf(17) assert jscode(2*Catalan) == "var Catalan = %s;\n2*Catalan" % Catalan.evalf(17) assert jscode( 2*EulerGamma) == "var EulerGamma = %s;\n2*EulerGamma" % EulerGamma.evalf(17) def test_jscode_Rational(): assert jscode(Rational(3, 7)) == "3/7" assert jscode(Rational(18, 9)) == "2" assert jscode(Rational(3, -7)) == "-3/7" assert jscode(Rational(-3, -7)) == "3/7" def test_Relational(): assert jscode(Eq(x, y)) == "x == y" assert jscode(Ne(x, y)) == "x != y" assert jscode(Le(x, y)) == "x <= y" assert jscode(Lt(x, y)) == "x < y" assert jscode(Gt(x, y)) == "x > y" assert jscode(Ge(x, y)) == "x >= y" def test_Mod(): assert jscode(Mod(x, y)) == '((x % y) + y) % y' assert jscode(Mod(x, x + y)) == '((x % (x + y)) + (x + y)) % (x + y)' p1, p2 = symbols('p1 p2', positive=True) assert jscode(Mod(p1, p2)) == 'p1 % p2' assert jscode(Mod(p1, p2 + 3)) == 'p1 % (p2 + 3)' assert jscode(Mod(-3, -7, evaluate=False)) == '(-3) % (-7)' assert jscode(-Mod(p1, p2)) == '-(p1 % p2)' assert jscode(x*Mod(p1, p2)) == 'x*(p1 % p2)' def test_jscode_Integer(): assert jscode(Integer(67)) == "67" assert jscode(Integer(-1)) == "-1" def test_jscode_functions(): assert jscode(sin(x) ** cos(x)) == "Math.pow(Math.sin(x), Math.cos(x))" assert jscode(sinh(x) * cosh(x)) == "Math.sinh(x)*Math.cosh(x)" assert jscode(Max(x, y) + Min(x, y)) == "Math.max(x, y) + Math.min(x, y)" assert jscode(tanh(x)*acosh(y)) == "Math.tanh(x)*Math.acosh(y)" assert jscode(asin(x)-acos(y)) == "-Math.acos(y) + Math.asin(x)" def test_jscode_inline_function(): x = symbols('x') g = implemented_function('g', Lambda(x, 2*x)) assert jscode(g(x)) == "2*x" g = implemented_function('g', Lambda(x, 2*x/Catalan)) assert jscode(g(x)) == "var Catalan = %s;\n2*x/Catalan" % Catalan.evalf(17) A = IndexedBase('A') i = Idx('i', symbols('n', integer=True)) g = implemented_function('g', Lambda(x, x*(1 + x)*(2 + x))) assert jscode(g(A[i]), assign_to=A[i]) == ( "for (var i=0; i 1), (sin(x), x > 0)) raises(ValueError, lambda: jscode(expr)) def test_jscode_Piecewise_deep(): p = jscode(2*Piecewise((x, x < 1), (x**2, True))) s = \ """\ 2*((x < 1) ? ( x ) : ( Math.pow(x, 2) ))\ """ assert p == s def test_jscode_settings(): raises(TypeError, lambda: jscode(sin(x), method="garbage")) def test_jscode_Indexed(): n, m, o = symbols('n m o', integer=True) i, j, k = Idx('i', n), Idx('j', m), Idx('k', o) p = JavascriptCodePrinter() p._not_c = set() x = IndexedBase('x')[j] assert p._print_Indexed(x) == 'x[j]' A = IndexedBase('A')[i, j] assert p._print_Indexed(A) == 'A[%s]' % (m*i+j) B = IndexedBase('B')[i, j, k] assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k) assert p._not_c == set() def test_jscode_loops_matrix_vector(): n, m = symbols('n m', integer=True) A = IndexedBase('A') x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', m) j = Idx('j', n) s = ( 'for (var i=0; i0), (y, True)), sin(z)]) A = MatrixSymbol('A', 3, 1) assert jscode(mat, A) == ( "A[0] = x*y;\n" "if (y > 0) {\n" " A[1] = x + 2;\n" "}\n" "else {\n" " A[1] = y;\n" "}\n" "A[2] = Math.sin(z);") # Test using MatrixElements in expressions expr = Piecewise((2*A[2, 0], x > 0), (A[2, 0], True)) + sin(A[1, 0]) + A[0, 0] assert jscode(expr) == ( "((x > 0) ? (\n" " 2*A[2]\n" ")\n" ": (\n" " A[2]\n" ")) + Math.sin(A[1]) + A[0]") # Test using MatrixElements in a Matrix q = MatrixSymbol('q', 5, 1) M = MatrixSymbol('M', 3, 3) m = Matrix([[sin(q[1,0]), 0, cos(q[2,0])], [q[1,0] + q[2,0], q[3, 0], 5], [2*q[4, 0]/q[1,0], sqrt(q[0,0]) + 4, 0]]) assert jscode(m, M) == ( "M[0] = Math.sin(q[1]);\n" "M[1] = 0;\n" "M[2] = Math.cos(q[2]);\n" "M[3] = q[1] + q[2];\n" "M[4] = q[3];\n" "M[5] = 5;\n" "M[6] = 2*q[4]/q[1];\n" "M[7] = Math.sqrt(q[0]) + 4;\n" "M[8] = 0;") def test_MatrixElement_printing(): # test cases for issue #11821 A = MatrixSymbol("A", 1, 3) B = MatrixSymbol("B", 1, 3) C = MatrixSymbol("C", 1, 3) assert(jscode(A[0, 0]) == "A[0]") assert(jscode(3 * A[0, 0]) == "3*A[0]") F = C[0, 0].subs(C, A - B) assert(jscode(F) == "(A - B)[0]")