xref: /petsc/include/petscmath.h (revision 992144d0cb3c842d97cc8e5d51faae10c27f3335)
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_LONG_DOUBLE)
322 #  define PETSC_MAX_REAL                1.e4900L
323 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
324 #  define PETSC_MACHINE_EPSILON         1.e-18
325 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-9
326 #  define PETSC_SMALL                   1.e-13
327 #elif defined(PETSC_USE_REAL___FLOAT128)
328 #  define PETSC_MAX_REAL                FLT128_MAX
329 #  define PETSC_MIN_REAL                -FLT128_MAX
330 #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
331 #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17
332 #  define PETSC_SMALL                   1.e-20
333 #endif
334 
335 #if defined PETSC_HAVE_ADIC
336 /* Use MPI_Allreduce when ADIC is not available. */
337 extern PetscErrorCode  PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*);
338 extern PetscErrorCode  PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*);
339 extern PetscErrorCode  PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*);
340 #endif
341 
342 /*MC
343       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
344 
345     Input Parameter:
346 .     a - the double
347 
348 
349      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
350       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
351       out this form, thus removing the check.
352 
353      Level: beginner
354 
355 M*/
356 #if defined(PETSC_USE_REAL___FLOAT128)
357 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
358   return isinfq(PetscAbsScalar(a)) || isnanq(PetscAbsScalar(a));
359 }
360 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
361   return isinfq(a) || isnanq(a);
362 }
363 #elif defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) && !defined(_GLIBCXX_CMATH)
364 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
365   return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a));
366 }
367 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
368   return isinf(a) || isnan(a);
369 }
370 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
371 #if defined(PETSC_HAVE_FLOAT_H)
372 #include "float.h"  /* Microsoft Windows defines _finite() in float.h */
373 #endif
374 #if defined(PETSC_HAVE_IEEEFP_H)
375 #include "ieeefp.h"  /* Solaris prototypes these here */
376 #endif
377 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
378   return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a));
379 }
380 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
381   return !_finite(a) || _isnan(a);
382 }
383 #else
384 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
385   return  ((a - a) != 0.0);
386 }
387 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
388   return ((a - a) != 0.0);
389 }
390 #endif
391 
392 
393 /* ----------------------------------------------------------------------------*/
394 /*
395     PetscLogDouble variables are used to contain double precision numbers
396   that are not used in the numerical computations, but rather in logging,
397   timing etc.
398 */
399 typedef double PetscLogDouble;
400 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
401 
402 #define PassiveReal   PetscReal
403 #define PassiveScalar PetscScalar
404 
405 /*
406     These macros are currently hardwired to match the regular data types, so there is no support for a different
407     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
408  */
409 #define MPIU_MATSCALAR MPIU_SCALAR
410 typedef PetscScalar MatScalar;
411 typedef PetscReal MatReal;
412 
413 
414 PETSC_EXTERN_CXX_END
415 #endif
416