43 namespace lsst {
namespace ap {
namespace match {
namespace detail {
47 template <
typename Node>
50 typedef typename std::vector<HeapEntry>::iterator Iter;
52 for (Iter i =
_heap.begin(), e =
_heap.end(); i != e; ++i) {
62 template <
typename Node>
64 return _isBinarySearchTree(_root) &&
65 _isRedChildBlack(_root) &&
72 template <
typename Node>
86 double const maxCoord0 = i->maxCoord0;
95 if (p != 0 && p->color !=
BLACK) {
97 int d = (ggp->link[1] == gp);
98 if (i == p->link[lastDir]) {
99 ggp->link[
d] = _rotate(gp, !lastDir);
101 ggp->link[
d] = _doubleRotate(gp, !lastDir);
108 if (maxCoord0 > n->reach) {
109 n->reach = maxCoord0;
111 Node *c0 = n->link[0];
112 Node *c1 = n->link[1];
113 if (c0 != 0 && c1 != 0 && c0->color !=
BLACK && c1->color !=
BLACK) {
119 if (n->color !=
BLACK && p != 0 && p->color !=
BLACK) {
121 int d = (ggp->link[1] == gp);
122 if (n == p->link[lastDir]) {
123 ggp->link[
d] = _rotate(gp, !lastDir);
125 ggp->link[
d] = _doubleRotate(gp, !lastDir);
137 _root = head.link[1];
138 _root->color =
BLACK;
143 template <
typename Node>
150 Node *stack[2*
sizeof(size_t)*CHAR_BIT];
155 head.link[1] = _root;
159 while (n->link[dir] != 0) {
170 if (n->color ==
BLACK &&
171 (n->link[dir] == 0 || n->link[dir]->color ==
BLACK)) {
172 if (n->link[!dir] != 0 && n->link[!dir]->color !=
BLACK) {
174 p = p->link[lastDir] = _rotate(n, dir);
176 Node *s = p->link[!lastDir];
178 Node *sld = s->link[lastDir];
179 Node *snld = s->link[!lastDir];
180 if ((sld == 0 || sld->color ==
BLACK) &&
181 (snld == 0 || snld->color ==
BLACK)) {
188 int d = (gp->link[1] == p);
189 if (sld != 0 && sld->color ==
RED) {
190 stack[level++] = sld;
191 s = _doubleRotate(p, lastDir);
194 s = _rotate(p, lastDir);
200 s->link[0]->color =
BLACK;
201 s->link[1]->color =
BLACK;
208 p->link[p->link[1] == n] = n->link[n->link[0] == 0];
212 for (; level > 0; p = stack[--level]) {
215 n->link[0] = r->link[0];
216 n->link[1] = r->link[1];
218 gp = stack[level - 1];
219 gp->link[gp->link[1] == r] = n;
222 p->reach = _reach(p);
226 _root = head.link[1];
228 _root->color =
BLACK;
235 template <
typename Node>
237 typename std::vector<std::pair<double, Node *> >::size_type n)
240 throw std::length_error(
"cannot expand vector: "
241 "max_size() would be exceeded");
243 typename std::vector<std::pair<double, Node *> >::size_type c = 2*
_heap.size();
247 if (c <
_heap.size() || c >
_heap.max_size()) {
248 c =
_heap.max_size();
256 template <
typename Node>
261 if ((n->link[0] != 0 &&
lessThan(n, n->link[0])) ||
262 (n->link[1] != 0 &&
lessThan(n->link[1], n))) {
265 return _isBinarySearchTree(n->link[0]) &&
266 _isBinarySearchTree(n->link[1]);
271 template <
typename Node>
276 if (n->color ==
RED) {
277 if ((n->link[0] != 0 && n->link[0]->color ==
RED) ||
278 (n->link[1] != 0 && n->link[1]->color ==
RED)) {
282 return _isRedChildBlack(n->link[0]) &&
283 _isRedChildBlack(n->link[1]);
288 template <
typename Node>
294 if (n->color ==
BLACK) {
300 return _isBalanced(_root, numBlack);
305 template <
typename Node>
308 return (numBlack == 0);
310 if (n->color ==
BLACK) {
313 return _isBalanced(n->link[0], numBlack) &&
314 _isBalanced(n->link[1], numBlack);
319 template <
typename Node>
321 double reach = _checkReach(_root);
329 template <
typename Node>
332 return -std::numeric_limits<double>::infinity();
334 double r0 = _checkReach(n->link[0]);
338 double r1 = _checkReach(n->link[1]);
343 return (r == n->reach) ? r : std::numeric_limits<double>::quiet_NaN();
388 b, 0.0, static_cast<double>(max));
413 b, static_cast<double>(min),
static_cast<double>(
max));
virtual double getMinCoord0() const =0
bool _isIntervalTree() const
static bool _isBinarySearchTree(Node const *n)
static bool _isRedChildBlack(Node const *n)
virtual bool isValid() const
AngleUnit const radians
constant with units of radians
virtual ~SweepStructure()
virtual double getMaxCoord0() const =0
std::pair< double, Node * > HeapEntry
virtual double getMaxCoord1() const =0
bool lessThan(CartesianNode const *a, CartesianNode const *b)
std::vector< std::pair< Angle, Ref * > > _heap
lsst::afw::geom::Angle Angle
Arena< MatchablePos > _arena
void _grow(typename std::vector< HeapEntry >::size_type n)
static double _checkReach(Node const *n)
afw::table::Key< double > b
Sweep line data structures useful for region-region matching.
void thetaRangeReduce(Angle &min, Angle &max)