猪冰龙

导航

maple usage 语言转换

 


Code Generation
" From equations to source code ¨C General application development (software to software) ¨C Real-time simulation (software to hardware via RT platform)

 

" Automate the model derivation and programming process
   ¨C More target languages
   ¨C Optimized code generation and equation simplification

4.3 ´úÂëÉú³É
Code generation ÊÇMapleÖг£ÓõÄÒ»¸ö¹¤¾ß£¬Ä¿µÄÊǽ«MapleµÄÓ¦Óõ½ÆäËûϵͳ¡£Maple¿ÉÒÔת»»¹«Ê½¡¢ÊýÖµ³ÌÐò¡¢Êý¾Ý¼¯¡¢¾ØÕóµÈµ½±àÒëÓïÑÔ¡£MapleÖ§³ÖµÄת»»ÓïÑÔ°üÀ¨C¡¢Java¡¢Visual Basic¡¢Matlab¡¢Fortran¡£
restart; with(CodeGeneration);
[C, Fortran, IntermediateCode, Java, LanguageDefinition, Matlab, 

  Names, Save, Translate, VisualBasic]

4.3.1 ת»» Maple ¹«Ê½

Àý×Ó£º¼ÆËãÒ»¸ö 3x3 ¾ØÕ󣨰üº¬·ûºÅÏµÄÄæ¾ØÕ󣬲¢½«½á¹ûת»»ÎªC´úÂë¡£

ÀûÓÃ×ó²àµÄÃæ°å£¬ÊäÈëÒ»¸ö 3x3 ¾ØÕ󣬾ØÕóÈçÏ£º
M := Matrix(3, 3, [[a, 3, c], [1, b, 2], [-1, 0, -1]]);

ʹÓÃÓÒ¼ü²Ëµ¥»òÃüÁî¼ÆËãMµÄÄæ¾ØÕó¡£
Minv := 1/M;
            Minv:=Matrix(%id = 18446744074328686894)

Êä³öÄæ¾ØÕó½á¹ûµ½C´úÂë¡£
C(Minv);
cg0[0][0] = b / (3 - c * b + a * b);
cg0[0][1] = -3 / (3 - c * b + a * b);
cg0[0][2] = (-6 + c * b) / (3 - c * b + a * b);
cg0[1][0] = 1 / (3 - c * b + a * b);
cg0[1][1] = (a - c) / (3 - c * b + a * b);
cg0[1][2] = (2 * a - c) / (3 - c * b + a * b);
cg0[2][0] = -b / (3 - c * b + a * b);
cg0[2][1] = 3 / (3 - c * b + a * b);
cg0[2][2] = -(-3 + a * b) / (3 - c * b + a * b);

ÉÏÃæµÄ´úÂë¿ÉÒÔÕý³£¹¤×÷£¬µ«ÊÇЧÂʲ»¸ß£¬ÒòΪËü¶à´ÎÖØ¸´¼ÆËãÁ˱í´ïʽ(-3 + b * c - a * b) ¡£Õâ¸ö±í´ïʽӦ¸Ã¼ÆËãÒ»´Î£¬²¢´æ´¢Îª±äÁ¿£¬ÒÔ±ãÒÔËû±í´ïʽµ÷Óá£ÎÒÃÇ¿ÉÒÔͨ¹ýÔÚCÊä³öÃüÁîÖмÓÈë optimize Ñ¡ÏîʵÏÖÕâÒ»µã¡£

ͨ³££¬optimizeÑ¡Ïî»á×îС»¯Êä³ö´úÂëÖÐËãÊõ¼ÆËãµÄ´ÎÊý¡£
C(Minv, optimize);
t1 = (int) ((double) c * (double) b);
t2 = (int) ((double) a * (double) b);
t4 = 1 / (3 - t1 + t2);
t5 = b * t4;
t6 = 3 * t4;
cg1[0][0] = t5;
cg1[0][1] = -t6;
cg1[0][2] = (-6 + t1) * t4;
cg1[1][0] = t4;
cg1[1][1] = (a - c) * t4;
cg1[1][2] = (2 * a - c) * t4;
cg1[2][0] = -t5;
cg1[2][1] = t6;
cg1[2][2] = -(-3 + t2) * t4;

