Overview of the codegen Package - Maple Help

Online Help

All Products    Maple    MapleSim


Home : Support : Online Help : Programming : codegen Package : codegen

Overview of the codegen Package

 

Calling Sequence

Description

List of codegen Package Commands

Examples

Calling Sequence

codegen[command](arguments)

Description

• 

The code generation (codegen) package contains tools for creating, manipulating, and translating Maple procedures into other languages. This includes tools for automatic differentiation of Maple procedures, code optimization, translation into C, Fortran and MathML, and an operation count of a Maple procedure.

• 

Each command in the codegen package can be accessed by using either the long form or the short form of the command name in the command calling sequence.

• 

Important: The newer CodeGeneration package also offers translation of Maple code to other languages. The codegen[C] and codegen[fortran] commands have been deprecated, and the superseding commands CodeGeneration[C] and CodeGeneration[Fortran] should be used instead.  Additionally, codegen[maple2intrep] and codegen[intrep2maple] have been superseded by ToInert and FromInert.

List of codegen Package Commands

• 

The following is a list of available commands.

C(deprecated)

cost

declare

dontreturn

eqn

fortran(deprecated)

GRADIENT

HESSIAN

horner

intrep2maple(deprecated)

JACOBIAN

joinprocs

makeglobal

makeparam

makeproc

makevoid

maple2intrep(deprecated)

MathML

optimize

packargs

packlocals

packparams

prep2trans

renamevar

split

swapargs

 

 

  

To display the help page for a particular codegen command, see Getting Help with a Command in a Package.

Examples

withcodegen:

The first example shows how the package can be used to create a Fortran subroutine to compute a vector valued function.

f1ⅇtxy:

gxyⅇtx2:

vfg

v:=1ⅇtxyxyⅇtx2

(1)

fg := makeproc(v,parameters=[t,x,y]);

fg:=proct,x,ylocalv;v:=array1..2;v[1]:=1exp−t*x*y;v[2]:=xy*exp−t*x^2;vend proc

(2)

fortranfg,optimized

      subroutine fg(t,x,y,crea_par)
      doubleprecision t
      doubleprecision x
      doubleprecision y
      doubleprecision crea_par(2)

      doubleprecision t1
      doubleprecision t5
      doubleprecision v(2)

        t1 = exp(-t)
        v(1) = -t1*x*y+1
        t5 = x**2
        v(2) = -y*t1*t5+x
        crea_par(1) = v(1)
        crea_par(2) = v(2)
        return
        return
      end

The function f below computes the square of the distance from a point (x,y) to a circle of radius r with centre (h,k) under translation by (C,D) followed by rotation of theta radians. We use automatic differentiation to compute the gradient of the function f with respect to C,D,theta and generate C code for the result.  Finally we output the computational cost of the optimized code.

f := proc(C,D,theta,x,y,h,k,r)
local s,c,xbar,ybar,d1,d2,d;
  s := sin(theta);
  c := cos(theta);
  xbar := (x+C)*c + (y+D)*s;
  ybar := (y+D)*c - (x+C)*s;
  d1 := (h-xbar)^2;
  d2 := (k-ybar)^2;
  d := sqrt( d1+d2 ) - r;
  d^2
end proc:

GGRADIENTf,C,D,θ,result_type=array

G:=procC,D,theta,x,y,h,k,rlocalc,d,d1,d2,dfr0,grd,s,xbar,ybar;s:=sintheta;c:=costheta;xbar:=x+C*c+y+D*s;ybar:=y+D*cx+C*s;d1:=hxbar^2;d2:=kybar^2;d:=sqrtd1+d2r;dfr0:=array1..7;dfr0[7]:=2*d;dfr0[6]:=1/2*dfr0[7]/d1+d2^1/2;dfr0[5]:=1/2*dfr0[7]/d1+d2^1/2;dfr0[4]:=dfr0[6]*−2*k+2*ybar;dfr0[3]:=dfr0[5]*−2*h+2*xbar;dfr0[2]:=dfr0[4]*y+D+dfr0[3]*x+C;dfr0[1]:=dfr0[4]*−xC+dfr0[3]*y+D;grd:=array1..3;grd[1]:=0;grd[2]:=c*dfr0[4]+s*dfr0[3];grd[3]:=−dfr0[2]*sintheta+dfr0[1]*costheta;returngrdend proc

(3)

CG,optimized,precision=single

