Eigen  5.0.1
 
Loading...
Searching...
No Matches
Scaling.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_ITERSCALING_H
12#define EIGEN_ITERSCALING_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
51template <typename MatrixType_>
52class IterScaling {
53 public:
54 using MatrixType = MatrixType_;
55 using Scalar = typename MatrixType::Scalar;
56 using Index = typename MatrixType::Index;
57
58 IterScaling() { init(); }
59
60 IterScaling(const MatrixType& matrix) {
61 init();
62 compute(matrix);
63 }
64
72 void compute(const MatrixType& mat) {
73 using std::abs;
74 int m = mat.rows();
75 int n = mat.cols();
76 eigen_assert((m > 0 && m == n) && "Please give a non - empty matrix");
77 m_left.resize(m);
78 m_right.resize(n);
79 m_left.setOnes();
80 m_right.setOnes();
81 m_matrix = mat;
82 // Temporary left and right scaling vectors
83 VectorXd Dr(m), Dc(n), DrRes(m), DcRes(n);
84 double EpsRow = 1.0, EpsCol = 1.0;
85 int its = 0;
86 do { // Iterate until the infinite norm of each row and column is approximately 1
87 // Get the maximum value in each row and column
88 Dr.setZero();
89 Dc.setZero();
90 for (int k = 0; k < m_matrix.outerSize(); ++k) {
91 for (typename MatrixType::InnerIterator it(m_matrix, k); it; ++it) {
92 if (Dr(it.row()) < abs(it.value())) Dr(it.row()) = abs(it.value());
93
94 if (Dc(it.col()) < abs(it.value())) Dc(it.col()) = abs(it.value());
95 }
96 }
97 for (int i = 0; i < m; ++i) {
98 Dr(i) = numext::sqrt(Dr(i));
99 }
100 for (int i = 0; i < n; ++i) {
101 Dc(i) = numext::sqrt(Dc(i));
102 }
103 // Save the scaling factors
104 for (int i = 0; i < m; ++i) {
105 m_left(i) /= Dr(i);
106 }
107 for (int i = 0; i < n; ++i) {
108 m_right(i) /= Dc(i);
109 }
110 // Scale the rows and the columns of the matrix
111 DrRes.setZero();
112 DcRes.setZero();
113 for (int k = 0; k < m_matrix.outerSize(); ++k) {
114 for (typename MatrixType::InnerIterator it(m_matrix, k); it; ++it) {
115 it.valueRef() = it.value() / (Dr(it.row()) * Dc(it.col()));
116 // Accumulate the norms of the row and column vectors
117 if (DrRes(it.row()) < abs(it.value())) DrRes(it.row()) = abs(it.value());
118
119 if (DcRes(it.col()) < abs(it.value())) DcRes(it.col()) = abs(it.value());
120 }
121 }
122 DrRes.array() = (1 - DrRes.array()).abs();
123 EpsRow = DrRes.maxCoeff();
124 DcRes.array() = (1 - DcRes.array()).abs();
125 EpsCol = DcRes.maxCoeff();
126 its++;
127 } while ((EpsRow > m_tol || EpsCol > m_tol) && (its < m_maxits));
128 m_isInitialized = true;
129 }
130
135 void computeRef(MatrixType& mat) {
136 compute(mat);
137 mat = m_matrix;
138 }
139
141 VectorXd& LeftScaling() { return m_left; }
142
145 VectorXd& RightScaling() { return m_right; }
146
149 void setTolerance(double tol) { m_tol = tol; }
150
151 protected:
152 void init() {
153 m_tol = 1e-10;
154 m_maxits = 5;
155 m_isInitialized = false;
156 }
157
158 MatrixType m_matrix;
159 bool m_isInitialized;
160 VectorXd m_left; // Left scaling vector
161 VectorXd m_right; // Right scaling vector
162 double m_tol;
163 int m_maxits; // Maximum number of iterations allowed
164};
165} // namespace Eigen
166#endif
void setTolerance(double tol)
Definition Scaling.h:149
void compute(const MatrixType &mat)
Definition Scaling.h:72
VectorXd & LeftScaling()
Definition Scaling.h:141
void computeRef(MatrixType &mat)
Definition Scaling.h:135
VectorXd & RightScaling()
Definition Scaling.h:145
Derived & setZero(Index size)
Definition CwiseNullaryOp.h:536
Matrix< double, Dynamic, 1 > VectorXd
DynamicĂ—1 vector of type double.
Definition Matrix.h:489