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 int *nsupermax,
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++){
159 f = w1*w2*KP*(x1[k] - x2[k])/(
dist*
dist);
161 f = w1*w2*KP*(x1[k] - x2[k])/pow(
dist, 1.- p);
183 if ((qt1 == qt2 && i2 < i1) || i1 == i2) {
189 for (k = 0; k <
dim; k++){
191 f = wgt1*wgt2*KP*(x1[k] - x2[k])/(
dist*
dist);
193 f = wgt1*wgt2*KP*(x1[k] - x2[k])/pow(
dist, 1.- p);
208 for (i = 0; i < 1<<
dim; i++){
210 for (j = i; j < 1<<
dim; j++){
218 for (i = 0; i < 1<<
dim; i++){
223 for (i = 0; i < 1<<
dim; i++){
228 for (i = 0; i < 1<<
dim; i++){
233 for (i = 0; i < 1<<
dim; i++){
264 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
270 for (i = 0; i < 1<<
dim; i++){
277 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
300 int n = qt->
n,
dim = qt->
dim, i;
302 for (i = 0; i < 4; i++) counts[i] = 0;
304 for (i = 0; i <
dim*n; i++) force[i] = 0;
308 for (i = 0; i < 4; i++) counts[i] /= n;
332 for (i = 1; i < n; i++){
333 for (k = 0; k <
dim; k++){
340 for (i = 0; i <
dim; i++) {
342 width = fmax(width,
xmax[i] -
xmin[i]);
344 width = fmax(width, 0.00001);
348 for (i = 0; i < n; i++){
385 for (i = 0; i < 1<<
dim; i++){
405 for (i =
dim - 1; i >= 0; i--){
424 for (k = 0; k <
dim; k++){
445 for (i = 0; i < q->
dim; i++) {
448 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),
464 }
else if (level < max_level){
474 assert(ii < 1<<
dim && ii >= 0);
486 assert(ii < 1<<
dim && ii >= 0);
494 while (q->
l !=
NULL) {
525 if (dim < 2 || dim > 3)
return;
526 fprintf(fp,
"(*in c*){Line[{");
529 fprintf(fp,
"{%f, %f}",
center[0] + width,
center[1] + width);
530 fprintf(fp,
",{%f, %f}",
center[0] - width,
center[1] + width);
531 fprintf(fp,
",{%f, %f}",
center[0] - width,
center[1] - width);
532 fprintf(fp,
",{%f, %f}",
center[0] + width,
center[1] - width);
533 fprintf(fp,
",{%f, %f}",
center[0] + width,
center[1] + width);
534 }
else if (
dim == 3){
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);
547 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] - width);
548 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] - width);
549 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] - width);
554 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] + width);
559 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] + width);
564 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] + width);
569 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] + width);
574 fprintf(fp,
"}]}(*end C*)");
591 printf(
",(*a*) {Red,");
593 if (l != l0) printf(
",");
595 fprintf(fp,
"(*node %d*) Point[{", l->
id);
596 for (i = 0; i <
dim; i++){
597 if (i != 0) printf(
",");
598 fprintf(fp,
"%f",
coord[i]);
607 for (i = 0; i < 1<<
dim; i++){
608 fprintf(fp,
",(*b*){");
620 fprintf(fp,
"Graphics[{");
621 }
else if (q->
dim == 3){
622 fprintf(fp,
"Graphics3D[{");
628 fprintf(fp,
"}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
630 fprintf(fp,
"}, PlotRange -> All]\n");
635 double *min,
int *
imin,
648 if(*min < 0 ||
dist < *min) {
651 for (i = 0; i <
dim; i++) y[i] =
coord[i];
658 if (*min >= 0 && (
dist - sqrt((
double)
dim) * qt->
width > *min)){
663 for (i = 0; i < 1<<
dim; i++){
666 if (
dist < qmin || qmin < 0){
674 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)
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)
void QuadTree_get_supernodes(QuadTree qt, double bh, double *pt, int nodeid, int *nsuper, int *nsupermax, double **center, double **supernode_wgts, double **distances, double *counts)
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)