Actual source code: petscmath.h
petsc-3.7.7 2017-09-25
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: #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