ÏÖÔÚÊä³ö´úÂëµÄЧÂʵõ½ÁËÌá¸ß¡£

4.3.2 ת»»Maple³ÌÐò
Àý×Ó£º½« Maple µÄÅ£¶Ù·½·¨³ÌÐòת»»Îª C£¬Java£¬Matlab£¬Fortran ºÍ VB¡£

ÏÂÃæµÄ Maple ³ÌÐòʹÓÃÅ£¶Ù·½·¨¸ø¶¨³õʼµã¼ÆËãÁË 
                          cos(a x + b)
 µÄ¸ù¡£Óû§ÊäÈëÕûÊý a ºÍ b£¬ÒÔ¼°³õʼµã¡£
f := proc(a::integer, b::integer, x::float)
    local x0, x1, v, vp;

    x1 := x; 
    x0 := x+1;

    while abs(x1-x0)>10^(-3) do
        v := cos(a*x1+b);
        vp := -a*sin(a*x1+b);
        x0 := x1;
        x1 := x1-v/vp;
    end do;

    x1;
     end proc:

f(2, 3, .3);
                          0.8561944904
cos(2*%+3);
                                     -10
                       6.153101422 10   

ת»»³ÌÐòΪ C¡£×¢Òâµ½ Maple °üº¬ÁË C's math.h ¿âÎļþ£¬Í¬Ê±ËµÃ÷ÁËÊäÈë±äÁ¿ÊÇ int ºÍ double£¬¶ÔÓ¦µÄ Maple Êý¾ÝÀàÐÍÊÇ integer ºÍ float.
C(f);
#include <math.h>

double f (int a, int b, double x)
{
  double x0;
  double x1;
  double v;
  double vp;
  x1 = x;
  x0 = x + 0.1e1;
  while (0.1e1 / 0.1000e4 < fabs(x1 - x0))
  {
    v = cos((double) a * x1 + (double) b);
    vp = -(double) a * sin((double) a * x1 + (double) b);
    x0 = x1;
    x1 = x1 - v / vp;
  }
  return(x1);
}

ת»»³ÌÐòµ½ Fortran
Fortran(f);
      doubleprecision function f (a, b, x)
        integer a
        integer b
        doubleprecision x
        doubleprecision x0
        doubleprecision x1
        doubleprecision v
        doubleprecision vp
        x1 = x
        x0 = x + 0.1D1
100     continue
        if (0.1D1 / 0.1000D4 .lt. abs(x1 - x0)) then
          v = cos(dble(a) * x1 + dble(b))
          vp = -dble(a) * sin(dble(a) * x1 + dble(b))
          x0 = x1
          x1 = x1 - v / vp
        goto 100
        end if
        f = x1
        return
      end

ת»»³ÌÐòµ½ Java£¬×¢Òâµ½Êä³öµÄ´úÂë°üº¬ÁË java.lang.Math Àà¡£
Java(f);
import java.lang.Math;

class CodeGenerationClass {
  public static double f (int a, int b, double x)
  {
    double x0;
    double x1;
    double v;
    double vp;
    x1 = x;
    x0 = x + 0.1e1;
    while (0.1e1 / 0.1000e4 < Math.abs(x1 - x0))
    {
      v = Math.cos((double) a * x1 + (double) b);
      vp = -(double) a * Math.sin((double) a * x1 + (double) b);
      x0 = x1;
      x1 = x1 - v / vp;
    }
    return(x1);
  }
}

ת»»³ÌÐòµ½ VB¡£  
VisualBasic(f);
Imports System.Math

Public Module CodeGenerationModule
  Public Function f( _
    ByVal a As Integer, _
    ByVal b As Integer, _
    ByVal x As Double) As Double
    Dim x0 As Double
    Dim x1 As Double
    Dim v As Double
    Dim vp As Double
    x1 = x
    x0 = x + 0.1E1
    Do While (0.1E1 / 0.1000E4 < Abs(x1 - x0))
      v = Cos(CDbl(a) * x1 + CDbl(b))
      vp = -CDbl(a) * Sin(CDbl(a) * x1 + CDbl(b))
      x0 = x1
      x1 = x1 - v / vp
    Loop
    Return x1
  End Function
End Module

