xref: /petsc/include/petscmath.h (revision 9b08a59868f6db739c6debaa370dc27c6bb27ca0)
1 /*
2 
3       PETSc mathematics include file. Defines certain basic mathematical
4     constants and functions for working with single and double precision
5     floating point numbers as well as complex and integers.
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 PETSC_EXTERN_CXX_BEGIN
15 
16 extern  MPI_Datatype  MPIU_2SCALAR;
17 extern  MPI_Datatype  MPIU_2INT;
18 
19 /*
20 
21      Defines operations that are different for complex and real numbers;
22    note that one cannot really mix the use of complex and real in the same
23    PETSc program. All PETSc objects in one program are built around the object
24    PetscScalar which is either always a real or a complex.
25 
26 */
27 
28 #define PetscExpPassiveScalar(a) PetscExpScalar()
29 
30 /*
31     Complex number definitions
32  */
33 #if defined(PETSC_USE_COMPLEX)
34 #if defined(PETSC_CLANGUAGE_CXX)
35 /* C++ support of complex number */
36 #include <complex>
37 
38 #define PetscRealPart(a)      (a).real()
39 #define PetscImaginaryPart(a) (a).imag()
40 #define PetscAbsScalar(a)     std::abs(a)
41 #define PetscConj(a)          std::conj(a)
42 #define PetscSqrtScalar(a)    std::sqrt(a)
43 #define PetscPowScalar(a,b)   std::pow(a,b)
44 #define PetscExpScalar(a)     std::exp(a)
45 #define PetscLogScalar(a)     std::log(a)
46 #define PetscSinScalar(a)     std::sin(a)
47 #define PetscCosScalar(a)     std::cos(a)
48 
49 #if defined(PETSC_USE_REAL_SINGLE)
50 typedef std::complex<float> PetscScalar;
51 #elif defined(PETSC_USE_REAL_DOUBLE)
52 typedef std::complex<double> PetscScalar;
53 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
54 typedef std::complex<long double> PetscScalar;
55 #endif /* PETSC_USE_REAL_* */
56 
57 #else /* PETSC_CLANGUAGE_CXX */
58 /*  C support of complex numbers: Requires C99 compliant compiler*/
59 #include <complex.h>
60 
61 #if defined(PETSC_USE_REAL_SINGLE)
62 typedef float complex PetscScalar;
63 
64 #define PetscRealPart(a)      crealf(a)
65 #define PetscImaginaryPart(a) cimagf(a)
66 #define PetscAbsScalar(a)     cabsf(a)
67 #define PetscConj(a)          conjf(a)
68 #define PetscSqrtScalar(a)    csqrtf(a)
69 #define PetscPowScalar(a,b)   cpowf(a,b)
70 #define PetscExpScalar(a)     cexpf(a)
71 #define PetscLogScalar(a)     clogf(a)
72 #define PetscSinScalar(a)     csinf(a)
73 #define PetscCosScalar(a)     ccosf(a)
74 
75 #elif defined(PETSC_USE_REAL_DOUBLE)
76 typedef double complex PetscScalar;
77 
78 #define PetscRealPart(a)      creal(a)
79 #define PetscImaginaryPart(a) cimag(a)
80 #define PetscAbsScalar(a)     cabs(a)
81 #define PetscConj(a)          conj(a)
82 #define PetscSqrtScalar(a)    csqrt(a)
83 #define PetscPowScalar(a,b)   cpow(a,b)
84 #define PetscExpScalar(a)     cexp(a)
85 #define PetscLogScalar(a)     clog(a)
86 #define PetscSinScalar(a)     csin(a)
87 #define PetscCosScalar(a)     ccos(a)
88 
89 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
90 typedef long double complex PetscScalar;
91 
92 #define PetscRealPart(a)      creall(a)
93 #define PetscImaginaryPart(a) cimagl(a)
94 #define PetscAbsScalar(a)     cabsl(a)
95 #define PetscConj(a)          conjl(a)
96 #define PetscSqrtScalar(a)    csqrtl(a)
97 #define PetscPowScalar(a,b)   cpowl(a,b)
98 #define PetscExpScalar(a)     cexpl(a)
99 #define PetscLogScalar(a)     clogl(a)
100 #define PetscSinScalar(a)     csinl(a)
101 #define PetscCosScalar(a)     ccosl(a)
102 
103 #endif /* PETSC_USE_REAL_* */
104 #endif /* PETSC_CLANGUAGE_CXX */
105 
106 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
107 extern  MPI_Datatype  MPI_C_DOUBLE_COMPLEX;
108 extern  MPI_Datatype  MPI_C_COMPLEX;
109 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
110 
111 #if defined(PETSC_USE_REAL_SINGLE)
112 #define MPIU_SCALAR MPI_C_COMPLEX
113 #elif defined(PETSC_USE_REAL_DOUBLE)
114 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX
115 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
116 #define MPIU_SCALAR error
117 #endif /* PETSC_USE_REAL_* */
118 
119 /*
120     real number definitions
121  */
122 #else /* PETSC_USE_COMPLEX */
123 #if defined(PETSC_USE_REAL_SINGLE)
124 #define MPIU_SCALAR           MPI_FLOAT
125 typedef float PetscScalar;
126 #elif defined(PETSC_USE_REAL_DOUBLE)
127 #define MPIU_SCALAR           MPI_DOUBLE
128 typedef double PetscScalar;
129 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
130 #define MPIU_SCALAR           MPI_LONG_DOUBLE
131 typedef long double PetscScalar;
132 #elif defined(PETSC_USE_REAL___FLOAT128)
133 extern MPI_Datatype MPIU___FLOAT128;
134 #define MPIU_SCALAR MPIU___FLOAT128
135 typedef __float128 PetscScalar;
136 #endif /* PETSC_USE_REAL_* */
137 #define PetscRealPart(a)      (a)
138 #define PetscImaginaryPart(a) (0.)
139 #define PetscAbsScalar(a)     (((a)<0.0)   ? -(a) : (a))
140 #define PetscConj(a)          (a)
141 #if !defined(PETSC_USE_REAL___FLOAT128)
142 #define PetscSqrtScalar(a)    sqrt(a)
143 #define PetscPowScalar(a,b)   pow(a,b)
144 #define PetscExpScalar(a)     exp(a)
145 #define PetscLogScalar(a)     log(a)
146 #define PetscSinScalar(a)     sin(a)
147 #define PetscCosScalar(a)     cos(a)
148 #else /* PETSC_USE_REAL___FLOAT128 */
149 #include <quadmath.h>
150 #define PetscSqrtScalar(a)    sqrtq(a)
151 #define PetscPowScalar(a,b)   powq(a,b)
152 #define PetscExpScalar(a)     expq(a)
153 #define PetscLogScalar(a)     logq(a)
154 #define PetscSinScalar(a)     sinq(a)
155 #define PetscCosScalar(a)     cosq(a)
156 #endif /* PETSC_USE_REAL___FLOAT128 */
157 
158 #endif /* PETSC_USE_COMPLEX */
159 
160 #if defined(PETSC_USE_REAL_SINGLE)
161 #define MPIU_REAL   MPI_FLOAT
162 typedef float PetscReal;
163 #elif defined(PETSC_USE_REAL_DOUBLE)
164 #define MPIU_REAL   MPI_DOUBLE
165 typedef double PetscReal;
166 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
167 #define MPIU_REAL   MPI_LONG_DOUBLE
168 typedef long double PetscReal;
169 #elif defined(PETSC_USE_REAL___FLOAT128)
170 #define MPIU_REAL MPIU___FLOAT128
171 typedef __float128 PetscReal;
172 #endif /* PETSC_USE_REAL_* */
173 
174 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
175 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
176 
177 /* --------------------------------------------------------------------------*/
178 
179 /*
180    Certain objects may be created using either single or double precision.
181    This is currently not used.
182 */
183 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
184 
185 /* PETSC_i is the imaginary number, i */
186 extern  PetscScalar  PETSC_i;
187 
188 /*MC
189    PetscMin - Returns minimum of two numbers
190 
191    Synopsis:
192    type PetscMin(type v1,type v2)
193 
194    Not Collective
195 
196    Input Parameter:
197 +  v1 - first value to find minimum of
198 -  v2 - second value to find minimum of
199 
200 
201    Notes: type can be integer or floating point value
202 
203    Level: beginner
204 
205 
206 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
207 
208 M*/
209 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
210 
211 /*MC
212    PetscMax - Returns maxium of two numbers
213 
214    Synopsis:
215    type max PetscMax(type v1,type v2)
216 
217    Not Collective
218 
219    Input Parameter:
220 +  v1 - first value to find maximum of
221 -  v2 - second value to find maximum of
222 
223    Notes: type can be integer or floating point value
224 
225    Level: beginner
226 
227 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
228 
229 M*/
230 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
231 
232 /*MC
233    PetscAbsInt - Returns the absolute value of an integer
234 
235    Synopsis:
236    int abs PetscAbsInt(int v1)
237 
238    Not Collective
239 
240    Input Parameter:
241 .   v1 - the integer
242 
243    Level: beginner
244 
245 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
246 
247 M*/
248 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
249 
250 /*MC
251    PetscAbsReal - Returns the absolute value of an real number
252 
253    Synopsis:
254    Real abs PetscAbsReal(PetscReal v1)
255 
256    Not Collective
257 
258    Input Parameter:
259 .   v1 - the double
260 
261 
262    Level: beginner
263 
264 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
265 
266 M*/
267 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
268 
269 /*MC
270    PetscSqr - Returns the square of a number
271 
272    Synopsis:
273    type sqr PetscSqr(type v1)
274 
275    Not Collective
276 
277    Input Parameter:
278 .   v1 - the value
279 
280    Notes: type can be integer or floating point value
281 
282    Level: beginner
283 
284 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
285 
286 M*/
287 #define PetscSqr(a)     ((a)*(a))
288 
289 /* ----------------------------------------------------------------------------*/
290 /*
291      Basic constants
292 */
293 #if defined(PETSC_USE_REAL___FLOAT128)
294 #define PETSC_PI                 M_PIq
295 #elif defined(M_PI)
296 #define PETSC_PI                 M_PI
297 #else
298 #define PETSC_PI                 3.14159265358979323846264
299 #endif
300 
301 
302 #define PETSC_MAX_INT            2147483647
303 #define PETSC_MIN_INT            -2147483647
304 
305 #if defined(PETSC_USE_REAL_SINGLE)
306 #if defined(MAXFLOAT)
307 #  define PETSC_MAX_REAL                 MAXFLOAT
308 #else
309 #  define PETSC_MAX_REAL                1.e30
310 #endif
311 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
312 #  define PETSC_MACHINE_EPSILON         1.e-7
313 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
314 #  define PETSC_SMALL                   1.e-5
315 #elif defined(PETSC_USE_REAL_DOUBLE)
316 #  define PETSC_MAX_REAL                1.e300
317 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
318 #  define PETSC_MACHINE_EPSILON         1.e-14
319 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
320 #  define PETSC_SMALL                   1.e-10
321 #elif defined(PETSC_USE_REAL___FLOAT128)
322 #  define PETSC_MAX_REAL                FLT128_MAX
323 #  define PETSC_MIN_REAL                -FLT128_MAX
324 #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
325 #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17
326 #  define PETSC_SMALL                   1.e-20
327 #endif
328 
329 #if defined PETSC_HAVE_ADIC
330 /* Use MPI_Allreduce when ADIC is not available. */
331 extern PetscErrorCode  PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*);
332 extern PetscErrorCode  PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*);
333 extern PetscErrorCode  PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*);
334 #endif
335 
336 /*MC
337       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
338 
339     Input Parameter:
340 .     a - the double
341 
342 
343      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
344       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
345       out this form, thus removing the check.
346 
347      Level: beginner
348 
349 M*/
350 #if defined(PETSC_USE_REAL___FLOAT128)
351 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
352   return isinfq(PetscAbsScalar(a)) || isnanq(PetscAbsScalar(a));
353 }
354 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
355   return isinfq(a) || isnanq(a);
356 }
357 #elif defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) && !defined(_GLIBCXX_CMATH)
358 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
359   return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a));
360 }
361 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
362   return isinf(a) || isnan(a);
363 }
364 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
365 #if defined(PETSC_HAVE_FLOAT_H)
366 #include "float.h"  /* Microsoft Windows defines _finite() in float.h */
367 #endif
368 #if defined(PETSC_HAVE_IEEEFP_H)
369 #include "ieeefp.h"  /* Solaris prototypes these here */
370 #endif
371 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
372   return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a));
373 }
374 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
375   return !_finite(a) || _isnan(a);
376 }
377 #else
378 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
379   return  ((a - a) != 0.0);
380 }
381 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
382   return ((a - a) != 0.0);
383 }
384 #endif
385 
386 
387 /* ----------------------------------------------------------------------------*/
388 /*
389     PetscLogDouble variables are used to contain double precision numbers
390   that are not used in the numerical computations, but rather in logging,
391   timing etc.
392 */
393 typedef double PetscLogDouble;
394 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
395 
396 #define PassiveReal   PetscReal
397 #define PassiveScalar PetscScalar
398 
399 /*
400     These macros are currently hardwired to match the regular data types, so there is no support for a different
401     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
402  */
403 #define MPIU_MATSCALAR MPIU_SCALAR
404 typedef PetscScalar MatScalar;
405 typedef PetscReal MatReal;
406 
407 
408 PETSC_EXTERN_CXX_END
409 #endif
410