Re: Optimize evaluation of symbolic expressions
- To: mathgroup at smc.vnet.net
- Subject: [mg130959] Re: Optimize evaluation of symbolic expressions
- From: biosthezerg at gmail.com
- Date: Wed, 29 May 2013 03:57:10 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Delivered-to: l-mathgroup@wolfram.com
- Delivered-to: mathgroup-outx@smc.vnet.net
- Delivered-to: mathgroup-newsendx@smc.vnet.net
- References: <h4ef4m$t1b$1@smc.vnet.net> <h4h23q$ifr$1@smc.vnet.net>
On Sunday, 26 July 2009 08:54:34 UTC+1, Stonewall Ballard wrote: > On Jul 25, 4:18 am, Harrie Kraai <hakr... at xs4all.nl> wrote: > > > ... > > If I would program this myself, I would, of course, evaluate the > > subexpression (1 + x^2 + y^2) first and use this result 4 times in the > > subsequent calculations. > > > > It looks to me like Mathematica is not able to or at least does not make > > this optimization. (Find out using 'Trace'). Perhaps this is difficult > > to do in a general sense because any subexpression may have > > side-effects. However, in this case it should be possible to instruct > > Mathematica to collect common subexpressions first. It would surely make > > calculations much faster. > > The symbolic calculations have led to an expression that is > > "Simplify"-ed in terms of reading (perhaps) but not in terms of > > evaluation. Is there, or should there be a function that translates > > expressions to a form that is optimized for evaluation? > >... > > I have read that internally, Mathematica recognizes common > subexpressions and evaluates them only once. That doesn't help me when > I use Mathematica to create C code, so I wrote an explicit common > subexpression hoister that rewrites an expression into one with > variables holding multiply-used parts. It's not perfect, but it works > for me. > <http://stoney.sb.org/wordpress/2009/06/converting-symbolic- > mathematica-expressions-to-c-code/> > > Maybe this would be useful to you too. > > - Stoney Hi, I'm having a similar problem... I have generated a set of expressions in Mathematica, in a format like: (a X1 + b X2 + c X3 + d) / (e X1 + f X2 + g X3 + h) + (i X1 + j X2 + k X3 + l)(m X1 + n X2 + o X3 + p)/(q X1 + r X2 + s X3 + t)^2 , here is an example: >(-C1 (-k13 Cos[r1] Cos[r2] Cos[r3] - k11 Cos[r2] Sin[r1]) + > X1 (-k13 Cos[r1] Cos[r2] Cos[r3] - k11 Cos[r2] Sin[r1]) - > C3 (k11 Cos[r1] - k13 Cos[r3] Sin[r1]) + > X3 (k11 Cos[r1] - k13 Cos[r3] Sin[r1]) - > C2 (-k13 Cos[r1] Cos[r3] Sin[r2] - k11 Sin[r1] Sin[r2]) + > X2 (-k13 Cos[r1] Cos[r3] Sin[r2] - k11 Sin[r1] Sin[r2]))/(-C3 Cos[ > r1] Cos[r3] + X3 Cos[r1] Cos[r3] - > C2 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3]) + > X2 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3]) - > C1 (-Cos[r2] Cos[r3] Sin[r1] + Sin[r2] Sin[r3]) + > X1 (-Cos[r2] Cos[r3] Sin[r1] + > Sin[r2] Sin[r3])) - ((C1 Cos[r1] Cos[r2] Cos[r3] - > X1 Cos[r1] Cos[r2] Cos[r3] + C3 Cos[r3] Sin[r1] - > X3 Cos[r3] Sin[r1] + C2 Cos[r1] Cos[r3] Sin[r2] - > X2 Cos[r1] Cos[r3] Sin[ > r2]) (-C3 (k13 Cos[r1] Cos[r3] + k11 Sin[r1]) + > X3 (k13 Cos[r1] Cos[r3] + k11 Sin[r1]) - > C2 (k11 Cos[r1] Sin[r2] + > k13 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3])) + > X2 (k11 Cos[r1] Sin[r2] + > k13 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3])) - > C1 (k11 Cos[r1] Cos[r2] + > k13 (-Cos[r2] Cos[r3] Sin[r1] + Sin[r2] Sin[r3])) + > X1 (k11 Cos[r1] Cos[r2] + > k13 (-Cos[r2] Cos[r3] Sin[r1] + Sin[r2] Sin[r3]))))/(-C3 Cos[ > r1] Cos[r3] + X3 Cos[r1] Cos[r3] - > C2 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3]) + > X2 (-Cos[r3] Sin[r1] Sin[r2] - Cos[r2] Sin[r3]) - > C1 (-Cos[r2] Cos[r3] Sin[r1] + Sin[r2] Sin[r3]) + > X1 (-Cos[r2] Cos[r3] Sin[r1] + Sin[r2] Sin[r3]))^2 and I would like to make a C source code of it too... the syntax is not a problem, the optimisation is. C's, k's and r's are just scalars, so I can precompute all of them beforehand. On the other hand, X's are large arrays. I looked all over the internet, played with OptimizeExpression, Hold,..., but nothing helped. I tried your solution then. It looks promising, but there are two problems: 1) k12 and k13 just disappeared... I would believe they just cancelled out as they're kinda additive constants, but 1a) they didn't disappear earlier (and neither from my solution in another system (which is too slow anyway)) 1b) the result is just wrong, and 2) how could I set higher weight/cost (e.g. 1000x) for operations with X's? I guess I need to change the opCost function, but could you give me a hint please? Thanks a lot in advance! Karel