xref: /petsc/include/petscmath.h (revision 1093a60110fcc594e8594e94107edc434a2d33f9)
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 real or a complex.
24 
25 */
26 
27 #define PetscExpPassiveScalar(a) PetscExpScalar()
28 
29 /*
30     Complex number definitions
31  */
32 #if defined(PETSC_USE_COMPLEX)
33 #if defined(PETSC_CLANGUAGE_CXX)
34 /* C++ support of complex number */
35 #include <complex>
36 
37 #define PetscRealPart(a)      (a).real()
38 #define PetscImaginaryPart(a) (a).imag()
39 #define PetscAbsScalar(a)     std::abs(a)
40 #define PetscConj(a)          std::conj(a)
41 #define PetscSqrtScalar(a)    std::sqrt(a)
42 #define PetscPowScalar(a,b)   std::pow(a,b)
43 #define PetscExpScalar(a)     std::exp(a)
44 #define PetscLogScalar(a)     std::log(a)
45 #define PetscSinScalar(a)     std::sin(a)
46 #define PetscCosScalar(a)     std::cos(a)
47 
48 #if defined(PETSC_USE_SCALAR_SINGLE)
49 typedef std::complex<float> PetscScalar;
50 #elif defined(PETSC_USE_SCALAR_DOUBLE)
51 typedef std::complex<double> PetscScalar;
52 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
53 typedef std::complex<long double> PetscScalar;
54 #endif
55 
56 #else
57 /*  C support of complex numbers: Requires C99 compliant compiler*/
58 #include <complex.h>
59 
60 #if defined(PETSC_USE_SCALAR_SINGLE)
61 typedef float complex PetscScalar;
62 
63 #define PetscRealPart(a)      crealf(a)
64 #define PetscImaginaryPart(a) cimagf(a)
65 #define PetscAbsScalar(a)     cabsf(a)
66 #define PetscConj(a)          conjf(a)
67 #define PetscSqrtScalar(a)    csqrtf(a)
68 #define PetscPowScalar(a,b)   cpowf(a,b)
69 #define PetscExpScalar(a)     cexpf(a)
70 #define PetscLogScalar(a)     clogf(a)
71 #define PetscSinScalar(a)     csinf(a)
72 #define PetscCosScalar(a)     ccosf(a)
73 
74 #elif defined(PETSC_USE_SCALAR_DOUBLE)
75 typedef double complex PetscScalar;
76 
77 #define PetscRealPart(a)      creal(a)
78 #define PetscImaginaryPart(a) cimag(a)
79 #define PetscAbsScalar(a)     cabs(a)
80 #define PetscConj(a)          conj(a)
81 #define PetscSqrtScalar(a)    csqrt(a)
82 #define PetscPowScalar(a,b)   cpow(a,b)
83 #define PetscExpScalar(a)     cexp(a)
84 #define PetscLogScalar(a)     clog(a)
85 #define PetscSinScalar(a)     csin(a)
86 #define PetscCosScalar(a)     ccos(a)
87 
88 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
89 typedef long double complex PetscScalar;
90 
91 #define PetscRealPart(a)      creall(a)
92 #define PetscImaginaryPart(a) cimagl(a)
93 #define PetscAbsScalar(a)     cabsl(a)
94 #define PetscConj(a)          conjl(a)
95 #define PetscSqrtScalar(a)    csqrtl(a)
96 #define PetscPowScalar(a,b)   cpowl(a,b)
97 #define PetscExpScalar(a)     cexpl(a)
98 #define PetscLogScalar(a)     clogl(a)
99 #define PetscSinScalar(a)     csinl(a)
100 #define PetscCosScalar(a)     ccosl(a)
101 
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 #elif defined(PETSC_USE_SCALAR_DOUBLE)
113 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX
114 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
115 #define MPIU_SCALAR error
116 #endif
117 
118 /*
119     real number definitions
120  */
121 #else
122 #if defined(PETSC_USE_SCALAR_SINGLE)
123 #define MPIU_SCALAR           MPI_FLOAT
124 typedef float PetscScalar;
125 #elif defined(PETSC_USE_SCALAR_DOUBLE)
126 #define MPIU_SCALAR           MPI_DOUBLE
127 typedef double PetscScalar;
128 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
129 #define MPIU_SCALAR           MPI_LONG_DOUBLE
130 typedef long double PetscScalar;
131 #endif
132 #define PetscRealPart(a)      (a)
133 #define PetscImaginaryPart(a) (0.)
134 #define PetscAbsScalar(a)     (((a)<0.0)   ? -(a) : (a))
135 #define PetscConj(a)          (a)
136 #define PetscSqrtScalar(a)    sqrt(a)
137 #define PetscPowScalar(a,b)   pow(a,b)
138 #define PetscExpScalar(a)     exp(a)
139 #define PetscLogScalar(a)     log(a)
140 #define PetscSinScalar(a)     sin(a)
141 #define PetscCosScalar(a)     cos(a)
142 
143 #endif
144 
145 #if defined(PETSC_USE_SCALAR_SINGLE)
146 #define MPIU_REAL   MPI_FLOAT
147 typedef float PetscReal;
148 #elif defined(PETSC_USE_SCALAR_DOUBLE)
149 #define MPIU_REAL   MPI_DOUBLE
150 typedef double PetscReal;
151 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE)
152 #define MPIU_REAL   MPI_LONG_DOUBLE
153 typedef long double PetscReal;
154 #endif
155 
156 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
157 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
158 
159 /* --------------------------------------------------------------------------*/
160 
161 /*
162    Certain objects may be created using either single or double precision.
163    This is currently not used.
164 */
165 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
166 
167 /* PETSC_i is the imaginary number, i */
168 extern  PetscScalar  PETSC_i;
169 
170 /*MC
171    PetscMin - Returns minimum of two numbers
172 
173    Synopsis:
174    type PetscMin(type v1,type v2)
175 
176    Not Collective
177 
178    Input Parameter:
179 +  v1 - first value to find minimum of
180 -  v2 - second value to find minimum of
181 
182 
183    Notes: type can be integer or floating point value
184 
185    Level: beginner
186 
187 
188 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
189 
190 M*/
191 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
192 
193 /*MC
194    PetscMax - Returns maxium of two numbers
195 
196    Synopsis:
197    type max PetscMax(type v1,type v2)
198 
199    Not Collective
200 
201    Input Parameter:
202 +  v1 - first value to find maximum of
203 -  v2 - second value to find maximum of
204 
205    Notes: type can be integer or floating point value
206 
207    Level: beginner
208 
209 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
210 
211 M*/
212 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
213 
214 /*MC
215    PetscAbsInt - Returns the absolute value of an integer
216 
217    Synopsis:
218    int abs PetscAbsInt(int v1)
219 
220    Not Collective
221 
222    Input Parameter:
223 .   v1 - the integer
224 
225    Level: beginner
226 
227 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
228 
229 M*/
230 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
231 
232 /*MC
233    PetscAbsReal - Returns the absolute value of an real number
234 
235    Synopsis:
236    Real abs PetscAbsReal(PetscReal v1)
237 
238    Not Collective
239 
240    Input Parameter:
241 .   v1 - the double
242 
243 
244    Level: beginner
245 
246 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
247 
248 M*/
249 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
250 
251 /*MC
252    PetscSqr - Returns the square of a number
253 
254    Synopsis:
255    type sqr PetscSqr(type v1)
256 
257    Not Collective
258 
259    Input Parameter:
260 .   v1 - the value
261 
262    Notes: type can be integer or floating point value
263 
264    Level: beginner
265 
266 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
267 
268 M*/
269 #define PetscSqr(a)     ((a)*(a))
270 
271 /* ----------------------------------------------------------------------------*/
272 /*
273      Basic constants - These should be done much better
274 */
275 #define PETSC_PI                 3.14159265358979323846264
276 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
277 #define PETSC_MAX_INT            2147483647
278 #define PETSC_MIN_INT            -2147483647
279 
280 #if defined(PETSC_USE_SCALAR_SINGLE)
281 #  define PETSC_MAX                     1.e30
282 #  define PETSC_MIN                    -1.e30
283 #  define PETSC_MACHINE_EPSILON         1.e-7
284 #  define PETSC_SQRT_MACHINE_EPSILON    3.e-4
285 #  define PETSC_SMALL                   1.e-5
286 #else
287 #  define PETSC_MAX                     1.e300
288 #  define PETSC_MIN                    -1.e300
289 #  define PETSC_MACHINE_EPSILON         1.e-14
290 #  define PETSC_SQRT_MACHINE_EPSILON    1.e-7
291 #  define PETSC_SMALL                   1.e-10
292 #endif
293 
294 #if defined PETSC_HAVE_ADIC
295 /* Use MPI_Allreduce when ADIC is not available. */
296 extern PetscErrorCode  PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*);
297 extern PetscErrorCode  PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*);
298 extern PetscErrorCode  PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*);
299 #endif
300 
301 /*MC
302       PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0.
303 
304     Input Parameter:
305 .     a - the double
306 
307 
308      Notes: uses the C99 standard isinf() and isnan() on systems where they exist.
309       Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile
310       out this form, thus removing the check.
311 
312      Level: beginner
313 
314 M*/
315 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
316 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
317   return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a));
318 }
319 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
320   return isinf(a) || isnan(a);
321 }
322 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
323 #if defined(PETSC_HAVE_FLOAT_H)
324 #include "float.h"  /* Microsoft Windows defines _finite() in float.h */
325 #endif
326 #if defined(PETSC_HAVE_IEEEFP_H)
327 #include "ieeefp.h"  /* Solaris prototypes these here */
328 #endif
329 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
330   return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a));
331 }
332 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
333   return !_finite(a) || _isnan(a);
334 }
335 #else
336 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) {
337   return  ((a - a) != 0.0);
338 }
339 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) {
340   return ((a - a) != 0.0);
341 }
342 #endif
343 
344 
345 /* ----------------------------------------------------------------------------*/
346 /*
347     PetscLogDouble variables are used to contain double precision numbers
348   that are not used in the numerical computations, but rather in logging,
349   timing etc.
350 */
351 typedef double PetscLogDouble;
352 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
353 
354 #define PassiveReal   PetscReal
355 #define PassiveScalar PetscScalar
356 
357 /*
358     These macros are currently hardwired to match the regular data types, so there is no support for a different
359     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
360  */
361 #define MPIU_MATSCALAR MPIU_SCALAR
362 typedef PetscScalar MatScalar;
363 typedef PetscReal MatReal;
364 
365 
366 PETSC_EXTERN_CXX_END
367 #endif
368