ת»»³ÌÐòµ½ MATLAB
Matlab(f);
function freturn = f(a, b, x)
  x1 = x;
  x0 = x + 0.1e1;
  while (0.1e1 / 0.1000e4 < abs(x1 - x0))
    v = cos(a * x1 + b);
    vp = -a * sin(a * x1 + b);
    x0 = x1;
    x1 = x1 - v / vp;
  end
  freturn = x1;
4.3.3 ת»»µ½ÐµÄÄ¿±êÓïÑÔ£¨¿ÉÑ¡£©
ʹÓà LanguageDefinition ×Ó³ÌÐò°ü£¬Äã¿ÉÒÔÌí¼ÓÓïÑÔÉèÖã¬ÒÔ±ã CodeGeneration ¿ÉÒÔת»»¡£ Äã¿ÉÒÔͨ¹ý´´½¨Ò»¸öеÄÓïÑÔ¶¨Ò壬»ò¼Ì³ÐÏÖÓÐÓïÑÔ¶¨ÒåµÄͬʱ¸²¸ÇÏ£Íû¸Ä±äµÄ²¿·Ö£¬ÊµÏÖÕâ¸öÄ¿µÄ¡£
with(LanguageDefinition);
[Add, DefaultPrinter, Define, GenericPrinter, Get, GetInstance, 

  IsDefined, ListLanguages]

£¨ÎÒÃǽ«ÔÚAdvanced Maple ProgrammingµÚ4²¿·ÖmodulesÖÐѧϰÕâЩ֪ʶ¡££©
m := 'module()
   export PrintTarget, Printer;
        PrintTarget := proc() 
           Printer:-PrintTarget(args): 
        end proc:
        Printer := eval(LanguageDefinition:-Get("default")):-Printer;
        Printer:-AddFunction("Pi", [anything]::anything, "pi");
        Printer:-AddOperator(Names:-Assignment = " := ");
end module':

Add º¯ÊýÔö¼Ó module µÄ¶¨Ò壬¶¨Òå CodeGeneration ±í¸ñÖпÉʶ±ðµÄÓïÑÔ¡£Õâ¸öÓïÑÔ¿ÉÒÔͨ¹ý Translate ºÍ Get ʹÓá£
Add("MyLanguage", m);

Translate ÃüÁîת»» Maple ´úÂëµ½¶¨ÒåµÄÄ¿±êÓïÑÔ¡£
Translate(Pi, language = "MyLanguage");
cg2  :=  pi;
m := 'module() export PrintTarget, Printer;
    Printer := eval(LanguageDefinition:-Get("C")):-Printer;
       
    PrintTarget := proc(ic, digits::posint, prec::name, func_prec, namelist)::string;
        Printer:-PrintTarget(args);
    end proc:
    
    # set precedence of addition higher than that of multiplication
    Printer:-SetPrecedence(
        Names:-Addition = Printer:-GetPrecedence(Names:-Multiplication)+5);
end module':

LanguageDefinition:-Add("MyLanguage", m);
Translate(x*y+z, language="MyLanguage");

cg3 = x * y + z;
4.3.4 Options for tailoring the generated code

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, has a rich set of data 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.  

So the CodeGeneration functions often must choose the most suitable translation in cases when more than one result is possible.  Occasionally, the choices Maple makes in generating the code made may not be the ones you expect.  However, Maple provides a number of options to customize the output.  Options common to all the CodeGeneration functions are described on the CodeGenerationOptions help page.

In the following example, all the parameters are assigned a floating-point type by default.
f := proc (x, y, z) return y*x-y*z+x*z end proc; C(f);
double f (double x, double y, double z)
{
  return(x * y - y * z + x * z);
}

Change the default type given to untyped variables by using the defaulttype option.
C(f, defaulttype = integer);
int f (int x, int y, int z)
{
  return(x * y - y * z + x * z);
}

Maple tries 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.
f := proc (x::float, y, z) y*x-y*z+x*z end proc; C(f, defaulttype = integer);
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(f, defaulttype = integer, deducetypes = false);
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(f, defaulttype = integer, deducetypes = false, coercetypes = false);
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(1+x+y, declare = [x::float, y::integer]);
cg0 = 0.1e1 + x + (double) y;

 

posted on 2017-03-07 17:04  猪冰龙  阅读(183)  评论(0)    收藏  举报