chore: 添加虚拟环境到仓库
- 添加 backend_service/venv 虚拟环境 - 包含所有Python依赖包 - 注意:虚拟环境约393MB,包含12655个文件
This commit is contained in:
@@ -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