Next: FORTRAN compiler limitations Up: Implementation Previous: Controlling line breaking

Assignments to expressions

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.

  1. Translation of an expression or list of expressions (lhs omitted or Null assignment).
  2. Assignment of an expression to a symbol (or string).
  3. Array assignment. Assignment of a list of expressions (rhs) to a symbol (lhs) resulting in a sequence of assignments to an array. The array index is determined by the shape of the array.
  4. Assignment of a list of expressions to a list of symbols - the lhs and rhs lists must have the same length, but can contain a mixture of lists and symbols.
If the lhs is a list, it may not contain sublists (it must pass the test VectorQ).

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->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)=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


bondaren@thsun1.jinr.ru