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