27 : compact_matrix_(compact_matrix),
28 variables_info_(variables_info),
29 basis_factorization_(basis_factorization),
31 recompute_edge_squared_norms_(true),
32 reset_devex_weights_(true),
33 edge_squared_norms_(),
34 matrix_column_norms_(),
36 direction_left_inverse_(),
41 matrix_column_norms_.
clear();
42 recompute_edge_squared_norms_ =
true;
43 reset_devex_weights_ =
true;
44 for (
bool* watcher : watchers_) *watcher =
true;
48 if (pricing_rule_ != GlopParameters ::STEEPEST_EDGE)
return false;
49 return recompute_edge_squared_norms_;
53 switch (pricing_rule_) {
54 case GlopParameters::DANTZIG:
56 case GlopParameters::STEEPEST_EDGE:
58 case GlopParameters::DEVEX:
64 if (recompute_edge_squared_norms_) ComputeEdgeSquaredNorms();
65 return edge_squared_norms_;
69 if (reset_devex_weights_) ResetDevexWeights();
70 return devex_weights_;
74 if (matrix_column_norms_.
empty()) ComputeMatrixColumnNorms();
75 return matrix_column_norms_;
80 if (!recompute_edge_squared_norms_) {
84 const Fractional old_squared_norm = edge_squared_norms_[entering_col];
86 edge_squared_norms_[entering_col] = precise_squared_norm;
88 const Fractional precise_norm = sqrt(precise_squared_norm);
89 const Fractional estimated_edges_norm_accuracy =
90 (precise_norm - sqrt(old_squared_norm)) / precise_norm;
91 stats_.edges_norm_accuracy.Add(estimated_edges_norm_accuracy);
92 if (std::abs(estimated_edges_norm_accuracy) >
93 parameters_.recompute_edges_norm_threshold()) {
94 VLOG(1) <<
"Recomputing edge norms: " << sqrt(precise_squared_norm)
95 <<
" vs " << sqrt(old_squared_norm);
96 recompute_edge_squared_norms_ =
true;
97 for (
bool* watcher : watchers_) *watcher =
true;
100 if (old_squared_norm < 0.25 * precise_squared_norm) {
101 VLOG(1) <<
"Imprecise norm, reprice. old=" << old_squared_norm
102 <<
" new=" << precise_squared_norm;
110 ColIndex leaving_col,
111 RowIndex leaving_row,
115 DCHECK_NE(entering_col, leaving_col);
116 if (!recompute_edge_squared_norms_) {
118 ComputeDirectionLeftInverse(entering_col, direction);
119 UpdateEdgeSquaredNorms(entering_col, leaving_col, leaving_row,
120 direction.
values, *update_row);
122 if (!reset_devex_weights_) {
125 ++num_devex_updates_since_reset_;
126 if (num_devex_updates_since_reset_ >
127 parameters_.devex_weights_reset_period()) {
128 reset_devex_weights_ =
true;
131 UpdateDevexWeights(entering_col, leaving_col, leaving_row,
132 direction.
values, *update_row);
137 void PrimalEdgeNorms::ComputeMatrixColumnNorms() {
146 void PrimalEdgeNorms::ComputeEdgeSquaredNorms() {
159 recompute_edge_squared_norms_ =
false;
165 void PrimalEdgeNorms::ComputeDirectionLeftInverse(
166 ColIndex entering_col,
const ScatteredColumn& direction) {
172 const ColIndex size =
RowToColIndex(direction.values.size());
173 const double kThreshold = 0.05 * size.value();
174 if (!direction_left_inverse_.
non_zeros.empty() &&
175 (direction_left_inverse_.
non_zeros.size() + direction.non_zeros.size() <
178 for (
const auto e : direction) {
179 direction_left_inverse_[
RowToColIndex(e.row())] = e.coefficient();
183 direction_left_inverse_.
non_zeros.clear();
186 if (direction.non_zeros.size() < kThreshold) {
189 basis_factorization_.
LeftSolve(&direction_left_inverse_);
194 direction_left_inverse_.
values) -
207 void PrimalEdgeNorms::UpdateEdgeSquaredNorms(ColIndex entering_col,
208 ColIndex leaving_col,
209 RowIndex leaving_row,
211 const UpdateRow& update_row) {
217 const Fractional pivot = -direction[leaving_row];
218 DCHECK_NE(pivot, 0.0);
222 const Fractional entering_squared_norm = edge_squared_norms_[entering_col];
226 int stat_lower_bounded_norms = 0;
228 const auto view = compact_matrix_.
view();
229 auto output = edge_squared_norms_.
view();
230 const auto direction_left_inverse =
232 for (
const ColIndex
col : update_row.GetNonZeroPositions()) {
235 view.ColumnScalarProduct(
col, direction_left_inverse);
236 num_operations_ += view.ColumnNumEntries(
col).value();
242 coeff * (coeff * leaving_squared_norm + factor * scalar_product);
252 ++stat_lower_bounded_norms;
255 output[leaving_col] = leaving_squared_norm;
256 stats_.lower_bounded_norms.Add(stat_lower_bounded_norms);
259 void PrimalEdgeNorms::UpdateDevexWeights(
260 ColIndex entering_col ,
261 ColIndex leaving_col , RowIndex leaving_row,
262 const DenseColumn& direction,
const UpdateRow& update_row) {
268 const Fractional pivot_magnitude = std::abs(direction[leaving_row]);
270 std::max(1.0, entering_norm / pivot_magnitude);
271 for (
const ColIndex
col : update_row.GetNonZeroPositions()) {
273 const Fractional update_vector_norm = std::abs(coeff) * leaving_norm;
274 devex_weights_[
col] =
277 devex_weights_[leaving_col] =
Square(leaving_norm);
280 void PrimalEdgeNorms::ResetDevexWeights() {
282 if (parameters_.initialize_devex_with_column_norms()) {
287 num_devex_updates_since_reset_ = 0;
288 reset_devex_weights_ =
false;
Fractional RightSolveSquaredNorm(const ColumnView &a) const
bool IsRefactorized() const
void LeftSolve(ScatteredRow *y) const
EntryIndex num_entries() const
ColIndex num_cols() const
Fractional ColumnScalarProduct(ColIndex col, const DenseRow &vector) const
ColumnView column(ColIndex col) const
const DenseRow & GetSquaredNorms()
PrimalEdgeNorms(const CompactSparseMatrix &compact_matrix, const VariablesInfo &variables_info, const BasisFactorization &basis_factorization)
const DenseRow & GetMatrixColumnNorms()
const DenseRow & GetEdgeSquaredNorms()
bool TestEnteringEdgeNormPrecision(ColIndex entering_col, const ScatteredColumn &direction)
const DenseRow & GetDevexWeights()
void UpdateBeforeBasisPivot(ColIndex entering_col, ColIndex leaving_col, RowIndex leaving_row, const ScatteredColumn &direction, UpdateRow *update_row)
bool NeedsBasisRefactorization() const
void resize(IntType size)
ConstView const_view() const
void assign(IntType size, const T &v)
void ComputeUpdateRow(RowIndex leaving_row)
const DenseBitRow & GetIsRelevantBitRow() const
Fractional Square(Fractional f)
Fractional PreciseSquaredNorm(const SparseColumn &v)
Fractional SquaredNorm(const SparseColumn &v)
double Density(const DenseRow &row)
ColIndex RowToColIndex(RowIndex row)
void ClearAndResizeVectorWithNonZeros(IndexType size, ScatteredRowOrCol *v)
const DenseRow & Transpose(const DenseColumn &col)
StrictITIVector< RowIndex, Fractional > DenseColumn
const ScatteredRow & TransposedView(const ScatteredColumn &c)
Collection of objects used to extend the Constraint Solver library.
#define IF_STATS_ENABLED(instructions)
#define SCOPED_TIME_STAT(stats)
std::vector< Index > non_zeros
StrictITIVector< Index, Fractional > values
#define VLOG(verboselevel)