Next: Conversion to Maple
Up: Implementation
Previous: FORTRAN compiler limitations
Array indices in C start from zero. The option AssignIndex may be used to modify the starting index of arrays. Here is the default behaviour.
In[4]:= CAssign[a,{{x1,x2},{x3,x4}}] Out[4]//OutputForm= a[0][0]=x1; a[0][1]=x2; a[1][0]=x3; a[1][1]=x4;Each statement is terminated using a semi-colon via the option AssignEnd.
Powers in C are converted according to the following rules:
In[5]:= CAssign[x^5-1/Sqrt[y]+z^(3/2)] Out[5]//OutputForm= pow(x,5.)+pow(z,3./2.)-1./sqrt(y);An array in Mathematica CForm can thus be incorrectly converted into a C function.
In[6]:= expr = Expand[(ArcCos[a[1]]-Sin[b[1]])^2]; In[7]:= CForm[expr] Out[7]//CForm= Power(ArcCos(a(1)),2) - 2*ArcCos(a(1))*Sin(b(1)) + Power(Sin(b(1)),2)CForm actually converts Part to an array. In this example, the list a needs to be wrapped in HoldForm to prevent an evaluation warning message.
In[8]:= CForm[ HoldForm[ a[[3,2]] ] ] Out[8]//CForm= a[3][2] In[9]:= CForm[ a[[3,2]] ] Part::partd: Part specification a[[3,2]] is longer than depth of object. Out[9]//CForm= a[3][2]What is actually required is to convert Mathematica arrays to C arrays. Since there is no distinction for arrays in Mathematica, it is not possible to perform this conversion automatically. Instead this is left up to the user via the option AssignToArray.
In[10]:= CAssign[expr,expr,AssignToArray->{a,b}] Out[10]//OutputForm= expr=pow(acos(a[1]),2.)+pow(sin(b[1]),2.)-2.*acos(a[1])*sin(b[1]);Notice the line continuation character which is added.
Since the lhs may be specified as a string, assignment to array elements in C is possible.
In[11]:= CAssign["a[2][1]",Exp[b+ArcTan[c]]] Out[11]//OutputForm= a[2][1]=exp(b+atan(c));When arrays are initialised in C, array elements that are not formally defined are defaulted to zero by a compiler [10]. Therefore, for the purposes of efficiency, it is desirable to remove unnecessary assignments and have them assigned by the compiler.
In[12]:= CAssign[a,{{0,b},{c,0}},AssignZero->False] Out[12]//OutputForm= a[0][1]=b; a[1][0]=c;Notice how the array indices correspond to the input.
There is a potential conflict with this option, when all assignments are zero-valued. In such a case, assignments to zeros are performed and an appropriate warning message is output.
In[13]:= CAssign[a,{0,0},AssignZero->False] AssignZero::continue: Expression encountered with no non-zero elements. Continuing with zero assignments. Out[13]//OutputForm= a[0]=0; a[1]=0;In some cases, C statement delimiters may not be required. For example if an expression is translated for use inside an if statement.
In[14]:= CAssign[a<=6||a>=-6,AssignEnd->""] Out[14]//OutputForm= a<=6.||a>=-6.Although C compiler impose no restriction on the number of lines a single expression may occupy, it is often useful to break up large expressions for debugging purposes etc. The default for C is to generate an array of temporary variables t[1], t[2], etc. The global symbol AssignTemporaryIndex specifies the number of temporary variables introduced during each call to an Assign function.
Long expressions are broken up using the backslash character
. This is a
preprocessor command which allows even token (the fundamental building blocks of C) to be
broken up [10, section 2.1.2].
When writing C code, it is often useful to control the precision of data types in the following manner.
Jorge Romao