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