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