Actual source code: petscmath.h

petsc-3.7.2 2016-06-05
Report Typos and Errors
  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: #elif defined(PETSC_USE_REAL___FLOAT128)
172: typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */
173: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128;
174: #endif  /* PETSC_USE_REAL_ */
175: #endif  /* ! PETSC_SKIP_COMPLEX */

177: #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
178: #if !defined(PETSC_SKIP_COMPLEX)
179: #define PETSC_HAVE_COMPLEX 1
180: #include <complex.h>

182: #if defined(PETSC_USE_REAL_SINGLE)
183: typedef float _Complex PetscComplex;

185: #define PetscRealPartComplex(a)      crealf(a)
186: #define PetscImaginaryPartComplex(a) cimagf(a)
187: #define PetscAbsComplex(a)           cabsf(a)
188: #define PetscConjComplex(a)          conjf(a)
189: #define PetscSqrtComplex(a)          csqrtf(a)
190: #define PetscPowComplex(a,b)         cpowf(a,b)
191: #define PetscExpComplex(a)           cexpf(a)
192: #define PetscLogComplex(a)           clogf(a)
193: #define PetscSinComplex(a)           csinf(a)
194: #define PetscCosComplex(a)           ccosf(a)
195: #define PetscAsinComplex(a)          casinf(a)
196: #define PetscAcosComplex(a)          cacosf(a)
197: #define PetscTanComplex(a)           ctanf(a)
198: #define PetscSinhComplex(a)          csinhf(a)
199: #define PetscCoshComplex(a)          ccoshf(a)
200: #define PetscTanhComplex(a)          ctanhf(a)

202: #elif defined(PETSC_USE_REAL_DOUBLE)
203: typedef double _Complex PetscComplex;

205: #define PetscRealPartComplex(a)      creal(a)
206: #define PetscImaginaryPartComplex(a) cimag(a)
207: #define PetscAbsComplex(a)           cabs(a)
208: #define PetscConjComplex(a)          conj(a)
209: #define PetscSqrtComplex(a)          csqrt(a)
210: #define PetscPowComplex(a,b)         cpow(a,b)
211: #define PetscExpComplex(a)           cexp(a)
212: #define PetscLogComplex(a)           clog(a)
213: #define PetscSinComplex(a)           csin(a)
214: #define PetscCosComplex(a)           ccos(a)
215: #define PetscAsinComplex(a)          casin(a)
216: #define PetscAcosComplex(a)          cacos(a)
217: #define PetscTanComplex(a)           ctan(a)
218: #define PetscSinhComplex(a)          csinh(a)
219: #define PetscCoshComplex(a)          ccosh(a)
220: #define PetscTanhComplex(a)          ctanh(a)

222: #elif defined(PETSC_USE_REAL___FLOAT128)
223: typedef __complex128 PetscComplex;
224: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);

226: #define PetscRealPartComplex(a)      crealq(a)
227: #define PetscImaginaryPartComplex(a) cimagq(a)
228: #define PetscAbsComplex(a)           cabsq(a)
229: #define PetscConjComplex(a)          conjq(a)
230: #define PetscSqrtComplex(a)          csqrtq(a)
231: #define PetscPowComplex(a,b)         cpowq(a,b)
232: #define PetscExpComplex(a)           cexpq(a)
233: #define PetscLogComplex(a)           clogq(a)
234: #define PetscSinComplex(a)           csinq(a)
235: #define PetscCosComplex(a)           ccosq(a)
236: #define PetscAsinComplex(a)          casinq(a)
237: #define PetscAcosComplex(a)          cacosq(a)
238: #define PetscTanComplex(a)           ctanq(a)
239: #define PetscSinhComplex(a)          csinhq(a)
240: #define PetscCoshComplex(a)          ccoshq(a)
241: #define PetscTanhComplex(a)          ctanhq(a)

243: #endif /* PETSC_USE_REAL_* */
244: #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
245: #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available"
246: #endif /* !PETSC_SKIP_COMPLEX */
247: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */

249: #if defined(PETSC_HAVE_COMPLEX)
250: #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
251: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
252: #define MPIU_C_COMPLEX MPI_C_COMPLEX
253: #else
254: # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX)
255:   typedef complexlib::complex<double> petsc_mpiu_c_double_complex;
256:   typedef complexlib::complex<float> petsc_mpiu_c_complex;
257: # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
258:   typedef double _Complex petsc_mpiu_c_double_complex;
259:   typedef float _Complex petsc_mpiu_c_complex;
260: # else
261:   typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
262:   typedef struct {float real,imag;} petsc_mpiu_c_complex;
263: # endif
264: PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
265: PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
266: #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
267: #endif /* PETSC_HAVE_COMPLEX */

269: #if defined(PETSC_HAVE_COMPLEX)
270: #  if defined(PETSC_USE_REAL_SINGLE)
271: #    define MPIU_COMPLEX MPIU_C_COMPLEX
272: #  elif defined(PETSC_USE_REAL_DOUBLE)
273: #    define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
274: #  elif defined(PETSC_USE_REAL___FLOAT128)
275: #    define MPIU_COMPLEX MPIU___COMPLEX128
276: #  endif /* PETSC_USE_REAL_* */
277: #endif

