The CodeGeneration Package - Maple Help

Home : Support : Online Help : Applications and Example Worksheets : Connectivity : examples/CodeGeneration

The CodeGeneration Package

The CodeGeneration package is a collection of functions that translate Maple code to other languages. This worksheet provides several simple examples to get you started with CodeGeneration.

Additional information and examples can be found in the help pages for the package and for the individual package members. The Code Generation Assistant also offers a convenient interface to code generation tools.



Introduction

The following command allows you to use the short form of the function names in the CodeGeneration package. The  functions C, CSharp, Fortran, Java, JavaScript, Matlab, Perl, Python, R, and VisualBasic provide translation to the programming languages implied by their names.

 > $\mathrm{with}\left(\mathrm{CodeGeneration}\right):$

With the CodeGeneration package, you can translate an expression, a list of equations representing a computation sequence, a procedure, or a module to any of the target languages.

 • Expressions are translated into assignments to variables with automatically generated names.
 • Lists of equations are translated into a sequence of assignments.
 • Procedures and modules are translated into their equivalent in the target language.

 > $\mathrm{Java}\left({ⅇ}^{x+y}\right)$
 cg = Math.exp(x + y);
 > $\mathrm{JavaScript}\left(x\cdot {ⅇ}^{x}\right)$
 cg0 = x * Math.exp(x);

 > $C\left(\left[x=2,y=x+z,z=xy+5\right]\right)$
 x = 2; y = x + z;z = x * y + 5;

 >
 x = -1; y = 2 * z;z = x + 1;

 > $\mathrm{VisualBasic}\left(\left[x=1,y=x+z,z=y+5\cdot x\right]\right)$
 x = 1 y = x + zz = y + 5 * x

 >
 > $\mathrm{Perl}\left(f\right)$
 #!/usr/bin/perl sub f{  local($u,$v) = @_;  return($u *$v + $u -$v);}

 > $\mathrm{Python}\left(f\right)$
 def f (u, v):     return(u * v + u - v)

 > $\mathrm{Matlab}\left(\left[\begin{array}{cc}15.0& x\\ -2.5& y\end{array}\right]\right)$
 cg1 = [0.150e2 x; -0.25e1 y;];

 > $R\left(\left[\begin{array}{cc}15.0& 4.2\\ -2.5& -1.0\end{array}\right]\right)$
 cg2 <- matrix(c(0.150e2,-0.25e1,0.42e1,-0.10e1),nrow=2,ncol=2)

The CodeGeneration package can translate only a subset of the Maple language. Limitations and special features of the individual target languages are described on the detail pages for each target (for example, CDetails).



Options for Customizing the Output

There are fundamental differences between the Maple language and the target languages supported by CodeGeneration that make direct translation difficult in some cases. For example, Maple is an interpreted language; it has a rich set of types, and allows implicit returns. The target languages support a more limited set of basic types and require variable and return types to be known at compile time.

As a consequence of these differences, the CodeGeneration functions are often required to choose the most suitable translation in cases where more than one result is possible. Occasionally, the choices made may not be the ones expected or desired. However, there are a number of options that you can use to customize the output. Options common to all the CodeGeneration functions are described on the CodeGenerationOptions help page.

Controlling Type Translation

In the following example, all the parameters are assigned a floating-point type by default.

 > $\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}C\left(f\right)$
 double f (double x, double y, double z){  return(x * y - y * z + x * z);}

The default type given to untyped variables can be changed by using the defaulttype option.

 > $C\left(f,\mathrm{defaulttype}=\mathrm{integer}\right)$
 int f (int x, int y, int z) {  return(x * y - y * z + x * z);}

CodeGeneration attempts to deduce the types of untyped variables. The default type is given only to those variables left untyped after the automatic type deduction process. In the following example, the parameters y and z are given a floating-point type because they are in an expression involving the float variable x. Thus, the default type, integer, is not assigned.

 > $C\left(f,\mathrm{defaulttype}=\mathrm{integer}\right)$
 double f (double x, double y, double z){  return(x * y - y * z + x * z);}

You can turn off the automatic type deduction system by using the deducetypes=false option. In the following example, parameters y and z are now given the default type.

 > $C\left(f,\mathrm{defaulttype}=\mathrm{integer},\mathrm{deducetypes}=\mathrm{false}\right)$
 double f (double x, int y, int z) {  return(x * (double) y - (double) (y * z) + x * (double) z);}

You can turn off explicit type coercion using the coercetypes=false option.

 > $C\left(f,\mathrm{defaulttype}=\mathrm{integer},\mathrm{deducetypes}=\mathrm{false},\mathrm{coercetypes}=\mathrm{false}\right)$
 double f (double x, int y, int z) {  return(x * y - y * z + x * z);}