#include <math.h>
void G(C,D,theta,x,y,h,k,r,grd)
float C;
float D;
float theta;
float x;
float y;
float h;
float k;
float r;
float grd[3];
{
  float c;
  float d1;
  float d2;
  float dfr0[7];
  float s;
  float t1;
  float t10;
  float t12;
  float t20;
  float t22;
  float t3;
  float t7;
  float t8;
  float t9;
  {
    s = sin(theta);
    c = cos(theta);
    t1 = x+C;
    t3 = y+D;
    t7 = -t1*c-t3*s+h;
    d1 = t7*t7;
    t8 = -t3*c+t1*s+k;
    d2 = t8*t8;
    t9 = d1+d2;
    t10 = sqrt(t9);
    dfr0[6] = 2.0*t10-2.0*r;
    t12 = sqrt(t9);
    dfr0[5] = dfr0[6]/t12/2.0;
    dfr0[4] = dfr0[5];
    dfr0[3] = -2.0*dfr0[4]*t8;
    dfr0[2] = -2.0*dfr0[4]*t7;
    t20 = dfr0[3];
    t22 = dfr0[2];
    dfr0[1] = t22*t1+t20*t3;
    dfr0[0] = -t20*t1+t22*t3;
    grd[0] = 0.0;
    grd[1] = t20*c+t22*s;
    grd[2] = dfr0[0]*c-dfr0[1]*s;
    return;
  }
}

costoptimizeG

23storage&plus;25assignments&plus;5functions&plus;12additions&plus;22multiplications&plus;18subscripts&plus;divisions

(4)

In this example, we compute 1+x+x^2/2+x^3/6+...+x^n/n! We do this in two ways.  Firstly, we use a symbolic sum. To obtain C code we explicitly convert the symbolic sum to a for loop.

fi&equals;0nxii&excl;

f:=i&equals;0nxii&excl;

(5)

F := makeproc(f,parameters=[n,x],locals=[i]);

F:=procn&comma;xlocali&semi;Sumx&Hat;i&sol;factoriali&comma;i&equals;0..nend proc

(6)

Fprep2transF

F:=procn&comma;xlocali&comma;i1&comma;s1&comma;t1&semi;if0<&minus;nthens1:=0elset1:=1&semi;s1:=1&semi;fori1tondot1:=x&ast;t1&sol;i1&semi;s1:=s1&plus;t1end doend if&semi;s1end proc

(7)

Fdeclaren::integer&comma;F

F:=procn::integer&comma;xlocali&comma;i1&comma;s1&comma;t1&semi;if0<&minus;nthens1:=0elset1:=1&semi;s1:=1&semi;fori1tondot1:=x&ast;t1&sol;i1&semi;s1:=s1&plus;t1end doend if&semi;s1end proc

(8)

CF

double F(n,x)
int n;
double x;
{
  double i;
  int i1;
  double s1;
  double t1;
  {
    if( 0.0 < -n )
      s1 = 0.0;
    else
      {
        t1 = 1.0;
        s1 = 1.0;
        for(i1 = 1;i1 <= n;i1++)
        {
          t1 = x/i1*t1;
          s1 += t1;
        }
      }
    return(s1);
  }
}

In the second approach, our program uses a loop to compute the finite sum. We use the intermediate representation for programs provided by the codegen package.  This representation is an expression tree.  It can be converted into a Maple procedure using the intrep2maple command which can then be converted into Fortran or C code if desired.

fProcParametersn::integer&comma;x::float&comma;Localsi&comma;s&comma;t&comma;StatSeqAssigns&comma;1.0&comma;Assignt&comma;1.0&comma;Fori&comma;1&comma;1&comma;n&comma;true&comma;StatSeqAssignt&comma;xti&comma;Assigns&comma;s&plus;t&comma;s

f:=ProcParametersn::integer&comma;x::float&comma;Localsi&comma;s&comma;t&comma;StatSeqAssigns&comma;1.0&comma;Assignt&comma;1.0&comma;Fori&comma;1&comma;1&comma;n&comma;true&comma;StatSeqAssignt&comma;xti&comma;Assigns&comma;s&plus;t&comma;s

(9)

Fintrep2maplef

F:=procn::integer&comma;x::floatlocali&comma;s&comma;t&semi;s:=1.0&semi;t:=1.0&semi;foritondot:=x&ast;t&sol;i&semi;s:=s&plus;tend do&semi;send proc

(10)

In this example, we compute the gradient and hessian of a simple function, manipulate the procedures then join the two together.

