MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

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?