Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More accurate cost function computation #75

Merged
merged 55 commits into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
97fa3eb
initial work on sparse matrix representation
GuyKatzHuji Jun 18, 2018
f67f40f
store/restore functionality
GuyKatzHuji Jun 18, 2018
9f1ad34
addLastRow functionality
GuyKatzHuji Jun 18, 2018
8315e89
getRow and getColumn
GuyKatzHuji Jun 18, 2018
9f96f81
column-merging functionality
GuyKatzHuji Jun 18, 2018
1ea9792
added an interface class
GuyKatzHuji Jun 19, 2018
1826116
introducing also sparse vectors
GuyKatzHuji Jun 19, 2018
a50b767
added addLastColumn functionality
GuyKatzHuji Jun 19, 2018
5394f30
another unittest
GuyKatzHuji Jun 19, 2018
c509909
get sparse columns/matrices in dense form
GuyKatzHuji Jun 19, 2018
66c00ce
WIP on storing the constraint matrix inside the tableau in sparse form
GuyKatzHuji Jun 19, 2018
b20cc6f
more WIP, fixed a few bugs, still have a couple of failing tests
GuyKatzHuji Jun 19, 2018
7f95cb1
fixed some test issues
GuyKatzHuji Jun 20, 2018
a90fd95
initialization
GuyKatzHuji Jun 20, 2018
dc2af7f
resize _a along with the rest
GuyKatzHuji Jun 20, 2018
4db0052
Merge branch 'master' into sparse_matrices
GuyKatzHuji Jul 8, 2018
f3683fb
sparse lu factors
GuyKatzHuji Jul 8, 2018
ea02f96
store also the transposed versions of F and V
GuyKatzHuji Jul 9, 2018
d3610b3
starting work on the sparse GE
GuyKatzHuji Jul 9, 2018
403decb
some work on changing the values within an existing sparse
GuyKatzHuji Jul 9, 2018
e05eb0e
refactoring and new functionality for CSRMatrix: any kind of
GuyKatzHuji Jul 10, 2018
2f3d16d
support for empty initialization and counting elements
GuyKatzHuji Jul 10, 2018
234b694
sparse GE is now working. minor bug fixes elsewhere
GuyKatzHuji Jul 10, 2018
36b9a60
compute Ft and Vt as part of the G-elimination process
GuyKatzHuji Jul 11, 2018
836d393
tests
GuyKatzHuji Jul 11, 2018
71b70c4
basis oracles can return also sparse columns, not just dense
GuyKatzHuji Jul 11, 2018
7408f3d
sparse LU factorization class
GuyKatzHuji Jul 11, 2018
f3b98ec
switch to using the sparse factorization in the engine/tableau
GuyKatzHuji Jul 11, 2018
64ae293
bug fix in mergeColumns, and nicer printing
GuyKatzHuji Jul 11, 2018
f583be0
bug fix
GuyKatzHuji Jul 11, 2018
d545f15
bug fix
GuyKatzHuji Jul 11, 2018
6120c31
bug fix: merging columns does not delete the actual column, just
GuyKatzHuji Jul 12, 2018
b667c26
configuration changes
GuyKatzHuji Jul 12, 2018
7364641
optimization: since the sparse columns of A are needed all the time,
GuyKatzHuji Jul 12, 2018
cb67ed9
a more efficient implementation of sparse vectors
GuyKatzHuji Jul 12, 2018
05e06de
comments and unit tests
GuyKatzHuji Jul 12, 2018
f0c9c68
cleanup
GuyKatzHuji Jul 12, 2018
ad79fac
Merge branch 'master' into sparse_matrices
GuyKatzHuji Jul 12, 2018
27b0f04
keep _A in dense column-major format, too, instead of repeatedly
GuyKatzHuji Jul 12, 2018
ad630e5
Merge branch 'master' into sparse_matrices
GuyKatzHuji Jul 12, 2018
7df63cd
bad deletes
GuyKatzHuji Jul 15, 2018
f3ab834
bug fix in test
GuyKatzHuji Jul 15, 2018
aa00bbc
bug fixes: relu constraint propagation, and the handling of merged
GuyKatzHuji Jul 15, 2018
b05229b
new test
GuyKatzHuji Jul 15, 2018
8421ff6
compute Ft incrementally, use it whenever sparse columns are required
GuyKatzHuji Jul 15, 2018
ce8968d
did the todo
GuyKatzHuji Jul 15, 2018
6da8e7f
valgrind fixes
GuyKatzHuji Jul 16, 2018
ab6e2a3
Merge branch 'master' into sparse_matrices
GuyKatzHuji Jul 16, 2018
1d42540
debugging
GuyKatzHuji Jul 16, 2018
089097e
un-initialized memory
GuyKatzHuji Jul 18, 2018
11bef7d
merge
GuyKatzHuji Jul 18, 2018
bca044d
cleanup
GuyKatzHuji Jul 18, 2018
518f157
fixing an issue with cost function degradation
GuyKatzHuji Jul 18, 2018
ee74206
Merge branch 'master' into sparse_matrices
GuyKatzHuji Jul 18, 2018
74d4648
reinstating the anti-looping trick
GuyKatzHuji Jul 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/configuration/GlobalConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const double GlobalConfiguration::GAUSSIAN_ELIMINATION_PIVOT_SCALE_THRESHOLD = 0
const unsigned GlobalConfiguration::MAX_SIMPLEX_PIVOT_SEARCH_ITERATIONS = 5;
const unsigned GlobalConfiguration::CONSTRAINT_VIOLATION_THRESHOLD = 20;
const unsigned GlobalConfiguration::BOUND_TIGHTING_ON_CONSTRAINT_MATRIX_FREQUENCY = 100;
const double GlobalConfiguration::COST_FUNCTION_ERROR_THRESHOLD = 0.0000000001;

