56#define localConstrMajorIterations 1000
77 float *dist_accumulator =
NULL;
78 float *tmp_coords =
NULL;
80 double *degrees =
NULL;
83 float *f_storage =
NULL;
84 float **coords =
NULL;
87 CMajEnvVPSC *cMajEnvHor =
NULL;
88 CMajEnvVPSC *cMajEnvVrt =
NULL;
98 double old_stress, new_stress = 0;
101 double nsizeScale = 0;
102 float maxEdgeLen = 0;
109 for (i = 0; i < n; i++) {
110 for (
size_t j = 1; j <
graph[i].nedges; j++) {
111 maxEdgeLen =
MAX(
graph[i].ewgts[j], maxEdgeLen);
129 fprintf(stderr,
"Calculating subset model");
135 "graph is disconnected. Hence, the circuit model\n");
137 "is undefined. Reverting to the shortest path model.\n");
141 fprintf(stderr,
"Calculating MDS model");
146 fprintf(stderr,
"Calculating shortest paths");
151 fprintf(stderr,
"Setting initial positions");
156 length = n + n * (n - 1) / 2;
157 for (i = 0; i <
length; i++) {
158 if (Dij[i] > diameter) {
159 diameter = (int) Dij[i];
165 for (i = 0; i <
dim; i++) {
166 for (
int j = 0; j < n; j++) {
167 max = fmax(max, fabs(d_coords[i][j]));
170 for (i = 0; i <
dim; i++) {
171 for (
int j = 0; j < n; j++) {
172 d_coords[i][j] *= 10 / max;
180 for (i = 0; i <
dim; i++) {
185 y_0 = d_coords[1][0];
186 for (i = 0; i < n; i++) {
187 d_coords[1][i] -= y_0;
197 lap_length = n + n * (n - 1) / 2;
202 if (opt->clusters.nclusters > 0) {
203 int nn = n + opt->clusters.nclusters * 2;
204 int clap_length = nn + nn * (nn - 1) / 2;
205 float *clap =
gv_calloc(clap_length,
sizeof(
float));
209 for (i = 0; i < nn; i++) {
210 for (
int j = 0; j < nn - i; j++) {
211 if (i < n && j < n - i) {
215 if (j == 1 && i % 2 == 1) {
230 lap_length = clap_length;
236 for (i = 0; i < n - 1; i++) {
239 for (
int j = 1; j < n - i; j++, count++) {
242 degrees[i + j] -= val;
244 degrees[i] -= degree;
246 for (step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
247 lap2[count] = (float) degrees[i];
252 for (i = 0; i <
dim; i++) {
253 coords[i] = f_storage + i * n;
254 for (
int j = 0; j < n; j++) {
255 coords[i][j] = j < orig_n ? (float)d_coords[i][j] : 0;
262 constant_term = (float) (n * (n - 1) / 2);
270 for (k = 1; k <
dim; k++) {
274 tmp_coords =
gv_calloc(n,
sizeof(
float));
275 dist_accumulator =
gv_calloc(n,
sizeof(
float));
277 old_stress = DBL_MAX;
279 if ((cMajEnvHor = initCMajVPSC(n, lap2,
graph, opt, 0)) ==
NULL) {
283 if ((cMajEnvVrt = initCMajVPSC(n, lap2,
graph, opt, opt->diredges)) ==
NULL) {
288 lap1 =
gv_calloc(lap_length,
sizeof(
float));
290 for (converged =
false, iterations = 0;
291 iterations < maxi && !converged; iterations++) {
296 for (count = 0, i = 0; i < n - 1; i++) {
304 for (k = 0; k <
dim; k++) {
314 for (
int j = 0; j <
len; j++) {
315 if (dist_accumulator[j] >= FLT_MAX || dist_accumulator[j] < 0) {
316 dist_accumulator[j] = 0;
322 for (
int j = 0; j <
len; j++, count++) {
323 val = lap1[count] *= dist_accumulator[j];
325 degrees[i + j + 1] -= val;
327 degrees[i] -= degree;
329 for (step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
330 lap1[count] = (float) degrees[i];
334 for (k = 0; k <
dim; k++) {
344 for (k = 0; k <
dim; k++) {
348 new_stress += constant_term;
349 for (k = 0; k <
dim; k++) {
355 if (
Verbose && (iterations % 1 == 0)) {
356 fprintf(stderr,
"%.3f ", new_stress);
357 if (iterations % 10 == 0)
358 fprintf(stderr,
"\n");
360 converged = new_stress < old_stress
361 && fabs(new_stress - old_stress) / fabs(old_stress + 1e-10) <
367 old_stress = new_stress;
372 if ((iterations >= maxi - 1 || converged) && opt->noverlap == 1
373 && nsizeScale < 0.999) {
376 fprintf(stderr,
"nsizescale=%f,iterations=%d\n",
377 nsizeScale, iterations);
395 if (opt->noverlap == 1 && nsizeScale > 0.001) {
396 generateNonoverlapConstraints(cMajEnvHor, nsizeScale, coords,
401 if (cMajEnvHor->m > 0) {
402 constrained_majorization_vpsc(cMajEnvHor, b[0], coords[0],
403 localConstrMajorIterations);
414 if (opt->noverlap == 1 && nsizeScale > 0.001) {
415 generateNonoverlapConstraints(cMajEnvVrt, nsizeScale, coords,
418 if (cMajEnvVrt->m > 0) {
419 if (constrained_majorization_vpsc(cMajEnvVrt, b[1], coords[1],
420 localConstrMajorIterations) < 0) {
430 fprintf(stderr,
"\nfinal e = %f %d iterations %.2f sec\n",
433 deleteCMajEnvVPSC(cMajEnvHor);
434 deleteCMajEnvVPSC(cMajEnvVrt);
436 if (opt->noverlap == 2) {
438 removeoverlaps(orig_n, coords, opt);
442 if (coords !=
NULL) {
443 for (i = 0; i <
dim; i++) {
444 for (
int j = 0; j < orig_n; j++) {
445 d_coords[i][j] = coords[i][j];
457 free(dist_accumulator);
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static Extype_t length(Exid_t *rhs, Exdisc_t *disc)
int conjugate_gradient_mkernel(float *A, float *x, float *b, int n, double tol, int max_iterations)
static double len(glCompPoint p)
void agwarningf(const char *fmt,...)
int agerr(agerrlevel_t level, const char *fmt,...)
Agraph_t * graph(char *name)
void invert_vec(int n, float *vec)
void invert_sqrt_vec(int n, float *vec)
void vectors_additionf(int n, float *vector1, float *vector2, float *result)
void set_vector_valf(int n, float val, float *result)
void orthog1(int n, double *vec)
void sqrt_vecf(int n, float *source, float *target)
void set_vector_val(int n, double val, double *result)
void right_mult_with_vector_ff(float *packed_matrix, int n, float *vector, float *result)
void vectors_mult_additionf(int n, float *vector1, float alpha, float *vector2)
void square_vec(int n, float *vec)
double vectors_inner_productf(int n, float *vector1, float *vector2)
float * compute_apsp_artificial_weights_packed(vtx_data *graph, int n)
float * circuitModel(vtx_data *graph, int nG)
int initLayout(int n, int dim, double **coords, node_t **nodes)
float * mdsModel(vtx_data *graph, int nG)
update matrix with actual edge lengths
float * compute_apsp_packed(vtx_data *graph, int n)
assumes integral weights > 0