You can obtain more control over how types are assigned by declaring the parameter, local variable, and return types explicitly in procedures or by using the declare option with expressions.

 > $C\left(1+x+y,\mathrm{declare}=\left[x::\mathrm{float},y::\mathrm{integer}\right]\right)$
 cg3 = 0.1e1 + x + (double) y;
 > 

Other Commonly Used Options

In the following example, the optimize option specifies that the computation sequence should be optimized before translation to Java.

 > $\mathrm{cs}:=\left[s=1.0+x,t=\mathrm{ln}\left(x\right){ⅇ}^{-x},r={ⅇ}^{-x}+xt\right]:$$\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\mathrm{Java}\left(\mathrm{cs},\mathrm{optimize}\right)$
 s = 0.10e1 + x;t1 = Math.log(x);t2 = Math.exp(-x);t = t1 * t2;r = x * t + t2;

The CodeGeneration functions normally print the formatted results. You can use the output=string option to specify that a string containing the result should be returned. The output option can also be used to print the result to a file.

 > $s:=\mathrm{Java}\left(\mathrm{log}\left(x\right)+\mathrm{sin}\left(y\right),\mathrm{output}=\mathrm{string}\right)$
 ${s}{:=}{"cg4 = Math.log\left(x\right) + Math.sin\left(y\right);"}$ (2.2.1)
 > $s≔\mathrm{JavaScript}\left(\mathrm{log}\left(x\right)+\mathrm{sin}\left(y\right),\mathrm{output}=\mathrm{string}\right)$
 ${s}{:=}{"cg5 = Math.log\left(x\right) + Math.sin\left(y\right);"}$ (2.2.2)

There are many other options not described here. For information about the available options, refer to the CodeGenerationOptions help page.

Using CodeGeneration with Other Maple Functions

By combining the CodeGeneration functions with other Maple functions, you can easily generate substantial pieces of C, Fortran, Java, Matlab, or R code to solve specific problems. Several examples are given below. Note that to translate Maple commands directly into commands in a target language, it is necessary in some cases to use unevaluation quotes ( ' ' ) to surround the command. If the unevaluation quotes are not used, the result of running the Maple command on the argument is translated.

A Spline Example

Use the CurveFitting[Spline] function to fit a natural cubic spline through a given list of points.

 > $s≔\mathrm{CurveFitting}\left[\mathrm{Spline}\right]\left(\left[\left[0,0\right],\left[1,1\right],\left[2,4\right],\left[3,3\right],\left[4,2\right]\right],v\right)$
 ${s}{:=}{{}\begin{array}{cc}\frac{{23}}{{28}}{}{{v}}^{{3}}{+}\frac{{5}}{{28}}{}{v}& {v}{<}{1}\\ {-}\frac{{59}}{{28}}{}{{v}}^{{3}}{+}\frac{{123}}{{14}}{}{{v}}^{{2}}{-}\frac{{241}}{{28}}{}{v}{+}\frac{{41}}{{14}}& {v}{<}{2}\\ \frac{{45}}{{28}}{}{{v}}^{{3}}{-}\frac{{27}}{{2}}{}{{v}}^{{2}}{+}\frac{{1007}}{{28}}{}{v}{-}\frac{{375}}{{14}}& {v}{<}{3}\\ {-}\frac{{9}}{{28}}{}{{v}}^{{3}}{+}\frac{{27}}{{7}}{}{{v}}^{{2}}{-}\frac{{451}}{{28}}{}{v}{+}\frac{{177}}{{7}}& {\mathrm{otherwise}}\end{array}$ (3.1.1)

Turn the resulting expression, a piecewise function, into a procedure by using the unapply function.

 > $p≔\mathrm{unapply}\left(s,v\right)$
 ${p}{:=}{v}{→}{\mathrm{piecewise}}{}\left({v}{<}{1}{,}\frac{{23}}{{28}}{}{{v}}^{{3}}{+}\frac{{5}}{{28}}{}{v}{,}{v}{<}{2}{,}{-}\frac{{59}}{{28}}{}{{v}}^{{3}}{+}\frac{{123}}{{14}}{}{{v}}^{{2}}{-}\frac{{241}}{{28}}{}{v}{+}\frac{{41}}{{14}}{,}{v}{<}{3}{,}\frac{{45}}{{28}}{}{{v}}^{{3}}{-}\frac{{27}}{{2}}{}{{v}}^{{2}}{+}\frac{{1007}}{{28}}{}{v}{-}\frac{{375}}{{14}}{,}{-}\frac{{9}}{{28}}{}{{v}}^{{3}}{+}\frac{{27}}{{7}}{}{{v}}^{{2}}{-}\frac{{451}}{{28}}{}{v}{+}\frac{{177}}{{7}}\right)$ (3.1.2)

Translate the procedure to Fortran, while declaring that v should be a float parameter.

 > $\mathrm{Fortran}\left(p,\mathrm{declare}=\left[v::\mathrm{float}\right]\right)$
 doubleprecision function p (v)        doubleprecision v        if (v .lt. 0.1D1) then          p = 0.23D2 / 0.28D2 * v ** 3 + 0.5D1 / 0.28D2 * v          return        else if (v .lt. 0.2D1) then          p = -0.59D2 / 0.28D2 * v ** 3 + 0.123D3 / 0.14D2 * v ** 2 - 0.     #241D3 / 0.28D2 * v + 0.41D2 / 0.14D2          return        else if (v .lt. 0.3D1) then          p = 0.45D2 / 0.28D2 * v ** 3 - 0.27D2 / 0.2D1 * v ** 2 + 0.100     #7D4 / 0.28D2 * v - 0.375D3 / 0.14D2          return        else          p = -0.9D1 / 0.28D2 * v ** 3 + 0.27D2 / 0.7D1 * v ** 2 - 0.451     #D3 / 0.28D2 * v + 0.177D3 / 0.7D1          return        end if      end

An Automatic Differentiation Example

Create a procedure, f.

 >

Compute the gradient (vector of partial derivatives) of f by using the codegen[GRADIENT] function. Although using the codegen[C] and codegen[fortran] functions are not recommended any longer, the codegen package still contains a number of useful utilities that can be used in combination with the CodeGeneration package.

 > $g≔\mathrm{codegen}\left[\mathrm{GRADIENT}\right]\left(f\right)$
 ${g}{:=}{\mathbf{proc}}\left({x}{::}{\mathrm{float}}{,}{y}{::}{\mathrm{float}}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{local}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{dfr0}}{,}{t}{::}{\mathrm{float}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{t}{:=}{\mathrm{exp}}{}\left({−}{x}\right){;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{dfr0}}{:=}{\mathrm{array}}{}\left({1}{..}{1}\right){;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{dfr0}}{[}{1}{]}{:=}{y}{+}{1}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{return}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{−}{\mathrm{dfr0}}{[}{1}{]}{*}{\mathrm{exp}}{}\left({−}{x}\right){,}{t}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end proc}}$ (3.2.1)

