xref: /petsc/include/petscmath.h (revision c0174eb74783e1ccfa817272a5782dd72b4cfcef)
1 /*
2 
3       PETSc mathematics include file. Defines certain basic mathematical
4     constants and functions for working with single, double, and quad precision
5     floating point numbers as well as complex single and double.
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 
15 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR;
16 PETSC_EXTERN MPI_Datatype MPIU_2INT;
17 
18 /*
19 
20      Defines operations that are different for complex and real numbers;
21    note that one cannot 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 #if defined(PETSC_USE_REAL_SINGLE)
29 #define MPIU_REAL   MPI_FLOAT
30 typedef float PetscReal;
31 #define PetscSqrtReal(a)    sqrt(a)
32 #elif defined(PETSC_USE_REAL_DOUBLE)
33 #define MPIU_REAL   MPI_DOUBLE
34 typedef double PetscReal;
35 #define PetscSqrtReal(a)    sqrt(a)
36 #elif defined(PETSC_USE_REAL___FLOAT128)
37 #if defined(__cplusplus)
38 extern "C" {
39 #endif
40 #include <quadmath.h>
41 #if defined(__cplusplus)
42 }
43 #endif
44 #define MPIU_REAL MPIU___FLOAT128
45 typedef __float128 PetscReal;
46 #define PetscSqrtReal(a)    sqrtq(a)
47 #endif /* PETSC_USE_REAL_* */
48 
49 /*
50     Complex number definitions
51  */
52 #if defined(PETSC_USE_COMPLEX)
53 #if defined(PETSC_CLANGUAGE_CXX)
54 /* C++ support of complex number */
55 #if defined(PETSC_HAVE_CUSP)
56 #define complexlib cusp
57 #include <cusp/complex.h>
58 #else
59 #define complexlib std
60 #include <complex>
61 #endif
62 
63 #define PetscRealPart(a)      (a).real()
64 #define PetscImaginaryPart(a) (a).imag()
65 #define PetscAbsScalar(a)     complexlib::abs(a)
66 #define PetscConj(a)          complexlib::conj(a)
67 #define PetscSqrtScalar(a)    complexlib::sqrt(a)
68 #define PetscPowScalar(a,b)   complexlib::pow(a,b)
69 #define PetscExpScalar(a)     complexlib::exp(a)
70 #define PetscLogScalar(a)     complexlib::log(a)
71 #define PetscSinScalar(a)     complexlib::sin(a)
72 #define PetscCosScalar(a)     complexlib::cos(a)
73 
74 #if defined(PETSC_USE_REAL_SINGLE)
75 typedef complexlib::complex<float> PetscScalar;
76 #elif defined(PETSC_USE_REAL_DOUBLE)
77 typedef complexlib::complex<double> PetscScalar;
78 #endif  /* PETSC_USE_REAL_ */
79 
80 #else /* PETSC_CLANGUAGE_CXX */
81 
82 /*  C support of complex numbers: Requires C99 compliant compiler*/
83 #include <complex.h>
84 
85 #if defined(PETSC_USE_REAL_SINGLE)
86 typedef float complex PetscScalar;
87 
88 #define PetscRealPart(a)      crealf(a)
89 #define PetscImaginaryPart(a) cimagf(a)
90 #define PetscAbsScalar(a)     cabsf(a)
91 #define PetscConj(a)          conjf(a)
92 #define PetscSqrtScalar(a)    csqrtf(a)
93 #define PetscPowScalar(a,b)   cpowf(a,b)
94 #define PetscExpScalar(a)     cexpf(a)
95 #define PetscLogScalar(a)     clogf(a)
96 #define PetscSinScalar(a)     csinf(a)
97 #define PetscCosScalar(a)     ccosf(a)
98 
99 #elif defined(PETSC_USE_REAL_DOUBLE)
100 typedef double complex PetscScalar;
101 
102 #define PetscRealPart(a)      creal(a)
103 #define PetscImaginaryPart(a) cimag(a)
104 #define PetscAbsScalar(a)     cabs(a)
105 #define PetscConj(a)          conj(a)
106 #define PetscSqrtScalar(a)    csqrt(a)
107 #define PetscPowScalar(a,b)   cpow(a,b)
108 #define PetscExpScalar(a)     cexp(a)
109 #define PetscLogScalar(a)     clog(a)
110 #define PetscSinScalar(a)     csin(a)
111 #define PetscCosScalar(a)     ccos(a)
112 
113 #endif /* PETSC_USE_REAL_* */
114 #endif /* PETSC_CLANGUAGE_CXX */
115 
116 #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
117 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
118 #define MPIU_C_COMPLEX MPI_C_COMPLEX
119 #else
120 PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX;
121 PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX;
122 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
123 
124 #if defined(PETSC_USE_REAL_SINGLE)
125 #define MPIU_SCALAR MPIU_C_COMPLEX
126 #elif defined(PETSC_USE_REAL_DOUBLE)
127 #define MPIU_SCALAR MPIU_C_DOUBLE_COMPLEX
128 #endif /* PETSC_USE_REAL_* */
129 
130 /*
131     real number definitions
132  */
133 #else /* PETSC_USE_COMPLEX */
134 #if defined(PETSC_USE_REAL_SINGLE)
135 #define MPIU_SCALAR           MPI_FLOAT
136 typedef float PetscScalar;
137 #elif defined(PETSC_USE_REAL_DOUBLE)
138 #define MPIU_SCALAR           MPI_DOUBLE
139 typedef double PetscScalar;
140 #elif defined(PETSC_USE_REAL___FLOAT128)
141 PETSC_EXTERN MPI_Datatype MPIU___FLOAT128;
142 #define MPIU_SCALAR MPIU___FLOAT128
143 typedef __float128 PetscScalar;
144 #endif /* PETSC_USE_REAL_* */
145 #define PetscRealPart(a)      (a)
146 #define PetscImaginaryPart(a) ((PetscReal)0.)
147 PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
148 #define PetscConj(a)          (a)
149 #if !defined(PETSC_USE_REAL___FLOAT128)
150 #define PetscSqrtScalar(a)    sqrt(a)
151 #define PetscPowScalar(a,b)   pow(a,b)
152 #define PetscExpScalar(a)     exp(a)
153 #define PetscLogScalar(a)     log(a)
154 #define PetscSinScalar(a)     sin(a)
155 #define PetscCosScalar(a)     cos(a)
156 #else /* PETSC_USE_REAL___FLOAT128 */
157 #define PetscSqrtScalar(a)    sqrtq(a)
158 #define PetscPowScalar(a,b)   powq(a,b)
159 #define PetscExpScalar(a)     expq(a)
160 #define PetscLogScalar(a)     logq(a)
161 #define PetscSinScalar(a)     sinq(a)
162 #define PetscCosScalar(a)     cosq(a)
163 #endif /* PETSC_USE_REAL___FLOAT128 */
164 
165 #endif /* PETSC_USE_COMPLEX */
166 
167 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
168 #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))
169 
170 /* --------------------------------------------------------------------------*/
171 
172 /*
173    Certain objects may be created using either single or double precision.
174    This is currently not used.
175 */
176 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
177 
178 /* PETSC_i is the imaginary number, i */
179 PETSC_EXTERN PetscScalar   PETSC_i;
180 
181 /*MC
182    PetscMin - Returns minimum of two numbers
183 
184    Synopsis:
185    type PetscMin(type v1,type v2)
186 
187    Not Collective
188 
189    Input Parameter:
190 +  v1 - first value to find minimum of
191 -  v2 - second value to find minimum of
192 
193 
194    Notes: type can be integer or floating point value
195 
196    Level: beginner
197 
198 
199 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
200 
201 M*/
202 #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
203 
204 /*MC
205    PetscMax - Returns maxium of two numbers
206 
207    Synopsis:
208    type max PetscMax(type v1,type v2)
209 
210    Not Collective
211 
212    Input Parameter:
213 +  v1 - first value to find maximum of
214 -  v2 - second value to find maximum of
215 
216    Notes: type can be integer or floating point value
217 
218    Level: beginner
219 
220 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
221 
222 M*/
223 #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
224 
225 /*MC
226    PetscClipInterval - Returns a number clipped to be within an interval
227 
228    Synopsis:
229    type clip PetscClipInterval(type x,type a,type b)
230 
231    Not Collective
232 
233    Input Parameter:
234 +  x - value to use if within interval (a,b)
235 .  a - lower end of interval
236 -  b - upper end of interval
237 
238    Notes: type can be integer or floating point value
239 
240    Level: beginner
241 
242 .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
243 
244 M*/
245 #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))
246 
247 /*MC
248    PetscAbsInt - Returns the absolute value of an integer
249 
250    Synopsis:
251    int abs PetscAbsInt(int v1)
252 
253    Not Collective
254 
255    Input Parameter:
256 .   v1 - the integer
257 
258    Level: beginner
259 
260 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
261 
262 M*/
263 #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))
264 
265 /*MC
266    PetscAbsReal - Returns the absolute value of an real number
267 
268    Synopsis:
269    Real abs PetscAbsReal(PetscReal v1)
270 
271    Not Collective
272 
273    Input Parameter:
274 .   v1 - the double
275 
276 
277    Level: beginner
278 
279 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
280 
281 M*/
282 #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))
283 
284 /*MC
285    PetscSqr - Returns the square of a number
286 
287    Synopsis:
288    type sqr PetscSqr(type v1)
289 
290    Not Collective
291 
292    Input Parameter:
293 .   v1 - the value
294 
295    Notes: type can be integer or floating point value
296 
297    Level: beginner
298 
299 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
300 
301 M*/
302 #define PetscSqr(a)     ((a)*(a))
303 
304 /* ----------------------------------------------------------------------------*/
305 /*
306      Basic constants
307 */
308 #if defined(PETSC_USE_REAL___FLOAT128)
309 #define PETSC_PI                 M_PIq
310 #elif defined(M_PI)
311 #define PETSC_PI                 M_PI
312 #else
313 #define PETSC_PI                 3.14159265358979323846264338327950288419716939937510582
314 #endif
315 
316 #if !defined(PETSC_USE_64BIT_INDICES)
317 #define PETSC_MAX_INT            2147483647
318 #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
319 #else
320 #define PETSC_MAX_INT            9223372036854775807L
321 #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
322 #endif
323 
324 #if defined(PETSC_USE_REAL_SINGLE)
325 #  define PETSC_MAX_REAL                3.40282346638528860e+38F
326 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
327 #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
328 #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
329 #  define PETSC_SMALL                   1.e-5
330 #elif defined(PETSC_USE_REAL_DOUBLE)
331 #  define PETSC_MAX_REAL                1.7976931348623157e+308
332 #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
333 #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
334 #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
335 #  define PETSC_SMALL                   1.e-10
336 #elif defined(PETSC_USE_REAL___FLOAT128)
337 #  define PETSC_MAX_REAL                FLT128_MAX
338 #  define PETSC_MIN_REAL                -FLT128_MAX
339 #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
340 #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17
341 #  define PETSC_SMALL                   1.e-20
342 #endif
343 
344 #if defined PETSC_HAVE_ADIC
345 /* Use MPI_Allreduce when ADIC is not available. */
346 PETSC_EXTERN PetscErrorCode PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*);
347 PETSC_EXTERN PetscErrorCode PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*);
348 PETSC_EXTERN PetscErrorCode PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*);
349 #endif
350 
351 PETSC_EXTERN PetscErrorCode PetscIsInfOrNanScalar(PetscScalar);
352 PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
353 
354 /* ----------------------------------------------------------------------------*/
355 #define PassiveReal   PetscReal
356 #define PassiveScalar PetscScalar
357 
358 /*
359     These macros are currently hardwired to match the regular data types, so there is no support for a different
360     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
361  */
362 #define MPIU_MATSCALAR MPIU_SCALAR
363 typedef PetscScalar MatScalar;
364 typedef PetscReal MatReal;
365 
366 
367 #endif
368