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