Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
Math.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* Math.h (C) 2000-2024 */
9/* */
10/* Diverse mathematical functions. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_MATH_H
13#define ARCANE_UTILS_MATH_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18#include "arcane/utils/Convert.h"
19
20#include <cmath>
21#include <cstdlib>
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26/*!
27 \brief Namespace for mathematical functions.
28
29 This namespace contains all mathematical functions used
30 by the code.
31*/
32namespace Arcane::math
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38/*!
39 * \brief Natural logarithm of \a v.
40 */
41ARCCORE_HOST_DEVICE inline double
42log(double v)
43{
44#ifdef ARCANE_CHECK_MATH
45 if (v == 0.0 || v < 0.0)
46 arcaneMathError(v, "log");
47#endif
48 return std::log(v);
49}
50
51/*!
52 * \brief Natural logarithm of \a v.
53 */
54ARCCORE_HOST_DEVICE inline long double
55log(long double v)
56{
57#ifdef ARCANE_CHECK_MATH
58 if (v == 0.0 || v < 0.0)
59 arcaneMathError(v, "log");
60#endif
61 return std::log(v);
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
67/*!
68 * \brief Decimal logarithm of \a v.
69 */
70ARCCORE_HOST_DEVICE inline double
71log10(double v)
72{
73#ifdef ARCANE_CHECK_MATH
74 if (v == 0.0 || v < 0.0)
75 arcaneMathError(v, "log");
76#endif
77 return std::log10(v);
78}
79
80/*!
81 * \brief Decimal logarithm of \a v.
82 */
83ARCCORE_HOST_DEVICE inline long double
84log10(long double v)
85{
86#ifdef ARCANE_CHECK_MATH
87 if (v == 0.0 || v < 0.0)
88 arcaneMathError(v, "log");
89#endif
90 return std::log10(v);
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96/*!
97 * \brief Round \a v down to the immediately lower integer.
98 */
99ARCCORE_HOST_DEVICE inline double
100floor(double v)
101{
102 return std::floor(v);
103}
104
105/*!
106 * \brief Round \a v down to the immediately lower integer.
107 */
108ARCCORE_HOST_DEVICE inline long double
109floor(long double v)
110{
111 return std::floor(v);
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117/*!
118 * \brief Exponential of \a v.
119 */
120ARCCORE_HOST_DEVICE inline double
121exp(double v)
122{
123 return std::exp(v);
124}
125
126/*!
127 * \brief Exponential of \a v.
128 */
129ARCCORE_HOST_DEVICE inline long double
130exp(long double v)
131{
132 return std::exp(v);
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
138/*!
139 * \brief Square root of \a v.
140 */
141ARCCORE_HOST_DEVICE inline double
142sqrt(double v)
143{
144#ifdef ARCANE_CHECK_MATH
145 if (v < 0.)
146 arcaneMathError(v, "sqrt");
147#endif
148 return std::sqrt(v);
149}
150
151/*!
152 * \brief Square root of \a v.
153 */
154ARCCORE_HOST_DEVICE inline long double
155sqrt(long double v)
156{
157#ifdef ARCANE_CHECK_MATH
158 if (v < 0.)
159 arcaneMathError(v, "sqrt");
160#endif
161 return std::sqrt(v);
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
167/*!
168 * \brief Power function.
169 *
170 * Calculates \a x to the power of \a y.
171 *
172 * \pre x>=0 or y is an integer
173 */
174ARCCORE_HOST_DEVICE inline double
175pow(double x, double y)
176{
177#ifdef ARCANE_CHECK_MATH
178 // Invalid arguments if x is negative and y is not an integer
179 if (x < 0.0 && ::floor(y) != y)
180 arcaneMathError(x, y, "pow");
181#endif
182 return std::pow(x, y);
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188/*!
189 * \brief Power function.
190 *
191 * Calculates \a x to the power of \a y.
192 *
193 * \pre x>=0 or y is an integer
194 */
195ARCCORE_HOST_DEVICE inline long double
196pow(long double x, long double y)
197{
198#ifdef ARCANE_CHECK_MATH
199 // Invalid arguments if x is negative and y is not an integer
200 if (x < 0.0 && ::floorl(y) != y)
201 arcaneMathError(x, y, "pow");
202#endif
203 return std::pow(x, y);
204}
205
206/*!
207 * \brief Power function.
208 *
209 * Calculates \a x to the power of \a y.
210 *
211 * \pre x>=0 or y is an integer
212 */
213ARCCORE_HOST_DEVICE inline long double
214pow(double x, long double y)
215{
216#ifdef ARCANE_CHECK_MATH
217 // Invalid arguments if x is negative and y is not an integer
218 if (x < 0.0 && ::floorl(y) != y)
219 arcaneMathError(x, y, "pow");
220#endif
221 return std::pow(x, y);
222}
223
224/*!
225 * \brief Power function.
226 *
227 * Calculates \a x to the power of \a y.
228 *
229 * \pre x>=0 or y is an integer
230 */
231ARCCORE_HOST_DEVICE inline long double
232pow(long double x, double y)
233{
234#ifdef ARCANE_CHECK_MATH
235 // Invalid arguments if x is negative and y is not an integer
236 if (x < 0.0 && ::floor(y) != y)
237 arcaneMathError(x, y, "pow");
238#endif
239 return std::pow(x, y);
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245/*!
246 * \brief Returns the minimum of two elements.
247 *
248 * \ingroup GroupMathUtils
249 *
250 * Uses the < operator to determine the minimum.
251 */
252template <class T> ARCCORE_HOST_DEVICE inline T
253min(const T& a, const T& b)
254{
255 return ((a < b) ? a : b);
256}
257
258/*!
259 * \brief Returns the minimum of two real numbers.
260 * \ingroup GroupMathUtils
261 */
262ARCCORE_HOST_DEVICE inline long double
263min(long double a, long double b)
264{
265 return ((a < b) ? a : b);
266}
267
268/*!
269 * \brief Returns the minimum of two real numbers.
270 * \ingroup GroupMathUtils
271 */
272ARCCORE_HOST_DEVICE inline long double
273min(double a, long double b)
274{
275 return ((a < b) ? a : b);
276}
277
278/*!
279 * \brief Returns the minimum of two real numbers.
280 * \ingroup GroupMathUtils
281 */
282ARCCORE_HOST_DEVICE inline long double
283min(long double a, double b)
284{
285 return ((a < b) ? a : b);
286}
287
288/*!
289 * \brief Returns the minimum of two real numbers.
290 * \ingroup GroupMathUtils
291 */
292ARCCORE_HOST_DEVICE inline double
293min(double a, double b)
294{
295 return ((a < b) ? a : b);
296}
297
298/*!
299 * \brief Returns the minimum of two real numbers.
300 * \ingroup GroupMathUtils
301 */
302ARCCORE_HOST_DEVICE inline float
303min(float a, float b)
304{
305 return ((a < b) ? a : b);
306}
307
308/*!
309 * \brief Returns the minimum of two integers.
310 * \ingroup GroupMathUtils
311 */
312ARCCORE_HOST_DEVICE inline int
313min(int a, int b)
314{
315 return ((a < b) ? a : b);
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321/*!
322 * \brief Returns the maximum of two elements.
323 *
324 * \ingroup GroupMathUtils
325 *
326 * Uses the < operator to determine the maximum.
327 */
328template <class T> ARCCORE_HOST_DEVICE inline T
329max(const T& a, const T& b)
330{
331 return ((a < b) ? b : a);
332}
333
334/*!
335 * \brief Returns the maximum of two real numbers.
336 * \ingroup GroupMathUtils
337 */
338ARCCORE_HOST_DEVICE inline long double
339max(long double a, long double b)
340{
341 return ((a < b) ? b : a);
342}
343
344/*!
345 * \brief Returns the maximum of two real numbers.
346 * \ingroup GroupMathUtils
347 */
348ARCCORE_HOST_DEVICE inline long double
349max(double a, long double b)
350{
351 return ((a < b) ? b : a);
352}
353
354/*!
355 * \brief Returns the maximum of two real numbers.
356 * \ingroup GroupMathUtils
357 */
358ARCCORE_HOST_DEVICE inline long double
359max(long double a, double b)
360{
361 return ((a < b) ? b : a);
362}
363
364/*!
365 * \brief Returns the maximum of two integers.
366 * \ingroup GroupMathUtils
367 */
368ARCCORE_HOST_DEVICE inline unsigned long
369max(unsigned long a, unsigned long b)
370{
371 return ((a < b) ? b : a);
372}
373
374/*!
375 * \brief Returns the maximum of two real numbers.
376 * \ingroup GroupMathUtils
377 */
378ARCCORE_HOST_DEVICE inline double
379max(double a, double b)
380{
381 return ((a < b) ? b : a);
382}
383
384/*!
385 * \brief Returns the maximum of two real numbers.
386 * \ingroup GroupMathUtils
387 */
388ARCCORE_HOST_DEVICE inline float
389max(float a, float b)
390{
391 return ((a < b) ? b : a);
392}
393
394/*!
395 * \brief Returns the maximum of two Int16
396 * \ingroup GroupMathUtils
397 */
398ARCCORE_HOST_DEVICE inline Int16
400{
401 return ((a < b) ? b : a);
402}
403
404/*!
405 * \brief Returns the maximum of two Int32
406 * \ingroup GroupMathUtils
407 */
408ARCCORE_HOST_DEVICE inline Int32
410{
411 return ((a < b) ? b : a);
412}
413
414/*!
415 * \brief Returns the maximum of two Int32
416 * \ingroup GroupMathUtils
417 */
418ARCCORE_HOST_DEVICE inline Int64
420{
421 return ((a < b) ? b : a);
422}
423
424/*!
425 * \brief Returns the maximum of two Int64
426 * \ingroup GroupMathUtils
427 */
428ARCCORE_HOST_DEVICE inline Int64
430{
431 return ((a < b) ? b : a);
432}
433
434/*!
435 * \brief Returns the maximum of two Int64
436 * \ingroup GroupMathUtils
437 */
438ARCCORE_HOST_DEVICE inline Int64
440{
441 return ((a < b) ? b : a);
442}
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
447/*!
448 * \brief Returns the absolute value of a real number.
449 * \ingroup GroupMathUtils
450 */
451ARCCORE_HOST_DEVICE inline long double
452abs(long double a)
453{
454 return std::abs(a);
455}
456
457/*!
458 * \brief Returns the absolute value of a real number.
459 * \ingroup GroupMathUtils
460 */
461ARCCORE_HOST_DEVICE inline double
462abs(double a)
463{
464 return std::abs(a);
465}
466
467/*!
468 * \brief Returns the absolute value of a real number.
469 * \ingroup GroupMathUtils
470 */
471ARCCORE_HOST_DEVICE inline float
472abs(float a)
473{
474 return std::abs(a);
475}
476
477/*!
478 * \brief Returns the absolute value of an 'int'.
479 * \ingroup GroupMathUtils
480 */
481ARCCORE_HOST_DEVICE inline short
482abs(short a)
483{
484 return (a > 0) ? a : (short)(-a);
485}
486
487/*!
488 * \brief Returns the absolute value of an 'int'.
489 * \ingroup GroupMathUtils
490 */
491ARCCORE_HOST_DEVICE inline int
492abs(int a)
493{
494 return (a > 0) ? a : (-a);
495}
496
497/*!
498 * \brief Returns the absolute value of a 'long'.
499 * \ingroup GroupMathUtils
500 */
501ARCCORE_HOST_DEVICE inline long
502abs(long a)
503{
504 return (a > 0L) ? a : (-a);
505}
506
507/*!
508 * \brief Returns the absolute value of a 'long'.
509 * \ingroup GroupMathUtils
510 */
511ARCCORE_HOST_DEVICE inline long long
512abs(long long a)
513{
514 return (a > 0LL) ? a : (-a);
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
520/*!
521 * \brief Truncates the precision of the real number v to nb_digit significant figures.
522 *
523 * For a double-precision real number in IEEE 754, the number of significant bits
524 * is 15 or 16 depending on the value. It should be noted that it is not possible
525 * to simply and quickly truncate the precision to a given value.
526 * This is why nb_digit represents an approximate number of digits.
527 * Notably, it is not possible to go below 8 significant figures.
528 *
529 * If nb_digit is less than or equal to zero or greater than 15, the value v is returned.
530 */
531extern ARCANE_UTILS_EXPORT double
532truncateDouble(double v, Integer nb_digit);
533
534/*---------------------------------------------------------------------------*/
535/*---------------------------------------------------------------------------*/
536
537/*!
538 * \brief Truncates the precision of the array of real numbers values to
539 * \a nb_digit significant figures.
540 *
541 * On exit, each element of values is modified as if after calling
542 * truncateDouble(double v,Integer nb_digit).
543 */
544extern ARCANE_UTILS_EXPORT void
546
547/*---------------------------------------------------------------------------*/
548/*---------------------------------------------------------------------------*/
549
550} // End namespace Arcane::math
551
552/*---------------------------------------------------------------------------*/
553/*---------------------------------------------------------------------------*/
554
555#ifdef ARCANE_REAL_USE_APFLOAT
556#include "arcane/utils/MathApfloat.h"
557#endif
558
559/*---------------------------------------------------------------------------*/
560/*---------------------------------------------------------------------------*/
561
562#endif
Declarations of types used in Arcane.
Modifiable view of an array of type T.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
Definition MathUtils.h:346
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
Definition MathUtils.h:407
Namespace for mathematical functions.
Definition MathUtils.h:36
__host__ __device__ double pow(double x, double y)
Power function.
Definition Math.h:175
__host__ __device__ double floor(double v)
Round v down to the immediately lower integer.
Definition Math.h:100
__host__ __device__ double sqrt(double v)
Square root of v.
Definition Math.h:142
__host__ __device__ double log(double v)
Natural logarithm of v.
Definition Math.h:42
__host__ __device__ double log10(double v)
Decimal logarithm of v.
Definition Math.h:71
double truncateDouble(double v, Integer nb_digit)
Truncates the precision of the real number v to nb_digit significant figures.
Definition Math.cc:81
__host__ __device__ double exp(double v)
Exponential of v.
Definition Math.h:121
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
std::int16_t Int16
Signed integer type of 16 bits.
__host__ __device__ void arcaneMathError(long double arg_value, const char *func_name)
Signals an invalid argument in a mathematical function.
std::int32_t Int32
Signed integer type of 32 bits.