ARPACK-Armadillo
SelectionRule.h
Go to the documentation of this file.
1 // Copyright (C) 2015 Yixuan Qiu
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://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 
22 
27 {
28 
30 
35 
37 
39 
42 
45 
47 
49 
51 };
53 
58 {
59  WHICH_LM = 0,
68 };
69 
71 
72 // Get the element type of a "scalar"
73 // ElemType<double> => double
74 // ElemType< std::complex<double> > => double
75 template <typename T>
76 class ElemType
77 {
78 public:
79  typedef T type;
80 };
81 
82 template <typename T>
83 class ElemType< std::complex<T> >
84 {
85 public:
86  typedef T type;
87 };
88 
89 // When comparing eigenvalues, we first calculate the "target"
90 // to sort. For example, if we want to choose the eigenvalues with
91 // largest magnitude, the target will be -std::abs(x).
92 // The minus sign is due to the fact that std::sort() sorts in ascending order.
93 
94 // Default target: throw an exceptoin
95 template <typename Scalar, int SelectionRule>
96 class SortingTarget
97 {
98 public:
99  static typename ElemType<Scalar>::type get(const Scalar &val)
100  {
101  throw std::invalid_argument("incompatible selection rule");
102  return -std::abs(val);
103  }
104 };
105 
106 // Specialization for LARGEST_MAGN
107 // This covers [float, double, complex] x [LARGEST_MAGN]
108 template <typename Scalar>
109 class SortingTarget<Scalar, LARGEST_MAGN>
110 {
111 public:
112  static typename ElemType<Scalar>::type get(const Scalar &val)
113  {
114  return -std::abs(val);
115  }
116 };
117 
118 // Specialization for LARGEST_REAL
119 // This covers [complex] x [LARGEST_REAL]
120 template <typename RealType>
121 class SortingTarget<std::complex<RealType>, LARGEST_REAL>
122 {
123 public:
124  static RealType get(const std::complex<RealType> &val)
125  {
126  return -val.real();
127  }
128 };
129 
130 // Specialization for LARGEST_IMAG
131 // This covers [complex] x [LARGEST_IMAG]
132 template <typename RealType>
133 class SortingTarget<std::complex<RealType>, LARGEST_IMAG>
134 {
135 public:
136  static RealType get(const std::complex<RealType> &val)
137  {
138  return -std::abs(val.imag());
139  }
140 };
141 
142 // Specialization for LARGEST_ALGE
143 // This covers [float, double] x [LARGEST_ALGE]
144 template <typename Scalar>
145 class SortingTarget<Scalar, LARGEST_ALGE>
146 {
147 public:
148  static Scalar get(const Scalar &val)
149  {
150  return -val;
151  }
152 };
153 
154 // Here BOTH_ENDS is the same as LARGEST_ALGE, but
155 // we need some additional steps, which are done in
156 // SymEigsSolver.h => retrieve_ritzpair().
157 // There we move the smallest values to the proper locations.
158 template <typename Scalar>
159 class SortingTarget<Scalar, BOTH_ENDS>
160 {
161 public:
162  static Scalar get(const Scalar &val)
163  {
164  return -val;
165  }
166 };
167 
168 // Specialization for SMALLEST_MAGN
169 // This covers [float, double, complex] x [SMALLEST_MAGN]
170 template <typename Scalar>
171 class SortingTarget<Scalar, SMALLEST_MAGN>
172 {
173 public:
174  static typename ElemType<Scalar>::type get(const Scalar &val)
175  {
176  return std::abs(val);
177  }
178 };
179 
180 // Specialization for SMALLEST_REAL
181 // This covers [complex] x [SMALLEST_REAL]
182 template <typename RealType>
183 class SortingTarget<std::complex<RealType>, SMALLEST_REAL>
184 {
185 public:
186  static RealType get(const std::complex<RealType> &val)
187  {
188  return val.real();
189  }
190 };
191 
192 // Specialization for SMALLEST_IMAG
193 // This covers [complex] x [SMALLEST_IMAG]
194 template <typename RealType>
195 class SortingTarget<std::complex<RealType>, SMALLEST_IMAG>
196 {
197 public:
198  static RealType get(const std::complex<RealType> &val)
199  {
200  return std::abs(val.imag());
201  }
202 };
203 
204 // Specialization for SMALLEST_ALGE
205 // This covers [float, double] x [SMALLEST_ALGE]
206 template <typename Scalar>
207 class SortingTarget<Scalar, SMALLEST_ALGE>
208 {
209 public:
210  static Scalar get(const Scalar &val)
211  {
212  return val;
213  }
214 };
215 
216 // Sort eigenvalues and return the order index
217 template <typename PairType>
218 class PairComparator
219 {
220 public:
221  bool operator() (const PairType &v1, const PairType &v2)
222  {
223  return v1.first < v2.first;
224  }
225 };
226 
227 template <typename T, int SelectionRule>
228 class SortEigenvalue
229 {
230 private:
231  typedef typename ElemType<T>::type TargetType; // Type of the sorting target, will be
232  // a floating number type, e.g. "double"
233  typedef std::pair<TargetType, int> PairType; // Type of the sorting pair, including
234  // the sorting target and the index
235 
236  std::vector<PairType> pair_sort;
237 
238 public:
239  SortEigenvalue(const T* start, int size) :
240  pair_sort(size)
241  {
242  for(int i = 0; i < size; i++)
243  {
244  pair_sort[i].first = SortingTarget<T, SelectionRule>::get(start[i]);
245  pair_sort[i].second = i;
246  }
247  PairComparator<PairType> comp;
248  std::sort(pair_sort.begin(), pair_sort.end(), comp);
249  }
250 
251  std::vector<int> index()
252  {
253  std::vector<int> ind(pair_sort.size());
254  for(unsigned int i = 0; i < ind.size(); i++)
255  ind[i] = pair_sort[i].second;
256 
257  return ind;
258  }
259 };
260 
262 
263 #endif // SELECTION_RULE_H
Alias for LARGEST_ALGE
Definition: SelectionRule.h:62
Alias for LARGEST_REAL
Definition: SelectionRule.h:60
Alias for BOTH_ENDS
Definition: SelectionRule.h:67
Alias for SMALLEST_ALGE
Definition: SelectionRule.h:66
Select eigenvalues with smallest imaginary part (in magnitude). Only for general eigen solvers...
Definition: SelectionRule.h:46
Select eigenvalues with largest imaginary part (in magnitude). Only for general eigen solvers...
Definition: SelectionRule.h:36
Alias for SMALLEST_IMAG
Definition: SelectionRule.h:65
SELECT_EIGENVALUE
Definition: SelectionRule.h:26
Select eigenvalues with largest real part. Only for general eigen solvers.
Definition: SelectionRule.h:34
Alias for SMALLEST_MAGN
Definition: SelectionRule.h:63
Alias for SMALLEST_REAL
Definition: SelectionRule.h:64
Alias for LARGEST_MAGN
Definition: SelectionRule.h:59
SELECT_EIGENVALUE_ALIAS
Definition: SelectionRule.h:57
Select eigenvalues with smallest algebraic value. Only for symmetric eigen solvers.
Definition: SelectionRule.h:48
Select eigenvalues with smallest real part. Only for general eigen solvers.
Definition: SelectionRule.h:44
Alias for LARGEST_IMAG
Definition: SelectionRule.h:61