f1&ExponentialE;txy

f:=1&ExponentialE;txy

(11)

F := makeproc(f,[x,y,t]);

F:=procx&comma;y&comma;t1exp&minus;t&ast;x&ast;yend proc

(12)

GGRADIENTF&comma;x&comma;y&comma;result_type&equals;array

G:=procx&comma;y&comma;tlocalgrd&semi;grd:=array1..2&semi;grd&lsqb;1&rsqb;:=&minus;exp&minus;t&ast;y&semi;grd&lsqb;2&rsqb;:=&minus;exp&minus;t&ast;x&semi;returngrdend proc

(13)

Gdontreturngrd&comma;makeparamgrd&comma;G

G:=procx&comma;y&comma;t&comma;grd::array1..2grd&lsqb;1&rsqb;:=&minus;exp&minus;t&ast;y&semi;grd&lsqb;2&rsqb;:=&minus;exp&minus;t&ast;x&semi;returnend proc

(14)

HHESSIANF&comma;x&comma;y&comma;result_type&equals;array&colon;

Hrenamevargrd&equals;hes&comma;dontreturngrd&comma;makeparamgrd&comma;H

H:=procx&comma;y&comma;t&comma;hes::array1..2&comma;1..2localdf&comma;dfr0&comma;grd1&comma;grd2&comma;t1&semi;t1:=exp&minus;t&semi;grd1:=&minus;t1&ast;y&semi;grd2:=&minus;t1&ast;x&semi;df:=array1..2&semi;dfr0:=array1..2&semi;df&lsqb;1&rsqb;:=1&semi;dfr0&lsqb;2&rsqb;:=1&semi;hes&lsqb;1&comma;1&rsqb;:=0&semi;hes&lsqb;1&comma;2&rsqb;:=&minus;df&lsqb;1&rsqb;&ast;t1&semi;hes&lsqb;2&comma;1&rsqb;:=&minus;dfr0&lsqb;2&rsqb;&ast;t1&semi;hes&lsqb;2&comma;2&rsqb;:=0&semi;returnend proc

(15)

GHoptimizejoinprocsG&comma;H

GH:=procx&comma;y&comma;t&comma;grd&comma;hes::array1..2&comma;1..2localt1&comma;t2&semi;t2:=exp&minus;t&semi;grd&lsqb;1&rsqb;:=&minus;t2&ast;y&semi;grd&lsqb;2&rsqb;:=&minus;t2&ast;x&semi;t1:=t2&semi;hes&lsqb;1&comma;1&rsqb;:=0&semi;hes&lsqb;1&comma;2&rsqb;:=&minus;t1&semi;hes&lsqb;2&comma;1&rsqb;:=hes&lsqb;1&comma;2&rsqb;&semi;hes&lsqb;2&comma;2&rsqb;:=0&semi;returnend proc

(16)

This final example shows the functionality of the maple2intrep and intrep2maple commands. The maple2intrep command converts a Maple procedure into an intermediate representation which is suitable for manipulation. One must be careful about how one evaluates this representation because the functions in the code will evaluate.

f := proc(x,n) local A,i;
  A := array(0..n);
  A[0] := 1;
  for i to n do A[i] := x*A[i-1] end do;
  A
end proc:

IRmaple2intrepf

IR:=ProcNamef..List0..n&comma;float&comma;Parametersx..float&comma;n..integer&comma;Options&comma;Description&comma;LocalsA..List0..n&comma;float&comma;i..integer&comma;Globals&comma;StatSeqAssignA&comma;array0..n&comma;AssignA0&comma;1&comma;Fori&comma;1&comma;1&comma;n&comma;true&comma;StatSeqAssignAi&comma;xA1&plus;i&comma;A

(17)

intrep2mapleIR

Error, non-integer ranges in array/table creation

intrep2mapleevalIR&comma;1

procx&comma;nlocalA&comma;i&semi;A:=array0..n&semi;A&lsqb;0&rsqb;:=1&semi;foritondoA&lsqb;i&rsqb;:=x&ast;A&lsqb;i1&rsqb;end do&semi;Aend proc

(18)

See Also

codegen[C(deprecated)]

codegen[fortran(deprecated)]

codegen[optimize]

CodeGeneration

CodeGeneration[C]

CodeGeneration[Fortran]

examples/codegen

UsingPackages

 


Download Help Document

Was this information helpful?



Please add your Comment (Optional)
E-mail Address (Optional)
What is ? This question helps us to combat spam