xref: /petsc/include/petscmath.h (revision 6497c311e7b976d467be1503c1effce92a60525c)
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)
505117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
519c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignf(a, b)
525117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaf(a)
531f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
541f17fa70SToby Isaac     #define PetscLGamma(a) gammaf(a)
551f17fa70SToby Isaac   #else
561f17fa70SToby Isaac     #define PetscLGamma(a) lgammaf(a)
571f17fa70SToby Isaac   #endif
585117d392SLisandro Dalcin 
595117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
605117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrt(a)
615117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrt(a)
625117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypot(a, b)
635117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2(a, b)
645117d392SLisandro Dalcin   #define PetscPowReal(a, b)      pow(a, b)
655117d392SLisandro Dalcin   #define PetscExpReal(a)         exp(a)
665117d392SLisandro Dalcin   #define PetscLogReal(a)         log(a)
675117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10(a)
685117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2(a)
695117d392SLisandro Dalcin   #define PetscSinReal(a)         sin(a)
705117d392SLisandro Dalcin   #define PetscCosReal(a)         cos(a)
715117d392SLisandro Dalcin   #define PetscTanReal(a)         tan(a)
725117d392SLisandro Dalcin   #define PetscAsinReal(a)        asin(a)
735117d392SLisandro Dalcin   #define PetscAcosReal(a)        acos(a)
745117d392SLisandro Dalcin   #define PetscAtanReal(a)        atan(a)
755117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinh(a)
765117d392SLisandro Dalcin   #define PetscCoshReal(a)        cosh(a)
775117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanh(a)
785117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinh(a)
795117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acosh(a)
805117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanh(a)
81d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erf(a)
825117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceil(a)
835117d392SLisandro Dalcin   #define PetscFloorReal(a)       floor(a)
845117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmod(a, b)
859c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysign(a, b)
865117d392SLisandro Dalcin   #define PetscTGamma(a)          tgamma(a)
871f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
881f17fa70SToby Isaac     #define PetscLGamma(a) gamma(a)
891f17fa70SToby Isaac   #else
901f17fa70SToby Isaac     #define PetscLGamma(a) lgamma(a)
911f17fa70SToby Isaac   #endif
925117d392SLisandro Dalcin 
935117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
945117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtq(a)
955117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtq(a)
965117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotq(a, b)
975117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2q(a, b)
985117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powq(a, b)
995117d392SLisandro Dalcin   #define PetscExpReal(a)         expq(a)
1005117d392SLisandro Dalcin   #define PetscLogReal(a)         logq(a)
1015117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10q(a)
1025117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2q(a)
1035117d392SLisandro Dalcin   #define PetscSinReal(a)         sinq(a)
1045117d392SLisandro Dalcin   #define PetscCosReal(a)         cosq(a)
1055117d392SLisandro Dalcin   #define PetscTanReal(a)         tanq(a)
1065117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinq(a)
1075117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosq(a)
1085117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanq(a)
1095117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhq(a)
1105117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshq(a)
1115117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhq(a)
1125117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhq(a)
1135117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshq(a)
1145117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhq(a)
115d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erfq(a)
1165117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilq(a)
1175117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorq(a)
1185117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodq(a, b)
1199c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignq(a, b)
1205117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaq(a)
1211f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
1221f17fa70SToby Isaac     #define PetscLGamma(a) gammaq(a)
1231f17fa70SToby Isaac   #else
1241f17fa70SToby Isaac     #define PetscLGamma(a) lgammaq(a)
1251f17fa70SToby Isaac   #endif
1265117d392SLisandro Dalcin 
1275117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
1285117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtf(a)
1295117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtf(a)
1305117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotf(a, b)
1315117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2f(a, b)
1325117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powf(a, b)
1335117d392SLisandro Dalcin   #define PetscExpReal(a)         expf(a)
1345117d392SLisandro Dalcin   #define PetscLogReal(a)         logf(a)
1355117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10f(a)
1365117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2f(a)
1375117d392SLisandro Dalcin   #define PetscSinReal(a)         sinf(a)
1385117d392SLisandro Dalcin   #define PetscCosReal(a)         cosf(a)
1395117d392SLisandro Dalcin   #define PetscTanReal(a)         tanf(a)
1405117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinf(a)
1415117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosf(a)
1425117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanf(a)
1435117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhf(a)
1445117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshf(a)
1455117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhf(a)
1465117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhf(a)
1475117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshf(a)
1485117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhf(a)
149d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erff(a)
1505117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilf(a)
1515117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorf(a)
1525117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
153ea007c46SStefano Zampini   #define PetscCopysignReal(a, b) copysignf(a, b)
1545117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaf(a)
1551f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
1561f17fa70SToby Isaac     #define PetscLGamma(a) gammaf(a)
1571f17fa70SToby Isaac   #else
1581f17fa70SToby Isaac     #define PetscLGamma(a) lgammaf(a)
1591f17fa70SToby Isaac   #endif
1605117d392SLisandro Dalcin 
1615117d392SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
1625117d392SLisandro Dalcin 
163d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscSignReal(PetscReal a)
164d71ae5a4SJacob Faibussowitsch {
1655117d392SLisandro Dalcin   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
1665117d392SLisandro Dalcin }
1675117d392SLisandro Dalcin 
1685117d392SLisandro Dalcin #if !defined(PETSC_HAVE_LOG2)
1695117d392SLisandro Dalcin   #undef PetscLog2Real
170d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscLog2Real(PetscReal a)
171d71ae5a4SJacob Faibussowitsch {
1725117d392SLisandro Dalcin   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
1735117d392SLisandro Dalcin }
1745117d392SLisandro Dalcin #endif
1755117d392SLisandro Dalcin 
176a2498233SPierre Jolivet #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
17793d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
1785117d392SLisandro Dalcin #endif
179a2498233SPierre Jolivet #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
18093d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
1815117d392SLisandro Dalcin #endif
1825117d392SLisandro Dalcin 
183df4397b0SStefano Zampini /*MC
18487497f52SBarry Smith    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in
185df4397b0SStefano Zampini 
186df4397b0SStefano Zampini    Level: beginner
187df4397b0SStefano Zampini 
188af27ebaaSBarry Smith    Note:
189af27ebaaSBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
190af27ebaaSBarry Smith 
191db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
192df4397b0SStefano Zampini M*/
193c1d390e3SJed Brown #if defined(PETSC_USE_REAL_SINGLE)
194c1d390e3SJed Brown   #define MPIU_REAL MPI_FLOAT
195c1d390e3SJed Brown #elif defined(PETSC_USE_REAL_DOUBLE)
196c1d390e3SJed Brown   #define MPIU_REAL MPI_DOUBLE
197c1d390e3SJed Brown #elif defined(PETSC_USE_REAL___FLOAT128)
198c1d390e3SJed Brown   #define MPIU_REAL MPIU___FLOAT128
199570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16)
200570b7f6dSBarry Smith   #define MPIU_REAL MPIU___FP16
201c1d390e3SJed Brown #endif /* PETSC_USE_REAL_* */
20259cb5930SBarry Smith 
2031093a601SBarry Smith /*
2041093a601SBarry Smith     Complex number definitions
2051093a601SBarry Smith  */
206df4397b0SStefano Zampini #if defined(PETSC_HAVE_COMPLEX)
207450fc7c9SSatish Balay   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
2081093a601SBarry Smith   /* C++ support of complex number */
209b7940d39SSatish Balay 
2109fa27a79SStefano Zampini     #define PetscRealPartComplex(a)      (static_cast<PetscComplex>(a)).real()
2119fa27a79SStefano Zampini     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
2129fa27a79SStefano Zampini     #define PetscAbsComplex(a)           petsccomplexlib::abs(static_cast<PetscComplex>(a))
2139fa27a79SStefano Zampini     #define PetscArgComplex(a)           petsccomplexlib::arg(static_cast<PetscComplex>(a))
2149fa27a79SStefano Zampini     #define PetscConjComplex(a)          petsccomplexlib::conj(static_cast<PetscComplex>(a))
2159fa27a79SStefano Zampini     #define PetscSqrtComplex(a)          petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
2169fa27a79SStefano Zampini     #define PetscPowComplex(a, b)        petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
2179fa27a79SStefano Zampini     #define PetscExpComplex(a)           petsccomplexlib::exp(static_cast<PetscComplex>(a))
2189fa27a79SStefano Zampini     #define PetscLogComplex(a)           petsccomplexlib::log(static_cast<PetscComplex>(a))
2199fa27a79SStefano Zampini     #define PetscSinComplex(a)           petsccomplexlib::sin(static_cast<PetscComplex>(a))
2209fa27a79SStefano Zampini     #define PetscCosComplex(a)           petsccomplexlib::cos(static_cast<PetscComplex>(a))
2219fa27a79SStefano Zampini     #define PetscTanComplex(a)           petsccomplexlib::tan(static_cast<PetscComplex>(a))
2229fa27a79SStefano Zampini     #define PetscAsinComplex(a)          petsccomplexlib::asin(static_cast<PetscComplex>(a))
2239fa27a79SStefano Zampini     #define PetscAcosComplex(a)          petsccomplexlib::acos(static_cast<PetscComplex>(a))
2249fa27a79SStefano Zampini     #define PetscAtanComplex(a)          petsccomplexlib::atan(static_cast<PetscComplex>(a))
2259fa27a79SStefano Zampini     #define PetscSinhComplex(a)          petsccomplexlib::sinh(static_cast<PetscComplex>(a))
2269fa27a79SStefano Zampini     #define PetscCoshComplex(a)          petsccomplexlib::cosh(static_cast<PetscComplex>(a))
2279fa27a79SStefano Zampini     #define PetscTanhComplex(a)          petsccomplexlib::tanh(static_cast<PetscComplex>(a))
2289fa27a79SStefano Zampini     #define PetscAsinhComplex(a)         petsccomplexlib::asinh(static_cast<PetscComplex>(a))
2299fa27a79SStefano Zampini     #define PetscAcoshComplex(a)         petsccomplexlib::acosh(static_cast<PetscComplex>(a))
2309fa27a79SStefano Zampini     #define PetscAtanhComplex(a)         petsccomplexlib::atanh(static_cast<PetscComplex>(a))
2315117d392SLisandro Dalcin 
2325117d392SLisandro Dalcin   /* TODO: Add configure tests
2335117d392SLisandro Dalcin 
2345117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
2355117d392SLisandro Dalcin #undef PetscTanComplex
2369fbee547SJacob Faibussowitsch static inline PetscComplex PetscTanComplex(PetscComplex z)
2375117d392SLisandro Dalcin {
2385117d392SLisandro Dalcin   return PetscSinComplex(z)/PetscCosComplex(z);
2395117d392SLisandro Dalcin }
240027d9794SBarry Smith #endif
241debe9ee2SPaul Mullowney 
2425117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
2435117d392SLisandro Dalcin #undef PetscTanhComplex
2449fbee547SJacob Faibussowitsch static inline PetscComplex PetscTanhComplex(PetscComplex z)
2455117d392SLisandro Dalcin {
2465117d392SLisandro Dalcin   return PetscSinhComplex(z)/PetscCoshComplex(z);
2475117d392SLisandro Dalcin }
2485117d392SLisandro Dalcin #endif
2495117d392SLisandro Dalcin 
2505117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
2515117d392SLisandro Dalcin #undef PetscAsinComplex
2529fbee547SJacob Faibussowitsch static inline PetscComplex PetscAsinComplex(PetscComplex z)
2535117d392SLisandro Dalcin {
2545117d392SLisandro Dalcin   const PetscComplex j(0,1);
2555117d392SLisandro Dalcin   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
2565117d392SLisandro Dalcin }
2575117d392SLisandro Dalcin #endif
2585117d392SLisandro Dalcin 
2595117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
2605117d392SLisandro Dalcin #undef PetscAcosComplex
2619fbee547SJacob Faibussowitsch static inline PetscComplex PetscAcosComplex(PetscComplex z)
2625117d392SLisandro Dalcin {
2635117d392SLisandro Dalcin   const PetscComplex j(0,1);
2645117d392SLisandro Dalcin   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
2655117d392SLisandro Dalcin }
2665117d392SLisandro Dalcin #endif
2675117d392SLisandro Dalcin 
2685117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
2695117d392SLisandro Dalcin #undef PetscAtanComplex
2709fbee547SJacob Faibussowitsch static inline PetscComplex PetscAtanComplex(PetscComplex z)
2715117d392SLisandro Dalcin {
2725117d392SLisandro Dalcin   const PetscComplex j(0,1);
2735117d392SLisandro Dalcin   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
2745117d392SLisandro Dalcin }
2755117d392SLisandro Dalcin #endif
2765117d392SLisandro Dalcin 
2775117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
2785117d392SLisandro Dalcin #undef PetscAsinhComplex
2799fbee547SJacob Faibussowitsch static inline PetscComplex PetscAsinhComplex(PetscComplex z)
2805117d392SLisandro Dalcin {
2815117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
2825117d392SLisandro Dalcin }
2835117d392SLisandro Dalcin #endif
2845117d392SLisandro Dalcin 
2855117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
2865117d392SLisandro Dalcin #undef PetscAcoshComplex
2879fbee547SJacob Faibussowitsch static inline PetscComplex PetscAcoshComplex(PetscComplex z)
2885117d392SLisandro Dalcin {
2895117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
2905117d392SLisandro Dalcin }
2915117d392SLisandro Dalcin #endif
2925117d392SLisandro Dalcin 
2935117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
2945117d392SLisandro Dalcin #undef PetscAtanhComplex
2959fbee547SJacob Faibussowitsch static inline PetscComplex PetscAtanhComplex(PetscComplex z)
2965117d392SLisandro Dalcin {
2975117d392SLisandro Dalcin   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
2985117d392SLisandro Dalcin }
2995117d392SLisandro Dalcin #endif
3005117d392SLisandro Dalcin 
3015117d392SLisandro Dalcin */
3025117d392SLisandro Dalcin 
3037a19d461SSatish Balay   #else /* C99 support of complex number */
304519e2a1fSPaul Mullowney 
3057a19d461SSatish Balay     #if defined(PETSC_USE_REAL_SINGLE)
30650f81f78SJed Brown       #define PetscRealPartComplex(a)      crealf(a)
30750f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimagf(a)
30850f81f78SJed Brown       #define PetscAbsComplex(a)           cabsf(a)
3095117d392SLisandro Dalcin       #define PetscArgComplex(a)           cargf(a)
31050f81f78SJed Brown       #define PetscConjComplex(a)          conjf(a)
31150f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrtf(a)
31250f81f78SJed Brown       #define PetscPowComplex(a, b)        cpowf(a, b)
31350f81f78SJed Brown       #define PetscExpComplex(a)           cexpf(a)
31450f81f78SJed Brown       #define PetscLogComplex(a)           clogf(a)
31550f81f78SJed Brown       #define PetscSinComplex(a)           csinf(a)
31650f81f78SJed Brown       #define PetscCosComplex(a)           ccosf(a)
3175117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctanf(a)
318255453a1SBarry Smith       #define PetscAsinComplex(a)          casinf(a)
319255453a1SBarry Smith       #define PetscAcosComplex(a)          cacosf(a)
3205117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catanf(a)
321a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinhf(a)
322a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccoshf(a)
323a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanhf(a)
3245117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinhf(a)
3255117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacoshf(a)
3265117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanhf(a)
3271093a601SBarry Smith 
328ce63c4c1SBarry Smith     #elif defined(PETSC_USE_REAL_DOUBLE)
32950f81f78SJed Brown       #define PetscRealPartComplex(a)      creal(a)
33050f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimag(a)
33150f81f78SJed Brown       #define PetscAbsComplex(a)           cabs(a)
3325117d392SLisandro Dalcin       #define PetscArgComplex(a)           carg(a)
33350f81f78SJed Brown       #define PetscConjComplex(a)          conj(a)
33450f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrt(a)
33550f81f78SJed Brown       #define PetscPowComplex(a, b)        cpow(a, b)
33650f81f78SJed Brown       #define PetscExpComplex(a)           cexp(a)
33750f81f78SJed Brown       #define PetscLogComplex(a)           clog(a)
33850f81f78SJed Brown       #define PetscSinComplex(a)           csin(a)
33950f81f78SJed Brown       #define PetscCosComplex(a)           ccos(a)
3405117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctan(a)
341255453a1SBarry Smith       #define PetscAsinComplex(a)          casin(a)
342255453a1SBarry Smith       #define PetscAcosComplex(a)          cacos(a)
3435117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catan(a)
344a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinh(a)
345a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccosh(a)
346a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanh(a)
3475117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinh(a)
3485117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacosh(a)
3495117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanh(a)
3501093a601SBarry Smith 
3518c764dc5SJose Roman     #elif defined(PETSC_USE_REAL___FLOAT128)
35250f81f78SJed Brown       #define PetscRealPartComplex(a)      crealq(a)
35350f81f78SJed Brown       #define PetscImaginaryPartComplex(a) cimagq(a)
35450f81f78SJed Brown       #define PetscAbsComplex(a)           cabsq(a)
3555117d392SLisandro Dalcin       #define PetscArgComplex(a)           cargq(a)
35650f81f78SJed Brown       #define PetscConjComplex(a)          conjq(a)
35750f81f78SJed Brown       #define PetscSqrtComplex(a)          csqrtq(a)
35850f81f78SJed Brown       #define PetscPowComplex(a, b)        cpowq(a, b)
35950f81f78SJed Brown       #define PetscExpComplex(a)           cexpq(a)
36050f81f78SJed Brown       #define PetscLogComplex(a)           clogq(a)
36150f81f78SJed Brown       #define PetscSinComplex(a)           csinq(a)
36250f81f78SJed Brown       #define PetscCosComplex(a)           ccosq(a)
3635117d392SLisandro Dalcin       #define PetscTanComplex(a)           ctanq(a)
364255453a1SBarry Smith       #define PetscAsinComplex(a)          casinq(a)
365255453a1SBarry Smith       #define PetscAcosComplex(a)          cacosq(a)
3665117d392SLisandro Dalcin       #define PetscAtanComplex(a)          catanq(a)
367a4bea5a6SPeter Brune       #define PetscSinhComplex(a)          csinhq(a)
368a4bea5a6SPeter Brune       #define PetscCoshComplex(a)          ccoshq(a)
369a4bea5a6SPeter Brune       #define PetscTanhComplex(a)          ctanhq(a)
3705117d392SLisandro Dalcin       #define PetscAsinhComplex(a)         casinhq(a)
3715117d392SLisandro Dalcin       #define PetscAcoshComplex(a)         cacoshq(a)
3725117d392SLisandro Dalcin       #define PetscAtanhComplex(a)         catanhq(a)
373a4bea5a6SPeter Brune 
374ce63c4c1SBarry Smith     #endif /* PETSC_USE_REAL_* */
3757a19d461SSatish Balay   #endif   /* (__cplusplus) */
376e489efc1SBarry Smith 
3773919e044SBarry Smith /*MC
3783919e044SBarry Smith    PETSC_i - the pure imaginary complex number i
3793919e044SBarry Smith 
3803919e044SBarry Smith    Level: intermediate
3813919e044SBarry Smith 
3823919e044SBarry Smith .seealso: `PetscComplex`, `PetscScalar`
3833919e044SBarry Smith M*/
38450f81f78SJed Brown PETSC_EXTERN PetscComplex PETSC_i;
3858a351411SToby Isaac 
3865117d392SLisandro Dalcin /*
3875117d392SLisandro Dalcin    Try to do the right thing for complex number construction: see
3888a351411SToby Isaac    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
3898a351411SToby Isaac    for details
3908a351411SToby Isaac */
391d71ae5a4SJacob Faibussowitsch static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
392d71ae5a4SJacob Faibussowitsch {
393450fc7c9SSatish Balay   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
3948a351411SToby Isaac   return PetscComplex(x, y);
3958a351411SToby Isaac   #elif defined(_Imaginary_I)
3968a351411SToby Isaac   return x + y * _Imaginary_I;
3978a351411SToby Isaac   #else
398616d7c5eSToby Isaac   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
399616d7c5eSToby Isaac 
400616d7c5eSToby Isaac        "For each floating type there is a corresponding real type, which is always a real floating
401616d7c5eSToby Isaac        type. For real floating types, it is the same type. For complex types, it is the type given
402616d7c5eSToby Isaac        by deleting the keyword _Complex from the type name."
403616d7c5eSToby Isaac 
404616d7c5eSToby Isaac        So type punning should be portable. */
4059371c9d4SSatish Balay     union
4069371c9d4SSatish Balay     {
4079371c9d4SSatish Balay       PetscComplex z;
4089371c9d4SSatish Balay       PetscReal    f[2];
4099371c9d4SSatish Balay     } uz;
410616d7c5eSToby Isaac 
411616d7c5eSToby Isaac     uz.f[0] = x;
412616d7c5eSToby Isaac     uz.f[1] = y;
413616d7c5eSToby Isaac     return uz.z;
414616d7c5eSToby Isaac   }
41550f81f78SJed Brown   #endif
4168a351411SToby Isaac }
4178a351411SToby Isaac 
418edd03b47SJacob Faibussowitsch   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
419edd03b47SJacob Faibussowitsch   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )
420de272c7aSSatish Balay 
421a2498233SPierre Jolivet   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
42293d501b3SJacob Faibussowitsch     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
42393d501b3SJacob Faibussowitsch     #if defined(PETSC_USE_COMPLEX)
42493d501b3SJacob Faibussowitsch       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
42593d501b3SJacob Faibussowitsch     #else
42693d501b3SJacob Faibussowitsch       #define MPIU___COMPLEX128_ATTR_TAG
42793d501b3SJacob Faibussowitsch     #endif
42893d501b3SJacob Faibussowitsch 
42993d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;
43093d501b3SJacob Faibussowitsch 
43193d501b3SJacob Faibussowitsch     #undef MPIU___COMPLEX128_ATTR_TAG
432613bf2b2SPierre Jolivet   #endif /* PETSC_HAVE_REAL___FLOAT128 */
4335117d392SLisandro Dalcin 
4345117d392SLisandro Dalcin   /*MC
43587497f52SBarry Smith    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`
4365117d392SLisandro Dalcin 
4375117d392SLisandro Dalcin    Level: beginner
4385117d392SLisandro Dalcin 
43995bd0b28SBarry Smith    Note:
44095bd0b28SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
44195bd0b28SBarry Smith 
442db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
4435117d392SLisandro Dalcin M*/
4445117d392SLisandro Dalcin   #if defined(PETSC_USE_REAL_SINGLE)
445de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_COMPLEX
4465117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL_DOUBLE)
447de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
4485117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL___FLOAT128)
4495117d392SLisandro Dalcin     #define MPIU_COMPLEX MPIU___COMPLEX128
4505117d392SLisandro Dalcin   #elif defined(PETSC_USE_REAL___FP16)
451de272c7aSSatish Balay     #define MPIU_COMPLEX MPI_C_COMPLEX
4525117d392SLisandro Dalcin   #endif /* PETSC_USE_REAL_* */
4535117d392SLisandro Dalcin 
4545117d392SLisandro Dalcin #endif /* PETSC_HAVE_COMPLEX */
4555117d392SLisandro Dalcin 
4565117d392SLisandro Dalcin /*
4575117d392SLisandro Dalcin     Scalar number definitions
4585117d392SLisandro Dalcin  */
4597a19d461SSatish Balay #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
4605117d392SLisandro Dalcin   /*MC
46187497f52SBarry Smith    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`
4625117d392SLisandro Dalcin 
4635117d392SLisandro Dalcin    Level: beginner
4645117d392SLisandro Dalcin 
46595bd0b28SBarry Smith    Note:
46695bd0b28SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
46795bd0b28SBarry Smith 
468db781477SPatrick Sanan .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
4695117d392SLisandro Dalcin M*/
4705117d392SLisandro Dalcin   #define MPIU_SCALAR MPIU_COMPLEX
4715117d392SLisandro Dalcin 
4725117d392SLisandro Dalcin   /*MC
47387497f52SBarry Smith    PetscRealPart - Returns the real part of a `PetscScalar`
4745117d392SLisandro Dalcin 
4755117d392SLisandro Dalcin    Synopsis:
4765117d392SLisandro Dalcin    #include <petscmath.h>
4775117d392SLisandro Dalcin    PetscReal PetscRealPart(PetscScalar v)
4785117d392SLisandro Dalcin 
4795117d392SLisandro Dalcin    Not Collective
4805117d392SLisandro Dalcin 
4815117d392SLisandro Dalcin    Input Parameter:
4825117d392SLisandro Dalcin .  v - value to find the real part of
4835117d392SLisandro Dalcin 
4845117d392SLisandro Dalcin    Level: beginner
4855117d392SLisandro Dalcin 
486db781477SPatrick Sanan .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
4875117d392SLisandro Dalcin M*/
4885117d392SLisandro Dalcin   #define PetscRealPart(a) PetscRealPartComplex(a)
4895117d392SLisandro Dalcin 
4905117d392SLisandro Dalcin   /*MC
49187497f52SBarry Smith    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`
4925117d392SLisandro Dalcin 
4935117d392SLisandro Dalcin    Synopsis:
4945117d392SLisandro Dalcin    #include <petscmath.h>
4955117d392SLisandro Dalcin    PetscReal PetscImaginaryPart(PetscScalar v)
4965117d392SLisandro Dalcin 
4975117d392SLisandro Dalcin    Not Collective
4985117d392SLisandro Dalcin 
4995117d392SLisandro Dalcin    Input Parameter:
5005117d392SLisandro Dalcin .  v - value to find the imaginary part of
5015117d392SLisandro Dalcin 
5025117d392SLisandro Dalcin    Level: beginner
5035117d392SLisandro Dalcin 
50495bd0b28SBarry Smith    Note:
5055117d392SLisandro Dalcin    If PETSc was configured for real numbers then this always returns the value 0
5065117d392SLisandro Dalcin 
507db781477SPatrick Sanan .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
5085117d392SLisandro Dalcin M*/
5095117d392SLisandro Dalcin   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
5105117d392SLisandro Dalcin 
5115117d392SLisandro Dalcin   #define PetscAbsScalar(a)    PetscAbsComplex(a)
5125117d392SLisandro Dalcin   #define PetscArgScalar(a)    PetscArgComplex(a)
5135117d392SLisandro Dalcin   #define PetscConj(a)         PetscConjComplex(a)
5145117d392SLisandro Dalcin   #define PetscSqrtScalar(a)   PetscSqrtComplex(a)
5155117d392SLisandro Dalcin   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
5165117d392SLisandro Dalcin   #define PetscExpScalar(a)    PetscExpComplex(a)
5175117d392SLisandro Dalcin   #define PetscLogScalar(a)    PetscLogComplex(a)
5185117d392SLisandro Dalcin   #define PetscSinScalar(a)    PetscSinComplex(a)
5195117d392SLisandro Dalcin   #define PetscCosScalar(a)    PetscCosComplex(a)
5205117d392SLisandro Dalcin   #define PetscTanScalar(a)    PetscTanComplex(a)
5215117d392SLisandro Dalcin   #define PetscAsinScalar(a)   PetscAsinComplex(a)
5225117d392SLisandro Dalcin   #define PetscAcosScalar(a)   PetscAcosComplex(a)
5235117d392SLisandro Dalcin   #define PetscAtanScalar(a)   PetscAtanComplex(a)
5245117d392SLisandro Dalcin   #define PetscSinhScalar(a)   PetscSinhComplex(a)
5255117d392SLisandro Dalcin   #define PetscCoshScalar(a)   PetscCoshComplex(a)
5265117d392SLisandro Dalcin   #define PetscTanhScalar(a)   PetscTanhComplex(a)
5275117d392SLisandro Dalcin   #define PetscAsinhScalar(a)  PetscAsinhComplex(a)
5285117d392SLisandro Dalcin   #define PetscAcoshScalar(a)  PetscAcoshComplex(a)
5295117d392SLisandro Dalcin   #define PetscAtanhScalar(a)  PetscAtanhComplex(a)
5305117d392SLisandro Dalcin 
5315117d392SLisandro Dalcin #else /* PETSC_USE_COMPLEX */
5325117d392SLisandro Dalcin   #define MPIU_SCALAR           MPIU_REAL
5335117d392SLisandro Dalcin   #define PetscRealPart(a)      (a)
5345117d392SLisandro Dalcin   #define PetscImaginaryPart(a) ((PetscReal)0)
5355117d392SLisandro Dalcin   #define PetscAbsScalar(a)     PetscAbsReal(a)
5365117d392SLisandro Dalcin   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
5375117d392SLisandro Dalcin   #define PetscConj(a)          (a)
5385117d392SLisandro Dalcin   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
5395117d392SLisandro Dalcin   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
5405117d392SLisandro Dalcin   #define PetscExpScalar(a)     PetscExpReal(a)
5415117d392SLisandro Dalcin   #define PetscLogScalar(a)     PetscLogReal(a)
5425117d392SLisandro Dalcin   #define PetscSinScalar(a)     PetscSinReal(a)
5435117d392SLisandro Dalcin   #define PetscCosScalar(a)     PetscCosReal(a)
5445117d392SLisandro Dalcin   #define PetscTanScalar(a)     PetscTanReal(a)
5455117d392SLisandro Dalcin   #define PetscAsinScalar(a)    PetscAsinReal(a)
5465117d392SLisandro Dalcin   #define PetscAcosScalar(a)    PetscAcosReal(a)
5475117d392SLisandro Dalcin   #define PetscAtanScalar(a)    PetscAtanReal(a)
5485117d392SLisandro Dalcin   #define PetscSinhScalar(a)    PetscSinhReal(a)
5495117d392SLisandro Dalcin   #define PetscCoshScalar(a)    PetscCoshReal(a)
5505117d392SLisandro Dalcin   #define PetscTanhScalar(a)    PetscTanhReal(a)
5515117d392SLisandro Dalcin   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
5525117d392SLisandro Dalcin   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
5535117d392SLisandro Dalcin   #define PetscAtanhScalar(a)   PetscAtanhReal(a)
5545117d392SLisandro Dalcin 
5555117d392SLisandro Dalcin #endif /* PETSC_USE_COMPLEX */
5565117d392SLisandro Dalcin 
5575117d392SLisandro Dalcin /*
5585117d392SLisandro Dalcin    Certain objects may be created using either single or double precision.
5595117d392SLisandro Dalcin    This is currently not used.
5605117d392SLisandro Dalcin */
5619371c9d4SSatish Balay typedef enum {
5629371c9d4SSatish Balay   PETSC_SCALAR_DOUBLE,
5639371c9d4SSatish Balay   PETSC_SCALAR_SINGLE,
5649371c9d4SSatish Balay   PETSC_SCALAR_LONG_DOUBLE,
5659371c9d4SSatish Balay   PETSC_SCALAR_HALF
5669371c9d4SSatish Balay } PetscScalarPrecision;
5675117d392SLisandro Dalcin 
5685117d392SLisandro Dalcin /*MC
5695117d392SLisandro Dalcin    PetscAbs - Returns the absolute value of a number
5705117d392SLisandro Dalcin 
5715117d392SLisandro Dalcin    Synopsis:
5725117d392SLisandro Dalcin    #include <petscmath.h>
5735117d392SLisandro Dalcin    type PetscAbs(type v)
5745117d392SLisandro Dalcin 
5755117d392SLisandro Dalcin    Not Collective
5765117d392SLisandro Dalcin 
5775117d392SLisandro Dalcin    Input Parameter:
5785117d392SLisandro Dalcin .  v - the number
5795117d392SLisandro Dalcin 
58016a05f60SBarry Smith    Level: beginner
58116a05f60SBarry Smith 
58287497f52SBarry Smith    Note:
58387497f52SBarry Smith    The type can be integer or real floating point value, but cannot be complex
5845117d392SLisandro Dalcin 
58516a05f60SBarry Smith .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
5865117d392SLisandro Dalcin M*/
5875117d392SLisandro Dalcin #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))
5885117d392SLisandro Dalcin 
5895117d392SLisandro Dalcin /*MC
5903919e044SBarry Smith    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1
5915117d392SLisandro Dalcin 
5925117d392SLisandro Dalcin    Synopsis:
5935117d392SLisandro Dalcin    #include <petscmath.h>
5945117d392SLisandro Dalcin    int PetscSign(type v)
5955117d392SLisandro Dalcin 
5965117d392SLisandro Dalcin    Not Collective
5975117d392SLisandro Dalcin 
5985117d392SLisandro Dalcin    Input Parameter:
5995117d392SLisandro Dalcin .  v - the number
6005117d392SLisandro Dalcin 
60116a05f60SBarry Smith    Level: beginner
60216a05f60SBarry Smith 
60387497f52SBarry Smith    Note:
60487497f52SBarry Smith    The type can be integer or real floating point value
6055117d392SLisandro Dalcin 
60616a05f60SBarry Smith .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
6075117d392SLisandro Dalcin M*/
6085117d392SLisandro Dalcin #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
609e489efc1SBarry Smith 
610b6a5bde7SBarry Smith /*MC
611b6a5bde7SBarry Smith    PetscMin - Returns minimum of two numbers
612b6a5bde7SBarry Smith 
613eca87e8dSBarry Smith    Synopsis:
614aaa7dc30SBarry Smith    #include <petscmath.h>
615eca87e8dSBarry Smith    type PetscMin(type v1,type v2)
616eca87e8dSBarry Smith 
617eca87e8dSBarry Smith    Not Collective
618eca87e8dSBarry Smith 
619d8d19677SJose E. Roman    Input Parameters:
620b6a5bde7SBarry Smith +  v1 - first value to find minimum of
621b6a5bde7SBarry Smith -  v2 - second value to find minimum of
622b6a5bde7SBarry Smith 
62316a05f60SBarry Smith    Level: beginner
62416a05f60SBarry Smith 
62587497f52SBarry Smith    Note:
6263919e044SBarry Smith    The type can be integer or floating point value, but cannot be complex
627b6a5bde7SBarry Smith 
628db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
629b6a5bde7SBarry Smith M*/
630e489efc1SBarry Smith #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))
631b6a5bde7SBarry Smith 
632b6a5bde7SBarry Smith /*MC
633d5b43468SJose E. Roman    PetscMax - Returns maximum of two numbers
634b6a5bde7SBarry Smith 
635eca87e8dSBarry Smith    Synopsis:
636aaa7dc30SBarry Smith    #include <petscmath.h>
637eca87e8dSBarry Smith    type max PetscMax(type v1,type v2)
638eca87e8dSBarry Smith 
639eca87e8dSBarry Smith    Not Collective
640eca87e8dSBarry Smith 
641d8d19677SJose E. Roman    Input Parameters:
642b6a5bde7SBarry Smith +  v1 - first value to find maximum of
643b6a5bde7SBarry Smith -  v2 - second value to find maximum of
644b6a5bde7SBarry Smith 
64516a05f60SBarry Smith    Level: beginner
64616a05f60SBarry Smith 
64787497f52SBarry Smith    Note:
64887497f52SBarry Smith    The type can be integer or floating point value
649b6a5bde7SBarry Smith 
650db781477SPatrick Sanan .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
651b6a5bde7SBarry Smith M*/
652e489efc1SBarry Smith #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))
653b6a5bde7SBarry Smith 
654b6a5bde7SBarry Smith /*MC
655d9a4bb16SJed Brown    PetscClipInterval - Returns a number clipped to be within an interval
656d9a4bb16SJed Brown 
657d9a4bb16SJed Brown    Synopsis:
658aaa7dc30SBarry Smith    #include <petscmath.h>
659d9a4bb16SJed Brown    type clip PetscClipInterval(type x,type a,type b)
660d9a4bb16SJed Brown 
661d9a4bb16SJed Brown    Not Collective
662d9a4bb16SJed Brown 
663d8d19677SJose E. Roman    Input Parameters:
6640d398bfeSStefano Zampini +  x - value to use if within interval [a,b]
665d9a4bb16SJed Brown .  a - lower end of interval
666d9a4bb16SJed Brown -  b - upper end of interval
667d9a4bb16SJed Brown 
66816a05f60SBarry Smith    Level: beginner
66916a05f60SBarry Smith 
67087497f52SBarry Smith    Note:
67187497f52SBarry Smith    The type can be integer or floating point value
672d9a4bb16SJed Brown 
6733919e044SBarry Smith    Example\:
6743919e044SBarry Smith .vb
6753919e044SBarry Smith   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
6763919e044SBarry Smith   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
6773919e044SBarry Smith .ve
6783919e044SBarry Smith 
679db781477SPatrick Sanan .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
680d9a4bb16SJed Brown M*/
681d9a4bb16SJed Brown #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
682d9a4bb16SJed Brown 
683d9a4bb16SJed Brown /*MC
684b6a5bde7SBarry Smith    PetscAbsInt - Returns the absolute value of an integer
685b6a5bde7SBarry Smith 
686b6a5bde7SBarry Smith    Synopsis:
687aaa7dc30SBarry Smith    #include <petscmath.h>
688b6a5bde7SBarry Smith    int abs PetscAbsInt(int v1)
689b6a5bde7SBarry Smith 
690eca87e8dSBarry Smith    Input Parameter:
691eca87e8dSBarry Smith .   v1 - the integer
692b6a5bde7SBarry Smith 
693b6a5bde7SBarry Smith    Level: beginner
694b6a5bde7SBarry Smith 
695db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
696b6a5bde7SBarry Smith M*/
6979fa7d148SSatish Balay #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
698b6a5bde7SBarry Smith 
699b6a5bde7SBarry Smith /*MC
700e2b46ddfSPierre Jolivet    PetscAbsReal - Returns the absolute value of a real number
701b6a5bde7SBarry Smith 
702eca87e8dSBarry Smith    Synopsis:
703aaa7dc30SBarry Smith    #include <petscmath.h>
704eca87e8dSBarry Smith    Real abs PetscAbsReal(PetscReal v1)
705eca87e8dSBarry Smith 
706b6a5bde7SBarry Smith    Input Parameter:
70716a05f60SBarry Smith .   v1 - the `PetscReal` value
708b6a5bde7SBarry Smith 
709b6a5bde7SBarry Smith    Level: beginner
710b6a5bde7SBarry Smith 
7113fb7ca22SBarry Smith .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
712b6a5bde7SBarry Smith M*/
7131118d4bcSLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
7141118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7151118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7161118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabs(a)
7171118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
7181118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsq(a)
7191118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7201118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7211118d4bcSLisandro Dalcin #endif
722b6a5bde7SBarry Smith 
723b6a5bde7SBarry Smith /*MC
724b6a5bde7SBarry Smith    PetscSqr - Returns the square of a number
725b6a5bde7SBarry Smith 
726b6a5bde7SBarry Smith    Synopsis:
727aaa7dc30SBarry Smith    #include <petscmath.h>
728b6a5bde7SBarry Smith    type sqr PetscSqr(type v1)
729b6a5bde7SBarry Smith 
730eca87e8dSBarry Smith    Not Collective
731eca87e8dSBarry Smith 
732eca87e8dSBarry Smith    Input Parameter:
733eca87e8dSBarry Smith .   v1 - the value
734eca87e8dSBarry Smith 
73516a05f60SBarry Smith    Level: beginner
73616a05f60SBarry Smith 
73787497f52SBarry Smith    Note:
7383919e044SBarry Smith    The type can be integer, floating point, or complex floating point
739b6a5bde7SBarry Smith 
740db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
741b6a5bde7SBarry Smith M*/
7424ebda54eSMatthew Knepley #define PetscSqr(a) ((a) * (a))
743e489efc1SBarry Smith 
7443fb7ca22SBarry Smith /*MC
7453fb7ca22SBarry Smith    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
7463fb7ca22SBarry Smith    precision of `PetscReal` be it half, single, double or 128-bit representation
7473fb7ca22SBarry Smith 
7483fb7ca22SBarry Smith    Synopsis:
7493fb7ca22SBarry Smith    #include <petscmath.h>
7503fb7ca22SBarry Smith    PetscReal PetscRealConstant(real_number)
7513fb7ca22SBarry Smith 
7523fb7ca22SBarry Smith    Not Collective
7533fb7ca22SBarry Smith 
7543fb7ca22SBarry Smith    Input Parameter:
7553fb7ca22SBarry Smith .   v1 - the real number, for example 1.5
7563fb7ca22SBarry Smith 
7573fb7ca22SBarry Smith    Level: beginner
7583fb7ca22SBarry Smith 
7593fb7ca22SBarry Smith    Note:
7603fb7ca22SBarry Smith    For example, if PETSc is configured with `--with-precision=__float128` and one writes
7613fb7ca22SBarry Smith .vb
7623fb7ca22SBarry Smith    PetscReal d = 1.5;
7633fb7ca22SBarry Smith .ve
76456087ca1SPierre 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
7653fb7ca22SBarry Smith .vb
7663fb7ca22SBarry Smith    PetscReal d = PetscRealConstant(1.5);
7673fb7ca22SBarry Smith .ve
7683fb7ca22SBarry Smith 
7693fb7ca22SBarry Smith .seealso: `PetscReal`
7703fb7ca22SBarry Smith M*/
771ee223c85SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
772ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
7735117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7745117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant
775ee223c85SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
776ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##Q
7775117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7785117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
779ee223c85SLisandro Dalcin #endif
780ee223c85SLisandro Dalcin 
781314da920SBarry Smith /*
782d34fcf5fSBarry Smith      Basic constants
783314da920SBarry Smith */
7843fb7ca22SBarry Smith /*MC
7853fb7ca22SBarry Smith   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.
7863fb7ca22SBarry Smith 
7873fb7ca22SBarry Smith   Level: beginner
7883fb7ca22SBarry Smith 
7893fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
7903fb7ca22SBarry Smith M*/
7913fb7ca22SBarry Smith 
7923fb7ca22SBarry Smith /*MC
7933fb7ca22SBarry Smith   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.
7943fb7ca22SBarry Smith 
7953fb7ca22SBarry Smith   Level: beginner
7963fb7ca22SBarry Smith 
7973fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
7983fb7ca22SBarry Smith M*/
7993fb7ca22SBarry Smith 
8003fb7ca22SBarry Smith /*MC
8013fb7ca22SBarry Smith   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.
8023fb7ca22SBarry Smith 
8033fb7ca22SBarry Smith   Level: beginner
8043fb7ca22SBarry Smith 
8053fb7ca22SBarry Smith .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
8063fb7ca22SBarry Smith M*/
8073fb7ca22SBarry Smith 
8082fab75feSLisandro Dalcin #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
8092fab75feSLisandro Dalcin #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
8107b156302SMatthew G. Knepley #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
811d34fcf5fSBarry Smith 
8123fb7ca22SBarry Smith /*MC
8133fb7ca22SBarry Smith   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`
8143fb7ca22SBarry Smith 
8153fb7ca22SBarry Smith   Level: beginner
8163fb7ca22SBarry Smith 
8173fb7ca22SBarry Smith .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8183fb7ca22SBarry Smith M*/
8193fb7ca22SBarry Smith 
8203fb7ca22SBarry Smith /*MC
8213fb7ca22SBarry Smith   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`
8223fb7ca22SBarry Smith 
8233fb7ca22SBarry Smith   Level: beginner
8243fb7ca22SBarry Smith 
8253fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8263fb7ca22SBarry Smith M*/
8273fb7ca22SBarry Smith 
8283fb7ca22SBarry Smith /*MC
8293fb7ca22SBarry Smith   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.
8303fb7ca22SBarry Smith 
8313fb7ca22SBarry Smith   Level: beginner
8323fb7ca22SBarry Smith 
8333fb7ca22SBarry Smith   Note:
8343fb7ca22SBarry Smith   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers
8353fb7ca22SBarry Smith 
8363fb7ca22SBarry Smith   Developer Note:
8373fb7ca22SBarry Smith   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.
8383fb7ca22SBarry Smith 
8393fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8403fb7ca22SBarry Smith M*/
8413fb7ca22SBarry Smith 
8423fb7ca22SBarry Smith /*MC
8433fb7ca22SBarry Smith   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`
8443fb7ca22SBarry Smith 
8453fb7ca22SBarry Smith   Level: beginner
8463fb7ca22SBarry Smith 
8473fb7ca22SBarry Smith   Note:
8483fb7ca22SBarry Smith   See <https://en.wikipedia.org/wiki/Machine_epsilon>
8493fb7ca22SBarry Smith 
8503fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
8513fb7ca22SBarry Smith M*/
8523fb7ca22SBarry Smith 
8533fb7ca22SBarry Smith /*MC
8543fb7ca22SBarry Smith   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`
8553fb7ca22SBarry Smith 
8563fb7ca22SBarry Smith   Level: beginner
8573fb7ca22SBarry Smith 
8583fb7ca22SBarry Smith   Note:
8593fb7ca22SBarry Smith   See `PETSC_MACHINE_EPSILON`
8603fb7ca22SBarry Smith 
8613fb7ca22SBarry Smith .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
8623fb7ca22SBarry Smith M*/
8633fb7ca22SBarry Smith 
8643fb7ca22SBarry Smith /*MC
8653fb7ca22SBarry Smith   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
8663fb7ca22SBarry Smith   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.
8673fb7ca22SBarry Smith 
8683fb7ca22SBarry Smith   Level: beginner
8693fb7ca22SBarry Smith 
8703fb7ca22SBarry Smith   Note:
8713fb7ca22SBarry Smith   See `PETSC_MACHINE_EPSILON`
8723fb7ca22SBarry Smith 
8733fb7ca22SBarry Smith .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
8743fb7ca22SBarry Smith          `PETSC_SQRT_MACHINE_EPSILON`
8753fb7ca22SBarry Smith M*/
8763fb7ca22SBarry Smith 
877ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
878ab824b78SBarry Smith   #define PETSC_MAX_REAL             3.40282346638528860e+38F
8799fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
880f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             1.1754944e-38F
88182a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
88282a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
883ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-5F
884ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE)
885ab824b78SBarry Smith   #define PETSC_MAX_REAL             1.7976931348623157e+308
8869fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
887f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             2.225073858507201e-308
88882a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
88982a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
890cf6e855fSSatish Balay   #define PETSC_SMALL                1.e-10
891ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128)
892ea345e14SBarry Smith   #define PETSC_MAX_REAL             FLT128_MAX
8939fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-FLT128_MAX)
894f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             FLT128_MIN
895d34fcf5fSBarry Smith   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
896ee223c85SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
897ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-20Q
8985117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
8995117d392SLisandro Dalcin   #define PETSC_MAX_REAL             65504.0F
9009fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
901f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             .00006103515625F
9025117d392SLisandro Dalcin   #define PETSC_MACHINE_EPSILON      .0009765625F
9035117d392SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON .03125F
9045117d392SLisandro Dalcin   #define PETSC_SMALL                5.e-3F
9059cf09972SJed Brown #endif
9063e523bebSBarry Smith 
907945b2ebdSBarry Smith /*MC
908945b2ebdSBarry Smith   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
909945b2ebdSBarry Smith 
910945b2ebdSBarry Smith   Level: intermediate
911945b2ebdSBarry Smith 
912945b2ebdSBarry Smith   Note:
913945b2ebdSBarry Smith   This is not the IEEE infinity value
914945b2ebdSBarry Smith 
915945b2ebdSBarry Smith .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
916945b2ebdSBarry Smith M*/
91725d0f998SSatish Balay #define PETSC_INFINITY (PETSC_MAX_REAL / 4)
918945b2ebdSBarry Smith 
919945b2ebdSBarry Smith /*MC
920945b2ebdSBarry Smith   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
921945b2ebdSBarry Smith 
922945b2ebdSBarry Smith   Level: intermediate
923945b2ebdSBarry Smith 
924945b2ebdSBarry Smith   Note:
925945b2ebdSBarry Smith   This is not the negative IEEE infinity value
926945b2ebdSBarry Smith 
927945b2ebdSBarry Smith .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
928945b2ebdSBarry Smith M*/
9299fa7d148SSatish Balay #define PETSC_NINFINITY (-PETSC_INFINITY)
930e270355aSBarry Smith 
9319f4f8022SLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
9323948c36eSLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
9338b49ba18SBarry Smith PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
934d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
935d71ae5a4SJacob Faibussowitsch {
9369371c9d4SSatish Balay   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
9379371c9d4SSatish Balay }
938d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfScalar(PetscScalar v)
939d71ae5a4SJacob Faibussowitsch {
9409371c9d4SSatish Balay   return PetscIsInfReal(PetscAbsScalar(v));
9419371c9d4SSatish Balay }
942d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNanScalar(PetscScalar v)
943d71ae5a4SJacob Faibussowitsch {
9449371c9d4SSatish Balay   return PetscIsNanReal(PetscAbsScalar(v));
9459371c9d4SSatish Balay }
946d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
947d71ae5a4SJacob Faibussowitsch {
9489371c9d4SSatish Balay   return PetscIsInfOrNanReal(PetscAbsScalar(v));
9499371c9d4SSatish Balay }
950d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNormalScalar(PetscScalar v)
951d71ae5a4SJacob Faibussowitsch {
9529371c9d4SSatish Balay   return PetscIsNormalReal(PetscAbsScalar(v));
9539371c9d4SSatish Balay }
9549a25a3ccSBarry Smith 
955b10005b4SLisandro Dalcin PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
956ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
957ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
958ce4818fdSLisandro Dalcin 
95928dd6638SJacob Faibussowitsch /*@C
96028dd6638SJacob Faibussowitsch   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
96128dd6638SJacob Faibussowitsch 
96228dd6638SJacob Faibussowitsch   Input Parameters:
96328dd6638SJacob Faibussowitsch + lhs  - The first number
96428dd6638SJacob Faibussowitsch . rhs  - The second number
96528dd6638SJacob Faibussowitsch . rtol - The relative tolerance
96628dd6638SJacob Faibussowitsch - atol - The absolute tolerance
96728dd6638SJacob Faibussowitsch 
96828dd6638SJacob Faibussowitsch   Level: beginner
96928dd6638SJacob Faibussowitsch 
97028dd6638SJacob Faibussowitsch   Note:
97128dd6638SJacob Faibussowitsch   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
97228dd6638SJacob Faibussowitsch   numbers.
97328dd6638SJacob Faibussowitsch 
97428dd6638SJacob Faibussowitsch .seealso: `PetscIsCloseAtTol()`
97528dd6638SJacob Faibussowitsch @*/
97628dd6638SJacob Faibussowitsch static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
97728dd6638SJacob Faibussowitsch {
97828dd6638SJacob Faibussowitsch   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
97928dd6638SJacob Faibussowitsch 
98028dd6638SJacob Faibussowitsch   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
98128dd6638SJacob Faibussowitsch   return close;
98228dd6638SJacob Faibussowitsch }
98328dd6638SJacob Faibussowitsch 
98498725619SBarry Smith /*
98598725619SBarry Smith     These macros are currently hardwired to match the regular data types, so there is no support for a different
98698725619SBarry Smith     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
98798725619SBarry Smith  */
98898725619SBarry Smith #define MPIU_MATSCALAR MPIU_SCALAR
98998725619SBarry Smith typedef PetscScalar MatScalar;
99098725619SBarry Smith typedef PetscReal   MatReal;
99198725619SBarry Smith 
9929371c9d4SSatish Balay struct petsc_mpiu_2scalar {
9939371c9d4SSatish Balay   PetscScalar a, b;
9949371c9d4SSatish Balay };
99593d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);
996df4397b0SStefano Zampini 
99793d501b3SJacob Faibussowitsch /* MPI Datatypes for composite reductions */
99893d501b3SJacob Faibussowitsch struct petsc_mpiu_real_int {
99993d501b3SJacob Faibussowitsch   PetscReal v;
100093d501b3SJacob Faibussowitsch   PetscInt  i;
100193d501b3SJacob Faibussowitsch };
100293d501b3SJacob Faibussowitsch 
100393d501b3SJacob Faibussowitsch struct petsc_mpiu_scalar_int {
100493d501b3SJacob Faibussowitsch   PetscScalar v;
100593d501b3SJacob Faibussowitsch   PetscInt    i;
100693d501b3SJacob Faibussowitsch };
100793d501b3SJacob Faibussowitsch 
100893d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
100993d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
1010092991acSStefano Zampini 
1011a616ada9SVaclav Hapla #if defined(PETSC_USE_64BIT_INDICES)
101293d501b3SJacob Faibussowitsch struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
101393d501b3SJacob Faibussowitsch   PetscInt a;
101493d501b3SJacob Faibussowitsch   PetscInt b;
10159371c9d4SSatish Balay };
1016*6497c311SBarry Smith struct __attribute__((packed)) petsc_mpiu_int_mpiint {
1017*6497c311SBarry Smith   PetscInt    a;
1018*6497c311SBarry Smith   PetscMPIInt b;
1019*6497c311SBarry Smith };
102093d501b3SJacob Faibussowitsch /*
102193d501b3SJacob Faibussowitsch  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
102293d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
102393d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
102493d501b3SJacob Faibussowitsch 
102593d501b3SJacob Faibussowitsch  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
102693d501b3SJacob Faibussowitsch  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
102793d501b3SJacob Faibussowitsch  pass! So we just comment it out...
102893d501b3SJacob Faibussowitsch */
102993d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
1030*6497c311SBarry Smith PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
10318ad47952SJed Brown #else
10328ad47952SJed Brown   #define MPIU_2INT       MPI_2INT
1033*6497c311SBarry Smith   #define MPIU_INT_MPIINT MPI_2INT
10348ad47952SJed Brown #endif
1035b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPI_4INT;
1036b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPIU_4INT;
1037e9fa29b7SSatish Balay 
1038d71ae5a4SJacob Faibussowitsch static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
1039d71ae5a4SJacob Faibussowitsch {
1040fa711258SJed Brown   PetscInt result = 1;
1041fa711258SJed Brown   while (power) {
1042fa711258SJed Brown     if (power & 1) result *= base;
1043fa711258SJed Brown     power >>= 1;
10446f2c871aSStefano Zampini     if (power) base *= base;
1045fa711258SJed Brown   }
1046fa711258SJed Brown   return result;
1047fa711258SJed Brown }
1048b2fb0278SBarry Smith 
1049d71ae5a4SJacob Faibussowitsch static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
1050d71ae5a4SJacob Faibussowitsch {
1051ad70a4c3SStefano Zampini   PetscInt64 result = 1;
1052ad70a4c3SStefano Zampini   while (power) {
1053ad70a4c3SStefano Zampini     if (power & 1) result *= base;
1054ad70a4c3SStefano Zampini     power >>= 1;
10556f2c871aSStefano Zampini     if (power) base *= base;
1056ad70a4c3SStefano Zampini   }
1057ad70a4c3SStefano Zampini   return result;
1058ad70a4c3SStefano Zampini }
1059ad70a4c3SStefano Zampini 
1060d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
1061d71ae5a4SJacob Faibussowitsch {
1062fa711258SJed Brown   PetscReal result = 1;
1063d98d5da7SBarry Smith   if (power < 0) {
1064d98d5da7SBarry Smith     power = -power;
106510d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
1066d98d5da7SBarry Smith   }
1067fa711258SJed Brown   while (power) {
1068fa711258SJed Brown     if (power & 1) result *= base;
1069fa711258SJed Brown     power >>= 1;
10706f2c871aSStefano Zampini     if (power) base *= base;
1071fa711258SJed Brown   }
1072fa711258SJed Brown   return result;
1073fa711258SJed Brown }
1074fa711258SJed Brown 
1075d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
1076d71ae5a4SJacob Faibussowitsch {
10775117d392SLisandro Dalcin   PetscScalar result = (PetscReal)1;
10788b49ba18SBarry Smith   if (power < 0) {
10798b49ba18SBarry Smith     power = -power;
108010d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
10818b49ba18SBarry Smith   }
10828b49ba18SBarry Smith   while (power) {
10838b49ba18SBarry Smith     if (power & 1) result *= base;
10848b49ba18SBarry Smith     power >>= 1;
10856f2c871aSStefano Zampini     if (power) base *= base;
10868b49ba18SBarry Smith   }
10878b49ba18SBarry Smith   return result;
10888b49ba18SBarry Smith }
10898b49ba18SBarry Smith 
1090d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
1091d71ae5a4SJacob Faibussowitsch {
1092b2fb0278SBarry Smith   PetscScalar cpower = power;
1093b2fb0278SBarry Smith   return PetscPowScalar(base, cpower);
1094b2fb0278SBarry Smith }
109578a59e97SMatthew G. Knepley 
1096c803a25aSBarry Smith /*MC
109766baab88SBarry Smith    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
1098c803a25aSBarry Smith 
1099c803a25aSBarry Smith    Synopsis:
1100c803a25aSBarry Smith    #include <petscmath.h>
110166baab88SBarry Smith    bool PetscApproximateLTE(PetscReal x,constant float)
1102c803a25aSBarry Smith 
1103c803a25aSBarry Smith    Not Collective
1104c803a25aSBarry Smith 
1105c803a25aSBarry Smith    Input Parameters:
1106c803a25aSBarry Smith +   x - the variable
110716a05f60SBarry Smith -   b - the constant float it is checking if `x` is less than or equal to
110816a05f60SBarry Smith 
110916a05f60SBarry Smith    Level: advanced
1110c803a25aSBarry Smith 
1111c803a25aSBarry Smith    Notes:
111287497f52SBarry Smith    The fudge factor is the value `PETSC_SMALL`
1113c803a25aSBarry Smith 
1114c803a25aSBarry Smith    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
1115c803a25aSBarry Smith 
1116c803a25aSBarry Smith    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
1117c803a25aSBarry Smith    floating point results.
1118c803a25aSBarry Smith 
11193919e044SBarry Smith    Example\:
11203919e044SBarry Smith .vb
11213919e044SBarry Smith   PetscReal x;
11223919e044SBarry Smith   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
11233919e044SBarry Smith .ve
11243919e044SBarry Smith 
1125db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
1126c803a25aSBarry Smith M*/
112766baab88SBarry Smith #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
1128c803a25aSBarry Smith 
1129c803a25aSBarry Smith /*MC
113066baab88SBarry Smith    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
1131c803a25aSBarry Smith 
1132c803a25aSBarry Smith    Synopsis:
1133c803a25aSBarry Smith    #include <petscmath.h>
113466baab88SBarry Smith    bool PetscApproximateGTE(PetscReal x,constant float)
1135c803a25aSBarry Smith 
1136c803a25aSBarry Smith    Not Collective
1137c803a25aSBarry Smith 
1138c803a25aSBarry Smith    Input Parameters:
1139c803a25aSBarry Smith +   x - the variable
114016a05f60SBarry Smith -   b - the constant float it is checking if `x` is greater than or equal to
114116a05f60SBarry Smith 
114216a05f60SBarry Smith    Level: advanced
1143c803a25aSBarry Smith 
1144c803a25aSBarry Smith    Notes:
114587497f52SBarry Smith    The fudge factor is the value `PETSC_SMALL`
1146c803a25aSBarry Smith 
1147c803a25aSBarry Smith    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
1148c803a25aSBarry Smith 
1149c803a25aSBarry Smith    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
1150c803a25aSBarry Smith    floating point results.
1151c803a25aSBarry Smith 
11523919e044SBarry Smith    Example\:
11533919e044SBarry Smith .vb
11543919e044SBarry Smith   PetscReal x;
11553919e044SBarry Smith   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
11563919e044SBarry Smith .ve
11573919e044SBarry Smith 
1158db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1159c803a25aSBarry Smith M*/
116066baab88SBarry Smith #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
1161c803a25aSBarry Smith 
1162faa75363SBarry Smith /*MC
1163faa75363SBarry Smith    PetscCeilInt - Returns the ceiling of the quotation of two positive integers
1164faa75363SBarry Smith 
1165faa75363SBarry Smith    Synopsis:
1166faa75363SBarry Smith    #include <petscmath.h>
1167faa75363SBarry Smith    PetscInt PetscCeilInt(PetscInt x,PetscInt y)
1168faa75363SBarry Smith 
1169faa75363SBarry Smith    Not Collective
1170faa75363SBarry Smith 
1171faa75363SBarry Smith    Input Parameters:
1172faa75363SBarry Smith +   x - the numerator
1173faa75363SBarry Smith -   y - the denominator
1174faa75363SBarry Smith 
1175faa75363SBarry Smith    Level: advanced
1176faa75363SBarry Smith 
11773919e044SBarry Smith   Example\:
11783919e044SBarry Smith .vb
11793919e044SBarry Smith   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
11803919e044SBarry Smith .ve
11813919e044SBarry Smith 
1182db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1183faa75363SBarry Smith M*/
1184faa75363SBarry Smith #define PetscCeilInt(x, y) ((((PetscInt)(x)) / ((PetscInt)(y))) + ((((PetscInt)(x)) % ((PetscInt)(y))) ? 1 : 0))
1185faa75363SBarry Smith 
1186faa75363SBarry Smith #define PetscCeilInt64(x, y) ((((PetscInt64)(x)) / ((PetscInt64)(y))) + ((((PetscInt64)(x)) % ((PetscInt64)(y))) ? 1 : 0))
1187faa75363SBarry Smith 
1188bebf13c0SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);
1189