def test_case(): ob = FCodePrinter() x, x_, x__, y, X, X_, Y = symbols('x,x_,x__,y,X,X_,Y') assert fcode(exp(x_) + sin(x*y) + cos(X*Y)) == \ ' exp(x_) + sin(x*y) + cos(X__*Y_)' assert fcode(exp(x__) + 2*x*Y*X_**Rational(7, 2)) == \ ' 2*X_**(7.0d0/2.0d0)*Y*x + exp(x__)' assert fcode(exp(x_) + sin(x*y) + cos(X*Y), name_mangling=False) == \ ' exp(x_) + sin(x*y) + cos(X*Y)' assert fcode(x - cos(X), name_mangling=False) == ' x - cos(X)' assert ob.doprint(X * sin(x) + x_, assign_to='me') == ' me = X*sin(x_) + x__' assert ob.doprint(X * sin(x), assign_to='mu') == ' mu = X*sin(x_)' assert ob.doprint(x_, assign_to='ad') == ' ad = x__' n, m = symbols('n,m', integer=True) A = IndexedBase('A') x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', m) I = Idx('I', n) assert fcode( A[i, I] * x[I], assign_to=y[i], source_format='free') == ("do i = 1, m\n" " y(i) = 0\n" "end do\n" "do i = 1, m\n" " do I_ = 1, n\n" " y(i) = A(i, I_)*x(I_) + y(i)\n" " end do\n" "end do")
def test_free_form_comment_line(): printer = FCodePrinter({ 'source_format': 'free'}) lines = [ "! This is a long comment on a single line that must be wrapped properly to produce nice output"] expected = [ '! This is a long comment on a single line that must be wrapped properly', '! to produce nice output'] assert printer._wrap_fortran(lines) == expected
def test_free_form_comment_line(): printer = FCodePrinter({'source_format': 'free'}) lines = [ "! This is a long comment on a single line that must be wrapped properly to produce nice output"] expected = [ '! This is a long comment on a single line that must be wrapped properly', '! to produce nice output'] assert printer._wrap_fortran(lines) == expected
def render_as_module(definitions, name, declarations=(), printer_settings=None): """ Creates a ``Module`` instance and renders it as a string. This generates Fortran source code for a module with the correct ``use`` statements. Parameters ========== definitions : iterable Passed to :class:`sympy.codegen.fnodes.Module`. name : str Passed to :class:`sympy.codegen.fnodes.Module`. declarations : iterable Passed to :class:`sympy.codegen.fnodes.Module`. It will be extended with use statements, 'implicit none' and public list generated from ``definitions``. printer_settings : dict Passed to ``FCodePrinter`` (default: ``{'standard': 2003, 'source_format': 'free'}``). """ printer_settings = printer_settings or {'standard': 2003, 'source_format': 'free'} printer = FCodePrinter(printer_settings) dummy = Dummy() if isinstance(definitions, Module): raise ValueError("This function expects to construct a module on its own.") mod = Module(name, chain(declarations, [dummy]), definitions) fstr = printer.doprint(mod) module_use_str = ' %s\n' % ' \n'.join(['use %s, only: %s' % (k, ', '.join(v)) for k, v in printer.module_uses.items()]) module_use_str += ' implicit none\n' module_use_str += ' private\n' module_use_str += ' public %s\n' % ', '.join([str(node.name) for node in definitions if getattr(node, 'name', None)]) return fstr.replace(printer.doprint(dummy), module_use_str) return fstr
def test_case(): ob = FCodePrinter() x,x_,x__,y,X,X_,Y = symbols('x,x_,x__,y,X,X_,Y') assert fcode(exp(x_) + sin(x*y) + cos(X*Y)) == \ ' exp(x_) + sin(x*y) + cos(X__*Y_)' assert fcode(exp(x__) + 2*x*Y*X_**Rational(7, 2)) == \ ' 2*X_**(7.0d0/2.0d0)*Y*x + exp(x__)' assert fcode(exp(x_) + sin(x*y) + cos(X*Y), name_mangling=False) == \ ' exp(x_) + sin(x*y) + cos(X*Y)' assert fcode(x - cos(X), name_mangling=False) == ' x - cos(X)' assert ob.doprint(X*sin(x) + x_, assign_to='me') == ' me = X*sin(x_) + x__' assert ob.doprint(X*sin(x), assign_to='mu') == ' mu = X*sin(x_)' assert ob.doprint(x_, assign_to='ad') == ' ad = x__' n, m = symbols('n,m', integer=True) A = IndexedBase('A') x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', m) I = Idx('I', n) assert fcode(A[i, I]*x[I], assign_to=y[i], source_format='free') == ( "do i = 1, m\n" " y(i) = 0\n" "end do\n" "do i = 1, m\n" " do I_ = 1, n\n" " y(i) = A(i, I_)*x(I_) + y(i)\n" " end do\n" "end do" )
def test_case(): ob = FCodePrinter() x, x_, x__, y, X, X_, Y = symbols("x,x_,x__,y,X,X_,Y") assert (fcode(exp(x_) + sin(x * y) + cos(X * Y)) == " exp(x_) + sin(x*y) + cos(X__*Y_)") assert (fcode(exp(x__) + 2 * x * Y * X_**Rational(7, 2)) == " 2*X_**(7.0d0/2.0d0)*Y*x + exp(x__)") assert (fcode( exp(x_) + sin(x * y) + cos(X * Y), name_mangling=False) == " exp(x_) + sin(x*y) + cos(X*Y)") assert fcode(x - cos(X), name_mangling=False) == " x - cos(X)" assert ob.doprint(X * sin(x) + x_, assign_to="me") == " me = X*sin(x_) + x__" assert ob.doprint(X * sin(x), assign_to="mu") == " mu = X*sin(x_)" assert ob.doprint(x_, assign_to="ad") == " ad = x__" n, m = symbols("n,m", integer=True) A = IndexedBase("A") x = IndexedBase("x") y = IndexedBase("y") i = Idx("i", m) I = Idx("I", n) assert fcode( A[i, I] * x[I], assign_to=y[i], source_format="free") == ("do i = 1, m\n" " y(i) = 0\n" "end do\n" "do i = 1, m\n" " do I_ = 1, n\n" " y(i) = A(i, I_)*x(I_) + y(i)\n" " end do\n" "end do")
def test_loops(): from sympy import symbols i,j,n,m = symbols('i j n m', integer=True) A,x,y = symbols('A x y') A = Indexed(A)(Idx(i, m), Idx(j, n)) x = Indexed(x)(Idx(j, n)) y = Indexed(y)(Idx(i, m)) # human = False printer = FCodePrinter({ 'source_format': 'free', 'assign_to':y, 'human':0}) expected = ([], set([A, x, y, Idx(j, n), Idx(i, m)]), 'do i = 1, m\n do j = 1, n\n y(i) = A(i, j)*x(j)\n end do\nend do') code = printer.doprint(A*x) # assert expected == code # human = True printer = FCodePrinter({ 'source_format': 'free', 'assign_to':y, 'human':1}) expected = ( '! Not Fortran:\n' '! A(i, j)\n' '! i\n' '! j\n' '! x(j)\n' '! y(i)\n' 'do i = 1, m\n' ' do j = 1, n\n' ' y(i) = A(i, j)*x(j)\n' ' end do\n' 'end do' ) code = printer.doprint(A*x) assert expected == code
def test_indent(): codelines = ("subroutine test(a)\n" "integer :: a, i, j\n" "\n" "do\n" "do \n" "do j = 1, 5\n" "if (a>b) then\n" "if(b>0) then\n" "a = 3\n" "donot_indent_me = 2\n" "do_not_indent_me_either = 2\n" "ifIam_indented_something_went_wrong = 2\n" "if_I_am_indented_something_went_wrong = 2\n" "end should not be unindented here\n" "end if\n" "endif\n" "end do\n" "end do\n" "enddo\n" "end subroutine\n" "\n" "subroutine test2(a)\n" "integer :: a\n" "do\n" "a = a + 1\n" "end do \n" "end subroutine\n") expected = ("subroutine test(a)\n" "integer :: a, i, j\n" "\n" "do\n" " do \n" " do j = 1, 5\n" " if (a>b) then\n" " if(b>0) then\n" " a = 3\n" " donot_indent_me = 2\n" " do_not_indent_me_either = 2\n" " ifIam_indented_something_went_wrong = 2\n" " if_I_am_indented_something_went_wrong = 2\n" " end should not be unindented here\n" " end if\n" " endif\n" " end do\n" " end do\n" "enddo\n" "end subroutine\n" "\n" "subroutine test2(a)\n" "integer :: a\n" "do\n" " a = a + 1\n" "end do \n" "end subroutine\n") p = FCodePrinter({"source_format": "free"}) result = p.indent_code(codelines) assert result == expected
def test_wrap_fortran(): # "########################################################################" printer = FCodePrinter() lines = [ "C This is a long comment on a single line that must be wrapped properly to produce nice output", " this = is + a + long + and + nasty + fortran + statement + that * must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that * must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that * must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement(that)/must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement(that)/must + be + wrapped + properly", ] wrapped_lines = printer._wrap_fortran(lines) expected_lines = [ "C This is a long comment on a single line that must be wrapped", "C properly to produce nice output", " this = is + a + long + and + nasty + fortran + statement + that *", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that *", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that", " @ * must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that*", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that", " @ *must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement +", " @ that*must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that**", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that", " @ **must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement + that", " @ **must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement +", " @ that**must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement(that)/", " @ must + be + wrapped + properly", " this = is + a + long + and + nasty + fortran + statement(that)", " @ /must + be + wrapped + properly", ] for line in wrapped_lines: assert len(line) <= 72 for w, e in zip(wrapped_lines, expected_lines): assert w == e assert len(wrapped_lines) == len(expected_lines)
def test_indent(): codelines = ('subroutine test(a)\n' 'integer :: a, i, j\n' '\n' 'do\n' 'do \n' 'do j = 1, 5\n' 'if (a>b) then\n' 'if(b>0) then\n' 'a = 3\n' 'donot_indent_me = 2\n' 'do_not_indent_me_either = 2\n' 'ifIam_indented_something_went_wrong = 2\n' 'if_I_am_indented_something_went_wrong = 2\n' 'end should not be unindented here\n' 'end if\n' 'endif\n' 'end do\n' 'end do\n' 'enddo\n' 'end subroutine\n' '\n' 'subroutine test2(a)\n' 'integer :: a\n' 'do\n' 'a = a + 1\n' 'end do \n' 'end subroutine\n') expected = ('subroutine test(a)\n' 'integer :: a, i, j\n' '\n' 'do\n' ' do \n' ' do j = 1, 5\n' ' if (a>b) then\n' ' if(b>0) then\n' ' a = 3\n' ' donot_indent_me = 2\n' ' do_not_indent_me_either = 2\n' ' ifIam_indented_something_went_wrong = 2\n' ' if_I_am_indented_something_went_wrong = 2\n' ' end should not be unindented here\n' ' end if\n' ' endif\n' ' end do\n' ' end do\n' 'enddo\n' 'end subroutine\n' '\n' 'subroutine test2(a)\n' 'integer :: a\n' 'do\n' ' a = a + 1\n' 'end do \n' 'end subroutine\n') p = FCodePrinter({'source_format': 'free'}) result = p.indent_code(codelines) assert result == expected
def test_fcode_NumberSymbol(): p = FCodePrinter() assert fcode( Catalan ) == ' parameter (Catalan = 0.915965594177219d0)\n Catalan' assert fcode( EulerGamma ) == ' parameter (EulerGamma = 0.577215664901533d0)\n EulerGamma' assert fcode(E) == ' parameter (E = 2.71828182845905d0)\n E' assert fcode( GoldenRatio ) == ' parameter (GoldenRatio = 1.61803398874989d0)\n GoldenRatio' assert fcode(pi) == ' parameter (pi = 3.14159265358979d0)\n pi' assert fcode(pi, precision=5) == ' parameter (pi = 3.1416d0)\n pi' assert fcode(Catalan, human=False) == (set([ (Catalan, p._print(Catalan.evalf(15))) ]), set([]), ' Catalan') assert fcode(EulerGamma, human=False) == (set([ (EulerGamma, p._print(EulerGamma.evalf(15))) ]), set([]), ' EulerGamma') assert fcode(E, human=False) == (set([(E, p._print(E.evalf(15)))]), set([]), ' E') assert fcode(GoldenRatio, human=False) == (set([ (GoldenRatio, p._print(GoldenRatio.evalf(15))) ]), set([]), ' GoldenRatio') assert fcode(pi, human=False) == (set([(pi, p._print(pi.evalf(15)))]), set([]), ' pi') assert fcode(pi, precision=5, human=False) == (set([ (pi, p._print(pi.evalf(5))) ]), set([]), ' pi')
def __init__(self, openmp=True, **kwargs): """Initialize a Fortran code printer. The printer class, the name of the template, and the line continuation symbol will be set automatically. """ if openmp: add_templ = { 'tensor_prelude': _FORTRAN_OMP_PARALLEL_PRELUDE, 'tensor_finale': _FORTRAN_OMP_PARALLEL_FINALE, 'init_prelude': _FORTRAN_OMP_INIT_PRELUDE, 'init_finale': _FORTRAN_OMP_INIT_FINALE, 'term_prelude': _FORTRAN_OMP_TERM_PRELUDE, 'term_finale': _FORTRAN_OMP_TERM_FINALE, } else: add_templ = None super().__init__(FCodePrinter(settings={'source_format': 'free'}), lambda base, indices: base + ('' if len(indices) == 0 else '({})'.format(', '.join( i.index for i in indices))), line_cont='&', add_filters={ 'form_loop_beg': self._form_fortran_loop_beg, 'form_loop_end': self._form_fortran_loop_end, }, add_globals={'zero_literal': '0.0'}, add_templ=add_templ, **kwargs)
def test_fcode_NumberSymbol(): prec = 17 p = FCodePrinter() assert fcode( Catalan ) == " parameter (Catalan = %sd0)\n Catalan" % Catalan.evalf( prec) assert fcode( EulerGamma ) == " parameter (EulerGamma = %sd0)\n EulerGamma" % EulerGamma.evalf( prec) assert fcode(E) == " parameter (E = %sd0)\n E" % E.evalf(prec) assert fcode( GoldenRatio ) == " parameter (GoldenRatio = %sd0)\n GoldenRatio" % GoldenRatio.evalf( prec) assert fcode( pi) == " parameter (pi = %sd0)\n pi" % pi.evalf(prec) assert fcode( pi, precision=5) == " parameter (pi = %sd0)\n pi" % pi.evalf(5) assert fcode(Catalan, human=False) == ( set([(Catalan, p._print(Catalan.evalf(prec)))]), set([]), " Catalan", ) assert fcode(EulerGamma, human=False) == ( set([(EulerGamma, p._print(EulerGamma.evalf(prec)))]), set([]), " EulerGamma", ) assert fcode(E, human=False) == ( set([(E, p._print(E.evalf(prec)))]), set([]), " E", ) assert fcode(GoldenRatio, human=False) == ( set([(GoldenRatio, p._print(GoldenRatio.evalf(prec)))]), set([]), " GoldenRatio", ) assert fcode(pi, human=False) == ( set([(pi, p._print(pi.evalf(prec)))]), set([]), " pi", ) assert fcode(pi, precision=5, human=False) == ( set([(pi, p._print(pi.evalf(5)))]), set([]), " pi", )
def test_wrap_fortran_keep_d0(): printer = FCodePrinter() lines = [ ' this_variable_is_very_long_because_we_try_to_test_line_break=1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break = 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break = 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break = 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break = 10.0d0' ] expected = [ ' this_variable_is_very_long_because_we_try_to_test_line_break=1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =', ' @ 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =', ' @ 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =', ' @ 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =', ' @ 1.0d0', ' this_variable_is_very_long_because_we_try_to_test_line_break =', ' @ 10.0d0' ] assert printer._wrap_fortran(lines) == expected
def test_fcode_NumberSymbol(): p = FCodePrinter() assert fcode(Catalan) == ' parameter (Catalan = 0.915965594177219d0)\n Catalan' assert fcode(EulerGamma) == ' parameter (EulerGamma = 0.577215664901533d0)\n EulerGamma' assert fcode(E) == ' parameter (E = 2.71828182845905d0)\n E' assert fcode(GoldenRatio) == ' parameter (GoldenRatio = 1.61803398874989d0)\n GoldenRatio' assert fcode(pi) == ' parameter (pi = 3.14159265358979d0)\n pi' assert fcode(pi,precision=5) == ' parameter (pi = 3.1416d0)\n pi' assert fcode(Catalan,human=False) == (set([(Catalan, p._print(Catalan.evalf(15)))]), set([]), ' Catalan') assert fcode(EulerGamma,human=False) == (set([(EulerGamma, p._print(EulerGamma.evalf(15)))]), set([]), ' EulerGamma') assert fcode(E,human=False) == (set([(E, p._print(E.evalf(15)))]), set([]), ' E') assert fcode(GoldenRatio,human=False) == (set([(GoldenRatio, p._print(GoldenRatio.evalf(15)))]), set([]), ' GoldenRatio') assert fcode(pi,human=False) == (set([(pi, p._print(pi.evalf(15)))]), set([]), ' pi') assert fcode(pi,precision=5,human=False) == (set([(pi, p._print(pi.evalf(5)))]), set([]), ' pi')
def test_fcode_NumberSymbol(): prec = 17 p = FCodePrinter() assert fcode(Catalan) == ' parameter (Catalan = %sd0)\n Catalan' % Catalan.evalf(prec) assert fcode(EulerGamma) == ' parameter (EulerGamma = %sd0)\n EulerGamma' % EulerGamma.evalf(prec) assert fcode(E) == ' parameter (E = %sd0)\n E' % E.evalf(prec) assert fcode(GoldenRatio) == ' parameter (GoldenRatio = %sd0)\n GoldenRatio' % GoldenRatio.evalf(prec) assert fcode(pi) == ' parameter (pi = %sd0)\n pi' % pi.evalf(prec) assert fcode( pi, precision=5) == ' parameter (pi = %sd0)\n pi' % pi.evalf(5) assert fcode(Catalan, human=False) == (set( [(Catalan, p._print(Catalan.evalf(prec)))]), set([]), ' Catalan') assert fcode(EulerGamma, human=False) == (set([(EulerGamma, p._print( EulerGamma.evalf(prec)))]), set([]), ' EulerGamma') assert fcode(E, human=False) == ( set([(E, p._print(E.evalf(prec)))]), set([]), ' E') assert fcode(GoldenRatio, human=False) == (set([(GoldenRatio, p._print( GoldenRatio.evalf(prec)))]), set([]), ' GoldenRatio') assert fcode(pi, human=False) == ( set([(pi, p._print(pi.evalf(prec)))]), set([]), ' pi') assert fcode(pi, precision=5, human=False) == ( set([(pi, p._print(pi.evalf(5)))]), set([]), ' pi')
def _indent_code(self, codelines): p = FCodePrinter({'source_format': 'free', 'human': False}) return p.indent_code(codelines)
def test_indent(): codelines = ( 'subroutine test(a)\n' 'integer :: a, i, j\n' '\n' 'do\n' 'do \n' 'do j = 1, 5\n' 'if (a>b) then\n' 'if(b>0) then\n' 'a = 3\n' 'donot_indent_me = 2\n' 'do_not_indent_me_either = 2\n' 'ifIam_indented_something_went_wrong = 2\n' 'if_I_am_indented_something_went_wrong = 2\n' 'end should not be unindented here\n' 'end if\n' 'endif\n' 'end do\n' 'end do\n' 'enddo\n' 'end subroutine\n' '\n' 'subroutine test2(a)\n' 'integer :: a\n' 'do\n' 'a = a + 1\n' 'end do \n' 'end subroutine\n' ) expected = ( 'subroutine test(a)\n' 'integer :: a, i, j\n' '\n' 'do\n' ' do \n' ' do j = 1, 5\n' ' if (a>b) then\n' ' if(b>0) then\n' ' a = 3\n' ' donot_indent_me = 2\n' ' do_not_indent_me_either = 2\n' ' ifIam_indented_something_went_wrong = 2\n' ' if_I_am_indented_something_went_wrong = 2\n' ' end should not be unindented here\n' ' end if\n' ' endif\n' ' end do\n' ' end do\n' 'enddo\n' 'end subroutine\n' '\n' 'subroutine test2(a)\n' 'integer :: a\n' 'do\n' ' a = a + 1\n' 'end do \n' 'end subroutine\n' ) p = FCodePrinter({'source_format': 'free'}) result = p.indent_code(codelines) assert result == expected
def _print_Indexed(self, expr): return FCodePrinter._print_Indexed(self, expr)