xref: /petsc/include/petscmath.h (revision d9822059a04b3bd78629edfbf3ebfea74b8f6e57)
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_SCALAR_SINGLE)
50 typedef std::complex<float> PetscScalar;
51 #elif defined(PETSC_USE_SCALAR_DOUBLE)
52 typedef std::complex<double> PetscScalar;
53 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
54 typedef std::complex<long double> PetscScalar;
55 #endif /* PETSC_USE_SCALAR_* */
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_SCALAR_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_SCALAR_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_SCALAR_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_SCALAR_* */
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_SCALAR_SINGLE)
112 #define MPIU_SCALAR MPI_C_COMPLEX
113 #elif defined(PETSC_USE_SCALAR_DOUBLE)
114 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX
115 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
116 #define MPIU_SCALAR error
117 #endif /* PETSC_USE_SCALAR_* */
118 
119 /*
120     real number definitions
121  */
122 #else /* PETSC_USE_COMPLEX */
123 #if defined(PETSC_USE_SCALAR_SINGLE)
124 #define MPIU_SCALAR           MPI_FLOAT
125 typedef float PetscScalar;
126 #elif defined(PETSC_USE_SCALAR_DOUBLE)
127 #define MPIU_SCALAR           MPI_DOUBLE
128 typedef double PetscScalar;
129 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
130 #define MPIU_SCALAR           MPI_LONG_DOUBLE
131 typedef long double PetscScalar;
132 #elif defined(PETSC_USE_SCALAR___FLOAT128)
133 extern MPI_Datatype MPIU___FLOAT128;
134 #define MPIU_SCALAR MPIU___FLOAT128
135 typedef __float128 PetscScalar;
136 #endif /* PETSC_USE_SCALAR_* */
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_SCALAR___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_SCALAR___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_SCALAR___FLOAT128 */
157 
158 #endif /* PETSC_USE_COMPLEX */
159 
160 #if defined(PETSC_USE_SCALAR_SINGLE)
161 #define MPIU_REAL   MPI_FLOAT
162 typedef float PetscReal;
163 #elif defined(PETSC_USE_SCALAR_DOUBLE)
164 #define MPIU_REAL   MPI_DOUBLE
165 typedef double PetscReal;
166 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
167 #define MPIU_REAL   MPI_LONG_DOUBLE
168 typedef long double PetscReal;
169 #elif defined(PETSC_USE_SCALAR___FLOAT128)
170 #define MPIU_REAL MPIU___FLOAT128
171 typedef __float128 PetscReal;
172 #endif /* PETSC_USE_SCALAR_* */
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 - These should be done much better
292 */
293 #define PETSC_PI                 3.14159265358979323846264
294 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
295 #define PETSC_MAX_INT            2147483647
296 #define PETSC_MIN_INT            -2147483647
297 
298 #if defined(PETSC_USE_SCALAR_SINGLE)
299 #  define PETSC_MAX                     1.e30
300 #  define PETSC_MIN                    -1.e30
301 #  define PETSC_MACHINE_EPSILON         1.e-7
302 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
303 #  define PETSC_SMALL                   1.e-5
304 #else
305 #  define PETSC_MAX                     1.e300
306 #  define PETSC_MIN                    -1.e300
307 #  define PETSC_MACHINE_EPSILON         1.e-14
308 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
309 #  define PETSC_SMALL                   1.e-10
310 #endif
311 
312 #if defined PETSC_HAVE_ADIC
313 /* Use MPI_Allreduce when ADIC is not available. */
314 extern PetscErrorCode  PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*);
315 extern PetscErrorCode  PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*);
316 extern PetscErrorCode  PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*);
317 #endif
318 
319 /*MC
320       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
321 
322     Input Parameter:
323 .     a - the double
324 
325 
326      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
327       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
328       out this form, thus removing the check.
329 
330      Level: beginner
331 
332 M*/
333 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
334 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
335   return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a));
336 }
337 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
338   return isinf(a) || isnan(a);
339 }
340 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
341 #if defined(PETSC_HAVE_FLOAT_H)
342 #include "float.h"  /* Microsoft Windows defines _finite() in float.h */
343 #endif
344 #if defined(PETSC_HAVE_IEEEFP_H)
345 #include "ieeefp.h"  /* Solaris prototypes these here */
346 #endif
347 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
348   return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a));
349 }
350 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
351   return !_finite(a) || _isnan(a);
352 }
353 #else
354 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
355   return  ((a - a) != 0.0);
356 }
357 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
358   return ((a - a) != 0.0);
359 }
360 #endif
361 
362 
363 /* ----------------------------------------------------------------------------*/
364 /*
365     PetscLogDouble variables are used to contain double precision numbers
366   that are not used in the numerical computations, but rather in logging,
367   timing etc.
368 */
369 typedef double PetscLogDouble;
370 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
371 
372 #define PassiveReal   PetscReal
373 #define PassiveScalar PetscScalar
374 
375 /*
376     These macros are currently hardwired to match the regular data types, so there is no support for a different
377     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
378  */
379 #define MPIU_MATSCALAR MPIU_SCALAR
380 typedef PetscScalar MatScalar;
381 typedef PetscReal MatReal;
382 
383 
384 PETSC_EXTERN_CXX_END
385 #endif
386