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