Ginkgo  Generated from tags/v1.0.0^0 branch based on master. Ginkgo version 1.0.0
A numerical linear algebra library targeting many-core architectures
math.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2019, the Ginkgo authors
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************<GINKGO LICENSE>*******************************/
32 
33 #ifndef GKO_CORE_BASE_MATH_HPP_
34 #define GKO_CORE_BASE_MATH_HPP_
35 
36 
37 #include <ginkgo/core/base/std_extensions.hpp>
38 #include <ginkgo/core/base/types.hpp>
39 
40 
41 #include <cmath>
42 #include <complex>
43 #include <cstdlib>
44 
45 
46 namespace gko {
47 
48 
49 // type manipulations
50 
51 
57 namespace detail {
58 
59 
63 template <typename T>
64 struct remove_complex_impl {
65  using type = T;
66 };
67 
71 template <typename T>
72 struct remove_complex_impl<std::complex<T>> {
73  using type = T;
74 };
75 
76 
77 template <typename T>
78 struct is_complex_impl : public std::integral_constant<bool, false> {};
79 
80 template <typename T>
81 struct is_complex_impl<std::complex<T>>
82  : public std::integral_constant<bool, true> {};
83 
84 
85 } // namespace detail
86 
87 
92 template <typename T>
93 using remove_complex = typename detail::remove_complex_impl<T>::type;
94 
95 
103 template <typename T>
104 GKO_INLINE GKO_ATTRIBUTES constexpr bool is_complex()
105 {
106  return detail::is_complex_impl<T>::value;
107 }
108 
109 
110 namespace detail {
111 
112 
113 template <typename T>
114 struct reduce_precision_impl {
115  using type = T;
116 };
117 
118 template <typename T>
119 struct reduce_precision_impl<std::complex<T>> {
120  using type = std::complex<typename reduce_precision_impl<T>::type>;
121 };
122 
123 template <>
124 struct reduce_precision_impl<double> {
125  using type = float;
126 };
127 
128 template <>
129 struct reduce_precision_impl<float> {
130  using type = half;
131 };
132 
133 
134 template <typename T>
135 struct increase_precision_impl {
136  using type = T;
137 };
138 
139 template <typename T>
140 struct increase_precision_impl<std::complex<T>> {
141  using type = std::complex<typename increase_precision_impl<T>::type>;
142 };
143 
144 template <>
145 struct increase_precision_impl<float> {
146  using type = double;
147 };
148 
149 template <>
150 struct increase_precision_impl<half> {
151  using type = float;
152 };
153 
154 
155 } // namespace detail
156 
157 
161 template <typename T>
162 using reduce_precision = typename detail::reduce_precision_impl<T>::type;
163 
164 
168 template <typename T>
169 using increase_precision = typename detail::increase_precision_impl<T>::type;
170 
171 
181 template <typename T>
182 GKO_INLINE GKO_ATTRIBUTES constexpr reduce_precision<T> round_down(T val)
183 {
184  return static_cast<reduce_precision<T>>(val);
185 }
186 
187 
197 template <typename T>
198 GKO_INLINE GKO_ATTRIBUTES constexpr increase_precision<T> round_up(T val)
199 {
200  return static_cast<increase_precision<T>>(val);
201 }
202 
203 
204 template <typename FloatType, size_type NumComponents, size_type ComponentId>
205 class truncated;
206 
207 
208 namespace detail {
209 
210 
211 template <typename T>
212 struct truncate_type_impl {
213  using type = truncated<T, 2, 0>;
214 };
215 
216 template <typename T, size_type Components>
217 struct truncate_type_impl<truncated<T, Components, 0>> {
218  using type = truncated<T, 2 * Components, 0>;
219 };
220 
221 template <typename T>
222 struct truncate_type_impl<std::complex<T>> {
223  using type = std::complex<typename truncate_type_impl<T>::type>;
224 };
225 
226 
227 template <typename T>
228 struct type_size_impl {
229  static constexpr auto value = sizeof(T) * byte_size;
230 };
231 
232 template <typename T>
233 struct type_size_impl<std::complex<T>> {
234  static constexpr auto value = sizeof(T) * byte_size;
235 };
236 
237 
238 } // namespace detail
239 
240 
245 template <typename T, size_type Limit = sizeof(uint16) * byte_size>
246 using truncate_type =
247  xstd::conditional_t<detail::type_size_impl<T>::value >= 2 * Limit,
249 
250 
257 template <typename S, typename R>
265  GKO_ATTRIBUTES R operator()(S val) { return static_cast<R>(val); }
266 };
267 
268 
269 // mathematical functions
270 
271 
280 GKO_INLINE GKO_ATTRIBUTES constexpr int64 ceildiv(int64 num, int64 den)
281 {
282  return (num + den - 1) / den;
283 }
284 
285 
291 template <typename T>
292 GKO_INLINE GKO_ATTRIBUTES constexpr T zero()
293 {
294  return T(0);
295 }
296 
297 
306 template <typename T>
307 GKO_INLINE GKO_ATTRIBUTES constexpr T zero(const T &)
308 {
309  return zero<T>();
310 }
311 
312 
318 template <typename T>
319 GKO_INLINE GKO_ATTRIBUTES constexpr T one()
320 {
321  return T(1);
322 }
323 
324 
333 template <typename T>
334 GKO_INLINE GKO_ATTRIBUTES constexpr T one(const T &)
335 {
336  return one<T>();
337 }
338 
339 
349 template <typename T>
350 GKO_INLINE GKO_ATTRIBUTES constexpr T abs(const T &x)
351 {
352  return x >= zero<T>() ? x : -x;
353 }
354 
355 
356 using std::abs; // use optimized abs functions for basic types
357 
358 
372 template <typename T>
373 GKO_INLINE GKO_ATTRIBUTES constexpr T max(const T &x, const T &y)
374 {
375  return x >= y ? x : y;
376 }
377 
378 
392 template <typename T>
393 GKO_INLINE GKO_ATTRIBUTES constexpr T min(const T &x, const T &y)
394 {
395  return x <= y ? x : y;
396 }
397 
398 
408 template <typename T>
409 GKO_ATTRIBUTES GKO_INLINE constexpr T real(const T &x)
410 {
411  return x;
412 }
413 
414 
424 template <typename T>
425 GKO_ATTRIBUTES GKO_INLINE constexpr T imag(const T &)
426 {
427  return zero<T>();
428 }
429 
430 
438 template <typename T>
439 GKO_ATTRIBUTES GKO_INLINE T conj(const T &x)
440 {
441  return x;
442 }
443 
444 
445 using std::sqrt; // use standard sqrt functions for basic types
446 
447 
455 template <typename T>
456 GKO_INLINE GKO_ATTRIBUTES constexpr auto squared_norm(const T &x)
457  -> decltype(real(conj(x) * x))
458 {
459  return real(conj(x) * x);
460 }
461 
462 
475 template <typename T>
476 GKO_INLINE GKO_ATTRIBUTES constexpr uint32 get_significant_bit(
477  const T &n, uint32 hint = 0u) noexcept
478 {
479  return (T{1} << (hint + 1)) > n ? hint : get_significant_bit(n, hint + 1u);
480 }
481 
482 
494 template <typename T>
495 GKO_INLINE GKO_ATTRIBUTES constexpr T get_superior_power(
496  const T &base, const T &limit, const T &hint = T{1}) noexcept
497 {
498  return hint >= limit ? hint : get_superior_power(base, limit, hint * base);
499 }
500 
501 
502 } // namespace gko
503 
504 
505 #endif // GKO_CORE_BASE_MATH_HPP_
constexpr int64 ceildiv(int64 num, int64 den)
Performs integer division with rounding up.
Definition: math.hpp:280
constexpr T get_superior_power(const T &base, const T &limit, const T &hint=T{1}) noexcept
Returns the smallest power of base not smaller than limit.
Definition: math.hpp:495
constexpr size_type byte_size
Number of bits in a byte.
Definition: types.hpp:185
typename detail::reduce_precision_impl< T >::type reduce_precision
Obtains the next type in the hierarchy with lower precision than T.
Definition: math.hpp:162
constexpr T zero()
Returns the additive identity for T.
Definition: math.hpp:292
constexpr reduce_precision< T > round_down(T val)
Reduces the precision of the input parameter.
Definition: math.hpp:182
std::uint32_t uint32
32-bit unsigned integral type.
Definition: types.hpp:134
STL namespace.
constexpr T abs(const T &x)
Returns the absolute value of the object.
Definition: math.hpp:350
Definition: math.hpp:205
constexpr T imag(const T &)
Returns the imaginary part of the object.
Definition: math.hpp:425
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
Used to convert objects of type S to objects of type R using static_cast.
Definition: math.hpp:258
constexpr uint32 get_significant_bit(const T &n, uint32 hint=0u) noexcept
Returns the position of the most significant bit of the number.
Definition: math.hpp:476
constexpr T real(const T &x)
Returns the real part of the object.
Definition: math.hpp:409
constexpr increase_precision< T > round_up(T val)
Increases the precision of the input parameter.
Definition: math.hpp:198
constexpr T min(const T &x, const T &y)
Returns the smaller of the arguments.
Definition: math.hpp:393
constexpr auto squared_norm(const T &x) -> decltype(real(conj(x) *x))
Returns the squared norm of the object.
Definition: math.hpp:456
std::int64_t int64
64-bit signed integral type.
Definition: types.hpp:117
T conj(const T &x)
Returns the conjugate of an object.
Definition: math.hpp:439
xstd::conditional_t< detail::type_size_impl< T >::value >=2 *Limit, typename detail::truncate_type_impl< T >::type, T > truncate_type
Truncates the type by half (by dropping bits), but ensures that it is at least Limit bits wide...
Definition: math.hpp:248
R operator()(S val)
Converts the object to result type.
Definition: math.hpp:265
typename detail::remove_complex_impl< T >::type remove_complex
Obtains a real counterpart of a std::complex type, and leaves the type unchanged if it is not a compl...
Definition: math.hpp:93
constexpr T max(const T &x, const T &y)
Returns the larger of the arguments.
Definition: math.hpp:373
constexpr bool is_complex()
Checks if T is a complex type.
Definition: math.hpp:104
constexpr T one()
Returns the multiplicative identity for T.
Definition: math.hpp:319
typename detail::increase_precision_impl< T >::type increase_precision
Obtains the next type in the hierarchy with higher precision than T.
Definition: math.hpp:169