15#if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP))
26static void ideal_distance_avoid_overlap(
int dim,
SparseMatrix A,
double *x,
double *width,
double *ideal_distance,
double *tmax,
double *tmin){
33 int *ia =
A->ia, *ja =
A->ja;
35 double expandmax = 1.5, expandmin = 1;
40 for (i = 0; i <
A->m; i++){
41 for (j = ia[i]; j < ia[i+1]; j++){
43 if (jj == i)
continue;
47 wx = width[i*
dim]+width[jj*
dim];
48 wy = width[i*
dim+1]+width[jj*
dim+1];
50 ideal_distance[j] = hypot(wx, wy);
58 t = fmin(wx /
dx, wy /
dy);
60 if (t > 1) t = fmax(t, 1.001);
61 *tmax = fmax(*tmax, t);
62 *tmin = fmin(*tmin, t);
63 t = fmin(expandmax, t);
64 t = fmax(expandmin, t);
66 ideal_distance[j] = t*
dist;
68 ideal_distance[j] = -t*
dist;
76enum {INTV_OPEN, INTV_CLOSE};
84static int comp_scan_points(
const void *p,
const void *q){
85 const scan_point *pp = p;
86 const scan_point *qq = q;
89 }
else if (pp->x < qq->x){
92 if (pp->node > qq->node){
94 }
else if (pp->node < qq->node){
102static void NodeDest(
void* a) {
107static SparseMatrix get_overlap_graph(
int dim,
int n,
double *x,
double *width,
int check_overlap_only){
117 scan_point *scanpointsx =
gv_calloc(2 * n,
sizeof(scan_point));
118 for (i = 0; i < n; i++){
119 scanpointsx[2*i].node = i;
120 scanpointsx[2*i].x = x[i*
dim] - width[i*
dim];
121 scanpointsx[2*i].status = INTV_OPEN;
122 scanpointsx[2*i+1].node = i+n;
123 scanpointsx[2*i+1].x = x[i*
dim] + width[i*
dim];
124 scanpointsx[2*i+1].status = INTV_CLOSE;
126 qsort(scanpointsx, 2*n,
sizeof(scan_point), comp_scan_points);
128 scan_point *scanpointsy =
gv_calloc(2 * n,
sizeof(scan_point));
129 for (i = 0; i < n; i++){
130 scanpointsy[i].node = i;
131 scanpointsy[i].x = x[i*
dim+1] - width[i*
dim+1];
132 scanpointsy[i].status = INTV_OPEN;
133 scanpointsy[i+n].node = i;
134 scanpointsy[i+n].x = x[i*
dim+1] + width[i*
dim+1];
135 scanpointsy[i+n].status = INTV_CLOSE;
140 for (i = 0; i < 2*n; i++){
142 fprintf(stderr,
" k = %d node = %d x====%f\n",(scanpointsx[i].
node)%n, (scanpointsx[i].
node), (scanpointsx[i].x));
145 k = (scanpointsx[i].node)%n;
148 if (scanpointsx[i].status == INTV_OPEN){
150 fprintf(stderr,
"inserting...");
151 treey->PrintKey(&(scanpointsy[k]));
157 fprintf(stderr,
"inserting2...");
158 treey->PrintKey(&(scanpointsy[k+n]));
163 double bsta, bbsta, bsto, bbsto;
int ii;
165 assert(scanpointsx[i].
node >= n);
168 ii = ((scan_point *)
newNode->key)->node;
170 bsta = scanpointsy[ii].x; bsto = scanpointsy[ii+n].x;
173 fprintf(stderr,
"popping..%d....yinterval={%f,%f}\n", scanpointsy[k + n].
node, bsta, bsto);
182 fprintf(stderr,
" predecessor is node %d y = %f\n", ((scan_point *)
newNode->key)->node, ((scan_point *)
newNode->key)->x);
185 if (fabs(0.5*(bsta+bsto) - 0.5*(bbsta+bbsto)) < 0.5*(bsto-bsta) + 0.5*(bbsto-bbsta)){
188 fprintf(stderr,
"====================================== %d %d\n",k,
neighbor);
190 if (check_overlap_only)
goto check_overlap_RETURN;
196 fprintf(stderr,
"deleting...");
197 treey->PrintKey(newNode0->
key);
200 if (newNode0)
RBDelete(treey,newNode0);
213 if (
Verbose) fprintf(stderr,
"found %d clashes\n",
A->nz);
222static void relative_position_constraints_delete(
void *d){
235 data->constr_penalty = 1;
236 data->edge_labeling_scheme = edge_labeling_scheme;
237 data->n_constr_nodes = n_constr_nodes;
238 data->constr_nodes = constr_nodes;
239 data->A_constr = A_constr;
246static void scale_coord(
int dim,
int m,
double *x,
double scale){
248 for (i = 0; i <
dim*m; i++) {
253static double overlap_scaling(
int dim,
int m,
double *x,
double *width,
254 double scale_sta,
double scale_sto,
255 double epsilon,
int maxiter) {
266 double scale = -1, scale_best = -1;
268 int check_overlap_only = 1;
275 if (scale_sta <= 0) {
278 scale_coord(
dim, m, x, scale_sta);
279 C = get_overlap_graph(
dim, m, x, width, check_overlap_only);
280 if (!
C ||
C->nz == 0) {
281 if (
Verbose) fprintf(stderr,
" shrinking with %f works\n", scale_sta);
285 scale_coord(
dim, m, x, 1./scale_sta);
290 if (scale_sta == 0) {
293 scale_sto = scale_sta;
295 scale_coord(
dim, m, x, scale_sto);
298 scale_coord(
dim, m, x, two);
299 C = get_overlap_graph(
dim, m, x, width, check_overlap_only);
303 scale_coord(
dim, m, x, 1/scale_sto);
306 scale_best = scale_sto;
307 while (iter++ < maxiter && scale_sto - scale_sta > epsilon){
309 if (
Verbose) fprintf(stderr,
"in overlap_scaling iter=%d, maxiter=%d, scaling bracket: {%f,%f}\n", iter, maxiter, scale_sta, scale_sto);
311 scale = 0.5*(scale_sta + scale_sto);
313 C = get_overlap_graph(
dim, m, x, width, check_overlap_only);
320 scale_best = scale_sto =
scale;
325 scale_coord(
dim, m, x, scale_best);
330 int dim,
double *x,
double *width,
bool neighborhood_only,
331 double *max_overlap,
double *min_overlap,
332 int edge_labeling_scheme,
int n_constr_nodes,
int *constr_nodes,
SparseMatrix A_constr,
int shrink
334 int i, j, k, *iw, *jw, jdiag;
336 double *d, *w, diag_d, diag_w,
dist;
342 if (constr_nodes && n_constr_nodes > 0 && edge_labeling_scheme !=
ELSCHEME_NONE){
344 sm->
data = relative_position_constraints_new(A_constr, edge_labeling_scheme, n_constr_nodes, constr_nodes);
357 if (!neighborhood_only){
359 C = get_overlap_graph(
dim, m, x, width, 0);
368 if (!(sm->
Lw) || !(sm->
Lwd)) {
375 ideal_distance_avoid_overlap(
dim, sm->
Lwd, x, width, sm->
Lwd->
a, max_overlap, min_overlap);
378 if (*max_overlap < 1 && shrink){
379 double scale_sta = fmin(1, *max_overlap * 1.0001);
380 const double scale_sto = 1;
382 if (
Verbose) fprintf(stderr,
" no overlap (overlap = %f), rescale to shrink\n", *max_overlap - 1);
384 scale_sta = overlap_scaling(
dim, m, x, width, scale_sta, scale_sto, 0.0001, 15);
394 for (i = 0; i < m; i++){
397 for (j = iw[i]; j < iw[i+1]; j++){
404 w[j] = -100/d[j]/d[j];
438static void scale_to_edge_length(
int dim,
SparseMatrix A,
double *x,
double avg_label_size){
444 if (
Verbose) fprintf(stderr,
"avg edge len=%f avg_label-size= %f\n",
dist, avg_label_size);
449 for (i = 0; i <
dim*
A->m; i++) x[i] *=
dist;
452static void print_bounding_box(
int n,
int dim,
double *x){
460 for (i = 0; i < n; i++){
461 for (k = 0; k <
dim; k++){
466 fprintf(stderr,
"bounding box = \n");
467 for (i = 0; i <
dim; i++) fprintf(stderr,
"{%f,%f}, ",
xmin[i],
xmax[i]);
468 fprintf(stderr,
"\n");
474static int check_convergence(
double max_overlap,
double res,
475 bool has_penalty_terms,
double epsilon) {
476 if (!has_penalty_terms)
477 return (max_overlap <= 1);
478 return res < epsilon;
482 int edge_labeling_scheme,
int n_constr_nodes,
int *constr_nodes,
SparseMatrix A_constr,
bool do_shrinking) {
497 double LARGE = 100000;
498 double avg_label_size, res = LARGE;
499 double max_overlap = 0, min_overlap = 999;
500 bool neighborhood_only =
true;
501 double epsilon = 0.005;
512 if (!label_sizes)
return;
514 if (initial_scaling < 0) {
516 for (i = 0; i <
A->m; i++) avg_label_size += label_sizes[i*
dim]+label_sizes[i*
dim+1];
517 avg_label_size /=
A->m;
518 scale_to_edge_length(
dim,
A, x, -initial_scaling*avg_label_size);
519 }
else if (initial_scaling > 0){
520 scale_to_edge_length(
dim,
A, x, initial_scaling);
526 _statistics[0] = _statistics[1] = 0.;
529 bool has_penalty_terms =
531 for (i = 0; i < ntry; i++){
534 &max_overlap, &min_overlap, edge_labeling_scheme, n_constr_nodes, constr_nodes, A_constr, shrink);
537 "overlap removal neighbors only?= %d iter -- %d, overlap factor = %g underlap factor = %g\n",
538 (
int)neighborhood_only, i, max_overlap - 1, min_overlap);
540 if (check_convergence(max_overlap, res, has_penalty_terms, epsilon)) {
543 if (!neighborhood_only){
547 neighborhood_only =
false;
556 if (
Verbose) fprintf(stderr,
"res = %f\n",res);
561 "overlap removal neighbors only?= %d iter -- %d, overlap factor = %g underlap factor = %g\n",
562 (
int)neighborhood_only, i, max_overlap - 1, min_overlap);
565 if (has_penalty_terms){
572 fprintf(stderr,
" number of cg iter = %f, number of stress majorization iter = %f number of overlap removal try = %d\n",
573 _statistics[0], _statistics[1], i - 1);
577 fprintf(stderr,
"post processing %f\n",((
double) (clock() - cpu)) / CLOCKS_PER_SEC);
585 int edge_labeling_scheme,
int n_constr_nodes,
int *constr_nodes,
SparseMatrix A_constr,
bool do_shrinking)
594 (void)initial_scaling;
595 (void)edge_labeling_scheme;
596 (void)n_constr_nodes;
603 agerrorf(
"remove_overlap: Graphviz not built with triangulation library\n");
SparseMatrix SparseMatrix_from_coordinate_format(SparseMatrix A)
SparseMatrix SparseMatrix_symmetrize(SparseMatrix A, bool pattern_symmetric_only)
SparseMatrix SparseMatrix_coordinate_form_add_entry(SparseMatrix A, int irn, int jcn, const void *val)
bool SparseMatrix_is_symmetric(SparseMatrix A, bool test_pattern_symmetry_only)
void SparseMatrix_delete(SparseMatrix A)
SparseMatrix SparseMatrix_copy(SparseMatrix A)
SparseMatrix SparseMatrix_add(SparseMatrix A, SparseMatrix B)
SparseMatrix SparseMatrix_new(int m, int n, int nz, int type, int format)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
SparseMatrix call_tri(int n, double *x)
static double dist(int dim, double *x, double *y)
double distance(double *x, int dim, int i, int j)
static pointf scale(double c, pointf p)
static node_list * newNode(Grid *g, Agnode_t *n, node_list *nxt)
void agerrorf(const char *fmt,...)
#define neighbor(t, i, edim, elist)
void remove_overlap(int dim, SparseMatrix A, double *x, double *label_sizes, int ntry, double initial_scaling, int edge_labeling_scheme, int n_constr_nodes, int *constr_nodes, SparseMatrix A_constr, bool do_shrinking)
#define OverlapSmoother_struct
OverlapSmoother OverlapSmoother_new(SparseMatrix A, int m, int dim, double *x, double *width, bool neighborhood_only, double *max_overlap, double *min_overlap, int edge_labeling_scheme, int n_constr_nodes, int *constr_nodes, SparseMatrix A_constr, int shrink)
void OverlapSmoother_delete(OverlapSmoother sm)
double OverlapSmoother_smooth(OverlapSmoother sm, int dim, double *x)
double StressMajorizationSmoother_smooth(StressMajorizationSmoother sm, int dim, double *x, int maxit_sm)
void StressMajorizationSmoother_delete(StressMajorizationSmoother sm)
@ SM_SCHEME_NORMAL_ELABEL
void RBDelete(rb_red_blk_tree *tree, rb_red_blk_node *z)
rb_red_blk_node * TreePredecessor(rb_red_blk_tree *tree, rb_red_blk_node *x)
void RBTreeDestroy(rb_red_blk_tree *tree)
rb_red_blk_node * RBExactQuery(rb_red_blk_tree *tree, void *q)
rb_red_blk_node * RBTreeInsert(rb_red_blk_tree *tree, void *key)
rb_red_blk_tree * RBTreeCreate(int(*CompFunc)(const void *, const void *), void(*DestFunc)(void *))
static double overlap(double i0, double i1, double j0, double j1)
double average_edge_length(SparseMatrix A, int dim, double *coord)
void(* data_deallocator)(void *)
graphs, nodes and edges info: Agraphinfo_t, Agnodeinfo_t and Agedgeinfo_t