fix(math): preserve certified sums and complete MKL algebra
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/solvers/linear/mkl_pardiso_solver.h"
|
||||
#include "solvers/eigen/mkl_feast_eigen_solver_test_seam.h"
|
||||
#include "math/dense_blas_internal.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
@@ -1095,6 +1096,10 @@ Result<FeastEigenResult> MklFeastEigenSolver::SolveImpl(
|
||||
const double difference = action[row] - mu * mass_action[row];
|
||||
residual_norm += difference * difference;
|
||||
ordered_vectors(row, output) = vectors[row + input * n] / norm;
|
||||
if (!std::isfinite(ordered_vectors(row, output)))
|
||||
return Result<FeastEigenResult>::Failure(
|
||||
TraceFailure("eigenpair-validation-failed", std::to_string(input),
|
||||
"FEAST returned a non-normalizable eigenvector."));
|
||||
}
|
||||
double residual_denominator = norm;
|
||||
if (mass != nullptr) {
|
||||
@@ -1183,20 +1188,20 @@ Result<FeastEigenResult> MklFeastEigenSolver::SolveImpl(
|
||||
}
|
||||
double gram_error = 0.0;
|
||||
double gram_squared = 0.0;
|
||||
std::vector<Vector> mass_modes;
|
||||
mass_modes.reserve(count);
|
||||
Matrix mass_modes{n, count};
|
||||
for (std::size_t right = 0; right < count; ++right) {
|
||||
Vector mode(n);
|
||||
for (std::size_t row = 0; row < n; ++row)
|
||||
mode[row] = ordered_vectors(row, right);
|
||||
mass_modes.push_back(mass != nullptr ? mass->Multiply(mode)
|
||||
: std::move(mode));
|
||||
const auto action = mass != nullptr ? mass->Multiply(mode) : std::move(mode);
|
||||
for (std::size_t row = 0; row < n; ++row)
|
||||
mass_modes(row, right) = action[row];
|
||||
}
|
||||
const auto gram = dense_blas_internal::MultiplyTransposeLeft(ordered_vectors,
|
||||
mass_modes);
|
||||
for (std::size_t left = 0U; left < count; ++left) {
|
||||
for (std::size_t right = 0U; right < count; ++right) {
|
||||
double dot = 0.0;
|
||||
for (std::size_t row = 0U; row < n; ++row)
|
||||
dot += ordered_vectors(row, left) * mass_modes[right][row];
|
||||
const double dot = gram(left, right);
|
||||
const double expected = left == right ? 1.0 : 0.0;
|
||||
const double difference = std::abs(dot - expected);
|
||||
gram_squared += difference * difference;
|
||||
|
||||
Reference in New Issue
Block a user