[GiNaC-devel] GiNaC is not a C compiler [Was: Optimized C-style output]

Stefan Weinzierl stefanw at thep.physik.uni-mainz.de
Tue Apr 3 10:09:10 CEST 2007


Hi,

after the discussions of the previous weeks comes now a new version for
the code generation.
There is now a new class "assign_lst", which has different methods for
different things:
 replace_common_subex(flag) to replace common subexpressions. The flag can
  used to select any combination from the set {add,mul,power,function} for
  which one wants this substitution.

 split_large_subex(nmax) splits subexpressions of type add or mul with
  more than nmax operands.

 get_temporary_variables() returns the list of all new temporary variables

 print(ostream) and operator<<: Print it out.

I attach an example program to show how it is used. The example program
first prints for each example the standard csrc output and the modified
(or "optimized") version.
Examples 5 and 6 show some limitations.
When running this program one gets:

Example 1: replace common subexpressions
 double res = log(sin(y+x))+sin(y+x)+pow(sin(y+x),2.0)+log(y+x);

 double tmp1 = y+x;
 double tmp0 = sin(tmp1);
 double res = log(tmp0)+(tmp0*tmp0)+log(tmp1)+tmp0;

Example 2: as above, but don't replace add and mul
 double res = log(sin(y+x))+sin(y+x)+pow(sin(y+x),2.0)+log(y+x);

 double tmp0 = sin(y+x);
 double res = (tmp0*tmp0)+tmp0+log(tmp0)+log(y+x);

Example 3: works also on several assignments
 double y1 = x2*sin(phi)+cos(phi)*x1;
 double y2 = cos(phi)*x2-x1*sin(phi);

 double tmp1 = sin(phi);
 double tmp0 = cos(phi);
 double y1 = x1*tmp0+tmp1*x2;
 double y2 = -x1*tmp1+tmp0*x2;

Example 4: split subexpressions with more than 6 operands
 double res = x1+x0+y6*y1*y0*y5*y4*y9*y8*y3*y2*y7+x5+x4+x9+x8+x3+x2+x7+x6;

 double tmp1 = x8+x3+x2+x7+x6;
 double tmp3 = y8*y3*y2*y7;
 double tmp2 = y6*y1*y0*y5*y4*y9;
 double tmp0 = x1+x0+x5+x4+x9+tmp3*tmp2;
 double res = tmp1+tmp0;

 List of temporary variables: {tmp0,tmp1,tmp2,tmp3}

Example 5: pow(x+y,2) is not a subexpr of pow(x+y,4)
 double res = 2.0*pow(y+x,2.0)+log(pow(y+x,4.0))+3.0*pow(y+x,3.0)+5.0*pow(y+x,5.0)+4.0*pow(y+x,4.0)+log(pow(y+x,2.0));

 double tmp2 = y+x;
 double tmp1 = ((tmp2*tmp2)*(tmp2*tmp2));
 double tmp0 = (tmp2*tmp2);
 double res = log(tmp0)+log(tmp1)+5.0*(tmp2*(tmp2*tmp2)*(tmp2*tmp2))+3.0*(tmp2*tmp2*tmp2)+4.0*tmp1+2.0*tmp0;

Example 6: Substitution works only syntactically
 double res = y+x+cos(y+x)+sin(y+x);

 double tmp0 = y+x;
 double res = sin(tmp0)+y+x+cos(tmp0);


Best wishes,

    Stefan

-------------- next part --------------
A non-text attachment was scrubbed...
Name: code_generation.h
Type: text/x-chdr
Size: 3625 bytes
Desc: header file
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20070403/4e963615/code_generation.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: code_generation.cpp
Type: text/x-c++src
Size: 10712 bytes
Desc: cpp file
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20070403/4e963615/code_generation-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: example.cpp
Type: text/x-c++src
Size: 2889 bytes
Desc: example
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20070403/4e963615/example.bin


More information about the GiNaC-devel mailing list