25 : basis_factorization_(basis_factorization),
26 recompute_edge_squared_norms_(true) {}
29 return recompute_edge_squared_norms_;
35 edge_squared_norms_.resize(new_size, 1.0);
39 if (recompute_edge_squared_norms_) ComputeEdgeSquaredNorms();
40 return edge_squared_norms_.const_view();
45 if (recompute_edge_squared_norms_)
return;
47 col_perm.
const_view(), &edge_squared_norms_, &tmp_edge_squared_norms_);
53 if (recompute_edge_squared_norms_)
return true;
60 const Fractional old_squared_norm = edge_squared_norms_[leaving_row];
61 const Fractional estimated_edge_norms_accuracy =
62 (sqrt(leaving_squared_norm) - sqrt(old_squared_norm)) /
63 sqrt(leaving_squared_norm);
64 stats_.edge_norms_accuracy.Add(estimated_edge_norms_accuracy);
66 if (std::abs(estimated_edge_norms_accuracy) >
67 parameters_.recompute_edges_norm_threshold()) {
68 VLOG(1) <<
"Recomputing edge norms: " << sqrt(leaving_squared_norm)
69 <<
" vs " << sqrt(old_squared_norm);
70 recompute_edge_squared_norms_ =
true;
74 edge_squared_norms_[leaving_row] = leaving_squared_norm;
75 const bool result = old_squared_norm > 0.25 * leaving_squared_norm;
77 VLOG(1) <<
"Recomputing leaving row. Norm was " << sqrt(old_squared_norm)
78 <<
" vs precise version " << sqrt(leaving_squared_norm);
84 ColIndex entering_col, RowIndex leaving_row,
88 if (recompute_edge_squared_norms_)
return;
92 const Fractional pivot = direction[leaving_row];
94 edge_squared_norms_[leaving_row] /
Square(pivot);
97 int stat_lower_bounded_norms = 0;
98 auto output = edge_squared_norms_.view();
99 for (
const auto e : direction) {
103 e.coefficient() * (e.coefficient() * new_leaving_squared_norm -
104 2.0 / pivot * tau[e.row()]);
111 if (output[e.row()] < kLowerBound) {
112 if (e.row() == leaving_row)
continue;
113 output[e.row()] = kLowerBound;
114 ++stat_lower_bounded_norms;
117 output[leaving_row] = new_leaving_squared_norm;
121void DualEdgeNorms::ComputeEdgeSquaredNorms() {
126 const bool test_limit = (time_limit_ !=
nullptr) &&
133 edge_squared_norms_.
resize(num_rows, 1.0);
134 for (RowIndex row(0); row < num_rows; ++row) {
142 recompute_edge_squared_norms_ =
false;
146 const ScatteredColumn& unit_row_left_inverse) {
const DenseColumn & RightSolveForTau(const ScatteredColumn &a) const
bool IsRefactorized() const
Returns true if the factorization was just recomputed.
EntryIndex NumberOfEntriesInLU() const
RowIndex GetNumberOfRows() const
Return the number of rows in the basis.
Fractional DualEdgeSquaredNorm(RowIndex row) const
DenseColumn::ConstView GetEdgeSquaredNorms()
void ResizeOnNewRows(RowIndex new_size)
DualEdgeNorms(const BasisFactorization &basis_factorization)
Takes references to the linear program data we need.
void UpdateDataOnBasisPermutation(const ColumnPermutation &col_perm)
Updates the norms if the columns of the basis where permuted.
bool NeedsBasisRefactorization() const
void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row, const ScatteredColumn &direction, const ScatteredRow &unit_row_left_inverse)
bool TestPrecision(RowIndex leaving_row, const ScatteredRow &unit_row_left_inverse)
StrictITISpan< IndexType, const IndexType > const_view() const
StrictITISpan< RowIndex, const Fractional > ConstView
void resize(IntType size)
double Density(const DenseRow &row)
Fractional Square(Fractional f)
Permutation< ColIndex > ColumnPermutation
const DenseRow & Transpose(const DenseColumn &col)
Similar comment as the other Transpose() implementation above.
Fractional SquaredNorm(const SparseColumn &v)
StrictITIVector< RowIndex, Fractional > DenseColumn
Column-vector types. Column-vector types are indexed by a row index.
void ApplyColumnPermutationToRowIndexedVector(StrictITISpan< ColIndex, const ColIndex > col_perm, RowIndexedVector *v, RowIndexedVector *tmp)
const ScatteredRow & TransposedView(const ScatteredColumn &c)
In SWIG mode, we don't want anything besides these top-level includes.
#define IF_STATS_ENABLED(instructions)
#define SCOPED_TIME_STAT(stats)