Actual source code: petscmath.h

petsc-3.6.4 2016-04-12
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: #define PetscExpPassiveScalar(a) PetscExpScalar()
 25: #if defined(PETSC_USE_REAL_SINGLE)
 26: #define MPIU_REAL   MPI_FLOAT
 27: typedef float PetscReal;
 28: #define PetscSqrtReal(a)    sqrt(a)
 29: #define PetscExpReal(a)     exp(a)
 30: #define PetscLogReal(a)     log(a)
 31: #define PetscLog10Real(a)   log10(a)
 32: #ifdef PETSC_HAVE_LOG2
 33: #define PetscLog2Real(a)    log2(a)
 34: #endif
 35: #define PetscSinReal(a)     sin(a)
 36: #define PetscCosReal(a)     cos(a)
 37: #define PetscTanReal(a)     tan(a)
 38: #define PetscAsinReal(a)    asin(a)
 39: #define PetscAcosReal(a)    acos(a)
 40: #define PetscAtanReal(a)    atan(a)
 41: #define PetscAtan2Real(a,b) atan2(a,b)
 42: #define PetscSinhReal(a)    sinh(a)
 43: #define PetscCoshReal(a)    cosh(a)
 44: #define PetscTanhReal(a)    tanh(a)
 45: #define PetscPowReal(a,b)   pow(a,b)
 46: #define PetscCeilReal(a)    ceil(a)
 47: #define PetscFloorReal(a)   floor(a)
 48: #define PetscFmodReal(a,b)  fmod(a,b)
 49: #define PetscTGamma(a)      tgammaf(a)
 50: #elif defined(PETSC_USE_REAL_DOUBLE)
 51: #define MPIU_REAL   MPI_DOUBLE
 52: typedef double PetscReal;
 53: #define PetscSqrtReal(a)    sqrt(a)
 54: #define PetscExpReal(a)     exp(a)
 55: #define PetscLogReal(a)     log(a)
 56: #define PetscLog10Real(a)   log10(a)
 57: #ifdef PETSC_HAVE_LOG2
 58: #define PetscLog2Real(a)    log2(a)
 59: #endif
 60: #define PetscSinReal(a)     sin(a)
 61: #define PetscCosReal(a)     cos(a)
 62: #define PetscTanReal(a)     tan(a)
 63: #define PetscAsinReal(a)    asin(a)
 64: #define PetscAcosReal(a)    acos(a)
 65: #define PetscAtanReal(a)    atan(a)
 66: #define PetscAtan2Real(a,b) atan2(a,b)
 67: #define PetscSinhReal(a)    sinh(a)
 68: #define PetscCoshReal(a)    cosh(a)
 69: #define PetscTanhReal(a)    tanh(a)
 70: #define PetscPowReal(a,b)   pow(a,b)
 71: #define PetscCeilReal(a)    ceil(a)
 72: #define PetscFloorReal(a)   floor(a)
 73: #define PetscFmodReal(a,b)  fmod(a,b)
 74: #define PetscTGamma(a)      tgamma(a)
 75: #elif defined(PETSC_USE_REAL___FLOAT128)
 76: #if defined(__cplusplus)
 77: extern "C" {
 78: #endif
 79: #include <quadmath.h>
 80: #if defined(__cplusplus)
 81: }
 82: #endif
 83: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
 84: #define MPIU_REAL MPIU___FLOAT128
 85: typedef __float128 PetscReal;
 86: #define PetscSqrtReal(a)    sqrtq(a)
 87: #define PetscExpReal(a)     expq(a)
 88: #define PetscLogReal(a)     logq(a)
 89: #define PetscLog10Real(a)   log10q(a)
 90: #ifdef PETSC_HAVE_LOG2
 91: #define PetscLog2Real(a)    log2q(a)
 92: #endif
 93: #define PetscSinReal(a)     sinq(a)
 94: #define PetscCosReal(a)     cosq(a)
 95: #define PetscTanReal(a)     tanq(a)
 96: #define PetscAsinReal(a)    asinq(a)
 97: #define PetscAcosReal(a)    acosq(a)
 98: #define PetscAtanReal(a)    atanq(a)
 99: #define PetscAtan2Real(a,b) atan2q(a,b)
