예제 #1
0
파일: test_ast.py 프로젝트: Lenqth/sympy
def test_Print():
    fmt = "%d %.3f"
    ps = Print([n, x], fmt)
    assert str(ps.format_string) == fmt
    assert ps.print_args == Tuple(n, x)
    assert ps.args == (Tuple(n, x), QuotedString(fmt), none)
    assert ps == Print((n, x), fmt)
    assert ps != Print([x, n], fmt)
    assert ps.func(*ps.args) == ps

    ps2 = Print([n, x])
    assert ps2 == Print([n, x])
    assert ps2 != ps
    assert ps2.format_string == None
예제 #2
0
def test_ccode_codegen_ast():
    assert ccode(Comment("this is a comment")) == "// this is a comment"
    assert ccode(While(abs(x) > 1,
                       [aug_assign(x, '-', 1)])) == ('while (fabs(x) > 1) {\n'
                                                     '   x -= 1;\n'
                                                     '}')
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ('{\n'
                                                            '   x += 1;\n'
                                                            '}')
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, 'pwer',
                                   [inp_x])) == 'double pwer(double x)'
    assert ccode(
        FunctionDefinition(
            real, 'pwer', [inp_x],
            [Assignment(x, x**2)])) == ('double pwer(double x){\n'
                                        '   x = pow(x, 2);\n'
                                        '}')

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(
        x,
        Print([x, y], "%d %d"),
        FunctionCall('pwer', [x]),
        Return(x),
    )
    assert ccode(block) == '\n'.join([
        'x;',
        'printf("%d %d", x, y);',
        'pwer(x);',
        'return x;',
    ])
예제 #3
0
def test_standard():
    ast = Print("x y".split(), "coordinate: %12.5g %12.5g")
    assert (render_as_module(ast, standard="python3") ==
            '\n\nprint("coordinate: %12.5g %12.5g" % (x, y))')
    assert (render_as_module(
        ast,
        standard="python2") == '\n\nprint "coordinate: %12.5g %12.5g" % (x, y)'
            )
예제 #4
0
def test_Program():
    x = Symbol('x', real=True)
    vx = Variable.deduced(x, 42)
    decl = Declaration(vx)
    prnt = Print([x, x+1])
    prog = Program('foo', [decl, prnt])
    if not has_fortran():
        skip("No fortran compiler found.")

    (stdout, stderr), info = compile_run_strings([('main.f90', fcode(prog, standard=90))], clean=True)
    assert '42' in stdout
    assert '43' in stdout
    assert stderr == ''
    assert info['exit_status'] == os.EX_OK
예제 #5
0
def test_Program():
    x = Symbol("x", real=True)
    vx = Variable.deduced(x, 42)
    decl = Declaration(vx)
    prnt = Print([x, x + 1])
    prog = Program("foo", [decl, prnt])
    if not has_fortran():
        skip("No fortran compiler found.")

    (stdout, stderr), info = compile_run_strings(
        [("main.f90", fcode(prog, standard=90))], clean=True)
    assert "42" in stdout
    assert "43" in stdout
    assert stderr == ""
    assert info["exit_status"] == os.EX_OK
예제 #6
0
def test_Print():
    fmt = "%d %.3f"
    ps = Print([n, x], fmt)
    assert str(ps.format_string) == fmt
    assert ps.print_args == Tuple(n, x)
    assert ps.args == (Tuple(n, x), QuotedString(fmt), none)
    assert ps == Print((n, x), fmt)
    assert ps != Print([x, n], fmt)
    assert ps.func(*ps.args) == ps

    ps2 = Print([n, x])
    assert ps2 == Print([n, x])
    assert ps2 != ps
    assert ps2.format_string == None
예제 #7
0
def test_ccode_codegen_ast():
    assert ccode(Comment("this is a comment")) == "// this is a comment"
    assert ccode(While(abs(x) > 1, [aug_assign(x, "-", 1)])) == (
        "while (fabs(x) > 1) {\n" "   x -= 1;\n" "}"
    )
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ("{\n" "   x += 1;\n" "}")
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, "pwer", [inp_x])) == "double pwer(double x)"
    assert ccode(
        FunctionDefinition(real, "pwer", [inp_x], [Assignment(x, x ** 2)])
    ) == ("double pwer(double x){\n" "   x = pow(x, 2);\n" "}")

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(x, Print([x, y], "%d %d"), FunctionCall("pwer", [x]), Return(x),)
    assert ccode(block) == "\n".join(
        ["x;", 'printf("%d %d", x, y);', "pwer(x);", "return x;",]
    )
