7 #ifndef SPECTRA_SELECTION_RULE_H
8 #define SPECTRA_SELECTION_RULE_H
18 #include "TypeTraits.h"
68 template <
typename Scalar, SortRule Rule>
72 static ElemType<Scalar> get(
const Scalar& val)
75 throw std::invalid_argument(
"incompatible selection rule");
82 template <
typename Scalar>
86 static ElemType<Scalar> get(
const Scalar& val)
95 template <
typename RealType>
99 static RealType get(
const std::complex<RealType>& val)
107 template <
typename RealType>
111 static RealType get(
const std::complex<RealType>& val)
114 return -abs(val.imag());
120 template <
typename Scalar>
124 static Scalar get(
const Scalar& val)
134 template <
typename Scalar>
138 static Scalar get(
const Scalar& val)
146 template <
typename Scalar>
150 static ElemType<Scalar> get(
const Scalar& val)
159 template <
typename RealType>
163 static RealType get(
const std::complex<RealType>& val)
171 template <
typename RealType>
175 static RealType get(
const std::complex<RealType>& val)
178 return abs(val.imag());
184 template <
typename Scalar>
188 static Scalar get(
const Scalar& val)
195 template <
typename T, SortRule Rule>
199 using Index = Eigen::Index;
200 using IndexArray = std::vector<Index>;
207 inline bool operator()(Index i, Index j)
209 return SortingTarget<T, Rule>::get(m_evals[i]) < SortingTarget<T, Rule>::get(m_evals[j]);
212 SortEigenvalue(
const T* start, Index size) :
213 m_evals(start), m_index(size)
215 for (Index i = 0; i < size; i++)
219 std::sort(m_index.begin(), m_index.end(), *
this);
222 inline IndexArray index()
const {
return m_index; }
223 inline void swap(IndexArray& other) { m_index.swap(other); }
227 template <
typename Scalar>
228 std::vector<Eigen::Index> argsort(
SortRule selection,
const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& values, Eigen::Index len)
230 using Index = Eigen::Index;
233 std::vector<Index> ind;
238 SortEigenvalue<Scalar, SortRule::LargestMagn> sorting(values.data(), len);
245 SortEigenvalue<Scalar, SortRule::LargestAlge> sorting(values.data(), len);
251 SortEigenvalue<Scalar, SortRule::SmallestMagn> sorting(values.data(), len);
257 SortEigenvalue<Scalar, SortRule::SmallestAlge> sorting(values.data(), len);
262 throw std::invalid_argument(
"unsupported selection rule");
274 std::vector<Index> ind_copy(ind);
275 for (Index i = 0; i < len; i++)
280 ind[i] = ind_copy[i / 2];
282 ind[i] = ind_copy[len - 1 - i / 2];
290 template <
typename Scalar>
291 std::vector<Eigen::Index> argsort(
SortRule selection,
const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& values)
293 return argsort<Scalar>(selection, values, values.size());
@ SmallestImag
Select eigenvalues with smallest imaginary part (in magnitude). Only for general eigen solvers.
@ SmallestAlge
Select eigenvalues with smallest algebraic value. Only for symmetric eigen solvers.
@ SmallestReal
Select eigenvalues with smallest real part. Only for general eigen solvers.
@ LargestImag
Select eigenvalues with largest imaginary part (in magnitude). Only for general eigen solvers.
@ LargestReal
Select eigenvalues with largest real part. Only for general eigen solvers.