Format.m: C, FORTRAN77, Maple and TeX Code Generation Package


This package extends Mathematica's built-in format rules. Assignments to expressions and lists are now possible. The package adds definitions Assign, CAssign and FortranAssign and MapleAssign. Many shortcomings of the built-in formatting code have also been addressed, such as the limit on continuation lines in FORTRAN77 and assignments to Expressions. Code optimization is possible via the auxiliary function Experimental`OptimizeExpression and the option AssignOptimize. The options of Experimental`OptimizeExpression, such as OptimizationLevel, can also be passed to the Assign functions. The functions are primarily intended for use with the Splice command. When using Splice, the option FormatType->OutputForm should be specified. Interactive output within a Mathematica session is also possible (see also the AssignToFile option). All expressions are written as Strings. This enable more precise formatting of expressions, removing the need for text editing. Any Mathematica print form (e.g. TeXForm) can be specified as an argument of the Assign command.


To allow the package to work in Mathematica 10, first we need to make a few changes to Format.m:

  • Change BeginPackage["Format`", "Utilities`FilterOptions`"] to BeginPackage["Format`"].

  • Add FilterOptions[fun_, opts___] := Sequence@@FilterRules[{opts}, Options[fun]] right after Begin["Private`"].

Now load the package,

<&lt;Format.m

and use it to generate code:

expr = C3 (c - y) + 
   C3 (c + y) + ((1 + nu) (-1 + 2 nu) P (c - y) ArcTan[(-c + y)/
        x])/(π Y) + ((1 + nu) (-1 + 2 nu) P (c + 
        y) ArcTan[(c + y)/x])/(π Y) + ((-1 + nu) (1 + nu) P x Log[
       x^2 + (c - y)^2])/(π Y) + ((1 + nu) P (x - nu x) Log[
       x^2 + (c + y)^2])/(π Y);

FortranAssign["expr", expr, AssignReplace -&gt; {"log" -> "dlog"}, AssignOptimize -> False]

gives the following

        expr = C3*(c - y) + C3*(c + y) + (3.183098861837907d-1*(1.d0 + n
     &  u)*(-1.d0d0 + 2.d0*nu)*P*(c - y)*atan((-c + y)/x))/Y + (3.183098
     &  861837907d-1*(1.d0 + nu)*(-1.d0d0 + 2.d0*nu)*P*(c + y)*atan((c +
     &   y)/x))/Y + (3.183098861837907d-1*(-1.d0d0 + nu)*(1.d0 + nu)*P*x
     &  *dlog((c - y)**2 + x*x))/Y + (3.183098861837907d-1*(1.d0 + nu)*P
     &  *(x - nu*x)*dlog((c + y)**2 + x*x))/Y

We can also use automatic expression optimization, which changes the formula to an equivalent form that minimizes the number of arithmetic operations. For this it needs to use temporary variables, which I named tempXX here.

FortranAssign["expr", expr, AssignReplace -> {"log" -> "dlog"}, 
 "OptimizationSymbol" -> temp]

        temp1 = -y
        temp2 = c + temp1
        temp6 = 1.d0 + nu
        temp7 = 2.d0*nu
        temp8 = -1.d0d0 + temp7
        temp4 = c + y
        temp9 = 1/Y
        temp10 = 1/x
        temp20 = x*x
        expr = C3*temp2 + C3*temp4 + 3.183098861837907d-1*P*temp4*temp6*
     &  temp8*temp9*atan(temp10*temp4) + 3.183098861837907d-1*P*temp2*te
     &  mp6*temp8*temp9*atan(temp10*(-c + y)) + 3.183098861837907d-1*(-1
     &  .d0d0 + nu)*P*temp6*temp9*x*dlog(temp20 + temp2*temp2) + 3.18309
     &  8861837907d-1*P*temp6*temp9*(x - nu*x)*dlog(temp20 + temp4*temp4
     &  )