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

Sheplyakov Alexei varg at theor.jinr.ru
Fri Mar 30 07:24:41 CEST 2007


Hello!

On Thu, Mar 29, 2007 at 07:51:56AM -0400, Warren Weckesser wrote:

> Alexei suggested a function called generate_code(...) that generated
> a complete function that returns the value of the expression.  That
> could be useful; presumably it would check for the symbols used in
> the expression, and make all of them arguments to the function.

It should also sort those symbols, so variables declared before they
used.

> I
> suggest calling this function generate_function(...) instead of
> generate_code().

That would be very misleading. There are functions in C++. There is 
also GiNaC::function, and related DECLARE_FUNCTION_* macros. So yet
another (unrelated) thing named "function" does not sound like a good
idea.

> For Fortran (assuming "implicit none" is used), it would be necessary
> for the code to first figure out the names of all the temporary
> variables that will be used before actually generating code, so my
> program can create the appropriate declaration of these variables.
> Alexei proposed this function:
> 
>    const ex find_common_subex(const ex& e, exmap& repls);
> 
> So, for Fortran output, I would call this function, and then use repls
> to generate the declarations of the temporary variables.

This function can be useful for absolutely diffrerent things.
If the exact form of some lengthy subexpressions is not important for
current operation (e.g. gcd()), I would call this function to replace
them with symbols. If I expect the expression to have a lot of easily
recognizable subexpressions I'd call it before .evalf(), then evalf()
subexpressions it detected, subs() them back into the original expression,
and finally evalf() it.

> Then I would
> call generate_assignment(...) to actually create the code that does
> the assignment.  (This would also work for C/C++.)
> 
> Alexei also proposed split_large_subex(...).  How would I use this
> together with find_common_subex() if I want to do both to a complicated
> expression?

ex e = a2*pow(x1+...+x1024, 2) + ... + a1024*pow(x1+...+x1024, 1024);

exmap repls;
e = find_common_subex(e, repls);

// Now e should be a2*pow(symbol1, 2) ... + a1024*pow(symbol1, 1024),
// and repls contains pair symbol1 => x1+...+x1024

e = split_large_subex(e, repls, 128);
// e: symbol2 + symbol3 + ... + symbol8;
// repls:
// symbol1 => x1+...+x1024
// symbol2 => a2*pow(symbol1,2) + ... + a130*pow(symbol1,130)
// symbol3 => a131*pow(symbol1,121) + ... + a259*pow(symbol1,259)
// .....
// symbol8 => a898*pow(symbol1,121) + ... + a1024*pow(symbol1,1024)

So repls contains "simpler" (?) expressions now. You can further split
and/or find common subexpressions by iterating over repls entries.

BTW, this example illustrates that such an "optimizer" does not optimize
anything. It would be better to (recursively) split that expression into

e = e1 + e2
e1 => a2*symbol2 + a4*pow(symbol2, 2) + ... + a1024*pow(symbol2, 512)
e2 => symbol1*(a3*symbol2 + ... + a1023*pow(symbol2, 511))
symbol2 => pow(symbol1, 2)

Best regards,
 Alexei

-- 
All science is either physics or stamp collecting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20070330/af927c8e/attachment.pgp


More information about the GiNaC-devel mailing list