Пример #1
0
node<P> batch_create(DistanceCallback& dcb, v_array<P> points)
{
	assert(points.index > 0);
	v_array<ds_node<P> > point_set;
	v_array<v_array<ds_node<P> > > stack;

	for (int i = 1; i < points.index; i++) {
		ds_node<P> temp;
		push(temp.dist, distance(dcb, points[0], points[i], std::numeric_limits<ScalarType>::max()));
		temp.p = points[i];
		push(point_set,temp);
	}

	v_array<ds_node<P> > consumed_set;

	ScalarType max_dist = max_set(point_set);

	node<P> top = batch_insert (dcb, points[0],
			get_scale(max_dist),
			get_scale(max_dist),
			point_set,
			consumed_set,
			stack);
	for (int i = 0; i<consumed_set.index;i++)
		free(consumed_set[i].dist.elements);
	free(consumed_set.elements);
	for (int i = 0; i<stack.index;i++)
		free(stack[i].elements);
	free(stack.elements);
	free(point_set.elements);
	return top;
}
Пример #2
0
template<class T> node<T> batch_create(const std::vector<T> &points,
					typename distfn<T>::Type distance,
					const double* dist_params, void* dist_extra)
{
  v_array<ds_node<T> > point_set;
  v_array<v_array<ds_node<T> > > stack;

  ds_node<T> initial_pt;
  initial_pt.p = points[0];
  for (std::vector<point>::size_type i = 1; i < points.size(); i++) {
    ds_node<T> temp;
    push(temp.dist, distance(points[0], points[i], std::numeric_limits< double >::max(), dist_params, dist_extra));
    temp.p = points[i];
    push(point_set,temp);
  }
  v_array< ds_node < T > > consumed_set;

  double max_dist = max_set(point_set);

  node<T> top = batch_insert(initial_pt,
			  get_scale(max_dist),
			  get_scale(max_dist),
			  point_set,
			  consumed_set,
			  stack,
			  distance, dist_params, dist_extra);

  for (int i = 0; i<consumed_set.index;i++)
    free(consumed_set[i].dist.elements);
  free(consumed_set.elements);
  for (int i = 0; i<stack.index;i++)
    free(stack[i].elements);
  free(stack.elements);
  free(point_set.elements);
  return top;
}
Пример #3
0
node<T> batch_insert(const ds_node<T>& p,
		  int max_scale,
		  int top_scale,
		  v_array< ds_node<T> >& point_set,
		  v_array< ds_node<T> >& consumed_set,
		  v_array<v_array< ds_node<T> > >& stack,
		  typename distfn<T>::Type distance,
		const double* dist_params, void* dist_extra)
{
  if (point_set.index == 0) {
    return new_leaf(p);
  } else {
    double max_dist = max_set(point_set); //O(|point_set|)
    int next_scale = min (max_scale - 1, get_scale(max_dist));

    /*
    if ((next_scale == -2147483648) || (top_scale - next_scale > 100) ) {
      printf("whoawhoawhoa\n");
      printf("max_set %f\n", max_dist);
      printf("next scale %d %d %d\n", max_scale-1, get_scale(max_dist), next_scale);
      //printf("p %f %f %f %f\n", p.p.pt1[0], p.p.pt1[1], p.p.pt2[0], p.p.pt2[1]);
      //printf("p %f %f\n", p.p.p[0], p.p.p[1]);
      //printf("ps %f %f %f %f\n", point_set[0].p.pt1[0], point_set[0].p.pt1[1], point_set[0].p.pt2[0], point_set[0].p.pt2[1]);
      printf("distance %f\n", distance(point_set[0].p, p.p, std::numeric_limits< double >::max(), dist_params, dist_extra));
      }*/

    if ((next_scale == -2147483648) || (top_scale - next_scale >= 100)) // We have points with distance 0.
      {
	v_array< node<T> > children;
	push(children,new_leaf(p));
	while (point_set.index > 0)
	  {
	    push(children,new_leaf(point_set.last()));
	    push(consumed_set,point_set.last());
	    point_set.decr();
	  }
	node<T> n = new_node(p);
	n.scale = 100; // A magic number meant to be larger than all scales.
	n.max_dist = 0;
	alloc(children,children.index);
	n.num_children = children.index;
	n.children = children.elements;
	return n;
      }
    else
      {
	v_array< ds_node<T> > far = pop(stack);
	split(point_set,far,max_scale); //O(|point_set|)

	node<T> child = batch_insert(p, next_scale, top_scale,
				  point_set, consumed_set, stack,
				  distance, dist_params, dist_extra);

	if (point_set.index == 0)
	  {
	    push(stack,point_set);
	    point_set=far;
	    return child;
	  }
	else {
	  node<T> n = new_node(p);
	  v_array< node<T> > children;
	  push(children, child);
	  v_array<ds_node<T> > new_point_set = pop(stack);
	  v_array<ds_node<T> > new_consumed_set = pop(stack);
	  while (point_set.index != 0) { //O(|point_set| * num_children)
	    ds_node<T> new_point_node = point_set.last();
	    T new_point = point_set.last().p;
	    double new_dist = point_set.last().dist.last();
	    push(consumed_set, point_set.last());
	    point_set.decr();

	    dist_split(point_set, new_point_set, new_point, max_scale, distance, dist_params, dist_extra); //O(|point_saet|)
	    dist_split(far,new_point_set,new_point,max_scale, distance, dist_params, dist_extra); //O(|far|)

	    node<T> new_child =
	      batch_insert(new_point_node, next_scale, top_scale,
			   new_point_set, new_consumed_set, stack,
			   distance, dist_params, dist_extra);
	    new_child.parent_dist = new_dist;

	    push(children, new_child);

	    double fmax = dist_of_scale(max_scale);
	    for(int i = 0; i< new_point_set.index; i++) //O(|new_point_set|)
	      {
		new_point_set[i].dist.decr();
		if (new_point_set[i].dist.last() <= fmax)
		  push(point_set, new_point_set[i]);
		else
		  push(far, new_point_set[i]);
	      }
	    for(int i = 0; i< new_consumed_set.index; i++) //O(|new_point_set|)
	      {
		new_consumed_set[i].dist.decr();
		push(consumed_set, new_consumed_set[i]);
	      }
	    new_point_set.index = 0;
	    new_consumed_set.index = 0;
	  }
	  push(stack,new_point_set);
	  push(stack,new_consumed_set);
	  push(stack,point_set);
	  point_set=far;
	  n.scale = top_scale - max_scale;
	  n.max_dist = max_set(consumed_set);
	  alloc(children,children.index);
	  n.num_children = children.index;
	  n.children = children.elements;
	  return n;
	}
      }
  }
}
Пример #4
0
node<P> batch_insert(DistanceCallback& dcb, const P& p,
		int max_scale,
		int top_scale,
		v_array<ds_node<P> >& point_set,
		v_array<ds_node<P> >& consumed_set,
		v_array<v_array<ds_node<P> > >& stack)
{
	if (point_set.index == 0)
		return new_leaf(p);
	else {
		ScalarType max_dist = max_set(point_set); //O(|point_set|)
		int next_scale = std::min(max_scale - 1, get_scale(max_dist));
		if (next_scale == -2147483647-1) // We have points with distance 0.
		{
			v_array<node<P> > children;
			push(children,new_leaf(p));
			while (point_set.index > 0)
			{
				push(children,new_leaf(point_set.last().p));
				push(consumed_set,point_set.last());
				point_set.decr();
			}
			node<P> n = new_node(p);
			n.scale = 100; // A magic number meant to be larger than all scales.
			n.max_dist = 0;
			alloc(children,children.index);
			n.num_children = children.index;
			n.children = children.elements;
			return n;
		}
		else
		{
			v_array<ds_node<P> > far = pop(stack);
			split(point_set,far,max_scale); //O(|point_set|)

			node<P> child = batch_insert(dcb, p, next_scale, top_scale, point_set, consumed_set, stack);

			if (point_set.index == 0)
			{
				push(stack,point_set);
				point_set=far;
				return child;
			}
			else {
				node<P> n = new_node(p);
				v_array<node<P> > children;
				push(children, child);
				v_array<ds_node<P> > new_point_set = pop(stack);
				v_array<ds_node<P> > new_consumed_set = pop(stack);
				while (point_set.index != 0) { //O(|point_set| * num_children)
					P new_point = point_set.last().p;
					ScalarType new_dist = point_set.last().dist.last();
					push(consumed_set, point_set.last());
					point_set.decr();

					dist_split(dcb,point_set,new_point_set,new_point,max_scale); //O(|point_saet|)
					dist_split(dcb,far,new_point_set,new_point,max_scale); //O(|far|)

					node<P> new_child =
						batch_insert(dcb, new_point, next_scale, top_scale, new_point_set, new_consumed_set, stack);
					new_child.parent_dist = new_dist;

					push(children, new_child);

					ScalarType fmax = dist_of_scale(max_scale);
					for(int i = 0; i< new_point_set.index; i++) //O(|new_point_set|)
					{
						new_point_set[i].dist.decr();
						if (new_point_set[i].dist.last() <= fmax)
							push(point_set, new_point_set[i]);
						else
							push(far, new_point_set[i]);
					}
					for(int i = 0; i< new_consumed_set.index; i++) //O(|new_point_set|)
					{
						new_consumed_set[i].dist.decr();
						push(consumed_set, new_consumed_set[i]);
					}
					new_point_set.index = 0;
					new_consumed_set.index = 0;
				}
				push(stack,new_point_set);
				push(stack,new_consumed_set);
				push(stack,point_set);
				point_set=far;
				n.scale = top_scale - max_scale;
				n.max_dist = max_set(consumed_set);
				alloc(children,children.index);
				n.num_children = children.index;
				n.children = children.elements;
				return n;
			}
		}
	}
}