comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Fast way to find the same value in an array
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Fast way to find the same value in an array [message #49284] Sun, 09 July 2006 15:01
greg michael is currently offline  greg michael
Messages: 163
Registered: January 2006
Senior Member
won?! ...I mean lost.
Re: Fast way to find the same value in an array [message #49285 is a reply to message #49284] Sun, 09 July 2006 14:56 Go to previous message
greg michael is currently offline  greg michael
Messages: 163
Registered: January 2006
Senior Member
Hi Boto,

Try this. On my (very ordinary) machine, it takes about 10 secs to
search 1e5, several minutes for 1e6. Didn't try 1e7, but I'd guess not
more than a few hours...

function MakeGalaxies,n
p=replicate({x:0.,y:0.,z:0.},n)
seed=0
p.x=randomu(seed,n)*1000.
p.y=randomu(seed,n)*1000.
p.z=randomu(seed,n)*1000.
return,p
end

function distance,p1,p2
return,sqrt((p2.x-p1.x)^2+(p2.y-p1.y)^2+(p2.z-p1.z)^2)
end

pro search,p,dist
;recursively splits the search volume into n_split^3 subvolumes. When
there are fewer than 'threshold' points
;in a subvolume, checks for matches the brute force way - every point
against every other.

n_split=3
threshold=75

s=(size(p))[1]

if s gt threshold then begin
xmn=min(p.x,max=xmx)
ymn=min(p.y,max=ymx)
zmn=min(p.z,max=zmx)

xg=xmn+findgen(n_split+1)*(xmx-xmn)/n_split ;grid boundaries
yg=ymn+findgen(n_split+1)*(ymx-ymn)/n_split
zg=zmn+findgen(n_split+1)*(zmx-zmn)/n_split

for j=0,n_split-1 do begin
for k=0,n_split-1 do begin
for l=0,n_split-1 do begin
w= where( (p.x ge xg[j]-dist) and (p.x lt xg[j+1]+dist) and $
(p.y ge yg[k]-dist) and (p.y lt yg[k+1]+dist) and $
(p.z ge zg[l]-dist) and (p.z lt zg[l+1]+dist) )
if n_elements(w) ge 2 then begin
res=search(p[w],dist)
endif
endfor
endfor
endfor

endif else begin
for i=0,s-2 do begin
for j=i+1,s-1 do begin
if distance(p[i],p[j]) le dist then begin
print,p[i],p[j]
endif
endfor
endfor

endelse

end


IDL> p=makegalaxies(1e5)
IDL> search,p,.5
{ 454.665 175.794 87.0097}{ 454.816 175.504
87.3471}
{ 556.761 981.076 933.809}{ 556.654 980.922
934.065}
{ 981.340 196.286 105.551}{ 981.387 196.102
105.703}
IDL> p=makegalaxies(1e6)
IDL> search,p,.2
{ 330.280 196.344 99.2760}{ 330.297 196.277
99.4484}
{ 249.980 173.201 640.821}{ 250.142 173.111
640.774}
{ 62.5799 42.0245 779.031}{ 62.4897 41.8944
779.097}
{ 297.023 425.521 640.250}{ 296.952 425.609
640.149}
{ 98.4379 461.400 673.197}{ 98.4014 461.355
673.278}
{ 189.966 444.613 924.605}{ 190.002 444.629
924.567}
{ 161.315 726.953 96.7764}{ 161.361 726.784
96.7790}
{ 254.492 823.492 494.062}{ 254.499 823.541
494.128}
{ 143.837 736.945 891.959}{ 143.846 737.073
892.034}
{ 548.274 302.271 158.284}{ 548.251 302.408
158.257}
{ 638.083 100.108 240.606}{ 638.107 100.159
240.530}
{ 628.376 117.708 191.394}{ 628.338 117.743
191.481}
{ 569.059 497.433 375.822}{ 569.195 497.334
375.896}
{ 519.456 995.505 547.080}{ 519.352 995.619
547.015}
{ 426.479 719.818 849.407}{ 426.415 719.915
849.277}
{ 824.665 139.718 151.656}{ 824.762 139.576
151.754}
{ 873.701 398.928 222.038}{ 873.774 398.952
222.147}
{ 924.378 468.693 62.9666}{ 924.546 468.719
62.9983}
{ 858.907 486.427 717.181}{ 858.761 486.428
717.239}
{ 720.754 820.070 405.199}{ 720.787 820.032
405.215}
{ 781.977 897.380 563.545}{ 782.112 897.508
563.536}

Seems that splitting into 3x3 is better than 10x10. I suspect this is
something to do with how the 'where' expression works. I don't know
much about IDL timing.

Meanwhile, France won...
regards,
Greg
Re: Fast way to find the same value in an array [message #49287 is a reply to message #49285] Sun, 09 July 2006 08:10 Go to previous message
greg michael is currently offline  greg michael
Messages: 163
Registered: January 2006
Senior Member
Instead of comparing each point with every other, suppose you do this:

- cut up your space into NxNxN subspaces (N=10, say)
- sort your points into each subspace
- for each subspace, consider the problem again, but including the
neighbouring subspaces. So now you have 27.N^3 easier sub-problems.
- either solve these directly (now 27.1e7/N^3 ~ 250,000 points) or
better, if you wrote the function well, feed these sub-problems back in
for a recursive solution.

regards,
Greg
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: How to perform a diagramm like these ?
Next Topic: How can I display truecolor image on a map?

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 19:04:41 PDT 2025

Total time taken to generate the page: 0.00573 seconds