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