2
$\begingroup$

In one of my older Notebooks I found a reference to NumericalMath`OptimizeExpression. When I wrote it, I handed the result of some transformations to

OptimizeExpression[#,OptimizeLevel -> -1]&

which yielded an expression where some variables $1, $2, ... collected intermediate results to streamline the computation of this particular result. Without these optimizations, the same intermediate results would have been computed many times in the subparts of the exprssion.

To which place has OptimizeExpression moved to in Version 10 or 11?

By which other function was it superseded?

Lengthy repeated expressions often result from solving equations (like roots of a square or cubic expression) when the parameters of it result from physics of a problem and therefore involve lengthy expressions. Of course, if you would manually do the substitutions before plugging them into some normal for, you would probably arrive at similar results as with OptimizeExpression (probably with better names than $1, $2 and so on).

Does Mathematica now have something which I am unaware of to let Solve, Roots and the like memorize substitutions done before they arrive at their result?

$\endgroup$
  • $\begingroup$ Evaluate Names["*`OptimizeExpression"]. $\endgroup$ – Szabolcs Oct 22 '16 at 12:21
  • $\begingroup$ Scabolcs, thank you for the trick to search for a displaced function using Names. I did not know that before. I found the hint mentioned below after searching in other posts under the tag "c-codegenerator". $\endgroup$ – Adalbert Hanßen Oct 22 '16 at 13:32
2
$\begingroup$

Perhaps Experimental`OptimizeExpression` is it. But when I originally used it (probably with Mma4.0), I used an option OptimizeLevel -> -1 which seems to no longer work.

In[13]:=  Needs["Experimental`"]    
In[15]:= ?Experimental`OptimizeExpression    
Experimental`OptimizeExpression    
Attributes[OptimizeExpression]={Protected}     
Options[OptimizeExpression]={ExcludedForms->{},ExternalForms->{},InertForms->{},OptimizationLevel->1,OptimizationSymbol->Compile`$}   

In[16]:= Options[Experimental`OptimizeExpression]    
Out[16]= {ExcludedForms -> {}, "ExternalForms" -> {}, "InertForms" -> {}, 
 "OptimizationLevel" -> 1, "OptimizationSymbol" -> Compile`$}

Did the name change from OptimizeLeve to OptimizationLevel?

The function from Experimental seems to be something similar, but not equal. This apparently worked long ago:

Solve[{px,py,pz}+d*{rx,ry,rz}=={x,y,Sqrt[r^2-x^2-y^2]},{x,y,d}] // OptimizeExpression[#,OptimizeLevel -> -1]&

and the result was:

OptimizedExpression[Module[{$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, 
   $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28}, 
  $1 = rx^2; $2 = ry^2; $3 = rz^2; $4 = $1 + $2 + $3; $5 = $4^(-1); $6 = -(px*$1*$5); 
   $7 = -(py*rx*ry*$5); $8 = -(pz*rx*rz*$5); $9 = 2*px*rx; $10 = 2*py*ry; $11 = 2*pz*rz; 
   $12 = $10 + $11 + $9; $13 = $12^2; $14 = px^2; $15 = py^2; $16 = pz^2; $17 = r^2; 
   $18 = -$17; $19 = $14 + $15 + $16 + $18; $20 = -4*$19*$4; $21 = $13 + $20; 
   $22 = Sqrt[$21]; $23 = -(px*rx*ry*$5); $24 = -(py*$2*$5); $25 = -(pz*ry*rz*$5); 
   $26 = -2*px*rx; $27 = -2*py*ry; $28 = -2*pz*rz; 
   {{x -> px - (rx*$22*$5)/2 + $6 + $7 + $8, y -> py + $23 + $24 + $25 - (ry*$22*$5)/2, 
     l -> ((-$22 + $26 + $27 + $28)*$5)/2}, {x -> px + (rx*$22*$5)/2 + $6 + $7 + $8, 
     y -> py + $23 + $24 + $25 + (ry*$22*$5)/2, l -> (($22 + $26 + $27 + $28)*$5)/2}}]]

but the new function no longer operates on the rhs of rules as the old one did. This does not work:

sol=Solve[{px,py,pz}+d*{rx,ry,rz}=={x,y,Sqrt[r^2-x^2-y^2]},{x,y,d}]
Experimental`OptimizeExpression[sol[[1]]]

But this one does

Experimental`OptimizeExpression[{x, y, d} /. sol[[1]]]

and it results in a Block in which some intermediate results (which are named Compile`\$1, Compile`\$2, ... now) are computed and used in the final expression

{px - px Compile`$40 Compile`$44 - py rx ry Compile`$44 - 
  pz rx rz Compile`$44 - (rx Compile`$44 Compile`$61)/2, 
 py - px rx ry Compile`$44 - py Compile`$41 Compile`$44 - 
  pz ry rz Compile`$44 - (ry Compile`$44 Compile`$61)/2, 
 1/2 Compile`$44 (-2 px rx - 2 py ry - 2 pz rz - Compile`$61)}

Unfortunately this is not a complete answer but just a starting point.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.