예제 #8
0
def test_Subroutine():
    # Code to generate the subroutine in the example from
    # http://www.fortran90.org/src/best-practices.html#arrays
    r = Symbol("r", real=True)
    i = Symbol("i", integer=True)
    v_r = Variable.deduced(r, attrs=(dimension(assumed_extent), intent_out))
    v_i = Variable.deduced(i)
    v_n = Variable("n", integer)
    do_loop = Do([Assignment(Element(r, [i]),
                             literal_dp(1) / i**2)], i, 1, v_n)
    sub = Subroutine(
        "f",
        [v_r],
        [
            Declaration(v_n),
            Declaration(v_i),
            Assignment(v_n, size(r)), do_loop
        ],
    )
    x = Symbol("x", real=True)
    v_x3 = Variable.deduced(x, attrs=[dimension(3)])
    mod = Module("mymod", definitions=[sub])
    prog = Program(
        "foo",
        [
            use(mod, only=[sub]),
            Declaration(v_x3),
            SubroutineCall(sub, [v_x3]),
            Print([sum_(v_x3), v_x3]),
        ],
    )

    if not has_fortran():
        skip("No fortran compiler found.")

    (stdout, stderr), info = compile_run_strings(
        [("a.f90", fcode(mod, standard=90)),
         ("b.f90", fcode(prog, standard=90))],
        clean=True,
    )
    ref = [1.0 / i**2 for i in range(1, 4)]
    assert str(sum(ref))[:-3] in stdout
    for _ in ref:
        assert str(_)[:-3] in stdout
    assert stderr == ""
예제 #9
0
def test_Module():
    x = Symbol('x', real=True)
    v_x = Variable.deduced(x)
    sq = FunctionDefinition(real, 'sqr', [v_x], [Return(x**2)])
    mod_sq = Module('mod_sq', [], [sq])
    sq_call = FunctionCall('sqr', [42.])
    prg_sq = Program(
        'foobar',
        [use('mod_sq', only=['sqr']),
         Print(['"Square of 42 = "', sq_call])])
    if not has_fortran():
        skip("No fortran compiler found.")
    (stdout, stderr), info = compile_run_strings(
        [('mod_sq.f90', fcode(mod_sq, standard=90)),
         ('main.f90', fcode(prg_sq, standard=90))],
        clean=True)
    assert '42' in stdout
    assert str(42**2) in stdout
    assert stderr == ''
예제 #10
0
def test_ImpliedDoLoop():
    if not has_fortran():
        skip("No fortran compiler found.")

    a, i = symbols('a i', integer=True)
    idl = ImpliedDoLoop(i**3, i, -3, 3, 2)
    ac = ArrayConstructor([-28, idl, 28])
    a = array(a, dim=[':'], attrs=[allocatable])
    prog = Program(
        'idlprog',
        [a.as_Declaration(), Assignment(a, ac),
         Print([a])])
    fsrc = fcode(prog, standard=2003, source_format='free')
    (stdout, stderr), info = compile_run_strings([('main.f90', fsrc)],
                                                 clean=True)
    for numstr in '-28 -27 -1 1 27 28'.split():
        assert numstr in stdout
    assert stderr == ''
    assert info['exit_status'] == os.EX_OK
예제 #11
0
def test_Module():
    x = Symbol("x", real=True)
    v_x = Variable.deduced(x)
    sq = FunctionDefinition(real, "sqr", [v_x], [Return(x**2)])
    mod_sq = Module("mod_sq", [], [sq])
    sq_call = FunctionCall("sqr", [42.0])
    prg_sq = Program(
        "foobar",
        [use("mod_sq", only=["sqr"]),
         Print(['"Square of 42 = "', sq_call])])
    if not has_fortran():
        skip("No fortran compiler found.")
    (stdout, stderr), info = compile_run_strings(
        [
            ("mod_sq.f90", fcode(mod_sq, standard=90)),
            ("main.f90", fcode(prg_sq, standard=90)),
        ],
        clean=True,
    )
    assert "42" in stdout
    assert str(42**2) in stdout
    assert stderr == ""
