Re: Re: RE: Product
- To: mathgroup at smc.vnet.net
- Subject: [mg87601] Re: [mg87575] Re: [mg87527] RE: [mg87457] Product
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Mon, 14 Apr 2008 05:43:17 -0400 (EDT)
- References: <200804110542.BAA04653@smc.vnet.net> <200804121059.GAA00044@smc.vnet.net> <200804130733.DAA11567@smc.vnet.net> <48023BF7.5010903@wolfram.com>
You are right of course and actually I realized that lists like {Log[2],....}, which are list sof symbols, can't be backed. But, in fact, I believed that my mytestlist was a list of reals and was quite surprised it was being unpacked. It's partly the fault of always putting thse semicolons at the end so I never say the actual result of the comutation! Andrzej On 14 Apr 2008, at 01:59, Carl Woll wrote: > 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>
- Product