[Date Index]
[Thread Index]
[Author Index]
Re: recode procedural algorithm to faster functional module
*To*: mathgroup at smc.vnet.net
*Subject*: [mg44108] Re: recode procedural algorithm to faster functional module
*From*: "Carl K. Woll" <carlw at u.washington.edu>
*Date*: Thu, 23 Oct 2003 07:14:52 -0400 (EDT)
*Organization*: University of Washington
*References*: <bmqqcl$rjv$1@smc.vnet.net>
*Sender*: owner-wri-mathgroup at wolfram.com
Robert,
If we can assume that the bricks in a particular list do not overlap, then
there is no need to check every brick in V1 with every brick in V2 as you do
in your code, and I believe as everyone else in this thread does with their
code. A much faster approach is then the following:
pc2[v1_List, v2_List] :=
Module[{min = Min[v1, v2] - 1, max = Max[v1, v2] + 1},
v1f =
Interpolation[
Transpose[{Flatten[{min, v1, max}],
Flatten[Table[{1, 0}, {Length[v1] + 1}]]}],
InterpolationOrder -> 0];
v2f =
Interpolation[
Transpose[{-Flatten[{min, v2, max}],
Flatten[Table[{0, 1}, {Length[v2] + 1}]]}],
InterpolationOrder -> 0];
Round[Plus @@ v1f[v2[[All, 1]]] + Plus @@ v2f[-v1[[All, 1]]]]]
The basic idea is that the Interpolating functions carry the information
about where each brick in a particular list is, and we can use this function
to find out which of the bricks in the other list overlap these bricks. The
one tricky part is that the zeroth order interpolation treats the intervals
as (a,b], so we have to be creative to come up with an interpolating
function which treats the intervals as [a,b). For example,
v1 = Table[{i - Random[]/3, i + Random[]/3}, {i, 1, 100}];
v2 = Table[{i - Random[]/3, i + Random[]/3}, {i, 1/2, 1000 + 1/2}];
yields lists where the bricks in the list do not overlap. With pc1 being
your original function, we find:
In[36]:=
Timing[pc1[v1, v2]]
Timing[pc2[v1, v2]]
Out[36]=
{2.312 Second, 26}
Out[37]=
{0.032 Second, 26}
The function pc2 is almost two orders of magnitude faster in this example,
so it ought to be faster than other proposed alternatives.
If the bricks in a single list do overlap, then the interpolating function
approach can still work, it would just require a slight modification (the
interpolating function will have to return the number of bricks at any
point). I also considered using the Interval function which I think was
comparable in speed to the above approach, but the Interval function
approach can not be modified to handle overlapping bricks in a single list.
Carl Woll
"Prince-Wright, Robert G SEPCO" <robert.prince-wright at shell.com> wrote in
message news:bmqqcl$rjv$1 at smc.vnet.net...
>
> Can someone please help me recode this Module so it is less procedural
> and hopefully runs a lot faster. The Lists V1 and V2 represent two time
> series with 'bricks' laid out along them. The Bricks have varying length
> set by v[[i]][[1]] and v[[i]][[2]] and the idea is to count the number
> of times there is an overlap. I can only see the dumb procedural way of
> taking each brick and checking if it overlaps in time with another!
>
>
>
> Concurrence[v1_List, v2_List,nsim_]:=Module [
>
> {k=1,c=0},
> Do[
> Do[
> Which[
> v1[[i]][[1]] == v2[[k]][[1]], c=c+1,
> v1[[i]][[1]] < v2[[k]][[1]] && v1[[i]][[2]] > v2[[k]][[1]], c=c+1,
> v1[[i]][[1]] > v2[[k]][[1]] && v1[[i]][[1]] < v2[[k]][[2]], c=c+1
> ];
> (*Write[ strm1, {v1[[i]][[1]],v2[[i]][[1]],c}];*)
> , {i,1,nsim}
> ], {k,1,nsim}
> ];
> c
> ]
>
> I've have a PowerPoint illustration if this is unclear and can e-mail it.
>
> thanks
> Robert Prince-Wright
>
Prev by Date:
**Re: Integrate with piecewise function**
Next by Date:
**Re: Integrate piecewise with Assumptions**
Previous by thread:
**Re: Re: recode procedural algorithm to faster functional module**
Next by thread:
**Re: recode procedural algorithm to faster functional module**
| |