@@ -25,13 +25,13 @@ type opticsClusterer struct {
2525 a , b []int
2626
2727 // variables used for concurrent computation of nearest neighbours and producing final mapping
28- l , s , o , f int
29- j chan * rangeJob
30- c chan * clusterJob
31- m * sync.Mutex
32- w * sync.WaitGroup
33- p * []float64
34- r * []int
28+ l , s , o , f , g int
29+ j chan * rangeJob
30+ c chan * clusterJob
31+ m * sync.Mutex
32+ w * sync.WaitGroup
33+ p * []float64
34+ r * []int
3535
3636 // visited points
3737 v []bool
@@ -251,13 +251,17 @@ func (c *opticsClusterer) update(p int, d float64, l *int, r *[]int, q *priority
251251
252252func (c * opticsClusterer ) extract () {
253253 var (
254- i , k , e , ue , cs , ce , s , p int = 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0
254+ i , k , e , ue , cs , ce , s , p int = 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0
255255 mib , d float64
256256 areas []* steepDownArea = make ([]* steepDownArea , 0 )
257257 clusters map [int ]bool = make (map [int ]bool )
258258 )
259259
260- for i < c .l - 2 {
260+ // first and last points are not assigned the reachability distance, so exclude them from calculations
261+ c .so = c .so [1 : len (c .so )- 2 ]
262+ c .g = len (c .so ) - 2
263+
264+ for i < len (c .so )- 1 {
261265 mib = math .Max (mib , c.re [c.so [i ]].p )
262266
263267 if c .isSteepDown (i , & e ) {
@@ -368,12 +372,16 @@ func (c *opticsClusterer) isSteepDown(i int, e *int) bool {
368372 return false
369373 }
370374
371- var counter , j int = 0 , i + 1
375+ var counter , j int = 0 , i
372376
373377 * e = j
374378
375379 for {
376- if c .re [c .so [j + 1 ]] == nil || c.re [c.so [j ]].p < c .re [c .so [j + 1 ]].p {
380+ if j > c .g {
381+ break
382+ }
383+
384+ if c.re [c.so [j ]].p < c .re [c .so [j + 1 ]].p {
377385 break
378386 }
379387
@@ -391,20 +399,24 @@ func (c *opticsClusterer) isSteepDown(i int, e *int) bool {
391399 j ++
392400 }
393401
394- return * e != i + 1
402+ return * e != i
395403}
396404
397405func (c * opticsClusterer ) isSteepUp (i int , e * int ) bool {
398406 if c.re [c.so [i ]].p > c .re [c .so [i + 1 ]].p * c .x {
399407 return false
400408 }
401409
402- var counter , j int = 0 , i + 1
410+ var counter , j int = 0 , i
403411
404412 * e = j
405413
406414 for {
407- if c .re [c .so [j + 1 ]] == nil || c.re [c.so [j ]].p > c .re [c .so [j + 1 ]].p {
415+ if j > c .g {
416+ break
417+ }
418+
419+ if c.re [c.so [j ]].p > c .re [c .so [j + 1 ]].p {
408420 break
409421 }
410422
@@ -422,7 +434,7 @@ func (c *opticsClusterer) isSteepUp(i int, e *int) bool {
422434 j ++
423435 }
424436
425- return * e != i + 1
437+ return * e != i
426438}
427439
428440func (c * opticsClusterer ) startClusterWorkers () {
0 commit comments