Spectra 1.1.0
Header-only C++ Library for Large Scale Eigenvalue Problems
Loading...
Searching...
No Matches
TypeTraits.h
1// Copyright (C) 2018-2025 Yixuan Qiu <yixuan.qiu@cos.name>
2//
3// This Source Code Form is subject to the terms of the Mozilla
4// Public License v. 2.0. If a copy of the MPL was not distributed
5// with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7#ifndef SPECTRA_TYPE_TRAITS_H
8#define SPECTRA_TYPE_TRAITS_H
9
10#include <Eigen/Core>
11#include <limits>
12
14
15// Clang-Format will have unintended effects:
16// static constexpr Scalar(min)()
17// So we turn it off here
18//
19// clang-format off
20
21namespace Spectra {
22
23// For a real value type "Scalar", we want to know its smallest
24// positive value, i.e., std::numeric_limits<Scalar>::min().
25// However, we must take non-standard value types into account,
26// so we rely on Eigen::NumTraits.
27//
28// Eigen::NumTraits has defined epsilon() and lowest(), but
29// lowest() means negative highest(), which is a very small
30// negative value.
31//
32// Therefore, we manually define this limit, and use eplison()^3
33// to mimic it for non-standard types.
34
35// Generic definition
36template <typename Scalar>
37struct TypeTraits
38{
39 static constexpr Scalar epsilon()
40 {
41 return Eigen::numext::numeric_limits<Scalar>::epsilon();
42 }
43 static constexpr Scalar (min)()
44 {
45 return epsilon() * epsilon() * epsilon();
46 }
47};
48
49// Full specialization
50template <>
51struct TypeTraits<float>
52{
53 static constexpr float epsilon()
54 {
55 return std::numeric_limits<float>::epsilon();
56 }
57 static constexpr float (min)()
58 {
59 return (std::numeric_limits<float>::min)();
60 }
61};
62
63template <>
64struct TypeTraits<double>
65{
66 static constexpr double epsilon()
67 {
68 return std::numeric_limits<double>::epsilon();
69 }
70 static constexpr double (min)()
71 {
72 return (std::numeric_limits<double>::min)();
73 }
74};
75
76template <>
77struct TypeTraits<long double>
78{
79 static constexpr long double epsilon()
80 {
81 return std::numeric_limits<long double>::epsilon();
82 }
83 static constexpr long double (min)()
84 {
85 return (std::numeric_limits<long double>::min)();
86 }
87};
88
89// Get the element type of a "scalar"
90// ElemType<double> => double
91// ElemType<std::complex<double>> => double
92template <typename T>
93using ElemType = typename Eigen::NumTraits<T>::Real;
94
95} // namespace Spectra
96
98
99#endif // SPECTRA_TYPE_TRAITS_H