add read me
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.parsing.ast_parser import parse_expr
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.core.sympify import SympifyError
|
||||
import warnings
|
||||
|
||||
def test_parse_expr():
|
||||
a, b = symbols('a, b')
|
||||
# tests issue_16393
|
||||
assert parse_expr('a + b', {}) == a + b
|
||||
raises(SympifyError, lambda: parse_expr('a + ', {}))
|
||||
|
||||
# tests Transform.visit_Constant
|
||||
assert parse_expr('1 + 2', {}) == S(3)
|
||||
assert parse_expr('1 + 2.0', {}) == S(3.0)
|
||||
|
||||
# tests Transform.visit_Name
|
||||
assert parse_expr('Rational(1, 2)', {}) == S(1)/2
|
||||
assert parse_expr('a', {'a': a}) == a
|
||||
|
||||
# tests issue_23092
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error')
|
||||
assert parse_expr('6 * 7', {}) == S(42)
|
||||
@@ -0,0 +1,178 @@
|
||||
import os
|
||||
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import skip
|
||||
from sympy.parsing.autolev import parse_autolev
|
||||
|
||||
antlr4 = import_module("antlr4")
|
||||
|
||||
if not antlr4:
|
||||
disabled = True
|
||||
|
||||
FILE_DIR = os.path.dirname(
|
||||
os.path.dirname(os.path.abspath(os.path.realpath(__file__))))
|
||||
|
||||
|
||||
def _test_examples(in_filename, out_filename, test_name=""):
|
||||
|
||||
in_file_path = os.path.join(FILE_DIR, 'autolev', 'test-examples',
|
||||
in_filename)
|
||||
correct_file_path = os.path.join(FILE_DIR, 'autolev', 'test-examples',
|
||||
out_filename)
|
||||
with open(in_file_path) as f:
|
||||
generated_code = parse_autolev(f, include_numeric=True)
|
||||
|
||||
with open(correct_file_path) as f:
|
||||
for idx, line1 in enumerate(f):
|
||||
if line1.startswith("#"):
|
||||
break
|
||||
try:
|
||||
line2 = generated_code.split('\n')[idx]
|
||||
assert line1.rstrip() == line2.rstrip()
|
||||
except Exception:
|
||||
msg = 'mismatch in ' + test_name + ' in line no: {0}'
|
||||
raise AssertionError(msg.format(idx+1))
|
||||
|
||||
|
||||
def test_rule_tests():
|
||||
|
||||
l = ["ruletest1", "ruletest2", "ruletest3", "ruletest4", "ruletest5",
|
||||
"ruletest6", "ruletest7", "ruletest8", "ruletest9", "ruletest10",
|
||||
"ruletest11", "ruletest12"]
|
||||
|
||||
for i in l:
|
||||
in_filepath = i + ".al"
|
||||
out_filepath = i + ".py"
|
||||
_test_examples(in_filepath, out_filepath, i)
|
||||
|
||||
|
||||
def test_pydy_examples():
|
||||
|
||||
l = ["mass_spring_damper", "chaos_pendulum", "double_pendulum",
|
||||
"non_min_pendulum"]
|
||||
|
||||
for i in l:
|
||||
in_filepath = os.path.join("pydy-example-repo", i + ".al")
|
||||
out_filepath = os.path.join("pydy-example-repo", i + ".py")
|
||||
_test_examples(in_filepath, out_filepath, i)
|
||||
|
||||
|
||||
def test_autolev_tutorial():
|
||||
|
||||
dir_path = os.path.join(FILE_DIR, 'autolev', 'test-examples',
|
||||
'autolev-tutorial')
|
||||
|
||||
if os.path.isdir(dir_path):
|
||||
l = ["tutor1", "tutor2", "tutor3", "tutor4", "tutor5", "tutor6",
|
||||
"tutor7"]
|
||||
for i in l:
|
||||
in_filepath = os.path.join("autolev-tutorial", i + ".al")
|
||||
out_filepath = os.path.join("autolev-tutorial", i + ".py")
|
||||
_test_examples(in_filepath, out_filepath, i)
|
||||
|
||||
|
||||
def test_dynamics_online():
|
||||
|
||||
dir_path = os.path.join(FILE_DIR, 'autolev', 'test-examples',
|
||||
'dynamics-online')
|
||||
|
||||
if os.path.isdir(dir_path):
|
||||
ch1 = ["1-4", "1-5", "1-6", "1-7", "1-8", "1-9_1", "1-9_2", "1-9_3"]
|
||||
ch2 = ["2-1", "2-2", "2-3", "2-4", "2-5", "2-6", "2-7", "2-8", "2-9",
|
||||
"circular"]
|
||||
ch3 = ["3-1_1", "3-1_2", "3-2_1", "3-2_2", "3-2_3", "3-2_4", "3-2_5",
|
||||
"3-3"]
|
||||
ch4 = ["4-1_1", "4-2_1", "4-4_1", "4-4_2", "4-5_1", "4-5_2"]
|
||||
chapters = [(ch1, "ch1"), (ch2, "ch2"), (ch3, "ch3"), (ch4, "ch4")]
|
||||
for ch, name in chapters:
|
||||
for i in ch:
|
||||
in_filepath = os.path.join("dynamics-online", name, i + ".al")
|
||||
out_filepath = os.path.join("dynamics-online", name, i + ".py")
|
||||
_test_examples(in_filepath, out_filepath, i)
|
||||
|
||||
|
||||
def test_output_01():
|
||||
"""Autolev example calculates the position, velocity, and acceleration of a
|
||||
point and expresses in a single reference frame::
|
||||
|
||||
(1) FRAMES C,D,F
|
||||
(2) VARIABLES FD'',DC''
|
||||
(3) CONSTANTS R,L
|
||||
(4) POINTS O,E
|
||||
(5) SIMPROT(F,D,1,FD)
|
||||
-> (6) F_D = [1, 0, 0; 0, COS(FD), -SIN(FD); 0, SIN(FD), COS(FD)]
|
||||
(7) SIMPROT(D,C,2,DC)
|
||||
-> (8) D_C = [COS(DC), 0, SIN(DC); 0, 1, 0; -SIN(DC), 0, COS(DC)]
|
||||
(9) W_C_F> = EXPRESS(W_C_F>, F)
|
||||
-> (10) W_C_F> = FD'*F1> + COS(FD)*DC'*F2> + SIN(FD)*DC'*F3>
|
||||
(11) P_O_E>=R*D2>-L*C1>
|
||||
(12) P_O_E>=EXPRESS(P_O_E>, D)
|
||||
-> (13) P_O_E> = -L*COS(DC)*D1> + R*D2> + L*SIN(DC)*D3>
|
||||
(14) V_E_F>=EXPRESS(DT(P_O_E>,F),D)
|
||||
-> (15) V_E_F> = L*SIN(DC)*DC'*D1> - L*SIN(DC)*FD'*D2> + (R*FD'+L*COS(DC)*DC')*D3>
|
||||
(16) A_E_F>=EXPRESS(DT(V_E_F>,F),D)
|
||||
-> (17) A_E_F> = L*(COS(DC)*DC'^2+SIN(DC)*DC'')*D1> + (-R*FD'^2-2*L*COS(DC)*DC'*FD'-L*SIN(DC)*FD'')*D2> + (R*FD''+L*COS(DC)*DC''-L*SIN(DC)*DC'^2-L*SIN(DC)*FD'^2)*D3>
|
||||
|
||||
"""
|
||||
|
||||
if not antlr4:
|
||||
skip('Test skipped: antlr4 is not installed.')
|
||||
|
||||
autolev_input = """\
|
||||
FRAMES C,D,F
|
||||
VARIABLES FD'',DC''
|
||||
CONSTANTS R,L
|
||||
POINTS O,E
|
||||
SIMPROT(F,D,1,FD)
|
||||
SIMPROT(D,C,2,DC)
|
||||
W_C_F>=EXPRESS(W_C_F>,F)
|
||||
P_O_E>=R*D2>-L*C1>
|
||||
P_O_E>=EXPRESS(P_O_E>,D)
|
||||
V_E_F>=EXPRESS(DT(P_O_E>,F),D)
|
||||
A_E_F>=EXPRESS(DT(V_E_F>,F),D)\
|
||||
"""
|
||||
|
||||
sympy_input = parse_autolev(autolev_input)
|
||||
|
||||
g = {}
|
||||
l = {}
|
||||
exec(sympy_input, g, l)
|
||||
|
||||
w_c_f = l['frame_c'].ang_vel_in(l['frame_f'])
|
||||
# P_O_E> means "the position of point E wrt to point O"
|
||||
p_o_e = l['point_e'].pos_from(l['point_o'])
|
||||
v_e_f = l['point_e'].vel(l['frame_f'])
|
||||
a_e_f = l['point_e'].acc(l['frame_f'])
|
||||
|
||||
# NOTE : The Autolev outputs above were manually transformed into
|
||||
# equivalent SymPy physics vector expressions. Would be nice to automate
|
||||
# this transformation.
|
||||
expected_w_c_f = (l['fd'].diff()*l['frame_f'].x +
|
||||
cos(l['fd'])*l['dc'].diff()*l['frame_f'].y +
|
||||
sin(l['fd'])*l['dc'].diff()*l['frame_f'].z)
|
||||
|
||||
assert (w_c_f - expected_w_c_f).simplify() == 0
|
||||
|
||||
expected_p_o_e = (-l['l']*cos(l['dc'])*l['frame_d'].x +
|
||||
l['r']*l['frame_d'].y +
|
||||
l['l']*sin(l['dc'])*l['frame_d'].z)
|
||||
|
||||
assert (p_o_e - expected_p_o_e).simplify() == 0
|
||||
|
||||
expected_v_e_f = (l['l']*sin(l['dc'])*l['dc'].diff()*l['frame_d'].x -
|
||||
l['l']*sin(l['dc'])*l['fd'].diff()*l['frame_d'].y +
|
||||
(l['r']*l['fd'].diff() +
|
||||
l['l']*cos(l['dc'])*l['dc'].diff())*l['frame_d'].z)
|
||||
assert (v_e_f - expected_v_e_f).simplify() == 0
|
||||
|
||||
expected_a_e_f = (l['l']*(cos(l['dc'])*l['dc'].diff()**2 +
|
||||
sin(l['dc'])*l['dc'].diff().diff())*l['frame_d'].x +
|
||||
(-l['r']*l['fd'].diff()**2 -
|
||||
2*l['l']*cos(l['dc'])*l['dc'].diff()*l['fd'].diff() -
|
||||
l['l']*sin(l['dc'])*l['fd'].diff().diff())*l['frame_d'].y +
|
||||
(l['r']*l['fd'].diff().diff() +
|
||||
l['l']*cos(l['dc'])*l['dc'].diff().diff() -
|
||||
l['l']*sin(l['dc'])*l['dc'].diff()**2 -
|
||||
l['l']*sin(l['dc'])*l['fd'].diff()**2)*l['frame_d'].z)
|
||||
assert (a_e_f - expected_a_e_f).simplify() == 0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import sympy
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.parsing.latex.lark import LarkLaTeXParser, TransformToSymPyExpr, parse_latex_lark
|
||||
from sympy.external import import_module
|
||||
|
||||
lark = import_module("lark")
|
||||
|
||||
# disable tests if lark is not present
|
||||
disabled = lark is None
|
||||
|
||||
grammar_file = os.path.join(os.path.dirname(__file__), "../latex/lark/grammar/latex.lark")
|
||||
|
||||
modification1 = """
|
||||
%override DIV_SYMBOL: DIV
|
||||
%override MUL_SYMBOL: MUL | CMD_TIMES
|
||||
"""
|
||||
|
||||
modification2 = r"""
|
||||
%override number: /\d+(,\d*)?/
|
||||
"""
|
||||
|
||||
def init_custom_parser(modification, transformer=None):
|
||||
latex_grammar = Path(grammar_file).read_text(encoding="utf-8")
|
||||
latex_grammar += modification
|
||||
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
f.write(bytes(latex_grammar, encoding="utf8"))
|
||||
f.flush()
|
||||
|
||||
parser = LarkLaTeXParser(grammar_file=f.name, transformer=transformer)
|
||||
|
||||
return parser
|
||||
|
||||
def test_custom1():
|
||||
# Removes the parser's ability to understand \cdot and \div.
|
||||
|
||||
parser = init_custom_parser(modification1)
|
||||
|
||||
with raises(lark.exceptions.UnexpectedCharacters):
|
||||
parser.doparse(r"a \cdot b")
|
||||
parser.doparse(r"x \div y")
|
||||
|
||||
class CustomTransformer(TransformToSymPyExpr):
|
||||
def number(self, tokens):
|
||||
if "," in tokens[0]:
|
||||
# The Float constructor expects a dot as the decimal separator
|
||||
return sympy.core.numbers.Float(tokens[0].replace(",", "."))
|
||||
else:
|
||||
return sympy.core.numbers.Integer(tokens[0])
|
||||
|
||||
def test_custom2():
|
||||
# Makes the parser parse commas as the decimal separator instead of dots
|
||||
|
||||
parser = init_custom_parser(modification2, CustomTransformer)
|
||||
|
||||
with raises(lark.exceptions.UnexpectedCharacters):
|
||||
# Asserting that the default parser cannot parse numbers which have commas as
|
||||
# the decimal separator
|
||||
parse_latex_lark("100,1")
|
||||
parse_latex_lark("0,009")
|
||||
|
||||
parser.doparse("100,1")
|
||||
parser.doparse("0,009")
|
||||
parser.doparse("2,71828")
|
||||
parser.doparse("3,14159")
|
||||
@@ -0,0 +1,406 @@
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.parsing.sym_expr import SymPyExpression
|
||||
from sympy.external import import_module
|
||||
|
||||
lfortran = import_module('lfortran')
|
||||
|
||||
if lfortran:
|
||||
from sympy.codegen.ast import (Variable, IntBaseType, FloatBaseType, String,
|
||||
Return, FunctionDefinition, Assignment,
|
||||
Declaration, CodeBlock)
|
||||
from sympy.core import Integer, Float, Add
|
||||
from sympy.core.symbol import Symbol
|
||||
|
||||
|
||||
expr1 = SymPyExpression()
|
||||
expr2 = SymPyExpression()
|
||||
src = """\
|
||||
integer :: a, b, c, d
|
||||
real :: p, q, r, s
|
||||
"""
|
||||
|
||||
|
||||
def test_sym_expr():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
d = a + b -c
|
||||
"""
|
||||
)
|
||||
expr3 = SymPyExpression(src,'f')
|
||||
expr4 = SymPyExpression(src1,'f')
|
||||
ls1 = expr3.return_expr()
|
||||
ls2 = expr4.return_expr()
|
||||
for i in range(0, 7):
|
||||
assert isinstance(ls1[i], Declaration)
|
||||
assert isinstance(ls2[i], Declaration)
|
||||
assert isinstance(ls2[8], Assignment)
|
||||
assert ls1[0] == Declaration(
|
||||
Variable(
|
||||
Symbol('a'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls1[1] == Declaration(
|
||||
Variable(
|
||||
Symbol('b'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls1[2] == Declaration(
|
||||
Variable(
|
||||
Symbol('c'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls1[3] == Declaration(
|
||||
Variable(
|
||||
Symbol('d'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls1[4] == Declaration(
|
||||
Variable(
|
||||
Symbol('p'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls1[5] == Declaration(
|
||||
Variable(
|
||||
Symbol('q'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls1[6] == Declaration(
|
||||
Variable(
|
||||
Symbol('r'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls1[7] == Declaration(
|
||||
Variable(
|
||||
Symbol('s'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls2[8] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') + Symbol('b') - Symbol('c')
|
||||
)
|
||||
|
||||
def test_assignment():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
a = b
|
||||
c = d
|
||||
p = q
|
||||
r = s
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(0, 12):
|
||||
if iter < 8:
|
||||
assert isinstance(ls1[iter], Declaration)
|
||||
else:
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('a')),
|
||||
Variable(Symbol('b'))
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Variable(Symbol('d'))
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('p')),
|
||||
Variable(Symbol('q'))
|
||||
)
|
||||
assert ls1[11] == Assignment(
|
||||
Variable(Symbol('r')),
|
||||
Variable(Symbol('s'))
|
||||
)
|
||||
|
||||
|
||||
def test_binop_add():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
c = a + b
|
||||
d = a + c
|
||||
s = p + q + r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(8, 11):
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Symbol('a') + Symbol('b')
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') + Symbol('c')
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('s')),
|
||||
Symbol('p') + Symbol('q') + Symbol('r')
|
||||
)
|
||||
|
||||
|
||||
def test_binop_sub():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
c = a - b
|
||||
d = a - c
|
||||
s = p - q - r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(8, 11):
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Symbol('a') - Symbol('b')
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') - Symbol('c')
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('s')),
|
||||
Symbol('p') - Symbol('q') - Symbol('r')
|
||||
)
|
||||
|
||||
|
||||
def test_binop_mul():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
c = a * b
|
||||
d = a * c
|
||||
s = p * q * r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(8, 11):
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Symbol('a') * Symbol('b')
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') * Symbol('c')
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('s')),
|
||||
Symbol('p') * Symbol('q') * Symbol('r')
|
||||
)
|
||||
|
||||
|
||||
def test_binop_div():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
c = a / b
|
||||
d = a / c
|
||||
s = p / q
|
||||
r = q / p
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(8, 12):
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Symbol('a') / Symbol('b')
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') / Symbol('c')
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('s')),
|
||||
Symbol('p') / Symbol('q')
|
||||
)
|
||||
assert ls1[11] == Assignment(
|
||||
Variable(Symbol('r')),
|
||||
Symbol('q') / Symbol('p')
|
||||
)
|
||||
|
||||
def test_mul_binop():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
d = a + b - c
|
||||
c = a * b + d
|
||||
s = p * q / r
|
||||
r = p * s + q / p
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
ls1 = expr1.return_expr()
|
||||
for iter in range(8, 12):
|
||||
assert isinstance(ls1[iter], Assignment)
|
||||
assert ls1[8] == Assignment(
|
||||
Variable(Symbol('d')),
|
||||
Symbol('a') + Symbol('b') - Symbol('c')
|
||||
)
|
||||
assert ls1[9] == Assignment(
|
||||
Variable(Symbol('c')),
|
||||
Symbol('a') * Symbol('b') + Symbol('d')
|
||||
)
|
||||
assert ls1[10] == Assignment(
|
||||
Variable(Symbol('s')),
|
||||
Symbol('p') * Symbol('q') / Symbol('r')
|
||||
)
|
||||
assert ls1[11] == Assignment(
|
||||
Variable(Symbol('r')),
|
||||
Symbol('p') * Symbol('s') + Symbol('q') / Symbol('p')
|
||||
)
|
||||
|
||||
|
||||
def test_function():
|
||||
src1 = """\
|
||||
integer function f(a,b)
|
||||
integer :: x, y
|
||||
f = x + y
|
||||
end function
|
||||
"""
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
for iter in expr1.return_expr():
|
||||
assert isinstance(iter, FunctionDefinition)
|
||||
assert iter == FunctionDefinition(
|
||||
IntBaseType(String('integer')),
|
||||
name=String('f'),
|
||||
parameters=(
|
||||
Variable(Symbol('a')),
|
||||
Variable(Symbol('b'))
|
||||
),
|
||||
body=CodeBlock(
|
||||
Declaration(
|
||||
Variable(
|
||||
Symbol('a'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
),
|
||||
Declaration(
|
||||
Variable(
|
||||
Symbol('b'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
),
|
||||
Declaration(
|
||||
Variable(
|
||||
Symbol('f'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
),
|
||||
Declaration(
|
||||
Variable(
|
||||
Symbol('x'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
),
|
||||
Declaration(
|
||||
Variable(
|
||||
Symbol('y'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
),
|
||||
Assignment(
|
||||
Variable(Symbol('f')),
|
||||
Add(Symbol('x'), Symbol('y'))
|
||||
),
|
||||
Return(Variable(Symbol('f')))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_var():
|
||||
expr1.convert_to_expr(src, 'f')
|
||||
ls = expr1.return_expr()
|
||||
for iter in expr1.return_expr():
|
||||
assert isinstance(iter, Declaration)
|
||||
assert ls[0] == Declaration(
|
||||
Variable(
|
||||
Symbol('a'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[1] == Declaration(
|
||||
Variable(
|
||||
Symbol('b'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[2] == Declaration(
|
||||
Variable(
|
||||
Symbol('c'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[3] == Declaration(
|
||||
Variable(
|
||||
Symbol('d'),
|
||||
type = IntBaseType(String('integer')),
|
||||
value = Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[4] == Declaration(
|
||||
Variable(
|
||||
Symbol('p'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls[5] == Declaration(
|
||||
Variable(
|
||||
Symbol('q'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls[6] == Declaration(
|
||||
Variable(
|
||||
Symbol('r'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
assert ls[7] == Declaration(
|
||||
Variable(
|
||||
Symbol('s'),
|
||||
type = FloatBaseType(String('real')),
|
||||
value = Float(0.0)
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
def test_raise():
|
||||
from sympy.parsing.fortran.fortran_parser import ASR2PyVisitor
|
||||
raises(ImportError, lambda: ASR2PyVisitor())
|
||||
raises(ImportError, lambda: SymPyExpression(' ', mode = 'f'))
|
||||
@@ -0,0 +1,195 @@
|
||||
import sympy
|
||||
from sympy.parsing.sympy_parser import (
|
||||
parse_expr,
|
||||
standard_transformations,
|
||||
convert_xor,
|
||||
implicit_multiplication_application,
|
||||
implicit_multiplication,
|
||||
implicit_application,
|
||||
function_exponentiation,
|
||||
split_symbols,
|
||||
split_symbols_custom,
|
||||
_token_splittable
|
||||
)
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_implicit_multiplication():
|
||||
cases = {
|
||||
'5x': '5*x',
|
||||
'abc': 'a*b*c',
|
||||
'3sin(x)': '3*sin(x)',
|
||||
'(x+1)(x+2)': '(x+1)*(x+2)',
|
||||
'(5 x**2)sin(x)': '(5*x**2)*sin(x)',
|
||||
'2 sin(x) cos(x)': '2*sin(x)*cos(x)',
|
||||
'pi x': 'pi*x',
|
||||
'x pi': 'x*pi',
|
||||
'E x': 'E*x',
|
||||
'EulerGamma y': 'EulerGamma*y',
|
||||
'E pi': 'E*pi',
|
||||
'pi (x + 2)': 'pi*(x+2)',
|
||||
'(x + 2) pi': '(x+2)*pi',
|
||||
'pi sin(x)': 'pi*sin(x)',
|
||||
}
|
||||
transformations = standard_transformations + (convert_xor,)
|
||||
transformations2 = transformations + (split_symbols,
|
||||
implicit_multiplication)
|
||||
for case in cases:
|
||||
implicit = parse_expr(case, transformations=transformations2)
|
||||
normal = parse_expr(cases[case], transformations=transformations)
|
||||
assert(implicit == normal)
|
||||
|
||||
application = ['sin x', 'cos 2*x', 'sin cos x']
|
||||
for case in application:
|
||||
raises(SyntaxError,
|
||||
lambda: parse_expr(case, transformations=transformations2))
|
||||
raises(TypeError,
|
||||
lambda: parse_expr('sin**2(x)', transformations=transformations2))
|
||||
|
||||
|
||||
def test_implicit_application():
|
||||
cases = {
|
||||
'factorial': 'factorial',
|
||||
'sin x': 'sin(x)',
|
||||
'tan y**3': 'tan(y**3)',
|
||||
'cos 2*x': 'cos(2*x)',
|
||||
'(cot)': 'cot',
|
||||
'sin cos tan x': 'sin(cos(tan(x)))'
|
||||
}
|
||||
transformations = standard_transformations + (convert_xor,)
|
||||
transformations2 = transformations + (implicit_application,)
|
||||
for case in cases:
|
||||
implicit = parse_expr(case, transformations=transformations2)
|
||||
normal = parse_expr(cases[case], transformations=transformations)
|
||||
assert(implicit == normal), (implicit, normal)
|
||||
|
||||
multiplication = ['x y', 'x sin x', '2x']
|
||||
for case in multiplication:
|
||||
raises(SyntaxError,
|
||||
lambda: parse_expr(case, transformations=transformations2))
|
||||
raises(TypeError,
|
||||
lambda: parse_expr('sin**2(x)', transformations=transformations2))
|
||||
|
||||
|
||||
def test_function_exponentiation():
|
||||
cases = {
|
||||
'sin**2(x)': 'sin(x)**2',
|
||||
'exp^y(z)': 'exp(z)^y',
|
||||
'sin**2(E^(x))': 'sin(E^(x))**2'
|
||||
}
|
||||
transformations = standard_transformations + (convert_xor,)
|
||||
transformations2 = transformations + (function_exponentiation,)
|
||||
for case in cases:
|
||||
implicit = parse_expr(case, transformations=transformations2)
|
||||
normal = parse_expr(cases[case], transformations=transformations)
|
||||
assert(implicit == normal)
|
||||
|
||||
other_implicit = ['x y', 'x sin x', '2x', 'sin x',
|
||||
'cos 2*x', 'sin cos x']
|
||||
for case in other_implicit:
|
||||
raises(SyntaxError,
|
||||
lambda: parse_expr(case, transformations=transformations2))
|
||||
|
||||
assert parse_expr('x**2', local_dict={ 'x': sympy.Symbol('x') },
|
||||
transformations=transformations2) == parse_expr('x**2')
|
||||
|
||||
|
||||
def test_symbol_splitting():
|
||||
# By default Greek letter names should not be split (lambda is a keyword
|
||||
# so skip it)
|
||||
transformations = standard_transformations + (split_symbols,)
|
||||
greek_letters = ('alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta',
|
||||
'eta', 'theta', 'iota', 'kappa', 'mu', 'nu', 'xi',
|
||||
'omicron', 'pi', 'rho', 'sigma', 'tau', 'upsilon',
|
||||
'phi', 'chi', 'psi', 'omega')
|
||||
|
||||
for letter in greek_letters:
|
||||
assert(parse_expr(letter, transformations=transformations) ==
|
||||
parse_expr(letter))
|
||||
|
||||
# Make sure symbol splitting resolves names
|
||||
transformations += (implicit_multiplication,)
|
||||
local_dict = { 'e': sympy.E }
|
||||
cases = {
|
||||
'xe': 'E*x',
|
||||
'Iy': 'I*y',
|
||||
'ee': 'E*E',
|
||||
}
|
||||
for case, expected in cases.items():
|
||||
assert(parse_expr(case, local_dict=local_dict,
|
||||
transformations=transformations) ==
|
||||
parse_expr(expected))
|
||||
|
||||
# Make sure custom splitting works
|
||||
def can_split(symbol):
|
||||
if symbol not in ('unsplittable', 'names'):
|
||||
return _token_splittable(symbol)
|
||||
return False
|
||||
transformations = standard_transformations
|
||||
transformations += (split_symbols_custom(can_split),
|
||||
implicit_multiplication)
|
||||
|
||||
assert(parse_expr('unsplittable', transformations=transformations) ==
|
||||
parse_expr('unsplittable'))
|
||||
assert(parse_expr('names', transformations=transformations) ==
|
||||
parse_expr('names'))
|
||||
assert(parse_expr('xy', transformations=transformations) ==
|
||||
parse_expr('x*y'))
|
||||
for letter in greek_letters:
|
||||
assert(parse_expr(letter, transformations=transformations) ==
|
||||
parse_expr(letter))
|
||||
|
||||
|
||||
def test_all_implicit_steps():
|
||||
cases = {
|
||||
'2x': '2*x', # implicit multiplication
|
||||
'x y': 'x*y',
|
||||
'xy': 'x*y',
|
||||
'sin x': 'sin(x)', # add parentheses
|
||||
'2sin x': '2*sin(x)',
|
||||
'x y z': 'x*y*z',
|
||||
'sin(2 * 3x)': 'sin(2 * 3 * x)',
|
||||
'sin(x) (1 + cos(x))': 'sin(x) * (1 + cos(x))',
|
||||
'(x + 2) sin(x)': '(x + 2) * sin(x)',
|
||||
'(x + 2) sin x': '(x + 2) * sin(x)',
|
||||
'sin(sin x)': 'sin(sin(x))',
|
||||
'sin x!': 'sin(factorial(x))',
|
||||
'sin x!!': 'sin(factorial2(x))',
|
||||
'factorial': 'factorial', # don't apply a bare function
|
||||
'x sin x': 'x * sin(x)', # both application and multiplication
|
||||
'xy sin x': 'x * y * sin(x)',
|
||||
'(x+2)(x+3)': '(x + 2) * (x+3)',
|
||||
'x**2 + 2xy + y**2': 'x**2 + 2 * x * y + y**2', # split the xy
|
||||
'pi': 'pi', # don't mess with constants
|
||||
'None': 'None',
|
||||
'ln sin x': 'ln(sin(x))', # multiple implicit function applications
|
||||
'sin x**2': 'sin(x**2)', # implicit application to an exponential
|
||||
'alpha': 'Symbol("alpha")', # don't split Greek letters/subscripts
|
||||
'x_2': 'Symbol("x_2")',
|
||||
'sin^2 x**2': 'sin(x**2)**2', # function raised to a power
|
||||
'sin**3(x)': 'sin(x)**3',
|
||||
'(factorial)': 'factorial',
|
||||
'tan 3x': 'tan(3*x)',
|
||||
'sin^2(3*E^(x))': 'sin(3*E**(x))**2',
|
||||
'sin**2(E^(3x))': 'sin(E**(3*x))**2',
|
||||
'sin^2 (3x*E^(x))': 'sin(3*x*E^x)**2',
|
||||
'pi sin x': 'pi*sin(x)',
|
||||
}
|
||||
transformations = standard_transformations + (convert_xor,)
|
||||
transformations2 = transformations + (implicit_multiplication_application,)
|
||||
for case in cases:
|
||||
implicit = parse_expr(case, transformations=transformations2)
|
||||
normal = parse_expr(cases[case], transformations=transformations)
|
||||
assert(implicit == normal)
|
||||
|
||||
|
||||
def test_no_methods_implicit_multiplication():
|
||||
# Issue 21020
|
||||
u = sympy.Symbol('u')
|
||||
transformations = standard_transformations + \
|
||||
(implicit_multiplication,)
|
||||
expr = parse_expr('x.is_polynomial(x)', transformations=transformations)
|
||||
assert expr == True
|
||||
expr = parse_expr('(exp(x) / (1 + exp(2x))).subs(exp(x), u)',
|
||||
transformations=transformations)
|
||||
assert expr == u/(u**2 + 1)
|
||||
@@ -0,0 +1,358 @@
|
||||
from sympy.testing.pytest import raises, XFAIL
|
||||
from sympy.external import import_module
|
||||
|
||||
from sympy.concrete.products import Product
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.function import (Derivative, Function)
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import (E, oo)
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.relational import (GreaterThan, LessThan, StrictGreaterThan, StrictLessThan, Unequality)
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.combinatorial.factorials import (binomial, factorial)
|
||||
from sympy.functions.elementary.complexes import (Abs, conjugate)
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.integers import (ceiling, floor)
|
||||
from sympy.functions.elementary.miscellaneous import (root, sqrt)
|
||||
from sympy.functions.elementary.trigonometric import (asin, cos, csc, sec, sin, tan)
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.series.limits import Limit
|
||||
|
||||
from sympy.core.relational import Eq, Ne, Lt, Le, Gt, Ge
|
||||
from sympy.physics.quantum.state import Bra, Ket
|
||||
from sympy.abc import x, y, z, a, b, c, t, k, n
|
||||
antlr4 = import_module("antlr4")
|
||||
|
||||
# disable tests if antlr4-python3-runtime is not present
|
||||
disabled = antlr4 is None
|
||||
|
||||
theta = Symbol('theta')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
# shorthand definitions
|
||||
def _Add(a, b):
|
||||
return Add(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _Mul(a, b):
|
||||
return Mul(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _Pow(a, b):
|
||||
return Pow(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _Sqrt(a):
|
||||
return sqrt(a, evaluate=False)
|
||||
|
||||
|
||||
def _Conjugate(a):
|
||||
return conjugate(a, evaluate=False)
|
||||
|
||||
|
||||
def _Abs(a):
|
||||
return Abs(a, evaluate=False)
|
||||
|
||||
|
||||
def _factorial(a):
|
||||
return factorial(a, evaluate=False)
|
||||
|
||||
|
||||
def _exp(a):
|
||||
return exp(a, evaluate=False)
|
||||
|
||||
|
||||
def _log(a, b):
|
||||
return log(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _binomial(n, k):
|
||||
return binomial(n, k, evaluate=False)
|
||||
|
||||
|
||||
def test_import():
|
||||
from sympy.parsing.latex._build_latex_antlr import (
|
||||
build_parser,
|
||||
check_antlr_version,
|
||||
dir_latex_antlr
|
||||
)
|
||||
# XXX: It would be better to come up with a test for these...
|
||||
del build_parser, check_antlr_version, dir_latex_antlr
|
||||
|
||||
|
||||
# These LaTeX strings should parse to the corresponding SymPy expression
|
||||
GOOD_PAIRS = [
|
||||
(r"0", 0),
|
||||
(r"1", 1),
|
||||
(r"-3.14", -3.14),
|
||||
(r"(-7.13)(1.5)", _Mul(-7.13, 1.5)),
|
||||
(r"x", x),
|
||||
(r"2x", 2*x),
|
||||
(r"x^2", x**2),
|
||||
(r"x^\frac{1}{2}", _Pow(x, _Pow(2, -1))),
|
||||
(r"x^{3 + 1}", x**_Add(3, 1)),
|
||||
(r"-c", -c),
|
||||
(r"a \cdot b", a * b),
|
||||
(r"a / b", a / b),
|
||||
(r"a \div b", a / b),
|
||||
(r"a + b", a + b),
|
||||
(r"a + b - a", _Add(a+b, -a)),
|
||||
(r"a^2 + b^2 = c^2", Eq(a**2 + b**2, c**2)),
|
||||
(r"(x + y) z", _Mul(_Add(x, y), z)),
|
||||
(r"a'b+ab'", _Add(_Mul(Symbol("a'"), b), _Mul(a, Symbol("b'")))),
|
||||
(r"y''_1", Symbol("y_{1}''")),
|
||||
(r"y_1''", Symbol("y_{1}''")),
|
||||
(r"\left(x + y\right) z", _Mul(_Add(x, y), z)),
|
||||
(r"\left( x + y\right ) z", _Mul(_Add(x, y), z)),
|
||||
(r"\left( x + y\right ) z", _Mul(_Add(x, y), z)),
|
||||
(r"\left[x + y\right] z", _Mul(_Add(x, y), z)),
|
||||
(r"\left\{x + y\right\} z", _Mul(_Add(x, y), z)),
|
||||
(r"1+1", _Add(1, 1)),
|
||||
(r"0+1", _Add(0, 1)),
|
||||
(r"1*2", _Mul(1, 2)),
|
||||
(r"0*1", _Mul(0, 1)),
|
||||
(r"1 \times 2 ", _Mul(1, 2)),
|
||||
(r"x = y", Eq(x, y)),
|
||||
(r"x \neq y", Ne(x, y)),
|
||||
(r"x < y", Lt(x, y)),
|
||||
(r"x > y", Gt(x, y)),
|
||||
(r"x \leq y", Le(x, y)),
|
||||
(r"x \geq y", Ge(x, y)),
|
||||
(r"x \le y", Le(x, y)),
|
||||
(r"x \ge y", Ge(x, y)),
|
||||
(r"\lfloor x \rfloor", floor(x)),
|
||||
(r"\lceil x \rceil", ceiling(x)),
|
||||
(r"\langle x |", Bra('x')),
|
||||
(r"| x \rangle", Ket('x')),
|
||||
(r"\sin \theta", sin(theta)),
|
||||
(r"\sin(\theta)", sin(theta)),
|
||||
(r"\sin^{-1} a", asin(a)),
|
||||
(r"\sin a \cos b", _Mul(sin(a), cos(b))),
|
||||
(r"\sin \cos \theta", sin(cos(theta))),
|
||||
(r"\sin(\cos \theta)", sin(cos(theta))),
|
||||
(r"\frac{a}{b}", a / b),
|
||||
(r"\dfrac{a}{b}", a / b),
|
||||
(r"\tfrac{a}{b}", a / b),
|
||||
(r"\frac12", _Pow(2, -1)),
|
||||
(r"\frac12y", _Mul(_Pow(2, -1), y)),
|
||||
(r"\frac1234", _Mul(_Pow(2, -1), 34)),
|
||||
(r"\frac2{3}", _Mul(2, _Pow(3, -1))),
|
||||
(r"\frac{\sin{x}}2", _Mul(sin(x), _Pow(2, -1))),
|
||||
(r"\frac{a + b}{c}", _Mul(a + b, _Pow(c, -1))),
|
||||
(r"\frac{7}{3}", _Mul(7, _Pow(3, -1))),
|
||||
(r"(\csc x)(\sec y)", csc(x)*sec(y)),
|
||||
(r"\lim_{x \to 3} a", Limit(a, x, 3, dir='+-')),
|
||||
(r"\lim_{x \rightarrow 3} a", Limit(a, x, 3, dir='+-')),
|
||||
(r"\lim_{x \Rightarrow 3} a", Limit(a, x, 3, dir='+-')),
|
||||
(r"\lim_{x \longrightarrow 3} a", Limit(a, x, 3, dir='+-')),
|
||||
(r"\lim_{x \Longrightarrow 3} a", Limit(a, x, 3, dir='+-')),
|
||||
(r"\lim_{x \to 3^{+}} a", Limit(a, x, 3, dir='+')),
|
||||
(r"\lim_{x \to 3^{-}} a", Limit(a, x, 3, dir='-')),
|
||||
(r"\lim_{x \to 3^+} a", Limit(a, x, 3, dir='+')),
|
||||
(r"\lim_{x \to 3^-} a", Limit(a, x, 3, dir='-')),
|
||||
(r"\infty", oo),
|
||||
(r"\lim_{x \to \infty} \frac{1}{x}", Limit(_Pow(x, -1), x, oo)),
|
||||
(r"\frac{d}{dx} x", Derivative(x, x)),
|
||||
(r"\frac{d}{dt} x", Derivative(x, t)),
|
||||
(r"f(x)", f(x)),
|
||||
(r"f(x, y)", f(x, y)),
|
||||
(r"f(x, y, z)", f(x, y, z)),
|
||||
(r"f'_1(x)", Function("f_{1}'")(x)),
|
||||
(r"f_{1}''(x+y)", Function("f_{1}''")(x+y)),
|
||||
(r"\frac{d f(x)}{dx}", Derivative(f(x), x)),
|
||||
(r"\frac{d\theta(x)}{dx}", Derivative(Function('theta')(x), x)),
|
||||
(r"x \neq y", Unequality(x, y)),
|
||||
(r"|x|", _Abs(x)),
|
||||
(r"||x||", _Abs(Abs(x))),
|
||||
(r"|x||y|", _Abs(x)*_Abs(y)),
|
||||
(r"||x||y||", _Abs(_Abs(x)*_Abs(y))),
|
||||
(r"\pi^{|xy|}", Symbol('pi')**_Abs(x*y)),
|
||||
(r"\int x dx", Integral(x, x)),
|
||||
(r"\int x d\theta", Integral(x, theta)),
|
||||
(r"\int (x^2 - y)dx", Integral(x**2 - y, x)),
|
||||
(r"\int x + a dx", Integral(_Add(x, a), x)),
|
||||
(r"\int da", Integral(1, a)),
|
||||
(r"\int_0^7 dx", Integral(1, (x, 0, 7))),
|
||||
(r"\int\limits_{0}^{1} x dx", Integral(x, (x, 0, 1))),
|
||||
(r"\int_a^b x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^b_a x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{a}^b x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^{b}_a x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{a}^{b} x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^{b}_{a} x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{f(a)}^{f(b)} f(z) dz", Integral(f(z), (z, f(a), f(b)))),
|
||||
(r"\int (x+a)", Integral(_Add(x, a), x)),
|
||||
(r"\int a + b + c dx", Integral(_Add(_Add(a, b), c), x)),
|
||||
(r"\int \frac{dz}{z}", Integral(Pow(z, -1), z)),
|
||||
(r"\int \frac{3 dz}{z}", Integral(3*Pow(z, -1), z)),
|
||||
(r"\int \frac{1}{x} dx", Integral(Pow(x, -1), x)),
|
||||
(r"\int \frac{1}{a} + \frac{1}{b} dx",
|
||||
Integral(_Add(_Pow(a, -1), Pow(b, -1)), x)),
|
||||
(r"\int \frac{3 \cdot d\theta}{\theta}",
|
||||
Integral(3*_Pow(theta, -1), theta)),
|
||||
(r"\int \frac{1}{x} + 1 dx", Integral(_Add(_Pow(x, -1), 1), x)),
|
||||
(r"x_0", Symbol('x_{0}')),
|
||||
(r"x_{1}", Symbol('x_{1}')),
|
||||
(r"x_a", Symbol('x_{a}')),
|
||||
(r"x_{b}", Symbol('x_{b}')),
|
||||
(r"h_\theta", Symbol('h_{theta}')),
|
||||
(r"h_{\theta}", Symbol('h_{theta}')),
|
||||
(r"h_{\theta}(x_0, x_1)",
|
||||
Function('h_{theta}')(Symbol('x_{0}'), Symbol('x_{1}'))),
|
||||
(r"x!", _factorial(x)),
|
||||
(r"100!", _factorial(100)),
|
||||
(r"\theta!", _factorial(theta)),
|
||||
(r"(x + 1)!", _factorial(_Add(x, 1))),
|
||||
(r"(x!)!", _factorial(_factorial(x))),
|
||||
(r"x!!!", _factorial(_factorial(_factorial(x)))),
|
||||
(r"5!7!", _Mul(_factorial(5), _factorial(7))),
|
||||
(r"\sqrt{x}", sqrt(x)),
|
||||
(r"\sqrt{x + b}", sqrt(_Add(x, b))),
|
||||
(r"\sqrt[3]{\sin x}", root(sin(x), 3)),
|
||||
(r"\sqrt[y]{\sin x}", root(sin(x), y)),
|
||||
(r"\sqrt[\theta]{\sin x}", root(sin(x), theta)),
|
||||
(r"\sqrt{\frac{12}{6}}", _Sqrt(_Mul(12, _Pow(6, -1)))),
|
||||
(r"\overline{z}", _Conjugate(z)),
|
||||
(r"\overline{\overline{z}}", _Conjugate(_Conjugate(z))),
|
||||
(r"\overline{x + y}", _Conjugate(_Add(x, y))),
|
||||
(r"\overline{x} + \overline{y}", _Conjugate(x) + _Conjugate(y)),
|
||||
(r"x < y", StrictLessThan(x, y)),
|
||||
(r"x \leq y", LessThan(x, y)),
|
||||
(r"x > y", StrictGreaterThan(x, y)),
|
||||
(r"x \geq y", GreaterThan(x, y)),
|
||||
(r"\mathit{x}", Symbol('x')),
|
||||
(r"\mathit{test}", Symbol('test')),
|
||||
(r"\mathit{TEST}", Symbol('TEST')),
|
||||
(r"\mathit{HELLO world}", Symbol('HELLO world')),
|
||||
(r"\sum_{k = 1}^{3} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^3 c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum^{3}_{k = 1} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum^3_{k = 1} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^{10} k^2", Sum(k**2, (k, 1, 10))),
|
||||
(r"\sum_{n = 0}^{\infty} \frac{1}{n!}",
|
||||
Sum(_Pow(_factorial(n), -1), (n, 0, oo))),
|
||||
(r"\prod_{a = b}^{c} x", Product(x, (a, b, c))),
|
||||
(r"\prod_{a = b}^c x", Product(x, (a, b, c))),
|
||||
(r"\prod^{c}_{a = b} x", Product(x, (a, b, c))),
|
||||
(r"\prod^c_{a = b} x", Product(x, (a, b, c))),
|
||||
(r"\exp x", _exp(x)),
|
||||
(r"\exp(x)", _exp(x)),
|
||||
(r"\lg x", _log(x, 10)),
|
||||
(r"\ln x", _log(x, E)),
|
||||
(r"\ln xy", _log(x*y, E)),
|
||||
(r"\log x", _log(x, E)),
|
||||
(r"\log xy", _log(x*y, E)),
|
||||
(r"\log_{2} x", _log(x, 2)),
|
||||
(r"\log_{a} x", _log(x, a)),
|
||||
(r"\log_{11} x", _log(x, 11)),
|
||||
(r"\log_{a^2} x", _log(x, _Pow(a, 2))),
|
||||
(r"[x]", x),
|
||||
(r"[a + b]", _Add(a, b)),
|
||||
(r"\frac{d}{dx} [ \tan x ]", Derivative(tan(x), x)),
|
||||
(r"\binom{n}{k}", _binomial(n, k)),
|
||||
(r"\tbinom{n}{k}", _binomial(n, k)),
|
||||
(r"\dbinom{n}{k}", _binomial(n, k)),
|
||||
(r"\binom{n}{0}", _binomial(n, 0)),
|
||||
(r"x^\binom{n}{k}", _Pow(x, _binomial(n, k))),
|
||||
(r"a \, b", _Mul(a, b)),
|
||||
(r"a \thinspace b", _Mul(a, b)),
|
||||
(r"a \: b", _Mul(a, b)),
|
||||
(r"a \medspace b", _Mul(a, b)),
|
||||
(r"a \; b", _Mul(a, b)),
|
||||
(r"a \thickspace b", _Mul(a, b)),
|
||||
(r"a \quad b", _Mul(a, b)),
|
||||
(r"a \qquad b", _Mul(a, b)),
|
||||
(r"a \! b", _Mul(a, b)),
|
||||
(r"a \negthinspace b", _Mul(a, b)),
|
||||
(r"a \negmedspace b", _Mul(a, b)),
|
||||
(r"a \negthickspace b", _Mul(a, b)),
|
||||
(r"\int x \, dx", Integral(x, x)),
|
||||
(r"\log_2 x", _log(x, 2)),
|
||||
(r"\log_a x", _log(x, a)),
|
||||
(r"5^0 - 4^0", _Add(_Pow(5, 0), _Mul(-1, _Pow(4, 0)))),
|
||||
(r"3x - 1", _Add(_Mul(3, x), -1))
|
||||
]
|
||||
|
||||
|
||||
def test_parseable():
|
||||
from sympy.parsing.latex import parse_latex
|
||||
for latex_str, sympy_expr in GOOD_PAIRS:
|
||||
assert parse_latex(latex_str) == sympy_expr, latex_str
|
||||
|
||||
# These bad LaTeX strings should raise a LaTeXParsingError when parsed
|
||||
BAD_STRINGS = [
|
||||
r"(",
|
||||
r")",
|
||||
r"\frac{d}{dx}",
|
||||
r"(\frac{d}{dx})",
|
||||
r"\sqrt{}",
|
||||
r"\sqrt",
|
||||
r"\overline{}",
|
||||
r"\overline",
|
||||
r"{",
|
||||
r"}",
|
||||
r"\mathit{x + y}",
|
||||
r"\mathit{21}",
|
||||
r"\frac{2}{}",
|
||||
r"\frac{}{2}",
|
||||
r"\int",
|
||||
r"!",
|
||||
r"!0",
|
||||
r"_",
|
||||
r"^",
|
||||
r"|",
|
||||
r"||x|",
|
||||
r"()",
|
||||
r"((((((((((((((((()))))))))))))))))",
|
||||
r"-",
|
||||
r"\frac{d}{dx} + \frac{d}{dt}",
|
||||
r"f(x,,y)",
|
||||
r"f(x,y,",
|
||||
r"\sin^x",
|
||||
r"\cos^2",
|
||||
r"@",
|
||||
r"#",
|
||||
r"$",
|
||||
r"%",
|
||||
r"&",
|
||||
r"*",
|
||||
r"" "\\",
|
||||
r"~",
|
||||
r"\frac{(2 + x}{1 - x)}",
|
||||
]
|
||||
|
||||
def test_not_parseable():
|
||||
from sympy.parsing.latex import parse_latex, LaTeXParsingError
|
||||
for latex_str in BAD_STRINGS:
|
||||
with raises(LaTeXParsingError):
|
||||
parse_latex(latex_str)
|
||||
|
||||
# At time of migration from latex2sympy, should fail but doesn't
|
||||
FAILING_BAD_STRINGS = [
|
||||
r"\cos 1 \cos",
|
||||
r"f(,",
|
||||
r"f()",
|
||||
r"a \div \div b",
|
||||
r"a \cdot \cdot b",
|
||||
r"a // b",
|
||||
r"a +",
|
||||
r"1.1.1",
|
||||
r"1 +",
|
||||
r"a / b /",
|
||||
]
|
||||
|
||||
@XFAIL
|
||||
def test_failing_not_parseable():
|
||||
from sympy.parsing.latex import parse_latex, LaTeXParsingError
|
||||
for latex_str in FAILING_BAD_STRINGS:
|
||||
with raises(LaTeXParsingError):
|
||||
parse_latex(latex_str)
|
||||
|
||||
# In strict mode, FAILING_BAD_STRINGS would fail
|
||||
def test_strict_mode():
|
||||
from sympy.parsing.latex import parse_latex, LaTeXParsingError
|
||||
for latex_str in FAILING_BAD_STRINGS:
|
||||
with raises(LaTeXParsingError):
|
||||
parse_latex(latex_str, strict=True)
|
||||
@@ -0,0 +1,16 @@
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import ignore_warnings, raises
|
||||
|
||||
antlr4 = import_module("antlr4", warn_not_installed=False)
|
||||
|
||||
# disable tests if antlr4-python3-runtime is not present
|
||||
if antlr4:
|
||||
disabled = True
|
||||
|
||||
|
||||
def test_no_import():
|
||||
from sympy.parsing.latex import parse_latex
|
||||
|
||||
with ignore_warnings(UserWarning):
|
||||
with raises(ImportError):
|
||||
parse_latex('1 + 1')
|
||||
@@ -0,0 +1,872 @@
|
||||
from sympy.testing.pytest import XFAIL
|
||||
from sympy.parsing.latex.lark import parse_latex_lark
|
||||
from sympy.external import import_module
|
||||
|
||||
from sympy.concrete.products import Product
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.function import Derivative, Function
|
||||
from sympy.core.numbers import E, oo, Rational
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.parameters import evaluate
|
||||
from sympy.core.relational import GreaterThan, LessThan, StrictGreaterThan, StrictLessThan, Unequality
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.combinatorial.factorials import binomial, factorial
|
||||
from sympy.functions.elementary.complexes import Abs, conjugate
|
||||
from sympy.functions.elementary.exponential import exp, log
|
||||
from sympy.functions.elementary.integers import ceiling, floor
|
||||
from sympy.functions.elementary.miscellaneous import root, sqrt, Min, Max
|
||||
from sympy.functions.elementary.trigonometric import asin, cos, csc, sec, sin, tan
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.series.limits import Limit
|
||||
from sympy import Matrix, MatAdd, MatMul, Transpose, Trace
|
||||
from sympy import I
|
||||
|
||||
from sympy.core.relational import Eq, Ne, Lt, Le, Gt, Ge
|
||||
from sympy.physics.quantum import Bra, Ket, InnerProduct
|
||||
from sympy.abc import x, y, z, a, b, c, d, t, k, n
|
||||
|
||||
from .test_latex import theta, f, _Add, _Mul, _Pow, _Sqrt, _Conjugate, _Abs, _factorial, _exp, _binomial
|
||||
|
||||
lark = import_module("lark")
|
||||
|
||||
# disable tests if lark is not present
|
||||
disabled = lark is None
|
||||
|
||||
# shorthand definitions that are only needed for the Lark LaTeX parser
|
||||
def _Min(*args):
|
||||
return Min(*args, evaluate=False)
|
||||
|
||||
|
||||
def _Max(*args):
|
||||
return Max(*args, evaluate=False)
|
||||
|
||||
|
||||
def _log(a, b=E):
|
||||
if b == E:
|
||||
return log(a, evaluate=False)
|
||||
else:
|
||||
return log(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _MatAdd(a, b):
|
||||
return MatAdd(a, b, evaluate=False)
|
||||
|
||||
|
||||
def _MatMul(a, b):
|
||||
return MatMul(a, b, evaluate=False)
|
||||
|
||||
|
||||
# These LaTeX strings should parse to the corresponding SymPy expression
|
||||
SYMBOL_EXPRESSION_PAIRS = [
|
||||
(r"x_0", Symbol('x_{0}')),
|
||||
(r"x_{1}", Symbol('x_{1}')),
|
||||
(r"x_a", Symbol('x_{a}')),
|
||||
(r"x_{b}", Symbol('x_{b}')),
|
||||
(r"h_\theta", Symbol('h_{theta}')),
|
||||
(r"h_{\theta}", Symbol('h_{theta}')),
|
||||
(r"y''_1", Symbol("y''_{1}")),
|
||||
(r"y_1''", Symbol("y_{1}''")),
|
||||
(r"\mathit{x}", Symbol('x')),
|
||||
(r"\mathit{test}", Symbol('test')),
|
||||
(r"\mathit{TEST}", Symbol('TEST')),
|
||||
(r"\mathit{HELLO world}", Symbol('HELLO world')),
|
||||
(r"a'", Symbol("a'")),
|
||||
(r"a''", Symbol("a''")),
|
||||
(r"\alpha'", Symbol("alpha'")),
|
||||
(r"\alpha''", Symbol("alpha''")),
|
||||
(r"a_b", Symbol("a_{b}")),
|
||||
(r"a_b'", Symbol("a_{b}'")),
|
||||
(r"a'_b", Symbol("a'_{b}")),
|
||||
(r"a'_b'", Symbol("a'_{b}'")),
|
||||
(r"a_{b'}", Symbol("a_{b'}")),
|
||||
(r"a_{b'}'", Symbol("a_{b'}'")),
|
||||
(r"a'_{b'}", Symbol("a'_{b'}")),
|
||||
(r"a'_{b'}'", Symbol("a'_{b'}'")),
|
||||
(r"\mathit{foo}'", Symbol("foo'")),
|
||||
(r"\mathit{foo'}", Symbol("foo'")),
|
||||
(r"\mathit{foo'}'", Symbol("foo''")),
|
||||
(r"a_b''", Symbol("a_{b}''")),
|
||||
(r"a''_b", Symbol("a''_{b}")),
|
||||
(r"a''_b'''", Symbol("a''_{b}'''")),
|
||||
(r"a_{b''}", Symbol("a_{b''}")),
|
||||
(r"a_{b''}''", Symbol("a_{b''}''")),
|
||||
(r"a''_{b''}", Symbol("a''_{b''}")),
|
||||
(r"a''_{b''}'''", Symbol("a''_{b''}'''")),
|
||||
(r"\mathit{foo}''", Symbol("foo''")),
|
||||
(r"\mathit{foo''}", Symbol("foo''")),
|
||||
(r"\mathit{foo''}'''", Symbol("foo'''''")),
|
||||
(r"a_\alpha", Symbol("a_{alpha}")),
|
||||
(r"a_\alpha'", Symbol("a_{alpha}'")),
|
||||
(r"a'_\alpha", Symbol("a'_{alpha}")),
|
||||
(r"a'_\alpha'", Symbol("a'_{alpha}'")),
|
||||
(r"a_{\alpha'}", Symbol("a_{alpha'}")),
|
||||
(r"a_{\alpha'}'", Symbol("a_{alpha'}'")),
|
||||
(r"a'_{\alpha'}", Symbol("a'_{alpha'}")),
|
||||
(r"a'_{\alpha'}'", Symbol("a'_{alpha'}'")),
|
||||
(r"a_\alpha''", Symbol("a_{alpha}''")),
|
||||
(r"a''_\alpha", Symbol("a''_{alpha}")),
|
||||
(r"a''_\alpha'''", Symbol("a''_{alpha}'''")),
|
||||
(r"a_{\alpha''}", Symbol("a_{alpha''}")),
|
||||
(r"a_{\alpha''}''", Symbol("a_{alpha''}''")),
|
||||
(r"a''_{\alpha''}", Symbol("a''_{alpha''}")),
|
||||
(r"a''_{\alpha''}'''", Symbol("a''_{alpha''}'''")),
|
||||
(r"\alpha_b", Symbol("alpha_{b}")),
|
||||
(r"\alpha_b'", Symbol("alpha_{b}'")),
|
||||
(r"\alpha'_b", Symbol("alpha'_{b}")),
|
||||
(r"\alpha'_b'", Symbol("alpha'_{b}'")),
|
||||
(r"\alpha_{b'}", Symbol("alpha_{b'}")),
|
||||
(r"\alpha_{b'}'", Symbol("alpha_{b'}'")),
|
||||
(r"\alpha'_{b'}", Symbol("alpha'_{b'}")),
|
||||
(r"\alpha'_{b'}'", Symbol("alpha'_{b'}'")),
|
||||
(r"\alpha_b''", Symbol("alpha_{b}''")),
|
||||
(r"\alpha''_b", Symbol("alpha''_{b}")),
|
||||
(r"\alpha''_b'''", Symbol("alpha''_{b}'''")),
|
||||
(r"\alpha_{b''}", Symbol("alpha_{b''}")),
|
||||
(r"\alpha_{b''}''", Symbol("alpha_{b''}''")),
|
||||
(r"\alpha''_{b''}", Symbol("alpha''_{b''}")),
|
||||
(r"\alpha''_{b''}'''", Symbol("alpha''_{b''}'''")),
|
||||
(r"\alpha_\beta", Symbol("alpha_{beta}")),
|
||||
(r"\alpha_{\beta}", Symbol("alpha_{beta}")),
|
||||
(r"\alpha_{\beta'}", Symbol("alpha_{beta'}")),
|
||||
(r"\alpha_{\beta''}", Symbol("alpha_{beta''}")),
|
||||
(r"\alpha'_\beta", Symbol("alpha'_{beta}")),
|
||||
(r"\alpha'_{\beta}", Symbol("alpha'_{beta}")),
|
||||
(r"\alpha'_{\beta'}", Symbol("alpha'_{beta'}")),
|
||||
(r"\alpha'_{\beta''}", Symbol("alpha'_{beta''}")),
|
||||
(r"\alpha''_\beta", Symbol("alpha''_{beta}")),
|
||||
(r"\alpha''_{\beta}", Symbol("alpha''_{beta}")),
|
||||
(r"\alpha''_{\beta'}", Symbol("alpha''_{beta'}")),
|
||||
(r"\alpha''_{\beta''}", Symbol("alpha''_{beta''}")),
|
||||
(r"\alpha_\beta'", Symbol("alpha_{beta}'")),
|
||||
(r"\alpha_{\beta}'", Symbol("alpha_{beta}'")),
|
||||
(r"\alpha_{\beta'}'", Symbol("alpha_{beta'}'")),
|
||||
(r"\alpha_{\beta''}'", Symbol("alpha_{beta''}'")),
|
||||
(r"\alpha'_\beta'", Symbol("alpha'_{beta}'")),
|
||||
(r"\alpha'_{\beta}'", Symbol("alpha'_{beta}'")),
|
||||
(r"\alpha'_{\beta'}'", Symbol("alpha'_{beta'}'")),
|
||||
(r"\alpha'_{\beta''}'", Symbol("alpha'_{beta''}'")),
|
||||
(r"\alpha''_\beta'", Symbol("alpha''_{beta}'")),
|
||||
(r"\alpha''_{\beta}'", Symbol("alpha''_{beta}'")),
|
||||
(r"\alpha''_{\beta'}'", Symbol("alpha''_{beta'}'")),
|
||||
(r"\alpha''_{\beta''}'", Symbol("alpha''_{beta''}'")),
|
||||
(r"\alpha_\beta''", Symbol("alpha_{beta}''")),
|
||||
(r"\alpha_{\beta}''", Symbol("alpha_{beta}''")),
|
||||
(r"\alpha_{\beta'}''", Symbol("alpha_{beta'}''")),
|
||||
(r"\alpha_{\beta''}''", Symbol("alpha_{beta''}''")),
|
||||
(r"\alpha'_\beta''", Symbol("alpha'_{beta}''")),
|
||||
(r"\alpha'_{\beta}''", Symbol("alpha'_{beta}''")),
|
||||
(r"\alpha'_{\beta'}''", Symbol("alpha'_{beta'}''")),
|
||||
(r"\alpha'_{\beta''}''", Symbol("alpha'_{beta''}''")),
|
||||
(r"\alpha''_\beta''", Symbol("alpha''_{beta}''")),
|
||||
(r"\alpha''_{\beta}''", Symbol("alpha''_{beta}''")),
|
||||
(r"\alpha''_{\beta'}''", Symbol("alpha''_{beta'}''")),
|
||||
(r"\alpha''_{\beta''}''", Symbol("alpha''_{beta''}''"))
|
||||
|
||||
]
|
||||
|
||||
UNEVALUATED_SIMPLE_EXPRESSION_PAIRS = [
|
||||
(r"0", 0),
|
||||
(r"1", 1),
|
||||
(r"-3.14", -3.14),
|
||||
(r"(-7.13)(1.5)", _Mul(-7.13, 1.5)),
|
||||
(r"1+1", _Add(1, 1)),
|
||||
(r"0+1", _Add(0, 1)),
|
||||
(r"1*2", _Mul(1, 2)),
|
||||
(r"0*1", _Mul(0, 1)),
|
||||
(r"x", x),
|
||||
(r"2x", 2 * x),
|
||||
(r"3x - 1", _Add(_Mul(3, x), -1)),
|
||||
(r"-c", -c),
|
||||
(r"\infty", oo),
|
||||
(r"a \cdot b", a * b),
|
||||
(r"1 \times 2 ", _Mul(1, 2)),
|
||||
(r"a / b", a / b),
|
||||
(r"a \div b", a / b),
|
||||
(r"a + b", a + b),
|
||||
(r"a + b - a", _Add(a + b, -a)),
|
||||
(r"(x + y) z", _Mul(_Add(x, y), z)),
|
||||
(r"a'b+ab'", _Add(_Mul(Symbol("a'"), b), _Mul(a, Symbol("b'"))))
|
||||
]
|
||||
|
||||
EVALUATED_SIMPLE_EXPRESSION_PAIRS = [
|
||||
(r"(-7.13)(1.5)", -10.695),
|
||||
(r"1+1", 2),
|
||||
(r"0+1", 1),
|
||||
(r"1*2", 2),
|
||||
(r"0*1", 0),
|
||||
(r"2x", 2 * x),
|
||||
(r"3x - 1", 3 * x - 1),
|
||||
(r"-c", -c),
|
||||
(r"a \cdot b", a * b),
|
||||
(r"1 \times 2 ", 2),
|
||||
(r"a / b", a / b),
|
||||
(r"a \div b", a / b),
|
||||
(r"a + b", a + b),
|
||||
(r"a + b - a", b),
|
||||
(r"(x + y) z", (x + y) * z),
|
||||
]
|
||||
|
||||
UNEVALUATED_FRACTION_EXPRESSION_PAIRS = [
|
||||
(r"\frac{a}{b}", a / b),
|
||||
(r"\dfrac{a}{b}", a / b),
|
||||
(r"\tfrac{a}{b}", a / b),
|
||||
(r"\frac12", _Mul(1, _Pow(2, -1))),
|
||||
(r"\frac12y", _Mul(_Mul(1, _Pow(2, -1)), y)),
|
||||
(r"\frac1234", _Mul(_Mul(1, _Pow(2, -1)), 34)),
|
||||
(r"\frac2{3}", _Mul(2, _Pow(3, -1))),
|
||||
(r"\frac{a + b}{c}", _Mul(a + b, _Pow(c, -1))),
|
||||
(r"\frac{7}{3}", _Mul(7, _Pow(3, -1)))
|
||||
]
|
||||
|
||||
EVALUATED_FRACTION_EXPRESSION_PAIRS = [
|
||||
(r"\frac{a}{b}", a / b),
|
||||
(r"\dfrac{a}{b}", a / b),
|
||||
(r"\tfrac{a}{b}", a / b),
|
||||
(r"\frac12", Rational(1, 2)),
|
||||
(r"\frac12y", y / 2),
|
||||
(r"\frac1234", 17),
|
||||
(r"\frac2{3}", Rational(2, 3)),
|
||||
(r"\frac{a + b}{c}", (a + b) / c),
|
||||
(r"\frac{7}{3}", Rational(7, 3))
|
||||
]
|
||||
|
||||
RELATION_EXPRESSION_PAIRS = [
|
||||
(r"x = y", Eq(x, y)),
|
||||
(r"x \neq y", Ne(x, y)),
|
||||
(r"x < y", Lt(x, y)),
|
||||
(r"x > y", Gt(x, y)),
|
||||
(r"x \leq y", Le(x, y)),
|
||||
(r"x \geq y", Ge(x, y)),
|
||||
(r"x \le y", Le(x, y)),
|
||||
(r"x \ge y", Ge(x, y)),
|
||||
(r"x < y", StrictLessThan(x, y)),
|
||||
(r"x \leq y", LessThan(x, y)),
|
||||
(r"x > y", StrictGreaterThan(x, y)),
|
||||
(r"x \geq y", GreaterThan(x, y)),
|
||||
(r"x \neq y", Unequality(x, y)), # same as 2nd one in the list
|
||||
(r"a^2 + b^2 = c^2", Eq(a**2 + b**2, c**2))
|
||||
]
|
||||
|
||||
UNEVALUATED_POWER_EXPRESSION_PAIRS = [
|
||||
(r"x^2", x ** 2),
|
||||
(r"x^\frac{1}{2}", _Pow(x, _Mul(1, _Pow(2, -1)))),
|
||||
(r"x^{3 + 1}", x ** _Add(3, 1)),
|
||||
(r"\pi^{|xy|}", Symbol('pi') ** _Abs(x * y)),
|
||||
(r"5^0 - 4^0", _Add(_Pow(5, 0), _Mul(-1, _Pow(4, 0))))
|
||||
]
|
||||
|
||||
EVALUATED_POWER_EXPRESSION_PAIRS = [
|
||||
(r"x^2", x ** 2),
|
||||
(r"x^\frac{1}{2}", sqrt(x)),
|
||||
(r"x^{3 + 1}", x ** 4),
|
||||
(r"\pi^{|xy|}", Symbol('pi') ** _Abs(x * y)),
|
||||
(r"5^0 - 4^0", 0)
|
||||
]
|
||||
|
||||
UNEVALUATED_INTEGRAL_EXPRESSION_PAIRS = [
|
||||
(r"\int x dx", Integral(_Mul(1, x), x)),
|
||||
(r"\int x \, dx", Integral(_Mul(1, x), x)),
|
||||
(r"\int x d\theta", Integral(_Mul(1, x), theta)),
|
||||
(r"\int (x^2 - y)dx", Integral(_Mul(1, x ** 2 - y), x)),
|
||||
(r"\int x + a dx", Integral(_Mul(1, _Add(x, a)), x)),
|
||||
(r"\int da", Integral(_Mul(1, 1), a)),
|
||||
(r"\int_0^7 dx", Integral(_Mul(1, 1), (x, 0, 7))),
|
||||
(r"\int\limits_{0}^{1} x dx", Integral(_Mul(1, x), (x, 0, 1))),
|
||||
(r"\int_a^b x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int^b_a x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int_{a}^b x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int^{b}_a x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int_{a}^{b} x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int^{b}_{a} x dx", Integral(_Mul(1, x), (x, a, b))),
|
||||
(r"\int_{f(a)}^{f(b)} f(z) dz", Integral(f(z), (z, f(a), f(b)))),
|
||||
(r"\int a + b + c dx", Integral(_Mul(1, _Add(_Add(a, b), c)), x)),
|
||||
(r"\int \frac{dz}{z}", Integral(_Mul(1, _Mul(1, Pow(z, -1))), z)),
|
||||
(r"\int \frac{3 dz}{z}", Integral(_Mul(1, _Mul(3, _Pow(z, -1))), z)),
|
||||
(r"\int \frac{1}{x} dx", Integral(_Mul(1, _Mul(1, Pow(x, -1))), x)),
|
||||
(r"\int \frac{1}{a} + \frac{1}{b} dx",
|
||||
Integral(_Mul(1, _Add(_Mul(1, _Pow(a, -1)), _Mul(1, Pow(b, -1)))), x)),
|
||||
(r"\int \frac{1}{x} + 1 dx", Integral(_Mul(1, _Add(_Mul(1, _Pow(x, -1)), 1)), x))
|
||||
]
|
||||
|
||||
EVALUATED_INTEGRAL_EXPRESSION_PAIRS = [
|
||||
(r"\int x dx", Integral(x, x)),
|
||||
(r"\int x \, dx", Integral(x, x)),
|
||||
(r"\int x d\theta", Integral(x, theta)),
|
||||
(r"\int (x^2 - y)dx", Integral(x ** 2 - y, x)),
|
||||
(r"\int x + a dx", Integral(x + a, x)),
|
||||
(r"\int da", Integral(1, a)),
|
||||
(r"\int_0^7 dx", Integral(1, (x, 0, 7))),
|
||||
(r"\int\limits_{0}^{1} x dx", Integral(x, (x, 0, 1))),
|
||||
(r"\int_a^b x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^b_a x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{a}^b x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^{b}_a x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{a}^{b} x dx", Integral(x, (x, a, b))),
|
||||
(r"\int^{b}_{a} x dx", Integral(x, (x, a, b))),
|
||||
(r"\int_{f(a)}^{f(b)} f(z) dz", Integral(f(z), (z, f(a), f(b)))),
|
||||
(r"\int a + b + c dx", Integral(a + b + c, x)),
|
||||
(r"\int \frac{dz}{z}", Integral(Pow(z, -1), z)),
|
||||
(r"\int \frac{3 dz}{z}", Integral(3 * Pow(z, -1), z)),
|
||||
(r"\int \frac{1}{x} dx", Integral(1 / x, x)),
|
||||
(r"\int \frac{1}{a} + \frac{1}{b} dx", Integral(1 / a + 1 / b, x)),
|
||||
(r"\int \frac{1}{a} - \frac{1}{b} dx", Integral(1 / a - 1 / b, x)),
|
||||
(r"\int \frac{1}{x} + 1 dx", Integral(1 / x + 1, x))
|
||||
]
|
||||
|
||||
DERIVATIVE_EXPRESSION_PAIRS = [
|
||||
(r"\frac{d}{dx} x", Derivative(x, x)),
|
||||
(r"\frac{d}{dt} x", Derivative(x, t)),
|
||||
(r"\frac{d}{dx} ( \tan x )", Derivative(tan(x), x)),
|
||||
(r"\frac{d f(x)}{dx}", Derivative(f(x), x)),
|
||||
(r"\frac{d\theta(x)}{dx}", Derivative(Function('theta')(x), x))
|
||||
]
|
||||
|
||||
TRIGONOMETRIC_EXPRESSION_PAIRS = [
|
||||
(r"\sin \theta", sin(theta)),
|
||||
(r"\sin(\theta)", sin(theta)),
|
||||
(r"\sin^{-1} a", asin(a)),
|
||||
(r"\sin a \cos b", _Mul(sin(a), cos(b))),
|
||||
(r"\sin \cos \theta", sin(cos(theta))),
|
||||
(r"\sin(\cos \theta)", sin(cos(theta))),
|
||||
(r"(\csc x)(\sec y)", csc(x) * sec(y)),
|
||||
(r"\frac{\sin{x}}2", _Mul(sin(x), _Pow(2, -1)))
|
||||
]
|
||||
|
||||
UNEVALUATED_LIMIT_EXPRESSION_PAIRS = [
|
||||
(r"\lim_{x \to 3} a", Limit(a, x, 3, dir="+-")),
|
||||
(r"\lim_{x \rightarrow 3} a", Limit(a, x, 3, dir="+-")),
|
||||
(r"\lim_{x \Rightarrow 3} a", Limit(a, x, 3, dir="+-")),
|
||||
(r"\lim_{x \longrightarrow 3} a", Limit(a, x, 3, dir="+-")),
|
||||
(r"\lim_{x \Longrightarrow 3} a", Limit(a, x, 3, dir="+-")),
|
||||
(r"\lim_{x \to 3^{+}} a", Limit(a, x, 3, dir="+")),
|
||||
(r"\lim_{x \to 3^{-}} a", Limit(a, x, 3, dir="-")),
|
||||
(r"\lim_{x \to 3^+} a", Limit(a, x, 3, dir="+")),
|
||||
(r"\lim_{x \to 3^-} a", Limit(a, x, 3, dir="-")),
|
||||
(r"\lim_{x \to \infty} \frac{1}{x}", Limit(_Mul(1, _Pow(x, -1)), x, oo))
|
||||
]
|
||||
|
||||
EVALUATED_LIMIT_EXPRESSION_PAIRS = [
|
||||
(r"\lim_{x \to \infty} \frac{1}{x}", Limit(1 / x, x, oo))
|
||||
]
|
||||
|
||||
UNEVALUATED_SQRT_EXPRESSION_PAIRS = [
|
||||
(r"\sqrt{x}", sqrt(x)),
|
||||
(r"\sqrt{x + b}", sqrt(_Add(x, b))),
|
||||
(r"\sqrt[3]{\sin x}", _Pow(sin(x), _Pow(3, -1))),
|
||||
# the above test needed to be handled differently than the ones below because root
|
||||
# acts differently if its second argument is a number
|
||||
(r"\sqrt[y]{\sin x}", root(sin(x), y)),
|
||||
(r"\sqrt[\theta]{\sin x}", root(sin(x), theta)),
|
||||
(r"\sqrt{\frac{12}{6}}", _Sqrt(_Mul(12, _Pow(6, -1))))
|
||||
]
|
||||
|
||||
EVALUATED_SQRT_EXPRESSION_PAIRS = [
|
||||
(r"\sqrt{x}", sqrt(x)),
|
||||
(r"\sqrt{x + b}", sqrt(x + b)),
|
||||
(r"\sqrt[3]{\sin x}", root(sin(x), 3)),
|
||||
(r"\sqrt[y]{\sin x}", root(sin(x), y)),
|
||||
(r"\sqrt[\theta]{\sin x}", root(sin(x), theta)),
|
||||
(r"\sqrt{\frac{12}{6}}", sqrt(2))
|
||||
]
|
||||
|
||||
UNEVALUATED_FACTORIAL_EXPRESSION_PAIRS = [
|
||||
(r"x!", _factorial(x)),
|
||||
(r"100!", _factorial(100)),
|
||||
(r"\theta!", _factorial(theta)),
|
||||
(r"(x + 1)!", _factorial(_Add(x, 1))),
|
||||
(r"(x!)!", _factorial(_factorial(x))),
|
||||
(r"x!!!", _factorial(_factorial(_factorial(x)))),
|
||||
(r"5!7!", _Mul(_factorial(5), _factorial(7)))
|
||||
]
|
||||
|
||||
EVALUATED_FACTORIAL_EXPRESSION_PAIRS = [
|
||||
(r"x!", factorial(x)),
|
||||
(r"100!", factorial(100)),
|
||||
(r"\theta!", factorial(theta)),
|
||||
(r"(x + 1)!", factorial(x + 1)),
|
||||
(r"(x!)!", factorial(factorial(x))),
|
||||
(r"x!!!", factorial(factorial(factorial(x)))),
|
||||
(r"5!7!", factorial(5) * factorial(7)),
|
||||
(r"24! \times 24!", factorial(24) * factorial(24))
|
||||
]
|
||||
|
||||
UNEVALUATED_SUM_EXPRESSION_PAIRS = [
|
||||
(r"\sum_{k = 1}^{3} c", Sum(_Mul(1, c), (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^3 c", Sum(_Mul(1, c), (k, 1, 3))),
|
||||
(r"\sum^{3}_{k = 1} c", Sum(_Mul(1, c), (k, 1, 3))),
|
||||
(r"\sum^3_{k = 1} c", Sum(_Mul(1, c), (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^{10} k^2", Sum(_Mul(1, k ** 2), (k, 1, 10))),
|
||||
(r"\sum_{n = 0}^{\infty} \frac{1}{n!}",
|
||||
Sum(_Mul(1, _Mul(1, _Pow(_factorial(n), -1))), (n, 0, oo)))
|
||||
]
|
||||
|
||||
EVALUATED_SUM_EXPRESSION_PAIRS = [
|
||||
(r"\sum_{k = 1}^{3} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^3 c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum^{3}_{k = 1} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum^3_{k = 1} c", Sum(c, (k, 1, 3))),
|
||||
(r"\sum_{k = 1}^{10} k^2", Sum(k ** 2, (k, 1, 10))),
|
||||
(r"\sum_{n = 0}^{\infty} \frac{1}{n!}", Sum(1 / factorial(n), (n, 0, oo)))
|
||||
]
|
||||
|
||||
UNEVALUATED_PRODUCT_EXPRESSION_PAIRS = [
|
||||
(r"\prod_{a = b}^{c} x", Product(x, (a, b, c))),
|
||||
(r"\prod_{a = b}^c x", Product(x, (a, b, c))),
|
||||
(r"\prod^{c}_{a = b} x", Product(x, (a, b, c))),
|
||||
(r"\prod^c_{a = b} x", Product(x, (a, b, c)))
|
||||
]
|
||||
|
||||
APPLIED_FUNCTION_EXPRESSION_PAIRS = [
|
||||
(r"f(x)", f(x)),
|
||||
(r"f(x, y)", f(x, y)),
|
||||
(r"f(x, y, z)", f(x, y, z)),
|
||||
(r"f'_1(x)", Function("f_{1}'")(x)),
|
||||
(r"f_{1}''(x+y)", Function("f_{1}''")(x + y)),
|
||||
(r"h_{\theta}(x_0, x_1)",
|
||||
Function('h_{theta}')(Symbol('x_{0}'), Symbol('x_{1}')))
|
||||
]
|
||||
|
||||
UNEVALUATED_COMMON_FUNCTION_EXPRESSION_PAIRS = [
|
||||
(r"|x|", _Abs(x)),
|
||||
(r"||x||", _Abs(Abs(x))),
|
||||
(r"|x||y|", _Abs(x) * _Abs(y)),
|
||||
(r"||x||y||", _Abs(_Abs(x) * _Abs(y))),
|
||||
(r"\lfloor x \rfloor", floor(x)),
|
||||
(r"\lceil x \rceil", ceiling(x)),
|
||||
(r"\exp x", _exp(x)),
|
||||
(r"\exp(x)", _exp(x)),
|
||||
(r"\lg x", _log(x, 10)),
|
||||
(r"\ln x", _log(x)),
|
||||
(r"\ln xy", _log(x * y)),
|
||||
(r"\log x", _log(x)),
|
||||
(r"\log xy", _log(x * y)),
|
||||
(r"\log_{2} x", _log(x, 2)),
|
||||
(r"\log_{a} x", _log(x, a)),
|
||||
(r"\log_{11} x", _log(x, 11)),
|
||||
(r"\log_{a^2} x", _log(x, _Pow(a, 2))),
|
||||
(r"\log_2 x", _log(x, 2)),
|
||||
(r"\log_a x", _log(x, a)),
|
||||
(r"\overline{z}", _Conjugate(z)),
|
||||
(r"\overline{\overline{z}}", _Conjugate(_Conjugate(z))),
|
||||
(r"\overline{x + y}", _Conjugate(_Add(x, y))),
|
||||
(r"\overline{x} + \overline{y}", _Conjugate(x) + _Conjugate(y)),
|
||||
(r"\min(a, b)", _Min(a, b)),
|
||||
(r"\min(a, b, c - d, xy)", _Min(a, b, c - d, x * y)),
|
||||
(r"\max(a, b)", _Max(a, b)),
|
||||
(r"\max(a, b, c - d, xy)", _Max(a, b, c - d, x * y)),
|
||||
# physics things don't have an `evaluate=False` variant
|
||||
(r"\langle x |", Bra('x')),
|
||||
(r"| x \rangle", Ket('x')),
|
||||
(r"\langle x | y \rangle", InnerProduct(Bra('x'), Ket('y'))),
|
||||
]
|
||||
|
||||
EVALUATED_COMMON_FUNCTION_EXPRESSION_PAIRS = [
|
||||
(r"|x|", Abs(x)),
|
||||
(r"||x||", Abs(Abs(x))),
|
||||
(r"|x||y|", Abs(x) * Abs(y)),
|
||||
(r"||x||y||", Abs(Abs(x) * Abs(y))),
|
||||
(r"\lfloor x \rfloor", floor(x)),
|
||||
(r"\lceil x \rceil", ceiling(x)),
|
||||
(r"\exp x", exp(x)),
|
||||
(r"\exp(x)", exp(x)),
|
||||
(r"\lg x", log(x, 10)),
|
||||
(r"\ln x", log(x)),
|
||||
(r"\ln xy", log(x * y)),
|
||||
(r"\log x", log(x)),
|
||||
(r"\log xy", log(x * y)),
|
||||
(r"\log_{2} x", log(x, 2)),
|
||||
(r"\log_{a} x", log(x, a)),
|
||||
(r"\log_{11} x", log(x, 11)),
|
||||
(r"\log_{a^2} x", log(x, _Pow(a, 2))),
|
||||
(r"\log_2 x", log(x, 2)),
|
||||
(r"\log_a x", log(x, a)),
|
||||
(r"\overline{z}", conjugate(z)),
|
||||
(r"\overline{\overline{z}}", conjugate(conjugate(z))),
|
||||
(r"\overline{x + y}", conjugate(x + y)),
|
||||
(r"\overline{x} + \overline{y}", conjugate(x) + conjugate(y)),
|
||||
(r"\min(a, b)", Min(a, b)),
|
||||
(r"\min(a, b, c - d, xy)", Min(a, b, c - d, x * y)),
|
||||
(r"\max(a, b)", Max(a, b)),
|
||||
(r"\max(a, b, c - d, xy)", Max(a, b, c - d, x * y)),
|
||||
(r"\langle x |", Bra('x')),
|
||||
(r"| x \rangle", Ket('x')),
|
||||
(r"\langle x | y \rangle", InnerProduct(Bra('x'), Ket('y'))),
|
||||
]
|
||||
|
||||
SPACING_RELATED_EXPRESSION_PAIRS = [
|
||||
(r"a \, b", _Mul(a, b)),
|
||||
(r"a \thinspace b", _Mul(a, b)),
|
||||
(r"a \: b", _Mul(a, b)),
|
||||
(r"a \medspace b", _Mul(a, b)),
|
||||
(r"a \; b", _Mul(a, b)),
|
||||
(r"a \thickspace b", _Mul(a, b)),
|
||||
(r"a \quad b", _Mul(a, b)),
|
||||
(r"a \qquad b", _Mul(a, b)),
|
||||
(r"a \! b", _Mul(a, b)),
|
||||
(r"a \negthinspace b", _Mul(a, b)),
|
||||
(r"a \negmedspace b", _Mul(a, b)),
|
||||
(r"a \negthickspace b", _Mul(a, b))
|
||||
]
|
||||
|
||||
UNEVALUATED_BINOMIAL_EXPRESSION_PAIRS = [
|
||||
(r"\binom{n}{k}", _binomial(n, k)),
|
||||
(r"\tbinom{n}{k}", _binomial(n, k)),
|
||||
(r"\dbinom{n}{k}", _binomial(n, k)),
|
||||
(r"\binom{n}{0}", _binomial(n, 0)),
|
||||
(r"x^\binom{n}{k}", _Pow(x, _binomial(n, k)))
|
||||
]
|
||||
|
||||
EVALUATED_BINOMIAL_EXPRESSION_PAIRS = [
|
||||
(r"\binom{n}{k}", binomial(n, k)),
|
||||
(r"\tbinom{n}{k}", binomial(n, k)),
|
||||
(r"\dbinom{n}{k}", binomial(n, k)),
|
||||
(r"\binom{n}{0}", binomial(n, 0)),
|
||||
(r"x^\binom{n}{k}", x ** binomial(n, k))
|
||||
]
|
||||
|
||||
MISCELLANEOUS_EXPRESSION_PAIRS = [
|
||||
(r"\left(x + y\right) z", _Mul(_Add(x, y), z)),
|
||||
(r"\left( x + y\right ) z", _Mul(_Add(x, y), z)),
|
||||
(r"\left( x + y\right ) z", _Mul(_Add(x, y), z)),
|
||||
]
|
||||
|
||||
UNEVALUATED_LITERAL_COMPLEX_NUMBER_EXPRESSION_PAIRS = [
|
||||
(r"\imaginaryunit^2", _Pow(I, 2)),
|
||||
(r"|\imaginaryunit|", _Abs(I)),
|
||||
(r"\overline{\imaginaryunit}", _Conjugate(I)),
|
||||
(r"\imaginaryunit+\imaginaryunit", _Add(I, I)),
|
||||
(r"\imaginaryunit-\imaginaryunit", _Add(I, -I)),
|
||||
(r"\imaginaryunit*\imaginaryunit", _Mul(I, I)),
|
||||
(r"\imaginaryunit/\imaginaryunit", _Mul(I, _Pow(I, -1))),
|
||||
(r"(1+\imaginaryunit)/|1+\imaginaryunit|", _Mul(_Add(1, I), _Pow(_Abs(_Add(1, I)), -1)))
|
||||
]
|
||||
|
||||
UNEVALUATED_MATRIX_EXPRESSION_PAIRS = [
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\begin{pmatrix}a & b \\x & y\\\end{pmatrix}",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\begin{bmatrix}a & b \\x & y\end{bmatrix}",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\left(\begin{matrix}a & b \\x & y\end{matrix}\right)",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\left[\begin{matrix}a & b \\x & y\end{matrix}\right]",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\left[\begin{array}{cc}a & b \\x & y\end{array}\right]",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\left(\begin{array}{cc}a & b \\x & y\end{array}\right)",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"\left( { \begin{array}{cc}a & b \\x & y\end{array} } \right)",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
(r"+\begin{pmatrix}a & b \\x & y\end{pmatrix}",
|
||||
Matrix([[a, b], [x, y]])),
|
||||
((r"\begin{pmatrix}x & y \\a & b\end{pmatrix}+"
|
||||
r"\begin{pmatrix}a & b \\x & y\end{pmatrix}"),
|
||||
_MatAdd(Matrix([[x, y], [a, b]]), Matrix([[a, b], [x, y]]))),
|
||||
(r"-\begin{pmatrix}a & b \\x & y\end{pmatrix}",
|
||||
_MatMul(-1, Matrix([[a, b], [x, y]]))),
|
||||
((r"\begin{pmatrix}x & y \\a & b\end{pmatrix}-"
|
||||
r"\begin{pmatrix}a & b \\x & y\end{pmatrix}"),
|
||||
_MatAdd(Matrix([[x, y], [a, b]]), _MatMul(-1, Matrix([[a, b], [x, y]])))),
|
||||
((r"\begin{pmatrix}a & b & c \\x & y & z \\a & b & c \end{pmatrix}*"
|
||||
r"\begin{pmatrix}x & y & z \\a & b & c \\a & b & c \end{pmatrix}*"
|
||||
r"\begin{pmatrix}a & b & c \\x & y & z \\x & y & z \end{pmatrix}"),
|
||||
_MatMul(_MatMul(Matrix([[a, b, c], [x, y, z], [a, b, c]]),
|
||||
Matrix([[x, y, z], [a, b, c], [a, b, c]])),
|
||||
Matrix([[a, b, c], [x, y, z], [x, y, z]]))),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}/2",
|
||||
_MatMul(Matrix([[a, b], [x, y]]), _Pow(2, -1))),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}^2",
|
||||
_Pow(Matrix([[a, b], [x, y]]), 2)),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}^{-1}",
|
||||
_Pow(Matrix([[a, b], [x, y]]), -1)),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}^T",
|
||||
Transpose(Matrix([[a, b], [x, y]]))),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}^{T}",
|
||||
Transpose(Matrix([[a, b], [x, y]]))),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}^\mathit{T}",
|
||||
Transpose(Matrix([[a, b], [x, y]]))),
|
||||
(r"\begin{pmatrix}1 & 2 \\3 & 4\end{pmatrix}^T",
|
||||
Transpose(Matrix([[1, 2], [3, 4]]))),
|
||||
((r"(\begin{pmatrix}1 & 2 \\3 & 4\end{pmatrix}+"
|
||||
r"\begin{pmatrix}1 & 2 \\3 & 4\end{pmatrix}^T)*"
|
||||
r"\begin{bmatrix}1\\0\end{bmatrix}"),
|
||||
_MatMul(_MatAdd(Matrix([[1, 2], [3, 4]]),
|
||||
Transpose(Matrix([[1, 2], [3, 4]]))),
|
||||
Matrix([[1], [0]]))),
|
||||
((r"(\begin{pmatrix}a & b \\x & y\end{pmatrix}+"
|
||||
r"\begin{pmatrix}x & y \\a & b\end{pmatrix})^2"),
|
||||
_Pow(_MatAdd(Matrix([[a, b], [x, y]]),
|
||||
Matrix([[x, y], [a, b]])), 2)),
|
||||
((r"(\begin{pmatrix}a & b \\x & y\end{pmatrix}+"
|
||||
r"\begin{pmatrix}x & y \\a & b\end{pmatrix})^T"),
|
||||
Transpose(_MatAdd(Matrix([[a, b], [x, y]]),
|
||||
Matrix([[x, y], [a, b]])))),
|
||||
(r"\overline{\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}}",
|
||||
_Conjugate(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]]))))
|
||||
]
|
||||
|
||||
EVALUATED_MATRIX_EXPRESSION_PAIRS = [
|
||||
(r"\det\left(\left[ { \begin{array}{cc}a&b\\x&y\end{array} } \right]\right)",
|
||||
Matrix([[a, b], [x, y]]).det()),
|
||||
(r"\det \begin{pmatrix}1&2\\3&4\end{pmatrix}", -2),
|
||||
(r"\det{\begin{pmatrix}1&2\\3&4\end{pmatrix}}", -2),
|
||||
(r"\det(\begin{pmatrix}1&2\\3&4\end{pmatrix})", -2),
|
||||
(r"\det\left(\begin{pmatrix}1&2\\3&4\end{pmatrix}\right)", -2),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}/\begin{vmatrix}a & b \\x & y\end{vmatrix}",
|
||||
_MatMul(Matrix([[a, b], [x, y]]), _Pow(Matrix([[a, b], [x, y]]).det(), -1))),
|
||||
(r"\begin{pmatrix}a & b \\x & y\end{pmatrix}/|\begin{matrix}a & b \\x & y\end{matrix}|",
|
||||
_MatMul(Matrix([[a, b], [x, y]]), _Pow(Matrix([[a, b], [x, y]]).det(), -1))),
|
||||
(r"\frac{\begin{pmatrix}a & b \\x & y\end{pmatrix}}{| { \begin{matrix}a & b \\x & y\end{matrix} } |}",
|
||||
_MatMul(Matrix([[a, b], [x, y]]), _Pow(Matrix([[a, b], [x, y]]).det(), -1))),
|
||||
(r"\overline{\begin{pmatrix}\imaginaryunit & 1+\imaginaryunit \\-\imaginaryunit & 4\end{pmatrix}}",
|
||||
Matrix([[-I, 1-I], [I, 4]])),
|
||||
(r"\begin{pmatrix}\imaginaryunit & 1+\imaginaryunit \\-\imaginaryunit & 4\end{pmatrix}^H",
|
||||
Matrix([[-I, I], [1-I, 4]])),
|
||||
(r"\trace(\begin{pmatrix}\imaginaryunit & 1+\imaginaryunit \\-\imaginaryunit & 4\end{pmatrix})",
|
||||
Trace(Matrix([[I, 1+I], [-I, 4]]))),
|
||||
(r"\adjugate(\begin{pmatrix}1 & 2 \\3 & 4\end{pmatrix})",
|
||||
Matrix([[4, -2], [-3, 1]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^\ast",
|
||||
Matrix([[-2*I, 6], [4, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\ast}",
|
||||
Matrix([[-2*I, 6], [4, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\ast\ast}",
|
||||
Matrix([[2*I, 4], [6, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\ast\ast\ast}",
|
||||
Matrix([[-2*I, 6], [4, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{*}",
|
||||
Matrix([[-2*I, 6], [4, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{**}",
|
||||
Matrix([[2*I, 4], [6, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{***}",
|
||||
Matrix([[-2*I, 6], [4, 8]])),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^\prime",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\prime}",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\prime\prime}",
|
||||
_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]]))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{\prime\prime\prime}",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{'}",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{''}",
|
||||
_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]]))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^{'''}",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})'",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})''",
|
||||
_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]]))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})'''",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"\det(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})",
|
||||
(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]]))).det()),
|
||||
(r"\trace(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})",
|
||||
Trace(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"\adjugate(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})",
|
||||
(Matrix([[8, -4], [-6, 2*I]]))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^T",
|
||||
Transpose(_MatAdd(Matrix([[I, 2], [3, 4]]),
|
||||
Matrix([[I, 2], [3, 4]])))),
|
||||
(r"(\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix}+\begin{pmatrix}\imaginaryunit&2\\3&4\end{pmatrix})^H",
|
||||
(Matrix([[-2*I, 6], [4, 8]])))
|
||||
]
|
||||
|
||||
|
||||
def test_symbol_expressions():
|
||||
expected_failures = {6, 7}
|
||||
for i, (latex_str, sympy_expr) in enumerate(SYMBOL_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_simple_expressions():
|
||||
expected_failures = {20}
|
||||
for i, (latex_str, sympy_expr) in enumerate(UNEVALUATED_SIMPLE_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for i, (latex_str, sympy_expr) in enumerate(EVALUATED_SIMPLE_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_fraction_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_FRACTION_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_FRACTION_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_relation_expressions():
|
||||
for latex_str, sympy_expr in RELATION_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
def test_power_expressions():
|
||||
expected_failures = {3}
|
||||
for i, (latex_str, sympy_expr) in enumerate(UNEVALUATED_POWER_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for i, (latex_str, sympy_expr) in enumerate(EVALUATED_POWER_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_integral_expressions():
|
||||
expected_failures = {14}
|
||||
for i, (latex_str, sympy_expr) in enumerate(UNEVALUATED_INTEGRAL_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, i
|
||||
|
||||
for i, (latex_str, sympy_expr) in enumerate(EVALUATED_INTEGRAL_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_derivative_expressions():
|
||||
expected_failures = {3, 4}
|
||||
for i, (latex_str, sympy_expr) in enumerate(DERIVATIVE_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for i, (latex_str, sympy_expr) in enumerate(DERIVATIVE_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_trigonometric_expressions():
|
||||
expected_failures = {3}
|
||||
for i, (latex_str, sympy_expr) in enumerate(TRIGONOMETRIC_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_limit_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_LIMIT_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_square_root_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_SQRT_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_SQRT_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_factorial_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_FACTORIAL_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_FACTORIAL_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_sum_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_SUM_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_SUM_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_product_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_PRODUCT_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
@XFAIL
|
||||
def test_applied_function_expressions():
|
||||
expected_failures = {0, 3, 4} # 0 is ambiguous, and the others require not-yet-added features
|
||||
# not sure why 1, and 2 are failing
|
||||
for i, (latex_str, sympy_expr) in enumerate(APPLIED_FUNCTION_EXPRESSION_PAIRS):
|
||||
if i in expected_failures:
|
||||
continue
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_common_function_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_COMMON_FUNCTION_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_COMMON_FUNCTION_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
# unhandled bug causing these to fail
|
||||
@XFAIL
|
||||
def test_spacing():
|
||||
for latex_str, sympy_expr in SPACING_RELATED_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_binomial_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_BINOMIAL_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_BINOMIAL_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_miscellaneous_expressions():
|
||||
for latex_str, sympy_expr in MISCELLANEOUS_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_literal_complex_number_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_LITERAL_COMPLEX_NUMBER_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
|
||||
def test_matrix_expressions():
|
||||
for latex_str, sympy_expr in UNEVALUATED_MATRIX_EXPRESSION_PAIRS:
|
||||
with evaluate(False):
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
|
||||
for latex_str, sympy_expr in EVALUATED_MATRIX_EXPRESSION_PAIRS:
|
||||
assert parse_latex_lark(latex_str) == sympy_expr, latex_str
|
||||
@@ -0,0 +1,280 @@
|
||||
from sympy import sin, Function, symbols, Dummy, Lambda, cos
|
||||
from sympy.parsing.mathematica import parse_mathematica, MathematicaParser
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.abc import n, w, x, y, z
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_mathematica():
|
||||
d = {
|
||||
'- 6x': '-6*x',
|
||||
'Sin[x]^2': 'sin(x)**2',
|
||||
'2(x-1)': '2*(x-1)',
|
||||
'3y+8': '3*y+8',
|
||||
'ArcSin[2x+9(4-x)^2]/x': 'asin(2*x+9*(4-x)**2)/x',
|
||||
'x+y': 'x+y',
|
||||
'355/113': '355/113',
|
||||
'2.718281828': '2.718281828',
|
||||
'Cos(1/2 * π)': 'Cos(π/2)',
|
||||
'Sin[12]': 'sin(12)',
|
||||
'Exp[Log[4]]': 'exp(log(4))',
|
||||
'(x+1)(x+3)': '(x+1)*(x+3)',
|
||||
'Cos[ArcCos[3.6]]': 'cos(acos(3.6))',
|
||||
'Cos[x]==Sin[y]': 'Eq(cos(x), sin(y))',
|
||||
'2*Sin[x+y]': '2*sin(x+y)',
|
||||
'Sin[x]+Cos[y]': 'sin(x)+cos(y)',
|
||||
'Sin[Cos[x]]': 'sin(cos(x))',
|
||||
'2*Sqrt[x+y]': '2*sqrt(x+y)', # Test case from the issue 4259
|
||||
'+Sqrt[2]': 'sqrt(2)',
|
||||
'-Sqrt[2]': '-sqrt(2)',
|
||||
'-1/Sqrt[2]': '-1/sqrt(2)',
|
||||
'-(1/Sqrt[3])': '-(1/sqrt(3))',
|
||||
'1/(2*Sqrt[5])': '1/(2*sqrt(5))',
|
||||
'Mod[5,3]': 'Mod(5,3)',
|
||||
'-Mod[5,3]': '-Mod(5,3)',
|
||||
'(x+1)y': '(x+1)*y',
|
||||
'x(y+1)': 'x*(y+1)',
|
||||
'Sin[x]Cos[y]': 'sin(x)*cos(y)',
|
||||
'Sin[x]^2Cos[y]^2': 'sin(x)**2*cos(y)**2',
|
||||
'Cos[x]^2(1 - Cos[y]^2)': 'cos(x)**2*(1-cos(y)**2)',
|
||||
'x y': 'x*y',
|
||||
'x y': 'x*y',
|
||||
'2 x': '2*x',
|
||||
'x 8': 'x*8',
|
||||
'2 8': '2*8',
|
||||
'4.x': '4.*x',
|
||||
'4. 3': '4.*3',
|
||||
'4. 3.': '4.*3.',
|
||||
'1 2 3': '1*2*3',
|
||||
' - 2 * Sqrt[ 2 3 * ( 1 + 5 ) ] ': '-2*sqrt(2*3*(1+5))',
|
||||
'Log[2,4]': 'log(4,2)',
|
||||
'Log[Log[2,4],4]': 'log(4,log(4,2))',
|
||||
'Exp[Sqrt[2]^2Log[2, 8]]': 'exp(sqrt(2)**2*log(8,2))',
|
||||
'ArcSin[Cos[0]]': 'asin(cos(0))',
|
||||
'Log2[16]': 'log(16,2)',
|
||||
'Max[1,-2,3,-4]': 'Max(1,-2,3,-4)',
|
||||
'Min[1,-2,3]': 'Min(1,-2,3)',
|
||||
'Exp[I Pi/2]': 'exp(I*pi/2)',
|
||||
'ArcTan[x,y]': 'atan2(y,x)',
|
||||
'Pochhammer[x,y]': 'rf(x,y)',
|
||||
'ExpIntegralEi[x]': 'Ei(x)',
|
||||
'SinIntegral[x]': 'Si(x)',
|
||||
'CosIntegral[x]': 'Ci(x)',
|
||||
'AiryAi[x]': 'airyai(x)',
|
||||
'AiryAiPrime[5]': 'airyaiprime(5)',
|
||||
'AiryBi[x]': 'airybi(x)',
|
||||
'AiryBiPrime[7]': 'airybiprime(7)',
|
||||
'LogIntegral[4]': ' li(4)',
|
||||
'PrimePi[7]': 'primepi(7)',
|
||||
'Prime[5]': 'prime(5)',
|
||||
'PrimeQ[5]': 'isprime(5)',
|
||||
'Rational[2,19]': 'Rational(2,19)', # test case for issue 25716
|
||||
}
|
||||
|
||||
for e in d:
|
||||
assert parse_mathematica(e) == sympify(d[e])
|
||||
|
||||
# The parsed form of this expression should not evaluate the Lambda object:
|
||||
assert parse_mathematica("Sin[#]^2 + Cos[#]^2 &[x]") == sin(x)**2 + cos(x)**2
|
||||
|
||||
d1, d2, d3 = symbols("d1:4", cls=Dummy)
|
||||
assert parse_mathematica("Sin[#] + Cos[#3] &").dummy_eq(Lambda((d1, d2, d3), sin(d1) + cos(d3)))
|
||||
assert parse_mathematica("Sin[#^2] &").dummy_eq(Lambda(d1, sin(d1**2)))
|
||||
assert parse_mathematica("Function[x, x^3]") == Lambda(x, x**3)
|
||||
assert parse_mathematica("Function[{x, y}, x^2 + y^2]") == Lambda((x, y), x**2 + y**2)
|
||||
|
||||
|
||||
def test_parser_mathematica_tokenizer():
|
||||
parser = MathematicaParser()
|
||||
|
||||
chain = lambda expr: parser._from_tokens_to_fullformlist(parser._from_mathematica_to_tokens(expr))
|
||||
|
||||
# Basic patterns
|
||||
assert chain("x") == "x"
|
||||
assert chain("42") == "42"
|
||||
assert chain(".2") == ".2"
|
||||
assert chain("+x") == "x"
|
||||
assert chain("-1") == "-1"
|
||||
assert chain("- 3") == "-3"
|
||||
assert chain("α") == "α"
|
||||
assert chain("+Sin[x]") == ["Sin", "x"]
|
||||
assert chain("-Sin[x]") == ["Times", "-1", ["Sin", "x"]]
|
||||
assert chain("x(a+1)") == ["Times", "x", ["Plus", "a", "1"]]
|
||||
assert chain("(x)") == "x"
|
||||
assert chain("(+x)") == "x"
|
||||
assert chain("-a") == ["Times", "-1", "a"]
|
||||
assert chain("(-x)") == ["Times", "-1", "x"]
|
||||
assert chain("(x + y)") == ["Plus", "x", "y"]
|
||||
assert chain("3 + 4") == ["Plus", "3", "4"]
|
||||
assert chain("a - 3") == ["Plus", "a", "-3"]
|
||||
assert chain("a - b") == ["Plus", "a", ["Times", "-1", "b"]]
|
||||
assert chain("7 * 8") == ["Times", "7", "8"]
|
||||
assert chain("a + b*c") == ["Plus", "a", ["Times", "b", "c"]]
|
||||
assert chain("a + b* c* d + 2 * e") == ["Plus", "a", ["Times", "b", "c", "d"], ["Times", "2", "e"]]
|
||||
assert chain("a / b") == ["Times", "a", ["Power", "b", "-1"]]
|
||||
|
||||
# Missing asterisk (*) patterns:
|
||||
assert chain("x y") == ["Times", "x", "y"]
|
||||
assert chain("3 4") == ["Times", "3", "4"]
|
||||
assert chain("a[b] c") == ["Times", ["a", "b"], "c"]
|
||||
assert chain("(x) (y)") == ["Times", "x", "y"]
|
||||
assert chain("3 (a)") == ["Times", "3", "a"]
|
||||
assert chain("(a) b") == ["Times", "a", "b"]
|
||||
assert chain("4.2") == "4.2"
|
||||
assert chain("4 2") == ["Times", "4", "2"]
|
||||
assert chain("4 2") == ["Times", "4", "2"]
|
||||
assert chain("3 . 4") == ["Dot", "3", "4"]
|
||||
assert chain("4. 2") == ["Times", "4.", "2"]
|
||||
assert chain("x.y") == ["Dot", "x", "y"]
|
||||
assert chain("4.y") == ["Times", "4.", "y"]
|
||||
assert chain("4 .y") == ["Dot", "4", "y"]
|
||||
assert chain("x.4") == ["Times", "x", ".4"]
|
||||
assert chain("x0.3") == ["Times", "x0", ".3"]
|
||||
assert chain("x. 4") == ["Dot", "x", "4"]
|
||||
|
||||
# Comments
|
||||
assert chain("a (* +b *) + c") == ["Plus", "a", "c"]
|
||||
assert chain("a (* + b *) + (**)c (* +d *) + e") == ["Plus", "a", "c", "e"]
|
||||
assert chain("""a + (*
|
||||
+ b
|
||||
*) c + (* d
|
||||
*) e
|
||||
""") == ["Plus", "a", "c", "e"]
|
||||
|
||||
# Operators couples + and -, * and / are mutually associative:
|
||||
# (i.e. expression gets flattened when mixing these operators)
|
||||
assert chain("a*b/c") == ["Times", "a", "b", ["Power", "c", "-1"]]
|
||||
assert chain("a/b*c") == ["Times", "a", ["Power", "b", "-1"], "c"]
|
||||
assert chain("a+b-c") == ["Plus", "a", "b", ["Times", "-1", "c"]]
|
||||
assert chain("a-b+c") == ["Plus", "a", ["Times", "-1", "b"], "c"]
|
||||
assert chain("-a + b -c ") == ["Plus", ["Times", "-1", "a"], "b", ["Times", "-1", "c"]]
|
||||
assert chain("a/b/c*d") == ["Times", "a", ["Power", "b", "-1"], ["Power", "c", "-1"], "d"]
|
||||
assert chain("a/b/c") == ["Times", "a", ["Power", "b", "-1"], ["Power", "c", "-1"]]
|
||||
assert chain("a-b-c") == ["Plus", "a", ["Times", "-1", "b"], ["Times", "-1", "c"]]
|
||||
assert chain("1/a") == ["Times", "1", ["Power", "a", "-1"]]
|
||||
assert chain("1/a/b") == ["Times", "1", ["Power", "a", "-1"], ["Power", "b", "-1"]]
|
||||
assert chain("-1/a*b") == ["Times", "-1", ["Power", "a", "-1"], "b"]
|
||||
|
||||
# Enclosures of various kinds, i.e. ( ) [ ] [[ ]] { }
|
||||
assert chain("(a + b) + c") == ["Plus", ["Plus", "a", "b"], "c"]
|
||||
assert chain(" a + (b + c) + d ") == ["Plus", "a", ["Plus", "b", "c"], "d"]
|
||||
assert chain("a * (b + c)") == ["Times", "a", ["Plus", "b", "c"]]
|
||||
assert chain("a b (c d)") == ["Times", "a", "b", ["Times", "c", "d"]]
|
||||
assert chain("{a, b, 2, c}") == ["List", "a", "b", "2", "c"]
|
||||
assert chain("{a, {b, c}}") == ["List", "a", ["List", "b", "c"]]
|
||||
assert chain("{{a}}") == ["List", ["List", "a"]]
|
||||
assert chain("a[b, c]") == ["a", "b", "c"]
|
||||
assert chain("a[[b, c]]") == ["Part", "a", "b", "c"]
|
||||
assert chain("a[b[c]]") == ["a", ["b", "c"]]
|
||||
assert chain("a[[b, c[[d, {e,f}]]]]") == ["Part", "a", "b", ["Part", "c", "d", ["List", "e", "f"]]]
|
||||
assert chain("a[b[[c,d]]]") == ["a", ["Part", "b", "c", "d"]]
|
||||
assert chain("a[[b[c]]]") == ["Part", "a", ["b", "c"]]
|
||||
assert chain("a[[b[[c]]]]") == ["Part", "a", ["Part", "b", "c"]]
|
||||
assert chain("a[[b[c[[d]]]]]") == ["Part", "a", ["b", ["Part", "c", "d"]]]
|
||||
assert chain("a[b[[c[d]]]]") == ["a", ["Part", "b", ["c", "d"]]]
|
||||
assert chain("x[[a+1, b+2, c+3]]") == ["Part", "x", ["Plus", "a", "1"], ["Plus", "b", "2"], ["Plus", "c", "3"]]
|
||||
assert chain("x[a+1, b+2, c+3]") == ["x", ["Plus", "a", "1"], ["Plus", "b", "2"], ["Plus", "c", "3"]]
|
||||
assert chain("{a+1, b+2, c+3}") == ["List", ["Plus", "a", "1"], ["Plus", "b", "2"], ["Plus", "c", "3"]]
|
||||
|
||||
# Flat operator:
|
||||
assert chain("a*b*c*d*e") == ["Times", "a", "b", "c", "d", "e"]
|
||||
assert chain("a +b + c+ d+e") == ["Plus", "a", "b", "c", "d", "e"]
|
||||
|
||||
# Right priority operator:
|
||||
assert chain("a^b") == ["Power", "a", "b"]
|
||||
assert chain("a^b^c") == ["Power", "a", ["Power", "b", "c"]]
|
||||
assert chain("a^b^c^d") == ["Power", "a", ["Power", "b", ["Power", "c", "d"]]]
|
||||
|
||||
# Left priority operator:
|
||||
assert chain("a/.b") == ["ReplaceAll", "a", "b"]
|
||||
assert chain("a/.b/.c/.d") == ["ReplaceAll", ["ReplaceAll", ["ReplaceAll", "a", "b"], "c"], "d"]
|
||||
|
||||
assert chain("a//b") == ["a", "b"]
|
||||
assert chain("a//b//c") == [["a", "b"], "c"]
|
||||
assert chain("a//b//c//d") == [[["a", "b"], "c"], "d"]
|
||||
|
||||
# Compound expressions
|
||||
assert chain("a;b") == ["CompoundExpression", "a", "b"]
|
||||
assert chain("a;") == ["CompoundExpression", "a", "Null"]
|
||||
assert chain("a;b;") == ["CompoundExpression", "a", "b", "Null"]
|
||||
assert chain("a[b;c]") == ["a", ["CompoundExpression", "b", "c"]]
|
||||
assert chain("a[b,c;d,e]") == ["a", "b", ["CompoundExpression", "c", "d"], "e"]
|
||||
assert chain("a[b,c;,d]") == ["a", "b", ["CompoundExpression", "c", "Null"], "d"]
|
||||
|
||||
# New lines
|
||||
assert chain("a\nb\n") == ["CompoundExpression", "a", "b"]
|
||||
assert chain("a\n\nb\n (c \nd) \n") == ["CompoundExpression", "a", "b", ["Times", "c", "d"]]
|
||||
assert chain("\na; b\nc") == ["CompoundExpression", "a", "b", "c"]
|
||||
assert chain("a + \nb\n") == ["Plus", "a", "b"]
|
||||
assert chain("a\nb; c; d\n e; (f \n g); h + \n i") == ["CompoundExpression", "a", "b", "c", "d", "e", ["Times", "f", "g"], ["Plus", "h", "i"]]
|
||||
assert chain("\n{\na\nb; c; d\n e (f \n g); h + \n i\n\n}\n") == ["List", ["CompoundExpression", ["Times", "a", "b"], "c", ["Times", "d", "e", ["Times", "f", "g"]], ["Plus", "h", "i"]]]
|
||||
|
||||
# Patterns
|
||||
assert chain("y_") == ["Pattern", "y", ["Blank"]]
|
||||
assert chain("y_.") == ["Optional", ["Pattern", "y", ["Blank"]]]
|
||||
assert chain("y__") == ["Pattern", "y", ["BlankSequence"]]
|
||||
assert chain("y___") == ["Pattern", "y", ["BlankNullSequence"]]
|
||||
assert chain("a[b_.,c_]") == ["a", ["Optional", ["Pattern", "b", ["Blank"]]], ["Pattern", "c", ["Blank"]]]
|
||||
assert chain("b_. c") == ["Times", ["Optional", ["Pattern", "b", ["Blank"]]], "c"]
|
||||
|
||||
# Slots for lambda functions
|
||||
assert chain("#") == ["Slot", "1"]
|
||||
assert chain("#3") == ["Slot", "3"]
|
||||
assert chain("#n") == ["Slot", "n"]
|
||||
assert chain("##") == ["SlotSequence", "1"]
|
||||
assert chain("##a") == ["SlotSequence", "a"]
|
||||
|
||||
# Lambda functions
|
||||
assert chain("x&") == ["Function", "x"]
|
||||
assert chain("#&") == ["Function", ["Slot", "1"]]
|
||||
assert chain("#+3&") == ["Function", ["Plus", ["Slot", "1"], "3"]]
|
||||
assert chain("#1 + #2&") == ["Function", ["Plus", ["Slot", "1"], ["Slot", "2"]]]
|
||||
assert chain("# + #&") == ["Function", ["Plus", ["Slot", "1"], ["Slot", "1"]]]
|
||||
assert chain("#&[x]") == [["Function", ["Slot", "1"]], "x"]
|
||||
assert chain("#1 + #2 & [x, y]") == [["Function", ["Plus", ["Slot", "1"], ["Slot", "2"]]], "x", "y"]
|
||||
assert chain("#1^2#2^3&") == ["Function", ["Times", ["Power", ["Slot", "1"], "2"], ["Power", ["Slot", "2"], "3"]]]
|
||||
|
||||
# Strings inside Mathematica expressions:
|
||||
assert chain('"abc"') == ["_Str", "abc"]
|
||||
assert chain('"a\\"b"') == ["_Str", 'a"b']
|
||||
# This expression does not make sense mathematically, it's just testing the parser:
|
||||
assert chain('x + "abc" ^ 3') == ["Plus", "x", ["Power", ["_Str", "abc"], "3"]]
|
||||
assert chain('"a (* b *) c"') == ["_Str", "a (* b *) c"]
|
||||
assert chain('"a" (* b *) ') == ["_Str", "a"]
|
||||
assert chain('"a [ b] "') == ["_Str", "a [ b] "]
|
||||
raises(SyntaxError, lambda: chain('"'))
|
||||
raises(SyntaxError, lambda: chain('"\\"'))
|
||||
raises(SyntaxError, lambda: chain('"abc'))
|
||||
raises(SyntaxError, lambda: chain('"abc\\"def'))
|
||||
|
||||
# Invalid expressions:
|
||||
raises(SyntaxError, lambda: chain("(,"))
|
||||
raises(SyntaxError, lambda: chain("()"))
|
||||
raises(SyntaxError, lambda: chain("a (* b"))
|
||||
|
||||
|
||||
def test_parser_mathematica_exp_alt():
|
||||
parser = MathematicaParser()
|
||||
|
||||
convert_chain2 = lambda expr: parser._from_fullformlist_to_fullformsympy(parser._from_fullform_to_fullformlist(expr))
|
||||
convert_chain3 = lambda expr: parser._from_fullformsympy_to_sympy(convert_chain2(expr))
|
||||
|
||||
Sin, Times, Plus, Power = symbols("Sin Times Plus Power", cls=Function)
|
||||
|
||||
full_form1 = "Sin[Times[x, y]]"
|
||||
full_form2 = "Plus[Times[x, y], z]"
|
||||
full_form3 = "Sin[Times[x, Plus[y, z], Power[w, n]]]]"
|
||||
full_form4 = "Rational[Rational[x, y], z]"
|
||||
|
||||
assert parser._from_fullform_to_fullformlist(full_form1) == ["Sin", ["Times", "x", "y"]]
|
||||
assert parser._from_fullform_to_fullformlist(full_form2) == ["Plus", ["Times", "x", "y"], "z"]
|
||||
assert parser._from_fullform_to_fullformlist(full_form3) == ["Sin", ["Times", "x", ["Plus", "y", "z"], ["Power", "w", "n"]]]
|
||||
assert parser._from_fullform_to_fullformlist(full_form4) == ["Rational", ["Rational", "x", "y"], "z"]
|
||||
|
||||
assert convert_chain2(full_form1) == Sin(Times(x, y))
|
||||
assert convert_chain2(full_form2) == Plus(Times(x, y), z)
|
||||
assert convert_chain2(full_form3) == Sin(Times(x, Plus(y, z), Power(w, n)))
|
||||
|
||||
assert convert_chain3(full_form1) == sin(x*y)
|
||||
assert convert_chain3(full_form2) == x*y + z
|
||||
assert convert_chain3(full_form3) == sin(x*(y + z)*w**n)
|
||||
@@ -0,0 +1,50 @@
|
||||
from sympy.parsing.maxima import parse_maxima
|
||||
from sympy.core.numbers import (E, Rational, oo)
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.combinatorial.factorials import factorial
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.exponential import log
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.abc import x
|
||||
|
||||
n = Symbol('n', integer=True)
|
||||
|
||||
|
||||
def test_parser():
|
||||
assert Abs(parse_maxima('float(1/3)') - 0.333333333) < 10**(-5)
|
||||
assert parse_maxima('13^26') == 91733330193268616658399616009
|
||||
assert parse_maxima('sin(%pi/2) + cos(%pi/3)') == Rational(3, 2)
|
||||
assert parse_maxima('log(%e)') == 1
|
||||
|
||||
|
||||
def test_injection():
|
||||
parse_maxima('c: x+1', globals=globals())
|
||||
# c created by parse_maxima
|
||||
assert c == x + 1 # noqa:F821
|
||||
|
||||
parse_maxima('g: sqrt(81)', globals=globals())
|
||||
# g created by parse_maxima
|
||||
assert g == 9 # noqa:F821
|
||||
|
||||
|
||||
def test_maxima_functions():
|
||||
assert parse_maxima('expand( (x+1)^2)') == x**2 + 2*x + 1
|
||||
assert parse_maxima('factor( x**2 + 2*x + 1)') == (x + 1)**2
|
||||
assert parse_maxima('2*cos(x)^2 + sin(x)^2') == 2*cos(x)**2 + sin(x)**2
|
||||
assert parse_maxima('trigexpand(sin(2*x)+cos(2*x))') == \
|
||||
-1 + 2*cos(x)**2 + 2*cos(x)*sin(x)
|
||||
assert parse_maxima('solve(x^2-4,x)') == [-2, 2]
|
||||
assert parse_maxima('limit((1+1/x)^x,x,inf)') == E
|
||||
assert parse_maxima('limit(sqrt(-x)/x,x,0,minus)') is -oo
|
||||
assert parse_maxima('diff(x^x, x)') == x**x*(1 + log(x))
|
||||
assert parse_maxima('sum(k, k, 1, n)', name_dict={
|
||||
"n": Symbol('n', integer=True),
|
||||
"k": Symbol('k', integer=True)
|
||||
}) == (n**2 + n)/2
|
||||
assert parse_maxima('product(k, k, 1, n)', name_dict={
|
||||
"n": Symbol('n', integer=True),
|
||||
"k": Symbol('k', integer=True)
|
||||
}) == factorial(n)
|
||||
assert parse_maxima('ratsimp((x^2-1)/(x+1))') == x - 1
|
||||
assert Abs( parse_maxima(
|
||||
'float(sec(%pi/3) + csc(%pi/3))') - 3.154700538379252) < 10**(-5)
|
||||
@@ -0,0 +1,209 @@
|
||||
from sympy.parsing.sym_expr import SymPyExpression
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.external import import_module
|
||||
|
||||
lfortran = import_module('lfortran')
|
||||
cin = import_module('clang.cindex', import_kwargs = {'fromlist': ['cindex']})
|
||||
|
||||
if lfortran and cin:
|
||||
from sympy.codegen.ast import (Variable, IntBaseType, FloatBaseType, String,
|
||||
Declaration, FloatType)
|
||||
from sympy.core import Integer, Float
|
||||
from sympy.core.symbol import Symbol
|
||||
|
||||
expr1 = SymPyExpression()
|
||||
src = """\
|
||||
integer :: a, b, c, d
|
||||
real :: p, q, r, s
|
||||
"""
|
||||
|
||||
def test_c_parse():
|
||||
src1 = """\
|
||||
int a, b = 4;
|
||||
float c, d = 2.4;
|
||||
"""
|
||||
expr1.convert_to_expr(src1, 'c')
|
||||
ls = expr1.return_expr()
|
||||
|
||||
assert ls[0] == Declaration(
|
||||
Variable(
|
||||
Symbol('a'),
|
||||
type=IntBaseType(String('intc'))
|
||||
)
|
||||
)
|
||||
assert ls[1] == Declaration(
|
||||
Variable(
|
||||
Symbol('b'),
|
||||
type=IntBaseType(String('intc')),
|
||||
value=Integer(4)
|
||||
)
|
||||
)
|
||||
assert ls[2] == Declaration(
|
||||
Variable(
|
||||
Symbol('c'),
|
||||
type=FloatType(
|
||||
String('float32'),
|
||||
nbits=Integer(32),
|
||||
nmant=Integer(23),
|
||||
nexp=Integer(8)
|
||||
)
|
||||
)
|
||||
)
|
||||
assert ls[3] == Declaration(
|
||||
Variable(
|
||||
Symbol('d'),
|
||||
type=FloatType(
|
||||
String('float32'),
|
||||
nbits=Integer(32),
|
||||
nmant=Integer(23),
|
||||
nexp=Integer(8)
|
||||
),
|
||||
value=Float('2.3999999999999999', precision=53)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_fortran_parse():
|
||||
expr = SymPyExpression(src, 'f')
|
||||
ls = expr.return_expr()
|
||||
|
||||
assert ls[0] == Declaration(
|
||||
Variable(
|
||||
Symbol('a'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[1] == Declaration(
|
||||
Variable(
|
||||
Symbol('b'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[2] == Declaration(
|
||||
Variable(
|
||||
Symbol('c'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[3] == Declaration(
|
||||
Variable(
|
||||
Symbol('d'),
|
||||
type=IntBaseType(String('integer')),
|
||||
value=Integer(0)
|
||||
)
|
||||
)
|
||||
assert ls[4] == Declaration(
|
||||
Variable(
|
||||
Symbol('p'),
|
||||
type=FloatBaseType(String('real')),
|
||||
value=Float('0.0', precision=53)
|
||||
)
|
||||
)
|
||||
assert ls[5] == Declaration(
|
||||
Variable(
|
||||
Symbol('q'),
|
||||
type=FloatBaseType(String('real')),
|
||||
value=Float('0.0', precision=53)
|
||||
)
|
||||
)
|
||||
assert ls[6] == Declaration(
|
||||
Variable(
|
||||
Symbol('r'),
|
||||
type=FloatBaseType(String('real')),
|
||||
value=Float('0.0', precision=53)
|
||||
)
|
||||
)
|
||||
assert ls[7] == Declaration(
|
||||
Variable(
|
||||
Symbol('s'),
|
||||
type=FloatBaseType(String('real')),
|
||||
value=Float('0.0', precision=53)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_convert_py():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
a = b + c
|
||||
s = p * q / r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
exp_py = expr1.convert_to_python()
|
||||
assert exp_py == [
|
||||
'a = 0',
|
||||
'b = 0',
|
||||
'c = 0',
|
||||
'd = 0',
|
||||
'p = 0.0',
|
||||
'q = 0.0',
|
||||
'r = 0.0',
|
||||
's = 0.0',
|
||||
'a = b + c',
|
||||
's = p*q/r'
|
||||
]
|
||||
|
||||
|
||||
def test_convert_fort():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
a = b + c
|
||||
s = p * q / r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
exp_fort = expr1.convert_to_fortran()
|
||||
assert exp_fort == [
|
||||
' integer*4 a',
|
||||
' integer*4 b',
|
||||
' integer*4 c',
|
||||
' integer*4 d',
|
||||
' real*8 p',
|
||||
' real*8 q',
|
||||
' real*8 r',
|
||||
' real*8 s',
|
||||
' a = b + c',
|
||||
' s = p*q/r'
|
||||
]
|
||||
|
||||
|
||||
def test_convert_c():
|
||||
src1 = (
|
||||
src +
|
||||
"""\
|
||||
a = b + c
|
||||
s = p * q / r
|
||||
"""
|
||||
)
|
||||
expr1.convert_to_expr(src1, 'f')
|
||||
exp_c = expr1.convert_to_c()
|
||||
assert exp_c == [
|
||||
'int a = 0',
|
||||
'int b = 0',
|
||||
'int c = 0',
|
||||
'int d = 0',
|
||||
'double p = 0.0',
|
||||
'double q = 0.0',
|
||||
'double r = 0.0',
|
||||
'double s = 0.0',
|
||||
'a = b + c;',
|
||||
's = p*q/r;'
|
||||
]
|
||||
|
||||
|
||||
def test_exceptions():
|
||||
src = 'int a;'
|
||||
raises(ValueError, lambda: SymPyExpression(src))
|
||||
raises(ValueError, lambda: SymPyExpression(mode = 'c'))
|
||||
raises(NotImplementedError, lambda: SymPyExpression(src, mode = 'd'))
|
||||
|
||||
elif not lfortran and not cin:
|
||||
def test_raise():
|
||||
raises(ImportError, lambda: SymPyExpression('int a;', 'c'))
|
||||
raises(ImportError, lambda: SymPyExpression('integer :: a', 'f'))
|
||||
@@ -0,0 +1,371 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import builtins
|
||||
import types
|
||||
|
||||
from sympy.assumptions import Q
|
||||
from sympy.core import Symbol, Function, Float, Rational, Integer, I, Mul, Pow, Eq, Lt, Le, Gt, Ge, Ne
|
||||
from sympy.functions import exp, factorial, factorial2, sin, Min, Max
|
||||
from sympy.logic import And
|
||||
from sympy.series import Limit
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.parsing.sympy_parser import (
|
||||
parse_expr, standard_transformations, rationalize, TokenError,
|
||||
split_symbols, implicit_multiplication, convert_equals_signs,
|
||||
convert_xor, function_exponentiation, lambda_notation, auto_symbol,
|
||||
repeated_decimals, implicit_multiplication_application,
|
||||
auto_number, factorial_notation, implicit_application,
|
||||
_transformation, T
|
||||
)
|
||||
|
||||
|
||||
def test_sympy_parser():
|
||||
x = Symbol('x')
|
||||
inputs = {
|
||||
'2*x': 2 * x,
|
||||
'3.00': Float(3),
|
||||
'22/7': Rational(22, 7),
|
||||
'2+3j': 2 + 3*I,
|
||||
'exp(x)': exp(x),
|
||||
'x!': factorial(x),
|
||||
'x!!': factorial2(x),
|
||||
'(x + 1)! - 1': factorial(x + 1) - 1,
|
||||
'3.[3]': Rational(10, 3),
|
||||
'.0[3]': Rational(1, 30),
|
||||
'3.2[3]': Rational(97, 30),
|
||||
'1.3[12]': Rational(433, 330),
|
||||
'1 + 3.[3]': Rational(13, 3),
|
||||
'1 + .0[3]': Rational(31, 30),
|
||||
'1 + 3.2[3]': Rational(127, 30),
|
||||
'.[0011]': Rational(1, 909),
|
||||
'0.1[00102] + 1': Rational(366697, 333330),
|
||||
'1.[0191]': Rational(10190, 9999),
|
||||
'10!': 3628800,
|
||||
'-(2)': -Integer(2),
|
||||
'[-1, -2, 3]': [Integer(-1), Integer(-2), Integer(3)],
|
||||
'Symbol("x").free_symbols': x.free_symbols,
|
||||
"S('S(3).n(n=3)')": Float(3, 3),
|
||||
'factorint(12, visual=True)': Mul(
|
||||
Pow(2, 2, evaluate=False),
|
||||
Pow(3, 1, evaluate=False),
|
||||
evaluate=False),
|
||||
'Limit(sin(x), x, 0, dir="-")': Limit(sin(x), x, 0, dir='-'),
|
||||
'Q.even(x)': Q.even(x),
|
||||
|
||||
|
||||
}
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text) == result
|
||||
|
||||
raises(TypeError, lambda:
|
||||
parse_expr('x', standard_transformations))
|
||||
raises(TypeError, lambda:
|
||||
parse_expr('x', transformations=lambda x,y: 1))
|
||||
raises(TypeError, lambda:
|
||||
parse_expr('x', transformations=(lambda x,y: 1,)))
|
||||
raises(TypeError, lambda: parse_expr('x', transformations=((),)))
|
||||
raises(TypeError, lambda: parse_expr('x', {}, [], []))
|
||||
raises(TypeError, lambda: parse_expr('x', [], [], {}))
|
||||
raises(TypeError, lambda: parse_expr('x', [], [], {}))
|
||||
|
||||
|
||||
def test_rationalize():
|
||||
inputs = {
|
||||
'0.123': Rational(123, 1000)
|
||||
}
|
||||
transformations = standard_transformations + (rationalize,)
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text, transformations=transformations) == result
|
||||
|
||||
|
||||
def test_factorial_fail():
|
||||
inputs = ['x!!!', 'x!!!!', '(!)']
|
||||
|
||||
|
||||
for text in inputs:
|
||||
try:
|
||||
parse_expr(text)
|
||||
assert False
|
||||
except TokenError:
|
||||
assert True
|
||||
|
||||
|
||||
def test_repeated_fail():
|
||||
inputs = ['1[1]', '.1e1[1]', '0x1[1]', '1.1j[1]', '1.1[1 + 1]',
|
||||
'0.1[[1]]', '0x1.1[1]']
|
||||
|
||||
|
||||
# All are valid Python, so only raise TypeError for invalid indexing
|
||||
for text in inputs:
|
||||
raises(TypeError, lambda: parse_expr(text))
|
||||
|
||||
|
||||
inputs = ['0.1[', '0.1[1', '0.1[]']
|
||||
for text in inputs:
|
||||
raises((TokenError, SyntaxError), lambda: parse_expr(text))
|
||||
|
||||
|
||||
def test_repeated_dot_only():
|
||||
assert parse_expr('.[1]') == Rational(1, 9)
|
||||
assert parse_expr('1 + .[1]') == Rational(10, 9)
|
||||
|
||||
|
||||
def test_local_dict():
|
||||
local_dict = {
|
||||
'my_function': lambda x: x + 2
|
||||
}
|
||||
inputs = {
|
||||
'my_function(2)': Integer(4)
|
||||
}
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text, local_dict=local_dict) == result
|
||||
|
||||
|
||||
def test_local_dict_split_implmult():
|
||||
t = standard_transformations + (split_symbols, implicit_multiplication,)
|
||||
w = Symbol('w', real=True)
|
||||
y = Symbol('y')
|
||||
assert parse_expr('yx', local_dict={'x':w}, transformations=t) == y*w
|
||||
|
||||
|
||||
def test_local_dict_symbol_to_fcn():
|
||||
x = Symbol('x')
|
||||
d = {'foo': Function('bar')}
|
||||
assert parse_expr('foo(x)', local_dict=d) == d['foo'](x)
|
||||
d = {'foo': Symbol('baz')}
|
||||
raises(TypeError, lambda: parse_expr('foo(x)', local_dict=d))
|
||||
|
||||
|
||||
def test_global_dict():
|
||||
global_dict = {
|
||||
'Symbol': Symbol
|
||||
}
|
||||
inputs = {
|
||||
'Q & S': And(Symbol('Q'), Symbol('S'))
|
||||
}
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text, global_dict=global_dict) == result
|
||||
|
||||
|
||||
def test_no_globals():
|
||||
|
||||
# Replicate creating the default global_dict:
|
||||
default_globals = {}
|
||||
exec('from sympy import *', default_globals)
|
||||
builtins_dict = vars(builtins)
|
||||
for name, obj in builtins_dict.items():
|
||||
if isinstance(obj, types.BuiltinFunctionType):
|
||||
default_globals[name] = obj
|
||||
default_globals['max'] = Max
|
||||
default_globals['min'] = Min
|
||||
|
||||
# Need to include Symbol or parse_expr will not work:
|
||||
default_globals.pop('Symbol')
|
||||
global_dict = {'Symbol':Symbol}
|
||||
|
||||
for name in default_globals:
|
||||
obj = parse_expr(name, global_dict=global_dict)
|
||||
assert obj == Symbol(name)
|
||||
|
||||
|
||||
def test_issue_2515():
|
||||
raises(TokenError, lambda: parse_expr('(()'))
|
||||
raises(TokenError, lambda: parse_expr('"""'))
|
||||
|
||||
|
||||
def test_issue_7663():
|
||||
x = Symbol('x')
|
||||
e = '2*(x+1)'
|
||||
assert parse_expr(e, evaluate=False) == parse_expr(e, evaluate=False)
|
||||
assert parse_expr(e, evaluate=False).equals(2*(x+1))
|
||||
|
||||
def test_recursive_evaluate_false_10560():
|
||||
inputs = {
|
||||
'4*-3' : '4*-3',
|
||||
'-4*3' : '(-4)*3',
|
||||
"-2*x*y": '(-2)*x*y',
|
||||
"x*-4*x": "x*(-4)*x"
|
||||
}
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text, evaluate=False) == parse_expr(result, evaluate=False)
|
||||
|
||||
|
||||
def test_function_evaluate_false():
|
||||
inputs = [
|
||||
'Abs(0)', 'im(0)', 're(0)', 'sign(0)', 'arg(0)', 'conjugate(0)',
|
||||
'acos(0)', 'acot(0)', 'acsc(0)', 'asec(0)', 'asin(0)', 'atan(0)',
|
||||
'acosh(0)', 'acoth(0)', 'acsch(0)', 'asech(0)', 'asinh(0)', 'atanh(0)',
|
||||
'cos(0)', 'cot(0)', 'csc(0)', 'sec(0)', 'sin(0)', 'tan(0)',
|
||||
'cosh(0)', 'coth(0)', 'csch(0)', 'sech(0)', 'sinh(0)', 'tanh(0)',
|
||||
'exp(0)', 'log(0)', 'sqrt(0)',
|
||||
]
|
||||
for case in inputs:
|
||||
expr = parse_expr(case, evaluate=False)
|
||||
assert case == str(expr) != str(expr.doit())
|
||||
assert str(parse_expr('ln(0)', evaluate=False)) == 'log(0)'
|
||||
assert str(parse_expr('cbrt(0)', evaluate=False)) == '0**(1/3)'
|
||||
|
||||
|
||||
def test_issue_10773():
|
||||
inputs = {
|
||||
'-10/5': '(-10)/5',
|
||||
'-10/-5' : '(-10)/(-5)',
|
||||
}
|
||||
for text, result in inputs.items():
|
||||
assert parse_expr(text, evaluate=False) == parse_expr(result, evaluate=False)
|
||||
|
||||
|
||||
def test_split_symbols():
|
||||
transformations = standard_transformations + \
|
||||
(split_symbols, implicit_multiplication,)
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
xy = Symbol('xy')
|
||||
|
||||
|
||||
assert parse_expr("xy") == xy
|
||||
assert parse_expr("xy", transformations=transformations) == x*y
|
||||
|
||||
|
||||
def test_split_symbols_function():
|
||||
transformations = standard_transformations + \
|
||||
(split_symbols, implicit_multiplication,)
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
a = Symbol('a')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
assert parse_expr("ay(x+1)", transformations=transformations) == a*y*(x+1)
|
||||
assert parse_expr("af(x+1)", transformations=transformations,
|
||||
local_dict={'f':f}) == a*f(x+1)
|
||||
|
||||
|
||||
def test_functional_exponent():
|
||||
t = standard_transformations + (convert_xor, function_exponentiation)
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
a = Symbol('a')
|
||||
yfcn = Function('y')
|
||||
assert parse_expr("sin^2(x)", transformations=t) == (sin(x))**2
|
||||
assert parse_expr("sin^y(x)", transformations=t) == (sin(x))**y
|
||||
assert parse_expr("exp^y(x)", transformations=t) == (exp(x))**y
|
||||
assert parse_expr("E^y(x)", transformations=t) == exp(yfcn(x))
|
||||
assert parse_expr("a^y(x)", transformations=t) == a**(yfcn(x))
|
||||
|
||||
|
||||
def test_match_parentheses_implicit_multiplication():
|
||||
transformations = standard_transformations + \
|
||||
(implicit_multiplication,)
|
||||
raises(TokenError, lambda: parse_expr('(1,2),(3,4]',transformations=transformations))
|
||||
|
||||
|
||||
def test_convert_equals_signs():
|
||||
transformations = standard_transformations + \
|
||||
(convert_equals_signs, )
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
assert parse_expr("1*2=x", transformations=transformations) == Eq(2, x)
|
||||
assert parse_expr("y = x", transformations=transformations) == Eq(y, x)
|
||||
assert parse_expr("(2*y = x) = False",
|
||||
transformations=transformations) == Eq(Eq(2*y, x), False)
|
||||
|
||||
|
||||
def test_parse_function_issue_3539():
|
||||
x = Symbol('x')
|
||||
f = Function('f')
|
||||
assert parse_expr('f(x)') == f(x)
|
||||
|
||||
def test_issue_24288():
|
||||
assert parse_expr("1 < 2", evaluate=False) == Lt(1, 2, evaluate=False)
|
||||
assert parse_expr("1 <= 2", evaluate=False) == Le(1, 2, evaluate=False)
|
||||
assert parse_expr("1 > 2", evaluate=False) == Gt(1, 2, evaluate=False)
|
||||
assert parse_expr("1 >= 2", evaluate=False) == Ge(1, 2, evaluate=False)
|
||||
assert parse_expr("1 != 2", evaluate=False) == Ne(1, 2, evaluate=False)
|
||||
assert parse_expr("1 == 2", evaluate=False) == Eq(1, 2, evaluate=False)
|
||||
assert parse_expr("1 < 2 < 3", evaluate=False) == And(Lt(1, 2, evaluate=False), Lt(2, 3, evaluate=False), evaluate=False)
|
||||
assert parse_expr("1 <= 2 <= 3", evaluate=False) == And(Le(1, 2, evaluate=False), Le(2, 3, evaluate=False), evaluate=False)
|
||||
assert parse_expr("1 < 2 <= 3 < 4", evaluate=False) == \
|
||||
And(Lt(1, 2, evaluate=False), Le(2, 3, evaluate=False), Lt(3, 4, evaluate=False), evaluate=False)
|
||||
# Valid Python relational operators that SymPy does not decide how to handle them yet
|
||||
raises(ValueError, lambda: parse_expr("1 in 2", evaluate=False))
|
||||
raises(ValueError, lambda: parse_expr("1 is 2", evaluate=False))
|
||||
raises(ValueError, lambda: parse_expr("1 not in 2", evaluate=False))
|
||||
raises(ValueError, lambda: parse_expr("1 is not 2", evaluate=False))
|
||||
|
||||
def test_split_symbols_numeric():
|
||||
transformations = (
|
||||
standard_transformations +
|
||||
(implicit_multiplication_application,))
|
||||
|
||||
n = Symbol('n')
|
||||
expr1 = parse_expr('2**n * 3**n')
|
||||
expr2 = parse_expr('2**n3**n', transformations=transformations)
|
||||
assert expr1 == expr2 == 2**n*3**n
|
||||
|
||||
expr1 = parse_expr('n12n34', transformations=transformations)
|
||||
assert expr1 == n*12*n*34
|
||||
|
||||
|
||||
def test_unicode_names():
|
||||
assert parse_expr('α') == Symbol('α')
|
||||
|
||||
|
||||
def test_python3_features():
|
||||
assert parse_expr("123_456") == 123456
|
||||
assert parse_expr("1.2[3_4]") == parse_expr("1.2[34]") == Rational(611, 495)
|
||||
assert parse_expr("1.2[012_012]") == parse_expr("1.2[012012]") == Rational(400, 333)
|
||||
assert parse_expr('.[3_4]') == parse_expr('.[34]') == Rational(34, 99)
|
||||
assert parse_expr('.1[3_4]') == parse_expr('.1[34]') == Rational(133, 990)
|
||||
assert parse_expr('123_123.123_123[3_4]') == parse_expr('123123.123123[34]') == Rational(12189189189211, 99000000)
|
||||
|
||||
|
||||
def test_issue_19501():
|
||||
x = Symbol('x')
|
||||
eq = parse_expr('E**x(1+x)', local_dict={'x': x}, transformations=(
|
||||
standard_transformations +
|
||||
(implicit_multiplication_application,)))
|
||||
assert eq.free_symbols == {x}
|
||||
|
||||
|
||||
def test_parsing_definitions():
|
||||
from sympy.abc import x
|
||||
assert len(_transformation) == 12 # if this changes, extend below
|
||||
assert _transformation[0] == lambda_notation
|
||||
assert _transformation[1] == auto_symbol
|
||||
assert _transformation[2] == repeated_decimals
|
||||
assert _transformation[3] == auto_number
|
||||
assert _transformation[4] == factorial_notation
|
||||
assert _transformation[5] == implicit_multiplication_application
|
||||
assert _transformation[6] == convert_xor
|
||||
assert _transformation[7] == implicit_application
|
||||
assert _transformation[8] == implicit_multiplication
|
||||
assert _transformation[9] == convert_equals_signs
|
||||
assert _transformation[10] == function_exponentiation
|
||||
assert _transformation[11] == rationalize
|
||||
assert T[:5] == T[0,1,2,3,4] == standard_transformations
|
||||
t = _transformation
|
||||
assert T[-1, 0] == (t[len(t) - 1], t[0])
|
||||
assert T[:5, 8] == standard_transformations + (t[8],)
|
||||
assert parse_expr('0.3x^2', transformations='all') == 3*x**2/10
|
||||
assert parse_expr('sin 3x', transformations='implicit') == sin(3*x)
|
||||
|
||||
|
||||
def test_builtins():
|
||||
cases = [
|
||||
('abs(x)', 'Abs(x)'),
|
||||
('max(x, y)', 'Max(x, y)'),
|
||||
('min(x, y)', 'Min(x, y)'),
|
||||
('pow(x, y)', 'Pow(x, y)'),
|
||||
]
|
||||
for built_in_func_call, sympy_func_call in cases:
|
||||
assert parse_expr(built_in_func_call) == parse_expr(sympy_func_call)
|
||||
assert str(parse_expr('pow(38, -1, 97)')) == '23'
|
||||
|
||||
|
||||
def test_issue_22822():
|
||||
raises(ValueError, lambda: parse_expr('x', {'': 1}))
|
||||
data = {'some_parameter': None}
|
||||
assert parse_expr('some_parameter is None', data) is True
|
||||
Reference in New Issue
Block a user