41 if (*nsuper >= *nsupermax) {
42 int new_nsupermax = *nsuper + 10;
44 *supernode_wgts =
gv_recalloc(*supernode_wgts, *nsupermax, new_nsupermax,
sizeof(
double));
45 *distances =
gv_recalloc(*distances, *nsupermax, new_nsupermax,
sizeof(
double));
46 *nsupermax = new_nsupermax;
63 for (i = 0; i <
dim; i++){
64 (*center)[
dim*(*nsuper)+i] =
coord[i];
77 for (i = 0; i <
dim; i++){
84 for (i = 0; i < 1<<
dim; i++){
86 supernode_wgts, distances, counts);
94 int *nsupermax,
double **
center,
double **supernode_wgts,
double **distances,
double *counts) {
103 if (!*supernode_wgts) *supernode_wgts =
gv_calloc(*nsupermax,
sizeof(
double));
104 if (!*distances) *distances =
gv_calloc(*nsupermax,
sizeof(
double));
121 double *force = qt->
data;
133 double *x1, *x2,
dist, wgt1, wgt2, f, *f1, *f2, w1, w2;
134 int dim, i, j, i1, i2, k;
137 if (!qt1 || !qt2)
return;
138 assert(qt1->
n > 0 && qt2->
n > 0);
155 for (k = 0; k <
dim; k++){
157 f = w1*w2*KP*(x1[k] - x2[k])/(
dist*
dist);
159 f = w1*w2*KP*(x1[k] - x2[k])/pow(
dist, 1.- p);
181 if ((qt1 == qt2 && i2 < i1) || i1 == i2) {
187 for (k = 0; k <
dim; k++){
189 f = wgt1*wgt2*KP*(x1[k] - x2[k])/(
dist*
dist);
191 f = wgt1*wgt2*KP*(x1[k] - x2[k])/pow(
dist, 1.- p);
206 for (i = 0; i < 1<<
dim; i++){
208 for (j = i; j < 1<<
dim; j++){
216 for (i = 0; i < 1<<
dim; i++){
221 for (i = 0; i < 1<<
dim; i++){
226 for (i = 0; i < 1<<
dim; i++){
231 for (i = 0; i < 1<<
dim; i++){
262 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
268 for (i = 0; i < 1<<
dim; i++){
275 for (k = 0; k <
dim; k++) f2[k] += wgt2*f[k];
298 int n = qt->
n,
dim = qt->
dim, i;
300 for (i = 0; i < 4; i++) counts[i] = 0;
302 for (i = 0; i <
dim*n; i++) force[i] = 0;
306 for (i = 0; i < 4; i++) counts[i] /= n;
330 for (i = 1; i < n; i++){
331 for (k = 0; k <
dim; k++){
338 for (i = 0; i <
dim; i++) {
340 width = fmax(width,
xmax[i] -
xmin[i]);
342 width = fmax(width, 0.00001);
346 for (i = 0; i < n; i++){
383 for (i = 0; i < 1<<
dim; i++){
403 for (i =
dim - 1; i >= 0; i--){
422 for (k = 0; k <
dim; k++){
443 for (i = 0; i < q->
dim; i++) {
446 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),
462 }
else if (level < max_level){
472 assert(ii < 1<<
dim && ii >= 0);
484 assert(ii < 1<<
dim && ii >= 0);
492 while (q->
l !=
NULL) {
523 if (dim < 2 || dim > 3)
return;
524 fprintf(fp,
"(*in c*){Line[{");
527 fprintf(fp,
"{%f, %f}",
center[0] + width,
center[1] + width);
528 fprintf(fp,
",{%f, %f}",
center[0] - width,
center[1] + width);
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 }
else if (
dim == 3){
536 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] + width);
537 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);
544 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] - width);
545 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);
552 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] + width,
center[2] + width);
557 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] + width,
center[2] + width);
562 fprintf(fp,
",{%f, %f, %f}",
center[0] + width,
center[1] - width,
center[2] + width);
567 fprintf(fp,
",{%f, %f, %f}",
center[0] - width,
center[1] - width,
center[2] + width);
572 fprintf(fp,
"}]}(*end C*)");
589 printf(
",(*a*) {Red,");
591 if (l != l0) printf(
",");
593 fprintf(fp,
"(*node %d*) Point[{", l->
id);
594 for (i = 0; i <
dim; i++){
595 if (i != 0) printf(
",");
596 fprintf(fp,
"%f",
coord[i]);
605 for (i = 0; i < 1<<
dim; i++){
606 fprintf(fp,
",(*b*){");
618 fprintf(fp,
"Graphics[{");
619 }
else if (q->
dim == 3){
620 fprintf(fp,
"Graphics3D[{");
626 fprintf(fp,
"}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
628 fprintf(fp,
"}, PlotRange -> All]\n");
633 double *min,
int *
imin,
646 if(*min < 0 ||
dist < *min) {
649 for (i = 0; i <
dim; i++) y[i] =
coord[i];
656 if (*min >= 0 && (
dist - sqrt((
double)
dim) * qt->
width > *min)){
661 for (i = 0; i < 1<<
dim; i++){
664 if (
dist < qmin || qmin < 0){
672 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)