SelectionRule.h
Go to the documentation of this file.
1 // Copyright (C) 2016-2019 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 SELECTION_RULE_H
8 #define SELECTION_RULE_H
9 
10 #include <vector> // std::vector
11 #include <cmath> // std::abs
12 #include <algorithm> // std::sort
13 #include <complex> // std::complex
14 #include <utility> // std::pair
15 #include <stdexcept> // std::invalid_argument
16 
17 namespace Spectra {
18 
24 
31 {
33 
38 
40 
42 
45 
48 
50 
52 
54 };
56 
63 {
64  WHICH_LM = 0,
73 };
74 
76 
77 // Get the element type of a "scalar"
78 // ElemType<double> => double
79 // ElemType< std::complex<double> > => double
80 template <typename T>
81 class ElemType
82 {
83 public:
84  typedef T type;
85 };
86 
87 template <typename T>
88 class ElemType<std::complex<T> >
89 {
90 public:
91  typedef T type;
92 };
93 
94 // When comparing eigenvalues, we first calculate the "target"
95 // to sort. For example, if we want to choose the eigenvalues with
96 // largest magnitude, the target will be -abs(x).
97 // The minus sign is due to the fact that std::sort() sorts in ascending order.
98 
99 // Default target: throw an exception
100 template <typename Scalar, int SelectionRule>
101 class SortingTarget
102 {
103 public:
104  static typename ElemType<Scalar>::type get(const Scalar& val)
105  {
106  using std::abs;
107  throw std::invalid_argument("incompatible selection rule");
108  return -abs(val);
109  }
110 };
111 
112 // Specialization for LARGEST_MAGN
113 // This covers [float, double, complex] x [LARGEST_MAGN]
114 template <typename Scalar>
115 class SortingTarget<Scalar, LARGEST_MAGN>
116 {
117 public:
118  static typename ElemType<Scalar>::type get(const Scalar& val)
119  {
120  using std::abs;
121  return -abs(val);
122  }
123 };
124 
125 // Specialization for LARGEST_REAL
126 // This covers [complex] x [LARGEST_REAL]
127 template <typename RealType>
128 class SortingTarget<std::complex<RealType>, LARGEST_REAL>
129 {
130 public:
131  static RealType get(const std::complex<RealType>& val)
132  {
133  return -val.real();
134  }
135 };
136 
137 // Specialization for LARGEST_IMAG
138 // This covers [complex] x [LARGEST_IMAG]
139 template <typename RealType>
140 class SortingTarget<std::complex<RealType>, LARGEST_IMAG>
141 {
142 public:
143  static RealType get(const std::complex<RealType>& val)
144  {
145  using std::abs;
146  return -abs(val.imag());
147  }
148 };
149 
150 // Specialization for LARGEST_ALGE
151 // This covers [float, double] x [LARGEST_ALGE]
152 template <typename Scalar>
153 class SortingTarget<Scalar, LARGEST_ALGE>
154 {
155 public:
156  static Scalar get(const Scalar& val)
157  {
158  return -val;
159  }
160 };
161 
162 // Here BOTH_ENDS is the same as LARGEST_ALGE, but
163 // we need some additional steps, which are done in
164 // SymEigsSolver.h => retrieve_ritzpair().
165 // There we move the smallest values to the proper locations.
166 template <typename Scalar>
167 class SortingTarget<Scalar, BOTH_ENDS>
168 {
169 public:
170  static Scalar get(const Scalar& val)
171  {
172  return -val;
173  }
174 };
175 
176 // Specialization for SMALLEST_MAGN
177 // This covers [float, double, complex] x [SMALLEST_MAGN]
178 template <typename Scalar>
179 class SortingTarget<Scalar, SMALLEST_MAGN>
180 {
181 public:
182  static typename ElemType<Scalar>::type get(const Scalar& val)
183  {
184  using std::abs;
185  return abs(val);
186  }
187 };
188 
189 // Specialization for SMALLEST_REAL
190 // This covers [complex] x [SMALLEST_REAL]
191 template <typename RealType>
192 class SortingTarget<std::complex<RealType>, SMALLEST_REAL>
193 {
194 public:
195  static RealType get(const std::complex<RealType>& val)
196  {
197  return val.real();
198  }
199 };
200 
201 // Specialization for SMALLEST_IMAG
202 // This covers [complex] x [SMALLEST_IMAG]
203 template <typename RealType>
204 class SortingTarget<std::complex<RealType>, SMALLEST_IMAG>
205 {
206 public:
207  static RealType get(const std::complex<RealType>& val)
208  {
209  using std::abs;
210  return abs(val.imag());
211  }
212 };
213 
214 // Specialization for SMALLEST_ALGE
215 // This covers [float, double] x [SMALLEST_ALGE]
216 template <typename Scalar>
217 class SortingTarget<Scalar, SMALLEST_ALGE>
218 {
219 public:
220  static Scalar get(const Scalar& val)
221  {
222  return val;
223  }
224 };
225 
226 // Sort eigenvalues and return the order index
227 template <typename PairType>
228 class PairComparator
229 {
230 public:
231  bool operator()(const PairType& v1, const PairType& v2)
232  {
233  return v1.first < v2.first;
234  }
235 };
236 
237 template <typename T, int SelectionRule>
238 class SortEigenvalue
239 {
240 private:
241  typedef typename ElemType<T>::type TargetType; // Type of the sorting target, will be
242  // a floating number type, e.g. "double"
243  typedef std::pair<TargetType, int> PairType; // Type of the sorting pair, including
244  // the sorting target and the index
245 
246  std::vector<PairType> pair_sort;
247 
248 public:
249  SortEigenvalue(const T* start, int size) :
250  pair_sort(size)
251  {
252  for (int i = 0; i < size; i++)
253  {
254  pair_sort[i].first = SortingTarget<T, SelectionRule>::get(start[i]);
255  pair_sort[i].second = i;
256  }
257  PairComparator<PairType> comp;
258  std::sort(pair_sort.begin(), pair_sort.end(), comp);
259  }
260 
261  std::vector<int> index()
262  {
263  std::vector<int> ind(pair_sort.size());
264  for (unsigned int i = 0; i < ind.size(); i++)
265  ind[i] = pair_sort[i].second;
266 
267  return ind;
268  }
269 };
270 
272 
273 } // namespace Spectra
274 
275 #endif // SELECTION_RULE_H
Alias for SMALLEST_IMAG
Definition: SelectionRule.h:70
SCALAR Scalar
Definition: bench_gemm.cpp:33
Vector v2
Vector v1
Select eigenvalues with smallest imaginary part (in magnitude). Only for general eigen solvers...
Definition: SelectionRule.h:49
Select eigenvalues with smallest algebraic value. Only for symmetric eigen solvers.
Definition: SelectionRule.h:51
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Alias for SMALLEST_MAGN
Definition: SelectionRule.h:68
Alias for SMALLEST_REAL
Definition: SelectionRule.h:69
Select eigenvalues with largest real part. Only for general eigen solvers.
Definition: SelectionRule.h:37
Alias for LARGEST_ALGE
Definition: SelectionRule.h:67
Select eigenvalues with smallest real part. Only for general eigen solvers.
Definition: SelectionRule.h:47
SELECT_EIGENVALUE_ALIAS
Definition: SelectionRule.h:62
Select eigenvalues with largest imaginary part (in magnitude). Only for general eigen solvers...
Definition: SelectionRule.h:39
Alias for LARGEST_REAL
Definition: SelectionRule.h:65
Alias for LARGEST_IMAG
Definition: SelectionRule.h:66
Alias for LARGEST_MAGN
Definition: SelectionRule.h:64
Alias for BOTH_ENDS
Definition: SelectionRule.h:72
Alias for SMALLEST_ALGE
Definition: SelectionRule.h:71
Container::iterator get(Container &c, Position position)
#define abs(x)
Definition: datatypes.h:17


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:54