void RestorationProblem::evaluate( const Matrix &xi, const Matrix &lambda, double *objval, Matrix &constr, Matrix &gradObj, double *&jacNz, int *&jacIndRow, int *&jacIndCol, SymMatrix *&hess, int dmode, int *info ) { int iCon, i; double diff, regTerm; Matrix xiOrig, slack; // The first nVar elements of the variable vector correspond to the variables of the original problem xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 ); slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 ); // Evaluate constraints of the original problem parent->evaluate( xiOrig, lambda, objval, constr, gradObj, jacNz, jacIndRow, jacIndCol, hess, dmode, info ); // Subtract slacks for( iCon=0; iCon<nCon; iCon++ ) constr( iCon ) -= slack( iCon ); /* Evaluate objective: minimize slacks plus deviation from reference point */ if( dmode < 0 ) return; *objval = 0.0; // First part: sum of slack variables for( i=0; i<nCon; i++ ) *objval += slack( i ) * slack( i ); *objval = 0.5 * rho * (*objval); // Second part: regularization term regTerm = 0.0; for( i=0; i<parent->nVar; i++ ) { diff = xiOrig( i ) - xiRef( i ); regTerm += diagScale( i ) * diff * diff; } regTerm = 0.5 * zeta * regTerm; *objval += regTerm; if( dmode > 0 ) {// compute objective gradient // gradient w.r.t. xi (regularization term) for( i=0; i<parent->nVar; i++ ) gradObj( i ) = zeta * diagScale( i ) * diagScale( i ) * (xiOrig( i ) - xiRef( i )); // gradient w.r.t. slack variables for( i=parent->nVar; i<nVar; i++ ) gradObj( i ) = rho * xi( i ); } *info = 0; }
void RestorationProblem::initialize( Matrix &xi, Matrix &lambda, Matrix &constrJac ) { int i, info; double objval; Matrix xiOrig, slack, constrJacOrig, constrRef; xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 ); slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 ); constrJacOrig.Submatrix( constrJac, parent->nCon, parent->nVar, 0, 0 ); // Call initialize of the parent problem to set up linear constraint matrix correctly parent->initialize( xiOrig, lambda, constrJacOrig ); // Jacobian entries for slacks for( i=0; i<parent->nCon; i++ ) constrJac( i, parent->nVar+i ) = -1.0; // The reference point is the starting value for the restoration phase for( i=0; i<parent->nVar; i++ ) xiOrig( i ) = xiRef( i ); // Initialize slack variables such that the constraints are feasible constrRef.Dimension( nCon ); parent->evaluate( xiOrig, &objval, constrRef, &info ); for( i=0; i<nCon; i++ ) { if( constrRef( i ) <= parent->bl( parent->nVar + i ) )// if lower bound is violated slack( i ) = constrRef( i ) - parent->bl( parent->nVar + i ); else if( constrRef( i ) > parent->bu( parent->nVar + i ) )// if upper bound is violated slack( i ) = constrRef( i ) - parent->bu( parent->nVar + i ); } // Set diagonal scaling matrix diagScale.Dimension( parent->nVar ).Initialize( 1.0 ); for( i=0; i<parent->nVar; i++ ) if( fabs( xiRef( i ) ) > 1.0 ) diagScale( i ) = 1.0 / fabs( xiRef( i ) ); // Regularization factor zeta and rho \todo wie setzen? zeta = 1.0e-3; rho = 1.0e3; lambda.Initialize( 0.0 ); }
bool Constraint::violated(Active<Variable, Constraint> *variables, double *x, double *sl) const { double s = slack(variables, x); if (sl) *sl = s; return violated(s); }
bool ACPI::append(const char *sig, const char *extra, const uint32_t extra_len) { // check if enough space to append acpi_sdt *table = find_child(sig, rsdt, 4); if (!table || slack(table) < extra_len) return 0; memcpy((char *)table + table->len, extra, extra_len); table->len += extra_len; table->checksum += checksum((const char *)table, table->len); if (options->debug.acpi) dump(table, 0); return 1; }
void ACPI::add_child(const acpi_sdt *replacement, acpi_sdt *const parent, const unsigned ptrsize) { // if insufficient space, replace unimportant tables if (slack(parent) < ptrsize) { const char *expendable[] = {"FPDT", "EINJ", "TCPA", "BERT", "ERST", "HEST"}; for (unsigned i = 0; i < (sizeof expendable / sizeof expendable[0]); i++) { if (replace_child(expendable[i], replacement, parent, ptrsize)) { printf("Replaced %s table\n", expendable[i]); return; } } fatal("Out of space when adding entry for ACPI table %s to %s", replacement->sig.s, parent->sig.s); } assert_checksum(replacement, replacement->len); uint64_t newp = 0; memcpy(&newp, &replacement, sizeof replacement); unsigned i = parent->len - sizeof(*parent); memcpy(&parent->data[i], &newp, ptrsize); if (memcmp(&parent->data[i], &newp, ptrsize)) goto again; parent->len += ptrsize; xassert(parent->len < RSDT_MAX); parent->checksum += checksum((const char *)parent, parent->len); return; again: if (!bios_shadowed) { shadow_bios(); add_child(replacement, parent, ptrsize); return; } fatal("ACPI tables immutable when adding child at 0x%p", &parent->data[i]); }
// Test KKT conditions on the solution. // The function returns true if the tested KKT conditions are satisfied // and false otherwise. // The function assumes that the model currently extracted to CPLEX is fully // described by obj, vars and rngs. static bool checkkkt (IloCplex& cplex, IloObjective const& obj, IloNumVarArray const& vars, IloRangeArray const& rngs, IloIntArray const& cone, double tol) { IloEnv env = cplex.getEnv(); IloModel model = cplex.getModel(); IloNumArray x(env), dslack(env); IloNumArray pi(env, rngs.getSize()), slack(env); // Read primal and dual solution information. cplex.getValues(x, vars); cplex.getSlacks(slack, rngs); // pi for second order cone constraints. getsocpconstrmultipliers(cplex, vars, rngs, pi, dslack); // pi for linear constraints. for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( !r.getQuadIterator().ok() ) pi[idx(r)] = cplex.getDual(r); } // Print out the data we just fetched. streamsize oprec = env.out().precision(3); ios_base::fmtflags oflags = env.out().setf(ios::fixed | ios::showpos); env.out() << "x = ["; for (IloInt i = 0; i < x.getSize(); ++i) env.out() << " " << x[i]; env.out() << " ]" << endl; env.out() << "dslack = ["; for (IloInt i = 0; i < dslack.getSize(); ++i) env.out() << " " << dslack[i]; env.out() << " ]" << endl; env.out() << "pi = ["; for (IloInt i = 0; i < rngs.getSize(); ++i) env.out() << " " << pi[i]; env.out() << " ]" << endl; env.out() << "slack = ["; for (IloInt i = 0; i < rngs.getSize(); ++i) env.out() << " " << slack[i]; env.out() << " ]" << endl; env.out().precision(oprec); env.out().flags(oflags); // Test primal feasibility. // This example illustrates the use of dual vectors returned by CPLEX // to verify dual feasibility, so we do not test primal feasibility // here. // Test dual feasibility. // We must have // - for all <= constraints the respective pi value is non-negative, // - for all >= constraints the respective pi value is non-positive, // - the dslack value for all non-cone variables must be non-negative. // Note that we do not support ranged constraints here. for (IloInt i = 0; i < vars.getSize(); ++i) { IloNumVar v = vars[i]; if ( cone[i] == NOT_IN_CONE && dslack[i] < -tol ) { env.error() << "Dual multiplier for " << v << " is not feasible: " << dslack[i] << endl; return false; } } for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( fabs (r.getLB() - r.getUB()) <= tol ) { // Nothing to check for equality constraints. } else if ( r.getLB() > -IloInfinity && pi[i] > tol ) { env.error() << "Dual multiplier " << pi[i] << " for >= constraint" << endl << r << endl << "not feasible" << endl; return false; } else if ( r.getUB() < IloInfinity && pi[i] < -tol ) { env.error() << "Dual multiplier " << pi[i] << " for <= constraint" << endl << r << endl << "not feasible" << endl; return false; } } // Test complementary slackness. // For each constraint either the constraint must have zero slack or // the dual multiplier for the constraint must be 0. We must also // consider the special case in which a variable is not explicitly // contained in a second order cone constraint. for (IloInt i = 0; i < vars.getSize(); ++i) { if ( cone[i] == NOT_IN_CONE ) { if ( fabs(x[i]) > tol && dslack[i] > tol ) { env.error() << "Invalid complementary slackness for " << vars[i] << ":" << endl << " " << x[i] << " and " << dslack[i] << endl; return false; } } } for (IloInt i = 0; i < rngs.getSize(); ++i) { if ( fabs(slack[i]) > tol && fabs(pi[i]) > tol ) { env.error() << "Invalid complementary slackness for " << endl << rngs[i] << ":" << endl << " " << slack[i] << " and " << pi[i] << endl; return false; } } // Test stationarity. // We must have // c - g[i]'(X)*pi[i] = 0 // where c is the objective function, g[i] is the i-th constraint of the // problem, g[i]'(x) is the derivate of g[i] with respect to x and X is the // optimal solution. // We need to distinguish the following cases: // - linear constraints g(x) = ax - b. The derivative of such a // constraint is g'(x) = a. // - second order constraints g(x[1],...,x[n]) = -x[1] + |(x[2],...,x[n])| // the derivative of such a constraint is // g'(x) = (-1, x[2]/|(x[2],...,x[n])|, ..., x[n]/|(x[2],...,x[n])| // (here |.| denotes the Euclidean norm). // - bound constraints g(x) = -x for variables that are not explicitly // contained in any second order cone constraint. The derivative for // such a constraint is g'(x) = -1. // Note that it may happen that the derivative of a second order cone // constraint is not defined at the optimal solution X (this happens if // X=0). In this case we just skip the stationarity test. IloNumArray sum(env, vars.getSize()); for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it) sum[idx(it.getVar())] = it.getCoef(); for (IloInt i = 0; i < vars.getSize(); ++i) { IloNumVar v = vars[i]; if ( cone[i] == NOT_IN_CONE ) sum[i] -= dslack[i]; } for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( r.getQuadIterator().ok() ) { // Quadratic (second order cone) constraint. IloNum norm = 0.0; for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) { if ( q.getCoef() > 0 ) norm += x[idx(q.getVar1())] * x[idx(q.getVar1())]; } norm = sqrt(norm); if ( fabs(norm) <= tol ) { // Derivative is not defined. Skip test. env.warning() << "Cannot test stationarity at non-differentiable point." << endl; return true; } else { for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) { if ( q.getCoef() < 0 ) sum[idx(q.getVar1())] -= pi[i]; else sum[idx(q.getVar1())] += pi[i] * x[idx(q.getVar1())] / norm; } } } else { // Linear constraint. for (IloExpr::LinearIterator l = r.getLinearIterator(); l.ok(); ++l) sum[idx(l.getVar())] -= pi[i] * l.getCoef(); } } // Now test that all elements in sum[] are 0. for (IloInt i = 0; i < vars.getSize(); ++i) { if ( fabs(sum[i]) > tol ) { env.error() << "Invalid stationarity " << sum[i] << " for " << vars[i] << endl; return false; } } return true; }
double TriConstraint::slackAtInitial () const { return slack(u->initialPos(scanDim), v->initialPos(scanDim), w->initialPos(scanDim)); }
double TriConstraint::slackAtFinal() const { return slack(u->finalPos(), v->finalPos(), w->finalPos()); }
bool Hungarian::solve() { int i, j, m, n, k, l, s, t, q, unmatched, cost; m = m_rows; n = m_cols; int INF = std::numeric_limits<int>::max(); //vertex alternating paths, vector<int> col_vertex(m), row_vertex(n), unchosen_row(m), parent_row(n), row_dec(m), col_inc(n), slack_row(m), slack(n); cost=0; for (i=0;i<m_rows;i++) { col_vertex[i]=0; unchosen_row[i]=0; row_dec[i]=0; slack_row[i]=0; } for (j=0;j<m_cols;j++) { row_vertex[j]=0; parent_row[j] = 0; col_inc[j]=0; slack[j]=0; } //Double check assignment matrix is 0 m_assignment.assign(m, vector<int>(n, HUNGARIAN_NOT_ASSIGNED)); // Begin subtract column minima in order to start with lots of zeroes 12 if (verbose) { fprintf(stderr, "Using heuristic\n"); } for (l=0;l<n;l++) { s = m_costmatrix[0][l]; for (k=1;k<m;k++) { if (m_costmatrix[k][l] < s) { s=m_costmatrix[k][l]; } cost += s; } if (s!=0) { for (k=0;k<m;k++) { m_costmatrix[k][l]-=s; } } //pre-initialize state 16 row_vertex[l]= -1; parent_row[l]= -1; col_inc[l]=0; slack[l]=INF; } // End subtract column minima in order to start with lots of zeroes 12 // Begin initial state 16 t=0; for (k=0;k<m;k++) { bool row_done = false; s=m_costmatrix[k][0]; for (l=0;l<n;l++) { if(l > 0) { if (m_costmatrix[k][l] < s) { s = m_costmatrix[k][l]; } row_dec[k]=s; } if (s == m_costmatrix[k][l] && row_vertex[l]<0) { col_vertex[k]=l; row_vertex[l]=k; if (verbose) { fprintf(stderr, "matching col %d==row %d\n",l,k); } row_done = true; break; } } if(!row_done) { col_vertex[k]= -1; if (verbose) { fprintf(stderr, "node %d: unmatched row %d\n",t,k); } unchosen_row[t++]=k; } } // End initial state 16 bool checked = false; // Begin Hungarian algorithm 18 //is matching already complete? if (t == 0) { checked = check_solution(row_dec, col_inc, col_vertex); if (checked) { //finish assignment, wrap up and done. bool assign = assign_solution(row_dec, col_inc, col_vertex); return true; } else { if(verbose) { fprintf(stderr, "Could not solve. Error.\n"); } return false; } } unmatched=t; while (1) { if (verbose) { fprintf(stderr, "Matched %d rows.\n",m-t); } q=0; bool try_matching; while (1) { while (q<t) { // Begin explore node q of the forest 19 k=unchosen_row[q]; s=row_dec[k]; for (l=0;l<n;l++) { if (slack[l]) { int del; del=m_costmatrix[k][l]-s+col_inc[l]; if (del<slack[l]) { if (del==0) { if (row_vertex[l]<0) { goto breakthru; } slack[l]=0; parent_row[l]=k; if (verbose){ fprintf(stderr, "node %d: row %d==col %d--row %d\n", t,row_vertex[l],l,k);} unchosen_row[t++]=row_vertex[l]; } else { slack[l]=del; slack_row[l]=k; } } } } // End explore node q of the forest 19 q++; } // Begin introduce a new zero into the matrix 21 s=INF; for (l=0;l<n;l++) { if (slack[l] && slack[l]<s) { s=slack[l]; } } for (q=0;q<t;q++) { row_dec[unchosen_row[q]]+=s; } for (l=0;l<n;l++) { //check slack if (slack[l]) { slack[l]-=s; if (slack[l]==0) { // Begin look at a new zero 22 k=slack_row[l]; if (verbose) { fprintf(stderr, "Decreasing uncovered elements by %d produces zero at [%d,%d]\n", s,k,l); } if (row_vertex[l]<0) { for (j=l+1;j<n;j++) if (slack[j]==0) { col_inc[j]+=s; } goto breakthru; } else { parent_row[l]=k; if (verbose) { fprintf(stderr, "node %d: row %d==col %d--row %d\n",t,row_vertex[l],l,k);} unchosen_row[t++]=row_vertex[l]; } // End look at a new zero 22 } } else { col_inc[l]+=s; } } // End introduce a new zero into the matrix 21 } breakthru: // Begin update the matching 20 if (verbose) { fprintf(stderr, "Breakthrough at node %d of %d!\n",q,t); } while (1) { j=col_vertex[k]; col_vertex[k]=l; row_vertex[l]=k; if (verbose) { fprintf(stderr, "rematching col %d==row %d\n",l,k); } if (j<0) { break; } k=parent_row[j]; l=j; } // End update the matching 20 if (--unmatched == 0) { checked = check_solution(row_dec, col_inc, col_vertex); if (checked) { //finish assignment, wrap up and done. bool assign = assign_solution(row_dec, col_inc, col_vertex); return true; } else { if(verbose) { fprintf(stderr, "Could not solve. Error.\n"); } return false; } } // Begin get ready for another stage 17 t=0; for (l=0;l<n;l++) { parent_row[l]= -1; slack[l]=INF; } for (k=0;k<m;k++) { if (col_vertex[k]<0) { if (verbose) { fprintf(stderr, "node %d: unmatched row %d\n",t,k);} unchosen_row[t++]=k; } } // End get ready for another stage 17 }// back to while loop }
void RestorationProblem::initialize( Matrix &xi, Matrix &lambda, double *&jacNz, int *&jacIndRow, int *&jacIndCol ) { int i, info; double objval; Matrix xiOrig, slack, constrRef; xiOrig.Submatrix( xi, parent->nVar, 1, 0, 0 ); slack.Submatrix( xi, parent->nCon, 1, parent->nVar, 0 ); // Call initialize of the parent problem. There, the sparse Jacobian is allocated double *jacNzOrig = NULL; int *jacIndRowOrig = NULL, *jacIndColOrig = NULL, nnz, nnzOrig; parent->initialize( xiOrig, lambda, jacNzOrig, jacIndRowOrig, jacIndColOrig ); nnzOrig = jacIndColOrig[parent->nVar]; // Copy sparse Jacobian from original problem nnz = nnzOrig + nCon; jacNz = new double[nnz]; jacIndRow = new int[nnz + (nVar+1)]; jacIndCol = jacIndRow + nnz; for( i=0; i<nnzOrig; i++ ) { jacNz[i] = jacNzOrig[i]; jacIndRow[i] = jacIndRowOrig[i]; } for( i=0; i<parent->nVar; i++ ) jacIndCol[i] = jacIndColOrig[i]; // Jacobian entries for slacks (one nonzero entry per column) for( i=nnzOrig; i<nnz; i++ ) { jacNz[i] = -1.0; jacIndRow[i] = i-nnzOrig; } for( i=parent->nVar; i<nVar+1; i++ ) jacIndCol[i] = nnzOrig + i - parent->nVar; // The reference point is the starting value for the restoration phase for( i=0; i<parent->nVar; i++ ) xiOrig( i ) = xiRef( i ); // Initialize slack variables such that the constraints are feasible constrRef.Dimension( nCon ); parent->evaluate( xiOrig, &objval, constrRef, &info ); for( i=0; i<nCon; i++ ) { if( constrRef( i ) <= parent->bl( parent->nVar + i ) )// if lower bound is violated slack( i ) = constrRef( i ) - parent->bl( parent->nVar + i ); else if( constrRef( i ) > parent->bu( parent->nVar + i ) )// if upper bound is violated slack( i ) = constrRef( i ) - parent->bu( parent->nVar + i ); } // Set diagonal scaling matrix diagScale.Dimension( parent->nVar ).Initialize( 1.0 ); for( i=0; i<parent->nVar; i++ ) if( fabs( xiRef( i ) ) > 1.0 ) diagScale( i ) = 1.0 / fabs( xiRef( i ) ); // Regularization factor zeta and rho \todo wie setzen? zeta = 1.0e-3; rho = 1.0e3; lambda.Initialize( 0.0 ); }
int main (int argc, char **argv) { int result = 0; IloEnv env; try { static int indices[] = { 0, 1, 2, 3, 4, 5, 6 }; IloModel model(env); /* ***************************************************************** * * * * S E T U P P R O B L E M * * * * The model we setup here is * * Minimize * * obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7 * * Subject To * * c1: x1 + x2 = 4 * * c2: x1 + x3 >= 3 * * c3: x6 + x7 <= 5 * * c4: -x1 + x7 >= -2 * * q1: [ -x1^2 + x2^2 ] <= 0 * * q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2 ] + 2 x1 <= 9.0 * q3: [ x6^2 - x7^2 ] >= 4 * * Bounds * * 0 <= x1 <= 3 * * x2 Free * * 0 <= x3 <= 0.5 * * x4 Free * * x5 Free * * x7 Free * * End * * * * ***************************************************************** */ IloNumVarArray x(env); x.add(IloNumVar(env, 0, 3, "x1")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x2")); x.add(IloNumVar(env, 0, 0.5, "x3")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x4")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x5")); x.add(IloNumVar(env, 0, IloInfinity, "x6")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x7")); for (IloInt i = 0; i < x.getSize(); ++i) x[i].setObject(&indices[i]); IloObjective obj = IloMinimize(env, 3*x[0] - x[1] + 3*x[2] + 2*x[3] + x[4] + 2*x[5] + 4*x[6], "obj"); model.add(obj); IloRangeArray linear(env); linear.add(IloRange(env, 4.0, x[0] + x[1], 4.0, "c1")); linear.add(IloRange(env, 3.0, x[0] + x[2], IloInfinity, "c2")); linear.add(IloRange(env, -IloInfinity, x[5] + x[6], 5.0, "c3")); linear.add(IloRange(env, -2.0, -x[0] + x[6], IloInfinity, "c4")); for (IloInt i = 0; i < linear.getSize(); ++i) linear[i].setObject(&indices[i]); model.add(linear); IloRangeArray quad(env); quad.add(IloRange(env, -IloInfinity, -x[0]*x[0] + x[1] * x[1], 0, "q1")); quad.add(IloRange(env, -IloInfinity, 4.25*x[2]*x[2] - 2*x[2]*x[3] + 4.25*x[3]*x[3] + -2*x[3]*x[4] + 4*x[4]*x[4] + 2*x[0], 9.0, "q2")); quad.add(IloRange(env, 4.0, x[5]*x[5] - x[6]*x[6], IloInfinity, "q3")); for (IloInt i = 0; i < quad.getSize(); ++i) quad[i].setObject(&indices[i]); model.add(quad); /* ***************************************************************** * * * * O P T I M I Z E P R O B L E M * * * * ***************************************************************** */ IloCplex cplex(model); cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, 1e-10); cplex.solve(); /* ***************************************************************** * * * * Q U E R Y S O L U T I O N * * * * ***************************************************************** */ IloNumArray xval(env); IloNumArray slack(env); IloNumArray qslack(env); IloNumArray cpi(env); IloNumArray rpi(env); IloNumArray qpi; cplex.getValues(x, xval); cplex.getSlacks(slack, linear); cplex.getSlacks(qslack, quad); cplex.getReducedCosts(cpi, x); cplex.getDuals(rpi, linear); qpi = getqconstrmultipliers(cplex, xval, quad); /* ***************************************************************** * * * * C H E C K K K T C O N D I T I O N S * * * * Here we verify that the optimal solution computed by CPLEX * * (and the qpi[] values computed above) satisfy the KKT * * conditions. * * * * ***************************************************************** */ // Primal feasibility: This example is about duals so we skip this test. // Dual feasibility: We must verify // - for <= constraints (linear or quadratic) the dual // multiplier is non-positive. // - for >= constraints (linear or quadratic) the dual // multiplier is non-negative. for (IloInt i = 0; i < linear.getSize(); ++i) { if ( linear[i].getLB() <= -IloInfinity ) { // <= constraint if ( rpi[i] > ZEROTOL ) { cerr << "Dual feasibility test failed for <= row " << i << ": " << rpi[i] << endl; result = -1; } } else if ( linear[i].getUB() >= IloInfinity ) { // >= constraint if ( rpi[i] < -ZEROTOL ) { cerr << "Dual feasibility test failed for >= row " << i << ":" << rpi[i] << endl; result = -1; } } else { // nothing to do for equality constraints } } for (IloInt q = 0; q < quad.getSize(); ++q) { if ( quad[q].getLB() <= -IloInfinity ) { // <= constraint if ( qpi[q] > ZEROTOL ) { cerr << "Dual feasibility test failed for <= quad " << q << ": " << qpi[q] << endl; result = -1; } } else if ( quad[q].getUB() >= IloInfinity ) { // >= constraint if ( qpi[q] < -ZEROTOL ) { cerr << "Dual feasibility test failed for >= quad " << q << ":" << qpi[q] << endl; result = -1; } } else { // nothing to do for equality constraints } } // Complementary slackness. // For any constraint the product of primal slack and dual multiplier // must be 0. for (IloInt i = 0; i < linear.getSize(); ++i) { if ( fabs (linear[i].getUB() - linear[i].getLB()) > ZEROTOL && fabs (slack[i] * rpi[i]) > ZEROTOL ) { cerr << "Complementary slackness test failed for row " << i << ": " << fabs (slack[i] * rpi[i]) << endl; result = -1; } } for (IloInt q = 0; q < quad.getSize(); ++q) { if ( fabs (quad[q].getUB() - quad[q].getLB()) > ZEROTOL && fabs (qslack[q] * qpi[q]) > ZEROTOL ) { cerr << "Complementary slackness test failed for quad " << q << ":" << fabs (qslack[q] * qpi[q]) << endl; result = -1; } } for (IloInt j = 0; j < x.getSize(); ++j) { if ( x[j].getUB() < IloInfinity ) { double const slk = x[j].getUB() - xval[j]; double const dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0; if ( fabs (slk * dual) > ZEROTOL ) { cerr << "Complementary slackness test failed for ub " << j << ": " << fabs (slk * dual) << endl; result = -1; } } if ( x[j].getLB() > -IloInfinity ) { double const slk = xval[j] - x[j].getLB(); double const dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0; if ( fabs (slk * dual) > ZEROTOL ) { cerr << "Complementary slackness test failed for lb " << j << ": " << fabs (slk * dual) << endl; result = -1; } } } // Stationarity. // The difference between objective function and gradient at optimal // solution multiplied by dual multipliers must be 0, i.e., for the // optimal solution x // 0 == c // - sum(r in rows) r'(x)*rpi[r] // - sum(q in quads) q'(x)*qpi[q] // - sum(c in cols) b'(x)*cpi[c] // where r' and q' are the derivatives of a row or quadratic constraint, // x is the optimal solution and rpi[r] and qpi[q] are the dual // multipliers for row r and quadratic constraint q. // b' is the derivative of a bound constraint and cpi[c] the dual bound // multiplier for column c. IloNumArray kktsum(env, x.getSize()); // Objective function. for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] = it.getCoef(); // Linear constraints. // The derivative of a linear constraint ax - b (<)= 0 is just a. for (IloInt i = 0; i < linear.getSize(); ++i) { for (IloExpr::LinearIterator it = linear[i].getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] -= rpi[i] * it.getCoef(); } // Quadratic constraints. // The derivative of a constraint xQx + ax - b <= 0 is // Qx + Q'x + a. for (IloInt q = 0; q < quad.getSize(); ++q) { for (IloExpr::LinearIterator it = quad[q].getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] -= qpi[q] * it.getCoef(); for (IloExpr::QuadIterator it = quad[q].getQuadIterator(); it.ok(); ++it) { kktsum[idx(it.getVar1())] -= qpi[q] * xval[idx(it.getVar2())] * it.getCoef(); kktsum[idx(it.getVar2())] -= qpi[q] * xval[idx(it.getVar1())] * it.getCoef(); } } // Bounds. // The derivative for lower bounds is -1 and that for upper bounds // is 1. // CPLEX already returns dj with the appropriate sign so there is // no need to distinguish between different bound types here. for (IloInt j = 0; j < x.getSize(); ++j) kktsum[j] -= cpi[j]; for (IloInt j = 0; j < kktsum.getSize(); ++j) { if ( fabs (kktsum[j]) > ZEROTOL ) { cerr << "Stationarity test failed at index " << j << ": " << kktsum[j] << endl; result = -1; } } if ( result == 0) { // KKT conditions satisfied. Dump out the optimal solutions and // the dual values. streamsize oprec = cout.precision(3); ios_base::fmtflags oflags = cout.setf(ios::fixed | ios::showpos); cout << "Optimal solution satisfies KKT conditions." << endl; cout << " x[] = " << xval << endl; cout << " cpi[] = " << cpi << endl; cout << " rpi[] = " << rpi << endl; cout << " qpi[] = " << qpi << endl; cout.precision(oprec); cout.flags(oflags); } } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; result = -1; } catch (...) { cerr << "Unknown exception caught" << endl; result = -1; } env.end(); return result; } // END main
bool ACPI::replace_child(const char *sig, const acpi_sdt *replacement, acpi_sdt *const parent, const unsigned ptrsize) { uint64_t newp = 0, childp; assert_checksum(replacement, replacement->len); memcpy(&newp, &replacement, sizeof(replacement)); unsigned i; for (i = 0; i + sizeof(*parent) < parent->len; i += ptrsize) { childp = 0; memcpy(&childp, &parent->data[i], ptrsize); if (childp > 0xffffffffULL) { printf("Error: Child pointer at %d (%p) outside 32-bit range (0x%" PRIx64 ")", i, &parent->data[i], childp); continue; } acpi_sdt *table; memcpy(&table, &childp, sizeof(table)); assert_checksum(table, table->len); // DSDT is special-cased if (table->sig.l == STR_DW_H("FACP") && !strncmp(sig, "DSDT", 4)) { struct acpi_fadt *fadt = (struct acpi_fadt *)&table->data; fadt->Dsdt = (uint32_t)replacement; if (ptrsize == 8) fadt->X_Dsdt = (uint64_t)replacement; table->checksum = 0; table->checksum = checksum((const char *)table, table->len); return 1; } if (table->sig.l == STR_DW_H(sig)) { memcpy(&parent->data[i], &newp, ptrsize); // check if writing succeeded if (memcmp(&parent->data[i], &newp, ptrsize)) goto again; parent->checksum += checksum((const char *)parent, parent->len); return 1; } } // handled by caller if (slack(parent) < ptrsize) return 0; // append entry to end of table memcpy(&parent->data[i], &newp, ptrsize); // check if writing succeeded if (memcmp(&parent->data[i], &newp, ptrsize)) goto again; parent->len += ptrsize; xassert(parent->len < RSDT_MAX); parent->checksum += checksum((const char *)parent, parent->len); return 1; again: if (!bios_shadowed) { shadow_bios(); return replace_child(sig, replacement, parent, ptrsize); } fatal("ACPI tables immutable when replacing child at 0x%p", &parent->data[i]); }