Re: A programming puzzle.

*To*: mathgroup at smc.vnet.net*Subject*: [mg60873] Re: A programming puzzle.*From*: Peter Pein <petsie at dordos.net>*Date*: Sat, 1 Oct 2005 02:55:48 -0400 (EDT)*References*: <dhge6k$1kg$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

jackgoldberg at comcast.net schrieb: > Hello everyone, > > I have a simple problem for which I would like an "elegant" solution. The problem is to convert the series > > a1*b1 + a2*b2 + a3*b3 + ... + an*bn > > into the equivalent series > > a1(b1 - b2) + (a1+a2)(b2 - b3) + ... +(a1 + a2 + ... + an-1)(bn-1 - bn) + > (a1 + a2 + ... + an)bn > > This process, I believe, is called summation-by-parts. This problem is not hard to do; one simply separates the ai's from the bi's, constructs the "partial" sums for the ai series and the differences for the bi series. Then a dot product gets the answer. I am interested in a more elegant solution, if one exists. > Taking care of all special cases will probably make any solution rather inelegant, so I am taking the liberty granted to all posers of only allowing series which have at least two terms AND the bi's are not constants and bi = bj is prohibited unless i = j. (This is, in fact, the situation I am concerned with.) > > I think some of you will have fun connocting ingenious solutions ... Let me know if you find any. Incidentally, timing is not crucial in my applications of "summation-by-parts" nor is storage of intermediate computations a problem. Thanks! > > Jack Goldberg > Another approach is to expand the series of the product around b1=b2, b2=b3 and so on (it's ugly, bcause I forced it into one (syntactic) line): In[1]:= sumbyparts[pr_]:= ((Plus@@(Last/@#)-pr)+Factor[#[[-1,1]]])&@ FoldList[(Take[Series[#1[[1]],Append[#2,1]][[3]],2]*{1, Subtract@@#2})&,{pr}, Transpose[Drop[(List@@pr)/.x_*y_\[RuleDelayed]y,#]&/@{-1,1}]] In[2]:= test5=(a/@#).(b/@#)&@Range[5]; In[3]:= sumbyparts[test5]//InputForm Out[3]//InputForm= a[1]*(b[1] - b[2]) + (a[1] + a[2])*(b[2] - b[3]) + (a[1] + a[2] + a[3])*(b[3] - b[4]) + (a[1] + a[2] + a[3] + a[4])*(b[4] - b[5]) + (a[1] + a[2] + a[3] + a[4] + a[5])*b[5] In[4]:= %//Expand//InputForm Out[4]//InputForm= a[1]*b[1] + a[2]*b[2] + a[3]*b[3] + a[4]*b[4] + a[5]*b[5] In[5]:= sumbyparts[3x+2y+c z]//InputForm Out[5]//InputForm= 3*(x - y) + 5*(y - z) + (5 + c)*z In[6]:= %//Expand//InputForm Out[6]//InputForm= 3*x + 2*y + c*z Tricky? Maybe... Elegant? NO. Peter