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