Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Numeric.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Numeric.h (C) 2000-2020 */
9/* */
10/* Définitions des constantes numériques. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_DATATYPE_NUMERIC_H
13#define ARCANE_DATATYPE_NUMERIC_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Limits.h"
18#include "arcane/utils/Math.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28/*!
29 * \internal
30 * \brief Opérations de comparaisons pour un type numérique T
31 *
32 * Cette classe définit juste un opérateur de comparaison pour le
33 * type 'T' paramètre template. Il existe deux types de comparaisons:
34 * - les comparaisons exactes (isEqual());
35 * - les comparaisons approximatives (isNearlyEqual()).
36 *
37 * Les deux types de comparaisons sont identiques, sauf pour les
38 * types flottants ou équivalents. Dans ce cas, la comparaison exacte
39 * compare bit à bit les deux valeurs et la comparaison approximative
40 * considère que deux nombres sont égaux si leur différence relative est
41 * inférieure à un epsilon près.
42 */
43template<class T>
45{
46 public:
47 /*!
48 * \brief Compare \a a à zéro.
49 * \retval true si \a a vaut zéro à un epsilon près,
50 * \retval false sinon.
51 */
52 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZero (const T& a)
53 {
54 return (a==T());
55 }
56
57 /*!
58 * \brief Compare \a a à zéro.
59 * \retval true si \a a vaut exactement zéro,
60 * \retval false sinon.
61 */
62 constexpr ARCCORE_HOST_DEVICE static bool isZero (const T& a)
63 {
64 return (a==T());
65 }
66
67 /*!
68 * \brief Compare \a a à \a b.
69 * \retval true si \a a et \b sont égaux à un epsilon près,
70 * \retval false sinon.
71 */
72 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqual(const T& a,const T& b)
73 {
74 return (a==b);
75 }
76
77 /*!
78 * \brief Compare \a a à \a b.
79 * \retval true si \a a et \b sont égaux à un epsilon près,
80 * \retval false sinon.
81 */
82 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqualWithEpsilon(const T& a,const T& b,const T&)
83 {
84 return (a==b);
85 }
86
87 /*!
88 * \brief Compare \a a à \a b.
89 * \retval true si \a a et \b sont exactements égaux,
90 * \retval false sinon.
91 */
92 constexpr ARCCORE_HOST_DEVICE static bool isEqual(const T& a,const T& b)
93 {
94 return (a==b);
95 }
96};
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100/*!
101 * \internal
102 * \brief Définit l'opérateur == pour les flottants.
103 *
104 * \note A terme, devrait utiliser pour l'epsilon la classe 'numeric_limits'
105 * de la STL quand cela sera implémenté.
106 */
107template<class T>
109{
110 private:
111 constexpr ARCCORE_HOST_DEVICE static T nepsilon() { return FloatInfo<T>::nearlyEpsilon(); }
112 public:
113 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZero(T a)
114 {
115 return ( (a<0.) ? a>-nepsilon() : a<nepsilon() );
116 }
117
118 /*!
119 * \brief Compare \a a à zéro à \a epsilon près.
120 *
121 * \a epsilon doit être positif.
122 *
123 * \retval true si abs(a)<epilon
124 * \retval false sinon
125 */
126 constexpr ARCCORE_HOST_DEVICE static bool isNearlyZeroWithEpsilon(T a,T epsilon)
127 {
128 return ( (a<0.) ? a>-epsilon : a<epsilon );
129 }
130
131 /*! \brief Compare \a avec \a b*epsilon.
132 * \warning b doit être positif. */
133 ARCCORE_HOST_DEVICE static bool isNearlyZero(T a,T b)
134 {
135 return ( (a<0.) ? a>-(b*nepsilon()) : a<(b*nepsilon()) );
136 }
137
138 constexpr ARCCORE_HOST_DEVICE static bool isTrueZero(T a) { return (a==FloatInfo<T>::zero()); }
139 constexpr ARCCORE_HOST_DEVICE static bool isZero(T a) { return (a==FloatInfo<T>::zero()); }
140 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqual(T a,T b)
141 {
142 T s = math::abs(a) + math::abs(b);
143 T d = a - b;
144 return (d==FloatInfo<T>::zero()) ? true : isNearlyZero(d/s);
145 }
146 constexpr ARCCORE_HOST_DEVICE static bool isNearlyEqualWithEpsilon(T a,T b,T epsilon)
147 {
148 T s = math::abs(a) + math::abs(b);
149 T d = a - b;
150 return (d==FloatInfo<T>::zero()) ? true : isNearlyZeroWithEpsilon(d/s,epsilon);
151 }
152 constexpr ARCCORE_HOST_DEVICE static bool isEqual(T a,T b)
153 {
154 return a==b;
155 }
156};
157/*!
158 * \internal
159 * \brief spécialisation de TypeEqualT pour le type <tt>float</tt>.
160 */
161template<>
162class TypeEqualT<float>
163: public FloatEqualT<float>
164{};
165
166/*!
167 * \internal
168 * \brief spécialisation de TypeEqualT pour le type <tt>double</tt>.
169 */
170template<>
171class TypeEqualT<double>
172: public FloatEqualT<double>
173{};
174
175/*!
176 * \internal
177 * \brief spécialisation de TypeEqualT pour le type <tt>long double</tt>.
178 */
179template<>
180class TypeEqualT<long double>
181: public FloatEqualT<long double>
182{};
183
184#ifdef ARCANE_REAL_NOT_BUILTIN
185/*!
186 * \internal
187 * \brief spécialisation de TypeEqualT pour le type <tt>Real</tt>.
188 */
189template<>
190class TypeEqualT<Real>
191: public FloatEqualT<Real>
192{};
193#endif
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198namespace math
199{
200
201/*!
202 * \brief Teste si deux valeurs sont à un peu près égales.
203 * Pour les types entiers, cette fonction est équivalente à IsEqual().
204 * Dans le cas de types réels, les deux nombres sont considérés comme égaux
205 * si et seulement si la valeur absolue de leur différence relative est
206 * inférieure à un epsilon donné. Cet
207 * epsilon est égal à float_info<_Type>::nearlyEpsilon().
208 * \retval true si les deux valeurs sont égales,
209 * \retval false sinon.
210 */
211template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
212isNearlyEqual(const _Type& a,const _Type& b)
213{
215}
216
217//! Surcharge pour les reels
218constexpr ARCCORE_HOST_DEVICE inline bool
219isNearlyEqual(Real a,Real b)
220{
222}
223
224/*!
225 * \brief Teste si deux valeurs sont à un peu près égales.
226 * Pour les types entiers, cette fonction est équivalente à IsEqual().
227 * Dans le cas de types réels, les deux nombres sont considérés comme égaux
228 * si et seulement si la valeur absolue de leur différence relative est
229 * inférieure à \a epsilon.
230 *
231 * \retval true si les deux valeurs sont égales,
232 * \retval false sinon.
233 */
234template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
235isNearlyEqualWithEpsilon(const _Type& a,const _Type& b,const _Type& epsilon)
236{
238}
239
240//! Surcharge pour les reels
241ARCCORE_HOST_DEVICE constexpr inline bool
242isNearlyEqualWithEpsilon(Real a,Real b,Real epsilon)
243{
245}
246
247/*!
248 * \brief Teste l'égalité bit à bit entre deux valeurs.
249 * \retval true si les deux valeurs sont égales,
250 * \retval false sinon.
251 */
252template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
253isEqual(const _Type& a,const _Type& b)
254{
255 return TypeEqualT<_Type>::isEqual(a,b);
256}
257
258//! Surcharge pour les reels
259ARCCORE_HOST_DEVICE constexpr inline bool
260isEqual(Real a,Real b)
261{
262 return TypeEqualT<Real>::isEqual(a,b);
263}
264
265/*!
266 * \brief Teste si une valeur est à peu près égale à zéro à un epsilon près.
267 *
268 * Pour les types entiers, cette fonction est équivalente à IsZero().
269 * Dans le cas de types réels, la valeur est considérée comme égale à
270 * zéro si et seulement si sa valeur absolue est inférieure à un epsilon
271 * donné par la fonction float_info<_Type>::nearlyEpsilon().
272 * \retval true si les deux valeurs sont égales,
273 * \retval false sinon.
274 */
275template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
276isNearlyZeroWithEpsilon(const _Type& a,const _Type& epsilon)
277{
279}
280
281/*!
282 * \brief Teste si une valeur est à peu près égale à zéro à l'epsilon standard près.
283 *
284 * L'epsilon standard est celui retourné par FloatInfo<_Type>::nearlyEpsilon().
285 *
286 * \sa isNearlyZero(const _Type& a,const _Type& epsilon).
287 */
288template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
289isNearlyZero(const _Type& a)
290{
292}
293
294/*!
295 * \brief Teste si une valeur est exactement égale à zéro.
296 * \retval true si \a vaut zéro,
297 * \retval false sinon.
298 */
299template<class _Type> constexpr ARCCORE_HOST_DEVICE inline bool
300isZero(const _Type& a)
301{
303}
304} // namespace math
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309} // End namespace Arcane
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
314#endif
constexpr __host__ static __device__ bool isNearlyZeroWithEpsilon(T a, T epsilon)
Compare a à zéro à epsilon près.
Definition Numeric.h:126
__host__ static __device__ bool isNearlyZero(T a, T b)
Compare avec b*epsilon.
Definition Numeric.h:133
Informations sur le type flottant.
Definition Limits.h:48
constexpr __host__ static __device__ bool isNearlyZero(const T &a)
Compare a à zéro.
Definition Numeric.h:52
constexpr __host__ static __device__ bool isZero(const T &a)
Compare a à zéro.
Definition Numeric.h:62
constexpr __host__ static __device__ bool isEqual(const T &a, const T &b)
Compare a à b.
Definition Numeric.h:92
constexpr __host__ static __device__ bool isNearlyEqual(const T &a, const T &b)
Compare a à b.
Definition Numeric.h:72
constexpr __host__ static __device__ bool isNearlyEqualWithEpsilon(const T &a, const T &b, const T &)
Compare a à b.
Definition Numeric.h:82
constexpr __host__ __device__ bool isNearlyZeroWithEpsilon(const _Type &a, const _Type &epsilon)
Teste si une valeur est à peu près égale à zéro à un epsilon près.
Definition Numeric.h:276
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:235
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:212
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Teste l'égalité bit à bit entre deux valeurs.
Definition Numeric.h:253
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-