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