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