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