Date: 2026-07-30T21:13:58+00:00

Actual source code: petscmath.h

      1: /*
      2:     PETSc mathematics include file. Defines certain basic mathematical
      3:     constants and functions for working with single, double, and quad precision
      4:     floating point numbers as well as complex single and double.

      6:     This file is included by petscsys.h and should not be used directly.
      7: */
      8: #pragma once

     10: #include <math.h>
     11: #include <petscmacros.h>
     12: #include <petscsystypes.h>

     14: /* SUBMANSEC = Sys */

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

     22: /*
     23:     Real number definitions
     24:  */
     25: #if defined(PETSC_USE_REAL_SINGLE)
     26:   /*MC
     27:     PetscSqrtReal - Returns the square root of a `PetscReal` value

     29:     Synopsis:
     30: #include <petscmath.h>
     31:     PetscReal PetscSqrtReal(PetscReal a)

     33:     Not Collective; No Fortran Support

     35:     Input Parameter:
     36:   . a - the value

     38:     Level: beginner

     40: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtComplex()`, `PetscSqrtScalar()`
     41:   M*/
     42:   #define PetscSqrtReal(a) sqrtf(a)
     43:   /*MC
     44:     PetscCbrtReal - Returns the cube root of a `PetscReal` value

     46:     Synopsis:
     47: #include <petscmath.h>
     48:     PetscReal PetscCbrtReal(PetscReal a)

     50:     Not Collective; No Fortran Support

     52:     Input Parameter:
     53:   . a - the value

     55:     Level: beginner

     57: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
     58:   M*/
     59:   #define PetscCbrtReal(a) cbrtf(a)
     60:   /*MC
     61:     PetscHypotReal - Returns the Euclidean distance `sqrt(a*a + b*b)` of two `PetscReal` values, without intermediate overflow

     63:     Synopsis:
     64: #include <petscmath.h>
     65:     PetscReal PetscHypotReal(PetscReal a, PetscReal b)

     67:     Not Collective; No Fortran Support

     69:     Input Parameters:
     70:   + a - the value
     71:   - b - the value

     73:     Level: beginner

     75: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
     76:   M*/
     77:   #define PetscHypotReal(a, b) hypotf(a, b)
     78:   /*MC
     79:     PetscAtan2Real - Returns the arc tangent of `a/b`, in the range $[-\pi, \pi]$, using the signs of `a` and `b` to select the quadrant

     81:     Synopsis:
     82: #include <petscmath.h>
     83:     PetscReal PetscAtan2Real(PetscReal a, PetscReal b)

     85:     Not Collective; No Fortran Support

     87:     Input Parameters:
     88:   + a - the value
     89:   - b - the value

     91:     Level: beginner

     93: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
     94:   M*/
     95:   #define PetscAtan2Real(a, b) atan2f(a, b)
     96:   /*MC
     97:     PetscPowReal - Returns the value of `a` raised to the power `b`, both `PetscReal`

     99:     Synopsis:
    100: #include <petscmath.h>
    101:     PetscReal PetscPowReal(PetscReal a, PetscReal b)

    103:     Not Collective; No Fortran Support

    105:     Input Parameters:
    106:   + a - the value
    107:   - b - the value

    109:     Level: beginner

    111: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowComplex()`, `PetscPowScalar()`
    112:   M*/
    113:   #define PetscPowReal(a, b) powf(a, b)
    114:   /*MC
    115:     PetscExpReal - Returns the natural exponential $e^a$ of a `PetscReal` value

    117:     Synopsis:
    118: #include <petscmath.h>
    119:     PetscReal PetscExpReal(PetscReal a)

    121:     Not Collective; No Fortran Support

    123:     Input Parameter:
    124:   . a - the value

    126:     Level: beginner

    128: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpComplex()`, `PetscExpScalar()`
    129:   M*/
    130:   #define PetscExpReal(a) expf(a)
    131:   /*MC
    132:     PetscLogReal - Returns the natural logarithm of a `PetscReal` value

    134:     Synopsis:
    135: #include <petscmath.h>
    136:     PetscReal PetscLogReal(PetscReal a)

    138:     Not Collective; No Fortran Support

    140:     Input Parameter:
    141:   . a - the value

    143:     Level: beginner

    145: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogComplex()`, `PetscLogScalar()`
    146:   M*/
    147:   #define PetscLogReal(a) logf(a)
    148:   /*MC
    149:     PetscLog10Real - Returns the base-10 logarithm of a `PetscReal` value

    151:     Synopsis:
    152: #include <petscmath.h>
    153:     PetscReal PetscLog10Real(PetscReal a)

    155:     Not Collective; No Fortran Support

    157:     Input Parameter:
    158:   . a - the value

    160:     Level: beginner

    162: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    163:   M*/
    164:   #define PetscLog10Real(a) log10f(a)
    165:   /*MC
    166:     PetscLog2Real - Returns the base-2 logarithm of a `PetscReal` value

    168:     Synopsis:
    169: #include <petscmath.h>
    170:     PetscReal PetscLog2Real(PetscReal a)

    172:     Not Collective; No Fortran Support

    174:     Input Parameter:
    175:   . a - the value

    177:     Level: beginner

    179: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    180:   M*/
    181:   #define PetscLog2Real(a) log2f(a)
    182:   /*MC
    183:     PetscSinReal - Returns the sine of a `PetscReal` value, with argument in radians

    185:     Synopsis:
    186: #include <petscmath.h>
    187:     PetscReal PetscSinReal(PetscReal a)

    189:     Not Collective; No Fortran Support

    191:     Input Parameter:
    192:   . a - the value

    194:     Level: beginner

    196: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinComplex()`, `PetscSinScalar()`
    197:   M*/
    198:   #define PetscSinReal(a) sinf(a)
    199:   /*MC
    200:     PetscCosReal - Returns the cosine of a `PetscReal` value, with argument in radians

    202:     Synopsis:
    203: #include <petscmath.h>
    204:     PetscReal PetscCosReal(PetscReal a)

    206:     Not Collective; No Fortran Support

    208:     Input Parameter:
    209:   . a - the value

    211:     Level: beginner

    213: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosComplex()`, `PetscCosScalar()`
    214:   M*/
    215:   #define PetscCosReal(a) cosf(a)
    216:   /*MC
    217:     PetscTanReal - Returns the tangent of a `PetscReal` value, with argument in radians

    219:     Synopsis:
    220: #include <petscmath.h>
    221:     PetscReal PetscTanReal(PetscReal a)

    223:     Not Collective; No Fortran Support

    225:     Input Parameter:
    226:   . a - the value

    228:     Level: beginner

    230: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanComplex()`, `PetscTanScalar()`
    231:   M*/
    232:   #define PetscTanReal(a) tanf(a)
    233:   /*MC
    234:     PetscAsinReal - Returns the arc sine of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

    236:     Synopsis:
    237: #include <petscmath.h>
    238:     PetscReal PetscAsinReal(PetscReal a)

    240:     Not Collective; No Fortran Support

    242:     Input Parameter:
    243:   . a - the value

    245:     Level: beginner

    247: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinComplex()`, `PetscAsinScalar()`
    248:   M*/
    249:   #define PetscAsinReal(a) asinf(a)
    250:   /*MC
    251:     PetscAcosReal - Returns the arc cosine of a `PetscReal` value, returned in radians in the range $[0, \pi]$

    253:     Synopsis:
    254: #include <petscmath.h>
    255:     PetscReal PetscAcosReal(PetscReal a)

    257:     Not Collective; No Fortran Support

    259:     Input Parameter:
    260:   . a - the value

    262:     Level: beginner

    264: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosComplex()`, `PetscAcosScalar()`
    265:   M*/
    266:   #define PetscAcosReal(a) acosf(a)
    267:   /*MC
    268:     PetscAtanReal - Returns the arc tangent of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

    270:     Synopsis:
    271: #include <petscmath.h>
    272:     PetscReal PetscAtanReal(PetscReal a)

    274:     Not Collective; No Fortran Support

    276:     Input Parameter:
    277:   . a - the value

    279:     Level: beginner

    281: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanComplex()`, `PetscAtanScalar()`
    282:   M*/
    283:   #define PetscAtanReal(a) atanf(a)
    284:   /*MC
    285:     PetscSinhReal - Returns the hyperbolic sine of a `PetscReal` value

    287:     Synopsis:
    288: #include <petscmath.h>
    289:     PetscReal PetscSinhReal(PetscReal a)

    291:     Not Collective; No Fortran Support

    293:     Input Parameter:
    294:   . a - the value

    296:     Level: beginner

    298: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhComplex()`, `PetscSinhScalar()`
    299:   M*/
    300:   #define PetscSinhReal(a) sinhf(a)
    301:   /*MC
    302:     PetscCoshReal - Returns the hyperbolic cosine of a `PetscReal` value

    304:     Synopsis:
    305: #include <petscmath.h>
    306:     PetscReal PetscCoshReal(PetscReal a)

    308:     Not Collective; No Fortran Support

    310:     Input Parameter:
    311:   . a - the value

    313:     Level: beginner

    315: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshComplex()`, `PetscCoshScalar()`
    316:   M*/
    317:   #define PetscCoshReal(a) coshf(a)
    318:   /*MC
    319:     PetscTanhReal - Returns the hyperbolic tangent of a `PetscReal` value

    321:     Synopsis:
    322: #include <petscmath.h>
    323:     PetscReal PetscTanhReal(PetscReal a)

    325:     Not Collective; No Fortran Support

    327:     Input Parameter:
    328:   . a - the value

    330:     Level: beginner

    332: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhComplex()`, `PetscTanhScalar()`
    333:   M*/
    334:   #define PetscTanhReal(a) tanhf(a)
    335:   /*MC
    336:     PetscAsinhReal - Returns the inverse hyperbolic sine of a `PetscReal` value

    338:     Synopsis:
    339: #include <petscmath.h>
    340:     PetscReal PetscAsinhReal(PetscReal a)

    342:     Not Collective; No Fortran Support

    344:     Input Parameter:
    345:   . a - the value

    347:     Level: beginner

    349: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhComplex()`, `PetscAsinhScalar()`
    350:   M*/
    351:   #define PetscAsinhReal(a) asinhf(a)
    352:   /*MC
    353:     PetscAcoshReal - Returns the inverse hyperbolic cosine of a `PetscReal` value

    355:     Synopsis:
    356: #include <petscmath.h>
    357:     PetscReal PetscAcoshReal(PetscReal a)

    359:     Not Collective; No Fortran Support

    361:     Input Parameter:
    362:   . a - the value

    364:     Level: beginner

    366: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshComplex()`, `PetscAcoshScalar()`
    367:   M*/
    368:   #define PetscAcoshReal(a) acoshf(a)
    369:   /*MC
    370:     PetscAtanhReal - Returns the inverse hyperbolic tangent of a `PetscReal` value

    372:     Synopsis:
    373: #include <petscmath.h>
    374:     PetscReal PetscAtanhReal(PetscReal a)

    376:     Not Collective; No Fortran Support

    378:     Input Parameter:
    379:   . a - the value

    381:     Level: beginner

    383: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhComplex()`, `PetscAtanhScalar()`
    384:   M*/
    385:   #define PetscAtanhReal(a) atanhf(a)
    386:   /*MC
    387:     PetscErfReal - Returns the error function of a `PetscReal` value

    389:     Synopsis:
    390: #include <petscmath.h>
    391:     PetscReal PetscErfReal(PetscReal a)

    393:     Not Collective; No Fortran Support

    395:     Input Parameter:
    396:   . a - the value

    398:     Level: beginner

    400: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    401:   M*/
    402:   #define PetscErfReal(a) erff(a)
    403:   /*MC
    404:     PetscCeilReal - Returns the smallest integer value, returned as a `PetscReal`, that is not less than `a`

    406:     Synopsis:
    407: #include <petscmath.h>
    408:     PetscReal PetscCeilReal(PetscReal a)

    410:     Not Collective; No Fortran Support

    412:     Input Parameter:
    413:   . a - the value

    415:     Level: beginner

    417: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    418:   M*/
    419:   #define PetscCeilReal(a) ceilf(a)
    420:   /*MC
    421:     PetscFloorReal - Returns the largest integer value, returned as a `PetscReal`, that is not greater than `a`

    423:     Synopsis:
    424: #include <petscmath.h>
    425:     PetscReal PetscFloorReal(PetscReal a)

    427:     Not Collective; No Fortran Support

    429:     Input Parameter:
    430:   . a - the value

    432:     Level: beginner

    434: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    435:   M*/
    436:   #define PetscFloorReal(a) floorf(a)
    437:   /*MC
    438:     PetscRintReal - Returns the value of `a` rounded to the nearest integer, returned as a `PetscReal` in the configured precision

    440:     Synopsis:
    441: #include <petscmath.h>
    442:     PetscReal PetscRintReal(PetscReal a)

    444:     Not Collective; No Fortran Support

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

    449:     Level: beginner

    451: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    452:   M*/
    453:   #define PetscRintReal(a) rintf(a)
    454:   /*MC
    455:     PetscFmodReal - Returns the floating-point remainder of `a/b`, with the same sign as `a`, returned as a `PetscReal`

    457:     Synopsis:
    458: #include <petscmath.h>
    459:     PetscReal PetscFmodReal(PetscReal a, PetscReal b)

    461:     Not Collective; No Fortran Support

    463:     Input Parameters:
    464:   + a - the value
    465:   - b - the value

    467:     Level: beginner

    469: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    470:   M*/
    471:   #define PetscFmodReal(a, b) fmodf(a, b)
    472:   /*MC
    473:     PetscCopysignReal - Returns the value with the magnitude of `a` and the sign of `b`, as a `PetscReal`

    475:     Synopsis:
    476: #include <petscmath.h>
    477:     PetscReal PetscCopysignReal(PetscReal a, PetscReal b)

    479:     Not Collective; No Fortran Support

    481:     Input Parameters:
    482:   + a - the value
    483:   - b - the value

    485:     Level: beginner

    487: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    488:   M*/
    489:   #define PetscCopysignReal(a, b) copysignf(a, b)
    490:   /*MC
    491:     PetscTGamma - Returns the value of the gamma function $\Gamma(a)$ in the configured `PetscReal` precision

    493:     Synopsis:
    494: #include <petscmath.h>
    495:     PetscReal PetscTGamma(PetscReal a)

    497:     Not Collective; No Fortran Support

    499:     Input Parameter:
    500:   . a - the value

    502:     Level: beginner

    504: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    505:   M*/
    506:   #define PetscTGamma(a) tgammaf(a)
    507:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
    508:     /*MC
    509:       PetscLGamma - Returns the natural logarithm of the absolute value of the gamma function in the configured `PetscReal` precision

    511:       Synopsis:
    512: #include <petscmath.h>
    513:       PetscReal PetscLGamma(PetscReal a)

    515:       Not Collective; No Fortran Support

    517:       Input Parameter:
    518:     . a - the value

    520:       Level: beginner

    522: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    523:     M*/
    524:     #define PetscLGamma(a) gammaf(a)
    525:   #else
    526:     #define PetscLGamma(a) lgammaf(a)
    527:   #endif

    529: #elif defined(PETSC_USE_REAL_DOUBLE)
    530:   #define PetscSqrtReal(a)        sqrt(a)
    531:   #define PetscCbrtReal(a)        cbrt(a)
    532:   #define PetscHypotReal(a, b)    hypot(a, b)
    533:   #define PetscAtan2Real(a, b)    atan2(a, b)
    534:   #define PetscPowReal(a, b)      pow(a, b)
    535:   #define PetscExpReal(a)         exp(a)
    536:   #define PetscLogReal(a)         log(a)
    537:   #define PetscLog10Real(a)       log10(a)
    538:   #define PetscLog2Real(a)        log2(a)
    539:   #define PetscSinReal(a)         sin(a)
    540:   #define PetscCosReal(a)         cos(a)
    541:   #define PetscTanReal(a)         tan(a)
    542:   #define PetscAsinReal(a)        asin(a)
    543:   #define PetscAcosReal(a)        acos(a)
    544:   #define PetscAtanReal(a)        atan(a)
    545:   #define PetscSinhReal(a)        sinh(a)
    546:   #define PetscCoshReal(a)        cosh(a)
    547:   #define PetscTanhReal(a)        tanh(a)
    548:   #define PetscAsinhReal(a)       asinh(a)
    549:   #define PetscAcoshReal(a)       acosh(a)
    550:   #define PetscAtanhReal(a)       atanh(a)
    551:   #define PetscErfReal(a)         erf(a)
    552:   #define PetscCeilReal(a)        ceil(a)
    553:   #define PetscFloorReal(a)       floor(a)
    554:   #define PetscRintReal(a)        rint(a)
    555:   #define PetscFmodReal(a, b)     fmod(a, b)
    556:   #define PetscCopysignReal(a, b) copysign(a, b)
    557:   #define PetscTGamma(a)          tgamma(a)
    558:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
    559:     #define PetscLGamma(a) gamma(a)
    560:   #else
    561:     #define PetscLGamma(a) lgamma(a)
    562:   #endif

    564: #elif defined(PETSC_USE_REAL___FLOAT128)
    565:   #define PetscSqrtReal(a)        sqrtq(a)
    566:   #define PetscCbrtReal(a)        cbrtq(a)
    567:   #define PetscHypotReal(a, b)    hypotq(a, b)
    568:   #define PetscAtan2Real(a, b)    atan2q(a, b)
    569:   #define PetscPowReal(a, b)      powq(a, b)
    570:   #define PetscExpReal(a)         expq(a)
    571:   #define PetscLogReal(a)         logq(a)
    572:   #define PetscLog10Real(a)       log10q(a)
    573:   #define PetscLog2Real(a)        log2q(a)
    574:   #define PetscSinReal(a)         sinq(a)
    575:   #define PetscCosReal(a)         cosq(a)
    576:   #define PetscTanReal(a)         tanq(a)
    577:   #define PetscAsinReal(a)        asinq(a)
    578:   #define PetscAcosReal(a)        acosq(a)
    579:   #define PetscAtanReal(a)        atanq(a)
    580:   #define PetscSinhReal(a)        sinhq(a)
    581:   #define PetscCoshReal(a)        coshq(a)
    582:   #define PetscTanhReal(a)        tanhq(a)
    583:   #define PetscAsinhReal(a)       asinhq(a)
    584:   #define PetscAcoshReal(a)       acoshq(a)
    585:   #define PetscAtanhReal(a)       atanhq(a)
    586:   #define PetscErfReal(a)         erfq(a)
    587:   #define PetscCeilReal(a)        ceilq(a)
    588:   #define PetscFloorReal(a)       floorq(a)
    589:   #define PetscRintReal(a)        rintq(a)
    590:   #define PetscFmodReal(a, b)     fmodq(a, b)
    591:   #define PetscCopysignReal(a, b) copysignq(a, b)
    592:   #define PetscTGamma(a)          tgammaq(a)
    593:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
    594:     #define PetscLGamma(a) gammaq(a)
    595:   #else
    596:     #define PetscLGamma(a) lgammaq(a)
    597:   #endif

    599: #elif defined(PETSC_USE_REAL___FP16)
    600:   #define PetscSqrtReal(a)        sqrtf(a)
    601:   #define PetscCbrtReal(a)        cbrtf(a)
    602:   #define PetscHypotReal(a, b)    hypotf(a, b)
    603:   #define PetscAtan2Real(a, b)    atan2f(a, b)
    604:   #define PetscPowReal(a, b)      powf(a, b)
    605:   #define PetscExpReal(a)         expf(a)
    606:   #define PetscLogReal(a)         logf(a)
    607:   #define PetscLog10Real(a)       log10f(a)
    608:   #define PetscLog2Real(a)        log2f(a)
    609:   #define PetscSinReal(a)         sinf(a)
    610:   #define PetscCosReal(a)         cosf(a)
    611:   #define PetscTanReal(a)         tanf(a)
    612:   #define PetscAsinReal(a)        asinf(a)
    613:   #define PetscAcosReal(a)        acosf(a)
    614:   #define PetscAtanReal(a)        atanf(a)
    615:   #define PetscSinhReal(a)        sinhf(a)
    616:   #define PetscCoshReal(a)        coshf(a)
    617:   #define PetscTanhReal(a)        tanhf(a)
    618:   #define PetscAsinhReal(a)       asinhf(a)
    619:   #define PetscAcoshReal(a)       acoshf(a)
    620:   #define PetscAtanhReal(a)       atanhf(a)
    621:   #define PetscErfReal(a)         erff(a)
    622:   #define PetscCeilReal(a)        ceilf(a)
    623:   #define PetscFloorReal(a)       floorf(a)
    624:   #define PetscRintReal(a)        rintf(a)
    625:   #define PetscFmodReal(a, b)     fmodf(a, b)
    626:   #define PetscCopysignReal(a, b) copysignf(a, b)
    627:   #define PetscTGamma(a)          tgammaf(a)
    628:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
    629:     #define PetscLGamma(a) gammaf(a)
    630:   #else
    631:     #define PetscLGamma(a) lgammaf(a)
    632:   #endif

    634: #endif /* PETSC_USE_REAL_* */

    636: static inline PetscReal PetscSignReal(PetscReal a)
    637: {
    638:   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
    639: }

    641: #if !defined(PETSC_HAVE_LOG2)
    642:   #undef PetscLog2Real
    643: static inline PetscReal PetscLog2Real(PetscReal a)
    644: {
    645:   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
    646: }
    647: #endif

    649: #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
    650: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
    651: #endif
    652: #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
    653: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
    654: #endif

    656: /*MC
    657:    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in

    659:    Level: beginner

    661:    Note:
    662:    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.

    664: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
    665: M*/
    666: #if defined(PETSC_USE_REAL_SINGLE)
    667:   #define MPIU_REAL MPI_FLOAT
    668: #elif defined(PETSC_USE_REAL_DOUBLE)
    669:   #define MPIU_REAL MPI_DOUBLE
    670: #elif defined(PETSC_USE_REAL___FLOAT128)
    671:   #define MPIU_REAL MPIU___FLOAT128
    672: #elif defined(PETSC_USE_REAL___FP16)
    673:   #define MPIU_REAL MPIU___FP16
    674: #endif /* PETSC_USE_REAL_* */

    676: /*
    677:     Complex number definitions
    678:  */
    679: #if defined(PETSC_HAVE_COMPLEX)
    680:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
    681:   /* C++ support of complex number */

    683:     /*MC
    684:       PetscRealPartComplex - Returns the real part of a `PetscComplex` value, as a `PetscReal`

    686:       Synopsis:
    687: #include <petscmath.h>
    688:       PetscReal PetscRealPartComplex(PetscComplex a)

    690:       Not Collective; No Fortran Support

    692:       Input Parameter:
    693:     . a - the value

    695:       Level: beginner

    697: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    698:     M*/
    699:     #define PetscRealPartComplex(a) (static_cast<PetscComplex>(a)).real()
    700:     /*MC
    701:       PetscImaginaryPartComplex - Returns the imaginary part of a `PetscComplex` value, as a `PetscReal`

    703:       Synopsis:
    704: #include <petscmath.h>
    705:       PetscReal PetscImaginaryPartComplex(PetscComplex a)

    707:       Not Collective; No Fortran Support

    709:       Input Parameter:
    710:     . a - the value

    712:       Level: beginner

    714: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    715:     M*/
    716:     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
    717:     /*MC
    718:       PetscAbsComplex - Returns the absolute value (magnitude) of a `PetscComplex` value, as a `PetscReal`

    720:       Synopsis:
    721: #include <petscmath.h>
    722:       PetscReal PetscAbsComplex(PetscComplex a)

    724:       Not Collective; No Fortran Support

    726:       Input Parameter:
    727:     . a - the value

    729:       Level: beginner

    731: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    732:     M*/
    733:     #define PetscAbsComplex(a) petsccomplexlib::abs(static_cast<PetscComplex>(a))
    734:     /*MC
    735:       PetscArgComplex - Returns the argument (phase angle) of a `PetscComplex` value, as a `PetscReal`

    737:       Synopsis:
    738: #include <petscmath.h>
    739:       PetscReal PetscArgComplex(PetscComplex a)

    741:       Not Collective; No Fortran Support

    743:       Input Parameter:
    744:     . a - the value

    746:       Level: beginner

    748: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    749:     M*/
    750:     #define PetscArgComplex(a) petsccomplexlib::arg(static_cast<PetscComplex>(a))
    751:     /*MC
    752:       PetscConjComplex - Returns the complex conjugate of a `PetscComplex` value

    754:       Synopsis:
    755: #include <petscmath.h>
    756:       PetscComplex PetscConjComplex(PetscComplex a)

    758:       Not Collective; No Fortran Support

    760:       Input Parameter:
    761:     . a - the value

    763:       Level: beginner

    765: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConj()`
    766:     M*/
    767:     #define PetscConjComplex(a) petsccomplexlib::conj(static_cast<PetscComplex>(a))
    768:     /*MC
    769:       PetscSqrtComplex - Returns the principal value of the square root of a `PetscComplex` value

    771:       Synopsis:
    772: #include <petscmath.h>
    773:       PetscComplex PetscSqrtComplex(PetscComplex a)

    775:       Not Collective; No Fortran Support

    777:       Input Parameter:
    778:     . a - the value

    780:       Level: beginner

    782: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtScalar()`
    783:     M*/
    784:     #define PetscSqrtComplex(a) petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
    785:     /*MC
    786:       PetscPowComplex - Returns the complex value `a` raised to the complex power `b`

    788:       Synopsis:
    789: #include <petscmath.h>
    790:       PetscComplex PetscPowComplex(PetscComplex a, PetscComplex b)

    792:       Not Collective; No Fortran Support

    794:       Input Parameters:
    795:     + a - the value
    796:     - b - the value

    798:       Level: beginner

    800: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowScalar()`
    801:     M*/
    802:     #define PetscPowComplex(a, b) petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
    803:     /*MC
    804:       PetscExpComplex - Returns the complex exponential $e^a$ of a `PetscComplex` value

    806:       Synopsis:
    807: #include <petscmath.h>
    808:       PetscComplex PetscExpComplex(PetscComplex a)

    810:       Not Collective; No Fortran Support

    812:       Input Parameter:
    813:     . a - the value

    815:       Level: beginner

    817: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpScalar()`
    818:     M*/
    819:     #define PetscExpComplex(a) petsccomplexlib::exp(static_cast<PetscComplex>(a))
    820:     /*MC
    821:       PetscLogComplex - Returns the principal value of the complex natural logarithm of a `PetscComplex` value

    823:       Synopsis:
    824: #include <petscmath.h>
    825:       PetscComplex PetscLogComplex(PetscComplex a)

    827:       Not Collective; No Fortran Support

    829:       Input Parameter:
    830:     . a - the value

    832:       Level: beginner

    834: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogScalar()`
    835:     M*/
    836:     #define PetscLogComplex(a) petsccomplexlib::log(static_cast<PetscComplex>(a))
    837:     /*MC
    838:       PetscSinComplex - Returns the complex sine of a `PetscComplex` value

    840:       Synopsis:
    841: #include <petscmath.h>
    842:       PetscComplex PetscSinComplex(PetscComplex a)

    844:       Not Collective; No Fortran Support

    846:       Input Parameter:
    847:     . a - the value

    849:       Level: beginner

    851: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinScalar()`
    852:     M*/
    853:     #define PetscSinComplex(a) petsccomplexlib::sin(static_cast<PetscComplex>(a))
    854:     /*MC
    855:       PetscCosComplex - Returns the complex cosine of a `PetscComplex` value

    857:       Synopsis:
    858: #include <petscmath.h>
    859:       PetscComplex PetscCosComplex(PetscComplex a)

    861:       Not Collective; No Fortran Support

    863:       Input Parameter:
    864:     . a - the value

    866:       Level: beginner

    868: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosScalar()`
    869:     M*/
    870:     #define PetscCosComplex(a) petsccomplexlib::cos(static_cast<PetscComplex>(a))
    871:     /*MC
    872:       PetscTanComplex - Returns the complex tangent of a `PetscComplex` value

    874:       Synopsis:
    875: #include <petscmath.h>
    876:       PetscComplex PetscTanComplex(PetscComplex a)

    878:       Not Collective; No Fortran Support

    880:       Input Parameter:
    881:     . a - the value

    883:       Level: beginner

    885: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanScalar()`
    886:     M*/
    887:     #define PetscTanComplex(a) petsccomplexlib::tan(static_cast<PetscComplex>(a))
    888:     /*MC
    889:       PetscAsinComplex - Returns the complex arc sine of a `PetscComplex` value

    891:       Synopsis:
    892: #include <petscmath.h>
    893:       PetscComplex PetscAsinComplex(PetscComplex a)

    895:       Not Collective; No Fortran Support

    897:       Input Parameter:
    898:     . a - the value

    900:       Level: beginner

    902: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinScalar()`
    903:     M*/
    904:     #define PetscAsinComplex(a) petsccomplexlib::asin(static_cast<PetscComplex>(a))
    905:     /*MC
    906:       PetscAcosComplex - Returns the complex arc cosine of a `PetscComplex` value

    908:       Synopsis:
    909: #include <petscmath.h>
    910:       PetscComplex PetscAcosComplex(PetscComplex a)

    912:       Not Collective; No Fortran Support

    914:       Input Parameter:
    915:     . a - the value

    917:       Level: beginner

    919: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosScalar()`
    920:     M*/
    921:     #define PetscAcosComplex(a) petsccomplexlib::acos(static_cast<PetscComplex>(a))
    922:     /*MC
    923:       PetscAtanComplex - Returns the complex arc tangent of a `PetscComplex` value

    925:       Synopsis:
    926: #include <petscmath.h>
    927:       PetscComplex PetscAtanComplex(PetscComplex a)

    929:       Not Collective; No Fortran Support

    931:       Input Parameter:
    932:     . a - the value

    934:       Level: beginner

    936: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanScalar()`
    937:     M*/
    938:     #define PetscAtanComplex(a) petsccomplexlib::atan(static_cast<PetscComplex>(a))
    939:     /*MC
    940:       PetscSinhComplex - Returns the complex hyperbolic sine of a `PetscComplex` value

    942:       Synopsis:
    943: #include <petscmath.h>
    944:       PetscComplex PetscSinhComplex(PetscComplex a)

    946:       Not Collective; No Fortran Support

    948:       Input Parameter:
    949:     . a - the value

    951:       Level: beginner

    953: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhScalar()`
    954:     M*/
    955:     #define PetscSinhComplex(a) petsccomplexlib::sinh(static_cast<PetscComplex>(a))
    956:     /*MC
    957:       PetscCoshComplex - Returns the complex hyperbolic cosine of a `PetscComplex` value

    959:       Synopsis:
    960: #include <petscmath.h>
    961:       PetscComplex PetscCoshComplex(PetscComplex a)

    963:       Not Collective; No Fortran Support

    965:       Input Parameter:
    966:     . a - the value

    968:       Level: beginner

    970: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshScalar()`
    971:     M*/
    972:     #define PetscCoshComplex(a) petsccomplexlib::cosh(static_cast<PetscComplex>(a))
    973:     /*MC
    974:       PetscTanhComplex - Returns the complex hyperbolic tangent of a `PetscComplex` value

    976:       Synopsis:
    977: #include <petscmath.h>
    978:       PetscComplex PetscTanhComplex(PetscComplex a)

    980:       Not Collective; No Fortran Support

    982:       Input Parameter:
    983:     . a - the value

    985:       Level: beginner

    987: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhScalar()`
    988:     M*/
    989:     #define PetscTanhComplex(a) petsccomplexlib::tanh(static_cast<PetscComplex>(a))
    990:     /*MC
    991:       PetscAsinhComplex - Returns the complex inverse hyperbolic sine of a `PetscComplex` value

    993:       Synopsis:
    994: #include <petscmath.h>
    995:       PetscComplex PetscAsinhComplex(PetscComplex a)

    997:       Not Collective; No Fortran Support

    999:       Input Parameter:
    1000:     . a - the value

    1002:       Level: beginner

    1004: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhScalar()`
    1005:     M*/
    1006:     #define PetscAsinhComplex(a) petsccomplexlib::asinh(static_cast<PetscComplex>(a))
    1007:     /*MC
    1008:       PetscAcoshComplex - Returns the complex inverse hyperbolic cosine of a `PetscComplex` value

    1010:       Synopsis:
    1011: #include <petscmath.h>
    1012:       PetscComplex PetscAcoshComplex(PetscComplex a)

    1014:       Not Collective; No Fortran Support

    1016:       Input Parameter:
    1017:     . a - the value

    1019:       Level: beginner

    1021: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshScalar()`
    1022:     M*/
    1023:     #define PetscAcoshComplex(a) petsccomplexlib::acosh(static_cast<PetscComplex>(a))
    1024:     /*MC
    1025:       PetscAtanhComplex - Returns the complex inverse hyperbolic tangent of a `PetscComplex` value

    1027:       Synopsis:
    1028: #include <petscmath.h>
    1029:       PetscComplex PetscAtanhComplex(PetscComplex a)

    1031:       Not Collective; No Fortran Support

    1033:       Input Parameter:
    1034:     . a - the value

    1036:       Level: beginner

    1038: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhScalar()`
    1039:     M*/
    1040:     #define PetscAtanhComplex(a) petsccomplexlib::atanh(static_cast<PetscComplex>(a))

    1042:   /* TODO: Add configure tests

    1044: #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
    1045: #undef PetscTanComplex
    1046: static inline PetscComplex PetscTanComplex(PetscComplex z)
    1047: {
    1048:   return PetscSinComplex(z)/PetscCosComplex(z);
    1049: }
    1050: #endif

    1052: #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
    1053: #undef PetscTanhComplex
    1054: static inline PetscComplex PetscTanhComplex(PetscComplex z)
    1055: {
    1056:   return PetscSinhComplex(z)/PetscCoshComplex(z);
    1057: }
    1058: #endif

    1060: #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
    1061: #undef PetscAsinComplex
    1062: static inline PetscComplex PetscAsinComplex(PetscComplex z)
    1063: {
    1064:   const PetscComplex j(0,1);
    1065:   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
    1066: }
    1067: #endif

    1069: #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
    1070: #undef PetscAcosComplex
    1071: static inline PetscComplex PetscAcosComplex(PetscComplex z)
    1072: {
    1073:   const PetscComplex j(0,1);
    1074:   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
    1075: }
    1076: #endif

    1078: #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
    1079: #undef PetscAtanComplex
    1080: static inline PetscComplex PetscAtanComplex(PetscComplex z)
    1081: {
    1082:   const PetscComplex j(0,1);
    1083:   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
    1084: }
    1085: #endif

    1087: #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
    1088: #undef PetscAsinhComplex
    1089: static inline PetscComplex PetscAsinhComplex(PetscComplex z)
    1090: {
    1091:   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
    1092: }
    1093: #endif

    1095: #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
    1096: #undef PetscAcoshComplex
    1097: static inline PetscComplex PetscAcoshComplex(PetscComplex z)
    1098: {
    1099:   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
    1100: }
    1101: #endif

    1103: #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
    1104: #undef PetscAtanhComplex
    1105: static inline PetscComplex PetscAtanhComplex(PetscComplex z)
    1106: {
    1107:   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
    1108: }
    1109: #endif

    1111: */

    1113:   #else /* C99 support of complex number */

    1115:     #if defined(PETSC_USE_REAL_SINGLE)
    1116:       #define PetscRealPartComplex(a)      crealf(a)
    1117:       #define PetscImaginaryPartComplex(a) cimagf(a)
    1118:       #define PetscAbsComplex(a)           cabsf(a)
    1119:       #define PetscArgComplex(a)           cargf(a)
    1120:       #define PetscConjComplex(a)          conjf(a)
    1121:       #define PetscSqrtComplex(a)          csqrtf(a)
    1122:       #define PetscPowComplex(a, b)        cpowf(a, b)
    1123:       #define PetscExpComplex(a)           cexpf(a)
    1124:       #define PetscLogComplex(a)           clogf(a)
    1125:       #define PetscSinComplex(a)           csinf(a)
    1126:       #define PetscCosComplex(a)           ccosf(a)
    1127:       #define PetscTanComplex(a)           ctanf(a)
    1128:       #define PetscAsinComplex(a)          casinf(a)
    1129:       #define PetscAcosComplex(a)          cacosf(a)
    1130:       #define PetscAtanComplex(a)          catanf(a)
    1131:       #define PetscSinhComplex(a)          csinhf(a)
    1132:       #define PetscCoshComplex(a)          ccoshf(a)
    1133:       #define PetscTanhComplex(a)          ctanhf(a)
    1134:       #define PetscAsinhComplex(a)         casinhf(a)
    1135:       #define PetscAcoshComplex(a)         cacoshf(a)
    1136:       #define PetscAtanhComplex(a)         catanhf(a)

    1138:     #elif defined(PETSC_USE_REAL_DOUBLE)
    1139:       #define PetscRealPartComplex(a)      creal(a)
    1140:       #define PetscImaginaryPartComplex(a) cimag(a)
    1141:       #define PetscAbsComplex(a)           cabs(a)
    1142:       #define PetscArgComplex(a)           carg(a)
    1143:       #define PetscConjComplex(a)          conj(a)
    1144:       #define PetscSqrtComplex(a)          csqrt(a)
    1145:       #define PetscPowComplex(a, b)        cpow(a, b)
    1146:       #define PetscExpComplex(a)           cexp(a)
    1147:       #define PetscLogComplex(a)           clog(a)
    1148:       #define PetscSinComplex(a)           csin(a)
    1149:       #define PetscCosComplex(a)           ccos(a)
    1150:       #define PetscTanComplex(a)           ctan(a)
    1151:       #define PetscAsinComplex(a)          casin(a)
    1152:       #define PetscAcosComplex(a)          cacos(a)
    1153:       #define PetscAtanComplex(a)          catan(a)
    1154:       #define PetscSinhComplex(a)          csinh(a)
    1155:       #define PetscCoshComplex(a)          ccosh(a)
    1156:       #define PetscTanhComplex(a)          ctanh(a)
    1157:       #define PetscAsinhComplex(a)         casinh(a)
    1158:       #define PetscAcoshComplex(a)         cacosh(a)
    1159:       #define PetscAtanhComplex(a)         catanh(a)

    1161:     #elif defined(PETSC_USE_REAL___FLOAT128)
    1162:       #define PetscRealPartComplex(a)      crealq(a)
    1163:       #define PetscImaginaryPartComplex(a) cimagq(a)
    1164:       #define PetscAbsComplex(a)           cabsq(a)
    1165:       #define PetscArgComplex(a)           cargq(a)
    1166:       #define PetscConjComplex(a)          conjq(a)
    1167:       #define PetscSqrtComplex(a)          csqrtq(a)
    1168:       #define PetscPowComplex(a, b)        cpowq(a, b)
    1169:       #define PetscExpComplex(a)           cexpq(a)
    1170:       #define PetscLogComplex(a)           clogq(a)
    1171:       #define PetscSinComplex(a)           csinq(a)
    1172:       #define PetscCosComplex(a)           ccosq(a)
    1173:       #define PetscTanComplex(a)           ctanq(a)
    1174:       #define PetscAsinComplex(a)          casinq(a)
    1175:       #define PetscAcosComplex(a)          cacosq(a)
    1176:       #define PetscAtanComplex(a)          catanq(a)
    1177:       #define PetscSinhComplex(a)          csinhq(a)
    1178:       #define PetscCoshComplex(a)          ccoshq(a)
    1179:       #define PetscTanhComplex(a)          ctanhq(a)
    1180:       #define PetscAsinhComplex(a)         casinhq(a)
    1181:       #define PetscAcoshComplex(a)         cacoshq(a)
    1182:       #define PetscAtanhComplex(a)         catanhq(a)

    1184:     #endif /* PETSC_USE_REAL_* */
    1185:   #endif   /* (__cplusplus) */

    1187: /*MC
    1188:    PETSC_i - the pure imaginary complex number i

    1190:    Level: intermediate

    1192: .seealso: `PetscComplex`, `PetscScalar`
    1193: M*/
    1194: PETSC_EXTERN PetscComplex PETSC_i;

    1196: /*
    1197:    Try to do the right thing for complex number construction: see
    1198:    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
    1199:    for details
    1200: */
    1201: static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
    1202: {
    1203:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
    1204:   return PetscComplex(x, y);
    1205:   #elif defined(_Imaginary_I)
    1206:   return x + y * _Imaginary_I;
    1207:   #else
    1208:   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),

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

    1214:        So type punning should be portable. */
    1215:     union
    1216:     {
    1217:       PetscComplex z;
    1218:       PetscReal    f[2];
    1219:     } uz;

    1221:     uz.f[0] = x;
    1222:     uz.f[1] = y;
    1223:     return uz.z;
    1224:   }
    1225:   #endif
    1226: }

    1228:   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
    1229:   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )

    1231:   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
    1232:     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
    1233:     #if defined(PETSC_USE_COMPLEX)
    1234:       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
    1235:     #else
    1236:       #define MPIU___COMPLEX128_ATTR_TAG
    1237:     #endif

    1239: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;

    1241:     #undef MPIU___COMPLEX128_ATTR_TAG
    1242:   #endif /* PETSC_HAVE_REAL___FLOAT128 */

    1244:   /*MC
    1245:    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`

    1247:    Level: beginner

    1249:    Note:
    1250:    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.

    1252: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
    1253: M*/
    1254:   #if defined(PETSC_USE_REAL_SINGLE)
    1255:     #define MPIU_COMPLEX MPI_C_COMPLEX
    1256:   #elif defined(PETSC_USE_REAL_DOUBLE)
    1257:     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
    1258:   #elif defined(PETSC_USE_REAL___FLOAT128)
    1259:     #define MPIU_COMPLEX MPIU___COMPLEX128
    1260:   #elif defined(PETSC_USE_REAL___FP16)
    1261:     #define MPIU_COMPLEX MPI_C_COMPLEX
    1262:   #endif /* PETSC_USE_REAL_* */

    1264: #endif /* PETSC_HAVE_COMPLEX */

    1266: /*
    1267:     Scalar number definitions
    1268:  */
    1269: #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
    1270:   /*MC
    1271:    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`

    1273:    Level: beginner

    1275:    Note:
    1276:    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.

    1278: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
    1279: M*/
    1280:   #define MPIU_SCALAR MPIU_COMPLEX

    1282:   /*MC
    1283:    PetscRealPart - Returns the real part of a `PetscScalar`

    1285:    Synopsis:
    1286: #include <petscmath.h>
    1287:    PetscReal PetscRealPart(PetscScalar v)

    1289:    Not Collective

    1291:    Input Parameter:
    1292: .  v - value to find the real part of

    1294:    Level: beginner

    1296: .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
    1297: M*/
    1298:   #define PetscRealPart(a) PetscRealPartComplex(a)

    1300:   /*MC
    1301:    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`

    1303:    Synopsis:
    1304: #include <petscmath.h>
    1305:    PetscReal PetscImaginaryPart(PetscScalar v)

    1307:    Not Collective

    1309:    Input Parameter:
    1310: .  v - value to find the imaginary part of

    1312:    Level: beginner

    1314:    Note:
    1315:    If PETSc was configured for real numbers then this always returns the value 0

    1317: .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
    1318: M*/
    1319:   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)

    1321:   /*MC
    1322:     PetscAbsScalar - Returns the absolute value (magnitude) of a `PetscScalar` value, as a `PetscReal`

    1324:     Synopsis:
    1325: #include <petscmath.h>
    1326:     PetscReal PetscAbsScalar(PetscScalar a)

    1328:     Not Collective; No Fortran Support

    1330:     Input Parameter:
    1331:   . a - the value

    1333:     Level: beginner

    1335: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    1336:   M*/
    1337:   #define PetscAbsScalar(a) PetscAbsComplex(a)
    1338:   /*MC
    1339:     PetscArgScalar - Returns the argument (phase angle) of a `PetscScalar` value, as a `PetscReal`; for real `PetscScalar` this is `0` for nonnegative values and `PETSC_PI` otherwise

    1341:     Synopsis:
    1342: #include <petscmath.h>
    1343:     PetscReal PetscArgScalar(PetscScalar a)

    1345:     Not Collective; No Fortran Support

    1347:     Input Parameter:
    1348:   . a - the value

    1350:     Level: beginner

    1352: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
    1353:   M*/
    1354:   #define PetscArgScalar(a) PetscArgComplex(a)
    1355:   /*MC
    1356:     PetscConj - Returns the complex conjugate of a `PetscScalar` value; the identity when `PetscScalar` is real

    1358:     Synopsis:
    1359: #include <petscmath.h>
    1360:     PetscScalar PetscConj(PetscScalar a)

    1362:     Not Collective; No Fortran Support

    1364:     Input Parameter:
    1365:   . a - the value

    1367:     Level: beginner

    1369: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConjComplex()`
    1370:   M*/
    1371:   #define PetscConj(a) PetscConjComplex(a)
    1372:   /*MC
    1373:     PetscSqrtScalar - Returns the square root of a `PetscScalar` value

    1375:     Synopsis:
    1376: #include <petscmath.h>
    1377:     PetscScalar PetscSqrtScalar(PetscScalar a)

    1379:     Not Collective; No Fortran Support

    1381:     Input Parameter:
    1382:   . a - the value

    1384:     Level: beginner

    1386: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtComplex()`
    1387:   M*/
    1388:   #define PetscSqrtScalar(a) PetscSqrtComplex(a)
    1389:   /*MC
    1390:     PetscPowScalar - Returns the value of `a` raised to the power `b`, both `PetscScalar`

    1392:     Synopsis:
    1393: #include <petscmath.h>
    1394:     PetscScalar PetscPowScalar(PetscScalar a, PetscScalar b)

    1396:     Not Collective; No Fortran Support

    1398:     Input Parameters:
    1399:   + a - the value
    1400:   - b - the value

    1402:     Level: beginner

    1404: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowComplex()`
    1405:   M*/
    1406:   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
    1407:   /*MC
    1408:     PetscExpScalar - Returns the exponential $e^a$ of a `PetscScalar` value

    1410:     Synopsis:
    1411: #include <petscmath.h>
    1412:     PetscScalar PetscExpScalar(PetscScalar a)

    1414:     Not Collective; No Fortran Support

    1416:     Input Parameter:
    1417:   . a - the value

    1419:     Level: beginner

    1421: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpComplex()`
    1422:   M*/
    1423:   #define PetscExpScalar(a) PetscExpComplex(a)
    1424:   /*MC
    1425:     PetscLogScalar - Returns the natural logarithm of a `PetscScalar` value

    1427:     Synopsis:
    1428: #include <petscmath.h>
    1429:     PetscScalar PetscLogScalar(PetscScalar a)

    1431:     Not Collective; No Fortran Support

    1433:     Input Parameter:
    1434:   . a - the value

    1436:     Level: beginner

    1438: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogComplex()`
    1439:   M*/
    1440:   #define PetscLogScalar(a) PetscLogComplex(a)
    1441:   /*MC
    1442:     PetscSinScalar - Returns the sine of a `PetscScalar` value

    1444:     Synopsis:
    1445: #include <petscmath.h>
    1446:     PetscScalar PetscSinScalar(PetscScalar a)

    1448:     Not Collective; No Fortran Support

    1450:     Input Parameter:
    1451:   . a - the value

    1453:     Level: beginner

    1455: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinComplex()`
    1456:   M*/
    1457:   #define PetscSinScalar(a) PetscSinComplex(a)
    1458:   /*MC
    1459:     PetscCosScalar - Returns the cosine of a `PetscScalar` value

    1461:     Synopsis:
    1462: #include <petscmath.h>
    1463:     PetscScalar PetscCosScalar(PetscScalar a)

    1465:     Not Collective; No Fortran Support

    1467:     Input Parameter:
    1468:   . a - the value

    1470:     Level: beginner

    1472: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosComplex()`
    1473:   M*/
    1474:   #define PetscCosScalar(a) PetscCosComplex(a)
    1475:   /*MC
    1476:     PetscTanScalar - Returns the tangent of a `PetscScalar` value

    1478:     Synopsis:
    1479: #include <petscmath.h>
    1480:     PetscScalar PetscTanScalar(PetscScalar a)

    1482:     Not Collective; No Fortran Support

    1484:     Input Parameter:
    1485:   . a - the value

    1487:     Level: beginner

    1489: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanComplex()`
    1490:   M*/
    1491:   #define PetscTanScalar(a) PetscTanComplex(a)
    1492:   /*MC
    1493:     PetscAsinScalar - Returns the arc sine of a `PetscScalar` value

    1495:     Synopsis:
    1496: #include <petscmath.h>
    1497:     PetscScalar PetscAsinScalar(PetscScalar a)

    1499:     Not Collective; No Fortran Support

    1501:     Input Parameter:
    1502:   . a - the value

    1504:     Level: beginner

    1506: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinComplex()`
    1507:   M*/
    1508:   #define PetscAsinScalar(a) PetscAsinComplex(a)
    1509:   /*MC
    1510:     PetscAcosScalar - Returns the arc cosine of a `PetscScalar` value

    1512:     Synopsis:
    1513: #include <petscmath.h>
    1514:     PetscScalar PetscAcosScalar(PetscScalar a)

    1516:     Not Collective; No Fortran Support

    1518:     Input Parameter:
    1519:   . a - the value

    1521:     Level: beginner

    1523: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosComplex()`
    1524:   M*/
    1525:   #define PetscAcosScalar(a) PetscAcosComplex(a)
    1526:   /*MC
    1527:     PetscAtanScalar - Returns the arc tangent of a `PetscScalar` value

    1529:     Synopsis:
    1530: #include <petscmath.h>
    1531:     PetscScalar PetscAtanScalar(PetscScalar a)

    1533:     Not Collective; No Fortran Support

    1535:     Input Parameter:
    1536:   . a - the value

    1538:     Level: beginner

    1540: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanComplex()`
    1541:   M*/
    1542:   #define PetscAtanScalar(a) PetscAtanComplex(a)
    1543:   /*MC
    1544:     PetscSinhScalar - Returns the hyperbolic sine of a `PetscScalar` value

    1546:     Synopsis:
    1547: #include <petscmath.h>
    1548:     PetscScalar PetscSinhScalar(PetscScalar a)

    1550:     Not Collective; No Fortran Support

    1552:     Input Parameter:
    1553:   . a - the value

    1555:     Level: beginner

    1557: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhComplex()`
    1558:   M*/
    1559:   #define PetscSinhScalar(a) PetscSinhComplex(a)
    1560:   /*MC
    1561:     PetscCoshScalar - Returns the hyperbolic cosine of a `PetscScalar` value

    1563:     Synopsis:
    1564: #include <petscmath.h>
    1565:     PetscScalar PetscCoshScalar(PetscScalar a)

    1567:     Not Collective; No Fortran Support

    1569:     Input Parameter:
    1570:   . a - the value

    1572:     Level: beginner

    1574: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshComplex()`
    1575:   M*/
    1576:   #define PetscCoshScalar(a) PetscCoshComplex(a)
    1577:   /*MC
    1578:     PetscTanhScalar - Returns the hyperbolic tangent of a `PetscScalar` value

    1580:     Synopsis:
    1581: #include <petscmath.h>
    1582:     PetscScalar PetscTanhScalar(PetscScalar a)

    1584:     Not Collective; No Fortran Support

    1586:     Input Parameter:
    1587:   . a - the value

    1589:     Level: beginner

    1591: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhComplex()`
    1592:   M*/
    1593:   #define PetscTanhScalar(a) PetscTanhComplex(a)
    1594:   /*MC
    1595:     PetscAsinhScalar - Returns the inverse hyperbolic sine of a `PetscScalar` value

    1597:     Synopsis:
    1598: #include <petscmath.h>
    1599:     PetscScalar PetscAsinhScalar(PetscScalar a)

    1601:     Not Collective; No Fortran Support

    1603:     Input Parameter:
    1604:   . a - the value

    1606:     Level: beginner

    1608: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhComplex()`
    1609:   M*/
    1610:   #define PetscAsinhScalar(a) PetscAsinhComplex(a)
    1611:   /*MC
    1612:     PetscAcoshScalar - Returns the inverse hyperbolic cosine of a `PetscScalar` value

    1614:     Synopsis:
    1615: #include <petscmath.h>
    1616:     PetscScalar PetscAcoshScalar(PetscScalar a)

    1618:     Not Collective; No Fortran Support

    1620:     Input Parameter:
    1621:   . a - the value

    1623:     Level: beginner

    1625: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshComplex()`
    1626:   M*/
    1627:   #define PetscAcoshScalar(a) PetscAcoshComplex(a)
    1628:   /*MC
    1629:     PetscAtanhScalar - Returns the inverse hyperbolic tangent of a `PetscScalar` value

    1631:     Synopsis:
    1632: #include <petscmath.h>
    1633:     PetscScalar PetscAtanhScalar(PetscScalar a)

    1635:     Not Collective; No Fortran Support

    1637:     Input Parameter:
    1638:   . a - the value

    1640:     Level: beginner

    1642: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhComplex()`
    1643:   M*/
    1644:   #define PetscAtanhScalar(a) PetscAtanhComplex(a)

    1646: #else /* PETSC_USE_COMPLEX */
    1647:   #define MPIU_SCALAR           MPIU_REAL
    1648:   #define PetscRealPart(a)      (a)
    1649:   #define PetscImaginaryPart(a) ((PetscReal)0)
    1650:   #define PetscAbsScalar(a)     PetscAbsReal(a)
    1651:   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
    1652:   #define PetscConj(a)          (a)
    1653:   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
    1654:   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
    1655:   #define PetscExpScalar(a)     PetscExpReal(a)
    1656:   #define PetscLogScalar(a)     PetscLogReal(a)
    1657:   #define PetscSinScalar(a)     PetscSinReal(a)
    1658:   #define PetscCosScalar(a)     PetscCosReal(a)
    1659:   #define PetscTanScalar(a)     PetscTanReal(a)
    1660:   #define PetscAsinScalar(a)    PetscAsinReal(a)
    1661:   #define PetscAcosScalar(a)    PetscAcosReal(a)
    1662:   #define PetscAtanScalar(a)    PetscAtanReal(a)
    1663:   #define PetscSinhScalar(a)    PetscSinhReal(a)
    1664:   #define PetscCoshScalar(a)    PetscCoshReal(a)
    1665:   #define PetscTanhScalar(a)    PetscTanhReal(a)
    1666:   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
    1667:   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
    1668:   #define PetscAtanhScalar(a)   PetscAtanhReal(a)

    1670: #endif /* PETSC_USE_COMPLEX */

    1672: /*E
    1673:    PetscScalarPrecision - Names of the floating-point precisions that a `PetscScalar` could in principle be built with

    1675:    Values:
    1676: +   `PETSC_SCALAR_DOUBLE`      - IEEE double precision
    1677: .   `PETSC_SCALAR_SINGLE`      - IEEE single precision
    1678: .   `PETSC_SCALAR_LONG_DOUBLE` - C `long double` precision
    1679: -   `PETSC_SCALAR_HALF`        - IEEE half precision

    1681:    Level: developer

    1683:    Note:
    1684:    This enum is reserved for situations where an object might be created in a precision different from `PetscScalar`; the current PETSc code does not use it.

    1686: .seealso: `PetscScalar`, `PetscReal`, `PetscComplex`
    1687: E*/
    1688: typedef enum {
    1689:   PETSC_SCALAR_DOUBLE,
    1690:   PETSC_SCALAR_SINGLE,
    1691:   PETSC_SCALAR_LONG_DOUBLE,
    1692:   PETSC_SCALAR_HALF
    1693: } PetscScalarPrecision;

    1695: /*MC
    1696:    PetscAbs - Returns the absolute value of a number

    1698:    Synopsis:
    1699: #include <petscmath.h>
    1700:    type PetscAbs(type v)

    1702:    Not Collective

    1704:    Input Parameter:
    1705: .  v - the number

    1707:    Level: beginner

    1709:    Note:
    1710:    The type can be integer or real floating point value, but cannot be complex

    1712: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
    1713: M*/
    1714: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))

    1716: /*MC
    1717:    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1

    1719:    Synopsis:
    1720: #include <petscmath.h>
    1721:    int PetscSign(type v)

    1723:    Not Collective

    1725:    Input Parameter:
    1726: .  v - the number

    1728:    Level: beginner

    1730:    Note:
    1731:    The type can be integer or real floating point value

    1733: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
    1734: M*/
    1735: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

    1737: /*MC
    1738:    PetscMin - Returns minimum of two numbers

    1740:    Synopsis:
    1741: #include <petscmath.h>
    1742:    type PetscMin(type v1,type v2)

    1744:    Not Collective

    1746:    Input Parameters:
    1747: +  v1 - first value to find minimum of
    1748: -  v2 - second value to find minimum of

    1750:    Level: beginner

    1752:    Note:
    1753:    The type can be integer or floating point value, but cannot be complex

    1755: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
    1756: M*/
    1757: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))

    1759: /*MC
    1760:    PetscMax - Returns maximum of two numbers

    1762:    Synopsis:
    1763: #include <petscmath.h>
    1764:    type max PetscMax(type v1,type v2)

    1766:    Not Collective

    1768:    Input Parameters:
    1769: +  v1 - first value to find maximum of
    1770: -  v2 - second value to find maximum of

    1772:    Level: beginner

    1774:    Note:
    1775:    The type can be integer or floating point value

    1777: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
    1778: M*/
    1779: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))

    1781: /*MC
    1782:    PetscClipInterval - Returns a number clipped to be within an interval

    1784:    Synopsis:
    1785: #include <petscmath.h>
    1786:    type clip PetscClipInterval(type x,type a,type b)

    1788:    Not Collective

    1790:    Input Parameters:
    1791: +  x - value to use if within interval [a,b]
    1792: .  a - lower end of interval
    1793: -  b - upper end of interval

    1795:    Level: beginner

    1797:    Note:
    1798:    The type can be integer or floating point value

    1800:    Example\:
    1801: .vb
    1802:   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
    1803:   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
    1804: .ve

    1806: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
    1807: M*/
    1808: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))

    1810: /*MC
    1811:    PetscAbsInt - Returns the absolute value of an integer

    1813:    Synopsis:
    1814: #include <petscmath.h>
    1815:    int abs PetscAbsInt(int v1)

    1817:    Input Parameter:
    1818: .   v1 - the integer

    1820:    Level: beginner

    1822: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
    1823: M*/
    1824: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))

    1826: /*MC
    1827:    PetscAbsReal - Returns the absolute value of a real number

    1829:    Synopsis:
    1830: #include <petscmath.h>
    1831:    Real abs PetscAbsReal(PetscReal v1)

    1833:    Input Parameter:
    1834: .   v1 - the `PetscReal` value

    1836:    Level: beginner

    1838: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
    1839: M*/
    1840: #if defined(PETSC_USE_REAL_SINGLE)
    1841:   #define PetscAbsReal(a) fabsf(a)
    1842: #elif defined(PETSC_USE_REAL_DOUBLE)
    1843:   #define PetscAbsReal(a) fabs(a)
    1844: #elif defined(PETSC_USE_REAL___FLOAT128)
    1845:   #define PetscAbsReal(a) fabsq(a)
    1846: #elif defined(PETSC_USE_REAL___FP16)
    1847:   #define PetscAbsReal(a) fabsf(a)
    1848: #endif

    1850: /*MC
    1851:    PetscSqr - Returns the square of a number

    1853:    Synopsis:
    1854: #include <petscmath.h>
    1855:    type sqr PetscSqr(type v1)

    1857:    Not Collective

    1859:    Input Parameter:
    1860: .   v1 - the value

    1862:    Level: beginner

    1864:    Note:
    1865:    The type can be integer, floating point, or complex floating point

    1867: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
    1868: M*/
    1869: #define PetscSqr(a) ((a) * (a))

    1871: /*MC
    1872:    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
    1873:    precision of `PetscReal` be it half, single, double or 128-bit representation

    1875:    Synopsis:
    1876: #include <petscmath.h>
    1877:    PetscReal PetscRealConstant(real_number)

    1879:    Not Collective

    1881:    Input Parameter:
    1882: .   v1 - the real number, for example 1.5

    1884:    Level: beginner

    1886:    Note:
    1887:    For example, if PETSc is configured with `--with-precision=__float128` and one writes
    1888: .vb
    1889:    PetscReal d = 1.5;
    1890: .ve
    1891:    the result is 1.5 in double precision extended to 128 bit representation, meaning it is very far from the correct value. Hence, one should write
    1892: .vb
    1893:    PetscReal d = PetscRealConstant(1.5);
    1894: .ve

    1896: .seealso: `PetscReal`
    1897: M*/
    1898: #if defined(PETSC_USE_REAL_SINGLE)
    1899:   #define PetscRealConstant(constant) constant##F
    1900: #elif defined(PETSC_USE_REAL_DOUBLE)
    1901:   #define PetscRealConstant(constant) constant
    1902: #elif defined(PETSC_USE_REAL___FLOAT128)
    1903:   #define PetscRealConstant(constant) constant##Q
    1904: #elif defined(PETSC_USE_REAL___FP16)
    1905:   #define PetscRealConstant(constant) constant##F
    1906: #endif

    1908: /*
    1909:      Basic constants
    1910: */
    1911: /*MC
    1912:   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.

    1914:   Level: beginner

    1916: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
    1917: M*/

    1919: /*MC
    1920:   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.

    1922:   Level: beginner

    1924: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
    1925: M*/

    1927: /*MC
    1928:   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.

    1930:   Level: beginner

    1932: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
    1933: M*/

    1935: /*MC
    1936:   PETSC_E - the value of Euler's constant $ e $ to the correct precision of `PetscReal`.

    1938:   Level: beginner

    1940: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
    1941: M*/

    1943: #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
    1944: #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
    1945: #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
    1946: #define PETSC_E     PetscRealConstant(2.7182818284590452353602874713526625)

    1948: /*MC
    1949:   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`

    1951:   Level: beginner

    1953: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
    1954: M*/

    1956: /*MC
    1957:   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`

    1959:   Level: beginner

    1961: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
    1962: M*/

    1964: /*MC
    1965:   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.

    1967:   Level: beginner

    1969:   Note:
    1970:   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers

    1972:   Developer Note:
    1973:   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.

    1975: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
    1976: M*/

    1978: /*MC
    1979:   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`

    1981:   Level: beginner

    1983:   Note:
    1984:   See <https://en.wikipedia.org/wiki/Machine_epsilon>

    1986: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
    1987: M*/

    1989: /*MC
    1990:   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`

    1992:   Level: beginner

    1994:   Note:
    1995:   See `PETSC_MACHINE_EPSILON`

    1997: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
    1998: M*/

    2000: /*MC
    2001:   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
    2002:   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.

    2004:   Level: beginner

    2006:   Note:
    2007:   See `PETSC_MACHINE_EPSILON`

    2009: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
    2010:          `PETSC_SQRT_MACHINE_EPSILON`
    2011: M*/

    2013: #if defined(PETSC_USE_REAL_SINGLE)
    2014:   #define PETSC_MAX_REAL             3.40282346638528860e+38F
    2015:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
    2016:   #define PETSC_REAL_MIN             1.1754944e-38F
    2017:   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
    2018:   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
    2019:   #define PETSC_SMALL                1.e-5F
    2020: #elif defined(PETSC_USE_REAL_DOUBLE)
    2021:   #define PETSC_MAX_REAL             1.7976931348623157e+308
    2022:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
    2023:   #define PETSC_REAL_MIN             2.225073858507201e-308
    2024:   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
    2025:   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
    2026:   #define PETSC_SMALL                1.e-10
    2027: #elif defined(PETSC_USE_REAL___FLOAT128)
    2028:   #define PETSC_MAX_REAL             FLT128_MAX
    2029:   #define PETSC_MIN_REAL             (-FLT128_MAX)
    2030:   #define PETSC_REAL_MIN             FLT128_MIN
    2031:   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
    2032:   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
    2033:   #define PETSC_SMALL                1.e-20Q
    2034: #elif defined(PETSC_USE_REAL___FP16)
    2035:   #define PETSC_MAX_REAL             65504.0F
    2036:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
    2037:   #define PETSC_REAL_MIN             .00006103515625F
    2038:   #define PETSC_MACHINE_EPSILON      .0009765625F
    2039:   #define PETSC_SQRT_MACHINE_EPSILON .03125F
    2040:   #define PETSC_SMALL                5.e-3F
    2041: #endif

    2043: /*MC
    2044:   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`

    2046:   Level: intermediate

    2048:   Note:
    2049:   This is not the IEEE infinity value

    2051: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
    2052: M*/
    2053: #define PETSC_INFINITY (PETSC_MAX_REAL / 4)

    2055: /*MC
    2056:   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`

    2058:   Level: intermediate

    2060:   Note:
    2061:   This is not the negative IEEE infinity value

    2063: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
    2064: M*/
    2065: #define PETSC_NINFINITY (-PETSC_INFINITY)

    2067: PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
    2068: PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
    2069: PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
    2070: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
    2071: {
    2072:   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
    2073: }
    2074: static inline PetscBool PetscIsInfScalar(PetscScalar v)
    2075: {
    2076:   return PetscIsInfReal(PetscAbsScalar(v));
    2077: }
    2078: static inline PetscBool PetscIsNanScalar(PetscScalar v)
    2079: {
    2080:   return PetscIsNanReal(PetscAbsScalar(v));
    2081: }
    2082: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
    2083: {
    2084:   return PetscIsInfOrNanReal(PetscAbsScalar(v));
    2085: }
    2086: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
    2087: {
    2088:   return PetscIsNormalReal(PetscAbsScalar(v));
    2089: }

    2091: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
    2092: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
    2093: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);

    2095: /*@C
    2096:   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`

    2098:   Input Parameters:
    2099: + lhs  - The first number
    2100: . rhs  - The second number
    2101: . rtol - The relative tolerance
    2102: - atol - The absolute tolerance

    2104:   Level: beginner

    2106:   Note:
    2107:   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
    2108:   numbers.

    2110: .seealso: `PetscIsCloseAtTol()`
    2111: @*/
    2112: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
    2113: {
    2114:   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);

    2116:   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
    2117:   return close;
    2118: }

    2120: /*
    2121:     These macros are currently hardwired to match the regular data types, so there is no support for a different
    2122:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
    2123:  */
    2124: #define MPIU_MATSCALAR MPIU_SCALAR

    2126: /*MC
    2127:    MatScalar - Datatype used inside matrix implementations to store matrix entries

    2129:    Level: developer

    2131:    Note:
    2132:    `MatScalar` is currently a synonym for `PetscScalar`. It exists so that matrix internals can, in principle, store entries in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

    2134: .seealso: `PetscScalar`, `MatReal`, `Mat`, `PETSC_USE_COMPLEX`
    2135: M*/
    2136: typedef PetscScalar MatScalar;

    2138: /*MC
    2139:    MatReal - Datatype used inside matrix implementations to store real-valued matrix data

    2141:    Level: developer

    2143:    Note:
    2144:    `MatReal` is currently a synonym for `PetscReal`. It exists so that matrix internals can, in principle, store data in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

    2146: .seealso: `PetscReal`, `MatScalar`, `Mat`
    2147: M*/
    2148: typedef PetscReal MatReal;

    2150: struct petsc_mpiu_2scalar {
    2151:   PetscScalar a, b;
    2152: };
    2153: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);

    2155: /* MPI Datatypes for composite reductions */
    2156: struct petsc_mpiu_real_int {
    2157:   PetscReal v;
    2158:   PetscInt  i;
    2159: };

    2161: struct petsc_mpiu_scalar_int {
    2162:   PetscScalar v;
    2163:   PetscInt    i;
    2164: };

    2166: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
    2167: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);

    2169: #if defined(PETSC_USE_64BIT_INDICES)
    2170: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
    2171:   PetscInt a;
    2172:   PetscInt b;
    2173: };
    2174: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
    2175:   PetscInt    a;
    2176:   PetscMPIInt b;
    2177: };
    2178: /*
    2179:  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
    2180:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
    2181:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");

    2183:  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
    2184:  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
    2185:  pass! So we just comment it out...
    2186: */
    2187: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
    2188: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
    2189: #else
    2190:   #define MPIU_2INT       MPI_2INT
    2191:   #define MPIU_INT_MPIINT MPI_2INT
    2192: #endif
    2193: PETSC_EXTERN MPI_Datatype MPI_4INT;
    2194: PETSC_EXTERN MPI_Datatype MPIU_4INT;

    2196: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
    2197: {
    2198:   PetscInt result = 1;
    2199:   while (power) {
    2200:     if (power & 1) result *= base;
    2201:     power >>= 1;
    2202:     if (power) base *= base;
    2203:   }
    2204:   return result;
    2205: }

    2207: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
    2208: {
    2209:   PetscInt64 result = 1;
    2210:   while (power) {
    2211:     if (power & 1) result *= base;
    2212:     power >>= 1;
    2213:     if (power) base *= base;
    2214:   }
    2215:   return result;
    2216: }

    2218: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
    2219: {
    2220:   PetscReal result = 1;
    2221:   if (power < 0) {
    2222:     power = -power;
    2223:     base  = ((PetscReal)1) / base;
    2224:   }
    2225:   while (power) {
    2226:     if (power & 1) result *= base;
    2227:     power >>= 1;
    2228:     if (power) base *= base;
    2229:   }
    2230:   return result;
    2231: }

    2233: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
    2234: {
    2235:   PetscScalar result = (PetscReal)1;
    2236:   if (power < 0) {
    2237:     power = -power;
    2238:     base  = ((PetscReal)1) / base;
    2239:   }
    2240:   while (power) {
    2241:     if (power & 1) result *= base;
    2242:     power >>= 1;
    2243:     if (power) base *= base;
    2244:   }
    2245:   return result;
    2246: }

    2248: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
    2249: {
    2250:   PetscScalar cpower = power;
    2251:   return PetscPowScalar(base, cpower);
    2252: }

    2254: /*MC
    2255:    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers

    2257:    Synopsis:
    2258: #include <petscmath.h>
    2259:    bool PetscApproximateLTE(PetscReal x,constant float)

    2261:    Not Collective

    2263:    Input Parameters:
    2264: +   x - the variable
    2265: -   b - the constant float it is checking if `x` is less than or equal to

    2267:    Level: advanced

    2269:    Notes:
    2270:    The fudge factor is the value `PETSC_SMALL`

    2272:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

    2274:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
    2275:    floating point results.

    2277:    Example\:
    2278: .vb
    2279:   PetscReal x;
    2280:   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
    2281: .ve

    2283: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
    2284: M*/
    2285: #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))

    2287: /*MC
    2288:    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers

    2290:    Synopsis:
    2291: #include <petscmath.h>
    2292:    bool PetscApproximateGTE(PetscReal x,constant float)

    2294:    Not Collective

    2296:    Input Parameters:
    2297: +   x - the variable
    2298: -   b - the constant float it is checking if `x` is greater than or equal to

    2300:    Level: advanced

    2302:    Notes:
    2303:    The fudge factor is the value `PETSC_SMALL`

    2305:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

    2307:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
    2308:    floating point results.

    2310:    Example\:
    2311: .vb
    2312:   PetscReal x;
    2313:   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
    2314: .ve

    2316: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    2317: M*/
    2318: #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))

    2320: /*@C
    2321:    PetscCeilInt - Returns the ceiling of the quotation of two positive integers

    2323:    Not Collective

    2325:    Input Parameters:
    2326: +   x - the numerator
    2327: -   y - the denominator

    2329:    Level: advanced

    2331:   Example\:
    2332: .vb
    2333:   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
    2334: .ve

    2336: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    2337: @*/
    2338: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
    2339: {
    2340:   return x / y + (x % y ? 1 : 0);
    2341: }

    2343: /*@C
    2344:    PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers

    2346:    Not Collective

    2348:    Input Parameters:
    2349: +   x - the numerator
    2350: -   y - the denominator

    2352:    Level: advanced

    2354:   Example\:
    2355: .vb
    2356:   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
    2357: .ve

    2359: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    2360: @*/
    2361: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
    2362: {
    2363:   return x / y + (x % y ? 1 : 0);
    2364: }

    2366: /*@C
    2367:    PetscGCD - Returns the greatest common divisor of two integers

    2369:    Not Collective

    2371:    Input Parameters:
    2372: +   a - first number
    2373: -   b - second number

    2375:    Level: advanced

    2377: .seealso: `PetscLCM()`
    2378: @*/
    2379: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
    2380: {
    2381:   a = PetscAbsInt(a);
    2382:   b = PetscAbsInt(b);
    2383:   while (b != 0) {
    2384:     PetscInt tmp = b;

    2386:     b = a % b;
    2387:     a = tmp;
    2388:   }
    2389:   return a;
    2390: }

    2392: /*@C
    2393:    PetscLCM - Returns the least common multiple of two integers

    2395:    Not Collective

    2397:    Input Parameters:
    2398: +   a - first number
    2399: -   b - second number

    2401:    Level: advanced

    2403: .seealso: `PetscGCD()`
    2404: @*/
    2405: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
    2406: {
    2407:   PetscInt gcd;

    2409:   a = PetscAbsInt(a);
    2410:   b = PetscAbsInt(b);

    2412:   gcd = PetscGCD(a, b);
    2413:   return gcd ? a * (b / gcd) : 0;
    2414: }

    2416: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);