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