xref: /petsc/include/petscmath.h (revision fad8df86d05f3e620b0625d4f57cb9ae9c96a958)
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 petsc.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 PETSC_DLLEXPORT MPIU_2SCALAR;
17 extern  MPI_Datatype PETSC_DLLEXPORT 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    C90 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 PETSC_DLLEXPORT MPI_C_DOUBLE_COMPLEX;
109 #endif
110 
111 #define MPIU_SCALAR         MPI_C_DOUBLE_COMPLEX
112 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
113 #define MPIU_MATSCALAR        ??Notdone
114 #else
115 #define MPIU_MATSCALAR      MPI_C_DOUBLE_COMPLEX
116 #endif
117 
118 
119 /* Compiling for real numbers only */
120 #else
121 #  if defined(PETSC_USE_SCALAR_SINGLE)
122 #    define MPIU_SCALAR           MPI_FLOAT
123 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
124 #    define MPIU_SCALAR           MPI_LONG_DOUBLE
125 #  elif defined(PETSC_USE_SCALAR_INT)
126 #    define MPIU_SCALAR           MPI_INT
127 #  elif defined(PETSC_USE_SCALAR_QD_DD)
128 #    define MPIU_SCALAR           MPIU_QD_DD
129 #  else
130 #    define MPIU_SCALAR           MPI_DOUBLE
131 #  endif
132 #  if defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
133 #    define MPIU_MATSCALAR        MPI_FLOAT
134 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
135 #    define MPIU_MATSCALAR        MPI_LONG_DOUBLE
136 #  elif defined(PETSC_USE_SCALAR_INT)
137 #    define MPIU_MATSCALAR        MPI_INT
138 #  elif defined(PETSC_USE_SCALAR_QD_DD)
139 #    define MPIU_MATSCALAR        MPIU_QD_DD
140 #  else
141 #    define MPIU_MATSCALAR        MPI_DOUBLE
142 #  endif
143 #  define PetscRealPart(a)      (a)
144 #  define PetscImaginaryPart(a) (0.)
145 #  define PetscAbsScalar(a)     (((a)<0.0)   ? -(a) : (a))
146 #  define PetscConj(a)          (a)
147 #  define PetscSqrtScalar(a)    sqrt(a)
148 #  define PetscPowScalar(a,b)   pow(a,b)
149 #  define PetscExpScalar(a)     exp(a)
150 #  define PetscLogScalar(a)     log(a)
151 #  define PetscSinScalar(a)     sin(a)
152 #  define PetscCosScalar(a)     cos(a)
153 
154 #  if defined(PETSC_USE_SCALAR_SINGLE)
155   typedef float PetscScalar;
156 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
157   typedef long double PetscScalar;
158 #  elif defined(PETSC_USE_SCALAR_INT)
159   typedef int PetscScalar;
160 #  elif defined(PETSC_USE_SCALAR_QD_DD)
161 #  include "qd/dd_real.h"
162   typedef dd_real PetscScalar;
163 #  else
164   typedef double PetscScalar;
165 #  endif
166 #endif
167 
168 #if defined(PETSC_USE_SCALAR_SINGLE)
169 #  define MPIU_REAL   MPI_FLOAT
170 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
171 #  define MPIU_REAL   MPI_LONG_DOUBLE
172 #elif defined(PETSC_USE_SCALAR_INT)
173 #  define MPIU_REAL   MPI_INT
174 #elif defined(PETSC_USE_SCALAR_QD_DD)
175 #  define MPIU_REAL   MPIU_QD_DD
176 #else
177 #  define MPIU_REAL   MPI_DOUBLE
178 #endif
179 
180 #if defined(PETSC_USE_SCALAR_QD_DD)
181 extern  MPI_Datatype PETSC_DLLEXPORT MPIU_QD_DD;
182 #endif
183 
184 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
185 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
186 /*
187        Allows compiling PETSc so that matrix values are stored in
188    single precision but all other objects still use double
189    precision. This does not work for complex numbers in that case
190    it remains double
191 
192           EXPERIMENTAL! NOT YET COMPLETELY WORKING
193 */
194 
195 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
196 typedef float MatScalar;
197 #else
198 typedef PetscScalar MatScalar;
199 #endif
200 
201 #if defined(PETSC_USE_SCALAR_SINGLE)
202   typedef float PetscReal;
203 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
204   typedef long double PetscReal;
205 #elif defined(PETSC_USE_SCALAR_INT)
206   typedef int PetscReal;
207 #elif defined(PETSC_USE_SCALAR_QD_DD)
208   typedef dd_real PetscReal;
209 #else
210   typedef double PetscReal;
211 #endif
212 
213 #if defined(PETSC_USE_COMPLEX)
214 typedef PetscReal MatReal;
215 #elif defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
216 typedef float MatReal;
217 #else
218 typedef PetscReal MatReal;
219 #endif
220 
221 
222 /* --------------------------------------------------------------------------*/
223 
224 /*
225    Certain objects may be created using either single
226   or double precision.
227 */
228 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_QD_DD } PetscScalarPrecision;
229 
230 /* PETSC_i is the imaginary number, i */
231 extern  PetscScalar PETSC_DLLEXPORT PETSC_i;
232 
233 /*MC
234    PetscMin - Returns minimum of two numbers
235 
236    Input Parameter:
237 +  v1 - first value to find minimum of
238 -  v2 - second value to find minimum of
239 
240    Synopsis:
241    type PetscMin(type v1,type v2)
242 
243    Notes: type can be integer or floating point value
244 
245    Level: beginner
246 
247 
248 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
249 
250 M*/
251 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
252 
253 /*MC
254    PetscMax - Returns maxium of two numbers
255 
256    Input Parameter:
257 +  v1 - first value to find maximum of
258 -  v2 - second value to find maximum of
259 
260    Synopsis:
261    type max PetscMax(type v1,type v2)
262 
263    Notes: type can be integer or floating point value
264 
265    Level: beginner
266 
267 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
268 
269 M*/
270 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
271 
272 /*MC
273    PetscAbsInt - Returns the absolute value of an integer
274 
275    Input Parameter:
276 .   v1 - the integer
277 
278    Synopsis:
279    int abs PetscAbsInt(int v1)
280 
281 
282    Level: beginner
283 
284 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
285 
286 M*/
287 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
288 
289 /*MC
290    PetscAbsReal - Returns the absolute value of an real number
291 
292    Input Parameter:
293 .   v1 - the double
294 
295    Synopsis:
296    int abs PetscAbsReal(PetscReal v1)
297 
298 
299    Level: beginner
300 
301 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
302 
303 M*/
304 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
305 
306 /*MC
307    PetscSqr - Returns the square of a number
308 
309    Input Parameter:
310 .   v1 - the value
311 
312    Synopsis:
313    type sqr PetscSqr(type v1)
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 #elif defined(PETSC_USE_SCALAR_QD_DD)
346 #  define PETSC_MAX                     1.e300
347 #  define PETSC_MIN                    -1.e300
348 #  define PETSC_MACHINE_EPSILON         1.e-30
349 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-15
350 #  define PETSC_SMALL                   1.e-25
351 #else
352 #  define PETSC_MAX                     1.e300
353 #  define PETSC_MIN                    -1.e300
354 #  define PETSC_MACHINE_EPSILON         1.e-14
355 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
356 #  define PETSC_SMALL                   1.e-10
357 #endif
358 
359 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal*,PetscReal*,MPI_Comm);
360 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal*,PetscReal*,MPI_Comm);
361 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar*,PetscScalar*,MPI_Comm);
362 
363 /*MC
364       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
365 
366     Input Parameter:
367 .     a - the double
368 
369 
370      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
371       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
372       out this form, thus removing the check.
373 
374      Level: beginner
375 
376 M*/
377 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
378 #define PetscIsInfOrNanScalar(a) (isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)))
379 #define PetscIsInfOrNanReal(a) (isinf(a) || isnan(a))
380 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
381 #if defined(PETSC_HAVE_FLOAT_H)
382 #include "float.h"  /* windows defines _finite() in float.h */
383 #endif
384 #if defined(PETSC_HAVE_IEEEFP_H)
385 #include "ieeefp.h"  /* Solaris prototypes these here */
386 #endif
387 #define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)))
388 #define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a))
389 #else
390 #define PetscIsInfOrNanScalar(a) ((a - a) != 0.0)
391 #define PetscIsInfOrNanReal(a) ((a - a) != 0.0)
392 #endif
393 
394 
395 /* ----------------------------------------------------------------------------*/
396 /*
397     PetscLogDouble variables are used to contain double precision numbers
398   that are not used in the numerical computations, but rather in logging,
399   timing etc.
400 */
401 typedef double PetscLogDouble;
402 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
403 
404 #define PassiveReal   PetscReal
405 #define PassiveScalar PetscScalar
406 
407 
408 PETSC_EXTERN_CXX_END
409 #endif
410