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