33 static node_data node_data_new(
int dim,
real weight,
real *
coord,
int id){
40 for (i = 0; i < dim; i++) nd->
coord[i] = coord[i];
67 #define node_data_get_data(d) (((node_data) (d))->data)
72 if (*nsuper >= *nsupermax) {
73 *nsupermax = *nsuper +
MAX(10, (
int) 0.2*(*nsuper));
74 *center =
REALLOC(*center,
sizeof(
real)*(*nsupermax)*dim);
75 *supernode_wgts =
REALLOC(*supernode_wgts,
sizeof(
real)*(*nsupermax));
76 *distances =
REALLOC(*distances,
sizeof(
real)*(*nsupermax));
80 void QuadTree_get_supernodes_internal(
QuadTree qt,
real bh,
real *
point,
int nodeid,
int *nsuper,
int *nsupermax,
real **center,
real **supernode_wgts,
real **distances,
real *counts,
int *flag){
95 for (i = 0; i < dim; i++){
96 (*center)[dim*(*nsuper)+i] = coord[i];
108 if (qt->
width < bh*dist){
110 for (i = 0; i < dim; i++){
111 (*center)[dim*(*nsuper)+i] = qt->
average[i];
117 for (i = 0; i < 1<<dim; i++){
119 supernode_wgts, distances, counts, flag);
127 int *nsupermax,
real **center,
real **supernode_wgts,
real **distances,
double *counts,
int *flag){
136 if (!*center) *center =
MALLOC(
sizeof(
real)*(*nsupermax)*dim);
137 if (!*supernode_wgts) *supernode_wgts =
MALLOC(
sizeof(
real)*(*nsupermax));
138 if (!*distances) *distances =
MALLOC(
sizeof(
real)*(*nsupermax));
139 QuadTree_get_supernodes_internal(qt, bh, point, nodeid, nsuper, nsupermax, center, supernode_wgts, distances, counts, flag);
154 static real *get_or_alloc_force_qt(
QuadTree qt,
int dim){
160 for (i = 0; i < dim; i++) force[i] = 0.;
170 real *x1, *x2,
dist, wgt1, wgt2, f, *f1, *f2, w1, w2;
171 int dim, i, j, i1, i2, k;
174 if (!qt1 || !qt2)
return;
187 f1 = get_or_alloc_force_qt(qt1, dim);
190 f2 = get_or_alloc_force_qt(qt2, dim);
192 for (k = 0; k < dim; k++){
194 f = w1*w2*KP*(x1[k] - x2[k])/(dist*dist);
196 f = w1*w2*KP*(x1[k] - x2[k])/pow(dist, 1.- p);
211 f1 = get_or_assign_node_force(force, i1, l1, dim);
217 f2 = get_or_assign_node_force(force, i2, l2, dim);
218 if ((qt1 == qt2 && i2 < i1) || i1 == i2) {
224 for (k = 0; k < dim; k++){
226 f = wgt1*wgt2*KP*(x1[k] - x2[k])/(dist*dist);
228 f = wgt1*wgt2*KP*(x1[k] - x2[k])/pow(dist, 1.- p);
243 for (i = 0; i < 1<<dim; i++){
245 for (j = i; j < 1<<dim; j++){
247 QuadTree_repulsive_force_interact(qt11, qt12, x, force, bh, p, KP, counts);
253 for (i = 0; i < 1<<dim; i++){
255 QuadTree_repulsive_force_interact(qt11, qt2, x, force, bh, p, KP, counts);
258 for (i = 0; i < 1<<dim; i++){
260 QuadTree_repulsive_force_interact(qt11, qt1, x, force, bh, p, KP, counts);
263 for (i = 0; i < 1<<dim; i++){
265 QuadTree_repulsive_force_interact(qt11, qt2, x, force, bh, p, KP, counts);
268 for (i = 0; i < 1<<dim; i++){
270 QuadTree_repulsive_force_interact(qt11, qt1, x, force, bh, p, KP, counts);
278 static void QuadTree_repulsive_force_accumulate(
QuadTree qt,
real *force,
real *counts){
288 f = get_or_alloc_force_qt(qt, dim);
295 f2 = get_or_assign_node_force(force, i, l, dim);
298 for (k = 0; k < dim; k++) f2[k] += wgt2*f[k];
304 for (i = 0; i < 1<<dim; i++){
308 f2 = get_or_alloc_force_qt(qt2, dim);
311 for (k = 0; k < dim; k++) f2[k] += wgt2*f[k];
312 QuadTree_repulsive_force_accumulate(qt2, force, counts);
334 int n = qt->
n, dim = qt->
dim, i;
336 for (i = 0; i < 4; i++) counts[i] = 0;
340 for (i = 0; i < dim*n; i++) force[i] = 0;
342 QuadTree_repulsive_force_interact(qt, qt, x, force, bh, p, KP, counts);
343 QuadTree_repulsive_force_accumulate(qt, force, counts);
344 for (i = 0; i < 4; i++) counts[i] /= n;
359 if (!xmin || !xmax || !center) {
366 for (i = 0; i < dim; i++) xmin[i] = coord[i];
367 for (i = 0; i < dim; i++) xmax[i] = coord[i];
369 for (i = 1; i < n; i++){
370 for (k = 0; k < dim; k++){
371 xmin[k] =
MIN(xmin[k], coord[i*dim+k]);
372 xmax[k] =
MAX(xmax[k], coord[i*dim+k]);
376 width = xmax[0] - xmin[0];
377 for (i = 0; i < dim; i++) {
378 center[i] = (xmin[i] + xmax[i])*0.5;
379 width =
MAX(width, xmax[i] - xmin[i]);
381 if (width == 0) width = 0.00001;
386 for (i = 0; i < n; i++){
390 for (i = 0; i < n; i++){
409 for (i = 0; i < dim; i++) q->
center[i] = center[i];
429 for (i = 0; i < 1<<dim; i++){
438 static int QuadTree_get_quadrant(
int dim,
real *center,
real *
coord){
445 for (i = dim - 1; i >= 0; i--){
446 if (coord[i] - center[i] < 0){
464 for (k = 0; k < dim; k++){
478 int i, dim = q->
dim, ii;
485 for (i = 0; i < q->
dim; i++) {
488 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),
500 for (i = 0; i < q->
dim; i++) q->
average[i] = coord[i];
501 nd = node_data_new(q->
dim, weight, coord,
id);
504 }
else if (level < max_level){
510 for (i = 0; i < 1<<dim; i++) q->
qts[i] =
NULL;
514 ii = QuadTree_get_quadrant(dim, q->
center, coord);
515 assert(ii < 1<<dim && ii >= 0);
518 q->
qts[ii] = QuadTree_add_internal(q->
qts[ii], coord, weight,
id, level + 1);
526 ii = QuadTree_get_quadrant(dim, q->
center, coord);
527 assert(ii < 1<<dim && ii >= 0);
531 q->
qts[ii] = QuadTree_add_internal(q->
qts[ii], coord, weight, idd, level + 1);
546 nd = node_data_new(q->
dim, weight, coord,
id);
556 return QuadTree_add_internal(q, coord, weight,
id, 0);
560 static void draw_polygon(FILE *fp,
int dim,
real *center,
real width){
562 if (dim < 2 || dim > 3)
return;
563 fprintf(fp,
"(*in c*){Line[{");
566 fprintf(fp,
"{%f, %f}", center[0] + width, center[1] + width);
567 fprintf(fp,
",{%f, %f}", center[0] - width, center[1] + width);
568 fprintf(fp,
",{%f, %f}", center[0] - width, center[1] - width);
569 fprintf(fp,
",{%f, %f}", center[0] + width, center[1] - width);
570 fprintf(fp,
",{%f, %f}", center[0] + width, center[1] + width);
571 }
else if (dim == 3){
574 fprintf(fp,
"{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
575 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] + width);
576 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] + width);
577 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] + width);
578 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
582 fprintf(fp,
"{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
583 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] - width);
584 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] - width);
585 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] - width);
586 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
590 fprintf(fp,
"{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
591 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
595 fprintf(fp,
"{%f, %f, %f}", center[0] - width, center[1] + width, center[2] - width);
596 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] + width);
600 fprintf(fp,
"{%f, %f, %f}", center[0] + width, center[1] - width, center[2] - width);
601 fprintf(fp,
",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] + width);
605 fprintf(fp,
"{%f, %f, %f}", center[0] - width, center[1] - width, center[2] - width);
606 fprintf(fp,
",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] + width);
611 fprintf(fp,
"}]}(*end C*)");
615 static void QuadTree_print_internal(FILE *fp,
QuadTree q,
int level){
628 printf(
",(*a*) {Red,");
630 if (l != l0) printf(
",");
633 for (i = 0; i < dim; i++){
634 if (i != 0) printf(
",");
635 fprintf(fp,
"%f",coord[i]);
644 for (i = 0; i < 1<<dim; i++){
645 fprintf(fp,
",(*b*){");
646 QuadTree_print_internal(fp, q->
qts[i], level + 1);
657 fprintf(fp,
"Graphics[{");
658 }
else if (q->
dim == 3){
659 fprintf(fp,
"Graphics3D[{");
663 QuadTree_print_internal(fp, q, 0);
665 fprintf(fp,
"}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
667 fprintf(fp,
"}, PlotRange -> All]\n");
674 static void QuadTree_get_nearest_internal(
QuadTree qt,
real *x,
real *y,
real *min,
int *imin,
int tentative,
int *flag){
690 if(*min < 0 || dist < *min) {
693 for (i = 0; i < dim; i++) y[i] = coord[i];
701 if (*min >= 0 && (dist - sqrt((
real) dim) * qt->
width > *min)){
706 for (i = 0; i < 1<<dim; i++){
709 if (dist < qmin || qmin < 0){
715 QuadTree_get_nearest_internal(qt->
qts[iq], x, y, min, imin, tentative, flag);
717 for (i = 0; i < 1<<dim; i++){
718 QuadTree_get_nearest_internal(qt->
qts[i], x, y, min, imin, tentative, flag);
732 QuadTree_get_nearest_internal(qt, x, ymin, min, imin,
TRUE, flag);
734 QuadTree_get_nearest_internal(qt, x, ymin, min, imin,
FALSE, flag);
void check_or_realloc_arrays(int dim, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances)
void QuadTree_get_repulsive_force(QuadTree qt, real *force, real *x, real bh, real p, real KP, real *counts, int *flag)
QuadTree QuadTree_new_in_quadrant(int dim, real *center, real width, int max_level, int i)
real point_distance(real *p1, real *p2, int dim)
SingleLinkedList SingleLinkedList_new(void *data)
QuadTree QuadTree_new(int dim, real *center, real width, int max_level)
void QuadTree_get_supernodes_internal(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances, real *counts, int *flag)
void QuadTree_print(FILE *fp, QuadTree q)
real * node_data_get_coord(void *d)
SingleLinkedList SingleLinkedList_get_next(SingleLinkedList l)
SingleLinkedList SingleLinkedList_prepend(SingleLinkedList l, void *data)
void * SingleLinkedList_get_data(SingleLinkedList l)
void QuadTree_get_supernodes(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances, double *counts, int *flag)
void SingleLinkedList_delete(SingleLinkedList head, void(*linklist_deallocator)(void *))
struct node_data_struct * node_data
if(aagss+aagstacksize-1<=aagssp)
void QuadTree_delete(QuadTree q)
void node_data_delete(void *d)
QuadTree QuadTree_new_from_point_list(int dim, int n, int max_level, real *coord, real *weight)
real node_data_get_weight(void *d)
int node_data_get_id(void *d)
void QuadTree_get_nearest(QuadTree qt, real *x, real *ymin, int *imin, real *min, int *flag)
double dist(Site *s, Site *t)
real distance_cropped(real *x, int dim, int i, int j)
QuadTree QuadTree_add(QuadTree q, real *coord, real weight, int id)
#define node_data_get_data(d)