Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
matrix_scaler.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 <string>
64#include <vector>
65
66#include "ortools/base/types.h"
67#include "ortools/glop/parameters.pb.h"
69#include "ortools/glop/status.h"
72
73namespace operations_research {
74namespace glop {
75
77 public:
79
80 // This type is neither copyable nor movable.
83
84 // Initializes the object with the SparseMatrix passed as argument.
85 // The row and column scaling factors are all set to 1.0 (i.e. no scaling.)
86 // In terms of matrices, R and C are set to identity matrices.
87 void Init(SparseMatrix* matrix);
88
89 // Clears the object, and puts it back into the same state as after being
90 // constructed.
91 void Clear();
92
93 // The column col of the matrix was multiplied by ColScalingFactor(col). The
94 // variable bounds and objective coefficient at the same columsn where DIVIDED
95 // by that same factor. If col is outside the matrix size, this returns 1.0.
96 Fractional ColScalingFactor(ColIndex col) const;
97
98 // The constraint row of the matrix was multiplied by RowScalingFactor(row),
99 // same for the constraint bounds (which is not the same as for the variable
100 // bounds for a column!). If row is outside the matrix size, this returns 1.0.
101 Fractional RowScalingFactor(RowIndex row) const;
102
103 // The inverse of both factor above (this is how we keep them) so this
104 // direction should be faster to query (no 1.0 / factor).
105 Fractional ColUnscalingFactor(ColIndex col) const;
106 Fractional RowUnscalingFactor(RowIndex row) const;
107
108 // These are unscaling factor, same as [Col|Row]UnscalingFactor().
109 const DenseRow& col_scales() const { return col_scales_; }
110 const DenseColumn& row_scales() const { return row_scales_; }
111
112 // Scales the matrix.
113 void Scale(GlopParameters::ScalingAlgorithm method);
114
115 // Scales a row vector up or down (depending whether parameter up is true or
116 // false) using the scaling factors determined by Scale().
117 // Scaling up means multiplying by the scaling factors, while scaling down
118 // means dividing by the scaling factors.
119 void ScaleRowVector(bool up, DenseRow* row_vector) const;
120
121 // Scales a column vector up or down (depending whether parameter up is true
122 // or false) using the scaling factors determined by Scale().
123 // Scaling up means multiplying by the scaling factors, while scaling down
124 // means dividing by the scaling factors.
125 void ScaleColumnVector(bool up, DenseColumn* column_vector) const;
126
127 private:
128 // Solves the scaling problem as a linear program.
129 Status LPScale();
130
131 // Computes the variance of the non-zero coefficients of the matrix.
132 // Used by Scale() do decide when to stop.
133 Fractional VarianceOfAbsoluteValueOfNonZeros() const;
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 // Scales the row indexed by row by 1/factor.
152 // Used by ScaleMatrixRowsGeometrically and EquilibrateRows.
153 RowIndex ScaleMatrixRows(const DenseColumn& factors);
154
155 // Scales the column index by col by 1/factor.
156 // Used by ScaleColumnsGeometrically and EquilibrateColumns.
157 void ScaleMatrixColumn(ColIndex col, Fractional factor);
158
159 // Returns a string containing information on the progress of the scaling
160 // algorithm. This is not meant to be called in an optimized mode as it takes
161 // some time to compute the displayed quantities.
162 std::string DebugInformationString() const;
163
164 // Pointer to the matrix to be scaled.
165 SparseMatrix* matrix_;
166
167 // Array of scaling factors for each row. Indexed by row number.
168 DenseColumn row_scales_;
169
170 // Array of scaling factors for each column. Indexed by column number.
171 DenseRow col_scales_;
172};
173
174} // namespace glop
175} // namespace operations_research
176
177#endif // OR_TOOLS_LP_DATA_MATRIX_SCALER_H_
const DenseRow & col_scales() const
These are unscaling factor, same as [Col|Row]UnscalingFactor().
void ScaleColumnVector(bool up, DenseColumn *column_vector) const
SparseMatrixScaler(const SparseMatrixScaler &)=delete
This type is neither copyable nor movable.
SparseMatrixScaler & operator=(const SparseMatrixScaler &)=delete
Fractional RowScalingFactor(RowIndex row) const
void ScaleRowVector(bool up, DenseRow *row_vector) const
Fractional ColScalingFactor(ColIndex col) const
Fractional RowUnscalingFactor(RowIndex row) const
void Scale(GlopParameters::ScalingAlgorithm method)
Scales the matrix.
Fractional ColUnscalingFactor(ColIndex col) const
ColIndex col
Definition markowitz.cc:187
RowIndex row
Definition markowitz.cc:186
In SWIG mode, we don't want anything besides these top-level includes.