def test_1_3_expression_parser_math_ops(): """Testing handling of mathematical operations by expression parsers: See Also -------- :class:`ExpressionParser`: Detailed documentation of expression parser attributes and methods. :class:`LambdaExpressionParser`: Documentation of a non-symbolic expression parser. """ # define test cases math_expressions = [("4 + 5", 9.), # simple addition ("4 - 5", -1.), # simple subtraction ("4. * 5.", 20.), # simple multiplication ("4. / 5.", 0.8), # simple division ("4.^2.", 16.), # simple exponentiation ("4. + -5.", -1.), # negation of variable ("4. * -2.", -8.), # negation of variable in higher-order operation ("4. + 5. * 2.", 14.), # multiplication before addition ("(4. + 5.) * 2.", 18.), # parentheses before everything ("4. * 5.^2.", 100.) # exponentiation before multiplication ] # test expression parser on expression results using tensorflow backend ####################################################################### # define backend b = TensorflowBackend() # evaluate expressions for expr, target in math_expressions: # tensorflow-based parser p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6) # test expression parser on expression results using numpy backend ################################################################## # define backend b = NumpyBackend() # evaluate expressions for expr, target in math_expressions: # tensorflow-based parser p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6)
def test_1_6_expression_parser_funcs(): """Testing handling of function calls by expression parsers: See Also -------- :class:`ExpressionParser`: Detailed documentation of expression parser attributes and methods. :class:`LambdaExpressionParser`: Documentation of a non-symbolic expression parser. """ # define variables A = np.array(np.random.randn(10, 10), dtype=np.float32) # define valid test cases expressions = [("abs(5.)", 5.), # simple function call ("abs(-5.)", 5.), # function call of negative arg ("abs(4. * -2. + 1)", 7.), # function call on mathematical expression ("int64(4 > 5)", 0), # function call on boolean expression ("abs(A[2, :])", np.abs(A[2, :])), # function call on indexed variable ("abs(sin(1.5))", np.abs(np.sin(1.5))), # nested function calls ] # define invalid test cases expressions_wrong = ["abs((4.)", # wrong parentheses I "abs[4.]", # wrong parentheses II "abs(0. True)", # no comma separation on arguments "abs(0.,1,5,3)", # wrong argument number ] # test function calling on tensorflow-based parser ################################################## # define backend b = TensorflowBackend() args = parse_dict({'A': {'vtype': 'constant', 'value': A, 'shape': A.shape, 'dtype': A.dtype}}, backend=b) # start testing: valid cases for expr, target in expressions: # tensorflow-based parser p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6) # invalid cases for expr in expressions_wrong: # tensorflow-based parser with pytest.raises((IndexError, ValueError, SyntaxError, TypeError, BaseException)): p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() # test function calling on numpy-based parser ############################################# # define backend b = NumpyBackend() # define variables args = parse_dict({'A': {'vtype': 'constant', 'value': A, 'shape': A.shape, 'dtype': A.dtype}}, backend=b) # start testing: valid cases for expr, target in expressions: # tensorflow-based parser p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6) # invalid cases for expr in expressions_wrong[:-1]: # tensorflow-based parser with pytest.raises((IndexError, ValueError, SyntaxError, TypeError, BaseException)): p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr()
def test_1_5_expression_parser_indexing(): """Testing handling of indexing operations by expression parsers: See Also -------- :class:`ExpressionParser`: Detailed documentation of expression parser attributes and methods. :class:`LambdaExpressionParser`: Documentation of a non-symbolic expression parser. """ # test indexing ability of tensorflow-based parser ################################################## # define backend b = TensorflowBackend() # define variables A = np.array(np.random.randn(10, 10), dtype=np.float32) B = np.eye(10, dtype=np.float32) == 1 arg_dict = {'A': {'vtype': 'constant', 'value': A, 'shape': A.shape, 'dtype': A.dtype}, 'B': {'vtype': 'constant', 'value': B, 'shape': B.shape, 'dtype': B.dtype}, 'd': {'vtype': 'constant', 'value': 4, 'Shape': (), 'dtype': 'int32'}} args = parse_dict(arg_dict, backend=b) # define valid test cases indexed_expressions = [("A[:]", A[:]), # single-dim indexing I ("A[0]", A[0]), # single-dim indexing II ("A[-2]", A[-2]), # single-dim indexing III ("A[0:5]", A[0:5]), # single-dim slicing I ("A[-1:0:-1]", A[-1:0:-1]), # single-dim slicing II ("A[4,5]", A[4, 5]), # two-dim indexing I ("A[5,0:-2]", A[5, 0:-2]), # two-dim indexing II ("A[A > 0.]", A[A > 0.]), # boolean indexing ("A[B]", A[B]), # indexing with other array ("A[d:8 - 1]", # using variables as indices A[4:8 - 1]), ] # test expression parsers on expression results for expr, target in indexed_expressions: # tensorflow-based parser p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6) # define invalid test cases indexed_expressions_wrong = ["A[1.2]", # indexing with float variables "A[all]", # indexing with undefined key words "A[-11]", # index out of bounds "A[0:5:2:1]", # too many arguments for slicing "A[-1::0:-1]", # wrong slicing syntax II ] # test expression parsers on expression results for expr in indexed_expressions_wrong: # tensorflow-based parser with pytest.raises((IndexError, ValueError, SyntaxError, TypeError, BaseException)): p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() # test indexing ability of numpy-based parser ############################################# # define backend b = NumpyBackend() args = parse_dict(arg_dict, backend=b) # test expression parsers on expression results for expr, target in indexed_expressions: p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result == pytest.approx(target, rel=1e-6) # test expression parsers on expression results for expr in indexed_expressions_wrong: with pytest.raises((IndexError, ValueError, SyntaxError, TypeError, BaseException)): p = ExpressionParser(expr_str=expr, args=args, backend=b) p.parse_expr() p.op.eval()
def test_1_4_expression_parser_logic_ops(): """Testing handling of logical operations by expression parsers: See Also -------- :class:`ExpressionParser`: Detailed documentation of expression parser attributes and methods. :class:`LambdaExpressionParser`: Documentation of a non-symbolic expression parser. """ # define test cases logic_expressions = ["4 == 4", # simple equals "4 != 5", # simple not-equals "4 < 5", # simple less "5 > 4", # simple larger "4 <= 4", # less equals I "4 <= 5", # less equals II "5 >= 5", # larger equals I "5 >= 4", # larger equals II ] # test expression parsers on expression results with tensforflow backend ######################################################################## # define backend b = TensorflowBackend() # correct expressions for expr in logic_expressions: p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.op.numpy() if hasattr(p.op, 'numpy') else p.op assert result # false logical expression expr = "5 >= 6" # tensorflow-based parser p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert not result # test expression parsers on expression results with numpy backend ################################################################## # define backend b = NumpyBackend() # correct expressions for expr in logic_expressions: # numpy-based parser p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert result # false logical expression expr = "5 >= 6" # tensorflow-based parser p = ExpressionParser(expr_str=expr, args={}, backend=b) p.parse_expr() result = p.rhs_eval.numpy() if hasattr(p.rhs_eval, 'numpy') else p.rhs_eval if hasattr(result, 'eval'): result = result.eval() assert not result