279: #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
280: typedef PetscComplex PetscScalar;
281: #define PetscRealPart(a)      PetscRealPartComplex(a)
282: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
283: #define PetscAbsScalar(a)     PetscAbsComplex(a)
284: #define PetscConj(a)          PetscConjComplex(a)
285: #define PetscSqrtScalar(a)    PetscSqrtComplex(a)
286: #define PetscPowScalar(a,b)   PetscPowComplex(a,b)
287: #define PetscExpScalar(a)     PetscExpComplex(a)
288: #define PetscLogScalar(a)     PetscLogComplex(a)
289: #define PetscSinScalar(a)     PetscSinComplex(a)
290: #define PetscCosScalar(a)     PetscCosComplex(a)
291: #define PetscAsinScalar(a)    PetscAsinComplex(a)
292: #define PetscAcosScalar(a)    PetscAcosComplex(a)
293: #define PetscTanScalar(a)     PetscTanComplex(a)
294: #define PetscSinhScalar(a)    PetscSinhComplex(a)
295: #define PetscCoshScalar(a)    PetscCoshComplex(a)
296: #define PetscTanhScalar(a)    PetscTanhComplex(a)
297: #define MPIU_SCALAR MPIU_COMPLEX

299: /*
300:     real number definitions
301:  */
302: #else /* PETSC_USE_COMPLEX */
303: typedef PetscReal PetscScalar;
304: #define MPIU_SCALAR MPIU_REAL

306: #define PetscRealPart(a)      (a)
307: #define PetscImaginaryPart(a) ((PetscReal)0.)
308: PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
309: #define PetscConj(a)          (a)
310: #if !defined(PETSC_USE_REAL___FLOAT128)
311: #define PetscSqrtScalar(a)    sqrt(a)
312: #define PetscPowScalar(a,b)   pow(a,b)
313: #define PetscExpScalar(a)     exp(a)
314: #define PetscLogScalar(a)     log(a)
315: #define PetscSinScalar(a)     sin(a)
316: #define PetscCosScalar(a)     cos(a)
317: #define PetscAsinScalar(a)    asin(a)
318: #define PetscAcosScalar(a)    acos(a)
319: #define PetscTanScalar(a)     tan(a)
320: #define PetscSinhScalar(a)    sinh(a)
321: #define PetscCoshScalar(a)    cosh(a)
322: #define PetscTanhScalar(a)    tanh(a)
323: #else /* PETSC_USE_REAL___FLOAT128 */
324: #define PetscSqrtScalar(a)    sqrtq(a)
325: #define PetscPowScalar(a,b)   powq(a,b)
326: #define PetscExpScalar(a)     expq(a)
327: #define PetscLogScalar(a)     logq(a)
328: #define PetscSinScalar(a)     sinq(a)
329: #define PetscCosScalar(a)     cosq(a)
330: #define PetscAsinScalar(a)    asinq(a)
331: #define PetscAcosScalar(a)    acosq(a)
332: #define PetscTanScalar(a)     tanq(a)
333: #define PetscSinhScalar(a)    sinhq(a)
334: #define PetscCoshScalar(a)    coshq(a)
335: #define PetscTanhScalar(a)    tanhq(a)
336: #endif /* PETSC_USE_REAL___FLOAT128 */

338: #endif /* PETSC_USE_COMPLEX */

340: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
341: #define PetscSignReal(a) (((a) >= 0.0) ? ((a) == 0.0 ? 0.0 : 1.0) : -1.0)
342: #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))

344: /* --------------------------------------------------------------------------*/

346: /*
347:    Certain objects may be created using either single or double precision.
348:    This is currently not used.
349: */
350: typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;

352: #if defined(PETSC_HAVE_COMPLEX)
353: /* PETSC_i is the imaginary number, i */
354: PETSC_EXTERN PetscComplex PETSC_i;
355: #endif

357: /*MC
358:    PetscMin - Returns minimum of two numbers

360:    Synopsis:
361:    #include <petscmath.h>
362:    type PetscMin(type v1,type v2)

364:    Not Collective

366:    Input Parameter:
367: +  v1 - first value to find minimum of
368: -  v2 - second value to find minimum of

370:    Notes: type can be integer or floating point value

372:    Level: beginner

374: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

376: M*/
377: #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))

379: /*MC
380:    PetscMax - Returns maxium of two numbers

382:    Synopsis:
383:    #include <petscmath.h>
384:    type max PetscMax(type v1,type v2)

386:    Not Collective

388:    Input Parameter:
389: +  v1 - first value to find maximum of
390: -  v2 - second value to find maximum of

392:    Notes: type can be integer or floating point value

394:    Level: beginner

396: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

398: M*/
399: #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))

