Next: FORTRAN compiler limitations
Up: Implementation
Previous: Controlling line breaking
Mathematica's output formats have only been implemented to translate expressions. As a result, it is not possible to produce assignment statements. Assign and related functions enable four categories of assignments.
The following example illustrates the inability of Mathematica's output forms to translate assignments.
In[4]:= expans = Expand[(b+c)^6]; In[5]:= FortranForm[a=expans] Out[5]//FortranForm= b**6 + 6*b**5*c + 15*b**4*c**2 + 20*b**3*c**3 + 15*b**2*c**4 + - 6*b*c**5 + c**6The result of the previous computation evaluates the expression expans and sets the symbol a to the result. In contrast what is required is to produce a translated assignment statement in FORTRAN without affecting the definition of the symbol. Other attempts, such as FortranForm[HoldForm[a=b]] also fail to give the desired result. Before proceeding, the previous definition must be cleared.
In[6]:= a=.;By specifying a lhs argument to our Assign function the desired assignment can be obtained.
In[7]:= FortranAssign[a,expans] Out[7]//OutputForm= a=b**6+6.d0*b**5*c+1.5d1*b**4*c**2+2.d1*b**3*c**3+1.5d1*b**2*c* & *4+6.d0*b*c**5+c**6Since FortranAssign has attribute HoldFirst, the definition of expans does not interfere with the assignment in the following example.
In[8]:= FortranAssign[expans,expans] Out[8]//OutputForm= expans=b**6+6.*b**5*c+15.*b**4*c**2+20.*b**3*c**3+15.*b**2*c* & *4+6.*b*c**5+c**6This enables us to use lhs names which would normally evaluate to expressions and maintain closer correspondence with our Mathematica definitions.
Another deficiency of FortranForm is that it does not always produce the desired results when applied to lists (in this case, no continuation lines).
In[9]:= Map[ FortranForm, {expans,expans} ] Out[9]//FortranForm= {b**6 + 6*b**5*c + 15*b**4*c**2 + 20*b**3*c**3 + 15*b**2*c**4 + 6*b*c**5 + c**6, b**6 + 6*b**5*c + 15*b**4*c**2 + 20*b**3*c**3 + 15*b**2*c**4 + 6*b*c**5 + c**6} In[10]:= FortranForm[{expans,expans}] Out[10]//FortranForm= List(b**6 + 6*b**5*c + 15*b**4*c**2 + 20*b**3*c**3 + 15*b**2*c**4 + - 6*b*c**5 + c**6,b**6 + 6*b**5*c + 15*b**4*c**2 + - 20*b**3*c**3 + 15*b**2*c**4 + 6*b*c**5 + c**6)With FortranAssign a sequence of array elements are assigned to when the lhs is a symbol or string and the rhs is a list.
In[11]:= FortranAssign[a,{expans,expans}] Out[11]//OutputForm= a(1)=b**6+6.d0*b**5*c+1.5d1*b**4*c**2+2.d1*b**3*c**3+1.5d1*b**2 & *c**4+6.d0*b*c**5+c**6 a(2)=b**6+6.d0*b**5*c+1.5d1*b**4*c**2+2.d1*b**3*c**3+1.5d1*b**2 & *c**4+6.d0*b*c**5+c**6Alternatively, different symbols can be assigned in a single statement, by constructing a list of lhs values.
In[12]:= lhs = {a1,a2}; In[13]:= rhs = {b1,b2}; In[14]:= FortranAssign[Evaluate[lhs],rhs] Out[14]//OutputForm= a1=b1 a2=b2In this way, a mixture of lists and symbols can be assigned to. The Assign functions automatically detect the type of the assigned object and generate an appropriate lhs, including array arguments if necessary. In this way blocks of assignments can be collected and issued simultaneously. Block assignments are more efficient than a sequence of single assignments since rewrite rules are generated only once and option type tests do not need to be repeated.
In[15]:= lhs = {a,b,c}; In[16]:= rhs = {d,{e1,e2},f}; In[17]:= FortranAssign[Evaluate[lhs],rhs] Out[17]//OutputForm= a=d b(1)=e1 b(2)=e2 c=fAny shape list can be assigned and the assignment variable assumes the appropriate index. Labels can also be attached to expressions along with terminating strings. Thus expressions can be separated by a carriage return as AssignEnd->n.
In[18]:= FortranAssign[a,{{ArcCos[w],x^(1/2)},{Exp[y],Log[z]}}, AssignLabel->55] Out[18]//OutputForm= 55 a(1,1)=acos(w) a(1,2)=sqrt(x) a(2,1)=exp(y) a(2,2)=log(z)Individual array elements can be assigned to by using the list assignment form.
In[19]:= FortranAssign[{a[2,3],a[3,2]},{b,c}] Out[19]//OutputForm= a(2,3)=b a(3,2)=cThe lhs may also be specified as a string or list of strings.
In[20]:= FortranAssign["a(2,1)",b+c d] Out[20]//OutputForm= a(2,1)=b+c*d
Jorge Romao