40 : matrix(mat), size(mat.size()) {
50 std::vector<double> x(size, 1.0);
51 std::vector<double> y(size);
53 for (
int iter = 0; iter < max_iters; ++iter) {
55 for (
int i = 0; i < size; ++i) {
57 for (
int j = 0; j < size; ++j) {
58 y[i] += matrix[i][j] * x[j];
63 double max_element = 0.0;
64 for (
int i = 0; i < size; ++i) {
65 max_element = std::max(max_element, std::abs(y[i]));
69 for (
int i = 0; i < size; ++i) {
75 for (
int i = 0; i < size; ++i) {
76 error += std::abs(y[i] - x[i]);
79 if (error < tolerance) {
87 std::cerr <<
"Warning: Power iteration did not converge within the"
88 "specified iterations\n";
94 double tolerance)
const {
96 std::vector<std::vector<double>> hessenberg_mtx = matrix;
99 for (
int iter = 0; iter < max_iters; ++iter) {
101 for (
int i = 0; i < size - 1; ++i) {
103 double a = hessenberg_mtx[i][i];
104 double b = hessenberg_mtx[i + 1][i];
105 double r = std::hypot(a, b);
110 for (
int j = 0; j < size; ++j) {
112 c * hessenberg_mtx[i][j] + s * hessenberg_mtx[i + 1][j];
114 -s * hessenberg_mtx[i][j] + c * hessenberg_mtx[i + 1][j];
115 hessenberg_mtx[i][j] = temp1;
116 hessenberg_mtx[i + 1][j] = temp2;
121 double offDiagonalSum = 0.0;
122 for (
int i = 2; i < size; ++i) {
123 offDiagonalSum += std::abs(hessenberg_mtx[i][i - 1]);
126 if (offDiagonalSum < tolerance) {
128 std::vector<double> eigenvalues;
129 for (
int i = 0; i < size; ++i) {
130 eigenvalues.push_back(hessenberg_mtx[i][i]);
137 std::cerr <<
"Warning: QR iteration did not converge within the "
138 "specified iterations\n";
140 return std::vector<double>();
145 std::vector<double> eigenvalues = qr_algorithm();
146 double determinant = std::accumulate(eigenvalues.begin(),
149 std::multiplies<double>());
155 std::vector<double> originalEigenvalues = qr_algorithm();
157 std::vector<double> perturbedEigenvalues;
158 for (
int i = 0; i < size; ++i) {
160 std::vector<std::vector<double>> perturbedMatrix = matrix;
161 perturbedMatrix[i][i] += perturbation;
164 std::vector<double> perturbedVals =
166 perturbedEigenvalues.push_back(perturbedVals[i]);
171 std::vector<double> sensitivity;
172 for (
int i = 0; i < size; ++i) {
174 (perturbedEigenvalues[i] - originalEigenvalues[i]) / perturbation;
175 sensitivity.push_back(sens);
182 std::vector<std::vector<double>> &schurMatrix,
183 double tolerance)
const {
185 schurMatrix = matrix;
187 for (
int i = size - 1; i > 0; --i) {
189 if (std::abs(schurMatrix[i][i - 1]) < tolerance) {
190 schurMatrix[i][i - 1] = 0.0;
193 double a = schurMatrix[i - 1][i - 1];
194 double b = schurMatrix[i][i - 1];
195 double r = std::hypot(a, b);
199 for (
int j = 0; j < size; ++j) {
201 c * schurMatrix[i - 1][j] + s * schurMatrix[i][j];
203 -s * schurMatrix[i - 1][j] + c * schurMatrix[i][j];
204 schurMatrix[i - 1][j] = temp1;
205 schurMatrix[i][j] = temp2;
211 std::vector<std::vector<double>>
213 std::vector<std::vector<double>> jordanMatrix(
215 std::vector<double>(size, 0.0));
216 std::vector<double> eigenvalues = qr_algorithm();
218 for (
int i = 0; i < size; ++i) {
219 jordanMatrix[i][i] = eigenvalues[i];
222 int jordanBlockSize = 1;
223 while (i + jordanBlockSize < size &&
224 std::abs(matrix[i + jordanBlockSize][i]) < tolerance) {
229 for (
int j = 1; j < jordanBlockSize; ++j) {
230 jordanMatrix[i + j][i + j - 1] = 1.0;
238 double tolerance)
const {
240 std::vector<double> x(size, 1.0);
241 double lambdaPrev = 0.0;
243 for (
int iter = 0; iter < maxIterations; ++iter) {
245 std::vector<double> Ax(size, 0.0);
248 for (
int i = 0; i < size; ++i) {
249 for (
int j = 0; j < size; ++j) {
250 Ax[i] += matrix[i][j] * x[j];
256 std::inner_product(x.begin(), x.end(), Ax.begin(), 0.0) /
257 std::inner_product(x.begin(), x.end(), x.begin(), 0.0);
260 if (std::abs(lambda - lambdaPrev) < tolerance) {
265 double normAx = std::sqrt(
266 std::inner_product(Ax.begin(), Ax.end(), Ax.begin(), 0.0));
267 for (
int i = 0; i < size; ++i) {
269 x[i] = Ax[i] / normAx;
275 std::cerr <<
"Warning: Rayleigh quotient iteration did not converge within "
276 "the specified iterations."
Class for computing eigenvalues of a matrix.
void schur_decomp(std::vector< std::vector< double >> &schurMatrix, double tolerance=1e-10) const
Computes the Schur decomposition of a matrix.
std::vector< double > qr_algorithm(int max_iters=100, double tolerance=1e-10) const
Calculate all eigenvalues of the matrix using the QR algorithm.
double power_iter(int max_iters=100, double tolerance=1e-10) const
Perform the power iteration method to find the dominant eigenvalue.
double rayleigh_iter(int maxIterations, double tolerance) const
Perform Rayleigh Quotient Iteration to approximate the dominant eigenvalue.
std::vector< double > sensitivity(double perturbation) const
Calculates the sensitivity of the eigenvalues of a matrix to small perturbations.
std::vector< std::vector< double > > jordan_normal_form(double tolerance=1e-10) const
Computes the Jordan normal form of a matrix.
double determinant() const
Eigen(const std::vector< std::vector< double >> &mat)
Constructor for the Eigen class.