void undoscale(lprec *lp) { int i, j, nz; MATrec *mat = lp->matA; REAL *value; int *rownr, *colnr; if(lp->scaling_used) { /* Unscale the OF */ for(j = 1; j <= lp->columns; j++) { lp->orig_obj[j] = unscaled_mat(lp, lp->orig_obj[j], 0, j); } /* Unscale the matrix */ mat_validate(mat); nz = get_nonzeros(lp); value = &(COL_MAT_VALUE(0)); rownr = &(COL_MAT_ROWNR(0)); colnr = &(COL_MAT_COLNR(0)); for(j = 0; j < nz; j++, value += matValueStep, rownr += matRowColStep, colnr += matRowColStep) { *value = unscaled_mat(lp, *value, *rownr, *colnr); } /* Unscale variable bounds */ for(i = lp->rows + 1, j = 1; i <= lp->sum; i++, j++) { lp->orig_lowbo[i] = unscaled_value(lp, lp->orig_lowbo[i], i); lp->orig_upbo[i] = unscaled_value(lp, lp->orig_upbo[i], i); lp->sc_lobound[j] = unscaled_value(lp, lp->sc_lobound[j], i); } /* Unscale the rhs, upper and lower bounds... */ for(i = 0; i <= lp->rows; i++) { lp->orig_rhs[i] = unscaled_value(lp, lp->orig_rhs[i], i); j = lp->presolve_undo->var_to_orig[i]; if(j != 0) lp->presolve_undo->fixed_rhs[j] = unscaled_value(lp, lp->presolve_undo->fixed_rhs[j], i); lp->orig_lowbo[i] = unscaled_value(lp, lp->orig_lowbo[i], i); lp->orig_upbo[i] = unscaled_value(lp, lp->orig_upbo[i], i); } FREE(lp->scalars); lp->scaling_used = FALSE; lp->columns_scaled = FALSE; set_action(&lp->spx_action, ACTION_REBASE | ACTION_REINVERT | ACTION_RECOMPUTE); } }
STATIC int write_lprow(lprec *lp, int rowno, void *userhandle, write_modeldata_func write_modeldata, int maxlen) { int i, ie, j, nchars; REAL a; MATrec *mat = lp->matA; MYBOOL first = TRUE, elements; if(rowno == 0) { i = 1; ie = lp->columns+1; } else { i = mat->row_end[rowno-1]; ie = mat->row_end[rowno]; } elements = ie - i; if(write_modeldata != NULL) { nchars = 0; for(; i < ie; i++) { if(rowno == 0) { j = i; a = get_mat(lp, 0, i); if(a == 0) continue; } else { j = ROW_MAT_COLNR(i); a = ROW_MAT_VALUE(i); a = my_chsign(is_chsign(lp, rowno), a); a = unscaled_mat(lp, a, rowno, j); } if(is_splitvar(lp, j)) continue; if(!first) nchars += write_data(userhandle, write_modeldata, " "); else first = FALSE; if(a == -1) nchars += write_data(userhandle, write_modeldata, "-"); else if(a == 1) nchars += write_data(userhandle, write_modeldata, "+"); else nchars += write_data(userhandle, write_modeldata, "%+.12g ", (double)a); nchars += write_data(userhandle, write_modeldata, "%s", get_col_name(lp, j)); /* Check if we should add a linefeed */ if((maxlen > 0) && (nchars >= maxlen) && (i < ie-1)) { write_data(userhandle, write_modeldata, "%s", "\n"); nchars = 0; } } } return(elements); }
STATIC void unscale_columns(lprec *lp) { int i, j, nz; MATrec *mat = lp->matA; REAL *value; int *rownr, *colnr; if(!lp->columns_scaled) return; /* Unscale OF */ for(j = 1; j <= lp->columns; j++) { lp->orig_obj[j] = unscaled_mat(lp, lp->orig_obj[j], 0, j); } /* Unscale mat */ mat_validate(mat); nz = get_nonzeros(lp); value = &(COL_MAT_VALUE(0)); rownr = &(COL_MAT_ROWNR(0)); colnr = &(COL_MAT_COLNR(0)); for(j = 0; j < nz; j++, value += matValueStep, rownr += matRowColStep, colnr += matRowColStep) { *value = unscaled_mat(lp, *value, *rownr, *colnr); } /* Unscale bounds as well */ for(i = lp->rows + 1, j = 1; i <= lp->sum; i++, j++) { lp->orig_lowbo[i] = unscaled_value(lp, lp->orig_lowbo[i], i); lp->orig_upbo[i] = unscaled_value(lp, lp->orig_upbo[i], i); lp->sc_lobound[j] = unscaled_value(lp, lp->sc_lobound[j], i); } for(i = lp->rows + 1; i<= lp->sum; i++) lp->scalars[i] = 1; lp->columns_scaled = FALSE; set_action(&lp->spx_action, ACTION_REBASE | ACTION_REINVERT | ACTION_RECOMPUTE); }
/* List the current basis matrix columns over the selected row range */ void blockWriteBMAT(FILE *output, const char *label, lprec* lp, int first, int last) { int i, j, jb, k = 0; double hold; if(first < 0) first = 0; if(last < 0) last = lp->rows; fprintf(output, "%s", label); fprintf(output, "\n"); for(i = first; i <= last; i++) { for(j = 1; j <= lp->rows; j++) { jb = lp->var_basic[j]; if(jb <= lp->rows) { if(jb == i) hold = 1; else hold = 0; } else hold = get_mat(lp, i, j); if(i == 0) modifyOF1(lp, jb, &hold, 1); hold = unscaled_mat(lp, hold, i, jb); fprintf(output, " %18g", hold); k++; if(my_mod(k, 4) == 0) { fprintf(output, "\n"); k = 0; } } if(my_mod(k, 4) != 0) { fprintf(output, "\n"); k = 0; } } if(my_mod(k, 4) != 0) fprintf(output, "\n"); }
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector) { MYBOOL *isnz = NULL, status = FALSE; REAL *values = NULL, *violation = NULL, eps = lp->epsprimal, *value, error, upB, loB, sortorder = -1.0; int i, j, jj, n, *rownr, *colnr, *slkpos = NULL, nrows = lp->rows, ncols = lp->columns, nsum = lp->sum; int *basisnr; MATrec *mat = lp->matA; if(!mat_validate(mat)) return( status ); /* Create helper arrays, providing for multiple use of the violation array */ if(!allocREAL(lp, &values, nsum+1, TRUE) || !allocREAL(lp, &violation, nsum+1, TRUE)) goto Finish; /* Compute the values of the constraints for the given guess vector */ i = 0; n = get_nonzeros(lp); rownr = &COL_MAT_ROWNR(i); colnr = &COL_MAT_COLNR(i); value = &COL_MAT_VALUE(i); for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) * guessvector[*colnr]; MEMMOVE(values+nrows+1, guessvector+1, ncols); /* Initialize bound "violation" or primal non-degeneracy measures, expressed as the absolute value of the differences from the closest bound. */ for(i = 1; i <= nsum; i++) { if(i <= nrows) { loB = get_rh_lower(lp, i); upB = get_rh_upper(lp, i); } else { loB = get_lowbo(lp, i-nrows); upB = get_upbo(lp, i-nrows); } /* Free constraints/variables */ if(my_infinite(lp, loB) && my_infinite(lp, upB)) error = 0; /* Violated constraints/variable bounds */ else if(values[i]+eps < loB) error = loB-values[i]; else if(values[i]-eps > upB) error = values[i]-upB; /* Non-violated constraints/variables bounds */ else if(my_infinite(lp, upB)) error = MAX(0, values[i]-loB); else if(my_infinite(lp, loB)) error = MAX(0, upB-values[i]); else error = MIN(upB-values[i], values[i]-loB); /* MAX(upB-values[i], values[i]-loB); */ if(error != 0) violation[i] = sortorder*error; basisvector[i] = i; } /* Sort decending , meaning that variables with the largest "violations" will be designated basic. Effectively, we are performing a greedy type algorithm, but start at the "least interesting" end. */ sortByREAL(basisvector, violation, nsum, 1, FALSE); error = violation[1]; /* Used for setting the return value */ /* Let us check for obvious row singularities and try to fix these. Note that we reuse the memory allocated to the violation array. First assemble necessary basis statistics... */ slkpos = (int *) violation; n = nrows+1; MEMCLEAR(slkpos, n); isnz = (MYBOOL *) (slkpos+n+1); MEMCLEAR(isnz, n); for(i = 1; i <= nrows; i++) { j = abs(basisvector[i]); if(j <= nrows) { isnz[j] = TRUE; slkpos[j] = i; } else { j-= nrows; jj = mat->col_end[j-1]; jj = COL_MAT_ROWNR(jj); isnz[jj] = TRUE; } } for(; i <= nsum; i++) { j = abs(basisvector[i]); if(j <= nrows) slkpos[j] = i; } /* ...then set the corresponding slacks basic for row rank deficient positions */ for(j = 1; j <= nrows; j++) { if(slkpos[j] == 0) report(lp, SEVERE, "guess_basis: Internal error"); if(!isnz[j]) { isnz[j] = TRUE; i = slkpos[j]; swapINT(&basisvector[i], &basisvector[j]); basisvector[j] = abs(basisvector[j]); } } /* Adjust the non-basic indeces for the (proximal) bound state */ for(i = nrows+1, basisnr = basisvector+i; i <= nsum; i++, basisnr++) { n = *basisnr; if(n <= nrows) { values[n] -= get_rh_lower(lp, n); if(values[n] <= eps) *basisnr = -(*basisnr); } else if(values[n]-eps <= get_lowbo(lp, n-nrows)) *basisnr = -(*basisnr); } /* Lastly normalize all basic variables to be coded as lower-bounded, or effectively zero-based in the case of free variables. */ for(i = 1; i <= nrows; i++) basisvector[i] = -abs(basisvector[i]); /* Clean up and return status */ status = (MYBOOL) (error <= eps); Finish: FREE(values); FREE(violation); return( status ); }
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector) { MYBOOL *isnz, status = FALSE; REAL *values = NULL, *violation = NULL, eps = lp->epsprimal, *value, error, upB, loB, sortorder = 1.0; int i, j, jj, n, *rownr, *colnr, *slkpos, nrows = lp->rows, ncols = lp->columns; MATrec *mat = lp->matA; if(!mat_validate(mat)) return( status ); /* Create helper arrays */ if(!allocREAL(lp, &values, lp->sum+1, TRUE) || !allocREAL(lp, &violation, lp->sum+1, TRUE)) goto Finish; /* Compute values of slack variables for given guess vector */ i = 0; n = get_nonzeros(lp); rownr = &COL_MAT_ROWNR(i); colnr = &COL_MAT_COLNR(i); value = &COL_MAT_VALUE(i); for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) * guessvector[*colnr]; MEMMOVE(values+nrows+1, guessvector+1, ncols); /* Initialize constraint bound violation measures (expressed as positive values) */ for(i = 1; i <= nrows; i++) { upB = get_rh_upper(lp, i); loB = get_rh_lower(lp, i); error = values[i] - upB; if(error > -eps) violation[i] = sortorder*MAX(0,error); else { error = loB - values[i]; if(error > -eps) violation[i] = sortorder*MAX(0,error); else if(my_infinite(lp, loB) && my_infinite(lp, upB)) ; else if(my_infinite(lp, upB)) violation[i] = sortorder*(loB - values[i]); else if(my_infinite(lp, loB)) violation[i] = sortorder*(values[i] - upB); else violation[i] = -sortorder*MAX(upB - values[i], values[i] - loB); } basisvector[i] = i; } /* Initialize user variable bound violation measures (expressed as positive values) */ for(i = 1; i <= ncols; i++) { n = nrows+i; upB = get_upbo(lp, i); loB = get_lowbo(lp, i); error = guessvector[i] - upB; if(error > -eps) violation[n] = sortorder*MAX(0,error); else { error = loB - values[n]; if(error > -eps) violation[n] = sortorder*MAX(0,error); else if(my_infinite(lp, loB) && my_infinite(lp, upB)) ; else if(my_infinite(lp, upB)) violation[n] = sortorder*(loB - values[n]); else if(my_infinite(lp, loB)) violation[n] = sortorder*(values[n] - upB); else violation[n] = -sortorder*MAX(upB - values[n], values[n] - loB); } basisvector[n] = n; } /* Sort decending by violation; this means that variables with the largest violations will be designated as basic */ sortByREAL(basisvector, violation, lp->sum, 1, FALSE); error = violation[1]; /* Adjust the non-basic indeces for the (proximal) bound state */ for(i = nrows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) { if(*rownr <= nrows) { values[*rownr] -= lp->orig_rhs[*rownr]; if(values[*rownr] <= eps) *rownr = -(*rownr); } else if(values[i] <= get_lowbo(lp, (*rownr)-nrows)+eps) *rownr = -(*rownr); } /* Let us check for obvious row singularities and try to fix these; First assemble necessary basis statistics... */ isnz = (MYBOOL *) values; MEMCLEAR(isnz, nrows+1); slkpos = (int *) violation; MEMCLEAR(slkpos, nrows+1); for(i = 1; i <= nrows; i++) { j = abs(basisvector[i]); if(j <= nrows) { isnz[j] = TRUE; slkpos[j] = i; } else { j-= nrows; jj = mat->col_end[j-1]; isnz[COL_MAT_ROWNR(jj)] = TRUE; /* if(++jj < mat->col_end[j]) isnz[COL_MAT_ROWNR(jj)] = TRUE; */ } } for(; i <= lp->sum; i++) { j = abs(basisvector[i]); if(j <= nrows) slkpos[j] = i; } /* ...then set the corresponding slacks basic for row rank deficient positions */ for(j = 1; j <= nrows; j++) { #ifdef Paranoia if(slkpos[j] == 0) report(lp, SEVERE, "guess_basis: Internal error"); #endif if(!isnz[j]) { isnz[j] = TRUE; i = slkpos[j]; swapINT(&basisvector[i], &basisvector[j]); basisvector[j] = abs(basisvector[j]); } } /* Lastly normalize all basic variables to be coded as lower-bounded */ for(i = 1; i <= nrows; i++) basisvector[i] = -abs(basisvector[i]); /* Clean up and return status */ status = (MYBOOL) (error <= eps); Finish: FREE(values); FREE(violation); return( status ); }
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector) { MYBOOL status = FALSE; REAL *values = NULL, *violation = NULL, *value, error, upB, loB, sortorder = 1.0; int i, n, *rownr, *colnr; MATrec *mat = lp->matA; if(!mat_validate(lp->matA)) return( status ); /* Create helper arrays */ if(!allocREAL(lp, &values, lp->sum+1, TRUE) || !allocREAL(lp, &violation, lp->sum+1, TRUE)) goto Finish; /* Compute values of slack variables for given guess vector */ i = 0; n = get_nonzeros(lp); rownr = &COL_MAT_ROWNR(i); colnr = &COL_MAT_COLNR(i); value = &COL_MAT_VALUE(i); for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) * guessvector[*colnr]; MEMMOVE(values+lp->rows+1, guessvector+1, lp->columns); /* Initialize constraint bound violation measures */ for(i = 1; i <= lp->rows; i++) { upB = get_rh_upper(lp, i); loB = get_rh_lower(lp, i); error = values[i] - upB; if(error > lp->epsprimal) violation[i] = sortorder*error; else { error = loB - values[i]; if(error > lp->epsprimal) violation[i] = sortorder*error; else if(is_infinite(lp, loB) && is_infinite(lp, upB)) ; else if(is_infinite(lp, upB)) violation[i] = sortorder*(loB - values[i]); else if(is_infinite(lp, loB)) violation[i] = sortorder*(values[i] - upB); else violation[i] = - sortorder*MAX(upB - values[i], values[i] - loB); } basisvector[i] = i; } /* Initialize user variable bound violation measures */ for(i = 1; i <= lp->columns; i++) { n = lp->rows+i; upB = get_upbo(lp, i); loB = get_lowbo(lp, i); error = guessvector[i] - upB; if(error > lp->epsprimal) violation[n] = sortorder*error; else { error = loB - values[n]; if(error > lp->epsprimal) violation[n] = sortorder*error; else if(is_infinite(lp, loB) && is_infinite(lp, upB)) ; else if(is_infinite(lp, upB)) violation[n] = sortorder*(loB - values[n]); else if(is_infinite(lp, loB)) violation[n] = sortorder*(values[n] - upB); else violation[n] = - sortorder*MAX(upB - values[n], values[n] - loB); } basisvector[n] = n; } /* Sort decending by violation; this means that variables with the largest violations will be designated as basic */ sortByREAL(basisvector, violation, lp->sum, 1, FALSE); /* Adjust the non-basic indeces for the (proximal) bound state */ error = lp->epsprimal; for(i = lp->rows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) { if(*rownr <= lp->rows) { if(values[*rownr] <= get_rh_lower(lp, *rownr)+error) *rownr = -(*rownr); } else if(values[i] <= get_lowbo(lp, (*rownr)-lp->rows)+error) *rownr = -(*rownr); } /* Clean up and return status */ status = (MYBOOL) (violation[1] == 0); Finish: FREE(values); FREE(violation); return( status ); }