10#ifndef EIGEN_CONDITIONESTIMATOR_H
11#define EIGEN_CONDITIONESTIMATOR_H
14#include "./InternalHeaderCheck.h"
20template <
typename Vector,
typename RealVector,
bool IsComplex>
21struct rcond_compute_sign {
23 const RealVector v_abs = v.cwiseAbs();
24 return (v_abs.array() ==
static_cast<typename Vector::RealScalar
>(0))
25 .select(Vector::Ones(v.size()), v.cwiseQuotient(v_abs));
30template <
typename Vector>
33 return (v.array() <
static_cast<typename Vector::RealScalar
>(0))
34 .select(-Vector::Ones(v.size()), Vector::Ones(v.size()));
58template <
typename Decomposition>
59typename Decomposition::RealScalar rcond_invmatrix_L1_norm_estimate(
const Decomposition& dec) {
60 typedef typename Decomposition::MatrixType MatrixType;
61 typedef typename Decomposition::Scalar Scalar;
62 typedef typename Decomposition::RealScalar RealScalar;
63 typedef typename internal::plain_col_type<MatrixType>::type
Vector;
64 typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVector;
65 const bool is_complex = (NumTraits<Scalar>::IsComplex != 0);
67 eigen_assert(dec.rows() == dec.cols());
68 const Index n = dec.rows();
72#ifdef __INTEL_COMPILER
74#pragma warning(disable : 2259)
76 Vector v = dec.solve(Vector::Ones(n) / Scalar(n));
77#ifdef __INTEL_COMPILER
85 RealScalar lower_bound = v.template lpNorm<1>();
86 if (n == 1)
return lower_bound;
91 RealScalar old_lower_bound = lower_bound;
94 Index v_max_abs_index = -1;
95 Index old_v_max_abs_index = v_max_abs_index;
96 for (
int k = 0; k < 4; ++k) {
97 sign_vector = internal::rcond_compute_sign<Vector, RealVector, is_complex>::run(v);
98 if (k > 0 && !is_complex && sign_vector == old_sign_vector) {
103 v = dec.adjoint().solve(sign_vector);
104 v.real().cwiseAbs().maxCoeff(&v_max_abs_index);
105 if (v_max_abs_index == old_v_max_abs_index) {
110 v = dec.solve(Vector::Unit(n, v_max_abs_index));
111 lower_bound = v.template lpNorm<1>();
112 if (lower_bound <= old_lower_bound) {
117 old_sign_vector = sign_vector;
119 old_v_max_abs_index = v_max_abs_index;
120 old_lower_bound = lower_bound;
132 Scalar alternating_sign(RealScalar(1));
133 for (
Index i = 0; i < n; ++i) {
135 v[i] = alternating_sign *
static_cast<RealScalar
>(RealScalar(1) + (RealScalar(i) / (RealScalar(n - 1))));
136 alternating_sign = -alternating_sign;
139 const RealScalar alternate_lower_bound = (2 * v.template lpNorm<1>()) / (3 * RealScalar(n));
140 return numext::maxi(lower_bound, alternate_lower_bound);
156template <
typename Decomposition>
157typename Decomposition::RealScalar rcond_estimate_helper(
typename Decomposition::RealScalar matrix_norm,
158 const Decomposition& dec) {
159 typedef typename Decomposition::RealScalar RealScalar;
160 eigen_assert(dec.rows() == dec.cols());
161 if (dec.rows() == 0)
return NumTraits<RealScalar>::infinity();
162 if (numext::is_exactly_zero(matrix_norm))
return RealScalar(0);
163 if (dec.rows() == 1)
return RealScalar(1);
164 const RealScalar inverse_matrix_norm = rcond_invmatrix_L1_norm_estimate(dec);
165 return (numext::is_exactly_zero(inverse_matrix_norm) ? RealScalar(0)
166 : (RealScalar(1) / inverse_matrix_norm) / matrix_norm);
Matrix< Type, Size, 1 > Vector
[c++11] SizeĆ1 vector of type Type.
Definition Matrix.h:522
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82