MathGroup Archive 2009

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

Search the Archive

Re: Can I do this faster?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg103019] Re: Can I do this faster?
  • From: pfalloon <pfalloon at gmail.com>
  • Date: Fri, 4 Sep 2009 03:14:58 -0400 (EDT)
  • References: <h7o2cd$jtk$1@smc.vnet.net>

On Sep 3, 7:30 pm, Andreas <aa... at ix.netcom.com> wrote:
> I start with two 2 dimensional lists.  The have equal depths, but may
> or may not have equal lengths.  Possible data looks like this:
>
> list1 = RandomReal[{0, 1}, {1500, 3}];
> list2 = RandomReal[ExponentialDistribution[2], {1000, 3}];
>
> The following produces the results I need, but takes longer to run
> than I'd like:
>
> Rest[FoldList[Times, 1,  Transpose[(t = #; 1 + Inner[Times, t, # - 1,
> Plus] & /@ list1) & /@
>     list2]]]
>
> Any suggestions rewriting this so I can make it run faster?
>
> Thanks.

I think the main reason for the slowness is that the Inner function is
much less efficient for large numerical matrices than the standard Dot
function. When you re-express the function using Dot, it is much
faster:

(* original definition *)
f1[list1_,list2_] := Module[{t}, Rest[FoldList[Times, 1,  Transpose[(t
= #; 1 + Inner[Times, t, # - 1, Plus] & /@ list1) & /@ list2]]]]

(* first attempt: incorporate the addition & subtraction into the
Inner function *)
f2[list1_,list2_] := Inner[Times[#1-1,#2] &, list1, Transpose@list2,
Plus[1, ##] &] // FoldList[Times, 1, #] & // Rest

(* best attempt: apply the addition & subtraction to the matrices as a
whole, so we can use the more-efficient Dot function *)
f3[list1_,list2_] := Rest@FoldList[Times, 1, 1+(list1-1).Transpose
[list2]]


Here is an example to show the speed-up:

In[62]:= (* sample matricies *)
list1 = RandomReal[{0, 1}, {1000, 3}];
list2 = RandomReal[ExponentialDistribution[2], {1500, 3}];

In[64]:= (* timings *)
res1=f1[list1, list2]; // AbsoluteTiming
res2=f2[list1, list2]; // AbsoluteTiming
res3=f3[list1, list2]; // AbsoluteTiming

Out[64]= {14.0311602,Null}
Out[65]= {9.7811874,Null}
Out[66]= {1.7187390,Null}

However, in testing this I noticed that the function appears to be
highly unstable numerically -- so you may want to investigate that
further:

(* test correctness of results: appears to be numerically unstable! *)
Max /@ Abs[res1 - res2]
Max /@ Abs[res1 - res3]


Hope this helps!

Cheers,
Peter.


  • Prev by Date: Re: Re: Bug in Solve?
  • Next by Date: Integrate[ 0.0*x, {x, 0, y}]
  • Previous by thread: Re: Re: Can I do this faster?
  • Next by thread: Re: Can I do this faster?