LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
SeedList.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
31 #ifndef LSST_AP_CLUSTER_DETAIL_SEEDLIST_CC
32 #define LSST_AP_CLUSTER_DETAIL_SEEDLIST_CC
33 
34 #include "SeedList.h"
35 
36 
37 namespace lsst { namespace ap { namespace cluster { namespace detail {
38 
39 template <int K, typename DataT>
41  _heap(new int[numPoints]),
42  _points(points),
43  _size(0),
44  _numPoints(numPoints)
45 { }
46 
47 template <int K, typename DataT>
49 
51 template <int K, typename DataT>
52 inline bool SeedList<K, DataT>::empty() const {
53  return _size == 0;
54 }
55 
57 template <int K, typename DataT>
58 inline int SeedList<K, DataT>::size() const {
59  return _size;
60 }
61 
63 template <int K, typename DataT>
64 inline int SeedList<K, DataT>::capacity() const {
65  return _numPoints;
66 }
67 
73 template <int K, typename DataT>
75  int s = _size;
76  if (s == 0) {
77  return -1;
78  }
79  int smallest = _heap[0];
80  _points[smallest].state = Point<K, DataT>::PROCESSED;
81  _size = --s;
82  if (s > 1) {
83  siftDown(_heap[s]);
84  } else if (s == 1) {
85  int i = _heap[1];
86  _heap[0] = i;
87  _points[i].state = 0;
88  }
89  return smallest;
90 }
91 
97 template <int K, typename DataT>
98 inline void SeedList<K, DataT>::add(int i) {
99  assert(i >= 0 && i < _numPoints);
100  assert(_size < _numPoints);
101  int s = _size;
102  _size = s + 1;
103  if (s == 0) {
104  _heap[0] = i;
105  _points[i].state = 0;
106  } else {
107  siftUp(s, i);
108  }
109 }
110 
118 template <int K, typename DataT>
119 inline void SeedList<K, DataT>::update(int i, double reach) {
120  assert(i >= 0 && i < _numPoints);
121  int heapIndex = _points[i].state;
122  if (heapIndex >= 0) {
123  assert(_heap[heapIndex] == i);
124  // the i-th point is already in the seed list
125  if (reach < _points[i].reach) {
126  _points[i].reach = reach;
127  siftUp(heapIndex, i);
128  }
129  } else {
130  // add i-th point to the seed list
131  _points[i].reach = reach;
132  add(i);
133  }
134 }
135 
136 template <int K, typename DataT>
137 inline void SeedList<K, DataT>::siftUp(int heapIndex, int pointIndex) {
138  assert(heapIndex < _size);
139  assert(pointIndex >= 0 && pointIndex < _numPoints);
140  double reach = _points[pointIndex].reach;
141  while (heapIndex > 0) {
142  int parentHeapIndex = (heapIndex - 1) >> 1;
143  int parentPointIndex = _heap[parentHeapIndex];
144  if (_points[parentPointIndex].reach <= reach) {
145  break;
146  }
147  _heap[heapIndex] = parentPointIndex;
148  _points[parentPointIndex].state = heapIndex;
149  heapIndex = parentHeapIndex;
150  }
151  _heap[heapIndex] = pointIndex;
152  _points[pointIndex].state = heapIndex;
153 }
154 
155 template <int K, typename DataT>
156 inline void SeedList<K, DataT>::siftDown(int pointIndex) {
157  assert(pointIndex >= 0 && pointIndex < _numPoints);
158  double reach = _points[pointIndex].reach;
159  int halfSize = _size >> 1;
160  int heapIndex = 0;
161  while (heapIndex < halfSize) {
162  int childHeapIndex = (heapIndex << 1) + 1;
163  int siblingHeapIndex = childHeapIndex + 1;
164  int childPointIndex = _heap[childHeapIndex];
165  double childReach = _points[childPointIndex].reach;
166  if (siblingHeapIndex < _size) {
167  int siblingPointIndex = _heap[siblingHeapIndex];
168  double siblingReach = _points[siblingPointIndex].reach;
169  if (siblingReach < childReach) {
170  childReach = siblingReach;
171  childPointIndex = siblingPointIndex;
172  childHeapIndex = siblingHeapIndex;
173  }
174  }
175  if (reach <= childReach) {
176  break;
177  }
178  _heap[heapIndex] = childPointIndex;
179  _points[childPointIndex].state = heapIndex;
180  heapIndex = childHeapIndex;
181  }
182  _heap[heapIndex] = pointIndex;
183  _points[pointIndex].state = heapIndex;
184 }
185 
189 template <int K, typename DataT>
191  // check that each point knows its location in the seed list
192  for (int i = 0; i < _numPoints; ++i) {
193  int h = _points[i].state;
194  if (h >= 0) {
195  if (h >= _size) {
196  // point has an invalid index into the seed list
197  return false;
198  }
199  if (_heap[h] != i) {
200  // point has an incorrect index into the seed list
201  return false;
202  }
203  }
204  }
205  for (int i = 0; i < _size; ++i) {
206  int p = _heap[i];
207  if (p < 0 || p >= _numPoints) {
208  // heap contains an invalid point index
209  return false;
210  }
211  if (_points[p].state != i) {
212  // point has an incorrect index into the seed list
213  return false;
214  }
215  }
216  // check the heap invariant
217  for (int i = 0; i < _size >> 1; ++i) {
218  double reach = _points[_heap[i]].reach;
219  int h = (i << 1) + 1;
220  int p = _heap[h];
221  if (_points[p].reach < reach) {
222  return false;
223  }
224  h += 1;
225  if (h < _size) {
226  int p = _heap[h];
227  if (_points[p].reach < reach) {
228  return false;
229  }
230  }
231  }
232  return true;
233 }
234 
235 }}}} // namespace lsst:ap::cluster::detail
236 
237 #endif // LSST_AP_CLUSTER_DETAIL_SEEDLIST_CC
Class that maintains the OPTICS seed list.
void siftUp(int heapIndex, int pointIndex)
Definition: SeedList.cc:137
std::vector< SourceCatalog > const cluster(SourceCatalog const &sources, ClusteringControl const &control)
Definition: clustering.cc:578
void update(int i, double reach)
Definition: SeedList.cc:119
SeedList(Point< K, DataT > *points, int numPoints)
Definition: SeedList.cc:40
int capacity() const
Returns the capacity of this seed list.
Definition: SeedList.cc:64
std::vector< std::pair< Angle, Ref * > > _heap
int size() const
Returns the number of entries in this seed list.
Definition: SeedList.cc:58
void siftDown(int pointIndex)
Definition: SeedList.cc:156
bool empty() const
Returns true if this seed list contains no entries.
Definition: SeedList.cc:52