void glp_unscale_prob(glp_prob *lp) { int m = glp_get_num_rows(lp); int n = glp_get_num_cols(lp); int i, j; for (i = 1; i <= m; i++) glp_set_rii(lp, i, 1.0); for (j = 1; j <= n; j++) glp_set_sjj(lp, j, 1.0); return; }
static void scale_prob(glp_prob *lp, int flags) { static const char *fmt = "%s: min|aij| = %10.3e max|aij| = %10.3e ratio = %10.3e\n"; double min_aij, max_aij, ratio; xprintf("Scaling...\n"); /* cancel the current scaling effect */ glp_unscale_prob(lp); /* report original scaling "quality" */ min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, " A", min_aij, max_aij, ratio); /* check if the problem is well scaled */ if (min_aij >= 0.10 && max_aij <= 10.0) { xprintf("Problem data seem to be well scaled\n"); /* skip scaling, if required */ if (flags & GLP_SF_SKIP) goto done; } /* perform iterative geometric mean scaling, if required */ if (flags & GLP_SF_GM) { gm_iterate(lp, 15, 0.90); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "GM", min_aij, max_aij, ratio); } /* perform equilibration scaling, if required */ if (flags & GLP_SF_EQ) { eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp)); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "EQ", min_aij, max_aij, ratio); } /* round scale factors to nearest power of two, if required */ if (flags & GLP_SF_2N) { int i, j; for (i = 1; i <= lp->m; i++) glp_set_rii(lp, i, round2n(glp_get_rii(lp, i))); for (j = 1; j <= lp->n; j++) glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j))); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "2N", min_aij, max_aij, ratio); } done: return; }
static void gm_scaling(glp_prob *lp, int flag) { int i, j, pass; double temp; xassert(flag == 0 || flag == 1); for (pass = 0; pass <= 1; pass++) { if (pass == flag) { /* scale rows */ for (i = 1; i <= lp->m; i++) { temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1); glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp)); } } else { /* scale columns */ for (j = 1; j <= lp->n; j++) { temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1); glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp)); } } } return; }