next up previous contents
Next: String manipulation Up: Implementation Previous: Converting powers

Array and sign conversion

There is nothing to distinguish between arrays and functions in Mathematica. Array and function arguments may therefore not be handled appropriately when translating expressions. Assign and related functions enable arrays and functions to be distinguished.

On an alternative note, the internal representation of a symbolic expression is often translated verbatim and this can lead to inefficiencies. An example is negation. Mathematica stores the expression -x internally as Times[-1,x]. The following expression is translated into appropriate form in FORTRAN.

In[4]:= FortranForm[ -x ]
Out[4]//FortranForm= -x
However, the function N is often applied to obtain numerical approximants, and convert constants, often simplifies results. This is not accounted for by Mathematica's formatting functions.

In[5]:= FortranForm[ N[a[1] - b[1]] ]

Out[5]//FortranForm= a(1.) - 1.*b(1.)
Two issues are raised here. There is a need for some method of protecting array or function arguments from numerical approximation. We also have to overcome the display of N[-x] as -1.*x, which results in unnecessary multiplication. A partial fix is to explicitly use NProtectedAll to protect specified arguments from N.

In[6]:= SetAttributes[{a,b},NProtectedAll];

In[7]:= FortranForm[a[1] - b[1]] //N

Out[7]//FortranForm= a(1) - 1.*b(1)
These attributes remain unless they are cleared.
In[8]:= Attributes[{a,b}]

Out[8]= {{NProtectedAll}, {NProtectedAll}}
Array conversion in the Assign functions is handled using the option AssignToArray. Conversion to the negative sign is accomplished by using a pattern matching rule to recover expressions of the form Times[-1.,$\_\_$].
In[9]:= ClearAttributes[{a,b},NProtectedAll];

In[10]:= FortranAssign[a[1] - b[1], AssignToArray->{a,b},
         AssignIndent->""]

Out[10]//OutputForm= a(1)-b(1)
Any attributes given to symbols by Assign functions are removed before execution is completed.
In[11]:= Attributes[{a,b}]

Out[11]= {{}, {}}
As illustrated above, when an array is specified explicitly using AssignToArray, it is exempt from the test for ANSI compatible functions.

A final example illustrates how functions with mixed argument types can be constructed and translated. These are neither arrays (integer indexed functions) nor real argument functions. The first step is to protect arguments from N.

In[12]:= SetAttributes[m,NProtectedAll];
The next step is to override the rule for specific cases. This can be done by specifying how arguments should be evaluated when N is applied.
In[13]:= m/: N[m[i_,r_,j_],prec___]:= m[i,N[r,prec],j] /; Head[r]=!=Real;
The pattern condition is needed to avoid infinite recursion, because of the infinite evaluation model that Mathematica uses. Here is an example of how this works. First the warning message for non-ANSI functions is suppressed.
In[14]:= Off[AssignFunction::undef];
In[15]:= FortranAssign[ 2 m[1,3/4,2] ]

Out[15]//OutputForm=
        2.d0*m(1,7.5d-1,2)


next up previous contents
Next: String manipulation Up: Implementation Previous: Converting powers

Jorge Romao
5/14/1998