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