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