LCOV - code coverage report
Current view: top level - home/gitlab-runner/builds/q8svuz_Y/0/slepc/petsc/include - petscmath.h (source / functions) Hit Total Coverage
Test: SLEPc Lines: 39 39 100.0 %
Date: 2024-12-18 00:42:09 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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.
       5             : 
       6             :     This file is included by petscsys.h and should not be used directly.
       7             : */
       8             : #pragma once
       9             : 
      10             : #include <math.h>
      11             : #include <petscmacros.h>
      12             : #include <petscsystypes.h>
      13             : 
      14             : /* SUBMANSEC = Sys */
      15             : 
      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             : */
      21             : 
      22             : /*
      23             :     Real number definitions
      24             :  */
      25             : #if defined(PETSC_USE_REAL_SINGLE)
      26             :   #define PetscSqrtReal(a)        sqrtf(a)
      27             :   #define PetscCbrtReal(a)        cbrtf(a)
      28             :   #define PetscHypotReal(a, b)    hypotf(a, b)
      29             :   #define PetscAtan2Real(a, b)    atan2f(a, b)
      30             :   #define PetscPowReal(a, b)      powf(a, b)
      31             :   #define PetscExpReal(a)         expf(a)
      32             :   #define PetscLogReal(a)         logf(a)
      33             :   #define PetscLog10Real(a)       log10f(a)
      34             :   #define PetscLog2Real(a)        log2f(a)
      35             :   #define PetscSinReal(a)         sinf(a)
      36             :   #define PetscCosReal(a)         cosf(a)
      37             :   #define PetscTanReal(a)         tanf(a)
      38             :   #define PetscAsinReal(a)        asinf(a)
      39             :   #define PetscAcosReal(a)        acosf(a)
      40             :   #define PetscAtanReal(a)        atanf(a)
      41             :   #define PetscSinhReal(a)        sinhf(a)
      42             :   #define PetscCoshReal(a)        coshf(a)
      43             :   #define PetscTanhReal(a)        tanhf(a)
      44             :   #define PetscAsinhReal(a)       asinhf(a)
      45             :   #define PetscAcoshReal(a)       acoshf(a)
      46             :   #define PetscAtanhReal(a)       atanhf(a)
      47             :   #define PetscErfReal(a)         erff(a)
      48             :   #define PetscCeilReal(a)        ceilf(a)
      49             :   #define PetscFloorReal(a)       floorf(a)
      50             :   #define PetscRintReal(a)        rintf(a)
      51             :   #define PetscFmodReal(a, b)     fmodf(a, b)
      52             :   #define PetscCopysignReal(a, b) copysignf(a, b)
      53             :   #define PetscTGamma(a)          tgammaf(a)
      54             :   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
      55             :     #define PetscLGamma(a) gammaf(a)
      56             :   #else
      57             :     #define PetscLGamma(a) lgammaf(a)
      58             :   #endif
      59             : 
      60             : #elif defined(PETSC_USE_REAL_DOUBLE)
      61             :   #define PetscSqrtReal(a)        sqrt(a)
      62             :   #define PetscCbrtReal(a)        cbrt(a)
      63             :   #define PetscHypotReal(a, b)    hypot(a, b)
      64             :   #define PetscAtan2Real(a, b)    atan2(a, b)
      65             :   #define PetscPowReal(a, b)      pow(a, b)
      66             :   #define PetscExpReal(a)         exp(a)
      67             :   #define PetscLogReal(a)         log(a)
      68             :   #define PetscLog10Real(a)       log10(a)
      69             :   #define PetscLog2Real(a)        log2(a)
      70             :   #define PetscSinReal(a)         sin(a)
      71             :   #define PetscCosReal(a)         cos(a)
      72             :   #define PetscTanReal(a)         tan(a)
      73             :   #define PetscAsinReal(a)        asin(a)
      74             :   #define PetscAcosReal(a)        acos(a)
      75             :   #define PetscAtanReal(a)        atan(a)
      76             :   #define PetscSinhReal(a)        sinh(a)
      77             :   #define PetscCoshReal(a)        cosh(a)
      78             :   #define PetscTanhReal(a)        tanh(a)
      79             :   #define PetscAsinhReal(a)       asinh(a)
      80             :   #define PetscAcoshReal(a)       acosh(a)
      81             :   #define PetscAtanhReal(a)       atanh(a)
      82             :   #define PetscErfReal(a)         erf(a)
      83             :   #define PetscCeilReal(a)        ceil(a)
      84             :   #define PetscFloorReal(a)       floor(a)
      85             :   #define PetscRintReal(a)        rint(a)
      86             :   #define PetscFmodReal(a, b)     fmod(a, b)
      87             :   #define PetscCopysignReal(a, b) copysign(a, b)
      88             :   #define PetscTGamma(a)          tgamma(a)
      89             :   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
      90             :     #define PetscLGamma(a) gamma(a)
      91             :   #else
      92             :     #define PetscLGamma(a) lgamma(a)
      93             :   #endif
      94             : 
      95             : #elif defined(PETSC_USE_REAL___FLOAT128)
      96             :   #define PetscSqrtReal(a)        sqrtq(a)
      97             :   #define PetscCbrtReal(a)        cbrtq(a)
      98             :   #define PetscHypotReal(a, b)    hypotq(a, b)
      99             :   #define PetscAtan2Real(a, b)    atan2q(a, b)
     100             :   #define PetscPowReal(a, b)      powq(a, b)
     101             :   #define PetscExpReal(a)         expq(a)
     102             :   #define PetscLogReal(a)         logq(a)
     103             :   #define PetscLog10Real(a)       log10q(a)
     104             :   #define PetscLog2Real(a)        log2q(a)
     105             :   #define PetscSinReal(a)         sinq(a)
     106             :   #define PetscCosReal(a)         cosq(a)
     107             :   #define PetscTanReal(a)         tanq(a)
     108             :   #define PetscAsinReal(a)        asinq(a)
     109             :   #define PetscAcosReal(a)        acosq(a)
     110             :   #define PetscAtanReal(a)        atanq(a)
     111             :   #define PetscSinhReal(a)        sinhq(a)
     112             :   #define PetscCoshReal(a)        coshq(a)
     113             :   #define PetscTanhReal(a)        tanhq(a)
     114             :   #define PetscAsinhReal(a)       asinhq(a)
     115             :   #define PetscAcoshReal(a)       acoshq(a)
     116             :   #define PetscAtanhReal(a)       atanhq(a)
     117             :   #define PetscErfReal(a)         erfq(a)
     118             :   #define PetscCeilReal(a)        ceilq(a)
     119             :   #define PetscFloorReal(a)       floorq(a)
     120             :   #define PetscRintReal(a)        rintq(a)
     121             :   #define PetscFmodReal(a, b)     fmodq(a, b)
     122             :   #define PetscCopysignReal(a, b) copysignq(a, b)
     123             :   #define PetscTGamma(a)          tgammaq(a)
     124             :   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
     125             :     #define PetscLGamma(a) gammaq(a)
     126             :   #else
     127             :     #define PetscLGamma(a) lgammaq(a)
     128             :   #endif
     129             : 
     130             : #elif defined(PETSC_USE_REAL___FP16)
     131             :   #define PetscSqrtReal(a)        sqrtf(a)
     132             :   #define PetscCbrtReal(a)        cbrtf(a)
     133             :   #define PetscHypotReal(a, b)    hypotf(a, b)
     134             :   #define PetscAtan2Real(a, b)    atan2f(a, b)
     135             :   #define PetscPowReal(a, b)      powf(a, b)
     136             :   #define PetscExpReal(a)         expf(a)
     137             :   #define PetscLogReal(a)         logf(a)
     138             :   #define PetscLog10Real(a)       log10f(a)
     139             :   #define PetscLog2Real(a)        log2f(a)
     140             :   #define PetscSinReal(a)         sinf(a)
     141             :   #define PetscCosReal(a)         cosf(a)
     142             :   #define PetscTanReal(a)         tanf(a)
     143             :   #define PetscAsinReal(a)        asinf(a)
     144             :   #define PetscAcosReal(a)        acosf(a)
     145             :   #define PetscAtanReal(a)        atanf(a)
     146             :   #define PetscSinhReal(a)        sinhf(a)
     147             :   #define PetscCoshReal(a)        coshf(a)
     148             :   #define PetscTanhReal(a)        tanhf(a)
     149             :   #define PetscAsinhReal(a)       asinhf(a)
     150             :   #define PetscAcoshReal(a)       acoshf(a)
     151             :   #define PetscAtanhReal(a)       atanhf(a)
     152             :   #define PetscErfReal(a)         erff(a)
     153             :   #define PetscCeilReal(a)        ceilf(a)
     154             :   #define PetscFloorReal(a)       floorf(a)
     155             :   #define PetscRintReal(a)        rintf(a)
     156             :   #define PetscFmodReal(a, b)     fmodf(a, b)
     157             :   #define PetscCopysignReal(a, b) copysignf(a, b)
     158             :   #define PetscTGamma(a)          tgammaf(a)
     159             :   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
     160             :     #define PetscLGamma(a) gammaf(a)
     161             :   #else
     162             :     #define PetscLGamma(a) lgammaf(a)
     163             :   #endif
     164             : 
     165             : #endif /* PETSC_USE_REAL_* */
     166             : 
     167             : static inline PetscReal PetscSignReal(PetscReal a)
     168             : {
     169             :   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
     170             : }
     171             : 
     172             : #if !defined(PETSC_HAVE_LOG2)
     173             :   #undef PetscLog2Real
     174             : static inline PetscReal PetscLog2Real(PetscReal a)
     175             : {
     176             :   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
     177             : }
     178             : #endif
     179             : 
     180             : #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
     181             : PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
     182             : #endif
     183             : #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
     184             : PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
     185             : #endif
     186             : 
     187             : /*MC
     188             :    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in
     189             : 
     190             :    Level: beginner
     191             : 
     192             :    Note:
     193             :    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
     194             : 
     195             : .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
     196             : M*/
     197             : #if defined(PETSC_USE_REAL_SINGLE)
     198             :   #define MPIU_REAL MPI_FLOAT
     199             : #elif defined(PETSC_USE_REAL_DOUBLE)
     200             :   #define MPIU_REAL MPI_DOUBLE
     201             : #elif defined(PETSC_USE_REAL___FLOAT128)
     202             :   #define MPIU_REAL MPIU___FLOAT128
     203             : #elif defined(PETSC_USE_REAL___FP16)
     204             :   #define MPIU_REAL MPIU___FP16
     205             : #endif /* PETSC_USE_REAL_* */
     206             : 
     207             : /*
     208             :     Complex number definitions
     209             :  */
     210             : #if defined(PETSC_HAVE_COMPLEX)
     211             :   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
     212             :   /* C++ support of complex number */
     213             : 
     214             :     #define PetscRealPartComplex(a)      (static_cast<PetscComplex>(a)).real()
     215             :     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
     216             :     #define PetscAbsComplex(a)           petsccomplexlib::abs(static_cast<PetscComplex>(a))
     217             :     #define PetscArgComplex(a)           petsccomplexlib::arg(static_cast<PetscComplex>(a))
     218             :     #define PetscConjComplex(a)          petsccomplexlib::conj(static_cast<PetscComplex>(a))
     219             :     #define PetscSqrtComplex(a)          petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
     220             :     #define PetscPowComplex(a, b)        petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
     221             :     #define PetscExpComplex(a)           petsccomplexlib::exp(static_cast<PetscComplex>(a))
     222             :     #define PetscLogComplex(a)           petsccomplexlib::log(static_cast<PetscComplex>(a))
     223             :     #define PetscSinComplex(a)           petsccomplexlib::sin(static_cast<PetscComplex>(a))
     224             :     #define PetscCosComplex(a)           petsccomplexlib::cos(static_cast<PetscComplex>(a))
     225             :     #define PetscTanComplex(a)           petsccomplexlib::tan(static_cast<PetscComplex>(a))
     226             :     #define PetscAsinComplex(a)          petsccomplexlib::asin(static_cast<PetscComplex>(a))
     227             :     #define PetscAcosComplex(a)          petsccomplexlib::acos(static_cast<PetscComplex>(a))
     228             :     #define PetscAtanComplex(a)          petsccomplexlib::atan(static_cast<PetscComplex>(a))
     229             :     #define PetscSinhComplex(a)          petsccomplexlib::sinh(static_cast<PetscComplex>(a))
     230             :     #define PetscCoshComplex(a)          petsccomplexlib::cosh(static_cast<PetscComplex>(a))
     231             :     #define PetscTanhComplex(a)          petsccomplexlib::tanh(static_cast<PetscComplex>(a))
     232             :     #define PetscAsinhComplex(a)         petsccomplexlib::asinh(static_cast<PetscComplex>(a))
     233             :     #define PetscAcoshComplex(a)         petsccomplexlib::acosh(static_cast<PetscComplex>(a))
     234             :     #define PetscAtanhComplex(a)         petsccomplexlib::atanh(static_cast<PetscComplex>(a))
     235             : 
     236             :   /* TODO: Add configure tests
     237             : 
     238             : #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
     239             : #undef PetscTanComplex
     240             : static inline PetscComplex PetscTanComplex(PetscComplex z)
     241             : {
     242             :   return PetscSinComplex(z)/PetscCosComplex(z);
     243             : }
     244             : #endif
     245             : 
     246             : #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
     247             : #undef PetscTanhComplex
     248             : static inline PetscComplex PetscTanhComplex(PetscComplex z)
     249             : {
     250             :   return PetscSinhComplex(z)/PetscCoshComplex(z);
     251             : }
     252             : #endif
     253             : 
     254             : #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
     255             : #undef PetscAsinComplex
     256             : static inline PetscComplex PetscAsinComplex(PetscComplex z)
     257             : {
     258             :   const PetscComplex j(0,1);
     259             :   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
     260             : }
     261             : #endif
     262             : 
     263             : #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
     264             : #undef PetscAcosComplex
     265             : static inline PetscComplex PetscAcosComplex(PetscComplex z)
     266             : {
     267             :   const PetscComplex j(0,1);
     268             :   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
     269             : }
     270             : #endif
     271             : 
     272             : #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
     273             : #undef PetscAtanComplex
     274             : static inline PetscComplex PetscAtanComplex(PetscComplex z)
     275             : {
     276             :   const PetscComplex j(0,1);
     277             :   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
     278             : }
     279             : #endif
     280             : 
     281             : #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
     282             : #undef PetscAsinhComplex
     283             : static inline PetscComplex PetscAsinhComplex(PetscComplex z)
     284             : {
     285             :   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
     286             : }
     287             : #endif
     288             : 
     289             : #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
     290             : #undef PetscAcoshComplex
     291             : static inline PetscComplex PetscAcoshComplex(PetscComplex z)
     292             : {
     293             :   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
     294             : }
     295             : #endif
     296             : 
     297             : #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
     298             : #undef PetscAtanhComplex
     299             : static inline PetscComplex PetscAtanhComplex(PetscComplex z)
     300             : {
     301             :   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
     302             : }
     303             : #endif
     304             : 
     305             : */
     306             : 
     307             :   #else /* C99 support of complex number */
     308             : 
     309             :     #if defined(PETSC_USE_REAL_SINGLE)
     310             :       #define PetscRealPartComplex(a)      crealf(a)
     311             :       #define PetscImaginaryPartComplex(a) cimagf(a)
     312             :       #define PetscAbsComplex(a)           cabsf(a)
     313             :       #define PetscArgComplex(a)           cargf(a)
     314             :       #define PetscConjComplex(a)          conjf(a)
     315             :       #define PetscSqrtComplex(a)          csqrtf(a)
     316             :       #define PetscPowComplex(a, b)        cpowf(a, b)
     317             :       #define PetscExpComplex(a)           cexpf(a)
     318             :       #define PetscLogComplex(a)           clogf(a)
     319             :       #define PetscSinComplex(a)           csinf(a)
     320             :       #define PetscCosComplex(a)           ccosf(a)
     321             :       #define PetscTanComplex(a)           ctanf(a)
     322             :       #define PetscAsinComplex(a)          casinf(a)
     323             :       #define PetscAcosComplex(a)          cacosf(a)
     324             :       #define PetscAtanComplex(a)          catanf(a)
     325             :       #define PetscSinhComplex(a)          csinhf(a)
     326             :       #define PetscCoshComplex(a)          ccoshf(a)
     327             :       #define PetscTanhComplex(a)          ctanhf(a)
     328             :       #define PetscAsinhComplex(a)         casinhf(a)
     329             :       #define PetscAcoshComplex(a)         cacoshf(a)
     330             :       #define PetscAtanhComplex(a)         catanhf(a)
     331             : 
     332             :     #elif defined(PETSC_USE_REAL_DOUBLE)
     333             :       #define PetscRealPartComplex(a)      creal(a)
     334             :       #define PetscImaginaryPartComplex(a) cimag(a)
     335             :       #define PetscAbsComplex(a)           cabs(a)
     336             :       #define PetscArgComplex(a)           carg(a)
     337             :       #define PetscConjComplex(a)          conj(a)
     338             :       #define PetscSqrtComplex(a)          csqrt(a)
     339             :       #define PetscPowComplex(a, b)        cpow(a, b)
     340             :       #define PetscExpComplex(a)           cexp(a)
     341             :       #define PetscLogComplex(a)           clog(a)
     342             :       #define PetscSinComplex(a)           csin(a)
     343             :       #define PetscCosComplex(a)           ccos(a)
     344             :       #define PetscTanComplex(a)           ctan(a)
     345             :       #define PetscAsinComplex(a)          casin(a)
     346             :       #define PetscAcosComplex(a)          cacos(a)
     347             :       #define PetscAtanComplex(a)          catan(a)
     348             :       #define PetscSinhComplex(a)          csinh(a)
     349             :       #define PetscCoshComplex(a)          ccosh(a)
     350             :       #define PetscTanhComplex(a)          ctanh(a)
     351             :       #define PetscAsinhComplex(a)         casinh(a)
     352             :       #define PetscAcoshComplex(a)         cacosh(a)
     353             :       #define PetscAtanhComplex(a)         catanh(a)
     354             : 
     355             :     #elif defined(PETSC_USE_REAL___FLOAT128)
     356             :       #define PetscRealPartComplex(a)      crealq(a)
     357             :       #define PetscImaginaryPartComplex(a) cimagq(a)
     358             :       #define PetscAbsComplex(a)           cabsq(a)
     359             :       #define PetscArgComplex(a)           cargq(a)
     360             :       #define PetscConjComplex(a)          conjq(a)
     361             :       #define PetscSqrtComplex(a)          csqrtq(a)
     362             :       #define PetscPowComplex(a, b)        cpowq(a, b)
     363             :       #define PetscExpComplex(a)           cexpq(a)
     364             :       #define PetscLogComplex(a)           clogq(a)
     365             :       #define PetscSinComplex(a)           csinq(a)
     366             :       #define PetscCosComplex(a)           ccosq(a)
     367             :       #define PetscTanComplex(a)           ctanq(a)
     368             :       #define PetscAsinComplex(a)          casinq(a)
     369             :       #define PetscAcosComplex(a)          cacosq(a)
     370             :       #define PetscAtanComplex(a)          catanq(a)
     371             :       #define PetscSinhComplex(a)          csinhq(a)
     372             :       #define PetscCoshComplex(a)          ccoshq(a)
     373             :       #define PetscTanhComplex(a)          ctanhq(a)
     374             :       #define PetscAsinhComplex(a)         casinhq(a)
     375             :       #define PetscAcoshComplex(a)         cacoshq(a)
     376             :       #define PetscAtanhComplex(a)         catanhq(a)
     377             : 
     378             :     #endif /* PETSC_USE_REAL_* */
     379             :   #endif   /* (__cplusplus) */
     380             : 
     381             : /*MC
     382             :    PETSC_i - the pure imaginary complex number i
     383             : 
     384             :    Level: intermediate
     385             : 
     386             : .seealso: `PetscComplex`, `PetscScalar`
     387             : M*/
     388             : PETSC_EXTERN PetscComplex PETSC_i;
     389             : 
     390             : /*
     391             :    Try to do the right thing for complex number construction: see
     392             :    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
     393             :    for details
     394             : */
     395        1658 : static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
     396             : {
     397             :   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
     398             :   return PetscComplex(x, y);
     399             :   #elif defined(_Imaginary_I)
     400             :   return x + y * _Imaginary_I;
     401             :   #else
     402             :   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
     403             : 
     404             :        "For each floating type there is a corresponding real type, which is always a real floating
     405             :        type. For real floating types, it is the same type. For complex types, it is the type given
     406             :        by deleting the keyword _Complex from the type name."
     407             : 
     408             :        So type punning should be portable. */
     409        1658 :     union
     410             :     {
     411             :       PetscComplex z;
     412             :       PetscReal    f[2];
     413             :     } uz;
     414             : 
     415        1658 :     uz.f[0] = x;
     416        1658 :     uz.f[1] = y;
     417        1658 :     return uz.z;
     418             :   }
     419             :   #endif
     420             : }
     421             : 
     422             :   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
     423             :   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )
     424             : 
     425             :   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
     426             :     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
     427             :     #if defined(PETSC_USE_COMPLEX)
     428             :       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
     429             :     #else
     430             :       #define MPIU___COMPLEX128_ATTR_TAG
     431             :     #endif
     432             : 
     433             : PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;
     434             : 
     435             :     #undef MPIU___COMPLEX128_ATTR_TAG
     436             :   #endif /* PETSC_HAVE_REAL___FLOAT128 */
     437             : 
     438             :   /*MC
     439             :    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`
     440             : 
     441             :    Level: beginner
     442             : 
     443             :    Note:
     444             :    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
     445             : 
     446             : .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
     447             : M*/
     448             :   #if defined(PETSC_USE_REAL_SINGLE)
     449             :     #define MPIU_COMPLEX MPI_C_COMPLEX
     450             :   #elif defined(PETSC_USE_REAL_DOUBLE)
     451             :     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
     452             :   #elif defined(PETSC_USE_REAL___FLOAT128)
     453             :     #define MPIU_COMPLEX MPIU___COMPLEX128
     454             :   #elif defined(PETSC_USE_REAL___FP16)
     455             :     #define MPIU_COMPLEX MPI_C_COMPLEX
     456             :   #endif /* PETSC_USE_REAL_* */
     457             : 
     458             : #endif /* PETSC_HAVE_COMPLEX */
     459             : 
     460             : /*
     461             :     Scalar number definitions
     462             :  */
     463             : #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
     464             :   /*MC
     465             :    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`
     466             : 
     467             :    Level: beginner
     468             : 
     469             :    Note:
     470             :    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
     471             : 
     472             : .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
     473             : M*/
     474             :   #define MPIU_SCALAR MPIU_COMPLEX
     475             : 
     476             :   /*MC
     477             :    PetscRealPart - Returns the real part of a `PetscScalar`
     478             : 
     479             :    Synopsis:
     480             :    #include <petscmath.h>
     481             :    PetscReal PetscRealPart(PetscScalar v)
     482             : 
     483             :    Not Collective
     484             : 
     485             :    Input Parameter:
     486             : .  v - value to find the real part of
     487             : 
     488             :    Level: beginner
     489             : 
     490             : .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
     491             : M*/
     492             :   #define PetscRealPart(a) PetscRealPartComplex(a)
     493             : 
     494             :   /*MC
     495             :    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`
     496             : 
     497             :    Synopsis:
     498             :    #include <petscmath.h>
     499             :    PetscReal PetscImaginaryPart(PetscScalar v)
     500             : 
     501             :    Not Collective
     502             : 
     503             :    Input Parameter:
     504             : .  v - value to find the imaginary part of
     505             : 
     506             :    Level: beginner
     507             : 
     508             :    Note:
     509             :    If PETSc was configured for real numbers then this always returns the value 0
     510             : 
     511             : .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
     512             : M*/
     513             :   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
     514             : 
     515             :   #define PetscAbsScalar(a)    PetscAbsComplex(a)
     516             :   #define PetscArgScalar(a)    PetscArgComplex(a)
     517             :   #define PetscConj(a)         PetscConjComplex(a)
     518             :   #define PetscSqrtScalar(a)   PetscSqrtComplex(a)
     519             :   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
     520             :   #define PetscExpScalar(a)    PetscExpComplex(a)
     521             :   #define PetscLogScalar(a)    PetscLogComplex(a)
     522             :   #define PetscSinScalar(a)    PetscSinComplex(a)
     523             :   #define PetscCosScalar(a)    PetscCosComplex(a)
     524             :   #define PetscTanScalar(a)    PetscTanComplex(a)
     525             :   #define PetscAsinScalar(a)   PetscAsinComplex(a)
     526             :   #define PetscAcosScalar(a)   PetscAcosComplex(a)
     527             :   #define PetscAtanScalar(a)   PetscAtanComplex(a)
     528             :   #define PetscSinhScalar(a)   PetscSinhComplex(a)
     529             :   #define PetscCoshScalar(a)   PetscCoshComplex(a)
     530             :   #define PetscTanhScalar(a)   PetscTanhComplex(a)
     531             :   #define PetscAsinhScalar(a)  PetscAsinhComplex(a)
     532             :   #define PetscAcoshScalar(a)  PetscAcoshComplex(a)
     533             :   #define PetscAtanhScalar(a)  PetscAtanhComplex(a)
     534             : 
     535             : #else /* PETSC_USE_COMPLEX */
     536             :   #define MPIU_SCALAR           MPIU_REAL
     537             :   #define PetscRealPart(a)      (a)
     538             :   #define PetscImaginaryPart(a) ((PetscReal)0)
     539             :   #define PetscAbsScalar(a)     PetscAbsReal(a)
     540             :   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
     541             :   #define PetscConj(a)          (a)
     542             :   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
     543             :   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
     544             :   #define PetscExpScalar(a)     PetscExpReal(a)
     545             :   #define PetscLogScalar(a)     PetscLogReal(a)
     546             :   #define PetscSinScalar(a)     PetscSinReal(a)
     547             :   #define PetscCosScalar(a)     PetscCosReal(a)
     548             :   #define PetscTanScalar(a)     PetscTanReal(a)
     549             :   #define PetscAsinScalar(a)    PetscAsinReal(a)
     550             :   #define PetscAcosScalar(a)    PetscAcosReal(a)
     551             :   #define PetscAtanScalar(a)    PetscAtanReal(a)
     552             :   #define PetscSinhScalar(a)    PetscSinhReal(a)
     553             :   #define PetscCoshScalar(a)    PetscCoshReal(a)
     554             :   #define PetscTanhScalar(a)    PetscTanhReal(a)
     555             :   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
     556             :   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
     557             :   #define PetscAtanhScalar(a)   PetscAtanhReal(a)
     558             : 
     559             : #endif /* PETSC_USE_COMPLEX */
     560             : 
     561             : /*
     562             :    Certain objects may be created using either single or double precision.
     563             :    This is currently not used.
     564             : */
     565             : typedef enum {
     566             :   PETSC_SCALAR_DOUBLE,
     567             :   PETSC_SCALAR_SINGLE,
     568             :   PETSC_SCALAR_LONG_DOUBLE,
     569             :   PETSC_SCALAR_HALF
     570             : } PetscScalarPrecision;
     571             : 
     572             : /*MC
     573             :    PetscAbs - Returns the absolute value of a number
     574             : 
     575             :    Synopsis:
     576             :    #include <petscmath.h>
     577             :    type PetscAbs(type v)
     578             : 
     579             :    Not Collective
     580             : 
     581             :    Input Parameter:
     582             : .  v - the number
     583             : 
     584             :    Level: beginner
     585             : 
     586             :    Note:
     587             :    The type can be integer or real floating point value, but cannot be complex
     588             : 
     589             : .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
     590             : M*/
     591             : #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))
     592             : 
     593             : /*MC
     594             :    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1
     595             : 
     596             :    Synopsis:
     597             :    #include <petscmath.h>
     598             :    int PetscSign(type v)
     599             : 
     600             :    Not Collective
     601             : 
     602             :    Input Parameter:
     603             : .  v - the number
     604             : 
     605             :    Level: beginner
     606             : 
     607             :    Note:
     608             :    The type can be integer or real floating point value
     609             : 
     610             : .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
     611             : M*/
     612             : #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
     613             : 
     614             : /*MC
     615             :    PetscMin - Returns minimum of two numbers
     616             : 
     617             :    Synopsis:
     618             :    #include <petscmath.h>
     619             :    type PetscMin(type v1,type v2)
     620             : 
     621             :    Not Collective
     622             : 
     623             :    Input Parameters:
     624             : +  v1 - first value to find minimum of
     625             : -  v2 - second value to find minimum of
     626             : 
     627             :    Level: beginner
     628             : 
     629             :    Note:
     630             :    The type can be integer or floating point value, but cannot be complex
     631             : 
     632             : .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
     633             : M*/
     634             : #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))
     635             : 
     636             : /*MC
     637             :    PetscMax - Returns maximum of two numbers
     638             : 
     639             :    Synopsis:
     640             :    #include <petscmath.h>
     641             :    type max PetscMax(type v1,type v2)
     642             : 
     643             :    Not Collective
     644             : 
     645             :    Input Parameters:
     646             : +  v1 - first value to find maximum of
     647             : -  v2 - second value to find maximum of
     648             : 
     649             :    Level: beginner
     650             : 
     651             :    Note:
     652             :    The type can be integer or floating point value
     653             : 
     654             : .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
     655             : M*/
     656             : #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))
     657             : 
     658             : /*MC
     659             :    PetscClipInterval - Returns a number clipped to be within an interval
     660             : 
     661             :    Synopsis:
     662             :    #include <petscmath.h>
     663             :    type clip PetscClipInterval(type x,type a,type b)
     664             : 
     665             :    Not Collective
     666             : 
     667             :    Input Parameters:
     668             : +  x - value to use if within interval [a,b]
     669             : .  a - lower end of interval
     670             : -  b - upper end of interval
     671             : 
     672             :    Level: beginner
     673             : 
     674             :    Note:
     675             :    The type can be integer or floating point value
     676             : 
     677             :    Example\:
     678             : .vb
     679             :   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
     680             :   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
     681             : .ve
     682             : 
     683             : .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
     684             : M*/
     685             : #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
     686             : 
     687             : /*MC
     688             :    PetscAbsInt - Returns the absolute value of an integer
     689             : 
     690             :    Synopsis:
     691             :    #include <petscmath.h>
     692             :    int abs PetscAbsInt(int v1)
     693             : 
     694             :    Input Parameter:
     695             : .   v1 - the integer
     696             : 
     697             :    Level: beginner
     698             : 
     699             : .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
     700             : M*/
     701             : #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
     702             : 
     703             : /*MC
     704             :    PetscAbsReal - Returns the absolute value of a real number
     705             : 
     706             :    Synopsis:
     707             :    #include <petscmath.h>
     708             :    Real abs PetscAbsReal(PetscReal v1)
     709             : 
     710             :    Input Parameter:
     711             : .   v1 - the `PetscReal` value
     712             : 
     713             :    Level: beginner
     714             : 
     715             : .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
     716             : M*/
     717             : #if defined(PETSC_USE_REAL_SINGLE)
     718             :   #define PetscAbsReal(a) fabsf(a)
     719             : #elif defined(PETSC_USE_REAL_DOUBLE)
     720             :   #define PetscAbsReal(a) fabs(a)
     721             : #elif defined(PETSC_USE_REAL___FLOAT128)
     722             :   #define PetscAbsReal(a) fabsq(a)
     723             : #elif defined(PETSC_USE_REAL___FP16)
     724             :   #define PetscAbsReal(a) fabsf(a)
     725             : #endif
     726             : 
     727             : /*MC
     728             :    PetscSqr - Returns the square of a number
     729             : 
     730             :    Synopsis:
     731             :    #include <petscmath.h>
     732             :    type sqr PetscSqr(type v1)
     733             : 
     734             :    Not Collective
     735             : 
     736             :    Input Parameter:
     737             : .   v1 - the value
     738             : 
     739             :    Level: beginner
     740             : 
     741             :    Note:
     742             :    The type can be integer, floating point, or complex floating point
     743             : 
     744             : .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
     745             : M*/
     746             : #define PetscSqr(a) ((a) * (a))
     747             : 
     748             : /*MC
     749             :    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
     750             :    precision of `PetscReal` be it half, single, double or 128-bit representation
     751             : 
     752             :    Synopsis:
     753             :    #include <petscmath.h>
     754             :    PetscReal PetscRealConstant(real_number)
     755             : 
     756             :    Not Collective
     757             : 
     758             :    Input Parameter:
     759             : .   v1 - the real number, for example 1.5
     760             : 
     761             :    Level: beginner
     762             : 
     763             :    Note:
     764             :    For example, if PETSc is configured with `--with-precision=__float128` and one writes
     765             : .vb
     766             :    PetscReal d = 1.5;
     767             : .ve
     768             :    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
     769             : .vb
     770             :    PetscReal d = PetscRealConstant(1.5);
     771             : .ve
     772             : 
     773             : .seealso: `PetscReal`
     774             : M*/
     775             : #if defined(PETSC_USE_REAL_SINGLE)
     776             :   #define PetscRealConstant(constant) constant##F
     777             : #elif defined(PETSC_USE_REAL_DOUBLE)
     778             :   #define PetscRealConstant(constant) constant
     779             : #elif defined(PETSC_USE_REAL___FLOAT128)
     780             :   #define PetscRealConstant(constant) constant##Q
     781             : #elif defined(PETSC_USE_REAL___FP16)
     782             :   #define PetscRealConstant(constant) constant##F
     783             : #endif
     784             : 
     785             : /*
     786             :      Basic constants
     787             : */
     788             : /*MC
     789             :   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.
     790             : 
     791             :   Level: beginner
     792             : 
     793             : .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
     794             : M*/
     795             : 
     796             : /*MC
     797             :   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.
     798             : 
     799             :   Level: beginner
     800             : 
     801             : .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
     802             : M*/
     803             : 
     804             : /*MC
     805             :   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.
     806             : 
     807             :   Level: beginner
     808             : 
     809             : .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
     810             : M*/
     811             : 
     812             : #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
     813             : #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
     814             : #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
     815             : 
     816             : /*MC
     817             :   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`
     818             : 
     819             :   Level: beginner
     820             : 
     821             : .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
     822             : M*/
     823             : 
     824             : /*MC
     825             :   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`
     826             : 
     827             :   Level: beginner
     828             : 
     829             : .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
     830             : M*/
     831             : 
     832             : /*MC
     833             :   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.
     834             : 
     835             :   Level: beginner
     836             : 
     837             :   Note:
     838             :   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers
     839             : 
     840             :   Developer Note:
     841             :   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.
     842             : 
     843             : .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
     844             : M*/
     845             : 
     846             : /*MC
     847             :   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`
     848             : 
     849             :   Level: beginner
     850             : 
     851             :   Note:
     852             :   See <https://en.wikipedia.org/wiki/Machine_epsilon>
     853             : 
     854             : .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
     855             : M*/
     856             : 
     857             : /*MC
     858             :   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`
     859             : 
     860             :   Level: beginner
     861             : 
     862             :   Note:
     863             :   See `PETSC_MACHINE_EPSILON`
     864             : 
     865             : .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
     866             : M*/
     867             : 
     868             : /*MC
     869             :   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
     870             :   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.
     871             : 
     872             :   Level: beginner
     873             : 
     874             :   Note:
     875             :   See `PETSC_MACHINE_EPSILON`
     876             : 
     877             : .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
     878             :          `PETSC_SQRT_MACHINE_EPSILON`
     879             : M*/
     880             : 
     881             : #if defined(PETSC_USE_REAL_SINGLE)
     882             :   #define PETSC_MAX_REAL             3.40282346638528860e+38F
     883             :   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
     884             :   #define PETSC_REAL_MIN             1.1754944e-38F
     885             :   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
     886             :   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
     887             :   #define PETSC_SMALL                1.e-5F
     888             : #elif defined(PETSC_USE_REAL_DOUBLE)
     889             :   #define PETSC_MAX_REAL             1.7976931348623157e+308
     890             :   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
     891             :   #define PETSC_REAL_MIN             2.225073858507201e-308
     892             :   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
     893             :   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
     894             :   #define PETSC_SMALL                1.e-10
     895             : #elif defined(PETSC_USE_REAL___FLOAT128)
     896             :   #define PETSC_MAX_REAL             FLT128_MAX
     897             :   #define PETSC_MIN_REAL             (-FLT128_MAX)
     898             :   #define PETSC_REAL_MIN             FLT128_MIN
     899             :   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
     900             :   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
     901             :   #define PETSC_SMALL                1.e-20Q
     902             : #elif defined(PETSC_USE_REAL___FP16)
     903             :   #define PETSC_MAX_REAL             65504.0F
     904             :   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
     905             :   #define PETSC_REAL_MIN             .00006103515625F
     906             :   #define PETSC_MACHINE_EPSILON      .0009765625F
     907             :   #define PETSC_SQRT_MACHINE_EPSILON .03125F
     908             :   #define PETSC_SMALL                5.e-3F
     909             : #endif
     910             : 
     911             : /*MC
     912             :   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
     913             : 
     914             :   Level: intermediate
     915             : 
     916             :   Note:
     917             :   This is not the IEEE infinity value
     918             : 
     919             : .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
     920             : M*/
     921             : #define PETSC_INFINITY (PETSC_MAX_REAL / 4)
     922             : 
     923             : /*MC
     924             :   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
     925             : 
     926             :   Level: intermediate
     927             : 
     928             :   Note:
     929             :   This is not the negative IEEE infinity value
     930             : 
     931             : .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
     932             : M*/
     933             : #define PETSC_NINFINITY (-PETSC_INFINITY)
     934             : 
     935             : PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
     936             : PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
     937             : PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
     938           9 : static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
     939             : {
     940           9 :   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
     941             : }
     942             : static inline PetscBool PetscIsInfScalar(PetscScalar v)
     943             : {
     944             :   return PetscIsInfReal(PetscAbsScalar(v));
     945             : }
     946     1388059 : static inline PetscBool PetscIsNanScalar(PetscScalar v)
     947             : {
     948     1388059 :   return PetscIsNanReal(PetscAbsScalar(v));
     949             : }
     950             : static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
     951             : {
     952             :   return PetscIsInfOrNanReal(PetscAbsScalar(v));
     953             : }
     954             : static inline PetscBool PetscIsNormalScalar(PetscScalar v)
     955             : {
     956             :   return PetscIsNormalReal(PetscAbsScalar(v));
     957             : }
     958             : 
     959             : PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
     960             : PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
     961             : PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
     962             : 
     963             : /*@C
     964             :   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
     965             : 
     966             :   Input Parameters:
     967             : + lhs  - The first number
     968             : . rhs  - The second number
     969             : . rtol - The relative tolerance
     970             : - atol - The absolute tolerance
     971             : 
     972             :   Level: beginner
     973             : 
     974             :   Note:
     975             :   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
     976             :   numbers.
     977             : 
     978             : .seealso: `PetscIsCloseAtTol()`
     979             : @*/
     980             : static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
     981             : {
     982             :   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
     983             : 
     984             :   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
     985             :   return close;
     986             : }
     987             : 
     988             : /*
     989             :     These macros are currently hardwired to match the regular data types, so there is no support for a different
     990             :     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
     991             :  */
     992             : #define MPIU_MATSCALAR MPIU_SCALAR
     993             : typedef PetscScalar MatScalar;
     994             : typedef PetscReal   MatReal;
     995             : 
     996             : struct petsc_mpiu_2scalar {
     997             :   PetscScalar a, b;
     998             : };
     999             : PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);
    1000             : 
    1001             : /* MPI Datatypes for composite reductions */
    1002             : struct petsc_mpiu_real_int {
    1003             :   PetscReal v;
    1004             :   PetscInt  i;
    1005             : };
    1006             : 
    1007             : struct petsc_mpiu_scalar_int {
    1008             :   PetscScalar v;
    1009             :   PetscInt    i;
    1010             : };
    1011             : 
    1012             : PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
    1013             : PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
    1014             : 
    1015             : #if defined(PETSC_USE_64BIT_INDICES)
    1016             : struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
    1017             :   PetscInt a;
    1018             :   PetscInt b;
    1019             : };
    1020             : struct __attribute__((packed)) petsc_mpiu_int_mpiint {
    1021             :   PetscInt    a;
    1022             :   PetscMPIInt b;
    1023             : };
    1024             : /*
    1025             :  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
    1026             :  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
    1027             :  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
    1028             : 
    1029             :  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
    1030             :  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
    1031             :  pass! So we just comment it out...
    1032             : */
    1033             : PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
    1034             : PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
    1035             : #else
    1036             :   #define MPIU_2INT       MPI_2INT
    1037             :   #define MPIU_INT_MPIINT MPI_2INT
    1038             : #endif
    1039             : PETSC_EXTERN MPI_Datatype MPI_4INT;
    1040             : PETSC_EXTERN MPI_Datatype MPIU_4INT;
    1041             : 
    1042         757 : static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
    1043             : {
    1044         757 :   PetscInt result = 1;
    1045        3613 :   while (power) {
    1046        2120 :     if (power & 1) result *= base;
    1047        2120 :     power >>= 1;
    1048        2120 :     if (power) base *= base;
    1049             :   }
    1050        1493 :   return result;
    1051             : }
    1052             : 
    1053             : static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
    1054             : {
    1055             :   PetscInt64 result = 1;
    1056             :   while (power) {
    1057             :     if (power & 1) result *= base;
    1058             :     power >>= 1;
    1059             :     if (power) base *= base;
    1060             :   }
    1061             :   return result;
    1062             : }
    1063             : 
    1064       26569 : static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
    1065             : {
    1066       26569 :   PetscReal result = 1;
    1067       26569 :   if (power < 0) {
    1068         402 :     power = -power;
    1069         402 :     base  = ((PetscReal)1) / base;
    1070             :   }
    1071       80879 :   while (power) {
    1072       54310 :     if (power & 1) result *= base;
    1073       54310 :     power >>= 1;
    1074       54310 :     if (power) base *= base;
    1075             :   }
    1076       26569 :   return result;
    1077             : }
    1078             : 
    1079       26135 : static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
    1080             : {
    1081       26135 :   PetscScalar result = (PetscReal)1;
    1082       26135 :   if (power < 0) {
    1083          22 :     power = -power;
    1084          22 :     base  = ((PetscReal)1) / base;
    1085             :   }
    1086       78384 :   while (power) {
    1087       52249 :     if (power & 1) result *= base;
    1088       52249 :     power >>= 1;
    1089       52249 :     if (power) base *= base;
    1090             :   }
    1091       26135 :   return result;
    1092             : }
    1093             : 
    1094         154 : static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
    1095             : {
    1096         154 :   PetscScalar cpower = power;
    1097         154 :   return PetscPowScalar(base, cpower);
    1098             : }
    1099             : 
    1100             : /*MC
    1101             :    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
    1102             : 
    1103             :    Synopsis:
    1104             :    #include <petscmath.h>
    1105             :    bool PetscApproximateLTE(PetscReal x,constant float)
    1106             : 
    1107             :    Not Collective
    1108             : 
    1109             :    Input Parameters:
    1110             : +   x - the variable
    1111             : -   b - the constant float it is checking if `x` is less than or equal to
    1112             : 
    1113             :    Level: advanced
    1114             : 
    1115             :    Notes:
    1116             :    The fudge factor is the value `PETSC_SMALL`
    1117             : 
    1118             :    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
    1119             : 
    1120             :    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
    1121             :    floating point results.
    1122             : 
    1123             :    Example\:
    1124             : .vb
    1125             :   PetscReal x;
    1126             :   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
    1127             : .ve
    1128             : 
    1129             : .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
    1130             : M*/
    1131             : #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
    1132             : 
    1133             : /*MC
    1134             :    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
    1135             : 
    1136             :    Synopsis:
    1137             :    #include <petscmath.h>
    1138             :    bool PetscApproximateGTE(PetscReal x,constant float)
    1139             : 
    1140             :    Not Collective
    1141             : 
    1142             :    Input Parameters:
    1143             : +   x - the variable
    1144             : -   b - the constant float it is checking if `x` is greater than or equal to
    1145             : 
    1146             :    Level: advanced
    1147             : 
    1148             :    Notes:
    1149             :    The fudge factor is the value `PETSC_SMALL`
    1150             : 
    1151             :    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
    1152             : 
    1153             :    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
    1154             :    floating point results.
    1155             : 
    1156             :    Example\:
    1157             : .vb
    1158             :   PetscReal x;
    1159             :   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
    1160             : .ve
    1161             : 
    1162             : .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    1163             : M*/
    1164             : #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
    1165             : 
    1166             : /*@C
    1167             :    PetscCeilInt - Returns the ceiling of the quotation of two positive integers
    1168             : 
    1169             :    Not Collective
    1170             : 
    1171             :    Input Parameters:
    1172             : +   x - the numerator
    1173             : -   y - the denominator
    1174             : 
    1175             :    Level: advanced
    1176             : 
    1177             :   Example\:
    1178             : .vb
    1179             :   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
    1180             : .ve
    1181             : 
    1182             : .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    1183             : @*/
    1184             : static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
    1185             : {
    1186             :   return x / y + (x % y ? 1 : 0);
    1187             : }
    1188             : 
    1189             : /*@C
    1190             :    PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers
    1191             : 
    1192             :    Not Collective
    1193             : 
    1194             :    Input Parameters:
    1195             : +   x - the numerator
    1196             : -   y - the denominator
    1197             : 
    1198             :    Level: advanced
    1199             : 
    1200             :   Example\:
    1201             : .vb
    1202             :   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
    1203             : .ve
    1204             : 
    1205             : .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
    1206             : @*/
    1207             : static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
    1208             : {
    1209             :   return x / y + (x % y ? 1 : 0);
    1210             : }
    1211             : 
    1212             : PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);

Generated by: LCOV version 1.14