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
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;', ])
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)' )
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
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
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;",] )
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 == ""
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 == ''
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
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 == ""
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;', ])
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))
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)'