Actual source code: petscmath.h
petsc-3.12.4 2020-02-04
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: */

     11: #if !defined(PETSCMATH_H)
     12: #define PETSCMATH_H
     13: #include <math.h>
     14:  #include <petscsystypes.h>

     16: /*

     18:    Defines operations that are different for complex and real numbers.
     19:    All PETSc objects in one program are built around the object
     20:    PetscScalar which is either always a real or a complex.

     22: */

     24: /*
     25:     Real number definitions
     26:  */
     27: #if defined(PETSC_USE_REAL_SINGLE)
     28: #define PetscSqrtReal(a)    sqrtf(a)
     29: #define PetscCbrtReal(a)    cbrtf(a)
     30: #define PetscHypotReal(a,b) hypotf(a,b)
     31: #define PetscAtan2Real(a,b) atan2f(a,b)
     32: #define PetscPowReal(a,b)   powf(a,b)
     33: #define PetscExpReal(a)     expf(a)
     34: #define PetscLogReal(a)     logf(a)
     35: #define PetscLog10Real(a)   log10f(a)
     36: #define PetscLog2Real(a)    log2f(a)
     37: #define PetscSinReal(a)     sinf(a)
     38: #define PetscCosReal(a)     cosf(a)
     39: #define PetscTanReal(a)     tanf(a)
     40: #define PetscAsinReal(a)    asinf(a)
     41: #define PetscAcosReal(a)    acosf(a)
     42: #define PetscAtanReal(a)    atanf(a)
     43: #define PetscSinhReal(a)    sinhf(a)
     44: #define PetscCoshReal(a)    coshf(a)
     45: #define PetscTanhReal(a)    tanhf(a)
     46: #define PetscAsinhReal(a)   asinhf(a)
     47: #define PetscAcoshReal(a)   acoshf(a)
     48: #define PetscAtanhReal(a)   atanhf(a)
     49: #define PetscCeilReal(a)    ceilf(a)
     50: #define PetscFloorReal(a)   floorf(a)
     51: #define PetscFmodReal(a,b)  fmodf(a,b)
     52: #define PetscTGamma(a)      tgammaf(a)

     54: #elif defined(PETSC_USE_REAL_DOUBLE)
     55: #define PetscSqrtReal(a)    sqrt(a)
     56: #define PetscCbrtReal(a)    cbrt(a)
     57: #define PetscHypotReal(a,b) hypot(a,b)
     58: #define PetscAtan2Real(a,b) atan2(a,b)
     59: #define PetscPowReal(a,b)   pow(a,b)
     60: #define PetscExpReal(a)     exp(a)
     61: #define PetscLogReal(a)     log(a)
     62: #define PetscLog10Real(a)   log10(a)
     63: #define PetscLog2Real(a)    log2(a)
     64: #define PetscSinReal(a)     sin(a)
     65: #define PetscCosReal(a)     cos(a)
     66: #define PetscTanReal(a)     tan(a)
     67: #define PetscAsinReal(a)    asin(a)
     68: #define PetscAcosReal(a)    acos(a)
     69: #define PetscAtanReal(a)    atan(a)
     70: #define PetscSinhReal(a)    sinh(a)
     71: #define PetscCoshReal(a)    cosh(a)
     72: #define PetscTanhReal(a)    tanh(a)
     73: #define PetscAsinhReal(a)   asinh(a)
     74: #define PetscAcoshReal(a)   acosh(a)
     75: #define PetscAtanhReal(a)   atanh(a)
     76: #define PetscCeilReal(a)    ceil(a)
     77: #define PetscFloorReal(a)   floor(a)
     78: #define PetscFmodReal(a,b)  fmod(a,b)
     79: #define PetscTGamma(a)      tgamma(a)

     81: #elif defined(PETSC_USE_REAL___FLOAT128)
     82: #define PetscSqrtReal(a)    sqrtq(a)
     83: #define PetscCbrtReal(a)    cbrtq(a)
     84: #define PetscHypotReal(a,b) hypotq(a,b)
     85: #define PetscAtan2Real(a,b) atan2q(a,b)
     86: #define PetscPowReal(a,b)   powq(a,b)
     87: #define PetscExpReal(a)     expq(a)
     88: #define PetscLogReal(a)     logq(a)
     89: #define PetscLog10Real(a)   log10q(a)
     90: #define PetscLog2Real(a)    log2q(a)
     91: #define PetscSinReal(a)     sinq(a)
     92: #define PetscCosReal(a)     cosq(a)
     93: #define PetscTanReal(a)     tanq(a)
     94: #define PetscAsinReal(a)    asinq(a)
     95: #define PetscAcosReal(a)    acosq(a)
     96: #define PetscAtanReal(a)    atanq(a)
     97: #define PetscSinhReal(a)    sinhq(a)
     98: #define PetscCoshReal(a)    coshq(a)
     99: #define PetscTanhReal(a)    tanhq(a)
    100: #define PetscAsinhReal(a)   asinhq(a)
    101: #define PetscAcoshReal(a)   acoshq(a)
    102: #define PetscAtanhReal(a)   atanhq(a)
    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)

    108: #elif defined(PETSC_USE_REAL___FP16)
    109: #define PetscSqrtReal(a)    sqrtf(a)
    110: #define PetscCbrtReal(a)    cbrtf(a)
    111: #define PetscHypotReal(a,b) hypotf(a,b)
    112: #define PetscAtan2Real(a,b) atan2f(a,b)
    113: #define PetscPowReal(a,b)   powf(a,b)
    114: #define PetscExpReal(a)     expf(a)
    115: #define PetscLogReal(a)     logf(a)
    116: #define PetscLog10Real(a)   log10f(a)
    117: #define PetscLog2Real(a)    log2f(a)
    118: #define PetscSinReal(a)     sinf(a)
    119: #define PetscCosReal(a)     cosf(a)
    120: #define PetscTanReal(a)     tanf(a)
    121: #define PetscAsinReal(a)    asinf(a)
    122: #define PetscAcosReal(a)    acosf(a)
    123: #define PetscAtanReal(a)    atanf(a)
    124: #define PetscSinhReal(a)    sinhf(a)
    125: #define PetscCoshReal(a)    coshf(a)
    126: #define PetscTanhReal(a)    tanhf(a)
    127: #define PetscAsinhReal(a)   asinhf(a)
    128: #define PetscAcoshReal(a)   acoshf(a)
    129: #define PetscAtanhReal(a)   atanhf(a)
    130: #define PetscCeilReal(a)    ceilf(a)
    131: #define PetscFloorReal(a)   floorf(a)
    132: #define PetscFmodReal(a,b)  fmodf(a,b)
    133: #define PetscTGamma(a)      tgammaf(a)

    135: #endif /* PETSC_USE_REAL_* */

    137: PETSC_STATIC_INLINE PetscReal PetscSignReal(PetscReal a)
    138: {
    139:   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
    140: }

    142: #if !defined(PETSC_HAVE_LOG2)
    143: #undef PetscLog2Real
    144: PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal a)
    145: {
    146:   return PetscLogReal(a)/PetscLogReal((PetscReal)2);
    147: }
    148: #endif

    150: #if defined(PETSC_USE_REAL___FLOAT128)
    151: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
    152: #endif
    153: #if defined(PETSC_USE_REAL___FP16)
    154: PETSC_EXTERN MPI_Datatype MPIU___FP16 PetscAttrMPITypeTag(__fp16);
    155: #endif

    157: /*MC
    158:    MPIU_REAL - MPI datatype corresponding to PetscReal

    160:    Notes:
    161:    In MPI calls that require an MPI datatype that matches a PetscReal or array of PetscReal values, pass this value.

    163:    Level: beginner

    165: .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_SCALAR, MPIU_COMPLEX, MPIU_INT
    166: M*/
    167: #if defined(PETSC_USE_REAL_SINGLE)
    168: #  define MPIU_REAL MPI_FLOAT
    169: #elif defined(PETSC_USE_REAL_DOUBLE)
    170: #  define MPIU_REAL MPI_DOUBLE
    171: #elif defined(PETSC_USE_REAL___FLOAT128)
    172: #  define MPIU_REAL MPIU___FLOAT128
    173: #elif defined(PETSC_USE_REAL___FP16)
    174: #  define MPIU_REAL MPIU___FP16
    175: #endif /* PETSC_USE_REAL_* */

    177: /*
    178:     Complex number definitions
    179:  */
    180: #if defined(PETSC_HAVE_COMPLEX)
    181: #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
    182: /* C++ support of complex number */

    184: #define PetscRealPartComplex(a)      (a).real()
    185: #define PetscImaginaryPartComplex(a) (a).imag()
    186: #define PetscAbsComplex(a)           petsccomplexlib::abs(a)
    187: #define PetscArgComplex(a)           petsccomplexlib::arg(a)
    188: #define PetscConjComplex(a)          petsccomplexlib::conj(a)
    189: #define PetscSqrtComplex(a)          petsccomplexlib::sqrt(a)
    190: #define PetscPowComplex(a,b)         petsccomplexlib::pow(a,b)
    191: #define PetscExpComplex(a)           petsccomplexlib::exp(a)
    192: #define PetscLogComplex(a)           petsccomplexlib::log(a)
    193: #define PetscSinComplex(a)           petsccomplexlib::sin(a)
    194: #define PetscCosComplex(a)           petsccomplexlib::cos(a)
    195: #define PetscTanComplex(a)           petsccomplexlib::tan(a)
    196: #define PetscAsinComplex(a)          petsccomplexlib::asin(a)
    197: #define PetscAcosComplex(a)          petsccomplexlib::acos(a)
    198: #define PetscAtanComplex(a)          petsccomplexlib::atan(a)
    199: #define PetscSinhComplex(a)          petsccomplexlib::sinh(a)
    200: #define PetscCoshComplex(a)          petsccomplexlib::cosh(a)
    201: #define PetscTanhComplex(a)          petsccomplexlib::tanh(a)
    202: #define PetscAsinhComplex(a)         petsccomplexlib::asinh(a)
    203: #define PetscAcoshComplex(a)         petsccomplexlib::acosh(a)
    204: #define PetscAtanhComplex(a)         petsccomplexlib::atanh(a)

    206: /* TODO: Add configure tests

    208: #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
    209: #undef PetscTanComplex
    210: PETSC_STATIC_INLINE PetscComplex PetscTanComplex(PetscComplex z)
    211: {
    212:   return PetscSinComplex(z)/PetscCosComplex(z);
    213: }
    214: #endif

    216: #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
    217: #undef PetscTanhComplex
    218: PETSC_STATIC_INLINE PetscComplex PetscTanhComplex(PetscComplex z)
    219: {
    220:   return PetscSinhComplex(z)/PetscCoshComplex(z);
    221: }
    222: #endif

    224: #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
    225: #undef PetscAsinComplex
    226: PETSC_STATIC_INLINE PetscComplex PetscAsinComplex(PetscComplex z)
    227: {
    228:   const PetscComplex j(0,1);
    229:   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
    230: }
    231: #endif

    233: #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
    234: #undef PetscAcosComplex
    235: PETSC_STATIC_INLINE PetscComplex PetscAcosComplex(PetscComplex z)
    236: {
    237:   const PetscComplex j(0,1);
    238:   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
    239: }
    240: #endif

    242: #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
    243: #undef PetscAtanComplex
    244: PETSC_STATIC_INLINE PetscComplex PetscAtanComplex(PetscComplex z)
    245: {
    246:   const PetscComplex j(0,1);
    247:   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
    248: }
    249: #endif

    251: #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
    252: #undef PetscAsinhComplex
    253: PETSC_STATIC_INLINE PetscComplex PetscAsinhComplex(PetscComplex z)
    254: {
    255:   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
    256: }
    257: #endif

    259: #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
    260: #undef PetscAcoshComplex
    261: PETSC_STATIC_INLINE PetscComplex PetscAcoshComplex(PetscComplex z)
    262: {
    263:   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
    264: }
    265: #endif

    267: #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
    268: #undef PetscAtanhComplex
    269: PETSC_STATIC_INLINE PetscComplex PetscAtanhComplex(PetscComplex z)
    270: {
    271:   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
    272: }
    273: #endif

    275: */

    277: #elif defined(PETSC_HAVE_C99_COMPLEX) && !defined(PETSC_USE_REAL___FP16)
    278: /* C99 support of complex number */

    280: #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16)
    281: #define PetscRealPartComplex(a)      crealf(a)
    282: #define PetscImaginaryPartComplex(a) cimagf(a)
    283: #define PetscAbsComplex(a)           cabsf(a)
    284: #define PetscArgComplex(a)           cargf(a)
    285: #define PetscConjComplex(a)          conjf(a)
    286: #define PetscSqrtComplex(a)          csqrtf(a)
    287: #define PetscPowComplex(a,b)         cpowf(a,b)
    288: #define PetscExpComplex(a)           cexpf(a)
    289: #define PetscLogComplex(a)           clogf(a)
    290: #define PetscSinComplex(a)           csinf(a)
    291: #define PetscCosComplex(a)           ccosf(a)
    292: #define PetscTanComplex(a)           ctanf(a)
    293: #define PetscAsinComplex(a)          casinf(a)
    294: #define PetscAcosComplex(a)          cacosf(a)
    295: #define PetscAtanComplex(a)          catanf(a)
    296: #define PetscSinhComplex(a)          csinhf(a)
    297: #define PetscCoshComplex(a)          ccoshf(a)
    298: #define PetscTanhComplex(a)          ctanhf(a)
    299: #define PetscAsinhComplex(a)         casinhf(a)
    300: #define PetscAcoshComplex(a)         cacoshf(a)
    301: #define PetscAtanhComplex(a)         catanhf(a)

    303: #elif defined(PETSC_USE_REAL_DOUBLE)
    304: #define PetscRealPartComplex(a)      creal(a)
    305: #define PetscImaginaryPartComplex(a) cimag(a)
    306: #define PetscAbsComplex(a)           cabs(a)
    307: #define PetscArgComplex(a)           carg(a)
    308: #define PetscConjComplex(a)          conj(a)
    309: #define PetscSqrtComplex(a)          csqrt(a)
    310: #define PetscPowComplex(a,b)         cpow(a,b)
    311: #define PetscExpComplex(a)           cexp(a)
    312: #define PetscLogComplex(a)           clog(a)
    313: #define PetscSinComplex(a)           csin(a)
    314: #define PetscCosComplex(a)           ccos(a)
    315: #define PetscTanComplex(a)           ctan(a)
    316: #define PetscAsinComplex(a)          casin(a)
    317: #define PetscAcosComplex(a)          cacos(a)
    318: #define PetscAtanComplex(a)          catan(a)
    319: #define PetscSinhComplex(a)          csinh(a)
    320: #define PetscCoshComplex(a)          ccosh(a)
    321: #define PetscTanhComplex(a)          ctanh(a)
    322: #define PetscAsinhComplex(a)         casinh(a)
    323: #define PetscAcoshComplex(a)         cacosh(a)
    324: #define PetscAtanhComplex(a)         catanh(a)

    326: #elif defined(PETSC_USE_REAL___FLOAT128)
    327: #define PetscRealPartComplex(a)      crealq(a)
    328: #define PetscImaginaryPartComplex(a) cimagq(a)
    329: #define PetscAbsComplex(a)           cabsq(a)
    330: #define PetscArgComplex(a)           cargq(a)
    331: #define PetscConjComplex(a)          conjq(a)
    332: #define PetscSqrtComplex(a)          csqrtq(a)
    333: #define PetscPowComplex(a,b)         cpowq(a,b)
    334: #define PetscExpComplex(a)           cexpq(a)
    335: #define PetscLogComplex(a)           clogq(a)
    336: #define PetscSinComplex(a)           csinq(a)
    337: #define PetscCosComplex(a)           ccosq(a)
    338: #define PetscTanComplex(a)           ctanq(a)
    339: #define PetscAsinComplex(a)          casinq(a)
    340: #define PetscAcosComplex(a)          cacosq(a)
    341: #define PetscAtanComplex(a)          catanq(a)
    342: #define PetscSinhComplex(a)          csinhq(a)
    343: #define PetscCoshComplex(a)          ccoshq(a)
    344: #define PetscTanhComplex(a)          ctanhq(a)
    345: #define PetscAsinhComplex(a)         casinhq(a)
    346: #define PetscAcoshComplex(a)         cacoshq(a)
    347: #define PetscAtanhComplex(a)         catanhq(a)

    349: #endif /* PETSC_USE_REAL_* */
    350: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */

    352: /*
    353:    PETSC_i is the imaginary number, i
    354: */
    355: PETSC_EXTERN PetscComplex PETSC_i;

    357: /*
    358:    Try to do the right thing for complex number construction: see
    359:    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
    360:    for details
    361: */
    362: PETSC_STATIC_INLINE PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
    363: {
    364: #if   defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
    365:   return PetscComplex(x,y);
    366: #elif defined(_Imaginary_I)
    367:   return x + y * _Imaginary_I;
    368: #else
    369:   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),

    371:        "For each floating type there is a corresponding real type, which is always a real floating
    372:        type. For real floating types, it is the same type. For complex types, it is the type given
    373:        by deleting the keyword _Complex from the type name."

    375:        So type punning should be portable. */
    376:     union { PetscComplex z; PetscReal f[2]; } uz;

    378:     uz.f[0] = x;
    379:     uz.f[1] = y;
    380:     return uz.z;
    381:   }
    382: #endif
    383: }

    385: #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
    386: #define MPIU_C_COMPLEX MPI_C_COMPLEX
    387: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
    388: #else
    389: # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
    390:   typedef petsccomplexlib::complex<double> petsc_mpiu_c_double_complex;
    391:   typedef petsccomplexlib::complex<float> petsc_mpiu_c_complex;
    392: # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
    393:   typedef double _Complex petsc_mpiu_c_double_complex;
    394:   typedef float _Complex petsc_mpiu_c_complex;
    395: # else
    396:   typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
    397:   typedef struct {float real,imag;} petsc_mpiu_c_complex;
    398: # endif
    399: PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
    400: PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
    401: #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
    402: #if defined(PETSC_USE_REAL___FLOAT128)
    403: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);
    404: #endif /* PETSC_USE_REAL___FLOAT128 */

    406: /*MC
    407:    MPIU_COMPLEX - MPI datatype corresponding to PetscComplex

    409:    Notes:
    410:    In MPI calls that require an MPI datatype that matches a PetscComplex or array of PetscComplex values, pass this value.

    412:    Level: beginner

    414: .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_REAL, MPIU_SCALAR, MPIU_COMPLEX, MPIU_INT, PETSC_i
    415: M*/
    416: #if defined(PETSC_USE_REAL_SINGLE)
    417: #  define MPIU_COMPLEX MPIU_C_COMPLEX
    418: #elif defined(PETSC_USE_REAL_DOUBLE)
    419: #  define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
    420: #elif defined(PETSC_USE_REAL___FLOAT128)
    421: #  define MPIU_COMPLEX MPIU___COMPLEX128
    422: #elif defined(PETSC_USE_REAL___FP16)
    423: #  define MPIU_COMPLEX MPIU_C_COMPLEX
    424: #endif /* PETSC_USE_REAL_* */

    426: #endif /* PETSC_HAVE_COMPLEX */

    428: /*
    429:     Scalar number definitions
    430:  */
    431: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)
    432: /*MC
    433:    MPIU_SCALAR - MPI datatype corresponding to PetscScalar

    435:    Notes:
    436:    In MPI calls that require an MPI datatype that matches a PetscScalar or array of PetscScalar values, pass this value.

    438:    Level: beginner

    440: .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_REAL, MPIU_COMPLEX, MPIU_INT
    441: M*/
    442: #define MPIU_SCALAR MPIU_COMPLEX

    444: /*MC
    445:    PetscRealPart - Returns the real part of a PetscScalar

    447:    Synopsis:
    448:    #include <petscmath.h>
    449:    PetscReal PetscRealPart(PetscScalar v)

    451:    Not Collective

    453:    Input Parameter:
    454: .  v - value to find the real part of

    456:    Level: beginner

    458: .seealso: PetscScalar, PetscImaginaryPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

    460: M*/
    461: #define PetscRealPart(a)      PetscRealPartComplex(a)

    463: /*MC
    464:    PetscImaginaryPart - Returns the imaginary part of a PetscScalar

    466:    Synopsis:
    467:    #include <petscmath.h>
    468:    PetscReal PetscImaginaryPart(PetscScalar v)

    470:    Not Collective

    472:    Input Parameter:
    473: .  v - value to find the imaginary part of

    475:    Level: beginner

    477:    Notes:
    478:        If PETSc was configured for real numbers then this always returns the value 0

    480: .seealso: PetscScalar, PetscRealPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

    482: M*/
    483: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)

    485: #define PetscAbsScalar(a)     PetscAbsComplex(a)
    486: #define PetscArgScalar(a)     PetscArgComplex(a)
    487: #define PetscConj(a)          PetscConjComplex(a)
    488: #define PetscSqrtScalar(a)    PetscSqrtComplex(a)
    489: #define PetscPowScalar(a,b)   PetscPowComplex(a,b)
    490: #define PetscExpScalar(a)     PetscExpComplex(a)
    491: #define PetscLogScalar(a)     PetscLogComplex(a)
    492: #define PetscSinScalar(a)     PetscSinComplex(a)
    493: #define PetscCosScalar(a)     PetscCosComplex(a)
    494: #define PetscTanScalar(a)     PetscTanComplex(a)
    495: #define PetscAsinScalar(a)    PetscAsinComplex(a)
    496: #define PetscAcosScalar(a)    PetscAcosComplex(a)
    497: #define PetscAtanScalar(a)    PetscAtanComplex(a)
    498: #define PetscSinhScalar(a)    PetscSinhComplex(a)
    499: #define PetscCoshScalar(a)    PetscCoshComplex(a)
    500: #define PetscTanhScalar(a)    PetscTanhComplex(a)
    501: #define PetscAsinhScalar(a)   PetscAsinhComplex(a)
    502: #define PetscAcoshScalar(a)   PetscAcoshComplex(a)
    503: #define PetscAtanhScalar(a)   PetscAtanhComplex(a)

    505: #else /* PETSC_USE_COMPLEX */
    506: #define MPIU_SCALAR MPIU_REAL
    507: #define PetscRealPart(a)      (a)
    508: #define PetscImaginaryPart(a) ((PetscReal)0)
    509: #define PetscAbsScalar(a)     PetscAbsReal(a)
    510: #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
    511: #define PetscConj(a)          (a)
    512: #define PetscSqrtScalar(a)    PetscSqrtReal(a)
    513: #define PetscPowScalar(a,b)   PetscPowReal(a,b)
    514: #define PetscExpScalar(a)     PetscExpReal(a)
    515: #define PetscLogScalar(a)     PetscLogReal(a)
    516: #define PetscSinScalar(a)     PetscSinReal(a)
    517: #define PetscCosScalar(a)     PetscCosReal(a)
    518: #define PetscTanScalar(a)     PetscTanReal(a)
    519: #define PetscAsinScalar(a)    PetscAsinReal(a)
    520: #define PetscAcosScalar(a)    PetscAcosReal(a)
    521: #define PetscAtanScalar(a)    PetscAtanReal(a)
    522: #define PetscSinhScalar(a)    PetscSinhReal(a)
    523: #define PetscCoshScalar(a)    PetscCoshReal(a)
    524: #define PetscTanhScalar(a)    PetscTanhReal(a)
    525: #define PetscAsinhScalar(a)   PetscAsinhReal(a)
    526: #define PetscAcoshScalar(a)   PetscAcoshReal(a)
    527: #define PetscAtanhScalar(a)   PetscAtanhReal(a)

    529: #endif /* PETSC_USE_COMPLEX */

    531: /*
    532:    Certain objects may be created using either single or double precision.
    533:    This is currently not used.
    534: */
    535: typedef enum { PETSC_SCALAR_DOUBLE, PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_HALF } PetscScalarPrecision;

    537: /* --------------------------------------------------------------------------*/

    539: /*MC
    540:    PetscAbs - Returns the absolute value of a number

    542:    Synopsis:
    543:    #include <petscmath.h>
    544:    type PetscAbs(type v)

    546:    Not Collective

    548:    Input Parameter:
    549: .  v - the number

    551:    Notes:
    552:     type can be integer or real floating point value

    554:    Level: beginner

    556: .seealso: PetscAbsInt(), PetscAbsReal(), PetscAbsScalar()

    558: M*/
    559: #define PetscAbs(a)  (((a) >= 0) ? (a) : (-(a)))

    561: /*MC
    562:    PetscSign - Returns the sign of a number as an integer

    564:    Synopsis:
    565:    #include <petscmath.h>
    566:    int PetscSign(type v)

    568:    Not Collective

    570:    Input Parameter:
    571: .  v - the number

    573:    Notes:
    574:     type can be integer or real floating point value

    576:    Level: beginner

    578: M*/
    579: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

    581: /*MC
    582:    PetscMin - Returns minimum of two numbers

    584:    Synopsis:
    585:    #include <petscmath.h>
    586:    type PetscMin(type v1,type v2)

    588:    Not Collective

    590:    Input Parameter:
    591: +  v1 - first value to find minimum of
    592: -  v2 - second value to find minimum of

    594:    Notes:
    595:     type can be integer or floating point value

    597:    Level: beginner

    599: .seealso: PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

    601: M*/
    602: #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))

    604: /*MC
    605:    PetscMax - Returns maxium of two numbers

    607:    Synopsis:
    608:    #include <petscmath.h>
    609:    type max PetscMax(type v1,type v2)

    611:    Not Collective

    613:    Input Parameter:
    614: +  v1 - first value to find maximum of
    615: -  v2 - second value to find maximum of

    617:    Notes:
    618:     type can be integer or floating point value

    620:    Level: beginner

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

    624: M*/
    625: #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))

    627: /*MC
    628:    PetscClipInterval - Returns a number clipped to be within an interval

    630:    Synopsis:
    631:    #include <petscmath.h>
    632:    type clip PetscClipInterval(type x,type a,type b)

    634:    Not Collective

    636:    Input Parameter:
    637: +  x - value to use if within interval (a,b)
    638: .  a - lower end of interval
    639: -  b - upper end of interval

    641:    Notes:
    642:     type can be integer or floating point value

    644:    Level: beginner

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

    648: M*/
    649: #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))

    651: /*MC
    652:    PetscAbsInt - Returns the absolute value of an integer

    654:    Synopsis:
    655:    #include <petscmath.h>
    656:    int abs PetscAbsInt(int v1)

    658:    Not Collective

    660:    Input Parameter:
    661: .   v1 - the integer

    663:    Level: beginner

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

    667: M*/
    668: #define PetscAbsInt(a)  (((a)<0)   ? (-(a)) : (a))

    670: /*MC
    671:    PetscAbsReal - Returns the absolute value of an real number

    673:    Synopsis:
    674:    #include <petscmath.h>
    675:    Real abs PetscAbsReal(PetscReal v1)

    677:    Not Collective

    679:    Input Parameter:
    680: .   v1 - the double

    683:    Level: beginner

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

    687: M*/
    688: #if defined(PETSC_USE_REAL_SINGLE)
    689: #define PetscAbsReal(a) fabsf(a)
    690: #elif defined(PETSC_USE_REAL_DOUBLE)
    691: #define PetscAbsReal(a) fabs(a)
    692: #elif defined(PETSC_USE_REAL___FLOAT128)
    693: #define PetscAbsReal(a) fabsq(a)
    694: #elif defined(PETSC_USE_REAL___FP16)
    695: #define PetscAbsReal(a) fabsf(a)
    696: #endif

    698: /*MC
    699:    PetscSqr - Returns the square of a number

    701:    Synopsis:
    702:    #include <petscmath.h>
    703:    type sqr PetscSqr(type v1)

    705:    Not Collective

    707:    Input Parameter:
    708: .   v1 - the value

    710:    Notes:
    711:     type can be integer or floating point value

    713:    Level: beginner

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

    717: M*/
    718: #define PetscSqr(a)     ((a)*(a))

    720: /* ----------------------------------------------------------------------------*/

    722: #if defined(PETSC_USE_REAL_SINGLE)
    723: #define PetscRealConstant(constant) constant##F
    724: #elif defined(PETSC_USE_REAL_DOUBLE)
    725: #define PetscRealConstant(constant) constant
    726: #elif defined(PETSC_USE_REAL___FLOAT128)
    727: #define PetscRealConstant(constant) constant##Q
    728: #elif defined(PETSC_USE_REAL___FP16)
    729: #define PetscRealConstant(constant) constant##F
    730: #endif

    732: /*
    733:      Basic constants
    734: */
    735: #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
    736: #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
    737: #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)

    739: #if !defined(PETSC_USE_64BIT_INDICES)
    740: #define PETSC_MAX_INT            2147483647
    741: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
    742: #else
    743: #define PETSC_MAX_INT            9223372036854775807L
    744: #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
    745: #endif

    747: #if defined(PETSC_USE_REAL_SINGLE)
    748: #  define PETSC_MAX_REAL                3.40282346638528860e+38F
    749: #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
    750: #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
    751: #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
    752: #  define PETSC_SMALL                   1.e-5F
    753: #elif defined(PETSC_USE_REAL_DOUBLE)
    754: #  define PETSC_MAX_REAL                1.7976931348623157e+308
    755: #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
    756: #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
    757: #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
    758: #  define PETSC_SMALL                   1.e-10
    759: #elif defined(PETSC_USE_REAL___FLOAT128)
    760: #  define PETSC_MAX_REAL                FLT128_MAX
    761: #  define PETSC_MIN_REAL                (-FLT128_MAX)
    762: #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
    763: #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078144567552953958511352539e-17Q
    764: #  define PETSC_SMALL                   1.e-20Q
    765: #elif defined(PETSC_USE_REAL___FP16)
    766: #  define PETSC_MAX_REAL                65504.0F
    767: #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
    768: #  define PETSC_MACHINE_EPSILON         .0009765625F
    769: #  define PETSC_SQRT_MACHINE_EPSILON    .03125F
    770: #  define PETSC_SMALL                   5.e-3F
    771: #endif

    773: #define PETSC_INFINITY               (PETSC_MAX_REAL/4)
    774: #define PETSC_NINFINITY              (-PETSC_INFINITY)

    776: PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal);
    777: PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal);
    778: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
    779: PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanReal(PetscReal v) {return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;}
    780: PETSC_STATIC_INLINE PetscBool PetscIsInfScalar(PetscScalar v) {return PetscIsInfReal(PetscAbsScalar(v));}
    781: PETSC_STATIC_INLINE PetscBool PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));}
    782: PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
    783: PETSC_STATIC_INLINE PetscBool PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}

    785: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal,PetscReal,PetscReal,PetscReal);
    786: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal,PetscReal);
    787: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar,PetscScalar);

    789: /*
    790:     These macros are currently hardwired to match the regular data types, so there is no support for a different
    791:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
    792:  */
    793: #define MPIU_MATSCALAR MPIU_SCALAR
    794: typedef PetscScalar MatScalar;
    795: typedef PetscReal MatReal;

    797: struct petsc_mpiu_2scalar {PetscScalar a,b;};
    798: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);

    800: #if defined(PETSC_USE_64BIT_INDICES)
    801: struct petsc_mpiu_2int {PetscInt a,b;};
    802: PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
    803: #else
    804: #define MPIU_2INT MPI_2INT
    805: #endif

    807: PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
    808: {
    809:   PetscInt result = 1;
    810:   while (power) {
    811:     if (power & 1) result *= base;
    812:     power >>= 1;
    813:     base *= base;
    814:   }
    815:   return result;
    816: }

    818: PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
    819: {
    820:   PetscReal result = 1;
    821:   if (power < 0) {
    822:     power = -power;
    823:     base  = ((PetscReal)1)/base;
    824:   }
    825:   while (power) {
    826:     if (power & 1) result *= base;
    827:     power >>= 1;
    828:     base *= base;
    829:   }
    830:   return result;
    831: }

    833: PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
    834: {
    835:   PetscScalar result = (PetscReal)1;
    836:   if (power < 0) {
    837:     power = -power;
    838:     base  = ((PetscReal)1)/base;
    839:   }
    840:   while (power) {
    841:     if (power & 1) result *= base;
    842:     power >>= 1;
    843:     base *= base;
    844:   }
    845:   return result;
    846: }

    848: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
    849: {
    850:   PetscScalar cpower = power;
    851:   return PetscPowScalar(base,cpower);
    852: }

    854: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt,const PetscReal[],const PetscReal[],PetscReal*,PetscReal*);
    855: #endif