xref: /petsc/include/petscmath.h (revision 3c48a1e8da19189ff2402a4e41a2fc082d52c349)
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 double 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: Warning it needs a
59    C99 compliant compiler to work...
60  */
61 
62 #if defined(PETSC_USE_SCALAR_SINGLE)
63 typedef float complex PetscScalar;
64 
65 #define PetscRealPart(a)      crealf(a)
66 #define PetscImaginaryPart(a) cimagf(a)
67 #define PetscAbsScalar(a)     cabsf(a)
68 #define PetscConj(a)          conjf(a)
69 #define PetscSqrtScalar(a)    csqrtf(a)
70 #define PetscPowScalar(a,b)   cpowf(a,b)
71 #define PetscExpScalar(a)     cexpf(a)
72 #define PetscLogScalar(a)     clogf(a)
73 #define PetscSinScalar(a)     csinf(a)
74 #define PetscCosScalar(a)     ccosf(a)
75 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
76 typedef long double complex PetscScalar;
77 
78 #define PetscRealPart(a)      creall(a)
79 #define PetscImaginaryPart(a) cimagl(a)
80 #define PetscAbsScalar(a)     cabsl(a)
81 #define PetscConj(a)          conjl(a)
82 #define PetscSqrtScalar(a)    csqrtl(a)
83 #define PetscPowScalar(a,b)   cpowl(a,b)
84 #define PetscExpScalar(a)     cexpl(a)
85 #define PetscLogScalar(a)     clogl(a)
86 #define PetscSinScalar(a)     csinl(a)
87 #define PetscCosScalar(a)     ccosl(a)
88 
89 #else
90 typedef double complex PetscScalar;
91 
92 #define PetscRealPart(a)      creal(a)
93 #define PetscImaginaryPart(a) cimag(a)
94 #define PetscAbsScalar(a)     cabs(a)
95 #define PetscConj(a)          conj(a)
96 #define PetscSqrtScalar(a)    csqrt(a)
97 #define PetscPowScalar(a,b)   cpow(a,b)
98 #define PetscExpScalar(a)     cexp(a)
99 #define PetscLogScalar(a)     clog(a)
100 #define PetscSinScalar(a)     csin(a)
101 #define PetscCosScalar(a)     ccos(a)
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 #else
113 #define MPIU_SCALAR         MPI_C_DOUBLE_COMPLEX
114 #endif
115 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
116 #define MPIU_MATSCALAR        ??Notdone
117 #else
118 #define MPIU_MATSCALAR      MPI_C_DOUBLE_COMPLEX
119 #endif
120 
121 
122 /* Compiling for real numbers only */
123 #else
124 #  if defined(PETSC_USE_SCALAR_SINGLE)
125 #    define MPIU_SCALAR           MPI_FLOAT
126 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
127 #    define MPIU_SCALAR           MPI_LONG_DOUBLE
128 #  else
129 #    define MPIU_SCALAR           MPI_DOUBLE
130 #  endif
131 #  if defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
132 #    define MPIU_MATSCALAR        MPI_FLOAT
133 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
134 #    define MPIU_MATSCALAR        MPI_LONG_DOUBLE
135 #  else
136 #    define MPIU_MATSCALAR        MPI_DOUBLE
137 #  endif
138 #  define PetscRealPart(a)      (a)
139 #  define PetscImaginaryPart(a) (0.)
140 #  define PetscAbsScalar(a)     (((a)<0.0)   ? -(a) : (a))
141 #  define PetscConj(a)          (a)
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 
149 #  if defined(PETSC_USE_SCALAR_SINGLE)
150   typedef float PetscScalar;
151 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
152   typedef long double PetscScalar;
153 #  else
154   typedef double PetscScalar;
155 #  endif
156 #endif
157 
158 #if defined(PETSC_USE_SCALAR_SINGLE)
159 #  define MPIU_REAL   MPI_FLOAT
160 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
161 #  define MPIU_REAL   MPI_LONG_DOUBLE
162 #else
163 #  define MPIU_REAL   MPI_DOUBLE
164 #endif
165 
166 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
167 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
168 /*
169        Allows compiling PETSc so that matrix values are stored in
170    single precision but all other objects still use double
171    precision. This does not work for complex numbers in that case
172    it remains double
173 
174           EXPERIMENTAL! NOT YET COMPLETELY WORKING
175 */
176 
177 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
178 typedef float MatScalar;
179 #else
180 typedef PetscScalar MatScalar;
181 #endif
182 
183 #if defined(PETSC_USE_SCALAR_SINGLE)
184   typedef float PetscReal;
185 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
186   typedef long double PetscReal;
187 #else
188   typedef double PetscReal;
189 #endif
190 
191 #if defined(PETSC_USE_COMPLEX)
192 typedef PetscReal MatReal;
193 #elif defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
194 typedef float MatReal;
195 #else
196 typedef PetscReal MatReal;
197 #endif
198 
199 
200 /* --------------------------------------------------------------------------*/
201 
202 /*
203    Certain objects may be created using either single or double precision.
204    This is currently not used.
205 */
206 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
207 
208 /* PETSC_i is the imaginary number, i */
209 extern  PetscScalar  PETSC_i;
210 
211 /*MC
212    PetscMin - Returns minimum of two numbers
213 
214    Synopsis:
215    type PetscMin(type v1,type v2)
216 
217    Not Collective
218 
219    Input Parameter:
220 +  v1 - first value to find minimum of
221 -  v2 - second value to find minimum of
222 
223 
224    Notes: type can be integer or floating point value
225 
226    Level: beginner
227 
228 
229 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
230 
231 M*/
232 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
233 
234 /*MC
235    PetscMax - Returns maxium of two numbers
236 
237    Synopsis:
238    type max PetscMax(type v1,type v2)
239 
240    Not Collective
241 
242    Input Parameter:
243 +  v1 - first value to find maximum of
244 -  v2 - second value to find maximum of
245 
246    Notes: type can be integer or floating point value
247 
248    Level: beginner
249 
250 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
251 
252 M*/
253 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
254 
255 /*MC
256    PetscAbsInt - Returns the absolute value of an integer
257 
258    Synopsis:
259    int abs PetscAbsInt(int v1)
260 
261    Not Collective
262 
263    Input Parameter:
264 .   v1 - the integer
265 
266    Level: beginner
267 
268 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
269 
270 M*/
271 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
272 
273 /*MC
274    PetscAbsReal - Returns the absolute value of an real number
275 
276    Synopsis:
277    Real abs PetscAbsReal(PetscReal v1)
278 
279    Not Collective
280 
281    Input Parameter:
282 .   v1 - the double
283 
284 
285    Level: beginner
286 
287 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
288 
289 M*/
290 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
291 
292 /*MC
293    PetscSqr - Returns the square of a number
294 
295    Synopsis:
296    type sqr PetscSqr(type v1)
297 
298    Not Collective
299 
300    Input Parameter:
301 .   v1 - the value
302 
303    Notes: type can be integer or floating point value
304 
305    Level: beginner
306 
307 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
308 
309 M*/
310 #define PetscSqr(a)     ((a)*(a))
311 
312 /* ----------------------------------------------------------------------------*/
313 /*
314      Basic constants - These should be done much better
315 */
316 #define PETSC_PI                 3.14159265358979323846264
317 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
318 #define PETSC_MAX_INT            2147483647
319 #define PETSC_MIN_INT            -2147483647
320 
321 #if defined(PETSC_USE_SCALAR_SINGLE)
322 #  define PETSC_MAX                     1.e30
323 #  define PETSC_MIN                    -1.e30
324 #  define PETSC_MACHINE_EPSILON         1.e-7
325 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
326 #  define PETSC_SMALL                   1.e-5
327 #else
328 #  define PETSC_MAX                     1.e300
329 #  define PETSC_MIN                    -1.e300
330 #  define PETSC_MACHINE_EPSILON         1.e-14
331 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
332 #  define PETSC_SMALL                   1.e-10
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_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
357 /* I had to introduce these inline functions because the C++ <valarray> header invalidates isinf(), making it std::isinf() */
358 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
359   return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a));
360 }
361 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
362   return isinf(a) || isnan(a);
363 }
364 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
365 #if defined(PETSC_HAVE_FLOAT_H)
366 #include "float.h"  /* windows defines _finite() in float.h */
367 #endif
368 #if defined(PETSC_HAVE_IEEEFP_H)
369 #include "ieeefp.h"  /* Solaris prototypes these here */
370 #endif
371 #define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)))
372 #define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a))
373 #else
374 #define PetscIsInfOrNanScalar(a) ((a - a) != 0.0)
375 #define PetscIsInfOrNanReal(a) ((a - a) != 0.0)
376 #endif
377 
378 
379 /* ----------------------------------------------------------------------------*/
380 /*
381     PetscLogDouble variables are used to contain double precision numbers
382   that are not used in the numerical computations, but rather in logging,
383   timing etc.
384 */
385 typedef double PetscLogDouble;
386 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
387 
388 #define PassiveReal   PetscReal
389 #define PassiveScalar PetscScalar
390 
391 
392 PETSC_EXTERN_CXX_END
393 #endif
394