xref: /petsc/include/petscmath.h (revision 7c4f633dc6bb6149cca88d301ead35a99e103cbb)
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_SINGLE)
48 typedef std::complex<float> PetscScalar;
49 #elif defined(PETSC_USE_LONG_DOUBLE)
50 typedef std::complex<long double> PetscScalar;
51 #elif defined(PETSC_USE_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_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_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_MAT_SINGLE)
110 #define MPIU_MATSCALAR        ??Notdone
111 #else
112 #define MPIU_MATSCALAR      MPIU_COMPLEX
113 #endif
114 
115 /* Compiling for real numbers only */
116 #else
117 #  if defined(PETSC_USE_SINGLE)
118 #    define MPIU_SCALAR           MPI_FLOAT
119 #  elif defined(PETSC_USE_LONG_DOUBLE)
120 #    define MPIU_SCALAR           MPI_LONG_DOUBLE
121 #  elif defined(PETSC_INT)
122 #    define MPIU_INT              MPI_INT
123 #  else
124 #    define MPIU_SCALAR           MPI_DOUBLE
125 #  endif
126 #  if defined(PETSC_USE_MAT_SINGLE) || defined(PETSC_USE_SINGLE)
127 #    define MPIU_MATSCALAR        MPI_FLOAT
128 #  elif defined(PETSC_USE_LONG_DOUBLE)
129 #    define MPIU_MATSCALAR        MPI_LONG_DOUBLE
130 #  elif defined(PETSC_USE_INT)
131 #    define MPIU_MATSCALAR        MPI_INT
132 #  else
133 #    define MPIU_MATSCALAR        MPI_DOUBLE
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 #  define PetscSqrtScalar(a)    sqrt(a)
140 #  define PetscPowScalar(a,b)   pow(a,b)
141 #  define PetscExpScalar(a)     exp(a)
142 #  define PetscLogScalar(a)     log(a)
143 #  define PetscSinScalar(a)     sin(a)
144 #  define PetscCosScalar(a)     cos(a)
145 
146 #  if defined(PETSC_USE_SINGLE)
147   typedef float PetscScalar;
148 #  elif defined(PETSC_USE_LONG_DOUBLE)
149   typedef long double PetscScalar;
150 #  elif defined(PETSC_USE_INT)
151   typedef int PetscScalar;
152 #  else
153   typedef double PetscScalar;
154 #  endif
155 #endif
156 
157 #if defined(PETSC_USE_SINGLE)
158 #  define MPIU_REAL   MPI_FLOAT
159 #elif defined(PETSC_USE_LONG_DOUBLE)
160 #  define MPIU_REAL   MPI_LONG_DOUBLE
161 #elif defined(PETSC_USE_INT)
162 #  define MPIU_REAL   MPI_INT
163 #else
164 #  define MPIU_REAL   MPI_DOUBLE
165 #endif
166 
167 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
168 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
169 /*
170        Allows compiling PETSc so that matrix values are stored in
171    single precision but all other objects still use double
172    precision. This does not work for complex numbers in that case
173    it remains double
174 
175           EXPERIMENTAL! NOT YET COMPLETELY WORKING
176 */
177 
178 #if defined(PETSC_USE_MAT_SINGLE)
179 typedef float MatScalar;
180 #else
181 typedef PetscScalar MatScalar;
182 #endif
183 
184 #if defined(PETSC_USE_SINGLE)
185   typedef float PetscReal;
186 #elif defined(PETSC_USE_LONG_DOUBLE)
187   typedef long double PetscReal;
188 #elif defined(PETSC_USE_INT)
189   typedef int PetscReal;
190 #else
191   typedef double PetscReal;
192 #endif
193 
194 #if defined(PETSC_USE_COMPLEX)
195 typedef PetscReal MatReal;
196 #elif defined(PETSC_USE_MAT_SINGLE) || defined(PETSC_USE_SINGLE)
197 typedef float MatReal;
198 #else
199 typedef PetscReal MatReal;
200 #endif
201 
202 
203 /* --------------------------------------------------------------------------*/
204 
205 /*
206    Certain objects may be created using either single
207   or double precision.
208 */
209 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
210 
211 /* PETSC_i is the imaginary number, i */
212 extern  PetscScalar PETSC_DLLEXPORT PETSC_i;
213 
214 /*MC
215    PetscMin - Returns minimum of two numbers
216 
217    Input Parameter:
218 +  v1 - first value to find minimum of
219 -  v2 - second value to find minimum of
220 
221    Synopsis:
222    type PetscMin(type v1,type v2)
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    Input Parameter:
238 +  v1 - first value to find maximum of
239 -  v2 - second value to find maximum of
240 
241    Synopsis:
242    type max PetscMax(type v1,type v2)
243 
244    Notes: type can be integer or floating point value
245 
246    Level: beginner
247 
248 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
249 
250 M*/
251 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
252 
253 /*MC
254    PetscAbsInt - Returns the absolute value of an integer
255 
256    Input Parameter:
257 .   v1 - the integer
258 
259    Synopsis:
260    int abs PetscAbsInt(int v1)
261 
262 
263    Level: beginner
264 
265 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
266 
267 M*/
268 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
269 
270 /*MC
271    PetscAbsReal - Returns the absolute value of an real number
272 
273    Input Parameter:
274 .   v1 - the double
275 
276    Synopsis:
277    int abs PetscAbsReal(PetscReal v1)
278 
279 
280    Level: beginner
281 
282 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
283 
284 M*/
285 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
286 
287 /*MC
288    PetscSqr - Returns the square of a number
289 
290    Input Parameter:
291 .   v1 - the value
292 
293    Synopsis:
294    type sqr PetscSqr(type v1)
295 
296    Notes: type can be integer or floating point value
297 
298    Level: beginner
299 
300 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
301 
302 M*/
303 #define PetscSqr(a)     ((a)*(a))
304 
305 /* ----------------------------------------------------------------------------*/
306 /*
307      Basic constants - These should be done much better
308 */
309 #define PETSC_PI                 3.14159265358979323846264
310 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
311 #define PETSC_MAX_INT            1000000000
312 #define PETSC_MIN_INT            -1000000000
313 
314 #if defined(PETSC_USE_SINGLE)
315 #  define PETSC_MAX                     1.e30
316 #  define PETSC_MIN                    -1.e30
317 #  define PETSC_MACHINE_EPSILON         1.e-7
318 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
319 #  define PETSC_SMALL                   1.e-5
320 #elif defined(PETSC_USE_INT)
321 #  define PETSC_MAX                     PETSC_MAX_INT
322 #  define PETSC_MIN                     PETSC_MIN_INT
323 #  define PETSC_MACHINE_EPSILON         1
324 #  define PETSC_SQRT_MACHINE_EPSILON    1
325 #  define PETSC_SMALL                   0
326 #else
327 #  define PETSC_MAX                     1.e300
328 #  define PETSC_MIN                    -1.e300
329 #  define PETSC_MACHINE_EPSILON         1.e-14
330 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
331 #  define PETSC_SMALL                   1.e-10
332 #endif
333 
334 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal*,PetscReal*,MPI_Comm);
335 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal*,PetscReal*,MPI_Comm);
336 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar*,PetscScalar*,MPI_Comm);
337 
338 /*MC
339       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
340 
341     Input Parameter:
342 .     a - the double
343 
344 
345      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
346       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
347       out this form, thus removing the check.
348 
349      Level: beginner
350 
351 M*/
352 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
353 #define PetscIsInfOrNanScalar(a) (isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)))
354 #define PetscIsInfOrNanReal(a) (isinf(a) || isnan(a))
355 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
356 #if defined(PETSC_HAVE_FLOAT_H)
357 #include "float.h"  /* windows defines _finite() in float.h */
358 #endif
359 #if defined(PETSC_HAVE_IEEEFP_H)
360 #include "ieeefp.h"  /* Solaris prototypes these here */
361 #endif
362 #define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)))
363 #define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a))
364 #else
365 #define PetscIsInfOrNanScalar(a) ((a - a) != 0.0)
366 #define PetscIsInfOrNanReal(a) ((a - a) != 0.0)
367 #endif
368 
369 
370 /* ----------------------------------------------------------------------------*/
371 /*
372     PetscLogDouble variables are used to contain double precision numbers
373   that are not used in the numerical computations, but rather in logging,
374   timing etc.
375 */
376 typedef double PetscLogDouble;
377 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
378 
379 #define PassiveReal   PetscReal
380 #define PassiveScalar PetscScalar
381 
382 
383 PETSC_EXTERN_CXX_END
384 #endif
385