1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3
4
5import sympy
6import mathics
7import random
8import sys
9import unittest
10
11
12class SympyConvert(unittest.TestCase):
13
14    def compare_to_sympy(self, mathics_expr, sympy_expr, **kwargs):
15        self.assertEqual(mathics_expr.to_sympy(**kwargs), sympy_expr)
16
17    def compare_to_mathics(self, mathics_expr, sympy_expr, **kwargs):
18        self.assertEqual(mathics_expr, mathics.from_sympy(sympy_expr, **kwargs))
19
20    def compare(self, mathics_expr, sympy_expr, **kwargs):
21        self.compare_to_sympy(mathics_expr, sympy_expr, **kwargs)
22        self.compare_to_mathics(mathics_expr, sympy_expr)
23
24    def testSymbol(self):
25        self.compare(
26            mathics.Symbol('Global`x'),
27            sympy.Symbol('_Mathics_User_Global`x'))
28        self.compare(
29            mathics.Symbol('_Mathics_User_x'),
30            sympy.Symbol('_Mathics_User_System`_Mathics_User_x'))
31
32    def testReal(self):
33        self.compare(mathics.Real('1.0'), sympy.Float('1.0'))
34        self.compare(mathics.Real(1.0), sympy.Float(1.0))
35
36    def testInteger(self):
37        self.compare(mathics.Integer(0), sympy.Integer(0))
38        self.compare(mathics.Integer(1), sympy.Integer(1))
39
40        n = random.randint(-sys.maxsize, sys.maxsize)
41        self.compare(mathics.Integer(n), sympy.Integer(n))
42
43        n = random.randint(sys.maxsize, sys.maxsize * sys.maxsize)
44        self.compare(mathics.Integer(n), sympy.Integer(n))
45
46    def testComplex(self):
47        self.compare(
48            mathics.Complex(mathics.Real('1.0'), mathics.Real('1.0')),
49            sympy.Add(sympy.Float('1.0'), sympy.Float('1.0') * sympy.I))
50
51        self.compare(
52            mathics.Complex(mathics.Integer(0), mathics.Integer(1)),
53            sympy.I)
54
55        self.compare(
56            mathics.Complex(mathics.Integer(-1), mathics.Integer(1)),
57            sympy.Integer(-1) + sympy.I)
58
59    def testString(self):
60        self.assertIsNone(mathics.String("abc").to_sympy())
61
62    def testAdd(self):
63        self.compare(
64            mathics.Expression(
65                'Plus', mathics.Integer(1), mathics.Symbol('Global`x')),
66            sympy.Add(
67                sympy.Integer(1),
68                sympy.Symbol('_Mathics_User_Global`x')))
69
70    def testIntegrate(self):
71        self.compare(
72            mathics.Expression(
73                'Integrate', mathics.Symbol('Global`x'),
74                mathics.Symbol('Global`y')),
75            sympy.Integral(
76                sympy.Symbol('_Mathics_User_Global`x'),
77                sympy.Symbol('_Mathics_User_Global`y')))
78
79    def testDerivative(self):
80        self.compare(
81            mathics.Expression(
82                'D', mathics.Symbol('Global`x'), mathics.Symbol('Global`y')),
83            sympy.Derivative(
84                sympy.Symbol('_Mathics_User_Global`x'),
85                sympy.Symbol('_Mathics_User_Global`y')))
86
87    def testDerivative2(self):
88        kwargs = {'converted_functions': set(['Global`f'])}
89
90        head = mathics.Expression(mathics.Expression('System`Derivative', mathics.Integer(1), mathics.Integer(0)), mathics.Symbol('Global`f'))
91        expr = mathics.Expression(head, mathics.Symbol('Global`x'), mathics.Symbol('Global`y'))
92
93        sfxy = sympy.Function(str('_Mathics_User_Global`f'))(sympy.Symbol('_Mathics_User_Global`x'), sympy.Symbol('_Mathics_User_Global`y'))
94        sym_expr = sympy.Derivative(sfxy, sympy.Symbol('_Mathics_User_Global`x'))
95
96        self.compare_to_sympy(expr, sym_expr, **kwargs)
97        # compare_to_mathics fails because Derivative becomes D (which then evaluates to Derivative)
98
99    def testConvertedFunctions(self):
100        kwargs = {'converted_functions': set(['Global`f'])}
101
102        marg1 = mathics.Expression('Global`f', mathics.Symbol('Global`x'))
103        sarg1 = sympy.Function(str('_Mathics_User_Global`f'))(sympy.Symbol('_Mathics_User_Global`x'))
104        self.compare(marg1, sarg1, **kwargs)
105
106        marg2 = mathics.Expression('Global`f',
107            mathics.Symbol('Global`x'), mathics.Symbol('Global`y'))
108        sarg2 = sympy.Function(str('_Mathics_User_Global`f'))(
109            sympy.Symbol('_Mathics_User_Global`x'), sympy.Symbol('_Mathics_User_Global`y'))
110        self.compare(marg2, sarg2, **kwargs)
111
112        self.compare(
113            mathics.Expression('D', marg2, mathics.Symbol('Global`x')),
114            sympy.Derivative(sarg2, sympy.Symbol('_Mathics_User_Global`x')),
115            **kwargs)
116
117    def testExpression(self):
118        self.compare(
119            mathics.Expression('Sin', mathics.Symbol('Global`x')),
120            sympy.sin(sympy.Symbol('_Mathics_User_Global`x')))
121
122    def testConstant(self):
123        self.compare(
124            mathics.Symbol('System`E'),
125            sympy.E)
126        self.compare(
127            mathics.Symbol('System`Pi'),
128            sympy.pi)
129
130    def testGamma(self):
131        self.compare(
132            mathics.Expression('Gamma', mathics.Symbol('Global`z')),
133            sympy.gamma(sympy.Symbol('_Mathics_User_Global`z')))
134        self.compare(
135            mathics.Expression(
136                'Gamma',
137                mathics.Symbol('Global`z'),
138                mathics.Symbol('Global`x')),
139            sympy.uppergamma(
140                sympy.Symbol('_Mathics_User_Global`z'),
141                sympy.Symbol('_Mathics_User_Global`x')))
142
143
144class PythonConvert(unittest.TestCase):
145    def compare(self, mathics_expr, python_expr):
146        self.assertEqual(mathics_expr.to_python(), python_expr)
147        self.assertEqual(mathics_expr, mathics.from_python(python_expr))
148
149    def testReal(self):
150        self.compare(mathics.Real('0.0'), 0.0)
151        self.compare(mathics.Real('1.5'), 1.5)
152        self.compare(mathics.Real('-1.5'), -1.5)
153
154    def testInteger(self):
155        self.compare(mathics.Integer(1), 1)
156
157    @unittest.expectedFailure
158    def testString(self):
159        self.compare(mathics.String("abc"), '"abc"')
160
161    @unittest.expectedFailure
162    def testSymbol(self):
163        self.compare(mathics.Symbol("abc"), "abc")
164
165    def testComplex(self):
166        self.compare(mathics.Complex(mathics.Integer(1), mathics.Integer(1)), 1 + 1j)
167        self.compare(mathics.Complex(mathics.MachineReal(1.0), mathics.MachineReal(1.0)), 1.0 + 1.0j)
168        self.compare(mathics.Complex(mathics.Integer(1), mathics.MachineReal(1.0)), 1 + 1.0j)
169        self.compare(mathics.Complex(mathics.MachineReal(1.0), mathics.Integer(1)), 1.0 + 1j)
170        self.compare(mathics.Complex(mathics.Real('1.0', 5), mathics.Integer(1)), 1.0 + 1j)
171        self.compare(mathics.Complex(mathics.Integer(1), mathics.Real('1.0', 20)), 1 + 1.0j)
172
173        self.compare(mathics.Complex(mathics.Integer(0), mathics.Integer(1)), 1j)
174        self.compare(mathics.Complex(mathics.Integer(1), mathics.Integer(0)), 1)
175
176    def testList(self):
177        self.compare(mathics.Expression('List', mathics.Integer(1)), [1])
178
179
180if __name__ == '__main__':
181    unittest.main()
182