27const Fractional EtaMatrix::kSparseThreshold = 0.5;
35 eta_coeff_ = direction.
values;
40 kSparseThreshold * eta_coeff_.
size().value()) {
54 if (!sparse_eta_coeff_.
IsEmpty()) {
55 LeftSolveWithSparseEta(y);
57 LeftSolveWithDenseEta(y);
68 if (!sparse_eta_coeff_.
IsEmpty()) {
69 RightSolveWithSparseEta(d);
71 RightSolveWithDenseEta(d);
80 bool is_eta_col_in_pos =
false;
81 const int size = pos->size();
82 for (
int i = 0; i < size; ++i) {
83 const ColIndex
col = (*pos)[i];
85 if (
col == eta_col_) {
86 is_eta_col_in_pos =
true;
89 y_value -= (*y)[
col] * eta_coeff_[
row];
92 (*y)[eta_col_] = y_value / eta_col_coefficient_;
95 if (!is_eta_col_in_pos) pos->push_back(eta_col_);
98void EtaMatrix::LeftSolveWithDenseEta(
DenseRow* y)
const {
100 const RowIndex num_rows(eta_coeff_.
size());
101 for (RowIndex
row(0);
row < num_rows; ++
row) {
104 (*y)[eta_col_] = y_value / eta_col_coefficient_;
107void EtaMatrix::LeftSolveWithSparseEta(
DenseRow* y)
const {
112 (*y)[eta_col_] = y_value / eta_col_coefficient_;
115void EtaMatrix::RightSolveWithDenseEta(
DenseColumn* d)
const {
118 const RowIndex num_rows(eta_coeff_.
size());
119 for (RowIndex
row(0);
row < num_rows; ++
row) {
122 (*d)[eta_row] =
coeff;
125void EtaMatrix::RightSolveWithSparseEta(
DenseColumn* d)
const {
129 (*d)[e.row()] -= e.coefficient() *
coeff;
131 (*d)[eta_row] =
coeff;
144 RowIndex leaving_variable_row,
146 const ColIndex leaving_variable_col =
RowToColIndex(leaving_variable_row);
148 new EtaMatrix(leaving_variable_col, direction);
149 eta_matrix_.push_back(eta_factorization);
154 for (
int i = eta_matrix_.size() - 1; i >= 0; --i) {
155 eta_matrix_[i]->LeftSolve(y);
161 for (
int i = eta_matrix_.size() - 1; i >= 0; --i) {
162 eta_matrix_[i]->SparseLeftSolve(y, pos);
168 const size_t num_eta_matrices = eta_matrix_.size();
169 for (
int i = 0; i < num_eta_matrices; ++i) {
170 eta_matrix_[i]->RightSolve(d);
180 compact_matrix_(*compact_matrix),
182 tau_is_computed_(false),
185 eta_factorization_(),
187 deterministic_time_(0.0) {
196 tau_computation_can_be_optimized_ =
false;
197 eta_factorization_.
Clear();
198 lu_factorization_.
Clear();
199 rank_one_factorization_.
Clear();
202 left_pool_mapping_.
clear();
203 right_pool_mapping_.
clear();
210 return ComputeFactorization();
214 const std::vector<ColIndex>& candidates) {
217 deterministic_time_ +=
231 stats_.refactorization_interval.Add(num_updates_);
233 return ComputeFactorization();
236Status BasisFactorization::ComputeFactorization() {
239 last_factorization_deterministic_time_ =
241 deterministic_time_ += last_factorization_deterministic_time_;
254Status BasisFactorization::MiddleProductFormUpdate(
255 ColIndex entering_col, RowIndex leaving_variable_row) {
256 const ColIndex right_index = entering_col < right_pool_mapping_.
size()
257 ? right_pool_mapping_[entering_col]
259 const ColIndex left_index =
264 LOG(
INFO) <<
"One update vector is missing!!!";
272 for (
const EntryIndex i : right_storage_.
Column(right_index)) {
275 scratchpad_non_zeros_.push_back(
row);
278 const SparseColumn& column_of_u =
281 scratchpad_[e.row()] -= e.coefficient();
282 scratchpad_non_zeros_.push_back(e.row());
289 &scratchpad_, &scratchpad_non_zeros_);
290 RankOneUpdateElementaryMatrix elementary_update_matrix(
291 &storage_, u_index, left_index, scalar_product);
292 if (elementary_update_matrix.IsSingular()) {
295 rank_one_factorization_.
Update(elementary_update_matrix);
300 RowIndex leaving_variable_row,
305 if (num_updates_ >= max_num_updates_) {
306 if (!parameters_.dynamically_adjust_refactorization_period()) {
316 if (last_factorization_deterministic_time_ <
327 if (use_middle_product_form_update_) {
329 MiddleProductFormUpdate(entering_col, leaving_variable_row));
331 eta_factorization_.
Update(entering_col, leaving_variable_row, direction);
333 tau_computation_can_be_optimized_ =
false;
340 if (use_middle_product_form_update_) {
356 if (use_middle_product_form_update_) {
372 if (use_middle_product_form_update_) {
373 if (tau_computation_can_be_optimized_) {
376 tau_computation_can_be_optimized_ =
false;
390 tau_is_computed_ =
true;
401 if (!use_middle_product_form_update_) {
414 if (j >= left_pool_mapping_.
size()) {
438 if (tau_is_computed_) {
439 tau_computation_can_be_optimized_ =
442 tau_computation_can_be_optimized_ =
false;
445 tau_is_computed_ =
false;
469 if (!use_middle_product_form_update_) {
481 if (
col >= right_pool_mapping_.
size()) {
490 right_pool_mapping_[
col] =
502 BumpDeterministicTimeForSolve(
a.num_entries().value());
509 BumpDeterministicTimeForSolve(1);
513bool BasisFactorization::IsIdentityBasis()
const {
514 const RowIndex num_rows = compact_matrix_.
num_rows();
515 for (RowIndex
row(0);
row < num_rows; ++
row) {
516 const ColIndex
col = basis_[
row];
520 if (entry_row !=
row ||
coeff != 1.0)
return false;
526 if (IsIdentityBasis())
return 1.0;
532 if (IsIdentityBasis())
return 1.0;
541 if (IsIdentityBasis())
return 1.0;
542 const RowIndex num_rows = compact_matrix_.
num_rows();
545 for (ColIndex
col(0);
col < num_cols; ++
col) {
553 for (RowIndex
row(0);
row < num_rows; ++
row) {
554 column_norm += std::abs(right_hand_side[
row]);
563 if (IsIdentityBasis())
return 1.0;
564 const RowIndex num_rows = compact_matrix_.
num_rows();
567 for (ColIndex
col(0);
col < num_cols; ++
col) {
574 for (RowIndex
row(0);
row < num_rows; ++
row) {
575 row_sum[
row] += std::abs(right_hand_side[
row]);
580 for (RowIndex
row(0);
row < num_rows; ++
row) {
587 if (IsIdentityBasis())
return 1.0;
592 if (IsIdentityBasis())
return 1.0;
598 if (IsIdentityBasis())
return 1.0;
599 BumpDeterministicTimeForSolve(compact_matrix_.
num_rows().value());
605 return deterministic_time_;
608void BasisFactorization::BumpDeterministicTimeForSolve(
int num_entries)
const {
610 if (compact_matrix_.
num_rows().value() == 0)
return;
611 const double density =
613 static_cast<double>(compact_matrix_.
num_rows().value());
614 deterministic_time_ +=
#define DCHECK_NE(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
Fractional ComputeInverseOneNorm() const
BasisFactorization(const CompactSparseMatrix *compact_matrix, const RowToColMapping *basis)
Fractional ComputeInfinityNormConditionNumberUpperBound() const
ABSL_MUST_USE_RESULT Status Refactorize()
Fractional ComputeInverseInfinityNorm() const
Fractional ComputeInfinityNorm() const
const DenseColumn & RightSolveForTau(const ScatteredColumn &a) const
void LeftSolveForUnitRow(ColIndex j, ScatteredRow *y) const
Fractional RightSolveSquaredNorm(const ColumnView &a) const
Fractional ComputeOneNorm() const
Fractional ComputeOneNormConditionNumber() const
ABSL_MUST_USE_RESULT Status Initialize()
bool IsRefactorized() const
void TemporaryLeftSolveForUnitRow(ColIndex j, ScatteredRow *y) const
ABSL_MUST_USE_RESULT Status Update(ColIndex entering_col, RowIndex leaving_variable_row, const ScatteredColumn &direction)
virtual ~BasisFactorization()
Fractional DualEdgeSquaredNorm(RowIndex row) const
RowToColMapping ComputeInitialBasis(const std::vector< ColIndex > &candidates)
void LeftSolve(ScatteredRow *y) const
void RightSolveForProblemColumn(ColIndex col, ScatteredColumn *d) const
Fractional ComputeInfinityNormConditionNumber() const
void SetParameters(const GlopParameters ¶meters)
void RightSolve(ScatteredColumn *d) const
double DeterministicTime() const
ABSL_MUST_USE_RESULT Status ForceRefactorization()
RowIndex GetFirstRow() const
Fractional GetFirstCoefficient() const
EntryIndex num_entries() const
ColIndex AddDenseColumn(const DenseColumn &dense_column)
ColIndex AddDenseColumnWithNonZeros(const DenseColumn &dense_column, const std::vector< RowIndex > &non_zeros)
ColIndex AddAndClearColumnWithNonZeros(DenseColumn *column, std::vector< RowIndex > *non_zeros)
void ColumnCopyToClearedDenseColumnWithNonZeros(ColIndex col, DenseColumn *dense_column, RowIndexVector *non_zeros) const
ColIndex AddDenseColumnPrefix(const DenseColumn &dense_column, RowIndex start)
RowIndex num_rows() const
Fractional EntryCoefficient(EntryIndex i) const
void ColumnCopyToClearedDenseColumn(ColIndex col, DenseColumn *dense_column) const
Fractional ColumnScalarProduct(ColIndex col, const DenseRow &vector) const
::util::IntegerRange< EntryIndex > Column(ColIndex col) const
void Reset(RowIndex num_rows)
RowIndex EntryRow(EntryIndex i) const
ColumnView column(ColIndex col) const
Fractional ComputeInfinityNorm() const
Fractional ComputeOneNorm() const
void RightSolve(DenseColumn *d) const
void LeftSolve(DenseRow *y) const
virtual ~EtaFactorization()
void SparseLeftSolve(DenseRow *y, ColIndexVector *pos) const
void Update(ColIndex entering_col, RowIndex leaving_variable_row, const ScatteredColumn &direction)
void RightSolve(DenseColumn *d) const
void LeftSolve(DenseRow *y) const
EtaMatrix(ColIndex eta_col, const ScatteredColumn &direction)
void SparseLeftSolve(DenseRow *y, ColIndexVector *pos) const
void LeftSolveUWithNonZeros(ScatteredRow *y) const
const SparseColumn & GetColumnOfU(ColIndex col) const
RowToColMapping ComputeInitialBasis(const CompactSparseMatrix &matrix, const std::vector< ColIndex > &candidates)
void RightSolveLForColumnView(const ColumnView &b, ScatteredColumn *x) const
void RightSolveLWithPermutedInput(const DenseColumn &a, ScatteredColumn *x) const
Fractional RightSolveSquaredNorm(const ColumnView &a) const
void RightSolveUWithNonZeros(ScatteredColumn *x) const
double DeterministicTimeOfLastFactorization() const
void LeftSolve(DenseRow *y) const
bool LeftSolveLWithNonZeros(ScatteredRow *y, ScatteredColumn *result_before_permutation) const
void RightSolve(DenseColumn *x) const
ColIndex LeftSolveUForUnitRow(ColIndex col, ScatteredRow *y) const
Fractional DualEdgeSquaredNorm(RowIndex row) const
void RightSolveLForScatteredColumn(const ScatteredColumn &b, ScatteredColumn *x) const
void RightSolveLWithNonZeros(ScatteredColumn *x) const
ABSL_MUST_USE_RESULT Status ComputeFactorization(const CompactSparseMatrixView &compact_matrix)
EntryIndex NumberOfEntries() const
Fractional ComputeInverseInfinityNormUpperBound() const
void RightSolveWithNonZeros(ScatteredColumn *d) const
void LeftSolveWithNonZeros(ScatteredRow *y) const
void ResetDeterministicTime()
double DeterministicTimeSinceLastReset() const
void Update(const RankOneUpdateElementaryMatrix &update_matrix)
EntryIndex num_entries() const
bool CheckNoDuplicates() const
typename Iterator::Entry Entry
void SetCoefficient(Index index, Fractional value)
void AssignToZero(IntType size)
void resize(IntType size)
void STLDeleteElements(T *container)
std::vector< ColIndex > ColIndexVector
bool IsAllZero(const Container &input)
StrictITIVector< ColIndex, Fractional > DenseRow
ColIndex RowToColIndex(RowIndex row)
void ClearAndResizeVectorWithNonZeros(IndexType size, ScatteredRowOrCol *v)
const DenseRow & Transpose(const DenseColumn &col)
RowIndex ColToRowIndex(ColIndex col)
std::vector< RowIndex > RowIndexVector
StrictITIVector< RowIndex, Fractional > DenseColumn
static double DeterministicTimeForFpOperations(int64_t n)
const ColIndex kInvalidCol(-1)
Collection of objects used to extend the Constraint Solver library.
#define RETURN_IF_NULL(x)
#define SCOPED_TIME_STAT(stats)
#define GLOP_RETURN_IF_ERROR(function_call)
#define GLOP_RETURN_AND_LOG_ERROR(error_code, message)
void SortNonZerosIfNeeded()
size_t NumNonZerosEstimate() const
std::vector< Index > non_zeros
StrictITIVector< Index, Fractional > values