<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
iamax.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2017-2021, University of Tennessee. All rights reserved.
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_BLAS_IAMAX_HH
12#define TLAPACK_BLAS_IAMAX_HH
13
15
16namespace tlapack {
17
36template <class abs_f>
37struct IamaxOpts : public EcOpts {
38 constexpr IamaxOpts(abs_f absf, const EcOpts& opts = {})
39 : EcOpts(opts), absf(absf){};
40
43};
44
67template <TLAPACK_VECTOR vector_t, class abs_f>
69{
70 // data traits
71 using idx_t = size_type<vector_t>;
72 using T = type_t<vector_t>;
73 using real_t = real_type<T>;
74
75 // constants
76 const real_t oneFourth(0.25);
77 const idx_t n = size(x);
78
79 // quick return
80 if (n <= 0) return 0;
81
82 bool scaledsmax = false; // indicates whether |x_i| = Inf
83 real_t smax(-1);
84 idx_t index = -1;
85 idx_t i = 0;
86 for (; i < n; ++i) {
87 if (isnan(x[i])) {
88 // return when first NaN found
89 return i;
90 }
91 else if (isinf(x[i])) {
92 // keep looking for first NaN
93 for (idx_t k = i + 1; k < n; ++k) {
94 if (isnan(x[k])) {
95 // return when first NaN found
96 return k;
97 }
98 }
99
100 // return the position of the first Inf
101 return i;
102 }
103 else { // still no Inf found yet
104 if (is_real<T>) {
105 real_t a = absf(x[i]);
106 if (a > smax) {
107 smax = a;
108 index = i;
109 }
110 }
111 else if (!scaledsmax) { // no |x_i| = Inf yet
112 real_t a = absf(x[i]);
113 if (isinf(a)) {
114 scaledsmax = true;
115 smax = absf(oneFourth * x[i]);
116 index = i;
117 }
118 else if (a > smax) {
119 smax = a;
120 index = i;
121 }
122 }
123 else { // scaledsmax = true
124 real_t a = absf(oneFourth * x[i]);
125 if (a > smax) {
126 smax = a;
127 index = i;
128 }
129 }
130 }
131 }
132
133 return index;
134}
135
157template <TLAPACK_VECTOR vector_t, class abs_f>
159{
160 // data traits
161 using idx_t = size_type<vector_t>;
162 using T = type_t<vector_t>;
163 using real_t = real_type<T>;
164
165 // constants
166 const real_t oneFourth(0.25);
167 const idx_t n = size(x);
168
169 // quick return
170 if (n <= 0) return 0;
171
172 bool scaledsmax = false; // indicates whether |x_i| = Inf
173 real_t smax(-1);
174 idx_t index = -1;
175 idx_t i = 0;
176 for (; i < n; ++i) {
177 if (isinf(x[i])) {
178 // return the position of the first Inf
179 return i;
180 }
181 else { // still no Inf found yet
182 if (is_real<T>) {
183 real_t a = absf(x[i]);
184 if (a > smax) {
185 smax = a;
186 index = i;
187 }
188 }
189 else if (!scaledsmax) { // no |x_i| = Inf yet
190 real_t a = absf(x[i]);
191 if (isinf(a)) {
192 scaledsmax = true;
193 smax = absf(oneFourth * x[i]);
194 index = i;
195 }
196 else if (a > smax) {
197 smax = a;
198 index = i;
199 }
200 }
201 else { // scaledsmax = true
202 real_t a = absf(oneFourth * x[i]);
203 if (a > smax) {
204 smax = a;
205 index = i;
206 }
207 }
208 }
209 }
210
211 return (index != idx_t(-1)) ? index : 0;
212}
213
233template <TLAPACK_VECTOR vector_t, class abs_f>
235{
236 return (opts.ec.nan == true) ? iamax_ec(x, opts.absf)
237 : iamax_nc(x, opts.absf);
238}
239
244template <TLAPACK_VECTOR vector_t, disable_if_allow_optblas_t<vector_t> = 0>
245size_type<vector_t> iamax(const vector_t& x)
246{
247 using T = type_t<vector_t>;
248 using real_t = real_type<T>;
249
250 return iamax(x, IamaxOpts([](const T& x) -> real_t { return abs1(x); }));
251}
252
253#ifdef TLAPACK_USE_LAPACKPP
254
255template <TLAPACK_LEGACY_VECTOR vector_t,
256 enable_if_allow_optblas_t<vector_t> = 0>
257size_type<vector_t> iamax(vector_t const& x)
258{
259 // Legacy objects
260 auto x_ = legacy_vector(x);
261
262 // Constants to forward
263 const auto& n = x_.n;
264
265 return ::blas::iamax(n, x_.ptr, x_.inc);
266}
267
268#endif
269
270} // namespace tlapack
271
272#endif // #ifndef TLAPACK_BLAS_IAMAX_HH
constexpr bool isnan(const T &x) noexcept
Extends std::isnan() to complex numbers.
Definition utils.hpp:125
constexpr bool isinf(const T &x) noexcept
Extends std::isinf() to complex numbers.
Definition utils.hpp:117
#define TLAPACK_LEGACY_VECTOR
Macro for tlapack::concepts::LegacyVector compatible with C++17.
Definition concepts.hpp:954
size_type< vector_t > iamax(const vector_t &x, const IamaxOpts< abs_f > &opts)
Return .
Definition iamax.hpp:234
size_type< vector_t > iamax_ec(const vector_t &x, abs_f absf)
Return .
Definition iamax.hpp:68
size_type< vector_t > iamax_nc(const vector_t &x, abs_f absf)
Return .
Definition iamax.hpp:158
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113
Options for error checking.
Definition exceptionHandling.hpp:76
Options for iamax.
Definition iamax.hpp:37
abs_f absf
Absolute value function In reference BLAS, absf(a) := |Re(a)| + |Im(a)|.
Definition iamax.hpp:41