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
>
>