xref: /petsc/include/petscmath.h (revision 4fc747eaadbeca11629f314a99edccbc2ed7b3d3)
1 /*
2 
3       PETSc mathematics include file. Defines certain basic mathematical
4     constants and functions for working with single, double, and quad precision
5     floating point numbers as well as complex single and double.
6 
7     This file is included by petscsys.h and should not be used directly.
8 
9 */
10 
11 #if !defined(__PETSCMATH_H)
12 #define __PETSCMATH_H
13 #include <math.h>
14 
15 /*
16 
17      Defines operations that are different for complex and real numbers;
18    note that one cannot mix the use of complex and real in the same
19    PETSc program. All PETSc objects in one program are built around the object
20    PetscScalar which is either always a real or a complex.
21 
22 */
23 
24 #if defined(PETSC_USE_REAL_SINGLE)
25 #define MPIU_REAL   MPI_FLOAT
26 typedef float PetscReal;
27 #define PetscSqrtReal(a)    sqrt(a)
28 #define PetscExpReal(a)     exp(a)
29 #define PetscLogReal(a)     log(a)
30 #define PetscLog10Real(a)   log10(a)
31 #ifdef PETSC_HAVE_LOG2
32 #define PetscLog2Real(a)    log2(a)
33 #endif
34 #define PetscSinReal(a)     sin(a)
35 #define PetscCosReal(a)     cos(a)
36 #define PetscTanReal(a)     tan(a)
37 #define PetscAsinReal(a)    asin(a)
38 #define PetscAcosReal(a)    acos(a)
39 #define PetscAtanReal(a)    atan(a)
40 #define PetscAtan2Real(a,b) atan2(a,b)
41 #define PetscSinhReal(a)    sinh(a)
42 #define PetscCoshReal(a)    cosh(a)
43 #define PetscTanhReal(a)    tanh(a)
44 #define PetscPowReal(a,b)   pow(a,b)
45 #define PetscCeilReal(a)    ceil(a)
46 #define PetscFloorReal(a)   floor(a)
47 #define PetscFmodReal(a,b)  fmod(a,b)
48 #define PetscTGamma(a)      tgammaf(a)
49 #elif defined(PETSC_USE_REAL_DOUBLE)
50 #define MPIU_REAL   MPI_DOUBLE
51 typedef double PetscReal;
52 #define PetscSqrtReal(a)    sqrt(a)
53 #define PetscExpReal(a)     exp(a)
54 #define PetscLogReal(a)     log(a)
55 #define PetscLog10Real(a)   log10(a)
56 #ifdef PETSC_HAVE_LOG2
57 #define PetscLog2Real(a)    log2(a)
58 #endif
59 #define PetscSinReal(a)     sin(a)
60 #define PetscCosReal(a)     cos(a)
61 #define PetscTanReal(a)     tan(a)
62 #define PetscAsinReal(a)    asin(a)
63 #define PetscAcosReal(a)    acos(a)
64 #define PetscAtanReal(a)    atan(a)
65 #define PetscAtan2Real(a,b) atan2(a,b)
66 #define PetscSinhReal(a)    sinh(a)
67 #define PetscCoshReal(a)    cosh(a)
68 #define PetscTanhReal(a)    tanh(a)
69 #define PetscPowReal(a,b)   pow(a,b)
70 #define PetscCeilReal(a)    ceil(a)
71 #define PetscFloorReal(a)   floor(a)
72 #define PetscFmodReal(a,b)  fmod(a,b)
73 #define PetscTGamma(a)      tgamma(a)
74 #elif defined(PETSC_USE_REAL___FLOAT128)
75 #if defined(__cplusplus)
76 extern "C" {
77 #endif
78 #include <quadmath.h>
79 #if defined(__cplusplus)
80 }
81 #endif
82 PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
83 #define MPIU_REAL MPIU___FLOAT128
84 typedef __float128 PetscReal;
85 #define PetscSqrtReal(a)    sqrtq(a)
86 #define PetscExpReal(a)     expq(a)
87 #define PetscLogReal(a)     logq(a)
88 #define PetscLog10Real(a)   log10q(a)
89 #ifdef PETSC_HAVE_LOG2
90 #define PetscLog2Real(a)    log2q(a)
91 #endif
92 #define PetscSinReal(a)     sinq(a)
93 #define PetscCosReal(a)     cosq(a)
94 #define PetscTanReal(a)     tanq(a)
95 #define PetscAsinReal(a)    asinq(a)
96 #define PetscAcosReal(a)    acosq(a)
97 #define PetscAtanReal(a)    atanq(a)
98 #define PetscAtan2Real(a,b) atan2q(a,b)
99 #define PetscSinhReal(a)    sinhq(a)
100 #define PetscCoshReal(a)    coshq(a)
101 #define PetscTanhReal(a)    tanhq(a)
102 #define PetscPowReal(a,b)   powq(a,b)
103 #define PetscCeilReal(a)    ceilq(a)
104 #define PetscFloorReal(a)   floorq(a)
105 #define PetscFmodReal(a,b)  fmodq(a,b)
106 #define PetscTGamma(a)      tgammaq(a)
107 #endif /* PETSC_USE_REAL_* */
108 
109 /*
110     Complex number definitions
111  */
112 #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
113 #if !defined(PETSC_SKIP_COMPLEX)
114 #define PETSC_HAVE_COMPLEX 1
115 /* C++ support of complex number */
116 #if defined(PETSC_HAVE_CUSP)
117 #define complexlib cusp
118 #include <cusp/complex.h>
119 #elif defined(PETSC_HAVE_VECCUDA) && __CUDACC_VER_MAJOR__ > 6
120 /* complex headers in thrust only available in CUDA 7.0 and above */
121 #define complexlib thrust
122 #include <thrust/complex.h>
123 #else
124 #define complexlib std
125 #include <complex>
126 #endif
127 
128 #define PetscRealPartComplex(a)      (a).real()
129 #define PetscImaginaryPartComplex(a) (a).imag()
130 #define PetscAbsComplex(a)           complexlib::abs(a)
131 #define PetscConjComplex(a)          complexlib::conj(a)
132 #define PetscSqrtComplex(a)          complexlib::sqrt(a)
133 #define PetscPowComplex(a,b)         complexlib::pow(a,b)
134 #define PetscExpComplex(a)           complexlib::exp(a)
135 #define PetscLogComplex(a)           complexlib::log(a)
136 #define PetscSinComplex(a)           complexlib::sin(a)
137 #define PetscCosComplex(a)           complexlib::cos(a)
138 #define PetscAsinComplex(a)          complexlib::asin(a)
139 #define PetscAcosComplex(a)          complexlib::acos(a)
140 #if defined(PETSC_HAVE_TANCOMPLEX)
141 #define PetscTanComplex(a)           complexlib::tan(a)
142 #else
143 #define PetscTanComplex(a)           PetscSinComplex(a)/PetscCosComplex(a)
144 #endif
145 #define PetscSinhComplex(a)          complexlib::sinh(a)
146 #define PetscCoshComplex(a)          complexlib::cosh(a)
147 #if defined(PETSC_HAVE_TANHCOMPLEX)
148 #define PetscTanhComplex(a)          complexlib::tanh(a)
149 #else
150 #define PetscTanhComplex(a)          PetscSinhComplex(a)/PetscCoshComplex(a)
151 #endif
152 
153 #if defined(PETSC_USE_REAL_SINGLE)
154 typedef complexlib::complex<float> PetscComplex;
155 #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND)
156 static inline PetscComplex operator+(const PetscComplex& lhs, const double& rhs) { return lhs + float(rhs); }
157 static inline PetscComplex operator+(const double& lhs, const PetscComplex& rhs) { return float(lhs) + rhs; }
158 static inline PetscComplex operator-(const PetscComplex& lhs, const double& rhs) { return lhs - float(rhs); }
159 static inline PetscComplex operator-(const double& lhs, const PetscComplex& rhs) { return float(lhs) - rhs; }
160 static inline PetscComplex operator*(const PetscComplex& lhs, const double& rhs) { return lhs * float(rhs); }
161 static inline PetscComplex operator*(const double& lhs, const PetscComplex& rhs) { return float(lhs) * rhs; }
162 static inline PetscComplex operator/(const PetscComplex& lhs, const double& rhs) { return lhs / float(rhs); }
163 static inline PetscComplex operator/(const double& lhs, const PetscComplex& rhs) { return float(lhs) / rhs; }
164 static inline bool operator==(const PetscComplex& lhs, const double& rhs) { return lhs.imag() == float(0) && lhs.real() == float(rhs); }
165 static inline bool operator==(const double& lhs, const PetscComplex& rhs) { return rhs.imag() == float(0) && rhs.real() == float(lhs); }
166 static inline bool operator!=(const PetscComplex& lhs, const double& rhs) { return lhs.imag() != float(0) || lhs.real() != float(rhs); }
167 static inline bool operator!=(const double& lhs, const PetscComplex& rhs) { return rhs.imag() != float(0) || rhs.real() != float(lhs); }
168 #endif  /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */
169 #elif defined(PETSC_USE_REAL_DOUBLE)
170 typedef complexlib::complex<double> PetscComplex;
171 #elif defined(PETSC_USE_REAL___FLOAT128)
172 typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */
173 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128;
174 #endif  /* PETSC_USE_REAL_ */
175 #endif  /* ! PETSC_SKIP_COMPLEX */
176 
177 #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
178 #if !defined(PETSC_SKIP_COMPLEX)
179 #define PETSC_HAVE_COMPLEX 1
180 #include <complex.h>
181 
182 #if defined(PETSC_USE_REAL_SINGLE)
183 typedef float _Complex PetscComplex;
184 
185 #define PetscRealPartComplex(a)      crealf(a)
186 #define PetscImaginaryPartComplex(a) cimagf(a)
187 #define PetscAbsComplex(a)           cabsf(a)
188 #define PetscConjComplex(a)          conjf(a)
189 #define PetscSqrtComplex(a)          csqrtf(a)
190 #define PetscPowComplex(a,b)         cpowf(a,b)
191 #define PetscExpComplex(a)           cexpf(a)
192 #define PetscLogComplex(a)           clogf(a)
193 #define PetscSinComplex(a)           csinf(a)
194 #define PetscCosComplex(a)           ccosf(a)
195 #define PetscAsinComplex(a)          casinf(a)
196 #define PetscAcosComplex(a)          cacosf(a)
197 #define PetscTanComplex(a)           ctanf(a)
198 #define PetscSinhComplex(a)          csinhf(a)
199 #define PetscCoshComplex(a)          ccoshf(a)
200 #define PetscTanhComplex(a)          ctanhf(a)
201 
202 #elif defined(PETSC_USE_REAL_DOUBLE)
203 typedef double _Complex PetscComplex;
204 
205 #define PetscRealPartComplex(a)      creal(a)
206 #define PetscImaginaryPartComplex(a) cimag(a)
207 #define PetscAbsComplex(a)           cabs(a)
208 #define PetscConjComplex(a)          conj(a)
209 #define PetscSqrtComplex(a)          csqrt(a)
210 #define PetscPowComplex(a,b)         cpow(a,b)
211 #define PetscExpComplex(a)           cexp(a)
212 #define PetscLogComplex(a)           clog(a)
213 #define PetscSinComplex(a)           csin(a)
214 #define PetscCosComplex(a)           ccos(a)
215 #define PetscAsinComplex(a)          casin(a)
216 #define PetscAcosComplex(a)          cacos(a)
217 #define PetscTanComplex(a)           ctan(a)
218 #define PetscSinhComplex(a)          csinh(a)
219 #define PetscCoshComplex(a)          ccosh(a)
220 #define PetscTanhComplex(a)          ctanh(a)
221 
222 #elif defined(PETSC_USE_REAL___FLOAT128)
223 typedef __complex128 PetscComplex;
224 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);
225 
226 #define PetscRealPartComplex(a)      crealq(a)
227 #define PetscImaginaryPartComplex(a) cimagq(a)
228 #define PetscAbsComplex(a)           cabsq(a)
229 #define PetscConjComplex(a)          conjq(a)
230 #define PetscSqrtComplex(a)          csqrtq(a)
231 #define PetscPowComplex(a,b)         cpowq(a,b)
232 #define PetscExpComplex(a)           cexpq(a)
233 #define PetscLogComplex(a)           clogq(a)
234 #define PetscSinComplex(a)           csinq(a)
235 #define PetscCosComplex(a)           ccosq(a)
236 #define PetscAsinComplex(a)          casinq(a)
237 #define PetscAcosComplex(a)          cacosq(a)
238 #define PetscTanComplex(a)           ctanq(a)
239 #define PetscSinhComplex(a)          csinhq(a)
240 #define PetscCoshComplex(a)          ccoshq(a)
241 #define PetscTanhComplex(a)          ctanhq(a)
242 
243 #endif /* PETSC_USE_REAL_* */
244 #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
245 #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available"
246 #endif /* !PETSC_SKIP_COMPLEX */
247 #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */
248 
249 #if defined(PETSC_HAVE_COMPLEX)
250 #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
251 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
252 #define MPIU_C_COMPLEX MPI_C_COMPLEX
253 #else
254 # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX)
255   typedef complexlib::complex<double> petsc_mpiu_c_double_complex;
256   typedef complexlib::complex<float> petsc_mpiu_c_complex;
257 # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
258   typedef double _Complex petsc_mpiu_c_double_complex;
259   typedef float _Complex petsc_mpiu_c_complex;
260 # else
261   typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
262   typedef struct {float real,imag;} petsc_mpiu_c_complex;
263 # endif
264 PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
265 PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
266 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
267 #endif /* PETSC_HAVE_COMPLEX */
268 
269 #if defined(PETSC_HAVE_COMPLEX)
270 #  if defined(PETSC_USE_REAL_SINGLE)
271 #    define MPIU_COMPLEX MPIU_C_COMPLEX
272 #  elif defined(PETSC_USE_REAL_DOUBLE)
273 #    define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
274 #  elif defined(PETSC_USE_REAL___FLOAT128)
275 #    define MPIU_COMPLEX MPIU___COMPLEX128
276 #  endif /* PETSC_USE_REAL_* */
277 #endif
278 
279 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
280 typedef PetscComplex PetscScalar;
281 #define PetscRealPart(a)      PetscRealPartComplex(a)
282 #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
283 #define PetscAbsScalar(a)     PetscAbsComplex(a)
284 #define PetscConj(a)          PetscConjComplex(a)
285 #define PetscSqrtScalar(a)    PetscSqrtComplex(a)
286 #define PetscPowScalar(a,b)   PetscPowComplex(a,b)
287 #define PetscExpScalar(a)     PetscExpComplex(a)
288 #define PetscLogScalar(a)     PetscLogComplex(a)
289 #define PetscSinScalar(a)     PetscSinComplex(a)
290 #define PetscCosScalar(a)     PetscCosComplex(a)
291 #define PetscAsinScalar(a)    PetscAsinComplex(a)
292 #define PetscAcosScalar(a)    PetscAcosComplex(a)
293 #define PetscTanScalar(a)     PetscTanComplex(a)
294 #define PetscSinhScalar(a)    PetscSinhComplex(a)
295 #define PetscCoshScalar(a)    PetscCoshComplex(a)
296 #define PetscTanhScalar(a)    PetscTanhComplex(a)
297 #define MPIU_SCALAR MPIU_COMPLEX
298 
299 /*
300     real number definitions
301  */
302 #else /* PETSC_USE_COMPLEX */
303 typedef PetscReal PetscScalar;
304 #define MPIU_SCALAR MPIU_REAL
305 
306 #define PetscRealPart(a)      (a)
307 #define PetscImaginaryPart(a) ((PetscReal)0.)
308 PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
309 #define PetscConj(a)          (a)
310 #if !defined(PETSC_USE_REAL___FLOAT128)
311 #define PetscSqrtScalar(a)    sqrt(a)
312 #define PetscPowScalar(a,b)   pow(a,b)
313 #define PetscExpScalar(a)     exp(a)
314 #define PetscLogScalar(a)     log(a)
315 #define PetscSinScalar(a)     sin(a)
316 #define PetscCosScalar(a)     cos(a)
317 #define PetscAsinScalar(a)    asin(a)
318 #define PetscAcosScalar(a)    acos(a)
319 #define PetscTanScalar(a)     tan(a)
320 #define PetscSinhScalar(a)    sinh(a)
321 #define PetscCoshScalar(a)    cosh(a)
322 #define PetscTanhScalar(a)    tanh(a)
323 #else /* PETSC_USE_REAL___FLOAT128 */
324 #define PetscSqrtScalar(a)    sqrtq(a)
325 #define PetscPowScalar(a,b)   powq(a,b)
326 #define PetscExpScalar(a)     expq(a)
327 #define PetscLogScalar(a)     logq(a)
328 #define PetscSinScalar(a)     sinq(a)
329 #define PetscCosScalar(a)     cosq(a)
330 #define PetscAsinScalar(a)    asinq(a)
331 #define PetscAcosScalar(a)    acosq(a)
332 #define PetscTanScalar(a)     tanq(a)
333 #define PetscSinhScalar(a)    sinhq(a)
334 #define PetscCoshScalar(a)    coshq(a)
335 #define PetscTanhScalar(a)    tanhq(a)
336 #endif /* PETSC_USE_REAL___FLOAT128 */
337 
338 #endif /* PETSC_USE_COMPLEX */
339 
340 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
341 #define PetscSignReal(a) (((a) >= 0.0) ? ((a) == 0.0 ? 0.0 : 1.0) : -1.0)
342 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
343 
344 /* --------------------------------------------------------------------------*/
345 
346 /*
347    Certain objects may be created using either single or double precision.
348    This is currently not used.
349 */
350 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
351 
352 #if defined(PETSC_HAVE_COMPLEX)
353 /* PETSC_i is the imaginary number, i */
354 PETSC_EXTERN PetscComplex PETSC_i;
355 #endif
356 
357 /*MC
358    PetscMin - Returns minimum of two numbers
359 
360    Synopsis:
361    #include <petscmath.h>
362    type PetscMin(type v1,type v2)
363 
364    Not Collective
365 
366    Input Parameter:
367 +  v1 - first value to find minimum of
368 -  v2 - second value to find minimum of
369 
370    Notes: type can be integer or floating point value
371 
372    Level: beginner
373 
374 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
375 
376 M*/
377 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
378 
379 /*MC
380    PetscMax - Returns maxium of two numbers
381 
382    Synopsis:
383    #include <petscmath.h>
384    type max PetscMax(type v1,type v2)
385 
386    Not Collective
387 
388    Input Parameter:
389 +  v1 - first value to find maximum of
390 -  v2 - second value to find maximum of
391 
392    Notes: type can be integer or floating point value
393 
394    Level: beginner
395 
396 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
397 
398 M*/
399 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
400 
401 /*MC
402    PetscClipInterval - Returns a number clipped to be within an interval
403 
404    Synopsis:
405    #include <petscmath.h>
406    type clip PetscClipInterval(type x,type a,type b)
407 
408    Not Collective
409 
410    Input Parameter:
411 +  x - value to use if within interval (a,b)
412 .  a - lower end of interval
413 -  b - upper end of interval
414 
415    Notes: type can be integer or floating point value
416 
417    Level: beginner
418 
419 .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
420 
421 M*/
422 #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))
423 
424 /*MC
425    PetscAbsInt - Returns the absolute value of an integer
426 
427    Synopsis:
428    #include <petscmath.h>
429    int abs PetscAbsInt(int v1)
430 
431    Not Collective
432 
433    Input Parameter:
434 .   v1 - the integer
435 
436    Level: beginner
437 
438 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
439 
440 M*/
441 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
442 
443 /*MC
444    PetscAbsReal - Returns the absolute value of an real number
445 
446    Synopsis:
447    #include <petscmath.h>
448    Real abs PetscAbsReal(PetscReal v1)
449 
450    Not Collective
451 
452    Input Parameter:
453 .   v1 - the double
454 
455 
456    Level: beginner
457 
458 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
459 
460 M*/
461 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
462 
463 /*MC
464    PetscSqr - Returns the square of a number
465 
466    Synopsis:
467    #include <petscmath.h>
468    type sqr PetscSqr(type v1)
469 
470    Not Collective
471 
472    Input Parameter:
473 .   v1 - the value
474 
475    Notes: type can be integer or floating point value
476 
477    Level: beginner
478 
479 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
480 
481 M*/
482 #define PetscSqr(a)     ((a)*(a))
483 
484 /* ----------------------------------------------------------------------------*/
485 /*
486      Basic constants
487 */
488 #if defined(PETSC_USE_REAL___FLOAT128)
489 #define PETSC_PI                 M_PIq
490 #elif defined(M_PI)
491 #define PETSC_PI                 M_PI
492 #else
493 #define PETSC_PI                 3.14159265358979323846264338327950288419716939937510582
494 #endif
495 
496 #if !defined(PETSC_USE_64BIT_INDICES)
497 #define PETSC_MAX_INT            2147483647
498 #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
499 #else
500 #define PETSC_MAX_INT            9223372036854775807L
501 #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
502 #endif
503 
504 #if defined(PETSC_USE_REAL_SINGLE)
505 #  define PETSC_MAX_REAL                3.40282346638528860e+38F
506 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
507 #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
508 #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
509 #  define PETSC_SMALL                   1.e-5
510 #elif defined(PETSC_USE_REAL_DOUBLE)
511 #  define PETSC_MAX_REAL                1.7976931348623157e+308
512 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
513 #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
514 #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
515 #  define PETSC_SMALL                   1.e-10
516 #elif defined(PETSC_USE_REAL___FLOAT128)
517 #  define PETSC_MAX_REAL                FLT128_MAX
518 #  define PETSC_MIN_REAL                -FLT128_MAX
519 #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
520 #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17q
521 #  define PETSC_SMALL                   1.e-20q
522 #endif
523 
524 #define PETSC_INFINITY                PETSC_MAX_REAL/4.0
525 #define PETSC_NINFINITY              -PETSC_INFINITY
526 
527 PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
528 PETSC_EXTERN PetscErrorCode PetscIsNanReal(PetscReal);
529 PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
530 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
531 PETSC_STATIC_INLINE PetscErrorCode PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));}
532 PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}
533 
534 /*
535     These macros are currently hardwired to match the regular data types, so there is no support for a different
536     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
537  */
538 #define MPIU_MATSCALAR MPIU_SCALAR
539 typedef PetscScalar MatScalar;
540 typedef PetscReal MatReal;
541 
542 struct petsc_mpiu_2scalar {PetscScalar a,b;};
543 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
544 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
545 struct petsc_mpiu_2int {PetscInt a,b;};
546 PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
547 #else
548 #define MPIU_2INT MPI_2INT
549 #endif
550 
551 PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
552 {
553   PetscInt result = 1;
554   while (power) {
555     if (power & 1) result *= base;
556     power >>= 1;
557     base *= base;
558   }
559   return result;
560 }
561 
562 PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
563 {
564   PetscReal result = 1;
565   if (power < 0) {
566     power = -power;
567     base  = ((PetscReal)1)/base;
568   }
569   while (power) {
570     if (power & 1) result *= base;
571     power >>= 1;
572     base *= base;
573   }
574   return result;
575 }
576 
577 PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
578 {
579   PetscScalar result = 1;
580   if (power < 0) {
581     power = -power;
582     base  = ((PetscReal)1)/base;
583   }
584   while (power) {
585     if (power & 1) result *= base;
586     power >>= 1;
587     base *= base;
588   }
589   return result;
590 }
591 
592 PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
593 {
594   PetscScalar cpower = power;
595   return PetscPowScalar(base,cpower);
596 }
597 
598 #ifndef PETSC_HAVE_LOG2
599 PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n)
600 {
601   return PetscLogReal(n)/PetscLogReal(2.0);
602 }
603 #endif
604 #endif
605