100: #define PetscSinhReal(a)    sinhq(a)
101: #define PetscCoshReal(a)    coshq(a)
102: #define PetscTanhReal(a)    tanhq(a)
103: #define PetscPowReal(a,b)   powq(a,b)
104: #define PetscCeilReal(a)    ceilq(a)
105: #define PetscFloorReal(a)   floorq(a)
106: #define PetscFmodReal(a,b)  fmodq(a,b)
107: #define PetscTGamma(a)      tgammaq(a)
108: #endif /* PETSC_USE_REAL_* */

110: /*
111:     Complex number definitions
112:  */
113: #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
114: #if !defined(PETSC_SKIP_COMPLEX)
115: #define PETSC_HAVE_COMPLEX 1
116: /* C++ support of complex number */
117: #if defined(PETSC_HAVE_CUSP)
118: #define complexlib cusp
119: #include <cusp/complex.h>
120: #else
121: #define complexlib std
122: #include <complex>
123: #endif

125: #define PetscRealPartComplex(a)      (a).real()
126: #define PetscImaginaryPartComplex(a) (a).imag()
127: #define PetscAbsComplex(a)           complexlib::abs(a)
128: #define PetscConjComplex(a)          complexlib::conj(a)
129: #define PetscSqrtComplex(a)          complexlib::sqrt(a)
130: #define PetscPowComplex(a,b)         complexlib::pow(a,b)
131: #define PetscExpComplex(a)           complexlib::exp(a)
132: #define PetscLogComplex(a)           complexlib::log(a)
133: #define PetscSinComplex(a)           complexlib::sin(a)
134: #define PetscCosComplex(a)           complexlib::cos(a)
135: #define PetscAsinComplex(a)          complexlib::asin(a)
136: #define PetscAcosComplex(a)          complexlib::acos(a)
137: #define PetscTanComplex(a)           complexlib::tan(a)
138: #define PetscSinhComplex(a)          complexlib::sinh(a)
139: #define PetscCoshComplex(a)          complexlib::cosh(a)
140: #define PetscTanhComplex(a)          complexlib::tanh(a)

142: #if defined(PETSC_USE_REAL_SINGLE)
143: typedef complexlib::complex<float> PetscComplex;
144: #elif defined(PETSC_USE_REAL_DOUBLE)
145: typedef complexlib::complex<double> PetscComplex;
146: #elif defined(PETSC_USE_REAL___FLOAT128)
147: typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */
148: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128;
149: #endif  /* PETSC_USE_REAL_ */
150: #endif  /* ! PETSC_SKIP_COMPLEX */

152: #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
153: #if !defined(PETSC_SKIP_COMPLEX)
154: #define PETSC_HAVE_COMPLEX 1
155: #include <complex.h>

157: #if defined(PETSC_USE_REAL_SINGLE)
158: typedef float _Complex PetscComplex;

160: #define PetscRealPartComplex(a)      crealf(a)
161: #define PetscImaginaryPartComplex(a) cimagf(a)
162: #define PetscAbsComplex(a)           cabsf(a)
163: #define PetscConjComplex(a)          conjf(a)
164: #define PetscSqrtComplex(a)          csqrtf(a)
165: #define PetscPowComplex(a,b)         cpowf(a,b)
166: #define PetscExpComplex(a)           cexpf(a)
167: #define PetscLogComplex(a)           clogf(a)
168: #define PetscSinComplex(a)           csinf(a)
169: #define PetscCosComplex(a)           ccosf(a)
170: #define PetscAsinComplex(a)          casinf(a)
171: #define PetscAcosComplex(a)          cacosf(a)
172: #define PetscTanComplex(a)           ctanf(a)
173: #define PetscSinhComplex(a)          csinhf(a)
174: #define PetscCoshComplex(a)          ccoshf(a)
175: #define PetscTanhComplex(a)          ctanhf(a)

177: #elif defined(PETSC_USE_REAL_DOUBLE)
178: typedef double _Complex PetscComplex;

