inline bool operator() (const double f1, const double f2) const { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; if (f1 == f2) return true ; if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; return (fabs(f1-f2) <= epsilon_*(1+tol)) ; }
inline bool operator() (const double f1, const double f2) const { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; if (f1 == f2) return true ; return (fabs(f1-f2) < epsilon_) ; }
/* CoinPostsolveMatrix check_sol overload for CoinPostsolveMatrix. Parameters and functionality identical to check_sol immediately above, but we have to remember we're working with a threaded column-major representation. */ void presolve_check_sol (const CoinPostsolveMatrix *postObj, int chkColSol, int chkRowAct, int chkStatus) { double *colels = postObj->colels_ ; int *hrow = postObj->hrow_ ; int *mcstrt = postObj->mcstrt_ ; int *hincol = postObj->hincol_ ; int *link = postObj->link_ ; int n = postObj->ncols_ ; int m = postObj->nrows_ ; double *csol = postObj->sol_ ; double *acts = postObj->acts_ ; double *clo = postObj->clo_ ; double *cup = postObj->cup_ ; double *rlo = postObj->rlo_ ; double *rup = postObj->rup_ ; double tol = postObj->ztolzb_ ; double *rsol = 0 ; if (chkRowAct) { rsol = new double[m] ; memset(rsol,0,m*sizeof(double)) ; } /* Open a loop to scan each column. For each column, do the following: * Update the row solution (lhs value) by adding the contribution from this column. * Check for bogus values (NaN, infinity) * check that the status of the variable agrees with the value and with the lower and upper bounds. Free should have no bounds, superbasic should have at least one. */ for (int j = 0 ; j < n ; ++j) { CoinBigIndex v = mcstrt[j] ; int colLen = hincol[j] ; double xj = csol[j] ; double lj = clo[j] ; double uj = cup[j] ; if (chkRowAct) { for (int u = 0 ; u < colLen ; ++u) { int i = hrow[v] ; double aij = colels[v] ; v = link[v] ; rsol[i] += aij*xj ; } } if (chkColSol) { if (CoinIsnan(xj)) { printf("NaN CSOL: %d : lb = %g x = %g ub = %g\n",j,lj,xj,uj) ; } if (xj <= -PRESOLVE_INF || xj >= PRESOLVE_INF) { printf("Inf CSOL: %d : lb = %g x = %g ub = %g\n",j,lj,xj,uj) ; } if (chkColSol > 1) { if (xj < lj-tol) { printf("low CSOL: %d : lb = %g x = %g ub = %g\n",j,lj,xj,uj) ; } else if (xj > uj+tol) { printf("high CSOL: %d : lb = %g x = %g ub = %g\n", j,lj,xj,uj) ; } } } if (chkStatus && postObj->colstat_) { CoinPrePostsolveMatrix::Status statj = postObj->getColumnStatus(j) ; switch (statj) { case CoinPrePostsolveMatrix::atUpperBound: { if (uj >= PRESOLVE_INF || fabs(xj-uj) > tol) { printf("Bad status CSOL: %d : status atUpperBound : ",j) ; printf("lb = %g x = %g ub = %g\n",lj,xj,uj) ; } break ; } case CoinPrePostsolveMatrix::atLowerBound: { if (lj <= -PRESOLVE_INF || fabs(xj-lj) > tol) { printf("Bad status CSOL: %d : status atLowerBound : ",j) ; printf("lb = %g x = %g ub = %g\n",lj,xj,uj) ; } break ; } case CoinPrePostsolveMatrix::isFree: { if (lj > -PRESOLVE_INF || uj < PRESOLVE_INF) { printf("Bad status CSOL: %d : status isFree : ",j) ; printf("lb = %g x = %g ub = %g\n",lj,xj,uj) ; } break ; } case CoinPrePostsolveMatrix::superBasic: { if (!(lj > -PRESOLVE_INF || uj < PRESOLVE_INF)) { printf("Bad status CSOL: %d : status superBasic : ",j) ; printf("lb = %g x = %g ub = %g\n",lj,xj,uj) ; } break ; } case CoinPrePostsolveMatrix::basic: { /* Nothing to do here. */ break ; } default: { printf("Bad status CSOL: %d : status unrecognized : ",j) ; break ; } } } } /* Now check the row solution. acts[i] is what presolve thinks we have, rsol[i] is what we've just calculated while scanning the columns. CoinPostsolveMatrix does not contain hinrow_, so we can't check for trivial rows (cf. check_sol for CoinPresolveMatrix). For each row, * Check for bogus values (NaN, infinity) */ tol *= 1.0e4; if (chkRowAct) { for (int i = 0 ; i < m ; ++i) { double lhsi = acts[i] ; double evali = rsol[i] ; double li = rlo[i] ; double ui = rup[i] ; if (CoinIsnan(evali) || CoinIsnan(lhsi)) { printf("NaN RSOL: %d : lb = %g eval = %g (expected %g) ub = %g\n", i,li,evali,lhsi,ui) ; } if (evali <= -PRESOLVE_INF || evali >= PRESOLVE_INF || lhsi <= -PRESOLVE_INF || lhsi >= PRESOLVE_INF) { printf("Inf RSOL: %d : lb = %g eval = %g (expected %g) ub = %g\n", i,li,evali,lhsi,ui) ; } if (chkRowAct > 1) { if (fabs(evali-lhsi) > tol) { printf("Inacc RSOL: %d : lb = %g eval = %g (expected %g) ub = %g\n", i,li,evali,lhsi,ui) ; } if (evali < li-tol || lhsi < li-tol) { printf("low RSOL: %d : lb = %g eval = %g (expected %g) ub = %g\n", i,li,evali,lhsi,ui) ; } else if (evali > ui+tol || lhsi > ui+tol) { printf("high RSOL: %d : lb = %g eval = %g (expected %g) ub = %g\n", i,li,evali,lhsi,ui) ; } } } delete [] rsol ; } return ; }