MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: RE: Product


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>
  • Prev by Date: Re: Cannot Factor an expression
  • Next by Date: Re: Pattern problem: How to count from a long list of numbers all
  • Previous by thread: Re: RE: Product
  • Next by thread: Re: Re: RE: Product