xref: /petsc/include/petscmath.h (revision 7556704393990e9a05104f18399364067eaa5e80)
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 extern  MPI_Datatype PETSC_DLLEXPORT MPIU_COMPLEX;
108 #define MPIU_SCALAR         MPIU_COMPLEX
109 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
110 #define MPIU_MATSCALAR        ??Notdone
111 #else
112 #define MPIU_MATSCALAR      MPIU_COMPLEX
113 #endif
114 
115 
116 /* Compiling for real numbers only */
117 #else
118 #  if defined(PETSC_USE_SCALAR_SINGLE)
119 #    define MPIU_SCALAR           MPI_FLOAT
120 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
121 #    define MPIU_SCALAR           MPI_LONG_DOUBLE
122 #  elif defined(PETSC_USE_SCALAR_INT)
123 #    define MPIU_SCALAR           MPI_INT
124 #  elif defined(PETSC_USE_SCALAR_QD_DD)
125 #    define MPIU_SCALAR           MPIU_QD_DD
126 #  else
127 #    define MPIU_SCALAR           MPI_DOUBLE
128 #  endif
129 #  if defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
130 #    define MPIU_MATSCALAR        MPI_FLOAT
131 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
132 #    define MPIU_MATSCALAR        MPI_LONG_DOUBLE
133 #  elif defined(PETSC_USE_SCALAR_INT)
134 #    define MPIU_MATSCALAR        MPI_INT
135 #  elif defined(PETSC_USE_SCALAR_QD_DD)
136 #    define MPIU_MATSCALAR        MPIU_QD_DD
137 #  else
138 #    define MPIU_MATSCALAR        MPI_DOUBLE
139 #  endif
140 #  define PetscRealPart(a)      (a)
141 #  define PetscImaginaryPart(a) (0.)
142 #  define PetscAbsScalar(a)     (((a)<0.0)   ? -(a) : (a))
143 #  define PetscConj(a)          (a)
144 #  define PetscSqrtScalar(a)    sqrt(a)
145 #  define PetscPowScalar(a,b)   pow(a,b)
146 #  define PetscExpScalar(a)     exp(a)
147 #  define PetscLogScalar(a)     log(a)
148 #  define PetscSinScalar(a)     sin(a)
149 #  define PetscCosScalar(a)     cos(a)
150 
151 #  if defined(PETSC_USE_SCALAR_SINGLE)
152   typedef float PetscScalar;
153 #  elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
154   typedef long double PetscScalar;
155 #  elif defined(PETSC_USE_SCALAR_INT)
156   typedef int PetscScalar;
157 #  elif defined(PETSC_USE_SCALAR_QD_DD)
158 #  include "qd/dd_real.h"
159   typedef dd_real PetscScalar;
160 #  else
161   typedef double PetscScalar;
162 #  endif
163 #endif
164 
165 #if defined(PETSC_USE_SCALAR_SINGLE)
166 #  define MPIU_REAL   MPI_FLOAT
167 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
168 #  define MPIU_REAL   MPI_LONG_DOUBLE
169 #elif defined(PETSC_USE_SCALAR_INT)
170 #  define MPIU_REAL   MPI_INT
171 #elif defined(PETSC_USE_SCALAR_QD_DD)
172 #  define MPIU_REAL   MPIU_QD_DD
173 #else
174 #  define MPIU_REAL   MPI_DOUBLE
175 #endif
176 
177 #if defined(PETSC_USE_SCALAR_QD_DD)
178 extern  MPI_Datatype PETSC_DLLEXPORT MPIU_QD_DD;
179 #endif
180 
181 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
182 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
183 /*
184        Allows compiling PETSc so that matrix values are stored in
185    single precision but all other objects still use double
186    precision. This does not work for complex numbers in that case
187    it remains double
188 
189           EXPERIMENTAL! NOT YET COMPLETELY WORKING
190 */
191 
192 #if defined(PETSC_USE_SCALAR_MAT_SINGLE)
193 typedef float MatScalar;
194 #else
195 typedef PetscScalar MatScalar;
196 #endif
197 
198 #if defined(PETSC_USE_SCALAR_SINGLE)
199   typedef float PetscReal;
200 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
201   typedef long double PetscReal;
202 #elif defined(PETSC_USE_SCALAR_INT)
203   typedef int PetscReal;
204 #elif defined(PETSC_USE_SCALAR_QD_DD)
205   typedef dd_real PetscReal;
206 #else
207   typedef double PetscReal;
208 #endif
209 
210 #if defined(PETSC_USE_COMPLEX)
211 typedef PetscReal MatReal;
212 #elif defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE)
213 typedef float MatReal;
214 #else
215 typedef PetscReal MatReal;
216 #endif
217 
218 
219 /* --------------------------------------------------------------------------*/
220 
221 /*
222    Certain objects may be created using either single
223   or double precision.
224 */
225 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_QD_DD } PetscScalarPrecision;
226 
227 /* PETSC_i is the imaginary number, i */
228 extern  PetscScalar PETSC_DLLEXPORT PETSC_i;
229 
230 /*MC
231    PetscMin - Returns minimum of two numbers
232 
233    Input Parameter:
234 +  v1 - first value to find minimum of
235 -  v2 - second value to find minimum of
236 
237    Synopsis:
238    type PetscMin(type v1,type v2)
239 
240    Notes: type can be integer or floating point value
241 
242    Level: beginner
243 
244 
245 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
246 
247 M*/
248 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
249 
250 /*MC
251    PetscMax - Returns maxium of two numbers
252 
253    Input Parameter:
254 +  v1 - first value to find maximum of
255 -  v2 - second value to find maximum of
256 
257    Synopsis:
258    type max PetscMax(type v1,type v2)
259 
260    Notes: type can be integer or floating point value
261 
262    Level: beginner
263 
264 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
265 
266 M*/
267 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
268 
269 /*MC
270    PetscAbsInt - Returns the absolute value of an integer
271 
272    Input Parameter:
273 .   v1 - the integer
274 
275    Synopsis:
276    int abs PetscAbsInt(int v1)
277 
278 
279    Level: beginner
280 
281 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
282 
283 M*/
284 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
285 
286 /*MC
287    PetscAbsReal - Returns the absolute value of an real number
288 
289    Input Parameter:
290 .   v1 - the double
291 
292    Synopsis:
293    int abs PetscAbsReal(PetscReal v1)
294 
295 
296    Level: beginner
297 
298 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
299 
300 M*/
301 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
302 
303 /*MC
304    PetscSqr - Returns the square of a number
305 
306    Input Parameter:
307 .   v1 - the value
308 
309    Synopsis:
310    type sqr PetscSqr(type v1)
311 
312    Notes: type can be integer or floating point value
313 
314    Level: beginner
315 
316 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
317 
318 M*/
319 #define PetscSqr(a)     ((a)*(a))
320 
321 /* ----------------------------------------------------------------------------*/
322 /*
323      Basic constants - These should be done much better
324 */
325 #define PETSC_PI                 3.14159265358979323846264
326 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
327 #define PETSC_MAX_INT            2147483647
328 #define PETSC_MIN_INT            -2147483647
329 
330 #if defined(PETSC_USE_SCALAR_SINGLE)
331 #  define PETSC_MAX                     1.e30
332 #  define PETSC_MIN                    -1.e30
333 #  define PETSC_MACHINE_EPSILON         1.e-7
334 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
335 #  define PETSC_SMALL                   1.e-5
336 #elif defined(PETSC_USE_SCALAR_INT)
337 #  define PETSC_MAX                     PETSC_MAX_INT
338 #  define PETSC_MIN                     PETSC_MIN_INT
339 #  define PETSC_MACHINE_EPSILON         1
340 #  define PETSC_SQRT_MACHINE_EPSILON    1
341 #  define PETSC_SMALL                   0
342 #elif defined(PETSC_USE_SCALAR_QD_DD)
343 #  define PETSC_MAX                     1.e300
344 #  define PETSC_MIN                    -1.e300
345 #  define PETSC_MACHINE_EPSILON         1.e-30
346 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-15
347 #  define PETSC_SMALL                   1.e-25
348 #else
349 #  define PETSC_MAX                     1.e300
350 #  define PETSC_MIN                    -1.e300
351 #  define PETSC_MACHINE_EPSILON         1.e-14
352 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
353 #  define PETSC_SMALL                   1.e-10
354 #endif
355 
356 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal*,PetscReal*,MPI_Comm);
357 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal*,PetscReal*,MPI_Comm);
358 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar*,PetscScalar*,MPI_Comm);
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