OR-Tools  8.1
matrix_scaler.h
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 
14 // The SparseMatrixScaler class provides tools to scale a SparseMatrix, i.e.
15 // reduce the range of its coefficients and make for each column and each row
16 // the maximum magnitude of its coefficients equal to 1.
17 //
18 // In the case there are bounds or costs on the columns or a right-hand side
19 // related to each row, SparseMatrixScaler provides the tools to scale those
20 // appropriately.
21 //
22 // More precisely, suppose we have the Linear Program:
23 // min c.x
24 // s.t A.x = b
25 // with l <= x <= u
26 //
27 // The rows of A are scaled by left-multiplying it by a diagonal matrix R
28 // whose elements R_ii correspond to the scaling factor of row i.
29 // The columns of A are scaled by right-multiplying it by a diagonal matrix C
30 // whose elements C_jj correspond to the scaling factor of column j.
31 //
32 // We obtain a matrix A' = R.A.C.
33 //
34 // We wish to scale x, c, b, l, u so as to work on the scaled problem:
35 // min c'.x'
36 // s.t A'.x' = b'
37 // with l' <= x' <= u'
38 //
39 // The right-hand side b needs to be left-multiplied by R, the cost function c
40 // needs to be right-multiplied by C. Finally, x, and its lower- and upper-bound
41 // vectors l and u need to be left-multiplied by C^-1.
42 //
43 // Note also that the dual vector y is scaled as follows:
44 // y'.R = y, thus y' = y.R^-1.
45 //
46 // The complete transformation is thus:
47 // A' = R.A.C,
48 // b' = R.b,
49 // c' = c.C,
50 // x' = C^-1.x,
51 // l' = C^-1.l,
52 // u' = C^-1.u,
53 // y' = y.R^-1.
54 //
55 // The validity of the above transformation can be checked by computing:
56 // c'.x' = c.C.C^-1.x = c.x.
57 // and:
58 // A'.x' = R.A.C.C^-1.x = R.A.x = R.b = b'.
59 
60 #ifndef OR_TOOLS_LP_DATA_MATRIX_SCALER_H_
61 #define OR_TOOLS_LP_DATA_MATRIX_SCALER_H_
62 
63 #include <vector>
64 
66 #include "ortools/base/macros.h"
70 #include "ortools/glop/status.h"
73 
74 namespace operations_research {
75 namespace glop {
76 
77 class SparseMatrix;
78 
80  public:
82 
83  // Initializes the object with the SparseMatrix passed as argument.
84  // The row and column scaling factors are all set to 1.0 (i.e. no scaling.)
85  // In terms of matrices, R and C are set to identity matrices.
86  void Init(SparseMatrix* matrix);
87 
88  // Clears the object, and puts it back into the same state as after being
89  // constructed.
90  void Clear();
91 
92  // The column col of the matrix was multiplied by ColScalingFactor(col). The
93  // variable bounds and objective coefficient at the same columsn where DIVIDED
94  // by that same factor. If col is outside the matrix size, this returns 1.0.
95  Fractional ColScalingFactor(ColIndex col) const;
96 
97  // The constraint row of the matrix was multiplied by RowScalingFactor(row),
98  // same for the constraint bounds (which is not the same as for the variable
99  // bounds for a column!). If row is outside the matrix size, this returns 1.0.
100  Fractional RowScalingFactor(RowIndex row) const;
101 
102  // The inverse of both factor above (this is how we keep them) so this
103  // direction should be faster to query (no 1.0 / factor).
104  Fractional ColUnscalingFactor(ColIndex col) const;
105  Fractional RowUnscalingFactor(RowIndex row) const;
106 
107  // TODO(user): rename function and field to col_scales (and row_scales)
108  const DenseRow& col_scale() const { return col_scale_; }
109 
110  // Scales the matrix.
111  void Scale(GlopParameters::ScalingAlgorithm method);
112 
113  // Solves the scaling problem as a linear program.
114  Status LPScale();
115 
116  // Unscales the matrix.
117  void Unscale();
118 
119  // Scales a row vector up or down (depending whether parameter up is true or
120  // false) using the scaling factors determined by Scale().
121  // Scaling up means multiplying by the scaling factors, while scaling down
122  // means dividing by the scaling factors.
123  void ScaleRowVector(bool up, DenseRow* row_vector) const;
124 
125  // Scales a column vector up or down (depending whether parameter up is true
126  // or false) using the scaling factors determined by Scale().
127  // Scaling up means multiplying by the scaling factors, while scaling down
128  // means dividing by the scaling factors.
129  void ScaleColumnVector(bool up, DenseColumn* column_vector) const;
130 
131  // Computes the variance of the non-zero coefficients of the matrix.
132  // Used by Scale() do decide when to stop.
134 
135  // Scales the rows. Returns the number of rows that have been scaled.
136  // Helper function to Scale().
137  RowIndex ScaleRowsGeometrically();
138 
139  // Scales the columns. Returns the number of columns that have been scaled.
140  // Helper function to Scale().
141  ColIndex ScaleColumnsGeometrically();
142 
143  // Equilibrates the rows. Returns the number of rows that have been scaled.
144  // Helper function to Scale().
145  RowIndex EquilibrateRows();
146 
147  // Equilibrates the Columns. Returns the number of columns that have been
148  // scaled. Helper function to Scale().
149  ColIndex EquilibrateColumns();
150 
151  private:
152  // Convert the matrix to be scaled into a linear program.
153  void GenerateLinearProgram(LinearProgram*);
154 
155  // Scales the row indexed by row by 1/factor.
156  // Used by ScaleMatrixRowsGeometrically and EquilibrateRows.
157  RowIndex ScaleMatrixRows(const DenseColumn& factors);
158 
159  // Scales the column index by col by 1/factor.
160  // Used by ScaleColumnsGeometrically and EquilibrateColumns.
161  void ScaleMatrixColumn(ColIndex col, Fractional factor);
162 
163  // Looks up the index to the scale factor variable for this matrix row, in the
164  // LinearProgram, or creates it. Note lp_ must be initialized first.
165  ColIndex GetRowScaleIndex(RowIndex row_num);
166 
167  // As above, but for the columns of the matrix.
168  ColIndex GetColumnScaleIndex(ColIndex col_num);
169 
170  // Returns a string containing information on the progress of the scaling
171  // algorithm. This is not meant to be called in an optimized mode as it takes
172  // some time to compute the displayed quantities.
173  std::string DebugInformationString() const;
174 
175  // Pointer to the matrix to be scaled.
176  SparseMatrix* matrix_;
177 
178  // Member pointer for convenience, in particular for GetRowScaleIndex and
179  // GetColumnScaleIndex.
180  LinearProgram* lp_;
181 
182  // Array of scaling factors for each row. Indexed by row number.
183  DenseColumn row_scale_;
184 
185  // Array of scaling factors for each column. Indexed by column number.
186  DenseRow col_scale_;
187 
188  DISALLOW_COPY_AND_ASSIGN(SparseMatrixScaler);
189 };
190 
191 } // namespace glop
192 } // namespace operations_research
193 
194 #endif // OR_TOOLS_LP_DATA_MATRIX_SCALER_H_
operations_research::glop::SparseMatrixScaler::col_scale
const DenseRow & col_scale() const
Definition: matrix_scaler.h:108
integral_types.h
lp_data.h
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::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
macros.h
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
revised_simplex.h
operations_research::glop::Fractional
double Fractional
Definition: lp_types.h:77
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::SparseMatrixScaler::RowUnscalingFactor
Fractional RowUnscalingFactor(RowIndex row) const
Definition: matrix_scaler.cc:46
operations_research::glop::SparseMatrix
Definition: sparse.h:61
operations_research::glop::SparseMatrixScaler::Scale
void Scale(GlopParameters::ScalingAlgorithm method)
Definition: matrix_scaler.cc:89
operations_research::glop::StrictITIVector< ColIndex, Fractional >
operations_research::glop::SparseMatrixScaler::RowScalingFactor
Fractional RowScalingFactor(RowIndex row) const
Definition: matrix_scaler.cc:56
operations_research::glop::SparseMatrixScaler
Definition: matrix_scaler.h:79
operations_research::glop::SparseMatrixScaler::Init
void Init(SparseMatrix *matrix)
Definition: matrix_scaler.cc:33
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
operations_research::glop::SparseMatrixScaler::Clear
void Clear()
Definition: matrix_scaler.cc:40
col
ColIndex col
Definition: markowitz.cc:176
row
RowIndex row
Definition: markowitz.cc:175
operations_research::glop::LinearProgram
Definition: lp_data.h:55
operations_research::glop::SparseMatrixScaler::Unscale
void Unscale()
Definition: matrix_scaler.cc:341
operations_research::glop::SparseMatrixScaler::EquilibrateRows
RowIndex EquilibrateRows()
Definition: matrix_scaler.cc:267
operations_research::glop::SparseMatrixScaler::VarianceOfAbsoluteValueOfNonZeros
Fractional VarianceOfAbsoluteValueOfNonZeros() const
Definition: matrix_scaler.cc:181
strong_vector.h
lp_types.h
operations_research::glop::SparseMatrixScaler::SparseMatrixScaler
SparseMatrixScaler()
Definition: matrix_scaler.cc:30
status.h
parameters.pb.h