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