00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "digcola.h"
00018 #ifdef DIGCOLA
00019 #include <math.h>
00020 #include <stdlib.h>
00021 #include <time.h>
00022 #include <stdio.h>
00023 #include <float.h>
00024 #include <assert.h>
00025 #include "matrix_ops.h"
00026 #include "kkutils.h"
00027 #include "quad_prog_solver.h"
00028
00029 #define quad_prog_tol 1e-2
00030
00031 float **unpackMatrix(float *packedMat, int n)
00032 {
00033 float **mat;
00034 int i, j, k;
00035
00036 mat = N_GNEW(n, float *);
00037 mat[0] = N_GNEW(n * n, float);
00038 set_vector_valf(n * n, 0, mat[0]);
00039 for (i = 1; i < n; i++) {
00040 mat[i] = mat[0] + i * n;
00041 }
00042
00043 for (i = 0, k = 0; i < n; i++) {
00044 for (j = i; j < n; j++, k++) {
00045 mat[j][i] = mat[i][j] = packedMat[k];
00046 }
00047 }
00048 return mat;
00049 }
00050
00051 static void ensureMonotonicOrdering(float *place, int n, int *ordering)
00052 {
00053
00054
00055 int i, node;
00056 float lower_bound = place[ordering[0]];
00057 for (i = 1; i < n; i++) {
00058 node = ordering[i];
00059 if (place[node] < lower_bound) {
00060 place[node] = lower_bound;
00061 }
00062 lower_bound = place[node];
00063 }
00064 }
00065
00066 static void
00067 ensureMonotonicOrderingWithGaps(float *place, int n, int *ordering,
00068 int *levels, int num_levels,
00069 float levels_gap)
00070 {
00071
00072
00073
00074
00075 int i;
00076 int node, level, max_in_level;
00077 float lower_bound = (float) -1e9;
00078
00079 level = -1;
00080 max_in_level = 0;
00081 for (i = 0; i < n; i++) {
00082 if (i >= max_in_level) {
00083
00084 level++;
00085 if (level == num_levels) {
00086
00087 max_in_level = n;
00088 } else {
00089 max_in_level = levels[level];
00090 }
00091 lower_bound =
00092 i > 0 ? place[ordering[i - 1]] + levels_gap : (float) -1e9;
00093 quicksort_placef(place, ordering, i, max_in_level - 1);
00094 }
00095
00096 node = ordering[i];
00097 if (place[node] < lower_bound) {
00098 place[node] = lower_bound;
00099 }
00100 }
00101 }
00102
00103 static void
00104 computeHierarchyBoundaries(float *place, int n, int *ordering, int *levels,
00105 int num_levels, float *hierarchy_boundaries)
00106 {
00107 int i;
00108 for (i = 0; i < num_levels; i++) {
00109 hierarchy_boundaries[i] = place[ordering[levels[i] - 1]];
00110 }
00111 }
00112
00113
00114 int
00115 constrained_majorization_new(CMajEnv * e, float *b, float **coords,
00116 int cur_axis, int dims, int max_iterations,
00117 float *hierarchy_boundaries, float levels_gap)
00118 {
00119 int n = e->n;
00120 float *place = coords[cur_axis];
00121 float **lap = e->A;
00122 int *ordering = e->ordering;
00123 int *levels = e->levels;
00124 int num_levels = e->num_levels;
00125 int i, j;
00126 float new_place_i;
00127 boolean converged = FALSE;
00128 float upper_bound, lower_bound;
00129 int node;
00130 int left, right;
00131 float cur_place;
00132 float des_place_block;
00133 float block_deg;
00134 float toBlockConnectivity;
00135 float *lap_node;
00136 int block_len;
00137 int first_next_level;
00138 int level = -1, max_in_level = 0;
00139 float *desired_place;
00140 float *prefix_desired_place;
00141 float *suffix_desired_place;
00142 int *block;
00143 int *lev;
00144 int counter;
00145
00146 if (max_iterations <= 0) {
00147 return 0;
00148 }
00149 if (levels_gap != 0) {
00150 return constrained_majorization_new_with_gaps(e, b, coords,
00151 cur_axis, dims,
00152 max_iterations,
00153 hierarchy_boundaries,
00154 levels_gap);
00155 }
00156
00157
00158 ensureMonotonicOrdering(place, n, ordering);
00159
00160
00161
00162
00163
00164 desired_place = e->fArray1;
00165
00166 prefix_desired_place = e->fArray2;
00167
00168 suffix_desired_place = e->fArray3;
00169
00170 block = e->iArray1;
00171
00172 lev = e->iArray2;
00173 for (i = 0; i < n; i++) {
00174 if (i >= max_in_level) {
00175
00176 level++;
00177 if (level == num_levels) {
00178
00179 max_in_level = n;
00180 } else {
00181 max_in_level = levels[level];
00182 }
00183 }
00184 node = ordering[i];
00185 lev[node] = level;
00186 }
00187
00188 for (counter = 0; counter < max_iterations && !converged; counter++) {
00189 converged = TRUE;
00190 lower_bound = -1e9;
00191 for (left = 0; left < n; left = right) {
00192 int best_i;
00193 double max_movement;
00194 double movement;
00195 float prefix_des_place, suffix_des_place;
00196
00197
00198
00199 cur_place = place[ordering[left]];
00200 for (right = left + 1; right < n; right++) {
00201 if (place[ordering[right]] != cur_place) {
00202 break;
00203 }
00204 }
00205
00206
00207 for (i = left; i < right; i++) {
00208 node = ordering[i];
00209 new_place_i = -b[node];
00210 lap_node = lap[node];
00211 for (j = 0; j < n; j++) {
00212 if (j == node) {
00213 continue;
00214 }
00215 new_place_i += lap_node[j] * place[j];
00216 }
00217 desired_place[node] = new_place_i / (-lap_node[node]);
00218 }
00219
00220
00221 block_len = 0;
00222 first_next_level = 0;
00223 for (i = left; i < right; i = first_next_level) {
00224 level = lev[ordering[i]];
00225 if (level == num_levels) {
00226
00227 first_next_level = right;
00228 } else {
00229 first_next_level = MIN(right, levels[level]);
00230 }
00231
00232
00233 for (j = i; j < first_next_level; j++) {
00234 node = ordering[j];
00235 if (desired_place[node] < cur_place) {
00236 block[block_len++] = node;
00237 }
00238 }
00239
00240 for (j = i; j < first_next_level; j++) {
00241 node = ordering[j];
00242 if (desired_place[node] == cur_place) {
00243 block[block_len++] = node;
00244 }
00245 }
00246
00247 for (j = i; j < first_next_level; j++) {
00248 node = ordering[j];
00249 if (desired_place[node] > cur_place) {
00250 block[block_len++] = node;
00251 }
00252 }
00253 }
00254
00255
00256 des_place_block = 0;
00257 block_deg = 0;
00258 for (i = 0; i < block_len; i++) {
00259 node = block[i];
00260 toBlockConnectivity = 0;
00261 lap_node = lap[node];
00262 for (j = 0; j < i; j++) {
00263 toBlockConnectivity -= lap_node[block[j]];
00264 }
00265 toBlockConnectivity *= 2;
00266
00267 des_place_block =
00268 (block_deg * des_place_block +
00269 (-lap_node[node]) * desired_place[node] +
00270 toBlockConnectivity * cur_place) / (block_deg -
00271 lap_node[node] +
00272 toBlockConnectivity);
00273 prefix_desired_place[i] = des_place_block;
00274 block_deg += toBlockConnectivity - lap_node[node];
00275 }
00276
00277
00278 des_place_block = 0;
00279 block_deg = 0;
00280 for (i = block_len - 1; i >= 0; i--) {
00281 node = block[i];
00282 toBlockConnectivity = 0;
00283 lap_node = lap[node];
00284 for (j = i + 1; j < block_len; j++) {
00285 toBlockConnectivity -= lap_node[block[j]];
00286 }
00287 toBlockConnectivity *= 2;
00288
00289 des_place_block =
00290 (block_deg * des_place_block +
00291 (-lap_node[node]) * desired_place[node] +
00292 toBlockConnectivity * cur_place) / (block_deg -
00293 lap_node[node] +
00294 toBlockConnectivity);
00295 suffix_desired_place[i] = des_place_block;
00296 block_deg += toBlockConnectivity - lap_node[node];
00297 }
00298
00299
00300
00301 best_i = -1;
00302 max_movement = 0;
00303 for (i = 0; i < block_len; i++) {
00304 suffix_des_place = suffix_desired_place[i];
00305 prefix_des_place =
00306 i > 0 ? prefix_desired_place[i - 1] : suffix_des_place;
00307
00308 if (suffix_des_place < prefix_des_place) {
00309 if (suffix_des_place < cur_place) {
00310 if (prefix_des_place > cur_place) {
00311 prefix_des_place = cur_place;
00312 }
00313 suffix_des_place = prefix_des_place;
00314 } else if (prefix_des_place > cur_place) {
00315 prefix_des_place = suffix_des_place;
00316 }
00317 }
00318 movement =
00319 (block_len - i) * fabs(suffix_des_place - cur_place) +
00320 i * fabs(prefix_des_place - cur_place);
00321 if (movement > max_movement) {
00322 max_movement = movement;
00323 best_i = i;
00324 }
00325 }
00326
00327 if (best_i >= 0) {
00328 suffix_des_place = suffix_desired_place[best_i];
00329 prefix_des_place =
00330 best_i >
00331 0 ? prefix_desired_place[best_i -
00332 1] : suffix_des_place;
00333
00334
00335 if (right >= n) {
00336
00337 upper_bound = 1e9;
00338 } else {
00339 upper_bound = place[ordering[right]];
00340 }
00341 suffix_des_place = MIN(suffix_des_place, upper_bound);
00342 prefix_des_place = MAX(prefix_des_place, lower_bound);
00343
00344
00345 if (suffix_des_place < prefix_des_place) {
00346 if (suffix_des_place < cur_place) {
00347 if (prefix_des_place > cur_place) {
00348 prefix_des_place = cur_place;
00349 }
00350 suffix_des_place = prefix_des_place;
00351 } else if (prefix_des_place > cur_place) {
00352 prefix_des_place = suffix_des_place;
00353 }
00354 }
00355
00356
00357 for (i = 0; i < best_i; i++) {
00358 place[block[i]] = prefix_des_place;
00359 }
00360
00361 for (i = best_i; i < block_len; i++) {
00362 place[block[i]] = suffix_des_place;
00363 }
00364
00365 lower_bound = suffix_des_place;
00366
00367
00368
00369
00370
00371 #if 0
00372 int max_in_level, min_in_level;
00373
00374 level = lev[best_i];
00375 if (level == num_levels) {
00376
00377 max_in_level = MIN(right, n);
00378 } else {
00379 max_in_level = MIN(right, levels[level]);
00380 }
00381 if (level == 0) {
00382
00383 min_in_level = MAX(left, 0);
00384 } else {
00385 min_in_level = MAX(left, levels[level - 1]);
00386 }
00387 #endif
00388 for (i = left; i < right; i++) {
00389 ordering[i] = block[i - left];
00390 }
00391 converged = converged
00392 && fabs(prefix_des_place - cur_place) < quad_prog_tol
00393 && fabs(suffix_des_place - cur_place) < quad_prog_tol;
00394
00395 } else {
00396
00397 lower_bound = cur_place;
00398 }
00399
00400 }
00401 }
00402
00403 computeHierarchyBoundaries(place, n, ordering, levels, num_levels,
00404 hierarchy_boundaries);
00405
00406 return counter;
00407 }
00408
00409 #ifdef IPSEPCOLA
00410 static float *place;
00411 static int compare_incr(const void *a, const void *b)
00412 {
00413 if (place[*(int *) a] > place[*(int *) b]) {
00414 return 1;
00415 } else if (place[*(int *) a] < place[*(int *) b]) {
00416 return -1;
00417 }
00418 return 0;
00419 }
00420
00421
00422
00423
00424
00425 int constrained_majorization_gradient_projection(CMajEnv * e,
00426 float *b, float **coords,
00427 int ndims, int cur_axis,
00428 int max_iterations,
00429 float
00430 *hierarchy_boundaries,
00431 float levels_gap)
00432 {
00433
00434 int i, j, counter;
00435 int *ordering = e->ordering;
00436 int *levels = e->levels;
00437 int num_levels = e->num_levels;
00438 boolean converged = FALSE;
00439 float *g = e->fArray1;
00440 float *old_place = e->fArray2;
00441 float *d = e->fArray4;
00442 float test = 0, tmptest = 0;
00443 float beta;
00444
00445 if (max_iterations == 0)
00446 return 0;
00447
00448 place = coords[cur_axis];
00449 #ifdef CONMAJ_LOGGING
00450 double prev_stress = 0;
00451 static int call_no = 0;
00452 for (i = 0; i < e->n; i++) {
00453 prev_stress += 2 * b[i] * place[i];
00454 for (j = 0; j < e->n; j++) {
00455 prev_stress -= e->A[i][j] * place[j] * place[i];
00456 }
00457 }
00458 FILE *logfile = fopen("constrained_majorization_log", "a");
00459
00460 fprintf(logfile, "grad proj %d: stress=%f\n", call_no, prev_stress);
00461 #endif
00462 for (counter = 0; counter < max_iterations && !converged; counter++) {
00463 float alpha;
00464 float numerator = 0, denominator = 0, r;
00465 converged = TRUE;
00466
00467 for (i = 0; i < e->n; i++) {
00468 old_place[i] = place[i];
00469 g[i] = 2 * b[i];
00470 for (j = 0; j < e->n; j++) {
00471 g[i] -= 2 * e->A[i][j] * place[j];
00472 }
00473 }
00474 for (i = 0; i < e->n; i++) {
00475 numerator += g[i] * g[i];
00476 r = 0;
00477 for (j = 0; j < e->n; j++) {
00478 r += 2 * e->A[i][j] * g[j];
00479 }
00480 denominator -= r * g[i];
00481 }
00482 alpha = numerator / denominator;
00483 for (i = 0; i < e->n; i++) {
00484 if (alpha > 0 && alpha < 1000) {
00485 place[i] -= alpha * g[i];
00486 }
00487 }
00488 if (num_levels)
00489 qsort((int *) ordering, (size_t) levels[0], sizeof(int),
00490 compare_incr);
00491
00492 for (i = 0; i < num_levels; i++) {
00493 int endOfLevel = i == num_levels - 1 ? e->n : levels[i + 1];
00494 int ui, li, u, l;
00495
00496
00497 qsort((int *) ordering + levels[i],
00498 (size_t) endOfLevel - levels[i], sizeof(int),
00499 compare_incr);
00500
00501 ui = levels[i]; li = ui - 1;
00502 l = ordering[li--]; u = ordering[ui++];
00503 if (place[l] + levels_gap > place[u]) {
00504 float sum =
00505 place[l] + place[u] - levels_gap * (e->lev[l] +
00506 e->lev[u]), w = 2;
00507 float avgPos = sum / w;
00508 float pos;
00509 boolean finished;
00510 do {
00511 finished = TRUE;
00512 if (ui < endOfLevel) {
00513 u = ordering[ui];
00514 pos = place[u] - levels_gap * e->lev[u];
00515 if (pos < avgPos) {
00516 ui++;
00517 w++;
00518 sum += pos;
00519 avgPos = sum / w;
00520 finished = FALSE;
00521 }
00522 }
00523
00524 if (li >= 0) {
00525 l = ordering[li];
00526 pos = place[l] - levels_gap * e->lev[l];
00527 if (pos > avgPos) {
00528 li--;
00529 w++;
00530 sum += pos;
00531 avgPos = sum / w;
00532 finished = FALSE;
00533 }
00534 }
00535 } while (!finished);
00536 for (j = li + 1; j < ui; j++) {
00537 place[ordering[j]] =
00538 avgPos + levels_gap * e->lev[ordering[j]];
00539 }
00540 }
00541 }
00542
00543 for (i = 0; i < e->n; i++) {
00544 d[i] = place[i] - old_place[i];
00545 }
00546
00547 numerator = 0, denominator = 0;
00548 for (i = 0; i < e->n; i++) {
00549 numerator += g[i] * d[i];
00550 r = 0;
00551 for (j = 0; j < e->n; j++) {
00552 r += 2 * e->A[i][j] * d[j];
00553 }
00554 denominator += r * d[i];
00555 }
00556 beta = numerator / denominator;
00557
00558 for (i = 0; i < e->n; i++) {
00559 if (beta > 0 && beta < 1.0) {
00560 place[i] = old_place[i] + beta * d[i];
00561 }
00562 tmptest = fabs(place[i] - old_place[i]);
00563 if (test < tmptest)
00564 test = tmptest;
00565 }
00566 computeHierarchyBoundaries(place, e->n, ordering, levels,
00567 num_levels, hierarchy_boundaries);
00568 #if 0
00569 if (num_levels)
00570 qsort((int *) ordering, (size_t) levels[0], sizeof(int),
00571 compare_incr);
00572 for (i = 0; i < num_levels; i++) {
00573 int endOfLevel = i == num_levels - 1 ? e->n : levels[i + 1];
00574
00575 qsort((int *) ordering + levels[i],
00576 (size_t) endOfLevel - levels[i], sizeof(int),
00577 compare_incr);
00578
00579 int l = ordering[levels[i] - 1], u = ordering[levels[i]];
00580
00581 }
00582 #endif
00583 #ifdef CONMAJ_LOGGING
00584 double stress = 0;
00585 for (i = 0; i < e->n; i++) {
00586 stress += 2 * b[i] * place[i];
00587 for (j = 0; j < e->n; j++) {
00588 stress -= e->A[i][j] * place[j] * place[i];
00589 }
00590 }
00591 fprintf(logfile, "%d: stress=%f, test=%f, %s\n", call_no, stress,
00592 test, (stress >= prev_stress) ? "No Improvement" : "");
00593 prev_stress = stress;
00594 #endif
00595 if (test > quad_prog_tol) {
00596 converged = FALSE;
00597 }
00598 }
00599 #ifdef CONMAJ_LOGGING
00600 call_no++;
00601 fclose(logfile);
00602 #endif
00603 return counter;
00604 }
00605 #endif
00606
00607 int
00608 constrained_majorization_new_with_gaps(CMajEnv * e, float *b,
00609 float **coords, int ndims,
00610 int cur_axis, int max_iterations,
00611 float *hierarchy_boundaries,
00612 float levels_gap)
00613 {
00614 float *place = coords[cur_axis];
00615 int i, j;
00616 int n = e->n;
00617 float **lap = e->A;
00618 int *ordering = e->ordering;
00619 int *levels = e->levels;
00620 int num_levels = e->num_levels;
00621 float new_place_i;
00622 boolean converged = FALSE;
00623 float upper_bound, lower_bound;
00624 int node;
00625 int left, right;
00626 float cur_place;
00627 float des_place_block;
00628 float block_deg;
00629 float toBlockConnectivity;
00630 float *lap_node;
00631 float *desired_place;
00632 float *prefix_desired_place;
00633 float *suffix_desired_place;
00634 int *block;
00635 int block_len;
00636 int first_next_level;
00637 int *lev;
00638 int level = -1, max_in_level = 0;
00639 int counter;
00640 float *gap;
00641 float total_gap, target_place;
00642
00643 if (max_iterations <= 0) {
00644 return 0;
00645 }
00646
00647 ensureMonotonicOrderingWithGaps(place, n, ordering, levels, num_levels,
00648 levels_gap);
00649
00650
00651
00652
00653
00654 desired_place = e->fArray1;
00655
00656 prefix_desired_place = e->fArray2;
00657
00658 suffix_desired_place = e->fArray3;
00659
00660 block = e->iArray1;
00661
00662 lev = e->iArray2;
00663 for (i = 0; i < n; i++) {
00664 if (i >= max_in_level) {
00665
00666 level++;
00667 if (level == num_levels) {
00668
00669 max_in_level = n;
00670 } else {
00671 max_in_level = levels[level];
00672 }
00673 }
00674 node = ordering[i];
00675 lev[node] = level;
00676 }
00677
00678
00679 gap = e->fArray4;
00680
00681 for (counter = 0; counter < max_iterations && !converged; counter++) {
00682 converged = TRUE;
00683 lower_bound = -1e9;
00684 for (left = 0; left < n; left = right) {
00685 int best_i;
00686 double max_movement;
00687 double movement;
00688 float prefix_des_place, suffix_des_place;
00689
00690
00691
00692 cur_place = place[ordering[left]];
00693 total_gap = 0;
00694 target_place = cur_place;
00695 gap[ordering[left]] = 0;
00696 for (right = left + 1; right < n; right++) {
00697 if (lev[right] > lev[right - 1]) {
00698
00699 target_place += levels_gap;
00700 total_gap += levels_gap;
00701 }
00702 node = ordering[right];
00703 #if 0
00704 if (place[node] != target_place)
00705 #endif
00706
00707 if (fabs(place[node] - target_place) > 1e-9) {
00708 break;
00709 }
00710 gap[node] = place[node] - cur_place;
00711 }
00712
00713
00714
00715
00716 for (i = left; i < right; i++) {
00717 node = ordering[i];
00718 new_place_i = -b[node];
00719 lap_node = lap[node];
00720 for (j = 0; j < n; j++) {
00721 if (j == node) {
00722 continue;
00723 }
00724 new_place_i += lap_node[j] * place[j];
00725 }
00726 desired_place[node] =
00727 new_place_i / (-lap_node[node]) - gap[node];
00728 }
00729
00730
00731
00732
00733 block_len = 0;
00734 first_next_level = 0;
00735 for (i = left; i < right; i = first_next_level) {
00736 level = lev[ordering[i]];
00737 if (level == num_levels) {
00738
00739 first_next_level = right;
00740 } else {
00741 first_next_level = MIN(right, levels[level]);
00742 }
00743
00744
00745
00746
00747 for (j = i; j < first_next_level; j++) {
00748 node = ordering[j];
00749 if (desired_place[node] < cur_place) {
00750 block[block_len++] = node;
00751 }
00752 }
00753
00754
00755
00756 for (j = i; j < first_next_level; j++) {
00757 node = ordering[j];
00758 if (desired_place[node] == cur_place) {
00759 block[block_len++] = node;
00760 }
00761 }
00762
00763
00764
00765 for (j = i; j < first_next_level; j++) {
00766 node = ordering[j];
00767 if (desired_place[node] > cur_place) {
00768 block[block_len++] = node;
00769 }
00770 }
00771 }
00772
00773
00774 des_place_block = 0;
00775 block_deg = 0;
00776 for (i = 0; i < block_len; i++) {
00777 node = block[i];
00778 toBlockConnectivity = 0;
00779 lap_node = lap[node];
00780 for (j = 0; j < i; j++) {
00781 toBlockConnectivity -= lap_node[block[j]];
00782 }
00783 toBlockConnectivity *= 2;
00784
00785 des_place_block =
00786 (block_deg * des_place_block +
00787 (-lap_node[node]) * desired_place[node] +
00788 toBlockConnectivity * cur_place) / (block_deg -
00789 lap_node[node] +
00790 toBlockConnectivity);
00791 prefix_desired_place[i] = des_place_block;
00792 block_deg += toBlockConnectivity - lap_node[node];
00793 }
00794
00795 if (block_len == n) {
00796
00797 prefix_desired_place[n - 1] = cur_place;
00798 }
00799
00800
00801 des_place_block = 0;
00802 block_deg = 0;
00803 for (i = block_len - 1; i >= 0; i--) {
00804 node = block[i];
00805 toBlockConnectivity = 0;
00806 lap_node = lap[node];
00807 for (j = i + 1; j < block_len; j++) {
00808 toBlockConnectivity -= lap_node[block[j]];
00809 }
00810 toBlockConnectivity *= 2;
00811
00812 des_place_block =
00813 (block_deg * des_place_block +
00814 (-lap_node[node]) * desired_place[node] +
00815 toBlockConnectivity * cur_place) / (block_deg -
00816 lap_node[node] +
00817 toBlockConnectivity);
00818 suffix_desired_place[i] = des_place_block;
00819 block_deg += toBlockConnectivity - lap_node[node];
00820 }
00821
00822 if (block_len == n) {
00823
00824 suffix_desired_place[0] = cur_place;
00825 }
00826
00827
00828
00829 best_i = -1;
00830 max_movement = 0;
00831 for (i = 0; i < block_len; i++) {
00832 suffix_des_place = suffix_desired_place[i];
00833 prefix_des_place =
00834 i > 0 ? prefix_desired_place[i - 1] : suffix_des_place;
00835
00836 if (suffix_des_place < prefix_des_place) {
00837 if (suffix_des_place < cur_place) {
00838 if (prefix_des_place > cur_place) {
00839 prefix_des_place = cur_place;
00840 }
00841 suffix_des_place = prefix_des_place;
00842 } else if (prefix_des_place > cur_place) {
00843 prefix_des_place = suffix_des_place;
00844 }
00845 }
00846 movement =
00847 (block_len - i) * fabs(suffix_des_place - cur_place) +
00848 i * fabs(prefix_des_place - cur_place);
00849 if (movement > max_movement) {
00850 max_movement = movement;
00851 best_i = i;
00852 }
00853 }
00854
00855 if (best_i >= 0) {
00856 suffix_des_place = suffix_desired_place[best_i];
00857 prefix_des_place =
00858 best_i >
00859 0 ? prefix_desired_place[best_i -
00860 1] : suffix_des_place;
00861
00862
00863 if (right >= n) {
00864
00865 upper_bound = 1e9;
00866 } else {
00867
00868
00869
00870
00871 if (lev[ordering[right]] > lev[ordering[right - 1]]) {
00872 upper_bound =
00873 place[ordering[right]] - levels_gap -
00874 gap[block[block_len - 1]];
00875 } else {
00876 upper_bound =
00877 place[ordering[right]] -
00878 gap[block[block_len - 1]];
00879 }
00880 }
00881 suffix_des_place = MIN(suffix_des_place, upper_bound);
00882 prefix_des_place = MAX(prefix_des_place, lower_bound);
00883
00884
00885 if (suffix_des_place < prefix_des_place) {
00886 if (suffix_des_place < cur_place) {
00887 if (prefix_des_place > cur_place) {
00888 prefix_des_place = cur_place;
00889 }
00890 suffix_des_place = prefix_des_place;
00891 } else if (prefix_des_place > cur_place) {
00892 prefix_des_place = suffix_des_place;
00893 }
00894 }
00895
00896
00897 for (i = 0; i < best_i; i++) {
00898 place[block[i]] = prefix_des_place + gap[block[i]];
00899 }
00900
00901 for (i = best_i; i < block_len; i++) {
00902 place[block[i]] = suffix_des_place + gap[block[i]];
00903 }
00904
00905
00906
00907 if (right < n
00908 && lev[ordering[right]] > lev[ordering[right - 1]]) {
00909 lower_bound = place[block[block_len - 1]] + levels_gap;
00910 } else {
00911 lower_bound = place[block[block_len - 1]];
00912 }
00913
00914
00915
00916
00917
00918
00919 #if 0
00920 int max_in_level, min_in_level;
00921
00922 level = lev[best_i];
00923 if (level == num_levels) {
00924
00925 max_in_level = MIN(right, n);
00926 } else {
00927 max_in_level = MIN(right, levels[level]);
00928 }
00929 if (level == 0) {
00930
00931 min_in_level = MAX(left, 0);
00932 } else {
00933 min_in_level = MAX(left, levels[level - 1]);
00934 }
00935 #endif
00936 for (i = left; i < right; i++) {
00937 ordering[i] = block[i - left];
00938 }
00939 converged = converged
00940 && fabs(prefix_des_place - cur_place) < quad_prog_tol
00941 && fabs(suffix_des_place - cur_place) < quad_prog_tol;
00942
00943
00944 } else {
00945
00946
00947 if (right < n
00948 && lev[ordering[right]] > lev[ordering[right - 1]]) {
00949 lower_bound = place[block[block_len - 1]] + levels_gap;
00950 } else {
00951 lower_bound = place[block[block_len - 1]];
00952 }
00953 }
00954 }
00955 orthog1f(n, place);
00956 computeHierarchyBoundaries(place, n, ordering, levels, num_levels,
00957 hierarchy_boundaries);
00958 }
00959
00960 return counter;
00961 }
00962
00963 void deleteCMajEnv(CMajEnv * e)
00964 {
00965 free(e->A[0]);
00966 free(e->A);
00967 free(e->lev);
00968 free(e->fArray1);
00969 free(e->fArray2);
00970 free(e->fArray3);
00971 free(e->fArray4);
00972 free(e->iArray1);
00973 free(e->iArray2);
00974 free(e->iArray3);
00975 free(e->iArray4);
00976 free(e);
00977 }
00978
00979 CMajEnv *initConstrainedMajorization(float *packedMat, int n,
00980 int *ordering, int *levels,
00981 int num_levels)
00982 {
00983 int i, level = -1, start_of_level_above = 0;
00984 CMajEnv *e = GNEW(CMajEnv);
00985 e->A = NULL;
00986 e->n = n;
00987 e->ordering = ordering;
00988 e->levels = levels;
00989 e->num_levels = num_levels;
00990 e->A = unpackMatrix(packedMat, n);
00991 e->lev = N_GNEW(n, int);
00992 for (i = 0; i < e->n; i++) {
00993 if (i >= start_of_level_above) {
00994 level++;
00995 start_of_level_above =
00996 (level == num_levels) ? e->n : levels[level];
00997 }
00998 e->lev[ordering[i]] = level;
00999 }
01000 e->fArray1 = N_GNEW(n, float);
01001 e->fArray2 = N_GNEW(n, float);
01002 e->fArray3 = N_GNEW(n, float);
01003 e->fArray4 = N_GNEW(n, float);
01004 e->iArray1 = N_GNEW(n, int);
01005 e->iArray2 = N_GNEW(n, int);
01006 e->iArray3 = N_GNEW(n, int);
01007 e->iArray4 = N_GNEW(n, int);
01008 return e;
01009 }
01010 #endif