58#define localConstrMajorIterations 1000
79 float *dist_accumulator =
NULL;
80 float *tmp_coords =
NULL;
82 double *degrees =
NULL;
85 float *f_storage =
NULL;
86 float **coords =
NULL;
89 CMajEnvVPSC *cMajEnvHor =
NULL;
90 CMajEnvVPSC *cMajEnvVrt =
NULL;
100 double old_stress, new_stress = 0;
103 double nsizeScale = 0;
104 float maxEdgeLen = 0;
111 for (
int i = 0; i < n; i++) {
112 for (
size_t j = 1; j <
graph[i].nedges; j++) {
113 maxEdgeLen =
MAX(
graph[i].ewgts[j], maxEdgeLen);
131 fprintf(stderr,
"Calculating subset model");
137 "graph is disconnected. Hence, the circuit model\n");
139 "is undefined. Reverting to the shortest path model.\n");
143 fprintf(stderr,
"Calculating MDS model");
148 fprintf(stderr,
"Calculating shortest paths");
153 fprintf(stderr,
"Setting initial positions");
158 length = n + n * (n - 1) / 2;
159 for (
int i = 0; i <
length; i++) {
160 if (Dij[i] > diameter) {
161 diameter = (int) Dij[i];
167 for (
int i = 0; i <
dim; i++) {
168 for (
int j = 0; j < n; j++) {
169 max = fmax(max, fabs(d_coords[i][j]));
172 for (
int i = 0; i <
dim; i++) {
173 for (
int j = 0; j < n; j++) {
174 d_coords[i][j] *= 10 / max;
182 for (
int i = 0; i <
dim; i++) {
187 y_0 = d_coords[1][0];
188 for (
int i = 0; i < n; i++) {
189 d_coords[1][i] -= y_0;
199 lap_length = n + n * (n - 1) / 2;
204 if (opt->clusters.nclusters > 0) {
205 const size_t nn = n + opt->clusters.nclusters * 2;
206 const size_t clap_length = nn + nn * (nn - 1) / 2;
207 float *clap =
gv_calloc(clap_length,
sizeof(
float));
211 for (
size_t i = 0; i < nn; i++) {
212 for (
int j = 0; j < nn - i; j++) {
213 if (i < n && j < n - i) {
217 if (j == 1 && i % 2 == 1) {
231 assert(nn <= INT_MAX);
233 assert(clap_length <= INT_MAX);
234 lap_length = (int)clap_length;
240 for (
int i = 0; i < n - 1; i++) {
243 for (
int j = 1; j < n - i; j++, count++) {
246 degrees[i + j] -= val;
248 degrees[i] -= degree;
251 for (step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
252 lap2[count] = (float) degrees[i];
257 for (i = 0; i <
dim; i++) {
258 coords[i] = f_storage + i * n;
259 for (
int j = 0; j < n; j++) {
260 coords[i][j] = j < orig_n ? (float)d_coords[i][j] : 0;
267 constant_term = (float) (n * (n - 1) / 2);
275 for (k = 1; k <
dim; k++) {
279 tmp_coords =
gv_calloc(n,
sizeof(
float));
280 dist_accumulator =
gv_calloc(n,
sizeof(
float));
282 old_stress = DBL_MAX;
284 if ((cMajEnvHor = initCMajVPSC(n, lap2,
graph, opt, 0)) ==
NULL) {
288 if ((cMajEnvVrt = initCMajVPSC(n, lap2,
graph, opt, opt->diredges)) ==
NULL) {
293 lap1 =
gv_calloc(lap_length,
sizeof(
float));
295 for (converged =
false, iterations = 0;
296 iterations < maxi && !converged; iterations++) {
301 for (count = 0, i = 0; i < n - 1; i++) {
309 for (k = 0; k <
dim; k++) {
319 for (
int j = 0; j <
len; j++) {
320 if (dist_accumulator[j] >= FLT_MAX || dist_accumulator[j] < 0) {
321 dist_accumulator[j] = 0;
327 for (
int j = 0; j <
len; j++, count++) {
328 val = lap1[count] *= dist_accumulator[j];
330 degrees[i + j + 1] -= val;
332 degrees[i] -= degree;
334 for (step = n, count = 0, i = 0; i < n; i++, count += step, step--) {
335 lap1[count] = (float) degrees[i];
339 for (k = 0; k <
dim; k++) {
349 for (k = 0; k <
dim; k++) {
353 new_stress += constant_term;
354 for (k = 0; k <
dim; k++) {
360 if (
Verbose && (iterations % 1 == 0)) {
361 fprintf(stderr,
"%.3f ", new_stress);
362 if (iterations % 10 == 0)
363 fprintf(stderr,
"\n");
365 converged = new_stress < old_stress
366 && fabs(new_stress - old_stress) / fabs(old_stress + 1e-10) <
372 old_stress = new_stress;
377 if ((iterations >= maxi - 1 || converged) && opt->noverlap == 1
378 && nsizeScale < 0.999) {
381 fprintf(stderr,
"nsizescale=%f,iterations=%d\n",
382 nsizeScale, iterations);
400 if (opt->noverlap == 1 && nsizeScale > 0.001) {
401 generateNonoverlapConstraints(cMajEnvHor, nsizeScale, coords,
406 if (cMajEnvHor->m > 0) {
407 constrained_majorization_vpsc(cMajEnvHor, b[0], coords[0],
408 localConstrMajorIterations);
419 if (opt->noverlap == 1 && nsizeScale > 0.001) {
420 generateNonoverlapConstraints(cMajEnvVrt, nsizeScale, coords,
423 if (cMajEnvVrt->m > 0) {
424 if (constrained_majorization_vpsc(cMajEnvVrt, b[1], coords[1],
425 localConstrMajorIterations) < 0) {
435 fprintf(stderr,
"\nfinal e = %f %d iterations %.2f sec\n",
438 deleteCMajEnvVPSC(cMajEnvHor);
439 deleteCMajEnvVPSC(cMajEnvVrt);
441 if (opt->noverlap == 2) {
443 removeoverlaps(orig_n, coords, opt);
447 if (coords !=
NULL) {
448 for (i = 0; i <
dim; i++) {
449 for (
int j = 0; j < orig_n; j++) {
450 d_coords[i][j] = coords[i][j];
462 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