Translate the gradient to C, optimizing the Maple code before translation.

 > $C\left(g,\mathrm{optimize}\right)$
 #include void g (double x, double y, double cgret[2]){  double dfr0[1];  double t;  t = exp(-x);  dfr0[0] = 0;  dfr0[0] = y + 0.1e1;  cgret[0] = -dfr0[0] * t;  cgret[1] = t;}

Finding Eigenvalues of a Matrix

Declare a matrix:

 > $\mathrm{MatlabMatrix}≔\left[\begin{array}{rr}3& 1\\ 1& 3\end{array}\right]:$
 > $\mathrm{Matlab}\left(\mathrm{MatlabMatrix}\right);$
 cg6 = [3 1; 1 3;];

Find the eigenvalues of the matrix:

 > $\mathrm{Matlab}('\mathrm{LinearAlgebra}:-\mathrm{Eigenvalues}'(\mathrm{MatlabMatrix}))$
 cg7 = eig([3 1; 1 3;]);

Computing Summary Statistics

Code generation for R can translate many commands from the Statistics package. In the following example, some summary statistics are computed on a list of value.

Declare a list of values:

 > $\mathrm{RList}≔\left[4,8,15,16,23,42\right]:$

Translate the list to R code:

 > $R\left(\mathrm{RList}\right);$
 cg8 <- c(4,8,15,16,23,42)

Compute some summary statistics.

 > $R\left('\mathrm{Statistics}:-\mathrm{FivePointSummary}'\left(\mathrm{RList}\right)\right)$
 cg9 <- fivenum(c(4,8,15,16,23,42))

Compare median and mean to see the differences in translations depending on if unevaluation quotes are used or not; when quotes are used, the command itself is translated to the target language.

 > $R\left('\mathrm{Statistics}:-\mathrm{Mean}'\left(\mathrm{RList}\right)\right)$
 cg10 <- mean(c(4,8,15,16,23,42))

In the case of not using unevaluation quotes, the result of a Maple computation (Median) is translated.

 > $R\left(\mathrm{Statistics}:-\mathrm{Median}\left(\mathrm{RList}\right)\right)$
 cg11 <- 0.155000000000000000e2

It is also possible to translate some visualization commands:

 >
 cg12 <- hist(c(4,8,15,16,23,42), col = "Orange")