180: #define PetscRealPartComplex(a)      creal(a)
181: #define PetscImaginaryPartComplex(a) cimag(a)
182: #define PetscAbsComplex(a)           cabs(a)
183: #define PetscConjComplex(a)          conj(a)
184: #define PetscSqrtComplex(a)          csqrt(a)
185: #define PetscPowComplex(a,b)         cpow(a,b)
186: #define PetscExpComplex(a)           cexp(a)
187: #define PetscLogComplex(a)           clog(a)
188: #define PetscSinComplex(a)           csin(a)
189: #define PetscCosComplex(a)           ccos(a)
190: #define PetscAsinComplex(a)          casin(a)
191: #define PetscAcosComplex(a)          cacos(a)
192: #define PetscTanComplex(a)           ctan(a)
193: #define PetscSinhComplex(a)          csinh(a)
194: #define PetscCoshComplex(a)          ccosh(a)
195: #define PetscTanhComplex(a)          ctanh(a)

197: #elif defined(PETSC_USE_REAL___FLOAT128)
198: typedef __complex128 PetscComplex;
199: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);

201: #define PetscRealPartComplex(a)      crealq(a)
202: #define PetscImaginaryPartComplex(a) cimagq(a)
203: #define PetscAbsComplex(a)           cabsq(a)
204: #define PetscConjComplex(a)          conjq(a)
205: #define PetscSqrtComplex(a)          csqrtq(a)
206: #define PetscPowComplex(a,b)         cpowq(a,b)
207: #define PetscExpComplex(a)           cexpq(a)
208: #define PetscLogComplex(a)           clogq(a)
209: #define PetscSinComplex(a)           csinq(a)
210: #define PetscCosComplex(a)           ccosq(a)
211: #define PetscAsinComplex(a)          casinq(a)
212: #define PetscAcosComplex(a)          cacosq(a)
213: #define PetscTanComplex(a)           ctanq(a)
214: #define PetscSinhComplex(a)          csinhq(a)
215: #define PetscCoshComplex(a)          ccoshq(a)
216: #define PetscTanhComplex(a)          ctanhq(a)

218: #endif /* PETSC_USE_REAL_* */
219: #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
220: #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available"
221: #endif /* !PETSC_SKIP_COMPLEX */
222: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */

224: #if defined(PETSC_HAVE_COMPLEX)
225: #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
226: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
227: #define MPIU_C_COMPLEX MPI_C_COMPLEX
228: #else
229: # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX)
230:   typedef complexlib::complex<double> petsc_mpiu_c_double_complex;
231:   typedef complexlib::complex<float> petsc_mpiu_c_complex;
232: # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
233:   typedef double _Complex petsc_mpiu_c_double_complex;
234:   typedef float _Complex petsc_mpiu_c_complex;
235: # else
236:   typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
237:   typedef struct {float real,imag;} petsc_mpiu_c_complex;
238: # endif
239: PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
240: PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
241: #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
242: #endif /* PETSC_HAVE_COMPLEX */

244: #if defined(PETSC_HAVE_COMPLEX)
245: #  if defined(PETSC_USE_REAL_SINGLE)
246: #    define MPIU_COMPLEX MPIU_C_COMPLEX
247: #  elif defined(PETSC_USE_REAL_DOUBLE)
248: #    define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
249: #  elif defined(PETSC_USE_REAL___FLOAT128)
250: #    define MPIU_COMPLEX MPIU___COMPLEX128
251: #  endif /* PETSC_USE_REAL_* */
252: #endif

254: #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
255: typedef PetscComplex PetscScalar;
256: #define PetscRealPart(a)      PetscRealPartComplex(a)
257: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
258: #define PetscAbsScalar(a)     PetscAbsComplex(a)
259: #define PetscConj(a)          PetscConjComplex(a)
260: #define PetscSqrtScalar(a)    PetscSqrtComplex(a)
261: #define PetscPowScalar(a,b)   PetscPowComplex(a,b)
262: #define PetscExpScalar(a)     PetscExpComplex(a)
263: #define PetscLogScalar(a)     PetscLogComplex(a)
264: #define PetscSinScalar(a)     PetscSinComplex(a)
265: #define PetscCosScalar(a)     PetscCosComplex(a)
266: #define PetscAsinScalar(a)    PetscAsinComplex(a)
267: #define PetscAcosScalar(a)    PetscAcosComplex(a)
268: #define PetscTanScalar(a)     PetscTanComplex(a)
269: #define PetscSinhScalar(a)    PetscSinhComplex(a)
270: #define PetscCoshScalar(a)    PetscCoshComplex(a)
271: #define PetscTanhScalar(a)    PetscTanhComplex(a)
272: #define MPIU_SCALAR MPIU_COMPLEX

