xref: /petsc/include/petscmath.h (revision 8f75537a422a1ef498528edf8aab5af730cd6d34)
1e489efc1SBarry Smith /*
2314da920SBarry Smith     PETSc mathematics include file. Defines certain basic mathematical
3a5057860SBarry Smith     constants and functions for working with single, double, and quad precision
4a5057860SBarry Smith     floating point numbers as well as complex single and double.
5314da920SBarry Smith 
6d382aafbSBarry Smith     This file is included by petscsys.h and should not be used directly.
7e489efc1SBarry Smith */
8a4963045SJacob Faibussowitsch #pragma once
9ac09b921SBarry Smith 
100a5f7794SBarry Smith #include <math.h>
1193d501b3SJacob Faibussowitsch #include <petscmacros.h>
12df4397b0SStefano Zampini #include <petscsystypes.h>
13df4397b0SStefano Zampini 
14ac09b921SBarry Smith /* SUBMANSEC = Sys */
15ac09b921SBarry Smith 
165117d392SLisandro Dalcin /*
175117d392SLisandro Dalcin    Defines operations that are different for complex and real numbers.
185117d392SLisandro Dalcin    All PETSc objects in one program are built around the object
195117d392SLisandro Dalcin    PetscScalar which is either always a real or a complex.
205117d392SLisandro Dalcin */
215117d392SLisandro Dalcin 
225117d392SLisandro Dalcin /*
235117d392SLisandro Dalcin     Real number definitions
245117d392SLisandro Dalcin  */
255117d392SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
265117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtf(a)
275117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtf(a)
285117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotf(a, b)
295117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2f(a, b)
305117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powf(a, b)
315117d392SLisandro Dalcin   #define PetscExpReal(a)         expf(a)
325117d392SLisandro Dalcin   #define PetscLogReal(a)         logf(a)
335117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10f(a)
345117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2f(a)
355117d392SLisandro Dalcin   #define PetscSinReal(a)         sinf(a)
365117d392SLisandro Dalcin   #define PetscCosReal(a)         cosf(a)
375117d392SLisandro Dalcin   #define PetscTanReal(a)         tanf(a)
385117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinf(a)
395117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosf(a)
405117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanf(a)
415117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhf(a)
425117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshf(a)
435117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhf(a)
445117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhf(a)
455117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshf(a)
465117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhf(a)
47d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erff(a)
485117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilf(a)
495117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorf(a)
50b0129811SMatthew G. Knepley   #define PetscRintReal(a)        rintf(a)
515117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
529c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignf(a, b)
535117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaf(a)
541f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
551f17fa70SToby Isaac     #define PetscLGamma(a) gammaf(a)
561f17fa70SToby Isaac   #else
571f17fa70SToby Isaac     #define PetscLGamma(a) lgammaf(a)
581f17fa70SToby Isaac   #endif
595117d392SLisandro Dalcin 
605117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
615117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrt(a)
625117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrt(a)
635117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypot(a, b)
645117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2(a, b)
655117d392SLisandro Dalcin   #define PetscPowReal(a, b)      pow(a, b)
665117d392SLisandro Dalcin   #define PetscExpReal(a)         exp(a)
675117d392SLisandro Dalcin   #define PetscLogReal(a)         log(a)
685117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10(a)
695117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2(a)
705117d392SLisandro Dalcin   #define PetscSinReal(a)         sin(a)
715117d392SLisandro Dalcin   #define PetscCosReal(a)         cos(a)
725117d392SLisandro Dalcin   #define PetscTanReal(a)         tan(a)
735117d392SLisandro Dalcin   #define PetscAsinReal(a)        asin(a)
745117d392SLisandro Dalcin   #define PetscAcosReal(a)        acos(a)
755117d392SLisandro Dalcin   #define PetscAtanReal(a)        atan(a)
765117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinh(a)
775117d392SLisandro Dalcin   #define PetscCoshReal(a)        cosh(a)
785117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanh(a)
795117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinh(a)
805117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acosh(a)
815117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanh(a)
82d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erf(a)
835117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceil(a)
845117d392SLisandro Dalcin   #define PetscFloorReal(a)       floor(a)
85b0129811SMatthew G. Knepley   #define PetscRintReal(a)        rint(a)
865117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmod(a, b)
879c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysign(a, b)
885117d392SLisandro Dalcin   #define PetscTGamma(a)          tgamma(a)
891f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
901f17fa70SToby Isaac     #define PetscLGamma(a) gamma(a)
911f17fa70SToby Isaac   #else
921f17fa70SToby Isaac     #define PetscLGamma(a) lgamma(a)
931f17fa70SToby Isaac   #endif
945117d392SLisandro Dalcin 
955117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
965117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtq(a)
975117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtq(a)
985117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotq(a, b)
995117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2q(a, b)
1005117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powq(a, b)
1015117d392SLisandro Dalcin   #define PetscExpReal(a)         expq(a)
1025117d392SLisandro Dalcin   #define PetscLogReal(a)         logq(a)
1035117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10q(a)
1045117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2q(a)
1055117d392SLisandro Dalcin   #define PetscSinReal(a)         sinq(a)
1065117d392SLisandro Dalcin   #define PetscCosReal(a)         cosq(a)
1075117d392SLisandro Dalcin   #define PetscTanReal(a)         tanq(a)
1085117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinq(a)
1095117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosq(a)
1105117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanq(a)
1115117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhq(a)
1125117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshq(a)
1135117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhq(a)
1145117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhq(a)
1155117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshq(a)
1165117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhq(a)
117d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erfq(a)
1185117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilq(a)
1195117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorq(a)
120b0129811SMatthew G. Knepley   #define PetscRintReal(a)        rintq(a)
1215117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodq(a, b)
1229c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignq(a, b)
1235117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaq(a)
1241f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
1251f17fa70SToby Isaac     #define PetscLGamma(a) gammaq(a)
1261f17fa70SToby Isaac   #else
1271f17fa70SToby Isaac     #define PetscLGamma(a) lgammaq(a)
1281f17fa70SToby Isaac   #endif
1295117d392SLisandro Dalcin 
1305117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
1315117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtf(a)
1325117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtf(a)
1335117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotf(a, b)
1345117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2f(a, b)
1355117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powf(a, b)
1365117d392SLisandro Dalcin   #define PetscExpReal(a)         expf(a)
1375117d392SLisandro Dalcin   #define PetscLogReal(a)         logf(a)
1385117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10f(a)
1395117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2f(a)
1405117d392SLisandro Dalcin   #define PetscSinReal(a)         sinf(a)
1415117d392SLisandro Dalcin   #define PetscCosReal(a)         cosf(a)
1425117d392SLisandro Dalcin   #define PetscTanReal(a)         tanf(a)
1435117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinf(a)
1445117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosf(a)
1455117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanf(a)
1465117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhf(a)
1475117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshf(a)
1485117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhf(a)
1495117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhf(a)
1505117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshf(a)
1515117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhf(a)
152d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erff(a)
1535117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilf(a)
1545117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorf(a)
155b0129811SMatthew G. Knepley   #define PetscRintReal(a)        rintf(a)
1565117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
157ea007c46SStefano Zampini   #define PetscCopysignReal(a, b) copysignf(a, b)
1585117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaf(a)
1591f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
1601f17fa70SToby Isaac     #define PetscLGamma(a) gammaf(a)
1611f17fa70SToby Isaac   #else
1621f17fa70SToby Isaac     #define PetscLGamma(a) lgammaf(a)
1631f17fa70SToby Isaac   #endif
1645117d392SLisandro Dalcin 
1655117d392SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
1665117d392SLisandro Dalcin 
PetscSignReal(PetscReal a)167d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscSignReal(PetscReal a)
168d71ae5a4SJacob Faibussowitsch {
1695117d392SLisandro Dalcin   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
1705117d392SLisandro Dalcin }
1715117d392SLisandro Dalcin 
1725117d392SLisandro Dalcin #if !defined(PETSC_HAVE_LOG2)
1735117d392SLisandro Dalcin   #undef PetscLog2Real
PetscLog2Real(PetscReal a)174d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscLog2Real(PetscReal a)
175d71ae5a4SJacob Faibussowitsch {
1765117d392SLisandro Dalcin   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
1775117d392SLisandro Dalcin }
1785117d392SLisandro Dalcin #endif
1795117d392SLisandro Dalcin 
180a2498233SPierre Jolivet #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
18193d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
1825117d392SLisandro Dalcin #endif
183a2498233SPierre Jolivet #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
18493d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
1855117d392SLisandro Dalcin #endif
1865117d392SLisandro Dalcin 
187df4397b0SStefano Zampini /*MC
18887497f52SBarry Smith    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in
189df4397b0SStefano Zampini 
190df4397b0SStefano Zampini    Level: beginner
191df4397b0SStefano Zampini 
192af27ebaaSBarry Smith    Note:
193af27ebaaSBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
194af27ebaaSBarry Smith 
195db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
196df4397b0SStefano Zampini M*/
197c1d390e3SJed Brown #if defined(PETSC_USE_REAL_SINGLE)
198c1d390e3SJed Brown   #define MPIU_REAL MPI_FLOAT
199c1d390e3SJed Brown #elif defined(PETSC_USE_REAL_DOUBLE)
200c1d390e3SJed Brown   #define MPIU_REAL MPI_DOUBLE
201c1d390e3SJed Brown #elif defined(PETSC_USE_REAL___FLOAT128)
202c1d390e3SJed Brown   #define MPIU_REAL MPIU___FLOAT128
203570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16)
204570b7f6dSBarry Smith   #define MPIU_REAL MPIU___FP16
205c1d390e3SJed Brown #endif /* PETSC_USE_REAL_* */
20659cb5930SBarry Smith 
2071093a601SBarry Smith /*
2081093a601SBarry Smith     Complex number definitions
2091093a601SBarry Smith  */
210df4397b0SStefano Zampini #if defined(PETSC_HAVE_COMPLEX)
211450fc7c9SSatish Balay   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
2121093a601SBarry Smith   /* C++ support of complex number */
213b7940d39SSatish Balay 
2149fa27a79SStefano Zampini     #define PetscRealPartComplex(a)      (static_cast<PetscComplex>(a)).real()
2159fa27a79SStefano Zampini     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
2169fa27a79SStefano Zampini     #define PetscAbsComplex(a)           petsccomplexlib::abs(static_cast<PetscComplex>(a))
2179fa27a79SStefano Zampini     #define PetscArgComplex(a)           petsccomplexlib::arg(static_cast<PetscComplex>(a))
2189fa27a79SStefano Zampini     #define PetscConjComplex(a)          petsccomplexlib::conj(static_cast<PetscComplex>(a))
2199fa27a79SStefano Zampini     #define PetscSqrtComplex(a)          petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
2209fa27a79SStefano Zampini     #define PetscPowComplex(a, b)        petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
2219fa27a79SStefano Zampini     #define PetscExpComplex(a)           petsccomplexlib::exp(static_cast<PetscComplex>(a))
2229fa27a79SStefano Zampini     #define PetscLogComplex(a)           petsccomplexlib::log(static_cast<PetscComplex>(a))
2239fa27a79SStefano Zampini     #define PetscSinComplex(a)           petsccomplexlib::sin(static_cast<PetscComplex>(a))
2249fa27a79SStefano Zampini     #define PetscCosComplex(a)           petsccomplexlib::cos(static_cast<PetscComplex>(a))
2259fa27a79SStefano Zampini     #define PetscTanComplex(a)           petsccomplexlib::tan(static_cast<PetscComplex>(a))
2269fa27a79SStefano Zampini     #define PetscAsinComplex(a)          petsccomplexlib::asin(static_cast<PetscComplex>(a))
2279fa27a79SStefano Zampini     #define PetscAcosComplex(a)          petsccomplexlib::acos(static_cast<PetscComplex>(a))
2289fa27a79SStefano Zampini     #define PetscAtanComplex(a)          petsccomplexlib::atan(static_cast<PetscComplex>(a))
2299fa27a79SStefano Zampini     #define PetscSinhComplex(a)          petsccomplexlib::sinh(static_cast<PetscComplex>(a))
2309fa27a79SStefano Zampini     #define PetscCoshComplex(a)          petsccomplexlib::cosh(static_cast<PetscComplex>(a))
2319fa27a79SStefano Zampini     #define PetscTanhComplex(a)          petsccomplexlib::tanh(static_cast<PetscComplex>(a))
2329fa27a79SStefano Zampini     #define PetscAsinhComplex(a)         petsccomplexlib::asinh(static_cast<PetscComplex>(a))
2339fa27a79SStefano Zampini     #define PetscAcoshComplex(a)         petsccomplexlib::acosh(static_cast<PetscComplex>(a))
2349fa27a79SStefano Zampini     #define PetscAtanhComplex(a)         petsccomplexlib::atanh(static_cast<PetscComplex>(a))
2355117d392SLisandro Dalcin 
2365117d392SLisandro Dalcin   /* TODO: Add configure tests
2375117d392SLisandro Dalcin 
2385117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
2395117d392SLisandro Dalcin #undef PetscTanComplex
2409fbee547SJacob Faibussowitsch static inline PetscComplex PetscTanComplex(PetscComplex z)
2415117d392SLisandro Dalcin {
2425117d392SLisandro Dalcin   return PetscSinComplex(z)/PetscCosComplex(z);
2435117d392SLisandro Dalcin }
244027d9794SBarry Smith #endif
245debe9ee2SPaul Mullowney 
2465117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
2475117d392SLisandro Dalcin #undef PetscTanhComplex
2489fbee547SJacob Faibussowitsch static inline PetscComplex PetscTanhComplex(PetscComplex z)
2495117d392SLisandro Dalcin {
2505117d392SLisandro Dalcin   return PetscSinhComplex(z)/PetscCoshComplex(z);
2515117d392SLisandro Dalcin }
2525117d392SLisandro Dalcin #endif
2535117d392SLisandro Dalcin 
2545117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
2555117d392SLisandro Dalcin #undef PetscAsinComplex
2569fbee547SJacob Faibussowitsch static inline PetscComplex PetscAsinComplex(PetscComplex z)
2575117d392SLisandro Dalcin {
2585117d392SLisandro Dalcin   const PetscComplex j(0,1);
2595117d392SLisandro Dalcin   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
2605117d392SLisandro Dalcin }
2615117d392SLisandro Dalcin #endif
2625117d392SLisandro Dalcin 
2635117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
2645117d392SLisandro Dalcin #undef PetscAcosComplex
2659fbee547SJacob Faibussowitsch static inline PetscComplex PetscAcosComplex(PetscComplex z)
2665117d392SLisandro Dalcin {
2675117d392SLisandro Dalcin   const PetscComplex j(0,1);
2685117d392SLisandro Dalcin   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
2695117d392SLisandro Dalcin }
2705117d392SLisandro Dalcin #endif
2715117d392SLisandro Dalcin 
2725117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
2735117d392SLisandro Dalcin #undef PetscAtanComplex
2749fbee547SJacob Faibussowitsch static inline PetscComplex PetscAtanComplex(PetscComplex z)
2755117d392SLisandro Dalcin {
2765117d392SLisandro Dalcin   const PetscComplex j(0,1);
2775117d392SLisandro Dalcin   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
2785117d392SLisandro Dalcin }
2795117d392SLisandro Dalcin #endif
2805117d392SLisandro Dalcin 
2815117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
2825117d392SLisandro Dalcin #undef PetscAsinhComplex
2839fbee547SJacob Faibussowitsch static inline PetscComplex PetscAsinhComplex(PetscComplex z)
2845117d392SLisandro Dalcin {
2855117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
2865117d392SLisandro Dalcin }
2875117d392SLisandro Dalcin #endif
2885117d392SLisandro Dalcin 
2895117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
2905117d392SLisandro Dalcin #undef PetscAcoshComplex
2919fbee547SJacob Faibussowitsch static inline PetscComplex PetscAcoshComplex(PetscComplex z)
2925117d392SLisandro Dalcin {
2935117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
2945117d392SLisandro Dalcin }
2955117d392SLisandro Dalcin #endif
2965117d392SLisandro Dalcin 
2975117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
2985117d392SLisandro Dalcin #undef PetscAtanhComplex
2999fbee547SJacob Faibussowitsch static inline PetscComplex PetscAtanhComplex(PetscComplex z)
3005117d392SLisandro Dalcin {
3015117d392SLisandro Dalcin   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
3025117d392SLisandro Dalcin }
3035117d392SLisandro Dalcin #endif
3045117d392SLisandro Dalcin 
3055117d392SLisandro Dalcin */
3065117d392SLisandro Dalcin 
3077a19d461SSatish Balay   #else /* C99 support of complex number */
308519e2a1fSPaul Mullowney 
3097a19d461SSatish Balay     #if defined(PETSC_USE_REAL_SINGLE)
31050f81f78SJed Brown       #define PetscRealPartComplex(a)      crealf(a)
31150f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimagf(a)
31250f81f78SJed Brown       #define PetscAbsComplex(a)           cabsf(a)
3135117d392SLisandro Dalcin       #define PetscArgComplex(a)           cargf(a)
31450f81f78SJed Brown       #define PetscConjComplex(a)          conjf(a)
31550f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrtf(a)
31650f81f78SJed Brown       #define PetscPowComplex(a, b)        cpowf(a, b)
31750f81f78SJed Brown       #define PetscExpComplex(a)           cexpf(a)
31850f81f78SJed Brown       #define PetscLogComplex(a)           clogf(a)
31950f81f78SJed Brown       #define PetscSinComplex(a)           csinf(a)
32050f81f78SJed Brown       #define PetscCosComplex(a)           ccosf(a)
3215117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctanf(a)
322255453a1SBarry Smith       #define PetscAsinComplex(a)          casinf(a)
323255453a1SBarry Smith       #define PetscAcosComplex(a)          cacosf(a)
3245117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catanf(a)
325a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinhf(a)
326a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccoshf(a)
327a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanhf(a)
3285117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinhf(a)
3295117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacoshf(a)
3305117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanhf(a)
3311093a601SBarry Smith 
332ce63c4c1SBarry Smith     #elif defined(PETSC_USE_REAL_DOUBLE)
33350f81f78SJed Brown       #define PetscRealPartComplex(a)      creal(a)
33450f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimag(a)
33550f81f78SJed Brown       #define PetscAbsComplex(a)           cabs(a)
3365117d392SLisandro Dalcin       #define PetscArgComplex(a)           carg(a)
33750f81f78SJed Brown       #define PetscConjComplex(a)          conj(a)
33850f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrt(a)
33950f81f78SJed Brown       #define PetscPowComplex(a, b)        cpow(a, b)
34050f81f78SJed Brown       #define PetscExpComplex(a)           cexp(a)
34150f81f78SJed Brown       #define PetscLogComplex(a)           clog(a)
34250f81f78SJed Brown       #define PetscSinComplex(a)           csin(a)
34350f81f78SJed Brown       #define PetscCosComplex(a)           ccos(a)
3445117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctan(a)
345255453a1SBarry Smith       #define PetscAsinComplex(a)          casin(a)
346255453a1SBarry Smith       #define PetscAcosComplex(a)          cacos(a)
3475117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catan(a)
348a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinh(a)
349a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccosh(a)
350a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanh(a)
3515117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinh(a)
3525117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacosh(a)
3535117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanh(a)
3541093a601SBarry Smith 
3558c764dc5SJose Roman     #elif defined(PETSC_USE_REAL___FLOAT128)
35650f81f78SJed Brown       #define PetscRealPartComplex(a)      crealq(a)
35750f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimagq(a)
35850f81f78SJed Brown       #define PetscAbsComplex(a)           cabsq(a)
3595117d392SLisandro Dalcin       #define PetscArgComplex(a)           cargq(a)
36050f81f78SJed Brown       #define PetscConjComplex(a)          conjq(a)
36150f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrtq(a)
36250f81f78SJed Brown       #define PetscPowComplex(a, b)        cpowq(a, b)
36350f81f78SJed Brown       #define PetscExpComplex(a)           cexpq(a)
36450f81f78SJed Brown       #define PetscLogComplex(a)           clogq(a)
36550f81f78SJed Brown       #define PetscSinComplex(a)           csinq(a)
36650f81f78SJed Brown       #define PetscCosComplex(a)           ccosq(a)
3675117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctanq(a)
368255453a1SBarry Smith       #define PetscAsinComplex(a)          casinq(a)
369255453a1SBarry Smith       #define PetscAcosComplex(a)          cacosq(a)
3705117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catanq(a)
371a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinhq(a)
372a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccoshq(a)
373a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanhq(a)
3745117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinhq(a)
3755117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacoshq(a)
3765117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanhq(a)
377a4bea5a6SPeter Brune 
378ce63c4c1SBarry Smith     #endif /* PETSC_USE_REAL_* */
3797a19d461SSatish Balay   #endif   /* (__cplusplus) */
380e489efc1SBarry Smith 
3813919e044SBarry Smith /*MC
3823919e044SBarry Smith    PETSC_i - the pure imaginary complex number i
3833919e044SBarry Smith 
3843919e044SBarry Smith    Level: intermediate
3853919e044SBarry Smith 
3863919e044SBarry Smith .seealso: `PetscComplex`, `PetscScalar`
3873919e044SBarry Smith M*/
38850f81f78SJed Brown PETSC_EXTERN PetscComplex PETSC_i;
3898a351411SToby Isaac 
3905117d392SLisandro Dalcin /*
3915117d392SLisandro Dalcin    Try to do the right thing for complex number construction: see
3928a351411SToby Isaac    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
3938a351411SToby Isaac    for details
3948a351411SToby Isaac */
PetscCMPLX(PetscReal x,PetscReal y)395d71ae5a4SJacob Faibussowitsch static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
396d71ae5a4SJacob Faibussowitsch {
397450fc7c9SSatish Balay   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
3988a351411SToby Isaac   return PetscComplex(x, y);
3998a351411SToby Isaac   #elif defined(_Imaginary_I)
4008a351411SToby Isaac   return x + y * _Imaginary_I;
4018a351411SToby Isaac   #else
402616d7c5eSToby Isaac   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
403616d7c5eSToby Isaac 
404616d7c5eSToby Isaac        "For each floating type there is a corresponding real type, which is always a real floating
405616d7c5eSToby Isaac        type. For real floating types, it is the same type. For complex types, it is the type given
406616d7c5eSToby Isaac        by deleting the keyword _Complex from the type name."
407616d7c5eSToby Isaac 
408616d7c5eSToby Isaac        So type punning should be portable. */
4099371c9d4SSatish Balay     union
4109371c9d4SSatish Balay     {
4119371c9d4SSatish Balay       PetscComplex z;
4129371c9d4SSatish Balay       PetscReal    f[2];
4139371c9d4SSatish Balay     } uz;
414616d7c5eSToby Isaac 
415616d7c5eSToby Isaac     uz.f[0] = x;
416616d7c5eSToby Isaac     uz.f[1] = y;
417616d7c5eSToby Isaac     return uz.z;
418616d7c5eSToby Isaac   }
41950f81f78SJed Brown   #endif
4208a351411SToby Isaac }
4218a351411SToby Isaac 
422edd03b47SJacob Faibussowitsch   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
423edd03b47SJacob Faibussowitsch   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )
424de272c7aSSatish Balay 
425a2498233SPierre Jolivet   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
42693d501b3SJacob Faibussowitsch     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
42793d501b3SJacob Faibussowitsch     #if defined(PETSC_USE_COMPLEX)
42893d501b3SJacob Faibussowitsch       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
42993d501b3SJacob Faibussowitsch     #else
43093d501b3SJacob Faibussowitsch       #define MPIU___COMPLEX128_ATTR_TAG
43193d501b3SJacob Faibussowitsch     #endif
43293d501b3SJacob Faibussowitsch 
43393d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;
43493d501b3SJacob Faibussowitsch 
43593d501b3SJacob Faibussowitsch     #undef MPIU___COMPLEX128_ATTR_TAG
436613bf2b2SPierre Jolivet   #endif /* PETSC_HAVE_REAL___FLOAT128 */
4375117d392SLisandro Dalcin 
4385117d392SLisandro Dalcin   /*MC
43987497f52SBarry Smith    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`
4405117d392SLisandro Dalcin 
4415117d392SLisandro Dalcin    Level: beginner
4425117d392SLisandro Dalcin 
44395bd0b28SBarry Smith    Note:
44495bd0b28SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
44595bd0b28SBarry Smith 
446db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
4475117d392SLisandro Dalcin M*/
4485117d392SLisandro Dalcin   #if defined(PETSC_USE_REAL_SINGLE)
449de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_COMPLEX
4505117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL_DOUBLE)
451de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
4525117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL___FLOAT128)
4535117d392SLisandro Dalcin     #define MPIU_COMPLEX MPIU___COMPLEX128
4545117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL___FP16)
455de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_COMPLEX
4565117d392SLisandro Dalcin   #endif /* PETSC_USE_REAL_* */
4575117d392SLisandro Dalcin 
4585117d392SLisandro Dalcin #endif /* PETSC_HAVE_COMPLEX */
4595117d392SLisandro Dalcin 
4605117d392SLisandro Dalcin /*
4615117d392SLisandro Dalcin     Scalar number definitions
4625117d392SLisandro Dalcin  */
4637a19d461SSatish Balay #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
4645117d392SLisandro Dalcin   /*MC
46587497f52SBarry Smith    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`
4665117d392SLisandro Dalcin 
4675117d392SLisandro Dalcin    Level: beginner
4685117d392SLisandro Dalcin 
46995bd0b28SBarry Smith    Note:
47095bd0b28SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
47195bd0b28SBarry Smith 
472db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
4735117d392SLisandro Dalcin M*/
4745117d392SLisandro Dalcin   #define MPIU_SCALAR MPIU_COMPLEX
4755117d392SLisandro Dalcin 
4765117d392SLisandro Dalcin   /*MC
47787497f52SBarry Smith    PetscRealPart - Returns the real part of a `PetscScalar`
4785117d392SLisandro Dalcin 
4795117d392SLisandro Dalcin    Synopsis:
4805117d392SLisandro Dalcin    #include <petscmath.h>
4815117d392SLisandro Dalcin    PetscReal PetscRealPart(PetscScalar v)
4825117d392SLisandro Dalcin 
4835117d392SLisandro Dalcin    Not Collective
4845117d392SLisandro Dalcin 
4855117d392SLisandro Dalcin    Input Parameter:
4865117d392SLisandro Dalcin .  v - value to find the real part of
4875117d392SLisandro Dalcin 
4885117d392SLisandro Dalcin    Level: beginner
4895117d392SLisandro Dalcin 
490db781477SPatrick Sanan .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
4915117d392SLisandro Dalcin M*/
4925117d392SLisandro Dalcin   #define PetscRealPart(a) PetscRealPartComplex(a)
4935117d392SLisandro Dalcin 
4945117d392SLisandro Dalcin   /*MC
49587497f52SBarry Smith    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`
4965117d392SLisandro Dalcin 
4975117d392SLisandro Dalcin    Synopsis:
4985117d392SLisandro Dalcin    #include <petscmath.h>
4995117d392SLisandro Dalcin    PetscReal PetscImaginaryPart(PetscScalar v)
5005117d392SLisandro Dalcin 
5015117d392SLisandro Dalcin    Not Collective
5025117d392SLisandro Dalcin 
5035117d392SLisandro Dalcin    Input Parameter:
5045117d392SLisandro Dalcin .  v - value to find the imaginary part of
5055117d392SLisandro Dalcin 
5065117d392SLisandro Dalcin    Level: beginner
5075117d392SLisandro Dalcin 
50895bd0b28SBarry Smith    Note:
5095117d392SLisandro Dalcin    If PETSc was configured for real numbers then this always returns the value 0
5105117d392SLisandro Dalcin 
511db781477SPatrick Sanan .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
5125117d392SLisandro Dalcin M*/
5135117d392SLisandro Dalcin   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
5145117d392SLisandro Dalcin 
5155117d392SLisandro Dalcin   #define PetscAbsScalar(a)    PetscAbsComplex(a)
5165117d392SLisandro Dalcin   #define PetscArgScalar(a)    PetscArgComplex(a)
5175117d392SLisandro Dalcin   #define PetscConj(a)         PetscConjComplex(a)
5185117d392SLisandro Dalcin   #define PetscSqrtScalar(a)   PetscSqrtComplex(a)
5195117d392SLisandro Dalcin   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
5205117d392SLisandro Dalcin   #define PetscExpScalar(a)    PetscExpComplex(a)
5215117d392SLisandro Dalcin   #define PetscLogScalar(a)    PetscLogComplex(a)
5225117d392SLisandro Dalcin   #define PetscSinScalar(a)    PetscSinComplex(a)
5235117d392SLisandro Dalcin   #define PetscCosScalar(a)    PetscCosComplex(a)
5245117d392SLisandro Dalcin   #define PetscTanScalar(a)    PetscTanComplex(a)
5255117d392SLisandro Dalcin   #define PetscAsinScalar(a)   PetscAsinComplex(a)
5265117d392SLisandro Dalcin   #define PetscAcosScalar(a)   PetscAcosComplex(a)
5275117d392SLisandro Dalcin   #define PetscAtanScalar(a)   PetscAtanComplex(a)
5285117d392SLisandro Dalcin   #define PetscSinhScalar(a)   PetscSinhComplex(a)
5295117d392SLisandro Dalcin   #define PetscCoshScalar(a)   PetscCoshComplex(a)
5305117d392SLisandro Dalcin   #define PetscTanhScalar(a)   PetscTanhComplex(a)
5315117d392SLisandro Dalcin   #define PetscAsinhScalar(a)  PetscAsinhComplex(a)
5325117d392SLisandro Dalcin   #define PetscAcoshScalar(a)  PetscAcoshComplex(a)
5335117d392SLisandro Dalcin   #define PetscAtanhScalar(a)  PetscAtanhComplex(a)
5345117d392SLisandro Dalcin 
5355117d392SLisandro Dalcin #else /* PETSC_USE_COMPLEX */
5365117d392SLisandro Dalcin   #define MPIU_SCALAR           MPIU_REAL
5375117d392SLisandro Dalcin   #define PetscRealPart(a)      (a)
5385117d392SLisandro Dalcin   #define PetscImaginaryPart(a) ((PetscReal)0)
5395117d392SLisandro Dalcin   #define PetscAbsScalar(a)     PetscAbsReal(a)
5405117d392SLisandro Dalcin   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
5415117d392SLisandro Dalcin   #define PetscConj(a)          (a)
5425117d392SLisandro Dalcin   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
5435117d392SLisandro Dalcin   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
5445117d392SLisandro Dalcin   #define PetscExpScalar(a)     PetscExpReal(a)
5455117d392SLisandro Dalcin   #define PetscLogScalar(a)     PetscLogReal(a)
5465117d392SLisandro Dalcin   #define PetscSinScalar(a)     PetscSinReal(a)
5475117d392SLisandro Dalcin   #define PetscCosScalar(a)     PetscCosReal(a)
5485117d392SLisandro Dalcin   #define PetscTanScalar(a)     PetscTanReal(a)
5495117d392SLisandro Dalcin   #define PetscAsinScalar(a)    PetscAsinReal(a)
5505117d392SLisandro Dalcin   #define PetscAcosScalar(a)    PetscAcosReal(a)
5515117d392SLisandro Dalcin   #define PetscAtanScalar(a)    PetscAtanReal(a)
5525117d392SLisandro Dalcin   #define PetscSinhScalar(a)    PetscSinhReal(a)
5535117d392SLisandro Dalcin   #define PetscCoshScalar(a)    PetscCoshReal(a)
5545117d392SLisandro Dalcin   #define PetscTanhScalar(a)    PetscTanhReal(a)
5555117d392SLisandro Dalcin   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
5565117d392SLisandro Dalcin   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
5575117d392SLisandro Dalcin   #define PetscAtanhScalar(a)   PetscAtanhReal(a)
5585117d392SLisandro Dalcin 
5595117d392SLisandro Dalcin #endif /* PETSC_USE_COMPLEX */
5605117d392SLisandro Dalcin 
5615117d392SLisandro Dalcin /*
5625117d392SLisandro Dalcin    Certain objects may be created using either single or double precision.
5635117d392SLisandro Dalcin    This is currently not used.
5645117d392SLisandro Dalcin */
5659371c9d4SSatish Balay typedef enum {
5669371c9d4SSatish Balay   PETSC_SCALAR_DOUBLE,
5679371c9d4SSatish Balay   PETSC_SCALAR_SINGLE,
5689371c9d4SSatish Balay   PETSC_SCALAR_LONG_DOUBLE,
5699371c9d4SSatish Balay   PETSC_SCALAR_HALF
5709371c9d4SSatish Balay } PetscScalarPrecision;
5715117d392SLisandro Dalcin 
5725117d392SLisandro Dalcin /*MC
5735117d392SLisandro Dalcin    PetscAbs - Returns the absolute value of a number
5745117d392SLisandro Dalcin 
5755117d392SLisandro Dalcin    Synopsis:
5765117d392SLisandro Dalcin    #include <petscmath.h>
5775117d392SLisandro Dalcin    type PetscAbs(type v)
5785117d392SLisandro Dalcin 
5795117d392SLisandro Dalcin    Not Collective
5805117d392SLisandro Dalcin 
5815117d392SLisandro Dalcin    Input Parameter:
5825117d392SLisandro Dalcin .  v - the number
5835117d392SLisandro Dalcin 
58416a05f60SBarry Smith    Level: beginner
58516a05f60SBarry Smith 
58687497f52SBarry Smith    Note:
58787497f52SBarry Smith    The type can be integer or real floating point value, but cannot be complex
5885117d392SLisandro Dalcin 
58916a05f60SBarry Smith .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
5905117d392SLisandro Dalcin M*/
5915117d392SLisandro Dalcin #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))
5925117d392SLisandro Dalcin 
5935117d392SLisandro Dalcin /*MC
5943919e044SBarry Smith    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1
5955117d392SLisandro Dalcin 
5965117d392SLisandro Dalcin    Synopsis:
5975117d392SLisandro Dalcin    #include <petscmath.h>
5985117d392SLisandro Dalcin    int PetscSign(type v)
5995117d392SLisandro Dalcin 
6005117d392SLisandro Dalcin    Not Collective
6015117d392SLisandro Dalcin 
6025117d392SLisandro Dalcin    Input Parameter:
6035117d392SLisandro Dalcin .  v - the number
6045117d392SLisandro Dalcin 
60516a05f60SBarry Smith    Level: beginner
60616a05f60SBarry Smith 
60787497f52SBarry Smith    Note:
60887497f52SBarry Smith    The type can be integer or real floating point value
6095117d392SLisandro Dalcin 
61016a05f60SBarry Smith .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
6115117d392SLisandro Dalcin M*/
6125117d392SLisandro Dalcin #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
613e489efc1SBarry Smith 
614b6a5bde7SBarry Smith /*MC
615b6a5bde7SBarry Smith    PetscMin - Returns minimum of two numbers
616b6a5bde7SBarry Smith 
617eca87e8dSBarry Smith    Synopsis:
618aaa7dc30SBarry Smith    #include <petscmath.h>
619eca87e8dSBarry Smith    type PetscMin(type v1,type v2)
620eca87e8dSBarry Smith 
621eca87e8dSBarry Smith    Not Collective
622eca87e8dSBarry Smith 
623d8d19677SJose E. Roman    Input Parameters:
624b6a5bde7SBarry Smith +  v1 - first value to find minimum of
625b6a5bde7SBarry Smith -  v2 - second value to find minimum of
626b6a5bde7SBarry Smith 
62716a05f60SBarry Smith    Level: beginner
62816a05f60SBarry Smith 
62987497f52SBarry Smith    Note:
6303919e044SBarry Smith    The type can be integer or floating point value, but cannot be complex
631b6a5bde7SBarry Smith 
632db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
633b6a5bde7SBarry Smith M*/
634e489efc1SBarry Smith #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))
635b6a5bde7SBarry Smith 
636b6a5bde7SBarry Smith /*MC
637d5b43468SJose E. Roman    PetscMax - Returns maximum of two numbers
638b6a5bde7SBarry Smith 
639eca87e8dSBarry Smith    Synopsis:
640aaa7dc30SBarry Smith    #include <petscmath.h>
641eca87e8dSBarry Smith    type max PetscMax(type v1,type v2)
642eca87e8dSBarry Smith 
643eca87e8dSBarry Smith    Not Collective
644eca87e8dSBarry Smith 
645d8d19677SJose E. Roman    Input Parameters:
646b6a5bde7SBarry Smith +  v1 - first value to find maximum of
647b6a5bde7SBarry Smith -  v2 - second value to find maximum of
648b6a5bde7SBarry Smith 
64916a05f60SBarry Smith    Level: beginner
65016a05f60SBarry Smith 
65187497f52SBarry Smith    Note:
65287497f52SBarry Smith    The type can be integer or floating point value
653b6a5bde7SBarry Smith 
654db781477SPatrick Sanan .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
655b6a5bde7SBarry Smith M*/
656e489efc1SBarry Smith #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))
657b6a5bde7SBarry Smith 
658b6a5bde7SBarry Smith /*MC
659d9a4bb16SJed Brown    PetscClipInterval - Returns a number clipped to be within an interval
660d9a4bb16SJed Brown 
661d9a4bb16SJed Brown    Synopsis:
662aaa7dc30SBarry Smith    #include <petscmath.h>
663d9a4bb16SJed Brown    type clip PetscClipInterval(type x,type a,type b)
664d9a4bb16SJed Brown 
665d9a4bb16SJed Brown    Not Collective
666d9a4bb16SJed Brown 
667d8d19677SJose E. Roman    Input Parameters:
6680d398bfeSStefano Zampini +  x - value to use if within interval [a,b]
669d9a4bb16SJed Brown .  a - lower end of interval
670d9a4bb16SJed Brown -  b - upper end of interval
671d9a4bb16SJed Brown 
67216a05f60SBarry Smith    Level: beginner
67316a05f60SBarry Smith 
67487497f52SBarry Smith    Note:
67587497f52SBarry Smith    The type can be integer or floating point value
676d9a4bb16SJed Brown 
6773919e044SBarry Smith    Example\:
6783919e044SBarry Smith .vb
6793919e044SBarry Smith   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
6803919e044SBarry Smith   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
6813919e044SBarry Smith .ve
6823919e044SBarry Smith 
683db781477SPatrick Sanan .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
684d9a4bb16SJed Brown M*/
685d9a4bb16SJed Brown #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
686d9a4bb16SJed Brown 
687d9a4bb16SJed Brown /*MC
688b6a5bde7SBarry Smith    PetscAbsInt - Returns the absolute value of an integer
689b6a5bde7SBarry Smith 
690b6a5bde7SBarry Smith    Synopsis:
691aaa7dc30SBarry Smith    #include <petscmath.h>
692b6a5bde7SBarry Smith    int abs PetscAbsInt(int v1)
693b6a5bde7SBarry Smith 
694eca87e8dSBarry Smith    Input Parameter:
695eca87e8dSBarry Smith .   v1 - the integer
696b6a5bde7SBarry Smith 
697b6a5bde7SBarry Smith    Level: beginner
698b6a5bde7SBarry Smith 
699db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
700b6a5bde7SBarry Smith M*/
7019fa7d148SSatish Balay #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
702b6a5bde7SBarry Smith 
703b6a5bde7SBarry Smith /*MC
704e2b46ddfSPierre Jolivet    PetscAbsReal - Returns the absolute value of a real number
705b6a5bde7SBarry Smith 
706eca87e8dSBarry Smith    Synopsis:
707aaa7dc30SBarry Smith    #include <petscmath.h>
708eca87e8dSBarry Smith    Real abs PetscAbsReal(PetscReal v1)
709eca87e8dSBarry Smith 
710b6a5bde7SBarry Smith    Input Parameter:
71116a05f60SBarry Smith .   v1 - the `PetscReal` value
712b6a5bde7SBarry Smith 
713b6a5bde7SBarry Smith    Level: beginner
714b6a5bde7SBarry Smith 
7153fb7ca22SBarry Smith .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
716b6a5bde7SBarry Smith M*/
7171118d4bcSLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
7181118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7191118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7201118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabs(a)
7211118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
7221118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsq(a)
7231118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7241118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7251118d4bcSLisandro Dalcin #endif
726b6a5bde7SBarry Smith 
727b6a5bde7SBarry Smith /*MC
728b6a5bde7SBarry Smith    PetscSqr - Returns the square of a number
729b6a5bde7SBarry Smith 
730b6a5bde7SBarry Smith    Synopsis:
731aaa7dc30SBarry Smith    #include <petscmath.h>
732b6a5bde7SBarry Smith    type sqr PetscSqr(type v1)
733b6a5bde7SBarry Smith 
734eca87e8dSBarry Smith    Not Collective
735eca87e8dSBarry Smith 
736eca87e8dSBarry Smith    Input Parameter:
737eca87e8dSBarry Smith .   v1 - the value
738eca87e8dSBarry Smith 
73916a05f60SBarry Smith    Level: beginner
74016a05f60SBarry Smith 
74187497f52SBarry Smith    Note:
7423919e044SBarry Smith    The type can be integer, floating point, or complex floating point
743b6a5bde7SBarry Smith 
744db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
745b6a5bde7SBarry Smith M*/
7464ebda54eSMatthew Knepley #define PetscSqr(a) ((a) * (a))
747e489efc1SBarry Smith 
7483fb7ca22SBarry Smith /*MC
7493fb7ca22SBarry Smith    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
7503fb7ca22SBarry Smith    precision of `PetscReal` be it half, single, double or 128-bit representation
7513fb7ca22SBarry Smith 
7523fb7ca22SBarry Smith    Synopsis:
7533fb7ca22SBarry Smith    #include <petscmath.h>
7543fb7ca22SBarry Smith    PetscReal PetscRealConstant(real_number)
7553fb7ca22SBarry Smith 
7563fb7ca22SBarry Smith    Not Collective
7573fb7ca22SBarry Smith 
7583fb7ca22SBarry Smith    Input Parameter:
7593fb7ca22SBarry Smith .   v1 - the real number, for example 1.5
7603fb7ca22SBarry Smith 
7613fb7ca22SBarry Smith    Level: beginner
7623fb7ca22SBarry Smith 
7633fb7ca22SBarry Smith    Note:
7643fb7ca22SBarry Smith    For example, if PETSc is configured with `--with-precision=__float128` and one writes
7653fb7ca22SBarry Smith .vb
7663fb7ca22SBarry Smith    PetscReal d = 1.5;
7673fb7ca22SBarry Smith .ve
76856087ca1SPierre Jolivet    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
7693fb7ca22SBarry Smith .vb
7703fb7ca22SBarry Smith    PetscReal d = PetscRealConstant(1.5);
7713fb7ca22SBarry Smith .ve
7723fb7ca22SBarry Smith 
7733fb7ca22SBarry Smith .seealso: `PetscReal`
7743fb7ca22SBarry Smith M*/
775ee223c85SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
776ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
7775117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7785117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant
779ee223c85SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
780ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##Q
7815117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7825117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
783ee223c85SLisandro Dalcin #endif
784ee223c85SLisandro Dalcin 
785314da920SBarry Smith /*
786d34fcf5fSBarry Smith      Basic constants
787314da920SBarry Smith */
7883fb7ca22SBarry Smith /*MC
7893fb7ca22SBarry Smith   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.
7903fb7ca22SBarry Smith 
7913fb7ca22SBarry Smith   Level: beginner
7923fb7ca22SBarry Smith 
7933fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
7943fb7ca22SBarry Smith M*/
7953fb7ca22SBarry Smith 
7963fb7ca22SBarry Smith /*MC
7973fb7ca22SBarry Smith   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.
7983fb7ca22SBarry Smith 
7993fb7ca22SBarry Smith   Level: beginner
8003fb7ca22SBarry Smith 
8013fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
8023fb7ca22SBarry Smith M*/
8033fb7ca22SBarry Smith 
8043fb7ca22SBarry Smith /*MC
8053fb7ca22SBarry Smith   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.
8063fb7ca22SBarry Smith 
8073fb7ca22SBarry Smith   Level: beginner
8083fb7ca22SBarry Smith 
8093fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
8103fb7ca22SBarry Smith M*/
8113fb7ca22SBarry Smith 
81221048c15SMatthew G. Knepley /*MC
81321048c15SMatthew G. Knepley   PETSC_E - the value of Euler's constant $ e $ to the correct precision of `PetscReal`.
81421048c15SMatthew G. Knepley 
81521048c15SMatthew G. Knepley   Level: beginner
81621048c15SMatthew G. Knepley 
81721048c15SMatthew G. Knepley .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
81821048c15SMatthew G. Knepley M*/
81921048c15SMatthew G. Knepley 
8202fab75feSLisandro Dalcin #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
8212fab75feSLisandro Dalcin #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
8227b156302SMatthew G. Knepley #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
82321048c15SMatthew G. Knepley #define PETSC_E     PetscRealConstant(2.7182818284590452353602874713526625)
824d34fcf5fSBarry Smith 
8253fb7ca22SBarry Smith /*MC
8263fb7ca22SBarry Smith   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`
8273fb7ca22SBarry Smith 
8283fb7ca22SBarry Smith   Level: beginner
8293fb7ca22SBarry Smith 
8303fb7ca22SBarry Smith .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8313fb7ca22SBarry Smith M*/
8323fb7ca22SBarry Smith 
8333fb7ca22SBarry Smith /*MC
8343fb7ca22SBarry Smith   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`
8353fb7ca22SBarry Smith 
8363fb7ca22SBarry Smith   Level: beginner
8373fb7ca22SBarry Smith 
8383fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8393fb7ca22SBarry Smith M*/
8403fb7ca22SBarry Smith 
8413fb7ca22SBarry Smith /*MC
8423fb7ca22SBarry Smith   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.
8433fb7ca22SBarry Smith 
8443fb7ca22SBarry Smith   Level: beginner
8453fb7ca22SBarry Smith 
8463fb7ca22SBarry Smith   Note:
8473fb7ca22SBarry Smith   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers
8483fb7ca22SBarry Smith 
8493fb7ca22SBarry Smith   Developer Note:
8503fb7ca22SBarry Smith   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.
8513fb7ca22SBarry Smith 
8523fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8533fb7ca22SBarry Smith M*/
8543fb7ca22SBarry Smith 
8553fb7ca22SBarry Smith /*MC
8563fb7ca22SBarry Smith   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`
8573fb7ca22SBarry Smith 
8583fb7ca22SBarry Smith   Level: beginner
8593fb7ca22SBarry Smith 
8603fb7ca22SBarry Smith   Note:
8613fb7ca22SBarry Smith   See <https://en.wikipedia.org/wiki/Machine_epsilon>
8623fb7ca22SBarry Smith 
8633fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8643fb7ca22SBarry Smith M*/
8653fb7ca22SBarry Smith 
8663fb7ca22SBarry Smith /*MC
8673fb7ca22SBarry Smith   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`
8683fb7ca22SBarry Smith 
8693fb7ca22SBarry Smith   Level: beginner
8703fb7ca22SBarry Smith 
8713fb7ca22SBarry Smith   Note:
8723fb7ca22SBarry Smith   See `PETSC_MACHINE_EPSILON`
8733fb7ca22SBarry Smith 
8743fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
8753fb7ca22SBarry Smith M*/
8763fb7ca22SBarry Smith 
8773fb7ca22SBarry Smith /*MC
8783fb7ca22SBarry Smith   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
8793fb7ca22SBarry Smith   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.
8803fb7ca22SBarry Smith 
8813fb7ca22SBarry Smith   Level: beginner
8823fb7ca22SBarry Smith 
8833fb7ca22SBarry Smith   Note:
8843fb7ca22SBarry Smith   See `PETSC_MACHINE_EPSILON`
8853fb7ca22SBarry Smith 
8863fb7ca22SBarry Smith .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
8873fb7ca22SBarry Smith          `PETSC_SQRT_MACHINE_EPSILON`
8883fb7ca22SBarry Smith M*/
8893fb7ca22SBarry Smith 
890ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
891ab824b78SBarry Smith   #define PETSC_MAX_REAL             3.40282346638528860e+38F
8929fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
893f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             1.1754944e-38F
89482a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
89582a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
896ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-5F
897ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE)
898ab824b78SBarry Smith   #define PETSC_MAX_REAL             1.7976931348623157e+308
8999fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
900f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             2.225073858507201e-308
90182a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
90282a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
903cf6e855fSSatish Balay   #define PETSC_SMALL                1.e-10
904ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128)
905ea345e14SBarry Smith   #define PETSC_MAX_REAL             FLT128_MAX
9069fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-FLT128_MAX)
907f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             FLT128_MIN
908d34fcf5fSBarry Smith   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
909ee223c85SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
910ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-20Q
9115117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
9125117d392SLisandro Dalcin   #define PETSC_MAX_REAL             65504.0F
9139fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
914f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             .00006103515625F
9155117d392SLisandro Dalcin   #define PETSC_MACHINE_EPSILON      .0009765625F
9165117d392SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON .03125F
9175117d392SLisandro Dalcin   #define PETSC_SMALL                5.e-3F
9189cf09972SJed Brown #endif
9193e523bebSBarry Smith 
920945b2ebdSBarry Smith /*MC
921945b2ebdSBarry Smith   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
922945b2ebdSBarry Smith 
923945b2ebdSBarry Smith   Level: intermediate
924945b2ebdSBarry Smith 
925945b2ebdSBarry Smith   Note:
926945b2ebdSBarry Smith   This is not the IEEE infinity value
927945b2ebdSBarry Smith 
928945b2ebdSBarry Smith .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
929945b2ebdSBarry Smith M*/
93025d0f998SSatish Balay #define PETSC_INFINITY (PETSC_MAX_REAL / 4)
931945b2ebdSBarry Smith 
932945b2ebdSBarry Smith /*MC
933945b2ebdSBarry Smith   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
934945b2ebdSBarry Smith 
935945b2ebdSBarry Smith   Level: intermediate
936945b2ebdSBarry Smith 
937945b2ebdSBarry Smith   Note:
938945b2ebdSBarry Smith   This is not the negative IEEE infinity value
939945b2ebdSBarry Smith 
940945b2ebdSBarry Smith .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
941945b2ebdSBarry Smith M*/
9429fa7d148SSatish Balay #define PETSC_NINFINITY (-PETSC_INFINITY)
943e270355aSBarry Smith 
9449f4f8022SLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
9453948c36eSLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
9468b49ba18SBarry Smith PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
PetscIsInfOrNanReal(PetscReal v)947d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
948d71ae5a4SJacob Faibussowitsch {
9499371c9d4SSatish Balay   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
9509371c9d4SSatish Balay }
PetscIsInfScalar(PetscScalar v)951d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfScalar(PetscScalar v)
952d71ae5a4SJacob Faibussowitsch {
9539371c9d4SSatish Balay   return PetscIsInfReal(PetscAbsScalar(v));
9549371c9d4SSatish Balay }
PetscIsNanScalar(PetscScalar v)955d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNanScalar(PetscScalar v)
956d71ae5a4SJacob Faibussowitsch {
9579371c9d4SSatish Balay   return PetscIsNanReal(PetscAbsScalar(v));
9589371c9d4SSatish Balay }
PetscIsInfOrNanScalar(PetscScalar v)959d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
960d71ae5a4SJacob Faibussowitsch {
9619371c9d4SSatish Balay   return PetscIsInfOrNanReal(PetscAbsScalar(v));
9629371c9d4SSatish Balay }
PetscIsNormalScalar(PetscScalar v)963d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNormalScalar(PetscScalar v)
964d71ae5a4SJacob Faibussowitsch {
9659371c9d4SSatish Balay   return PetscIsNormalReal(PetscAbsScalar(v));
9669371c9d4SSatish Balay }
9679a25a3ccSBarry Smith 
968b10005b4SLisandro Dalcin PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
969ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
970ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
971ce4818fdSLisandro Dalcin 
97228dd6638SJacob Faibussowitsch /*@C
97328dd6638SJacob Faibussowitsch   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
97428dd6638SJacob Faibussowitsch 
97528dd6638SJacob Faibussowitsch   Input Parameters:
97628dd6638SJacob Faibussowitsch + lhs  - The first number
97728dd6638SJacob Faibussowitsch . rhs  - The second number
97828dd6638SJacob Faibussowitsch . rtol - The relative tolerance
97928dd6638SJacob Faibussowitsch - atol - The absolute tolerance
98028dd6638SJacob Faibussowitsch 
98128dd6638SJacob Faibussowitsch   Level: beginner
98228dd6638SJacob Faibussowitsch 
98328dd6638SJacob Faibussowitsch   Note:
98428dd6638SJacob Faibussowitsch   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
98528dd6638SJacob Faibussowitsch   numbers.
98628dd6638SJacob Faibussowitsch 
98728dd6638SJacob Faibussowitsch .seealso: `PetscIsCloseAtTol()`
98828dd6638SJacob Faibussowitsch @*/
PetscIsCloseAtTolScalar(PetscScalar lhs,PetscScalar rhs,PetscReal rtol,PetscReal atol)98928dd6638SJacob Faibussowitsch static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
99028dd6638SJacob Faibussowitsch {
99128dd6638SJacob Faibussowitsch   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
99228dd6638SJacob Faibussowitsch 
99328dd6638SJacob Faibussowitsch   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
99428dd6638SJacob Faibussowitsch   return close;
99528dd6638SJacob Faibussowitsch }
99628dd6638SJacob Faibussowitsch 
99798725619SBarry Smith /*
99898725619SBarry Smith     These macros are currently hardwired to match the regular data types, so there is no support for a different
99998725619SBarry Smith     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
100098725619SBarry Smith  */
100198725619SBarry Smith #define MPIU_MATSCALAR MPIU_SCALAR
100298725619SBarry Smith typedef PetscScalar MatScalar;
100398725619SBarry Smith typedef PetscReal   MatReal;
100498725619SBarry Smith 
10059371c9d4SSatish Balay struct petsc_mpiu_2scalar {
10069371c9d4SSatish Balay   PetscScalar a, b;
10079371c9d4SSatish Balay };
100893d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);
1009df4397b0SStefano Zampini 
101093d501b3SJacob Faibussowitsch /* MPI Datatypes for composite reductions */
101193d501b3SJacob Faibussowitsch struct petsc_mpiu_real_int {
101293d501b3SJacob Faibussowitsch   PetscReal v;
101393d501b3SJacob Faibussowitsch   PetscInt  i;
101493d501b3SJacob Faibussowitsch };
101593d501b3SJacob Faibussowitsch 
101693d501b3SJacob Faibussowitsch struct petsc_mpiu_scalar_int {
101793d501b3SJacob Faibussowitsch   PetscScalar v;
101893d501b3SJacob Faibussowitsch   PetscInt    i;
101993d501b3SJacob Faibussowitsch };
102093d501b3SJacob Faibussowitsch 
102193d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
102293d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
1023092991acSStefano Zampini 
1024a616ada9SVaclav Hapla #if defined(PETSC_USE_64BIT_INDICES)
102593d501b3SJacob Faibussowitsch struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
102693d501b3SJacob Faibussowitsch   PetscInt a;
102793d501b3SJacob Faibussowitsch   PetscInt b;
10289371c9d4SSatish Balay };
10296497c311SBarry Smith struct __attribute__((packed)) petsc_mpiu_int_mpiint {
10306497c311SBarry Smith   PetscInt    a;
10316497c311SBarry Smith   PetscMPIInt b;
10326497c311SBarry Smith };
103393d501b3SJacob Faibussowitsch /*
103493d501b3SJacob Faibussowitsch  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
103593d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
103693d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
103793d501b3SJacob Faibussowitsch 
103893d501b3SJacob Faibussowitsch  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
103993d501b3SJacob Faibussowitsch  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
104093d501b3SJacob Faibussowitsch  pass! So we just comment it out...
104193d501b3SJacob Faibussowitsch */
104293d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
10436497c311SBarry Smith PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
10448ad47952SJed Brown #else
10458ad47952SJed Brown   #define MPIU_2INT       MPI_2INT
10466497c311SBarry Smith   #define MPIU_INT_MPIINT MPI_2INT
10478ad47952SJed Brown #endif
1048b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPI_4INT;
1049b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPIU_4INT;
1050e9fa29b7SSatish Balay 
PetscPowInt(PetscInt base,PetscInt power)1051d71ae5a4SJacob Faibussowitsch static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
1052d71ae5a4SJacob Faibussowitsch {
1053fa711258SJed Brown   PetscInt result = 1;
1054fa711258SJed Brown   while (power) {
1055fa711258SJed Brown     if (power & 1) result *= base;
1056fa711258SJed Brown     power >>= 1;
10576f2c871aSStefano Zampini     if (power) base *= base;
1058fa711258SJed Brown   }
1059fa711258SJed Brown   return result;
1060fa711258SJed Brown }
1061b2fb0278SBarry Smith 
PetscPowInt64(PetscInt base,PetscInt power)1062d71ae5a4SJacob Faibussowitsch static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
1063d71ae5a4SJacob Faibussowitsch {
1064ad70a4c3SStefano Zampini   PetscInt64 result = 1;
1065ad70a4c3SStefano Zampini   while (power) {
1066ad70a4c3SStefano Zampini     if (power & 1) result *= base;
1067ad70a4c3SStefano Zampini     power >>= 1;
10686f2c871aSStefano Zampini     if (power) base *= base;
1069ad70a4c3SStefano Zampini   }
1070ad70a4c3SStefano Zampini   return result;
1071ad70a4c3SStefano Zampini }
1072ad70a4c3SStefano Zampini 
PetscPowRealInt(PetscReal base,PetscInt power)1073d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
1074d71ae5a4SJacob Faibussowitsch {
1075fa711258SJed Brown   PetscReal result = 1;
1076d98d5da7SBarry Smith   if (power < 0) {
1077d98d5da7SBarry Smith     power = -power;
107810d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
1079d98d5da7SBarry Smith   }
1080fa711258SJed Brown   while (power) {
1081fa711258SJed Brown     if (power & 1) result *= base;
1082fa711258SJed Brown     power >>= 1;
10836f2c871aSStefano Zampini     if (power) base *= base;
1084fa711258SJed Brown   }
1085fa711258SJed Brown   return result;
1086fa711258SJed Brown }
1087fa711258SJed Brown 
PetscPowScalarInt(PetscScalar base,PetscInt power)1088d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
1089d71ae5a4SJacob Faibussowitsch {
10905117d392SLisandro Dalcin   PetscScalar result = (PetscReal)1;
10918b49ba18SBarry Smith   if (power < 0) {
10928b49ba18SBarry Smith     power = -power;
109310d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
10948b49ba18SBarry Smith   }
10958b49ba18SBarry Smith   while (power) {
10968b49ba18SBarry Smith     if (power & 1) result *= base;
10978b49ba18SBarry Smith     power >>= 1;
10986f2c871aSStefano Zampini     if (power) base *= base;
10998b49ba18SBarry Smith   }
11008b49ba18SBarry Smith   return result;
11018b49ba18SBarry Smith }
11028b49ba18SBarry Smith 
PetscPowScalarReal(PetscScalar base,PetscReal power)1103d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
1104d71ae5a4SJacob Faibussowitsch {
1105b2fb0278SBarry Smith   PetscScalar cpower = power;
1106b2fb0278SBarry Smith   return PetscPowScalar(base, cpower);
1107b2fb0278SBarry Smith }
110878a59e97SMatthew G. Knepley 
1109c803a25aSBarry Smith /*MC
111066baab88SBarry Smith    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
1111c803a25aSBarry Smith 
1112c803a25aSBarry Smith    Synopsis:
1113c803a25aSBarry Smith    #include <petscmath.h>
111466baab88SBarry Smith    bool PetscApproximateLTE(PetscReal x,constant float)
1115c803a25aSBarry Smith 
1116c803a25aSBarry Smith    Not Collective
1117c803a25aSBarry Smith 
1118c803a25aSBarry Smith    Input Parameters:
1119c803a25aSBarry Smith +   x - the variable
112016a05f60SBarry Smith -   b - the constant float it is checking if `x` is less than or equal to
112116a05f60SBarry Smith 
112216a05f60SBarry Smith    Level: advanced
1123c803a25aSBarry Smith 
1124c803a25aSBarry Smith    Notes:
112587497f52SBarry Smith    The fudge factor is the value `PETSC_SMALL`
1126c803a25aSBarry Smith 
1127c803a25aSBarry Smith    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
1128c803a25aSBarry Smith 
1129c803a25aSBarry Smith    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
1130c803a25aSBarry Smith    floating point results.
1131c803a25aSBarry Smith 
11323919e044SBarry Smith    Example\:
11333919e044SBarry Smith .vb
11343919e044SBarry Smith   PetscReal x;
11353919e044SBarry Smith   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
11363919e044SBarry Smith .ve
11373919e044SBarry Smith 
1138db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
1139c803a25aSBarry Smith M*/
114066baab88SBarry Smith #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
1141c803a25aSBarry Smith 
1142c803a25aSBarry Smith /*MC
114366baab88SBarry Smith    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
1144c803a25aSBarry Smith 
1145c803a25aSBarry Smith    Synopsis:
1146c803a25aSBarry Smith    #include <petscmath.h>
114766baab88SBarry Smith    bool PetscApproximateGTE(PetscReal x,constant float)
1148c803a25aSBarry Smith 
1149c803a25aSBarry Smith    Not Collective
1150c803a25aSBarry Smith 
1151c803a25aSBarry Smith    Input Parameters:
1152c803a25aSBarry Smith +   x - the variable
115316a05f60SBarry Smith -   b - the constant float it is checking if `x` is greater than or equal to
115416a05f60SBarry Smith 
115516a05f60SBarry Smith    Level: advanced
1156c803a25aSBarry Smith 
1157c803a25aSBarry Smith    Notes:
115887497f52SBarry Smith    The fudge factor is the value `PETSC_SMALL`
1159c803a25aSBarry Smith 
1160c803a25aSBarry Smith    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
1161c803a25aSBarry Smith 
1162c803a25aSBarry Smith    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
1163c803a25aSBarry Smith    floating point results.
1164c803a25aSBarry Smith 
11653919e044SBarry Smith    Example\:
11663919e044SBarry Smith .vb
11673919e044SBarry Smith   PetscReal x;
11683919e044SBarry Smith   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
11693919e044SBarry Smith .ve
11703919e044SBarry Smith 
1171db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1172c803a25aSBarry Smith M*/
117366baab88SBarry Smith #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
1174c803a25aSBarry Smith 
1175b7c0efcaSStefano Zampini /*@C
1176faa75363SBarry Smith    PetscCeilInt - Returns the ceiling of the quotation of two positive integers
1177faa75363SBarry Smith 
1178faa75363SBarry Smith    Not Collective
1179faa75363SBarry Smith 
1180faa75363SBarry Smith    Input Parameters:
1181faa75363SBarry Smith +   x - the numerator
1182faa75363SBarry Smith -   y - the denominator
1183faa75363SBarry Smith 
1184faa75363SBarry Smith    Level: advanced
1185faa75363SBarry Smith 
11863919e044SBarry Smith   Example\:
11873919e044SBarry Smith .vb
11883919e044SBarry Smith   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
11893919e044SBarry Smith .ve
11903919e044SBarry Smith 
1191b7c0efcaSStefano Zampini .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1192b7c0efcaSStefano Zampini @*/
PetscCeilInt(PetscInt x,PetscInt y)1193b7c0efcaSStefano Zampini static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
1194b7c0efcaSStefano Zampini {
1195b7c0efcaSStefano Zampini   return x / y + (x % y ? 1 : 0);
1196b7c0efcaSStefano Zampini }
1197faa75363SBarry Smith 
1198b7c0efcaSStefano Zampini /*@C
1199b7c0efcaSStefano Zampini    PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers
1200b7c0efcaSStefano Zampini 
1201b7c0efcaSStefano Zampini    Not Collective
1202b7c0efcaSStefano Zampini 
1203b7c0efcaSStefano Zampini    Input Parameters:
1204b7c0efcaSStefano Zampini +   x - the numerator
1205b7c0efcaSStefano Zampini -   y - the denominator
1206b7c0efcaSStefano Zampini 
1207b7c0efcaSStefano Zampini    Level: advanced
1208b7c0efcaSStefano Zampini 
1209b7c0efcaSStefano Zampini   Example\:
1210b7c0efcaSStefano Zampini .vb
1211b7c0efcaSStefano Zampini   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
1212b7c0efcaSStefano Zampini .ve
1213b7c0efcaSStefano Zampini 
1214b7c0efcaSStefano Zampini .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1215b7c0efcaSStefano Zampini @*/
PetscCeilInt64(PetscInt64 x,PetscInt64 y)1216b7c0efcaSStefano Zampini static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
1217b7c0efcaSStefano Zampini {
1218b7c0efcaSStefano Zampini   return x / y + (x % y ? 1 : 0);
1219b7c0efcaSStefano Zampini }
1220faa75363SBarry Smith 
12218a677b7aSStefano Zampini /*@C
1222b6512f73SStefano Zampini    PetscGCD - Returns the greatest common divisor of two integers
12238a677b7aSStefano Zampini 
12248a677b7aSStefano Zampini    Not Collective
12258a677b7aSStefano Zampini 
12268a677b7aSStefano Zampini    Input Parameters:
12278a677b7aSStefano Zampini +   a - first number
12288a677b7aSStefano Zampini -   b - second number
12298a677b7aSStefano Zampini 
12308a677b7aSStefano Zampini    Level: advanced
12318a677b7aSStefano Zampini 
12328a677b7aSStefano Zampini .seealso: `PetscLCM()`
12338a677b7aSStefano Zampini @*/
PetscGCD(PetscInt a,PetscInt b)12348a677b7aSStefano Zampini static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
12358a677b7aSStefano Zampini {
1236b6512f73SStefano Zampini   a = PetscAbsInt(a);
1237b6512f73SStefano Zampini   b = PetscAbsInt(b);
12388a677b7aSStefano Zampini   while (b != 0) {
12398a677b7aSStefano Zampini     PetscInt tmp = b;
1240b6512f73SStefano Zampini 
12418a677b7aSStefano Zampini     b = a % b;
12428a677b7aSStefano Zampini     a = tmp;
12438a677b7aSStefano Zampini   }
12448a677b7aSStefano Zampini   return a;
12458a677b7aSStefano Zampini }
12468a677b7aSStefano Zampini 
12478a677b7aSStefano Zampini /*@C
1248b6512f73SStefano Zampini    PetscLCM - Returns the least common multiple of two integers
12498a677b7aSStefano Zampini 
12508a677b7aSStefano Zampini    Not Collective
12518a677b7aSStefano Zampini 
12528a677b7aSStefano Zampini    Input Parameters:
12538a677b7aSStefano Zampini +   a - first number
12548a677b7aSStefano Zampini -   b - second number
12558a677b7aSStefano Zampini 
12568a677b7aSStefano Zampini    Level: advanced
12578a677b7aSStefano Zampini 
12588a677b7aSStefano Zampini .seealso: `PetscGCD()`
12598a677b7aSStefano Zampini @*/
PetscLCM(PetscInt a,PetscInt b)12608a677b7aSStefano Zampini static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
12618a677b7aSStefano Zampini {
1262*e07dcc01SStefano Zampini   PetscInt gcd;
1263*e07dcc01SStefano Zampini 
1264b6512f73SStefano Zampini   a = PetscAbsInt(a);
1265b6512f73SStefano Zampini   b = PetscAbsInt(b);
1266b6512f73SStefano Zampini 
1267*e07dcc01SStefano Zampini   gcd = PetscGCD(a, b);
12688a677b7aSStefano Zampini   return gcd ? a * (b / gcd) : 0;
12698a677b7aSStefano Zampini }
12708a677b7aSStefano Zampini 
1271bebf13c0SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);
1272