OR-Tools  8.1
matrix_scaler.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <algorithm>
17 #include <cmath>
18 #include <vector>
19 
20 #include "absl/strings/str_format.h"
21 #include "ortools/base/logging.h"
24 #include "ortools/lp_data/sparse.h"
26 
27 namespace operations_research {
28 namespace glop {
29 
31  : matrix_(nullptr), row_scale_(), col_scale_() {}
32 
34  DCHECK(matrix != nullptr);
35  matrix_ = matrix;
36  row_scale_.resize(matrix_->num_rows(), 1.0);
37  col_scale_.resize(matrix_->num_cols(), 1.0);
38 }
39 
41  matrix_ = nullptr;
42  row_scale_.clear();
43  col_scale_.clear();
44 }
45 
47  DCHECK_GE(row, 0);
48  return row < row_scale_.size() ? row_scale_[row] : 1.0;
49 }
50 
52  DCHECK_GE(col, 0);
53  return col < col_scale_.size() ? col_scale_[col] : 1.0;
54 }
55 
57  return 1.0 / RowUnscalingFactor(row);
58 }
59 
61  return 1.0 / ColUnscalingFactor(col);
62 }
63 
64 std::string SparseMatrixScaler::DebugInformationString() const {
65  // Note that some computations are redundant with the computations made in
66  // some callees, but we do not care as this function is supposed to be called
67  // with FLAGS_v set to 1.
68  DCHECK(!row_scale_.empty());
69  DCHECK(!col_scale_.empty());
70  Fractional max_magnitude;
71  Fractional min_magnitude;
72  matrix_->ComputeMinAndMaxMagnitudes(&min_magnitude, &max_magnitude);
73  const Fractional dynamic_range = max_magnitude / min_magnitude;
74  std::string output = absl::StrFormat(
75  "Min magnitude = %g, max magnitude = %g\n"
76  "Dynamic range = %g\n"
77  "Variance = %g\n"
78  "Minimum row scale = %g, maximum row scale = %g\n"
79  "Minimum col scale = %g, maximum col scale = %g\n",
80  min_magnitude, max_magnitude, dynamic_range,
82  *std::min_element(row_scale_.begin(), row_scale_.end()),
83  *std::max_element(row_scale_.begin(), row_scale_.end()),
84  *std::min_element(col_scale_.begin(), col_scale_.end()),
85  *std::max_element(col_scale_.begin(), col_scale_.end()));
86  return output;
87 }
88 
89 void SparseMatrixScaler::Scale(GlopParameters::ScalingAlgorithm method) {
90  // This is an implementation of the algorithm described in
91  // Benichou, M., Gauthier, J-M., Hentges, G., and Ribiere, G.,
92  // "The efficient solution of large-scale linear programming problems —
93  // some algorithmic techniques and computational results,"
94  // Mathematical Programming 13(3) (December 1977).
95  // http://www.springerlink.com/content/j3367676856m0064/
96  DCHECK(matrix_ != nullptr);
97  Fractional max_magnitude;
98  Fractional min_magnitude;
99  matrix_->ComputeMinAndMaxMagnitudes(&min_magnitude, &max_magnitude);
100  if (min_magnitude == 0.0) {
101  DCHECK_EQ(0.0, max_magnitude);
102  return; // Null matrix: nothing to do.
103  }
104  VLOG(1) << "Before scaling:\n" << DebugInformationString();
105  if (method == GlopParameters::LINEAR_PROGRAM) {
106  Status lp_status = LPScale();
107  // Revert to the default scaling method if there is an error with the LP.
108  if (lp_status.ok()) {
109  return;
110  } else {
111  VLOG(1) << "Error with LP scaling: " << lp_status.error_message();
112  }
113  }
114  // TODO(user): Decide precisely for which value of dynamic range we should cut
115  // off geometric scaling.
116  const Fractional dynamic_range = max_magnitude / min_magnitude;
117  const Fractional kMaxDynamicRangeForGeometricScaling = 1e20;
118  if (dynamic_range < kMaxDynamicRangeForGeometricScaling) {
119  const int kScalingIterations = 4;
120  const Fractional kVarianceThreshold(10.0);
121  for (int iteration = 0; iteration < kScalingIterations; ++iteration) {
122  const RowIndex num_rows_scaled = ScaleRowsGeometrically();
123  const ColIndex num_cols_scaled = ScaleColumnsGeometrically();
125  VLOG(1) << "Geometric scaling iteration " << iteration
126  << ". Rows scaled = " << num_rows_scaled
127  << ", columns scaled = " << num_cols_scaled << "\n";
128  VLOG(1) << DebugInformationString();
129  if (variance < kVarianceThreshold ||
130  (num_cols_scaled == 0 && num_rows_scaled == 0)) {
131  break;
132  }
133  }
134  }
135  RowIndex rows_equilibrated = EquilibrateRows();
136  ColIndex cols_equilibrated = EquilibrateColumns();
137  VLOG(1) << "Equilibration step: Rows scaled = " << rows_equilibrated
138  << ", columns scaled = " << cols_equilibrated << "\n";
139  VLOG(1) << DebugInformationString();
140 }
141 
142 namespace {
143 template <class I>
144 void ScaleVector(const absl::StrongVector<I, Fractional>& scale, bool up,
145  absl::StrongVector<I, Fractional>* vector_to_scale) {
146  RETURN_IF_NULL(vector_to_scale);
147  const I size(std::min(scale.size(), vector_to_scale->size()));
148  if (up) {
149  for (I i(0); i < size; ++i) {
150  (*vector_to_scale)[i] *= scale[i];
151  }
152  } else {
153  for (I i(0); i < size; ++i) {
154  (*vector_to_scale)[i] /= scale[i];
155  }
156  }
157 }
158 
159 template <typename InputIndexType>
160 ColIndex CreateOrGetScaleIndex(
161  InputIndexType num, LinearProgram* lp,
163  if ((*scale_var_indices)[num] == -1) {
164  (*scale_var_indices)[num] = lp->CreateNewVariable();
165  }
166  return (*scale_var_indices)[num];
167 }
168 } // anonymous namespace
169 
170 void SparseMatrixScaler::ScaleRowVector(bool up, DenseRow* row_vector) const {
171  DCHECK(row_vector != nullptr);
172  ScaleVector(col_scale_, up, row_vector);
173 }
174 
176  DenseColumn* column_vector) const {
177  DCHECK(column_vector != nullptr);
178  ScaleVector(row_scale_, up, column_vector);
179 }
180 
182  DCHECK(matrix_ != nullptr);
183  Fractional sigma_square(0.0);
184  Fractional sigma_abs(0.0);
185  double n = 0.0; // n is used in a calculation involving doubles.
186  const ColIndex num_cols = matrix_->num_cols();
187  for (ColIndex col(0); col < num_cols; ++col) {
188  for (const SparseColumn::Entry e : matrix_->column(col)) {
189  const Fractional magnitude = fabs(e.coefficient());
190  if (magnitude != 0.0) {
191  sigma_square += magnitude * magnitude;
192  sigma_abs += magnitude;
193  ++n;
194  }
195  }
196  }
197  if (n == 0.0) return 0.0;
198  // Since we know all the population (the non-zeros) and we are not using a
199  // sample, the variance is defined as below.
200  // For an explanation, see:
201  // http://en.wikipedia.org/wiki/Variance
202  // #Population_variance_and_sample_variance
203  return (sigma_square - sigma_abs * sigma_abs / n) / n;
204 }
205 
206 // For geometric scaling, we compute the maximum and minimum magnitudes
207 // of non-zeros in a row (resp. column). Let us denote these numbers as
208 // max and min. We then scale the row (resp. column) by dividing the
209 // coefficients by sqrt(min * max).
210 
212  DCHECK(matrix_ != nullptr);
213  DenseColumn max_in_row(matrix_->num_rows(), 0.0);
214  DenseColumn min_in_row(matrix_->num_rows(), kInfinity);
215  const ColIndex num_cols = matrix_->num_cols();
216  for (ColIndex col(0); col < num_cols; ++col) {
217  for (const SparseColumn::Entry e : matrix_->column(col)) {
218  const Fractional magnitude = fabs(e.coefficient());
219  const RowIndex row = e.row();
220  if (magnitude != 0.0) {
221  max_in_row[row] = std::max(max_in_row[row], magnitude);
222  min_in_row[row] = std::min(min_in_row[row], magnitude);
223  }
224  }
225  }
226  const RowIndex num_rows = matrix_->num_rows();
227  DenseColumn scaling_factor(num_rows, 0.0);
228  for (RowIndex row(0); row < num_rows; ++row) {
229  if (max_in_row[row] == 0.0) {
230  scaling_factor[row] = 1.0;
231  } else {
232  DCHECK_NE(kInfinity, min_in_row[row]);
233  scaling_factor[row] = sqrt(max_in_row[row] * min_in_row[row]);
234  }
235  }
236  return ScaleMatrixRows(scaling_factor);
237 }
238 
240  DCHECK(matrix_ != nullptr);
241  ColIndex num_cols_scaled(0);
242  const ColIndex num_cols = matrix_->num_cols();
243  for (ColIndex col(0); col < num_cols; ++col) {
244  Fractional max_in_col(0.0);
245  Fractional min_in_col(kInfinity);
246  for (const SparseColumn::Entry e : matrix_->column(col)) {
247  const Fractional magnitude = fabs(e.coefficient());
248  if (magnitude != 0.0) {
249  max_in_col = std::max(max_in_col, magnitude);
250  min_in_col = std::min(min_in_col, magnitude);
251  }
252  }
253  if (max_in_col != 0.0) {
254  const Fractional factor(sqrt(ToDouble(max_in_col * min_in_col)));
255  ScaleMatrixColumn(col, factor);
256  num_cols_scaled++;
257  }
258  }
259  return num_cols_scaled;
260 }
261 
262 // For equilibration, we compute the maximum magnitude of non-zeros
263 // in a row (resp. column), and then scale the row (resp. column) by dividing
264 // the coefficients this maximum magnitude.
265 // This brings the largest coefficient in a row equal to 1.0.
266 
268  DCHECK(matrix_ != nullptr);
269  const RowIndex num_rows = matrix_->num_rows();
270  DenseColumn max_magnitude(num_rows, 0.0);
271  const ColIndex num_cols = matrix_->num_cols();
272  for (ColIndex col(0); col < num_cols; ++col) {
273  for (const SparseColumn::Entry e : matrix_->column(col)) {
274  const Fractional magnitude = fabs(e.coefficient());
275  if (magnitude != 0.0) {
276  const RowIndex row = e.row();
277  max_magnitude[row] = std::max(max_magnitude[row], magnitude);
278  }
279  }
280  }
281  for (RowIndex row(0); row < num_rows; ++row) {
282  if (max_magnitude[row] == 0.0) {
283  max_magnitude[row] = 1.0;
284  }
285  }
286  return ScaleMatrixRows(max_magnitude);
287 }
288 
290  DCHECK(matrix_ != nullptr);
291  ColIndex num_cols_scaled(0);
292  const ColIndex num_cols = matrix_->num_cols();
293  for (ColIndex col(0); col < num_cols; ++col) {
294  const Fractional max_magnitude = InfinityNorm(matrix_->column(col));
295  if (max_magnitude != 0.0) {
296  ScaleMatrixColumn(col, max_magnitude);
297  num_cols_scaled++;
298  }
299  }
300  return num_cols_scaled;
301 }
302 
303 RowIndex SparseMatrixScaler::ScaleMatrixRows(const DenseColumn& factors) {
304  // Matrix rows are scaled by dividing their coefficients by factors[row].
305  DCHECK(matrix_ != nullptr);
306  const RowIndex num_rows = matrix_->num_rows();
307  DCHECK_EQ(num_rows, factors.size());
308  RowIndex num_rows_scaled(0);
309  for (RowIndex row(0); row < num_rows; ++row) {
310  const Fractional factor = factors[row];
311  DCHECK_NE(0.0, factor);
312  if (factor != 1.0) {
313  ++num_rows_scaled;
314  row_scale_[row] *= factor;
315  }
316  }
317 
318  const ColIndex num_cols = matrix_->num_cols();
319  for (ColIndex col(0); col < num_cols; ++col) {
320  SparseColumn* const column = matrix_->mutable_column(col);
321  if (column != nullptr) {
322  column->ComponentWiseDivide(factors);
323  }
324  }
325 
326  return num_rows_scaled;
327 }
328 
329 void SparseMatrixScaler::ScaleMatrixColumn(ColIndex col, Fractional factor) {
330  // A column is scaled by dividing by factor.
331  DCHECK(matrix_ != nullptr);
332  col_scale_[col] *= factor;
333  DCHECK_NE(0.0, factor);
334 
335  SparseColumn* const column = matrix_->mutable_column(col);
336  if (column != nullptr) {
337  column->DivideByConstant(factor);
338  }
339 }
340 
342  // Unscaling is easier than scaling since all scaling factors are stored.
343  DCHECK(matrix_ != nullptr);
344  const ColIndex num_cols = matrix_->num_cols();
345  for (ColIndex col(0); col < num_cols; ++col) {
346  const Fractional column_scale = col_scale_[col];
347  DCHECK_NE(0.0, column_scale);
348 
349  SparseColumn* const column = matrix_->mutable_column(col);
350  if (column != nullptr) {
351  column->MultiplyByConstant(column_scale);
352  column->ComponentWiseMultiply(row_scale_);
353  }
354  }
355 }
356 
358  DCHECK(matrix_ != nullptr);
359 
360  auto linear_program = absl::make_unique<LinearProgram>();
361  GlopParameters params;
362  auto simplex = absl::make_unique<RevisedSimplex>();
363  simplex->SetParameters(params);
364 
365  // Begin linear program construction.
366  // Beta represents the largest distance from zero among the constraint pairs.
367  // It resembles a slack variable because the 'objective' of each constraint is
368  // to cancel out the log "w" of the original nonzero |a_ij| (a.k.a. |a_rc|).
369  // Approaching 0 by addition in log space is the same as approaching 1 by
370  // multiplication in linear space. Hence, each variable's log magnitude is
371  // subtracted from the log row scale and log column scale. If the sum is
372  // positive, the positive constraint is trivially satisfied, but the negative
373  // constraint will determine the minimum necessary value of beta for that
374  // variable and scaling factors, and vice versa.
375  // For an MxN matrix, the resulting scaling LP has M+N+1 variables and
376  // O(M*N) constraints (2*M*N at maximum). As a result, using this LP to scale
377  // another linear program, will typically increase the time to
378  // optimization by a factor of 4, and has increased the time of some benchmark
379  // LPs by up to 10.
380 
381  // Indices to variables in the LinearProgram populated by
382  // GenerateLinearProgram.
383  absl::StrongVector<ColIndex, ColIndex> col_scale_var_indices;
384  absl::StrongVector<RowIndex, ColIndex> row_scale_var_indices;
385  row_scale_var_indices.resize(RowToIntIndex(matrix_->num_rows()), kInvalidCol);
386  col_scale_var_indices.resize(ColToIntIndex(matrix_->num_cols()), kInvalidCol);
387  const ColIndex beta = linear_program->CreateNewVariable();
388  linear_program->SetVariableBounds(beta, -kInfinity, kInfinity);
389  // Default objective is to minimize.
390  linear_program->SetObjectiveCoefficient(beta, 1);
391  matrix_->CleanUp();
392  const ColIndex num_cols = matrix_->num_cols();
393  for (ColIndex col(0); col < num_cols; ++col) {
394  SparseColumn* const column = matrix_->mutable_column(col);
395  // This is the variable representing the log of the scale factor for col.
396  const ColIndex column_scale = CreateOrGetScaleIndex<ColIndex>(
397  col, linear_program.get(), &col_scale_var_indices);
398  linear_program->SetVariableBounds(column_scale, -kInfinity, kInfinity);
399  for (EntryIndex i : column->AllEntryIndices()) {
400  const Fractional log_magnitude =
401  log2(std::abs(column->EntryCoefficient(i)));
402  const RowIndex row = column->EntryRow(i);
403  // This is the variable representing the log of the scale factor for row.
404  const ColIndex row_scale = CreateOrGetScaleIndex<RowIndex>(
405  row, linear_program.get(), &row_scale_var_indices);
406 
407  linear_program->SetVariableBounds(row_scale, -kInfinity, kInfinity);
408  // This is derived from the formulation in
409  // min β
410  // Subject to:
411  // ∀ c∈C, v∈V, p_{c,v} ≠ 0.0, w_{c,v} + s^{var}_v + s^{comb}_c + β ≥ 0.0
412  // ∀ c∈C, v∈V, p_{c,v} ≠ 0.0, w_{c,v} + s^{var}_v + s^{comb}_c ≤ β
413  // If a variable is integer, its scale factor is zero.
414 
415  // Start with the constraint w_cv + s_c + s_v + beta >= 0.
416  const RowIndex positive_constraint =
417  linear_program->CreateNewConstraint();
418  // Subtract the constant w_cv from both sides.
419  linear_program->SetConstraintBounds(positive_constraint, -log_magnitude,
420  kInfinity);
421  // +s_c, meaning (log) scale of the constraint C, pointed by row_scale.
422  linear_program->SetCoefficient(positive_constraint, row_scale, 1);
423  // +s_v, meaning (log) scale of the variable V, pointed by column_scale.
424  linear_program->SetCoefficient(positive_constraint, column_scale, 1);
425  // +beta
426  linear_program->SetCoefficient(positive_constraint, beta, 1);
427 
428  // Construct the constraint w_cv + s_c + s_v <= beta.
429  const RowIndex negative_constraint =
430  linear_program->CreateNewConstraint();
431  // Subtract w (and beta) from both sides.
432  linear_program->SetConstraintBounds(negative_constraint, -kInfinity,
433  -log_magnitude);
434  // +s_c, meaning (log) scale of the constraint C, pointed by row_scale.
435  linear_program->SetCoefficient(negative_constraint, row_scale, 1);
436  // +s_v, meaning (log) scale of the variable V, pointed by column_scale.
437  linear_program->SetCoefficient(negative_constraint, column_scale, 1);
438  // -beta
439  linear_program->SetCoefficient(negative_constraint, beta, -1);
440  }
441  }
442  // End linear program construction.
443 
444  linear_program->AddSlackVariablesWhereNecessary(false);
445  const Status simplex_status =
446  simplex->Solve(*linear_program, TimeLimit::Infinite().get());
447  if (!simplex_status.ok()) {
448  return simplex_status;
449  } else {
450  // Now the solution variables can be interpreted and translated from log
451  // space.
452  // For each row scale, unlog it and scale the constraints and constraint
453  // bounds.
454  const ColIndex num_cols = matrix_->num_cols();
455  for (ColIndex col(0); col < num_cols; ++col) {
456  const Fractional column_scale =
457  exp2(-simplex->GetVariableValue(CreateOrGetScaleIndex<ColIndex>(
458  col, linear_program.get(), &col_scale_var_indices)));
459  ScaleMatrixColumn(col, column_scale);
460  }
461  const RowIndex num_rows = matrix_->num_rows();
462  DenseColumn row_scale(num_rows, 0.0);
463  for (RowIndex row(0); row < num_rows; ++row) {
464  row_scale[row] =
465  exp2(-simplex->GetVariableValue(CreateOrGetScaleIndex<RowIndex>(
466  row, linear_program.get(), &row_scale_var_indices)));
467  }
468  ScaleMatrixRows(row_scale);
469  return Status::OK();
470  }
471 }
472 
473 } // namespace glop
474 } // namespace operations_research
absl::StrongVector::end
iterator end()
Definition: strong_vector.h:140
operations_research::glop::StrictITIVector::resize
void resize(IntType size)
Definition: lp_types.h:269
min
int64 min
Definition: alldiff_cst.cc:138
VLOG
#define VLOG(verboselevel)
Definition: base/logging.h:978
max
int64 max
Definition: alldiff_cst.cc:139
time_limit.h
operations_research::glop::SparseVector::ComponentWiseMultiply
void ComponentWiseMultiply(const DenseVector &factors)
Definition: sparse_vector.h:770
operations_research::glop::SparseVector::DivideByConstant
void DivideByConstant(Fractional factor)
Definition: sparse_vector.h:778
operations_research::glop::kInvalidCol
const ColIndex kInvalidCol(-1)
absl::StrongVector::size
size_type size() const
Definition: strong_vector.h:147
operations_research::glop::SparseMatrixScaler::ColUnscalingFactor
Fractional ColUnscalingFactor(ColIndex col) const
Definition: matrix_scaler.cc:51
operations_research::glop::SparseMatrixScaler::ScaleColumnVector
void ScaleColumnVector(bool up, DenseColumn *column_vector) const
Definition: matrix_scaler.cc:175
operations_research::glop::ColToIntIndex
Index ColToIntIndex(ColIndex col)
Definition: lp_types.h:54
logging.h
operations_research::glop::SparseMatrixScaler::ScaleColumnsGeometrically
ColIndex ScaleColumnsGeometrically()
Definition: matrix_scaler.cc:239
operations_research::glop::SparseMatrixScaler::ScaleRowVector
void ScaleRowVector(bool up, DenseRow *row_vector) const
Definition: matrix_scaler.cc:170
operations_research::glop::Status
Definition: status.h:24
lp_utils.h
operations_research::glop::InfinityNorm
Fractional InfinityNorm(const DenseColumn &v)
Definition: lp_data/lp_utils.cc:81
operations_research::glop::StrictITIVector::size
IntType size() const
Definition: lp_types.h:276
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::glop::ToDouble
static double ToDouble(double f)
Definition: lp_types.h:68
operations_research::glop::Status::OK
static const Status OK()
Definition: status.h:54
operations_research::glop::SparseColumn
Definition: sparse_column.h:44
matrix_scaler.h
operations_research::glop::SparseColumn::EntryRow
RowIndex EntryRow(EntryIndex i) const
Definition: sparse_column.h:51
RETURN_IF_NULL
#define RETURN_IF_NULL(x)
Definition: return_macros.h:20
revised_simplex.h
operations_research::glop::Fractional
double Fractional
Definition: lp_types.h:77
DCHECK_NE
#define DCHECK_NE(val1, val2)
Definition: base/logging.h:886
operations_research::glop::SparseMatrixScaler::EquilibrateColumns
ColIndex EquilibrateColumns()
Definition: matrix_scaler.cc:289
operations_research::glop::SparseMatrixScaler::LPScale
Status LPScale()
Definition: matrix_scaler.cc:357
operations_research::glop::kInfinity
const double kInfinity
Definition: lp_types.h:83
operations_research::glop::SparseMatrix::num_cols
ColIndex num_cols() const
Definition: sparse.h:177
operations_research::glop::SparseColumn::EntryCoefficient
Fractional EntryCoefficient(EntryIndex i) const
Definition: sparse_column.h:52
operations_research::glop::SparseMatrixScaler::RowUnscalingFactor
Fractional RowUnscalingFactor(RowIndex row) const
Definition: matrix_scaler.cc:46
operations_research::glop::SparseMatrix::CleanUp
void CleanUp()
Definition: sparse.cc:119
operations_research::glop::SparseMatrix
Definition: sparse.h:61
operations_research::glop::SparseMatrix::mutable_column
SparseColumn * mutable_column(ColIndex col)
Definition: sparse.h:181
operations_research::glop::SparseMatrixScaler::Scale
void Scale(GlopParameters::ScalingAlgorithm method)
Definition: matrix_scaler.cc:89
operations_research::glop::SparseMatrix::num_rows
RowIndex num_rows() const
Definition: sparse.h:176
operations_research::glop::StrictITIVector< ColIndex, Fractional >
absl::StrongVector::begin
iterator begin()
Definition: strong_vector.h:138
operations_research::glop::SparseMatrixScaler::RowScalingFactor
Fractional RowScalingFactor(RowIndex row) const
Definition: matrix_scaler.cc:56
DCHECK
#define DCHECK(condition)
Definition: base/logging.h:884
operations_research::glop::SparseMatrix::column
const SparseColumn & column(ColIndex col) const
Definition: sparse.h:180
operations_research::glop::SparseMatrixScaler::Init
void Init(SparseMatrix *matrix)
Definition: matrix_scaler.cc:33
operations_research::glop::SparseVector< RowIndex, SparseColumnIterator >::Entry
typename Iterator::Entry Entry
Definition: sparse_vector.h:91
operations_research::glop::SparseMatrixScaler::ColScalingFactor
Fractional ColScalingFactor(ColIndex col) const
Definition: matrix_scaler.cc:60
operations_research::glop::SparseMatrixScaler::ScaleRowsGeometrically
RowIndex ScaleRowsGeometrically()
Definition: matrix_scaler.cc:211
DCHECK_GE
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:889
absl::StrongVector::clear
void clear()
Definition: strong_vector.h:170
operations_research::glop::Status::error_message
const std::string & error_message() const
Definition: status.h:58
absl::StrongVector
Definition: strong_vector.h:76
operations_research::glop::SparseMatrixScaler::Clear
void Clear()
Definition: matrix_scaler.cc:40
col
ColIndex col
Definition: markowitz.cc:176
operations_research::glop::RowToIntIndex
Index RowToIntIndex(RowIndex row)
Definition: lp_types.h:57
row
RowIndex row
Definition: markowitz.cc:175
operations_research::glop::SparseMatrix::ComputeMinAndMaxMagnitudes
void ComputeMinAndMaxMagnitudes(Fractional *min_magnitude, Fractional *max_magnitude) const
Definition: sparse.cc:369
operations_research::glop::SparseMatrixScaler::Unscale
void Unscale()
Definition: matrix_scaler.cc:341
operations_research::glop::SparseMatrixScaler::EquilibrateRows
RowIndex EquilibrateRows()
Definition: matrix_scaler.cc:267
DCHECK_EQ
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:885
operations_research::glop::SparseMatrixScaler::VarianceOfAbsoluteValueOfNonZeros
Fractional VarianceOfAbsoluteValueOfNonZeros() const
Definition: matrix_scaler.cc:181
absl::StrongVector::resize
void resize(size_type new_size)
Definition: strong_vector.h:150
operations_research::TimeLimit::Infinite
static std::unique_ptr< TimeLimit > Infinite()
Creates a time limit object that uses infinite time for wall time, deterministic time and instruction...
Definition: time_limit.h:134
operations_research::glop::SparseVector::ComponentWiseDivide
void ComponentWiseDivide(const DenseVector &factors)
Definition: sparse_vector.h:786
operations_research::glop::SparseVector::AllEntryIndices
::util::IntegerRange< EntryIndex > AllEntryIndices() const
Definition: sparse_vector.h:302
absl::StrongVector::empty
bool empty() const
Definition: strong_vector.h:156
operations_research::glop::SparseVector::MultiplyByConstant
void MultiplyByConstant(Fractional factor)
Definition: sparse_vector.h:762
operations_research::glop::SparseMatrixScaler::SparseMatrixScaler
SparseMatrixScaler()
Definition: matrix_scaler.cc:30
sparse.h
operations_research::glop::Status::ok
bool ok() const
Definition: status.h:59