274: /*
275:     real number definitions
276:  */
277: #else /* PETSC_USE_COMPLEX */
278: typedef PetscReal PetscScalar;
279: #define MPIU_SCALAR MPIU_REAL

281: #define PetscRealPart(a)      (a)
282: #define PetscImaginaryPart(a) ((PetscReal)0.)
283: PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
284: #define PetscConj(a)          (a)
285: #if !defined(PETSC_USE_REAL___FLOAT128)
286: #define PetscSqrtScalar(a)    sqrt(a)
287: #define PetscPowScalar(a,b)   pow(a,b)
288: #define PetscExpScalar(a)     exp(a)
289: #define PetscLogScalar(a)     log(a)
290: #define PetscSinScalar(a)     sin(a)
291: #define PetscCosScalar(a)     cos(a)
292: #define PetscAsinScalar(a)    asin(a)
293: #define PetscAcosScalar(a)    acos(a)
294: #define PetscTanScalar(a)     tan(a)
295: #define PetscSinhScalar(a)    sinh(a)
296: #define PetscCoshScalar(a)    cosh(a)
297: #define PetscTanhScalar(a)    tanh(a)
298: #else /* PETSC_USE_REAL___FLOAT128 */
299: #define PetscSqrtScalar(a)    sqrtq(a)
300: #define PetscPowScalar(a,b)   powq(a,b)
301: #define PetscExpScalar(a)     expq(a)
302: #define PetscLogScalar(a)     logq(a)
303: #define PetscSinScalar(a)     sinq(a)
304: #define PetscCosScalar(a)     cosq(a)
305: #define PetscAsinScalar(a)    asinq(a)
306: #define PetscAcosScalar(a)    acosq(a)
307: #define PetscTanScalar(a)     tanq(a)
308: #define PetscSinhScalar(a)    sinhq(a)
309: #define PetscCoshScalar(a)    coshq(a)
310: #define PetscTanhScalar(a)    tanhq(a)
311: #endif /* PETSC_USE_REAL___FLOAT128 */

313: #endif /* PETSC_USE_COMPLEX */

315: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
316: #define PetscAbs(a)  (((a) >= 0) ? (a) : -(a))

318: /* --------------------------------------------------------------------------*/

320: /*
321:    Certain objects may be created using either single or double precision.
322:    This is currently not used.
323: */
324: typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;

326: #if defined(PETSC_HAVE_COMPLEX)
327: /* PETSC_i is the imaginary number, i */
328: PETSC_EXTERN PetscComplex PETSC_i;
329: #endif

331: /*MC
332:    PetscMin - Returns minimum of two numbers

334:    Synopsis:
335:    #include <petscmath.h>
336:    type PetscMin(type v1,type v2)

338:    Not Collective

340:    Input Parameter:
341: +  v1 - first value to find minimum of
342: -  v2 - second value to find minimum of

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

346:    Level: beginner

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

350: M*/
351: #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))

353: /*MC
354:    PetscMax - Returns maxium of two numbers

356:    Synopsis:
357:    #include <petscmath.h>
358:    type max PetscMax(type v1,type v2)

360:    Not Collective

362:    Input Parameter:
363: +  v1 - first value to find maximum of
364: -  v2 - second value to find maximum of

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

368:    Level: beginner

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

372: M*/
373: #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))

375: /*MC
376:    PetscClipInterval - Returns a number clipped to be within an interval

378:    Synopsis:
379:    #include <petscmath.h>
380:    type clip PetscClipInterval(type x,type a,type b)

382:    Not Collective

384:    Input Parameter:
385: +  x - value to use if within interval (a,b)
386: .  a - lower end of interval
387: -  b - upper end of interval

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

391:    Level: beginner

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

395: M*/
396: #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))

398: /*MC
399:    PetscAbsInt - Returns the absolute value of an integer

401:    Synopsis:
402:    #include <petscmath.h>
403:    int abs PetscAbsInt(int v1)

405:    Not Collective

407:    Input Parameter:
408: .   v1 - the integer

410:    Level: beginner

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

414: M*/
415: #define PetscAbsInt(a)  (((a)<0)   ? -(a) : (a))

