MCPcopy Create free account
hub / github.com/NeuralNetworkVerification/Marabou / encodeSigmoidConstraint

Method encodeSigmoidConstraint

src/engine/MILPEncoder.cpp:462–591  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

460}
461
462void MILPEncoder::encodeSigmoidConstraint( GurobiWrapper &gurobi, SigmoidConstraint *sigmoid )
463{
464 unsigned sourceVariable = sigmoid->getB(); // x_b
465 unsigned targetVariable = sigmoid->getF(); // x_f
466 double sourceLb = _tableau.getLowerBound( sourceVariable );
467 double sourceUb = _tableau.getUpperBound( sourceVariable );
468
469 if ( sourceLb == sourceUb )
470 {
471 return;
472 }
473 else if ( FloatUtils::lt( sourceLb, 0 ) && FloatUtils::gt( sourceUb, 0 ) )
474 {
475 List<GurobiWrapper::Term> terms;
476 String binVarName = Stringf( "a%u", _binVarIndex ); // a = 1 -> the case where x_b >= 0,
477 // otherwise where x_b <= 0
478 gurobi.addVariable( binVarName, 0, 1, GurobiWrapper::BINARY );
479
480 // Constraint where x_b >= 0
481 // Upper line is tangent and lower line is secant for an overapproximation with a
482 // linearization.
483
484 int binVal = 1;
485
486 // tangent line: x_f = tangentSlope * (x_b - tangentPoint) + yAtTangentPoint
487 double tangentPoint = sourceUb / 2;
488 double yAtTangentPoint = sigmoid->sigmoid( tangentPoint );
489 double tangentSlope = sigmoid->sigmoidDerivative( tangentPoint );
490 terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", targetVariable ) ) );
491 terms.append( GurobiWrapper::Term( -tangentSlope, Stringf( "x%u", sourceVariable ) ) );
492 gurobi.addLeqIndicatorConstraint(
493 binVarName, binVal, terms, -tangentSlope * tangentPoint + yAtTangentPoint );
494 terms.clear();
495
496 // secant line: x_f = secantSlope * (x_b - 0) + y_l
497 double y_l = sigmoid->sigmoid( 0 );
498 double y_u = sigmoid->sigmoid( sourceUb );
499 double secantSlope = ( y_u - y_l ) / sourceUb;
500 terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", targetVariable ) ) );
501 terms.append( GurobiWrapper::Term( -secantSlope, Stringf( "x%u", sourceVariable ) ) );
502 gurobi.addGeqIndicatorConstraint( binVarName, binVal, terms, y_l );
503 terms.clear();
504
505 // lower bound of x_b
506 terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", sourceVariable ) ) );
507 gurobi.addGeqIndicatorConstraint( binVarName, binVal, terms, 0 );
508 terms.clear();
509
510 // lower bound of x_f
511 terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", targetVariable ) ) );
512 gurobi.addGeqIndicatorConstraint( binVarName, binVal, terms, y_l );
513 terms.clear();
514
515 // Constraints where x_b <= 0
516 // Upper line is secant and lower line is tangent for an overapproximation with a
517 // linearization.
518
519 binVal = 0;

Callers

nothing calls this directly

Calls 15

StringfClass · 0.85
sigmoidMethod · 0.80
sigmoidDerivativeMethod · 0.80
TermClass · 0.50
getBMethod · 0.45
getFMethod · 0.45
getLowerBoundMethod · 0.45
getUpperBoundMethod · 0.45
addVariableMethod · 0.45
appendMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected