Re: Re: RE: Product

*To*: mathgroup at smc.vnet.net*Subject*: [mg87588] Re: [mg87575] Re: [mg87527] RE: [mg87457] Product*From*: Carl Woll <carlw at wolfram.com>*Date*: Mon, 14 Apr 2008 05:40:50 -0400 (EDT)*References*: <200804110542.BAA04653@smc.vnet.net> <200804121059.GAA00044@smc.vnet.net> <200804130733.DAA11567@smc.vnet.net>

Andrzej Kozlowski wrote: >The reason for the speed of Total unlike Plus is that it does not need >to unpack packed arrays. Here is how you can see what happens. > >SetSystemOptions["PackedArrayOptions" -> {"UnpackMessage" -> True}]; > >mytestlist = Table[RandomInteger[{1, 9}], {1000000}]; > > Note that mytestlist is a list of integers. >Developer`PackedArrayQ[mytestlist] >True > >So mytestlist is a packed array. Now let's see what happens if we add >it up using Plus: > >In[4]:= Plus @@ mytestlist >During evaluation of In[4]:= Developer`FromPackedArray::"unpack1" : >"Unpacking array." >During evaluation of In[4]:= Developer`FromPackedArray::"punpack1" : >"Unpacking array to >Out[4]= 4998322 > >Now the same with Total: > >In[5]:= Total[mytestlist] >Out[5]= 4998322 > >It is the unpacking of packed arrays by Plus that makes adding up this >list using Plus much slower. >As for multiplying: I can't think of any way to multiply the elements >of a list without unpacking. However, if, as in your example, the list >contains only positive numbers the following will still beat Times >(though not by much): > >Timing[b = Exp[Total[Log[mytestlist]]]; ] >During evaluation of In[3]:= Developer`FromPackedArray::"unpack1" : >"Unpacking array." >During evaluation of In[3]:= Developer`FromPackedArray::"unpack" : >"Unpacking array in call to Log >{2.0021780000000007, Null} > > Note that {Log[2], Log[8], ...} cannot be a packed array of integers or reals. If one were to use: mytestlist = Table[RandomReal[{1, 9}], {1000000}]; then the Exp[Total[Log[mytestlist]]] approach would be a couple orders of magnitude faster. In[824]:= Timing[b = Exp[Total[Log[mytestlist]]]] Timing[c = Times @@ mytestlist] Out[824]= {0.016,3.490395044*10^639025} Out[825]= {1.156,3.490395043914*10^639025} Also, if one wants to extend this to a list of both positive and negative numbers (without 0, of course) then there are two possibilities. The simplest and probably best is to just do the same using Abs and counting the number of negative numbers. The other possibility is to convert mytestlist into a packed array of complex numbers. For example: mytestlist = Table[RandomReal[{-1,1}], {1000000}]; In[836]:= Timing[b = Exp[Total[Log[Developer`ToPackedArray[mytestlist, Complex]]]]] Timing[c = Times @@ mytestlist] Out[836]= {0.125,-2.460527426692644*10^-434382+1.049783920030347*10^-434390 I} Out[837]= {1.125,-2.460527426692*10^-434382} Here one would take the real part at the end, of course. Carl Woll Wolfram Research >while > >In[4]:= Timing[a = Times @@ mytestlist; ] >During evaluation of In[4]:= Developer`FromPackedArray::"unpack1" : >"Unpacking array." >During evaluation of In[4]:= Developer`FromPackedArray::"punpack1" : >"Unpacking array to level 1 >{0.30934300000000015, Null} > >a == b >True > >If there is a method of multiplying without unpacking it should be a >lot faster but at least at this moment I can't think of one. > >Andrzej Kozlowski > > > >On 12 Apr 2008, at 19:59, Jose Luis Gomez wrote: > > >>(* Steven *) >>(* I think it is an interesting question *) >>(* See what happens when we compare total with other ways to add >>many small >>integers *) >> >>(* First a test list:*) >> >>In[1]:= mytestlist = Table[RandomInteger[{1, 9}], {1000000}]; >> >>(* add all the numbers in the list, and also report the computer >>time used >>to calculate:*) >> >>In[2]:= Timing[Plus @@ mytestlist] >> >>Out[2]= {0.266, 5003966} >> >>(* AGAIN add all the numbers in the list, BUT THIS TIME USING TOTAL >>and also >>report the computer time used to calculate:*) >> >>In[3]:= Timing[Total[mytestlist]] >> >>Out[3]= {0.031, 5003966} >> >>(* As you can see, for small integers, Total has a special algorithm >>that >>that adds ten times faster than just add all the numbers in order*) >>(* Therefore your question is equivalent to ask if there is an >>improved >>algorithm to multiply numbers, and if that algorithm is implemented >>in a >>special command in Mathematica, equivalent to Total*) >> >>(* I do not know the answer, while someone else answers this, you can >>multiply the following way:*) >> >>In[4]:= Times @@ mytestlist >> >>(* large result deleted *) >> >>(* The following link might be interesting for you:*) >>(* http://homepage.cem.itesm.mx/lgomez/matecmatica/fp/fp.html *) >>(* http://homepage.cem.itesm.mx/lgomez/matecmatica/funcionalprog.nb *) >> >>(* Hope that helps *) >>(* Jose *) >>(* Mexico *) >> >>-----Mensaje original----- >>De: Steven [mailto:steven_504 at telenet.be] >>Enviado el: Viernes, 11 de Abril de 2008 12:43 a.m. >>Para: mathgroup at smc.vnet.net >>Asunto: [mg87457] Product >> >>Silly beginner's question: is there a function to multiply all >>elements of a >>list, like Total does for addition? >>'fraid I can't find it. >>TIA >> >> >> >> >> > > >

**References**:**Product***From:*"Steven" <steven_504@telenet.be>

**RE: Product***From:*"Jose Luis Gomez" <jose.luis.gomez@itesm.mx>

**Re: RE: Product***From:*Andrzej Kozlowski <akoz@mimuw.edu.pl>