37 static void MSKAPI printstr(
void *handle,
char str[])
39 fprintf(logfile,
"%s", str);
42 #define INIT_sub_val(a,b) \
50 #define INIT_sub_val3(a,b,c) \
74 MosekEnv *mosek_init_hier(
float *lap,
int n,
int *ordering,
75 int *level_indexes,
int num_divisions,
79 int i, j, num_levels = num_divisions + 1;
81 MosekEnv *mskEnv =
GNEW(MosekEnv);
83 int nonzero_lapsize = (n * (n - 1)) / 2;
88 mskEnv->num_variables = n + num_divisions + 1;
90 logfile = fopen(
"quad_solve_log",
"w");
91 levels = assign_digcola_levels(ordering, n, level_indexes, num_divisions);
92 #ifdef DUMP_CONSTRAINTS
93 print_digcola_levels(logfile, levels, num_levels);
98 mskEnv->qval =
N_GNEW(nonzero_lapsize,
double);
99 mskEnv->qsubi =
N_GNEW(nonzero_lapsize,
int);
100 mskEnv->qsubj =
N_GNEW(nonzero_lapsize,
int);
103 mskEnv->xx =
N_GNEW(mskEnv->num_variables,
double);
107 num_constraints = get_num_digcola_constraints(levels,
108 num_levels) + num_divisions + 1;
112 #ifdef EQUAL_WIDTH_LEVELS
113 num_constraints += num_divisions;
117 for (i = 0; i < n - 1; i++) {
118 for (j = i; j < n - 1; j++) {
119 mskEnv->qval[count] = -2 * lap[count + n];
120 assert(mskEnv->qval[count] != 0);
121 mskEnv->qsubi[count] = j;
122 mskEnv->qsubj[count] = i;
126 #ifdef DUMP_CONSTRAINTS
127 fprintf(logfile,
"Q=[");
129 for (i = 0; i < mskEnv->num_variables; i++) {
131 fprintf(logfile,
";");
132 for (j = 0; j < mskEnv->num_variables; j++) {
133 if (j < i || i >= n - 1 || j >= n - 1) {
134 fprintf(logfile,
"0 ");
136 fprintf(logfile,
"%f ", -2 * lap[lapcntr++]);
140 fprintf(logfile,
"]\nQ=Q-diag(diag(Q))+Q'\n");
142 fprintf(logfile,
"\n");
147 if (mskEnv->r == MSK_RES_OK) {
151 MSK_linkfunctoenvstream(mskEnv->env, MSK_STREAM_LOG,
NULL,
156 mskEnv->r = MSK_initenv(mskEnv->env);
157 if (mskEnv->r == MSK_RES_OK) {
160 MSK_maketask(mskEnv->env, num_constraints,
161 mskEnv->num_variables, &mskEnv->task);
163 if (mskEnv->r == MSK_RES_OK) {
167 MSK_linkfunctotaskstream(mskEnv->task, MSK_STREAM_LOG,
170 if (mskEnv->r == MSK_RES_OK)
171 mskEnv->r = MSK_resizetask(mskEnv->task, num_constraints, mskEnv->num_variables, 0,
173 2 * num_constraints +
174 num_divisions, nonzero_lapsize);
177 if (mskEnv->r == MSK_RES_OK)
178 mskEnv->r = MSK_append(mskEnv->task, 1, num_constraints);
181 if (mskEnv->r == MSK_RES_OK)
183 MSK_append(mskEnv->task, 0, mskEnv->num_variables);
186 j < mskEnv->num_variables && mskEnv->r == MSK_RES_OK; ++j)
188 MSK_putbound(mskEnv->task, 0, j, MSK_BK_RA,
189 -MSK_INFINITY, MSK_INFINITY);
190 for (j = 0; j < levels[0].num_nodes && mskEnv->r == MSK_RES_OK;
192 int node = levels[0].nodes[j] - 1;
194 INIT_sub_val(c_var,node);
196 MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
200 MSK_putaij(mskEnv->task, c_ind, c_var, 1.0);
203 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
204 separation, MSK_INFINITY);
207 for (i = 0; i < num_divisions && mskEnv->r == MSK_RES_OK; i++) {
210 j < levels[i].num_nodes && mskEnv->r == MSK_RES_OK;
213 int node = levels[i].nodes[j] - 1;
215 INIT_sub_val(node,c_var);
217 MSK_putavec(mskEnv->task, 1, c_ind, 2, subi,
222 MSK_putaij(mskEnv->task, c_ind, c_var, -1.0);
225 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
226 separation, MSK_INFINITY);
230 j < levels[i + 1].num_nodes
231 && mskEnv->r == MSK_RES_OK; j++) {
232 int node = levels[i + 1].nodes[j] - 1;
234 INIT_sub_val(c_var,node);
236 MSK_putavec(mskEnv->task, 1, c_ind, 2, subi,
241 MSK_putaij(mskEnv->task, c_ind, c_var, 1.0);
244 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
245 separation, MSK_INFINITY);
250 for (j = 0; j < levels[i].num_nodes && mskEnv->r == MSK_RES_OK;
253 int node = levels[i].nodes[j] - 1;
255 INIT_sub_val(node,c_var);
257 MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
261 MSK_putaij(mskEnv->task, c_ind, c_var, -1.0);
264 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
265 separation, MSK_INFINITY);
269 for (i = 0; i < num_divisions + 1 && mskEnv->r == MSK_RES_OK;
271 int c_var = n - 1 + i, c_var2 = c_var + 1;
272 INIT_sub_val(c_var,c_var2);
274 MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
276 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO, 0,
280 #ifdef EQUAL_WIDTH_LEVELS
281 for (i = 1; i < num_divisions + 1 && mskEnv->r == MSK_RES_OK;
283 int c_var = n - 1 + i, c_var_lo = c_var - 1, c_var_hi =
285 INIT_sub_val3(c_var_lo, c_var, c_var_h);
287 MSK_putavec(mskEnv->task, 1, c_ind, 3, subi, vali);
289 MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_FX, 0, 0);
293 assert(c_ind == num_constraints);
294 #ifdef DUMP_CONSTRAINTS
295 fprintf(logfile,
"A=[");
296 for (i = 0; i < num_constraints; i++) {
298 fprintf(logfile,
";");
299 for (j = 0; j < mskEnv->num_variables; j++) {
301 MSK_getaij(mskEnv->task, i, j, &aij);
302 fprintf(logfile,
"%f ", aij);
305 fprintf(logfile,
"]\n");
306 fprintf(logfile,
"b=[");
307 for (i = 0; i < num_constraints; i++) {
308 fprintf(logfile,
"%f ", separation);
310 fprintf(logfile,
"]\n");
312 if (mskEnv->r == MSK_RES_OK) {
318 MSK_putqobj(mskEnv->task, nonzero_lapsize,
319 mskEnv->qsubi, mskEnv->qsubj,
324 delete_digcola_levels(levels, num_levels);
335 void mosek_quad_solve_hier(MosekEnv * mskEnv,
float *b,
int n,
336 float *coords,
float *hierarchy_boundaries)
339 for (i = 1; i < n && mskEnv->r == MSK_RES_OK; i++) {
340 mskEnv->r = MSK_putcj(mskEnv->task, i - 1, -2 * b[i]);
342 #ifdef DUMP_CONSTRAINTS
343 fprintf(logfile,
"x0=[");
344 for (j = 0; j < mskEnv->num_variables; j++) {
345 fprintf(logfile,
"%f ", j < n ? b[j] : 0);
347 fprintf(logfile,
"]\n");
348 fprintf(logfile,
"f=[");
349 double *c =
N_GNEW(mskEnv->num_variables,
double);
350 MSK_getc(mskEnv->task, c);
351 for (j = 0; j < mskEnv->num_variables; j++) {
352 fprintf(logfile,
"%f ", c[j]);
355 fprintf(logfile,
"]\n");
357 if (mskEnv->r == MSK_RES_OK)
358 mskEnv->r = MSK_optimize(mskEnv->task);
360 if (mskEnv->r == MSK_RES_OK) {
361 MSK_getsolutionslice(mskEnv->task,
364 0, mskEnv->num_variables, mskEnv->xx);
366 #ifdef DUMP_CONSTRAINTS
367 fprintf(logfile,
"Primal solution\n");
370 for (j = 0; j < mskEnv->num_variables; ++j) {
371 #ifdef DUMP_CONSTRAINTS
372 fprintf(logfile,
"x[%d]: %.2f\n", j, mskEnv->xx[j]);
375 coords[j + 1] = -mskEnv->xx[j];
376 }
else if (j >= n && j < mskEnv->num_variables - 1) {
377 hierarchy_boundaries[j - n] = -mskEnv->xx[j];
381 fprintf(logfile,
"Return code: %d\n", mskEnv->r);
390 MosekEnv *mosek_init_sep(
float *lap,
int num_variables,
int num_dummy_vars,
391 Constraint ** cs,
int num_constraints)
394 MosekEnv *mskEnv =
GNEW(MosekEnv);
396 int nonzero_lapsize = num_variables * (num_variables - 1) / 2;
398 mskEnv->num_variables = num_variables + num_dummy_vars - 1;
400 fprintf(stderr,
"MOSEK!\n");
401 logfile = fopen(
"quad_solve_log",
"w");
404 mskEnv->qval =
N_GNEW(nonzero_lapsize,
double);
405 mskEnv->qsubi =
N_GNEW(nonzero_lapsize,
int);
406 mskEnv->qsubj =
N_GNEW(nonzero_lapsize,
int);
409 mskEnv->xx =
N_GNEW(mskEnv->num_variables,
double);
413 for (i = 0; i < num_variables - 1; i++) {
414 for (j = i; j < num_variables - 1; j++) {
415 mskEnv->qval[count] = -2 * lap[count + num_variables];
417 mskEnv->qsubi[count] = j;
418 mskEnv->qsubj[count] = i;
422 #ifdef DUMP_CONSTRAINTS
423 fprintf(logfile,
"Q=[");
425 for (i = 0; i < num_variables - 1; i++) {
427 fprintf(logfile,
";");
428 for (j = 0; j < num_variables - 1; j++) {
430 fprintf(logfile,
"0 ");
432 fprintf(logfile,
"%f ", -2 * lap[num_variables + count++]);
436 fprintf(logfile,
"]\nQ=Q-diag(diag(Q))+Q'\n");
442 if (mskEnv->r == MSK_RES_OK) {
445 MSK_linkfunctoenvstream(mskEnv->env, MSK_STREAM_LOG,
NULL,
450 mskEnv->r = MSK_initenv(mskEnv->env);
451 if (mskEnv->r == MSK_RES_OK) {
454 MSK_maketask(mskEnv->env, num_constraints,
455 mskEnv->num_variables, &mskEnv->task);
457 if (mskEnv->r == MSK_RES_OK) {
459 MSK_linkfunctotaskstream(mskEnv->task, MSK_STREAM_LOG,
462 if (mskEnv->r == MSK_RES_OK)
463 mskEnv->r = MSK_resizetask(mskEnv->task, num_constraints, mskEnv->num_variables, 0,
471 if (mskEnv->r == MSK_RES_OK)
472 mskEnv->r = MSK_append(mskEnv->task, 1, num_constraints);
475 if (mskEnv->r == MSK_RES_OK)
477 MSK_append(mskEnv->task, 0, mskEnv->num_variables);
480 j < mskEnv->num_variables && mskEnv->r == MSK_RES_OK; j++)
482 MSK_putbound(mskEnv->task, 0, j, MSK_BK_RA,
483 -MSK_INFINITY, MSK_INFINITY);
484 for (i = 0; i < num_constraints; i++) {
485 int u = getLeftVarID(cs[i]) - 1;
486 int v = getRightVarID(cs[i]) - 1;
487 double separation = getSeparation(cs[i]);
490 MSK_putbound(mskEnv->task, 0, v, MSK_BK_RA,
491 -MSK_INFINITY, -separation);
492 assert(mskEnv->r == MSK_RES_OK);
495 MSK_putbound(mskEnv->task, 0, u, MSK_BK_RA,
496 separation, MSK_INFINITY);
497 assert(mskEnv->r == MSK_RES_OK);
502 MSK_putavec(mskEnv->task, 1, i, 2, subi, vali);
503 assert(mskEnv->r == MSK_RES_OK);
505 MSK_putbound(mskEnv->task, 1, i, MSK_BK_LO,
506 separation, MSK_INFINITY);
507 assert(mskEnv->r == MSK_RES_OK);
510 if (mskEnv->r == MSK_RES_OK) {
516 MSK_putqobj(mskEnv->task, nonzero_lapsize,
517 mskEnv->qsubi, mskEnv->qsubj,
519 assert(mskEnv->r == MSK_RES_OK);
532 void mosek_quad_solve_sep(MosekEnv * mskEnv,
int n,
float *b,
536 assert(n <= mskEnv->num_variables + 1);
537 for (i = 0; i < n - 1 && mskEnv->r == MSK_RES_OK; i++) {
538 mskEnv->r = MSK_putcj(mskEnv->task, i, -2 * b[i + 1]);
540 if (mskEnv->r == MSK_RES_OK)
541 mskEnv->r = MSK_optimize(mskEnv->task);
543 if (mskEnv->r == MSK_RES_OK) {
544 MSK_getsolutionslice(mskEnv->task,
547 0, mskEnv->num_variables, mskEnv->xx);
549 #ifdef DUMP_CONSTRAINTS
550 fprintf(logfile,
"Primal solution\n");
553 for (j = 1; j <= n; j++) {
554 #ifdef DUMP_CONSTRAINTS
555 fprintf(logfile,
"x[%d]: %.2f\n", j, mskEnv->xx[j - 1]);
557 coords[j] = -mskEnv->xx[j - 1];
560 fprintf(logfile,
"Return code: %d\n", mskEnv->r);
566 void mosek_delete(MosekEnv * mskEnv)
568 MSK_deletetask(&mskEnv->task);
569 MSK_deleteenv(&mskEnv->env);
Agnode_t * node(Agraph_t *g, char *name)