const bool GlobalConfiguration::PREPROCESS_INPUT_QUERY = true;
const bool GlobalConfiguration::PREPROCESSOR_ELIMINATE_VARIABLES = true;
Expand Down
3 changes: 3 additions & 0 deletions src/configuration/GlobalConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class GlobalConfiguration
// How often should we perform full bound tightening, on the entire contraints matrix A.
static const unsigned BOUND_TIGHTING_ON_CONSTRAINT_MATRIX_FREQUENCY;

// If the cost function error exceeds this threshold, it is recomputed
static const double COST_FUNCTION_ERROR_THRESHOLD;

// How often should projected steepest edge reset the reference space?
static const unsigned PSE_ITERATIONS_BEFORE_RESET;

Expand Down
51 changes: 28 additions & 23 deletions src/engine/CostFunctionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,12 @@ const double *CostFunctionManager::getCostFunction() const
return _costFunction;
}

void CostFunctionManager::updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow )
double CostFunctionManager::updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow,
const double *changeColumn
)
{
/*
This method is invoked when the non-basic _enteringVariable and
Expand All @@ -247,36 +249,39 @@ void CostFunctionManager::updateCostFunctionForPivot( unsigned enteringVariableI
ASSERT( _tableau->getM() == _m );
ASSERT( _tableau->getN() == _n );

/*
The current reduced cost of the entering variable is stored in
_costFunction, but since we have the change column we can compute a
more accurate version from scratch
*/
double enteringVariableCost = 0;
for ( unsigned i = 0; i < _m; ++i )
enteringVariableCost -= _basicCosts[i] * changeColumn[i];

double normalizedError =
FloatUtils::abs( enteringVariableCost - _costFunction[enteringVariableIndex] ) /
( FloatUtils::abs( enteringVariableCost ) + 1.0 );

// Update the cost of the new non-basic
_costFunction[enteringVariableIndex] /= pivotElement;
_costFunction[enteringVariableIndex] = enteringVariableCost / pivotElement;

for ( unsigned i = 0; i < _n - _m; ++i )
{
if ( i != enteringVariableIndex )
_costFunction[i] -= (*pivotRow)[i] * _costFunction[enteringVariableIndex];
}

unsigned leavingVariableStatus = _tableau->getBasicStatusByIndex( leavingVariableIndex );
/*
The leaving variable might have contributed to the cost function, but it will
soon be made within bounds. So, we adjust the reduced costs accordingly.
*/
_costFunction[enteringVariableIndex] -= _basicCosts[leavingVariableIndex];

// Update the basic cost for the leaving variable, which may have changed
// since we last computed it
switch ( leavingVariableStatus )
{
case ITableau::ABOVE_UB:
_basicCosts[leavingVariableIndex] = 1;
break;
case ITableau::BELOW_LB:
_basicCosts[leavingVariableIndex] = -1;
break;
default:
_basicCosts[leavingVariableIndex] = 0;
break;
}
// The entering varibale is non-basic, so it is within bounds.
_basicCosts[leavingVariableIndex] = 0;

// If the leaving variable was previously out of bounds, this is no longer
// the case. Adjust the non-basic cost.
_costFunction[enteringVariableIndex] -= _basicCosts[leavingVariableIndex];
_costFunctionStatus = ICostFunctionManager::COST_FUNCTION_UPDATED;
return normalizedError;
}