401: /*MC
402:    PetscClipInterval - Returns a number clipped to be within an interval

404:    Synopsis:
405:    #include <petscmath.h>
406:    type clip PetscClipInterval(type x,type a,type b)

408:    Not Collective

410:    Input Parameter:
411: +  x - value to use if within interval (a,b)
412: .  a - lower end of interval
413: -  b - upper end of interval

415:    Notes: type can be integer or floating point value

417:    Level: beginner

419: .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

421: M*/
422: #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))

424: /*MC
425:    PetscAbsInt - Returns the absolute value of an integer

427:    Synopsis:
428:    #include <petscmath.h>
429:    int abs PetscAbsInt(int v1)

431:    Not Collective

433:    Input Parameter:
434: .   v1 - the integer

436:    Level: beginner

438: .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()

440: M*/
441: #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))

443: /*MC
444:    PetscAbsReal - Returns the absolute value of an real number

446:    Synopsis:
447:    #include <petscmath.h>
448:    Real abs PetscAbsReal(PetscReal v1)

450:    Not Collective

452:    Input Parameter:
453: .   v1 - the double


456:    Level: beginner

458: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()

460: M*/
461: #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))

463: /*MC
464:    PetscSqr - Returns the square of a number

466:    Synopsis:
467:    #include <petscmath.h>
468:    type sqr PetscSqr(type v1)

470:    Not Collective

472:    Input Parameter:
473: .   v1 - the value

475:    Notes: type can be integer or floating point value

477:    Level: beginner

479: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()

481: M*/
482: #define PetscSqr(a)     ((a)*(a))

484: /* ----------------------------------------------------------------------------*/
485: /*
486:      Basic constants
487: */
488: #if defined(PETSC_USE_REAL___FLOAT128)
489: #define PETSC_PI                 M_PIq
490: #elif defined(M_PI)
491: #define PETSC_PI                 M_PI
492: #else
493: #define PETSC_PI                 3.14159265358979323846264338327950288419716939937510582
494: #endif

496: #if !defined(PETSC_USE_64BIT_INDICES)
497: #define PETSC_MAX_INT            2147483647
498: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
499: #else
500: #define PETSC_MAX_INT            9223372036854775807L
501: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
502: #endif

504: #if defined(PETSC_USE_REAL_SINGLE)
505: #  define PETSC_MAX_REAL                3.40282346638528860e+38F
506: #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
507: #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
508: #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
509: #  define PETSC_SMALL                   1.e-5
510: #elif defined(PETSC_USE_REAL_DOUBLE)
511: #  define PETSC_MAX_REAL                1.7976931348623157e+308
512: #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
513: #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
514: #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
515: #  define PETSC_SMALL                   1.e-10
516: #elif defined(PETSC_USE_REAL___FLOAT128)
517: #  define PETSC_MAX_REAL                FLT128_MAX
518: #  define PETSC_MIN_REAL                -FLT128_MAX
519: #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
520: #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17q
521: #  define PETSC_SMALL                   1.e-20q
522: #endif

524: #define PETSC_INFINITY                PETSC_MAX_REAL/4.0
525: #define PETSC_NINFINITY              -PETSC_INFINITY

527: PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
528: PETSC_EXTERN PetscErrorCode PetscIsNanReal(PetscReal);
529: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
530: PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
531: PETSC_STATIC_INLINE PetscErrorCode PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));}
532: PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}

534: /*
535:     These macros are currently hardwired to match the regular data types, so there is no support for a different
536:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
537:  */
538: #define MPIU_MATSCALAR MPIU_SCALAR
539: typedef PetscScalar MatScalar;
540: typedef PetscReal MatReal;

542: struct petsc_mpiu_2scalar {PetscScalar a,b;};
543: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
544: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
545: struct petsc_mpiu_2int {PetscInt a,b;};
546: PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
547: #else
548: #define MPIU_2INT MPI_2INT
549: #endif

551: PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
552: {
553:   PetscInt result = 1;
554:   while (power) {
555:     if (power & 1) result *= base;
556:     power >>= 1;
557:     base *= base;
558:   }
559:   return result;
560: }

562: PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
563: {
564:   PetscReal result = 1;
565:   if (power < 0) {
566:     power = -power;
567:     base  = ((PetscReal)1)/base;
568:   }
569:   while (power) {
570:     if (power & 1) result *= base;
571:     power >>= 1;
572:     base *= base;
573:   }
574:   return result;
575: }

577: PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
578: {
579:   PetscScalar result = 1;
580:   if (power < 0) {
581:     power = -power;
582:     base  = ((PetscReal)1)/base;
583:   }
584:   while (power) {
585:     if (power & 1) result *= base;
586:     power >>= 1;
587:     base *= base;
588:   }
589:   return result;
590: }

592: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
593: {
594:   PetscScalar cpower = power;
595:   return PetscPowScalar(base,cpower);
596: }

598: #ifndef PETSC_HAVE_LOG2
599: PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n)
600: {
601:   return PetscLogReal(n)/PetscLogReal(2.0);
602: }
603: #endif
604: #endif