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