예제 #12
0
def test_ccode_codegen_ast():
    # Note that C only allows comments of the form /* ... */, double forward
    # slash is not standard C, and some C compilers will grind to a halt upon
    # encountering them.
    assert ccode(
        Comment("this is a comment")) == "/* this is a comment */"  # not //
    assert ccode(While(abs(x) > 1,
                       [aug_assign(x, '-', 1)])) == ('while (fabs(x) > 1) {\n'
                                                     '   x -= 1;\n'
                                                     '}')
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ('{\n'
                                                            '   x += 1;\n'
                                                            '}')
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, 'pwer',
                                   [inp_x])) == 'double pwer(double x)'
    assert ccode(
        FunctionDefinition(
            real, 'pwer', [inp_x],
            [Assignment(x, x**2)])) == ('double pwer(double x){\n'
                                        '   x = pow(x, 2);\n'
                                        '}')

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(
        x,
        Print([x, y], "%d %d"),
        FunctionCall('pwer', [x]),
        Return(x),
    )
    assert ccode(block) == '\n'.join([
        'x;',
        'printf("%d %d", x, y);',
        'pwer(x);',
        'return x;',
    ])
예제 #13
0
def newtons_method(expr,
                   wrt,
                   atol=1e-12,
                   delta=None,
                   debug=False,
                   itermax=None,
                   counter=None):
    """ Generates an AST for Newton-Raphson method (a root-finding algorithm).

    Returns an abstract syntax tree (AST) based on ``sympy.codegen.ast`` for Netwon's
    method of root-finding.

    Parameters
    ==========

    expr : expression
    wrt : Symbol
        With respect to, i.e. what is the variable.
    atol : number or expr
        Absolute tolerance (stopping criterion)
    delta : Symbol
        Will be a ``Dummy`` if ``None``.
    debug : bool
        Whether to print convergence information during iterations
    itermax : number or expr
        Maximum number of iterations.
    counter : Symbol
        Will be a ``Dummy`` if ``None``.

    Examples
    ========

    >>> from sympy import symbols, cos
    >>> from sympy.codegen.ast import Assignment
    >>> from sympy.codegen.algorithms import newtons_method
    >>> x, dx, atol = symbols('x dx atol')
    >>> expr = cos(x) - x**3
    >>> algo = newtons_method(expr, x, atol, dx)
    >>> algo.has(Assignment(dx, -expr/expr.diff(x)))
    True

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Newton%27s_method

    """

    if delta is None:
        delta = Dummy()
        Wrapper = Scope
        name_d = 'delta'
    else:
        Wrapper = lambda x: x
        name_d = delta.name

    delta_expr = -expr / expr.diff(wrt)
    whl_bdy = [
        Assignment(delta, delta_expr),
        AddAugmentedAssignment(wrt, delta)
    ]
    if debug:
        prnt = Print([wrt, delta],
                     r"{}=%12.5g {}=%12.5g\n".format(wrt.name, name_d))
        whl_bdy = [whl_bdy[0], prnt] + whl_bdy[1:]
    req = Gt(Abs(delta), atol)
    declars = [Declaration(Variable(delta, type=real, value=oo))]
    if itermax is not None:
        counter = counter or Dummy(integer=True)
        v_counter = Variable.deduced(counter, 0)
        declars.append(Declaration(v_counter))
        whl_bdy.append(AddAugmentedAssignment(counter, 1))
        req = And(req, Lt(counter, itermax))
    whl = While(req, CodeBlock(*whl_bdy))
    blck = declars + [whl]
    return Wrapper(CodeBlock(*blck))
예제 #14
0
def test_standard():
    ast = Print('x y'.split(), "coordinate: %12.5g %12.5g")
    assert render_as_module(ast, standard='python3') == \
        '\n\nprint("coordinate: %12.5g %12.5g" % (x, y))'
    assert render_as_module(ast, standard='python2') == \
        '\n\nprint "coordinate: %12.5g %12.5g" % (x, y)'