29 transposed_matrix_(transposed_matrix),
30 variables_info_(variables_info),
32 basis_factorization_(basis_factorization),
33 unit_row_left_inverse_(),
34 non_zero_position_list_(),
35 non_zero_position_set_(),
48 return unit_row_left_inverse_;
52 RowIndex leaving_row) {
55 &unit_row_left_inverse_);
56 return unit_row_left_inverse_;
60 if (left_inverse_computed_for_ == leaving_row)
return;
61 left_inverse_computed_for_ = leaving_row;
65 &unit_row_left_inverse_);
70 unit_row_left_inverse_.
values) -
77 if (update_row_computed_for_ == leaving_row)
return;
78 update_row_computed_for_ = leaving_row;
82 if (parameters_.use_transposed_matrix()) {
84 EntryIndex num_row_wise_entries(0);
96 const Fractional drop_tolerance = parameters_.drop_tolerance();
97 unit_row_left_inverse_filtered_non_zeros_.clear();
98 const auto view = transposed_matrix_.
view();
99 if (unit_row_left_inverse_.
non_zeros.empty()) {
100 const ColIndex size = unit_row_left_inverse_.
values.
size();
101 for (ColIndex
col(0);
col < size; ++
col) {
102 if (std::abs(unit_row_left_inverse_.
values[
col]) > drop_tolerance) {
103 unit_row_left_inverse_filtered_non_zeros_.push_back(
col);
104 num_row_wise_entries += view.ColumnNumEntries(
col);
108 for (
const auto e : unit_row_left_inverse_) {
109 if (std::abs(e.coefficient()) > drop_tolerance) {
110 unit_row_left_inverse_filtered_non_zeros_.push_back(e.column());
111 num_row_wise_entries += view.ColumnNumEntries(e.column());
120 if (unit_row_left_inverse_filtered_non_zeros_.size() == 1) {
121 ComputeUpdatesForSingleRow(
122 unit_row_left_inverse_filtered_non_zeros_.front());
123 num_operations_ += num_row_wise_entries.value();
125 static_cast<double>(non_zero_position_list_.size()) /
126 static_cast<double>(matrix_.
num_cols().value())));
131 const EntryIndex num_col_wise_entries =
137 const double row_wise =
static_cast<double>(num_row_wise_entries.value());
138 if (row_wise < 0.5 *
static_cast<double>(num_col_wise_entries.value())) {
139 if (row_wise < 1.1 *
static_cast<double>(matrix_.
num_cols().value())) {
140 ComputeUpdatesRowWiseHypersparse();
145 5 * num_row_wise_entries.value() + matrix_.
num_cols().value() / 64;
147 ComputeUpdatesRowWise();
149 num_row_wise_entries.value() + matrix_.
num_rows().value();
152 ComputeUpdatesColumnWise();
154 num_col_wise_entries.value() + matrix_.
num_cols().value();
157 ComputeUpdatesColumnWise();
163 static_cast<double>(non_zero_position_list_.size()) /
164 static_cast<double>(matrix_.
num_cols().value())));
168 const std::string& algorithm) {
169 unit_row_left_inverse_.
values = lhs;
171 if (algorithm ==
"column") {
172 ComputeUpdatesColumnWise();
173 }
else if (algorithm ==
"row") {
174 ComputeUpdatesRowWise();
175 }
else if (algorithm ==
"row_hypersparse") {
176 ComputeUpdatesRowWiseHypersparse();
178 LOG(DFATAL) <<
"Unknown algorithm in ComputeUpdateRowForBenchmark(): '"
186 return non_zero_position_list_;
195 void UpdateRow::ComputeUpdatesRowWise() {
198 const auto output_coeffs = coefficient_.
view();
199 const auto view = transposed_matrix_.
view();
200 for (ColIndex
col : unit_row_left_inverse_filtered_non_zeros_) {
202 for (
const EntryIndex i : view.Column(
col)) {
204 output_coeffs[pos] += multiplier * view.EntryCoefficient(i);
208 non_zero_position_list_.clear();
209 const Fractional drop_tolerance = parameters_.drop_tolerance();
211 if (std::abs(output_coeffs[
col]) > drop_tolerance) {
212 non_zero_position_list_.push_back(
col);
219 void UpdateRow::ComputeUpdatesRowWiseHypersparse() {
221 const ColIndex num_cols = matrix_.
num_cols();
223 coefficient_.
resize(num_cols, 0.0);
225 const auto output_coeffs = coefficient_.
view();
226 const auto view = transposed_matrix_.
view();
227 for (ColIndex
col : unit_row_left_inverse_filtered_non_zeros_) {
229 for (
const EntryIndex i : view.Column(
col)) {
231 const Fractional v = multiplier * view.EntryCoefficient(i);
232 if (!non_zero_position_set_.
IsSet(pos)) {
237 output_coeffs[pos] = v;
238 non_zero_position_set_.
Set(pos);
240 output_coeffs[pos] += v;
247 non_zero_position_list_.clear();
248 const Fractional drop_tolerance = parameters_.drop_tolerance();
249 for (
const ColIndex
col : non_zero_position_set_) {
254 if (std::abs(output_coeffs[
col]) > drop_tolerance) {
255 non_zero_position_list_.push_back(
col);
260 void UpdateRow::ComputeUpdatesForSingleRow(ColIndex row_as_col) {
262 non_zero_position_list_.clear();
265 const Fractional drop_tolerance = parameters_.drop_tolerance();
266 const Fractional multiplier = unit_row_left_inverse_[row_as_col];
267 const auto output_coeffs = coefficient_.
view();
268 const auto view = transposed_matrix_.
view();
269 for (
const EntryIndex i : view.Column(row_as_col)) {
271 if (!is_relevant[pos])
continue;
273 const Fractional v = multiplier * view.EntryCoefficient(i);
274 if (std::abs(v) > drop_tolerance) {
275 output_coeffs[pos] = v;
276 non_zero_position_list_.push_back(pos);
281 void UpdateRow::ComputeUpdatesColumnWise() {
285 non_zero_position_list_.clear();
287 const Fractional drop_tolerance = parameters_.drop_tolerance();
288 const auto output_coeffs = coefficient_.
view();
289 const auto view = matrix_.
view();
290 const auto unit_row_left_inverse = unit_row_left_inverse_.
values.
const_view();
294 view.ColumnScalarProduct(
col, unit_row_left_inverse);
300 if (std::abs(coeff) > drop_tolerance) {
301 non_zero_position_list_.push_back(
col);
302 output_coeffs[
col] = coeff;
312 CHECK_EQ(leaving_row, left_inverse_computed_for_);
314 const ColIndex num_cols = matrix_.
num_cols();
318 (*output)[basis_[leaving_row]] = 1.0;
321 const Fractional drop_tolerance = parameters_.drop_tolerance();
322 const auto view = matrix_.
view();
323 const auto unit_row_left_inverse = unit_row_left_inverse_.
values.
const_view();
326 view.ColumnScalarProduct(
col, unit_row_left_inverse);
327 if (std::abs(coeff) > drop_tolerance) {
328 (*output)[
col] = coeff;
void ClearAndResize(IndexType size)
void Intersection(const Bitset64< IndexType > &other)
bool IsSet(IndexType i) const
void LeftSolveForUnitRow(ColIndex j, ScatteredRow *y) const
void TemporaryLeftSolveForUnitRow(ColIndex j, ScatteredRow *y) const
ColIndex num_cols() const
RowIndex num_rows() const
Fractional ColumnScalarProduct(ColIndex col, const DenseRow &vector) const
void AssignToZero(IntType size)
void resize(IntType size)
ConstView const_view() const
const ScatteredRow & GetUnitRowLeftInverse() const
const ScatteredRow & ComputeAndGetUnitRowLeftInverse(RowIndex leaving_row)
const DenseRow & GetCoefficients() const
void ComputeUpdateRowForBenchmark(const DenseRow &lhs, const std::string &algorithm)
void ComputeUnitRowLeftInverse(RowIndex leaving_row)
UpdateRow(const CompactSparseMatrix &matrix, const CompactSparseMatrix &transposed_matrix, const VariablesInfo &variables_info, const RowToColMapping &basis, const BasisFactorization &basis_factorization)
void ComputeFullUpdateRow(RowIndex leaving_row, DenseRow *output) const
void ComputeUpdateRow(RowIndex leaving_row)
void SetParameters(const GlopParameters ¶meters)
const ColIndexVector & GetNonZeroPositions() const
EntryIndex GetNumEntriesInRelevantColumns() const
const DenseBitRow & GetNotBasicBitRow() const
const DenseBitRow & GetIsRelevantBitRow() const
std::vector< ColIndex > ColIndexVector
void ComputeNonZeros(const StrictITIVector< IndexType, Fractional > &input, std::vector< IndexType > *non_zeros)
double Density(const DenseRow &row)
ColIndex RowToColIndex(RowIndex row)
constexpr RowIndex kInvalidRow(-1)
Bitset64< ColIndex > DenseBitRow
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