Actual source code: petscmath.h
petsc-3.7.3 2016-08-01
1: /*
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.
7: This file is included by petscsys.h and should not be used directly.
9: */
13: #include <math.h>
15: /*
17: Defines operations that are different for complex and real numbers;
18: note that one cannot mix the use of complex and real in the same
19: PETSc program. All PETSc objects in one program are built around the object
20: PetscScalar which is either always a real or a complex.
22: */
24: #if defined(PETSC_USE_REAL_SINGLE)
25: #define MPIU_REAL MPI_FLOAT
26: typedef float PetscReal;
27: #define PetscSqrtReal(a) sqrt(a)
28: #define PetscExpReal(a) exp(a)
29: #define PetscLogReal(a) log(a)
30: #define PetscLog10Real(a) log10(a)
31: #ifdef PETSC_HAVE_LOG2
32: #define PetscLog2Real(a) log2(a)
33: #endif
34: #define PetscSinReal(a) sin(a)
35: #define PetscCosReal(a) cos(a)
36: #define PetscTanReal(a) tan(a)
37: #define PetscAsinReal(a) asin(a)
38: #define PetscAcosReal(a) acos(a)
39: #define PetscAtanReal(a) atan(a)
40: #define PetscAtan2Real(a,b) atan2(a,b)
41: #define PetscSinhReal(a) sinh(a)
42: #define PetscCoshReal(a) cosh(a)
43: #define PetscTanhReal(a) tanh(a)
44: #define PetscPowReal(a,b) pow(a,b)
45: #define PetscCeilReal(a) ceil(a)
46: #define PetscFloorReal(a) floor(a)
47: #define PetscFmodReal(a,b) fmod(a,b)
48: #define PetscTGamma(a) tgammaf(a)
49: #elif defined(PETSC_USE_REAL_DOUBLE)
50: #define MPIU_REAL MPI_DOUBLE
51: typedef double PetscReal;
52: #define PetscSqrtReal(a) sqrt(a)
53: #define PetscExpReal(a) exp(a)
54: #define PetscLogReal(a) log(a)
55: #define PetscLog10Real(a) log10(a)
56: #ifdef PETSC_HAVE_LOG2
57: #define PetscLog2Real(a) log2(a)
58: #endif
59: #define PetscSinReal(a) sin(a)
60: #define PetscCosReal(a) cos(a)
61: #define PetscTanReal(a) tan(a)
62: #define PetscAsinReal(a) asin(a)
63: #define PetscAcosReal(a) acos(a)
64: #define PetscAtanReal(a) atan(a)
65: #define PetscAtan2Real(a,b) atan2(a,b)
66: #define PetscSinhReal(a) sinh(a)
67: #define PetscCoshReal(a) cosh(a)
68: #define PetscTanhReal(a) tanh(a)
69: #define PetscPowReal(a,b) pow(a,b)
70: #define PetscCeilReal(a) ceil(a)
71: #define PetscFloorReal(a) floor(a)
72: #define PetscFmodReal(a,b) fmod(a,b)
73: #define PetscTGamma(a) tgamma(a)
74: #elif defined(PETSC_USE_REAL___FLOAT128)
75: #if defined(__cplusplus)
76: extern "C" {
77: #endif
78: #include <quadmath.h>
79: #if defined(__cplusplus)
80: }
81: #endif
82: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
83: #define MPIU_REAL MPIU___FLOAT128
84: typedef __float128 PetscReal;
85: #define PetscSqrtReal(a) sqrtq(a)
86: #define PetscExpReal(a) expq(a)
87: #define PetscLogReal(a) logq(a)
88: #define PetscLog10Real(a) log10q(a)
89: #ifdef PETSC_HAVE_LOG2
90: #define PetscLog2Real(a) log2q(a)
91: #endif
92: #define PetscSinReal(a) sinq(a)
93: #define PetscCosReal(a) cosq(a)
94: #define PetscTanReal(a) tanq(a)
95: #define PetscAsinReal(a) asinq(a)
96: #define PetscAcosReal(a) acosq(a)
97: #define PetscAtanReal(a) atanq(a)
98: #define PetscAtan2Real(a,b) atan2q(a,b)
99: #define PetscSinhReal(a) sinhq(a)
100: #define PetscCoshReal(a) coshq(a)
101: #define PetscTanhReal(a) tanhq(a)
102: #define PetscPowReal(a,b) powq(a,b)
103: #define PetscCeilReal(a) ceilq(a)
104: #define PetscFloorReal(a) floorq(a)
105: #define PetscFmodReal(a,b) fmodq(a,b)
106: #define PetscTGamma(a) tgammaq(a)
107: #endif /* PETSC_USE_REAL_* */
109: /*
110: Complex number definitions
111: */
112: #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
113: #if !defined(PETSC_SKIP_COMPLEX)
114: #define PETSC_HAVE_COMPLEX 1
115: /* C++ support of complex number */
116: #if defined(PETSC_HAVE_CUSP)
117: #define complexlib cusp
118: #include <cusp/complex.h>
119: #elif defined(PETSC_HAVE_VECCUDA) && __CUDACC_VER_MAJOR__ > 6
120: /* complex headers in thrust only available in CUDA 7.0 and above */
121: #define complexlib thrust
122: #include <thrust/complex.h>
123: #else
124: #define complexlib std
125: #include <complex>
126: #endif
128: #define PetscRealPartComplex(a) (a).real()
129: #define PetscImaginaryPartComplex(a) (a).imag()
130: #define PetscAbsComplex(a) complexlib::abs(a)
131: #define PetscConjComplex(a) complexlib::conj(a)
132: #define PetscSqrtComplex(a) complexlib::sqrt(a)
133: #define PetscPowComplex(a,b) complexlib::pow(a,b)
134: #define PetscExpComplex(a) complexlib::exp(a)
135: #define PetscLogComplex(a) complexlib::log(a)
136: #define PetscSinComplex(a) complexlib::sin(a)
137: #define PetscCosComplex(a) complexlib::cos(a)
138: #define PetscAsinComplex(a) complexlib::asin(a)
139: #define PetscAcosComplex(a) complexlib::acos(a)
140: #if defined(PETSC_HAVE_TANCOMPLEX)
141: #define PetscTanComplex(a) complexlib::tan(a)
142: #else
143: #define PetscTanComplex(a) PetscSinComplex(a)/PetscCosComplex(a)
144: #endif
145: #define PetscSinhComplex(a) complexlib::sinh(a)
146: #define PetscCoshComplex(a) complexlib::cosh(a)
147: #if defined(PETSC_HAVE_TANHCOMPLEX)
148: #define PetscTanhComplex(a) complexlib::tanh(a)
149: #else
150: #define PetscTanhComplex(a) PetscSinhComplex(a)/PetscCoshComplex(a)
151: #endif
153: #if defined(PETSC_USE_REAL_SINGLE)
154: typedef complexlib::complex<float> PetscComplex;
155: #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND)
156: static inline PetscComplex operator+(const PetscComplex& lhs, const double& rhs) { return lhs + float(rhs); }
157: static inline PetscComplex operator+(const double& lhs, const PetscComplex& rhs) { return float(lhs) + rhs; }
158: static inline PetscComplex operator-(const PetscComplex& lhs, const double& rhs) { return lhs - float(rhs); }
159: static inline PetscComplex operator-(const double& lhs, const PetscComplex& rhs) { return float(lhs) - rhs; }
160: static inline PetscComplex operator*(const PetscComplex& lhs, const double& rhs) { return lhs * float(rhs); }
161: static inline PetscComplex operator*(const double& lhs, const PetscComplex& rhs) { return float(lhs) * rhs; }
162: static inline PetscComplex operator/(const PetscComplex& lhs, const double& rhs) { return lhs / float(rhs); }
163: static inline PetscComplex operator/(const double& lhs, const PetscComplex& rhs) { return float(lhs) / rhs; }
164: static inline bool operator==(const PetscComplex& lhs, const double& rhs) { return lhs.imag() == float(0) && lhs.real() == float(rhs); }
165: static inline bool operator==(const double& lhs, const PetscComplex& rhs) { return rhs.imag() == float(0) && rhs.real() == float(lhs); }
166: static inline bool operator!=(const PetscComplex& lhs, const double& rhs) { return lhs.imag() != float(0) || lhs.real() != float(rhs); }
167: static inline bool operator!=(const double& lhs, const PetscComplex& rhs) { return rhs.imag() != float(0) || rhs.real() != float(lhs); }
168: #endif /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */
169: #elif defined(PETSC_USE_REAL_DOUBLE)
170: typedef complexlib::complex<double> PetscComplex;
171: #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND)
172: static inline PetscComplex operator+(const PetscComplex& lhs, const PetscInt& rhs) { return lhs + double(rhs); }
173: static inline PetscComplex operator+(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) + rhs; }
174: static inline PetscComplex operator-(const PetscComplex& lhs, const PetscInt& rhs) { return lhs - double(rhs); }
175: static inline PetscComplex operator-(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) - rhs; }
176: static inline PetscComplex operator*(const PetscComplex& lhs, const PetscInt& rhs) { return lhs * double(rhs); }
177: static inline PetscComplex operator*(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) * rhs; }
178: static inline PetscComplex operator/(const PetscComplex& lhs, const PetscInt& rhs) { return lhs / double(rhs); }
179: static inline PetscComplex operator/(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) / rhs; }
180: static inline bool operator==(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() == double(0) && lhs.real() == double(rhs); }
181: static inline bool operator==(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() == double(0) && rhs.real() == double(lhs); }
182: static inline bool operator!=(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() != double(0) || lhs.real() != double(rhs); }
183: static inline bool operator!=(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() != double(0) || rhs.real() != double(lhs); }
184: #endif /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */
185: #elif defined(PETSC_USE_REAL___FLOAT128)
186: typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */
187: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128;
188: #endif /* PETSC_USE_REAL_ */
189: #endif /* ! PETSC_SKIP_COMPLEX */
191: #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
192: #if !defined(PETSC_SKIP_COMPLEX)
193: #define PETSC_HAVE_COMPLEX 1
194: #include <complex.h>
196: #if defined(PETSC_USE_REAL_SINGLE)
197: typedef float _Complex PetscComplex;
199: #define PetscRealPartComplex(a) crealf(a)
200: #define PetscImaginaryPartComplex(a) cimagf(a)
201: #define PetscAbsComplex(a) cabsf(a)
202: #define PetscConjComplex(a) conjf(a)
203: #define PetscSqrtComplex(a) csqrtf(a)
204: #define PetscPowComplex(a,b) cpowf(a,b)
205: #define PetscExpComplex(a) cexpf(a)
206: #define PetscLogComplex(a) clogf(a)
207: #define PetscSinComplex(a) csinf(a)
208: #define PetscCosComplex(a) ccosf(a)
209: #define PetscAsinComplex(a) casinf(a)
210: #define PetscAcosComplex(a) cacosf(a)
211: #define PetscTanComplex(a) ctanf(a)
212: #define PetscSinhComplex(a) csinhf(a)
213: #define PetscCoshComplex(a) ccoshf(a)
214: #define PetscTanhComplex(a) ctanhf(a)
216: #elif defined(PETSC_USE_REAL_DOUBLE)
217: typedef double _Complex PetscComplex;
219: #define PetscRealPartComplex(a) creal(a)
220: #define PetscImaginaryPartComplex(a) cimag(a)
221: #define PetscAbsComplex(a) cabs(a)
222: #define PetscConjComplex(a) conj(a)
223: #define PetscSqrtComplex(a) csqrt(a)
224: #define PetscPowComplex(a,b) cpow(a,b)
225: #define PetscExpComplex(a) cexp(a)
226: #define PetscLogComplex(a) clog(a)
227: #define PetscSinComplex(a) csin(a)
228: #define PetscCosComplex(a) ccos(a)
229: #define PetscAsinComplex(a) casin(a)
230: #define PetscAcosComplex(a) cacos(a)
231: #define PetscTanComplex(a) ctan(a)
232: #define PetscSinhComplex(a) csinh(a)
233: #define PetscCoshComplex(a) ccosh(a)
234: #define PetscTanhComplex(a) ctanh(a)
236: #elif defined(PETSC_USE_REAL___FLOAT128)
237: typedef __complex128 PetscComplex;
238: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);
240: #define PetscRealPartComplex(a) crealq(a)
241: #define PetscImaginaryPartComplex(a) cimagq(a)
242: #define PetscAbsComplex(a) cabsq(a)
243: #define PetscConjComplex(a) conjq(a)
244: #define PetscSqrtComplex(a) csqrtq(a)
245: #define PetscPowComplex(a,b) cpowq(a,b)
246: #define PetscExpComplex(a) cexpq(a)
247: #define PetscLogComplex(a) clogq(a)
248: #define PetscSinComplex(a) csinq(a)
249: #define PetscCosComplex(a) ccosq(a)
250: #define PetscAsinComplex(a) casinq(a)
251: #define PetscAcosComplex(a) cacosq(a)
252: #define PetscTanComplex(a) ctanq(a)
253: #define PetscSinhComplex(a) csinhq(a)
254: #define PetscCoshComplex(a) ccoshq(a)
255: #define PetscTanhComplex(a) ctanhq(a)
257: #endif /* PETSC_USE_REAL_* */
258: #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
259: #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available"
260: #endif /* !PETSC_SKIP_COMPLEX */
261: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */
263: #if defined(PETSC_HAVE_COMPLEX)
264: #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
265: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
266: #define MPIU_C_COMPLEX MPI_C_COMPLEX
267: #else
268: # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX)
269: typedef complexlib::complex<double> petsc_mpiu_c_double_complex;
270: typedef complexlib::complex<float> petsc_mpiu_c_complex;
271: # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
272: typedef double _Complex petsc_mpiu_c_double_complex;
273: typedef float _Complex petsc_mpiu_c_complex;
274: # else
275: typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
276: typedef struct {float real,imag;} petsc_mpiu_c_complex;
277: # endif
278: PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
279: PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
280: #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
281: #endif /* PETSC_HAVE_COMPLEX */
283: #if defined(PETSC_HAVE_COMPLEX)
284: # if defined(PETSC_USE_REAL_SINGLE)
285: # define MPIU_COMPLEX MPIU_C_COMPLEX
286: # elif defined(PETSC_USE_REAL_DOUBLE)
287: # define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
288: # elif defined(PETSC_USE_REAL___FLOAT128)
289: # define MPIU_COMPLEX MPIU___COMPLEX128
290: # endif /* PETSC_USE_REAL_* */
291: #endif
293: #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
294: typedef PetscComplex PetscScalar;
295: #define PetscRealPart(a) PetscRealPartComplex(a)
296: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
297: #define PetscAbsScalar(a) PetscAbsComplex(a)
298: #define PetscConj(a) PetscConjComplex(a)
299: #define PetscSqrtScalar(a) PetscSqrtComplex(a)
300: #define PetscPowScalar(a,b) PetscPowComplex(a,b)
301: #define PetscExpScalar(a) PetscExpComplex(a)
302: #define PetscLogScalar(a) PetscLogComplex(a)
303: #define PetscSinScalar(a) PetscSinComplex(a)
304: #define PetscCosScalar(a) PetscCosComplex(a)
305: #define PetscAsinScalar(a) PetscAsinComplex(a)
306: #define PetscAcosScalar(a) PetscAcosComplex(a)
307: #define PetscTanScalar(a) PetscTanComplex(a)
308: #define PetscSinhScalar(a) PetscSinhComplex(a)
309: #define PetscCoshScalar(a) PetscCoshComplex(a)
310: #define PetscTanhScalar(a) PetscTanhComplex(a)
311: #define MPIU_SCALAR MPIU_COMPLEX
313: /*
314: real number definitions
315: */
316: #else /* PETSC_USE_COMPLEX */
317: typedef PetscReal PetscScalar;
318: #define MPIU_SCALAR MPIU_REAL
320: #define PetscRealPart(a) (a)
321: #define PetscImaginaryPart(a) ((PetscReal)0.)
322: PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
323: #define PetscConj(a) (a)
324: #if !defined(PETSC_USE_REAL___FLOAT128)
325: #define PetscSqrtScalar(a) sqrt(a)
326: #define PetscPowScalar(a,b) pow(a,b)
327: #define PetscExpScalar(a) exp(a)
328: #define PetscLogScalar(a) log(a)
329: #define PetscSinScalar(a) sin(a)
330: #define PetscCosScalar(a) cos(a)
331: #define PetscAsinScalar(a) asin(a)
332: #define PetscAcosScalar(a) acos(a)
333: #define PetscTanScalar(a) tan(a)
334: #define PetscSinhScalar(a) sinh(a)
335: #define PetscCoshScalar(a) cosh(a)
336: #define PetscTanhScalar(a) tanh(a)
337: #else /* PETSC_USE_REAL___FLOAT128 */
338: #define PetscSqrtScalar(a) sqrtq(a)
339: #define PetscPowScalar(a,b) powq(a,b)
340: #define PetscExpScalar(a) expq(a)
341: #define PetscLogScalar(a) logq(a)
342: #define PetscSinScalar(a) sinq(a)
343: #define PetscCosScalar(a) cosq(a)
344: #define PetscAsinScalar(a) asinq(a)
345: #define PetscAcosScalar(a) acosq(a)
346: #define PetscTanScalar(a) tanq(a)
347: #define PetscSinhScalar(a) sinhq(a)
348: #define PetscCoshScalar(a) coshq(a)
349: #define PetscTanhScalar(a) tanhq(a)
350: #endif /* PETSC_USE_REAL___FLOAT128 */
352: #endif /* PETSC_USE_COMPLEX */
354: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
355: #define PetscSignReal(a) (((a) >= 0.0) ? ((a) == 0.0 ? 0.0 : 1.0) : -1.0)
356: #define PetscAbs(a) (((a) >= 0) ? (a) : -(a))
358: /* --------------------------------------------------------------------------*/
360: /*
361: Certain objects may be created using either single or double precision.
362: This is currently not used.
363: */
364: typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
366: #if defined(PETSC_HAVE_COMPLEX)
367: /* PETSC_i is the imaginary number, i */
368: PETSC_EXTERN PetscComplex PETSC_i;
369: #endif
371: /*MC
372: PetscMin - Returns minimum of two numbers
374: Synopsis:
375: #include <petscmath.h>
376: type PetscMin(type v1,type v2)
378: Not Collective
380: Input Parameter:
381: + v1 - first value to find minimum of
382: - v2 - second value to find minimum of
384: Notes: type can be integer or floating point value
386: Level: beginner
388: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
390: M*/
391: #define PetscMin(a,b) (((a)<(b)) ? (a) : (b))
393: /*MC
394: PetscMax - Returns maxium of two numbers
396: Synopsis:
397: #include <petscmath.h>
398: type max PetscMax(type v1,type v2)
400: Not Collective
402: Input Parameter:
403: + v1 - first value to find maximum of
404: - v2 - second value to find maximum of
406: Notes: type can be integer or floating point value
408: Level: beginner
410: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
412: M*/
413: #define PetscMax(a,b) (((a)<(b)) ? (b) : (a))
415: /*MC
416: PetscClipInterval - Returns a number clipped to be within an interval
418: Synopsis:
419: #include <petscmath.h>
420: type clip PetscClipInterval(type x,type a,type b)
422: Not Collective
424: Input Parameter:
425: + x - value to use if within interval (a,b)
426: . a - lower end of interval
427: - b - upper end of interval
429: Notes: type can be integer or floating point value
431: Level: beginner
433: .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
435: M*/
436: #define PetscClipInterval(x,a,b) (PetscMax((a),PetscMin((x),(b))))
438: /*MC
439: PetscAbsInt - Returns the absolute value of an integer
441: Synopsis:
442: #include <petscmath.h>
443: int abs PetscAbsInt(int v1)
445: Not Collective
447: Input Parameter:
448: . v1 - the integer
450: Level: beginner
452: .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
454: M*/
455: #define PetscAbsInt(a) (((a)<0) ? -(a) : (a))
457: /*MC
458: PetscAbsReal - Returns the absolute value of an real number
460: Synopsis:
461: #include <petscmath.h>
462: Real abs PetscAbsReal(PetscReal v1)
464: Not Collective
466: Input Parameter:
467: . v1 - the double
470: Level: beginner
472: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
474: M*/
475: #define PetscAbsReal(a) (((a)<0) ? -(a) : (a))
477: /*MC
478: PetscSqr - Returns the square of a number
480: Synopsis:
481: #include <petscmath.h>
482: type sqr PetscSqr(type v1)
484: Not Collective
486: Input Parameter:
487: . v1 - the value
489: Notes: type can be integer or floating point value
491: Level: beginner
493: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
495: M*/
496: #define PetscSqr(a) ((a)*(a))
498: /* ----------------------------------------------------------------------------*/
499: /*
500: Basic constants
501: */
502: #if defined(PETSC_USE_REAL___FLOAT128)
503: #define PETSC_PI M_PIq
504: #elif defined(M_PI)
505: #define PETSC_PI M_PI
506: #else
507: #define PETSC_PI 3.14159265358979323846264338327950288419716939937510582
508: #endif
510: #if !defined(PETSC_USE_64BIT_INDICES)
511: #define PETSC_MAX_INT 2147483647
512: #define PETSC_MIN_INT (-PETSC_MAX_INT - 1)
513: #else
514: #define PETSC_MAX_INT 9223372036854775807L
515: #define PETSC_MIN_INT (-PETSC_MAX_INT - 1)
516: #endif
518: #if defined(PETSC_USE_REAL_SINGLE)
519: # define PETSC_MAX_REAL 3.40282346638528860e+38F
520: # define PETSC_MIN_REAL -PETSC_MAX_REAL
521: # define PETSC_MACHINE_EPSILON 1.19209290e-07F
522: # define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
523: # define PETSC_SMALL 1.e-5
524: #elif defined(PETSC_USE_REAL_DOUBLE)
525: # define PETSC_MAX_REAL 1.7976931348623157e+308
526: # define PETSC_MIN_REAL -PETSC_MAX_REAL
527: # define PETSC_MACHINE_EPSILON 2.2204460492503131e-16
528: # define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
529: # define PETSC_SMALL 1.e-10
530: #elif defined(PETSC_USE_REAL___FLOAT128)
531: # define PETSC_MAX_REAL FLT128_MAX
532: # define PETSC_MIN_REAL -FLT128_MAX
533: # define PETSC_MACHINE_EPSILON FLT128_EPSILON
534: # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078e-17q
535: # define PETSC_SMALL 1.e-20q
536: #endif
538: #define PETSC_INFINITY PETSC_MAX_REAL/4.0
539: #define PETSC_NINFINITY -PETSC_INFINITY
541: PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
542: PETSC_EXTERN PetscErrorCode PetscIsNanReal(PetscReal);
543: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
544: PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
545: PETSC_STATIC_INLINE PetscErrorCode PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));}
546: PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}
548: /*
549: These macros are currently hardwired to match the regular data types, so there is no support for a different
550: MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
551: */
552: #define MPIU_MATSCALAR MPIU_SCALAR
553: typedef PetscScalar MatScalar;
554: typedef PetscReal MatReal;
556: struct petsc_mpiu_2scalar {PetscScalar a,b;};
557: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
558: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
559: struct petsc_mpiu_2int {PetscInt a,b;};
560: PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
561: #else
562: #define MPIU_2INT MPI_2INT
563: #endif
565: PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
566: {
567: PetscInt result = 1;
568: while (power) {
569: if (power & 1) result *= base;
570: power >>= 1;
571: base *= base;
572: }
573: return result;
574: }
576: PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
577: {
578: PetscReal result = 1;
579: if (power < 0) {
580: power = -power;
581: base = ((PetscReal)1)/base;
582: }
583: while (power) {
584: if (power & 1) result *= base;
585: power >>= 1;
586: base *= base;
587: }
588: return result;
589: }
591: PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
592: {
593: PetscScalar result = 1;
594: if (power < 0) {
595: power = -power;
596: base = ((PetscReal)1)/base;
597: }
598: while (power) {
599: if (power & 1) result *= base;
600: power >>= 1;
601: base *= base;
602: }
603: return result;
604: }
606: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
607: {
608: PetscScalar cpower = power;
609: return PetscPowScalar(base,cpower);
610: }
612: #ifndef PETSC_HAVE_LOG2
613: PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n)
614: {
615: return PetscLogReal(n)/PetscLogReal(2.0);
616: }
617: #endif
618: #endif