Re: OptimizeExpression

• To: mathgroup at smc.vnet.net
• Subject: [mg86197] Re: OptimizeExpression
• From: Jens-Peer Kuska <kuska at informatik.uni-leipzig.de>
• Date: Wed, 5 Mar 2008 03:41:59 -0500 (EST)
• References: <fqisvi\$mct\$1@smc.vnet.net>

```Hi,

you should *not* process the result of Experimental`OptimizeExpression
Compile[] will accept the result and generate a optimized
Mathematica code from it. That is what the function is used/written
for.

So, ok let start with your example

oexp = Experimental`OptimizeExpression[(3 + 3*a^2 +
Sqrt[5 + 6*a + 5*a^2] + a*(4 + Sqrt[5 + 6*a + 5*a^2]))/6];

The result is an OptimzedExpression[] that Hold the expression, because
otherwise it will (and must) evaluate to the original expression.
While the variable definitions are uncritical the CompoundExpression[]
in the Block[] must be kept unevaluated

{locals, code} =
ReleaseHold[(Hold @@ oexp) /.
Verbatim[Block][vars_, seq_] :> {vars, Hold[seq]}]

the code is Hold[CompoundExpression[__]]
Since CForm[] is only a wrapper it will not prevent
the evaluation and so one has to split the CompoundExpression[]

code1 = code /.  Hold[CompoundExpression[seq__]] :> Hold[{seq}]

One need a Hold[] for every element in the statement sequence
and than the outer Hold can be removed

code2 = First[
code1 //.
Hold[{a___Hold, b_, c___}] /; Head[Unevaluated[b]] =!= Hold :>
Hold[{a, Hold[b], c}]]

next we have to transform the individual statements
to CForm[] and to strings,

statements = StringReplace[ToString[CForm[#]],
"Hold(" ~~ ShortestMatch[a___] ~~ ")" :> a] & /@ code2

and now the statements are transformed into a single String
with propper formating

mycsequence=StringJoin @@ Riffle[statements, ";\n"]

Now lets turn back to the local variables, my Mathematica
6. generate variables like Internal_\$\$198 but the \$ sign
is not supported by all compilers

replacevar =
Rule @@@ Transpose[ {ToString[CForm[#]] & /@ locals,
StringReplace[
StringReplace[ToString[#], {__ ~~ "`" ~~ a_ :> a }],
"\$" -> "_"] & /@ locals}]

and

mycsequence1 = StringReplace[mycsequence, replacevar]

replace the variables,
and finally add the variable declaration and a C-block

"{\ndouble " <>
StringJoin @@
Riffle[Last /@ replacevar,
","] <> ";\n\n" <> mycsequence1 <> ";\n}\n"

and we end with

{
double __103,__105,__106,__107,__108;

__103 = Power(a,2);
__105 = 6*a;
__106 = 5*__103;
__107 = 5 + __105 + __106;
__108 = Sqrt(__107);
(3 + 3*__103 + __108 + a*(4 + __108)/6.);
}

now add in your C-editor the name of the variable
for the result

{
double __103,__105,__106,__107,__108;

__103 = Power(a,2);
__105 = 6*a;
__106 = 5*__103;
__107 = 5 + __105 + __106;
__108 = Sqrt(__107);
optimizedExpression=(3 + 3*__103 + __108 + a*(4 + __108)/6.);
}

and you are done.
Regards
Jens

Evan Drumwright wrote:
> Hi everyone,
>
> I'm trying to send a very large (200+MB) expression to a C file using CForm, which, as you might imagine, crashes my compiler.  From other discussions on this list, I have seen that you can use the OptimizeExpression[] function to eliminate common subexpressions, and I think that this will work.  However, I don't understand how to process the resulting compound expression.  For instance:
>
>
> Experimental`OptimizeExpression[(3+3*a^2 + Sqrt[5 + 6*a + 5*a^2] + a*(4 + Sqrt[5 + 6*a + 5*a^2]))/6]
>
> generates
>
> Out[1]= Experimental`OptimizedExpression[Block[{\$\$11, \$\$13, \$\$14, \$\$15,
>
>                       2
>>      \$\$16}, \$\$11 = a ; \$\$13 = 6 a; \$\$14 = 5 \$\$11; \$\$15 = 5 + \$\$13 + \$\$14;
>
>                           3 + 3 \$\$11 + \$\$16 + a (4 + \$\$16)
>>      \$\$16 = Sqrt[\$\$15]; --------------------------------]]
>                                          6
>
> Now, I'd like to get out the individual set of statements:
>
> \$\$11 = a;
> \$\$13 = 6a;
> \$\$14 = 5 \$\$11;
> \$\$15 = 5 + \$\$13 + \$\$14;
> \$\$16 = Sqrt[\$\$15];
> (3 + 3\$\$11 + \$\$16 + a(4+\$\$16)/6
>
>
> But, if I were to look at the function in the optimized expression, I get the original function:
>
> In[2]:= %[[1]]
>
>                2                     2                             2
>         3 + 3 a  + Sqrt[5 + 6 a + 5 a ] + a (4 + Sqrt[5 + 6 a + 5 a ])
> Out[2]= --------------------------------------------------------------
>                                       6
>
>
> I suppose part of the difficulty is that I don't see a way to treat a CompoundExpression as a list of statements to be CForm'd.  Can anyone tell me how I'd do this?
>
>
> Thanks,
> Evan
>
>

```

• Prev by Date: Re: Mathematica 6 obtains imaginary eigenvalues for a Hermitian
• Next by Date: Re: Pathological list for ListLinePlot?
• Previous by thread: Re: OptimizeExpression
• Next by thread: Re: Efficiency and ReplacePart?