417: /*MC
418:    PetscAbsReal - Returns the absolute value of an real number

420:    Synopsis:
421:    #include <petscmath.h>
422:    Real abs PetscAbsReal(PetscReal v1)

424:    Not Collective

426:    Input Parameter:
427: .   v1 - the double


430:    Level: beginner

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

434: M*/
435: #define PetscAbsReal(a) (((a)<0)   ? -(a) : (a))

437: /*MC
438:    PetscSqr - Returns the square of a number

440:    Synopsis:
441:    #include <petscmath.h>
442:    type sqr PetscSqr(type v1)

444:    Not Collective

446:    Input Parameter:
447: .   v1 - the value

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

451:    Level: beginner

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

455: M*/
456: #define PetscSqr(a)     ((a)*(a))

458: /* ----------------------------------------------------------------------------*/
459: /*
460:      Basic constants
461: */
462: #if defined(PETSC_USE_REAL___FLOAT128)
463: #define PETSC_PI                 M_PIq
464: #elif defined(M_PI)
465: #define PETSC_PI                 M_PI
466: #else
467: #define PETSC_PI                 3.14159265358979323846264338327950288419716939937510582
468: #endif

470: #if !defined(PETSC_USE_64BIT_INDICES)
471: #define PETSC_MAX_INT            2147483647
472: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
473: #else
474: #define PETSC_MAX_INT            9223372036854775807L
475: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
476: #endif

478: #if defined(PETSC_USE_REAL_SINGLE)
479: #  define PETSC_MAX_REAL                3.40282346638528860e+38F
480: #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
481: #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
482: #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
483: #  define PETSC_SMALL                   1.e-5
484: #elif defined(PETSC_USE_REAL_DOUBLE)
485: #  define PETSC_MAX_REAL                1.7976931348623157e+308
486: #  define PETSC_MIN_REAL                -PETSC_MAX_REAL
487: #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
488: #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
489: #  define PETSC_SMALL                   1.e-10
490: #elif defined(PETSC_USE_REAL___FLOAT128)
491: #  define PETSC_MAX_REAL                FLT128_MAX
492: #  define PETSC_MIN_REAL                -FLT128_MAX
493: #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
494: #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078e-17
495: #  define PETSC_SMALL                   1.e-20
496: #endif

498: #define PETSC_INFINITY                PETSC_MAX_REAL/4.0
499: #define PETSC_NINFINITY              -PETSC_INFINITY

501: PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
502: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
503: PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
504: PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}

506: /* ----------------------------------------------------------------------------*/
507: #define PassiveReal   PetscReal
508: #define PassiveScalar PetscScalar

510: /*
511:     These macros are currently hardwired to match the regular data types, so there is no support for a different
512:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
513:  */
514: #define MPIU_MATSCALAR MPIU_SCALAR
515: typedef PetscScalar MatScalar;
516: typedef PetscReal MatReal;

518: struct petsc_mpiu_2scalar {PetscScalar a,b;};
519: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
520: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
521: struct petsc_mpiu_2int {PetscInt a,b;};
522: PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
523: #else
524: #define MPIU_2INT MPI_2INT
525: #endif

527: PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
528: {
529:   PetscInt result = 1;
530:   while (power) {
531:     if (power & 1) result *= base;
532:     power >>= 1;
533:     base *= base;
534:   }
535:   return result;
536: }

538: PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
539: {
540:   PetscReal result = 1;
541:   if (power < 0) {
542:     power = -power;
543:     if (base != 0.0) base  = 1./base;
544:   }
545:   while (power) {
546:     if (power & 1) result *= base;
547:     power >>= 1;
548:     base *= base;
549:   }
550:   return result;
551: }

553: PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
554: {
555:   PetscScalar result = 1;
556:   if (power < 0) {
557:     power = -power;
558:     if (base != 0.0) base  = 1./base;
559:   }
560:   while (power) {
561:     if (power & 1) result *= base;
562:     power >>= 1;
563:     base *= base;
564:   }
565:   return result;
566: }

568: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
569: {
570:   PetscScalar cpower = power;
571:   return PetscPowScalar(base,cpower);
572: }

574: #ifndef PETSC_HAVE_LOG2
575: PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n)
576: {
577:   return PetscLogReal(n)/PetscLogReal(2.0);
578: }
579: #endif
580: #endif