bool CostFunctionManager::costFunctionInvalid() const
Expand Down
9 changes: 5 additions & 4 deletions src/engine/CostFunctionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ class CostFunctionManager : public ICostFunctionManager
Update the cost fucntion just before a coming pivot step, to avoid having to compute
it from scratch afterwards.
*/
void updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow );
double updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow,
const double *changeColumn );

/*
For debugging purposes: dump the cost function.
Expand Down
9 changes: 5 additions & 4 deletions src/engine/ICostFunctionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ class ICostFunctionManager
virtual const double *getCostFunction() const = 0;
virtual void dumpCostFunction() const = 0;
virtual void setCostFunctionStatus( ICostFunctionManager::CostFunctionStatus status ) = 0;
virtual void updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow ) = 0;
virtual double updateCostFunctionForPivot( unsigned enteringVariableIndex,
unsigned leavingVariableIndex,
double pivotElement,
const TableauRow *pivotRow,
const double *changeColumn ) = 0;

virtual bool costFunctionInvalid() const = 0;
virtual bool costFunctionJustComputed() const = 0;
Expand Down
12 changes: 8 additions & 4 deletions src/engine/Tableau.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1977,10 +1977,14 @@ void Tableau::updateCostFunctionForPivot()
return;

double pivotElement = -_changeColumn[_leavingVariable];
_costFunctionManager->updateCostFunctionForPivot( _enteringVariable,
_leavingVariable,
pivotElement,
_pivotRow );
double normalizedError = _costFunctionManager->updateCostFunctionForPivot( _enteringVariable,
_leavingVariable,
pivotElement,
_pivotRow,
_changeColumn );

if ( FloatUtils::gt( normalizedError, GlobalConfiguration::COST_FUNCTION_ERROR_THRESHOLD ) )
_costFunctionManager->invalidateCostFunction();
}

ITableau::BasicAssignmentStatus Tableau::getBasicAssignmentStatus() const
Expand Down
11 changes: 7 additions & 4 deletions src/engine/tests/MockCostFunctionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,14 @@ class MockCostFunctionManager : public ICostFunctionManager
{
}

void updateCostFunctionForPivot( unsigned /* enteringVariableIndex */,
unsigned /* leavingVariableIndex */,
double /* pivotElement */,
const TableauRow */* pivotRow */ )
double updateCostFunctionForPivot( unsigned /* enteringVariableIndex */,
unsigned /* leavingVariableIndex */,
double /* pivotElement */,
const TableauRow */* pivotRow */,
const double */* changeColumn */
)
{
return 0;
}

bool costFunctionInvalid() const
Expand Down