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**6
The 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**6
Since 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**6
This 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**6
Alternatively, 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=b2
In 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=f
Any 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->
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)=c
The 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