43 if (*nsuper >= *nsupermax) {
44 int new_nsupermax = *nsuper + 10;
46 *supernode_wgts =
gv_recalloc(*supernode_wgts, *nsupermax, new_nsupermax,
sizeof(
double));
47 *distances =
gv_recalloc(*distances, *nsupermax, new_nsupermax,
sizeof(
double));
48 *nsupermax = new_nsupermax;
65 for (i = 0; i <
dim; i++){
66 (*center)[
dim*(*nsuper)+i] =
coord[i];
79 for (i = 0; i <
dim; i++){
86 for (i = 0; i < 1<<
dim; i++){
88 supernode_wgts, distances, counts);
96 double **
center,
double **supernode_wgts,
double **distances,
double *counts) {
105 if (!*supernode_wgts) *supernode_wgts =
gv_calloc(nsupermax,
sizeof(
double));
106 if (!*distances) *distances =
gv_calloc(nsupermax,
sizeof(
double));
123 double *force = qt->
data;
135 double *x1, *x2,
dist, wgt1, wgt2, f, *f1, *f2, w1, w2;
136 int dim, i, j, i1, i2, k;
139 if (!qt1 || !qt2)
return;
140 assert(qt1->
n > 0 && qt2->
n > 0);
157 for (k = 0; k <
dim; k++){
158 f = w1 * w2 * KP * (x1[k] - x2[k]) / pow(
dist, 1.0 - p);
179 if ((qt1 == qt2 && i2 < i1) || i1 == i2) {
185 for (k = 0; k <
dim; k++){
186 f = wgt1 * wgt2 * KP * (x1[k] - x2[k]) / pow(
dist, 1.0 - p);
200 for (i = 0; i < 1<<
dim; i++){
202 for (j = i; j < 1<<
dim; j++){
210 for (i = 0; i < 1<<
dim; i++){
215 for (i = 0; i < 1<<
dim; i++){
220 for (i = 0; i < 1<<
dim; i++){
225 for (i = 0; i < 1<<
dim; i++){
256 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
262 for (i = 0; i < 1<<
dim; i++){
269 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
292 int n = qt->
n,
dim = qt->
dim, i;
294 for (i = 0; i < 4; i++) counts[i] = 0;
296 for (i = 0; i <
dim*n; i++) force[i] = 0;
300 for (i = 0; i < 4; i++) counts[i] /= n;
324 for (i = 1; i < n; i++){
325 for (k = 0; k <
dim; k++){
332 for (i = 0; i <
dim; i++) {
334 width = fmax(width,
xmax[i] -
xmin[i]);
336 width = fmax(width, 0.00001);
340 for (i = 0; i < n; i++){
377 for (i = 0; i < 1<<
dim; i++){
397 for (i =
dim - 1; i >= 0; i--){
416 for (k = 0; k <
dim; k++){
437 for (i = 0; i < q->
dim; i++) {
440 fprintf(stderr,
"coordinate %f is outside of the box:{%f, %f}, \n(q->center[i] - q->width) - coord[i] =%g, coord[i]-(q->center[i] + q->width) = %g\n",
coord[i], (q->
center[i] - q->
width), (q->
center[i] + q->
width),
456 }
else if (level < max_level){
466 assert(ii < 1<<
dim && ii >= 0);
478 assert(ii < 1<<
dim && ii >= 0);
486 while (q->
l !=
NULL) {
517 if (dim < 2 || dim > 3)
return;
518 fprintf(fp,
"(*in c*){Line[{");
521 fprintf(fp,
"{%f, %f}",
center[0] + width,
center[1] + width);
522 fprintf(fp,
",{%f, %f}",
center[0] - width,
center[1] + width);
523 fprintf(fp,
",{%f, %f}",
center[0] - width,
center[1] - width);
524 fprintf(fp,
",{%f, %f}",
center[0] + width,
center[1] - width);
525 fprintf(fp,
",{%f, %f}",
center[0] + width,
center[1] + width);
526 }
else if (
dim == 3){
530 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] + width);
531 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] + width);
532 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] + width);
533 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] + width);
538 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] - width);
539 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] - width);
540 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] - width);
541 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] - width);
546 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] + width);
551 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] + width);
556 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] + width);
561 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] + width);
566 fprintf(fp,
"}]}(*end C*)");
583 printf(
",(*a*) {Red,");
585 if (l != l0) printf(
",");
587 fprintf(fp,
"(*node %d*) Point[{", l->
id);
588 for (i = 0; i <
dim; i++){
589 if (i != 0) printf(
",");
590 fprintf(fp,
"%f",
coord[i]);
599 for (i = 0; i < 1<<
dim; i++){
600 fprintf(fp,
",(*b*){");
612 fprintf(fp,
"Graphics[{");
613 }
else if (q->
dim == 3){
614 fprintf(fp,
"Graphics3D[{");
620 fprintf(fp,
"}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
622 fprintf(fp,
"}, PlotRange -> All]\n");
627 double *min,
int *
imin,
640 if(*min < 0 ||
dist < *min) {
643 for (i = 0; i <
dim; i++) y[i] =
coord[i];
650 if (*min >= 0 && (
dist - sqrt((
double)
dim) * qt->
width > *min)){
655 for (i = 0; i < 1<<
dim; i++){
658 if (
dist < qmin || qmin < 0){
666 for (i = 0; i < 1<<
dim; i++){
void QuadTree_get_nearest(QuadTree qt, double *x, double *ymin, int *imin, double *min)
static void QuadTree_print_internal(FILE *fp, QuadTree q, int level)
void QuadTree_get_repulsive_force(QuadTree qt, double *force, double *x, double bh, double p, double KP, double *counts)
QuadTree QuadTree_add(QuadTree q, double *coord, double weight, int id)
static void draw_polygon(FILE *fp, int dim, double *center, double width)
QuadTree QuadTree_new_in_quadrant(int dim, double *center, double width, int max_level, int i)
static void node_data_delete(node_data nd)
QuadTree QuadTree_new_from_point_list(int dim, int n, int max_level, double *coord)
static void check_or_realloc_arrays(int dim, int *nsuper, int *nsupermax, double **center, double **supernode_wgts, double **distances)
void QuadTree_print(FILE *fp, QuadTree q)
static double * get_or_assign_node_force(double *force, int i, node_data l, int dim)
void QuadTree_get_supernodes(QuadTree qt, double bh, double *pt, int nodeid, int *nsuper, double **center, double **supernode_wgts, double **distances, double *counts)
QuadTree QuadTree_new(int dim, double *center, double width, int max_level)
static double * get_or_alloc_force_qt(QuadTree qt, int dim)
static node_data node_data_new(int dim, double weight, double *coord, int id)
static void QuadTree_repulsive_force_interact(QuadTree qt1, QuadTree qt2, double *x, double *force, double bh, double p, double KP, double *counts)
static QuadTree QuadTree_add_internal(QuadTree q, double *coord, double weight, int id, int level)
static void QuadTree_repulsive_force_accumulate(QuadTree qt, double *force, double *counts)
static int QuadTree_get_quadrant(int dim, double *center, double *coord)
static void QuadTree_get_supernodes_internal(QuadTree qt, double bh, double *pt, int nodeid, int *nsuper, int *nsupermax, double **center, double **supernode_wgts, double **distances, double *counts)
void QuadTree_delete(QuadTree q)
double distance_cropped(double *x, int dim, int i, int j)
static void QuadTree_get_nearest_internal(QuadTree qt, double *x, double *y, double *min, int *imin, bool tentative)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
static double dist(int dim, double *x, double *y)
double point_distance(double *p1, double *p2, int dim)
geometric types and macros (e.g. points and boxes)
static int imin(int a, int b)
minimum of two integers
static point center(point vertex[], size_t n)