xref: /petsc/include/petscmath.h (revision 945b2ebdc5b7ebcb622acfbe60dbc4e0db537728)
1e489efc1SBarry Smith /*
2314da920SBarry Smith 
3314da920SBarry Smith     PETSc mathematics include file. Defines certain basic mathematical
4a5057860SBarry Smith     constants and functions for working with single, double, and quad precision
5a5057860SBarry Smith     floating point numbers as well as complex single and double.
6314da920SBarry Smith 
7d382aafbSBarry Smith     This file is included by petscsys.h and should not be used directly.
8e7029fe1SSatish Balay 
9e489efc1SBarry Smith */
10a4963045SJacob Faibussowitsch #pragma once
11ac09b921SBarry Smith 
120a5f7794SBarry Smith #include <math.h>
1393d501b3SJacob Faibussowitsch #include <petscmacros.h>
14df4397b0SStefano Zampini #include <petscsystypes.h>
15df4397b0SStefano Zampini 
16ac09b921SBarry Smith /* SUBMANSEC = Sys */
17ac09b921SBarry Smith 
185117d392SLisandro Dalcin /*
195117d392SLisandro Dalcin 
205117d392SLisandro Dalcin    Defines operations that are different for complex and real numbers.
215117d392SLisandro Dalcin    All PETSc objects in one program are built around the object
225117d392SLisandro Dalcin    PetscScalar which is either always a real or a complex.
235117d392SLisandro Dalcin 
245117d392SLisandro Dalcin */
255117d392SLisandro Dalcin 
265117d392SLisandro Dalcin /*
275117d392SLisandro Dalcin     Real number definitions
285117d392SLisandro Dalcin  */
295117d392SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
305117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtf(a)
315117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtf(a)
325117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotf(a, b)
335117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2f(a, b)
345117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powf(a, b)
355117d392SLisandro Dalcin   #define PetscExpReal(a)         expf(a)
365117d392SLisandro Dalcin   #define PetscLogReal(a)         logf(a)
375117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10f(a)
385117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2f(a)
395117d392SLisandro Dalcin   #define PetscSinReal(a)         sinf(a)
405117d392SLisandro Dalcin   #define PetscCosReal(a)         cosf(a)
415117d392SLisandro Dalcin   #define PetscTanReal(a)         tanf(a)
425117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinf(a)
435117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosf(a)
445117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanf(a)
455117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhf(a)
465117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshf(a)
475117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhf(a)
485117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhf(a)
495117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshf(a)
505117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhf(a)
51d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erff(a)
525117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilf(a)
535117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorf(a)
545117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
559c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignf(a, b)
565117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaf(a)
571f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
581f17fa70SToby Isaac     #define PetscLGamma(a) gammaf(a)
591f17fa70SToby Isaac   #else
601f17fa70SToby Isaac     #define PetscLGamma(a) lgammaf(a)
611f17fa70SToby Isaac   #endif
625117d392SLisandro Dalcin 
635117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
645117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrt(a)
655117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrt(a)
665117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypot(a, b)
675117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2(a, b)
685117d392SLisandro Dalcin   #define PetscPowReal(a, b)      pow(a, b)
695117d392SLisandro Dalcin   #define PetscExpReal(a)         exp(a)
705117d392SLisandro Dalcin   #define PetscLogReal(a)         log(a)
715117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10(a)
725117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2(a)
735117d392SLisandro Dalcin   #define PetscSinReal(a)         sin(a)
745117d392SLisandro Dalcin   #define PetscCosReal(a)         cos(a)
755117d392SLisandro Dalcin   #define PetscTanReal(a)         tan(a)
765117d392SLisandro Dalcin   #define PetscAsinReal(a)        asin(a)
775117d392SLisandro Dalcin   #define PetscAcosReal(a)        acos(a)
785117d392SLisandro Dalcin   #define PetscAtanReal(a)        atan(a)
795117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinh(a)
805117d392SLisandro Dalcin   #define PetscCoshReal(a)        cosh(a)
815117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanh(a)
825117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinh(a)
835117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acosh(a)
845117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanh(a)
85d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erf(a)
865117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceil(a)
875117d392SLisandro Dalcin   #define PetscFloorReal(a)       floor(a)
885117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmod(a, b)
899c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysign(a, b)
905117d392SLisandro Dalcin   #define PetscTGamma(a)          tgamma(a)
911f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
921f17fa70SToby Isaac     #define PetscLGamma(a) gamma(a)
931f17fa70SToby Isaac   #else
941f17fa70SToby Isaac     #define PetscLGamma(a) lgamma(a)
951f17fa70SToby Isaac   #endif
965117d392SLisandro Dalcin 
975117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
985117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtq(a)
995117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtq(a)
1005117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotq(a, b)
1015117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2q(a, b)
1025117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powq(a, b)
1035117d392SLisandro Dalcin   #define PetscExpReal(a)         expq(a)
1045117d392SLisandro Dalcin   #define PetscLogReal(a)         logq(a)
1055117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10q(a)
1065117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2q(a)
1075117d392SLisandro Dalcin   #define PetscSinReal(a)         sinq(a)
1085117d392SLisandro Dalcin   #define PetscCosReal(a)         cosq(a)
1095117d392SLisandro Dalcin   #define PetscTanReal(a)         tanq(a)
1105117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinq(a)
1115117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosq(a)
1125117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanq(a)
1135117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhq(a)
1145117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshq(a)
1155117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhq(a)
1165117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhq(a)
1175117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshq(a)
1185117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhq(a)
119d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erfq(a)
1205117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilq(a)
1215117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorq(a)
1225117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodq(a, b)
1239c3ee494SJed Brown   #define PetscCopysignReal(a, b) copysignq(a, b)
1245117d392SLisandro Dalcin   #define PetscTGamma(a)          tgammaq(a)
1251f17fa70SToby Isaac   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
1261f17fa70SToby Isaac     #define PetscLGamma(a) gammaq(a)
1271f17fa70SToby Isaac   #else
1281f17fa70SToby Isaac     #define PetscLGamma(a) lgammaq(a)
1291f17fa70SToby Isaac   #endif
1305117d392SLisandro Dalcin 
1315117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
1325117d392SLisandro Dalcin   #define PetscSqrtReal(a)        sqrtf(a)
1335117d392SLisandro Dalcin   #define PetscCbrtReal(a)        cbrtf(a)
1345117d392SLisandro Dalcin   #define PetscHypotReal(a, b)    hypotf(a, b)
1355117d392SLisandro Dalcin   #define PetscAtan2Real(a, b)    atan2f(a, b)
1365117d392SLisandro Dalcin   #define PetscPowReal(a, b)      powf(a, b)
1375117d392SLisandro Dalcin   #define PetscExpReal(a)         expf(a)
1385117d392SLisandro Dalcin   #define PetscLogReal(a)         logf(a)
1395117d392SLisandro Dalcin   #define PetscLog10Real(a)       log10f(a)
1405117d392SLisandro Dalcin   #define PetscLog2Real(a)        log2f(a)
1415117d392SLisandro Dalcin   #define PetscSinReal(a)         sinf(a)
1425117d392SLisandro Dalcin   #define PetscCosReal(a)         cosf(a)
1435117d392SLisandro Dalcin   #define PetscTanReal(a)         tanf(a)
1445117d392SLisandro Dalcin   #define PetscAsinReal(a)        asinf(a)
1455117d392SLisandro Dalcin   #define PetscAcosReal(a)        acosf(a)
1465117d392SLisandro Dalcin   #define PetscAtanReal(a)        atanf(a)
1475117d392SLisandro Dalcin   #define PetscSinhReal(a)        sinhf(a)
1485117d392SLisandro Dalcin   #define PetscCoshReal(a)        coshf(a)
1495117d392SLisandro Dalcin   #define PetscTanhReal(a)        tanhf(a)
1505117d392SLisandro Dalcin   #define PetscAsinhReal(a)       asinhf(a)
1515117d392SLisandro Dalcin   #define PetscAcoshReal(a)       acoshf(a)
1525117d392SLisandro Dalcin   #define PetscAtanhReal(a)       atanhf(a)
153d6685f55SMatthew G. Knepley   #define PetscErfReal(a)         erff(a)
1545117d392SLisandro Dalcin   #define PetscCeilReal(a)        ceilf(a)
1555117d392SLisandro Dalcin   #define PetscFloorReal(a)       floorf(a)
1565117d392SLisandro Dalcin   #define PetscFmodReal(a, b)     fmodf(a, b)
1579c3ee494SJed Brown   #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 
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
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    Notes:
19187497f52SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
192df4397b0SStefano Zampini 
193df4397b0SStefano Zampini    Level: beginner
194df4397b0SStefano Zampini 
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 
3811093a601SBarry Smith /*
3825117d392SLisandro Dalcin    PETSC_i is the imaginary number, i
3831093a601SBarry Smith */
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    Notes:
43887497f52SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
4395117d392SLisandro Dalcin 
4405117d392SLisandro Dalcin    Level: beginner
4415117d392SLisandro Dalcin 
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    Notes:
46487497f52SBarry Smith    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
4655117d392SLisandro Dalcin 
4665117d392SLisandro Dalcin    Level: beginner
4675117d392SLisandro Dalcin 
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 
5045117d392SLisandro Dalcin    Notes:
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
5905117d392SLisandro Dalcin    PetscSign - Returns the sign of a number as an integer
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:
62687497f52SBarry Smith    The type can be integer or floating point value
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 
673db781477SPatrick Sanan .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
674d9a4bb16SJed Brown M*/
675d9a4bb16SJed Brown #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
676d9a4bb16SJed Brown 
677d9a4bb16SJed Brown /*MC
678b6a5bde7SBarry Smith    PetscAbsInt - Returns the absolute value of an integer
679b6a5bde7SBarry Smith 
680b6a5bde7SBarry Smith    Synopsis:
681aaa7dc30SBarry Smith    #include <petscmath.h>
682b6a5bde7SBarry Smith    int abs PetscAbsInt(int v1)
683b6a5bde7SBarry Smith 
684eca87e8dSBarry Smith    Input Parameter:
685eca87e8dSBarry Smith .   v1 - the integer
686b6a5bde7SBarry Smith 
687b6a5bde7SBarry Smith    Level: beginner
688b6a5bde7SBarry Smith 
689db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
690b6a5bde7SBarry Smith M*/
6919fa7d148SSatish Balay #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
692b6a5bde7SBarry Smith 
693b6a5bde7SBarry Smith /*MC
694b6a5bde7SBarry Smith    PetscAbsReal - Returns the absolute value of an real number
695b6a5bde7SBarry Smith 
696eca87e8dSBarry Smith    Synopsis:
697aaa7dc30SBarry Smith    #include <petscmath.h>
698eca87e8dSBarry Smith    Real abs PetscAbsReal(PetscReal v1)
699eca87e8dSBarry Smith 
700b6a5bde7SBarry Smith    Input Parameter:
70116a05f60SBarry Smith .   v1 - the `PetscReal` value
702b6a5bde7SBarry Smith 
703b6a5bde7SBarry Smith    Level: beginner
704b6a5bde7SBarry Smith 
705db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
706b6a5bde7SBarry Smith M*/
7071118d4bcSLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
7081118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7091118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7101118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabs(a)
7111118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
7121118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsq(a)
7131118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7141118d4bcSLisandro Dalcin   #define PetscAbsReal(a) fabsf(a)
7151118d4bcSLisandro Dalcin #endif
716b6a5bde7SBarry Smith 
717b6a5bde7SBarry Smith /*MC
718b6a5bde7SBarry Smith    PetscSqr - Returns the square of a number
719b6a5bde7SBarry Smith 
720b6a5bde7SBarry Smith    Synopsis:
721aaa7dc30SBarry Smith    #include <petscmath.h>
722b6a5bde7SBarry Smith    type sqr PetscSqr(type v1)
723b6a5bde7SBarry Smith 
724eca87e8dSBarry Smith    Not Collective
725eca87e8dSBarry Smith 
726eca87e8dSBarry Smith    Input Parameter:
727eca87e8dSBarry Smith .   v1 - the value
728eca87e8dSBarry Smith 
72916a05f60SBarry Smith    Level: beginner
73016a05f60SBarry Smith 
73187497f52SBarry Smith    Note:
73287497f52SBarry Smith    The type can be integer or floating point value
733b6a5bde7SBarry Smith 
734db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
735b6a5bde7SBarry Smith M*/
7364ebda54eSMatthew Knepley #define PetscSqr(a) ((a) * (a))
737e489efc1SBarry Smith 
738ee223c85SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
739ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
7405117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7415117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant
742ee223c85SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
743ee223c85SLisandro Dalcin   #define PetscRealConstant(constant) constant##Q
7445117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7455117d392SLisandro Dalcin   #define PetscRealConstant(constant) constant##F
746ee223c85SLisandro Dalcin #endif
747ee223c85SLisandro Dalcin 
748314da920SBarry Smith /*
749d34fcf5fSBarry Smith      Basic constants
750314da920SBarry Smith */
7512fab75feSLisandro Dalcin #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
7522fab75feSLisandro Dalcin #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
7537b156302SMatthew G. Knepley #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
754d34fcf5fSBarry Smith 
755ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
756ab824b78SBarry Smith   #define PETSC_MAX_REAL             3.40282346638528860e+38F
7579fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
758f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             1.1754944e-38F
75982a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
76082a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
761ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-5F
762ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE)
763ab824b78SBarry Smith   #define PETSC_MAX_REAL             1.7976931348623157e+308
7649fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
765f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             2.225073858507201e-308
76682a7e548SBarry Smith   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
76782a7e548SBarry Smith   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
768cf6e855fSSatish Balay   #define PETSC_SMALL                1.e-10
769ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128)
770ea345e14SBarry Smith   #define PETSC_MAX_REAL             FLT128_MAX
7719fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-FLT128_MAX)
772f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             FLT128_MIN
773d34fcf5fSBarry Smith   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
774ee223c85SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
775ee223c85SLisandro Dalcin   #define PETSC_SMALL                1.e-20Q
7765117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7775117d392SLisandro Dalcin   #define PETSC_MAX_REAL             65504.0F
7789fa7d148SSatish Balay   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
779f87a0b54SStefano Zampini   #define PETSC_REAL_MIN             .00006103515625F
7805117d392SLisandro Dalcin   #define PETSC_MACHINE_EPSILON      .0009765625F
7815117d392SLisandro Dalcin   #define PETSC_SQRT_MACHINE_EPSILON .03125F
7825117d392SLisandro Dalcin   #define PETSC_SMALL                5.e-3F
7839cf09972SJed Brown #endif
7843e523bebSBarry Smith 
785*945b2ebdSBarry Smith /*MC
786*945b2ebdSBarry Smith     PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
787*945b2ebdSBarry Smith 
788*945b2ebdSBarry Smith    Level: intermediate
789*945b2ebdSBarry Smith 
790*945b2ebdSBarry Smith   Note:
791*945b2ebdSBarry Smith   This is not the IEEE infinity value
792*945b2ebdSBarry Smith 
793*945b2ebdSBarry Smith .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
794*945b2ebdSBarry Smith M*/
79525d0f998SSatish Balay #define PETSC_INFINITY  (PETSC_MAX_REAL / 4)
796*945b2ebdSBarry Smith 
797*945b2ebdSBarry Smith /*MC
798*945b2ebdSBarry Smith     PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
799*945b2ebdSBarry Smith 
800*945b2ebdSBarry Smith    Level: intermediate
801*945b2ebdSBarry Smith 
802*945b2ebdSBarry Smith   Note:
803*945b2ebdSBarry Smith   This is not the negative IEEE infinity value
804*945b2ebdSBarry Smith 
805*945b2ebdSBarry Smith .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
806*945b2ebdSBarry Smith M*/
8079fa7d148SSatish Balay #define PETSC_NINFINITY (-PETSC_INFINITY)
808e270355aSBarry Smith 
8099f4f8022SLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
8103948c36eSLisandro Dalcin PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
8118b49ba18SBarry Smith PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
812d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
813d71ae5a4SJacob Faibussowitsch {
8149371c9d4SSatish Balay   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
8159371c9d4SSatish Balay }
816d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfScalar(PetscScalar v)
817d71ae5a4SJacob Faibussowitsch {
8189371c9d4SSatish Balay   return PetscIsInfReal(PetscAbsScalar(v));
8199371c9d4SSatish Balay }
820d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNanScalar(PetscScalar v)
821d71ae5a4SJacob Faibussowitsch {
8229371c9d4SSatish Balay   return PetscIsNanReal(PetscAbsScalar(v));
8239371c9d4SSatish Balay }
824d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
825d71ae5a4SJacob Faibussowitsch {
8269371c9d4SSatish Balay   return PetscIsInfOrNanReal(PetscAbsScalar(v));
8279371c9d4SSatish Balay }
828d71ae5a4SJacob Faibussowitsch static inline PetscBool PetscIsNormalScalar(PetscScalar v)
829d71ae5a4SJacob Faibussowitsch {
8309371c9d4SSatish Balay   return PetscIsNormalReal(PetscAbsScalar(v));
8319371c9d4SSatish Balay }
8329a25a3ccSBarry Smith 
833b10005b4SLisandro Dalcin PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
834ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
835ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
836ce4818fdSLisandro Dalcin 
83728dd6638SJacob Faibussowitsch /*@C
83828dd6638SJacob Faibussowitsch   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
83928dd6638SJacob Faibussowitsch 
84028dd6638SJacob Faibussowitsch   Input Parameters:
84128dd6638SJacob Faibussowitsch + lhs  - The first number
84228dd6638SJacob Faibussowitsch . rhs  - The second number
84328dd6638SJacob Faibussowitsch . rtol - The relative tolerance
84428dd6638SJacob Faibussowitsch - atol - The absolute tolerance
84528dd6638SJacob Faibussowitsch 
84628dd6638SJacob Faibussowitsch   Level: beginner
84728dd6638SJacob Faibussowitsch 
84828dd6638SJacob Faibussowitsch   Note:
84928dd6638SJacob Faibussowitsch   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
85028dd6638SJacob Faibussowitsch   numbers.
85128dd6638SJacob Faibussowitsch 
85228dd6638SJacob Faibussowitsch .seealso: `PetscIsCloseAtTol()`
85328dd6638SJacob Faibussowitsch @*/
85428dd6638SJacob Faibussowitsch static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
85528dd6638SJacob Faibussowitsch {
85628dd6638SJacob Faibussowitsch   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
85728dd6638SJacob Faibussowitsch 
85828dd6638SJacob Faibussowitsch   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
85928dd6638SJacob Faibussowitsch   return close;
86028dd6638SJacob Faibussowitsch }
86128dd6638SJacob Faibussowitsch 
86298725619SBarry Smith /*
86398725619SBarry Smith     These macros are currently hardwired to match the regular data types, so there is no support for a different
86498725619SBarry Smith     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
86598725619SBarry Smith  */
86698725619SBarry Smith #define MPIU_MATSCALAR MPIU_SCALAR
86798725619SBarry Smith typedef PetscScalar MatScalar;
86898725619SBarry Smith typedef PetscReal   MatReal;
86998725619SBarry Smith 
8709371c9d4SSatish Balay struct petsc_mpiu_2scalar {
8719371c9d4SSatish Balay   PetscScalar a, b;
8729371c9d4SSatish Balay };
87393d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);
874df4397b0SStefano Zampini 
87593d501b3SJacob Faibussowitsch /* MPI Datatypes for composite reductions */
87693d501b3SJacob Faibussowitsch struct petsc_mpiu_real_int {
87793d501b3SJacob Faibussowitsch   PetscReal v;
87893d501b3SJacob Faibussowitsch   PetscInt  i;
87993d501b3SJacob Faibussowitsch };
88093d501b3SJacob Faibussowitsch 
88193d501b3SJacob Faibussowitsch struct petsc_mpiu_scalar_int {
88293d501b3SJacob Faibussowitsch   PetscScalar v;
88393d501b3SJacob Faibussowitsch   PetscInt    i;
88493d501b3SJacob Faibussowitsch };
88593d501b3SJacob Faibussowitsch 
88693d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
88793d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
888092991acSStefano Zampini 
889a616ada9SVaclav Hapla #if defined(PETSC_USE_64BIT_INDICES)
89093d501b3SJacob Faibussowitsch struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
89193d501b3SJacob Faibussowitsch   PetscInt a;
89293d501b3SJacob Faibussowitsch   PetscInt b;
8939371c9d4SSatish Balay };
89493d501b3SJacob Faibussowitsch /*
89593d501b3SJacob Faibussowitsch  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
89693d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
89793d501b3SJacob Faibussowitsch  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
89893d501b3SJacob Faibussowitsch 
89993d501b3SJacob Faibussowitsch  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
90093d501b3SJacob Faibussowitsch  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
90193d501b3SJacob Faibussowitsch  pass! So we just comment it out...
90293d501b3SJacob Faibussowitsch */
90393d501b3SJacob Faibussowitsch PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
9048ad47952SJed Brown #else
9058ad47952SJed Brown   #define MPIU_2INT MPI_2INT
9068ad47952SJed Brown #endif
907b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPI_4INT;
908b5a892a1SMatthew G. Knepley PETSC_EXTERN MPI_Datatype MPIU_4INT;
909e9fa29b7SSatish Balay 
910d71ae5a4SJacob Faibussowitsch static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
911d71ae5a4SJacob Faibussowitsch {
912fa711258SJed Brown   PetscInt result = 1;
913fa711258SJed Brown   while (power) {
914fa711258SJed Brown     if (power & 1) result *= base;
915fa711258SJed Brown     power >>= 1;
9166f2c871aSStefano Zampini     if (power) base *= base;
917fa711258SJed Brown   }
918fa711258SJed Brown   return result;
919fa711258SJed Brown }
920b2fb0278SBarry Smith 
921d71ae5a4SJacob Faibussowitsch static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
922d71ae5a4SJacob Faibussowitsch {
923ad70a4c3SStefano Zampini   PetscInt64 result = 1;
924ad70a4c3SStefano Zampini   while (power) {
925ad70a4c3SStefano Zampini     if (power & 1) result *= base;
926ad70a4c3SStefano Zampini     power >>= 1;
9276f2c871aSStefano Zampini     if (power) base *= base;
928ad70a4c3SStefano Zampini   }
929ad70a4c3SStefano Zampini   return result;
930ad70a4c3SStefano Zampini }
931ad70a4c3SStefano Zampini 
932d71ae5a4SJacob Faibussowitsch static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
933d71ae5a4SJacob Faibussowitsch {
934fa711258SJed Brown   PetscReal result = 1;
935d98d5da7SBarry Smith   if (power < 0) {
936d98d5da7SBarry Smith     power = -power;
93710d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
938d98d5da7SBarry Smith   }
939fa711258SJed Brown   while (power) {
940fa711258SJed Brown     if (power & 1) result *= base;
941fa711258SJed Brown     power >>= 1;
9426f2c871aSStefano Zampini     if (power) base *= base;
943fa711258SJed Brown   }
944fa711258SJed Brown   return result;
945fa711258SJed Brown }
946fa711258SJed Brown 
947d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
948d71ae5a4SJacob Faibussowitsch {
9495117d392SLisandro Dalcin   PetscScalar result = (PetscReal)1;
9508b49ba18SBarry Smith   if (power < 0) {
9518b49ba18SBarry Smith     power = -power;
95210d40e53SLisandro Dalcin     base  = ((PetscReal)1) / base;
9538b49ba18SBarry Smith   }
9548b49ba18SBarry Smith   while (power) {
9558b49ba18SBarry Smith     if (power & 1) result *= base;
9568b49ba18SBarry Smith     power >>= 1;
9576f2c871aSStefano Zampini     if (power) base *= base;
9588b49ba18SBarry Smith   }
9598b49ba18SBarry Smith   return result;
9608b49ba18SBarry Smith }
9618b49ba18SBarry Smith 
962d71ae5a4SJacob Faibussowitsch static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
963d71ae5a4SJacob Faibussowitsch {
964b2fb0278SBarry Smith   PetscScalar cpower = power;
965b2fb0278SBarry Smith   return PetscPowScalar(base, cpower);
966b2fb0278SBarry Smith }
96778a59e97SMatthew G. Knepley 
968c803a25aSBarry Smith /*MC
96966baab88SBarry Smith     PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
970c803a25aSBarry Smith 
971c803a25aSBarry Smith    Synopsis:
972c803a25aSBarry Smith    #include <petscmath.h>
97366baab88SBarry Smith    bool PetscApproximateLTE(PetscReal x,constant float)
974c803a25aSBarry Smith 
975c803a25aSBarry Smith    Not Collective
976c803a25aSBarry Smith 
977c803a25aSBarry Smith    Input Parameters:
978c803a25aSBarry Smith +   x - the variable
97916a05f60SBarry Smith -   b - the constant float it is checking if `x` is less than or equal to
98016a05f60SBarry Smith 
98116a05f60SBarry Smith    Level: advanced
982c803a25aSBarry Smith 
983c803a25aSBarry Smith    Notes:
98487497f52SBarry Smith      The fudge factor is the value `PETSC_SMALL`
985c803a25aSBarry Smith 
986c803a25aSBarry Smith      The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
987c803a25aSBarry Smith 
988c803a25aSBarry Smith      This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
989c803a25aSBarry Smith      floating point results.
990c803a25aSBarry Smith 
991db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
992c803a25aSBarry Smith M*/
99366baab88SBarry Smith #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
994c803a25aSBarry Smith 
995c803a25aSBarry Smith /*MC
99666baab88SBarry Smith     PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
997c803a25aSBarry Smith 
998c803a25aSBarry Smith    Synopsis:
999c803a25aSBarry Smith    #include <petscmath.h>
100066baab88SBarry Smith    bool PetscApproximateGTE(PetscReal x,constant float)
1001c803a25aSBarry Smith 
1002c803a25aSBarry Smith    Not Collective
1003c803a25aSBarry Smith 
1004c803a25aSBarry Smith    Input Parameters:
1005c803a25aSBarry Smith +   x - the variable
100616a05f60SBarry Smith -   b - the constant float it is checking if `x` is greater than or equal to
100716a05f60SBarry Smith 
100816a05f60SBarry Smith    Level: advanced
1009c803a25aSBarry Smith 
1010c803a25aSBarry Smith    Notes:
101187497f52SBarry Smith      The fudge factor is the value `PETSC_SMALL`
1012c803a25aSBarry Smith 
1013c803a25aSBarry Smith      The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
1014c803a25aSBarry Smith 
1015c803a25aSBarry Smith      This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
1016c803a25aSBarry Smith      floating point results.
1017c803a25aSBarry Smith 
1018db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1019c803a25aSBarry Smith M*/
102066baab88SBarry Smith #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
1021c803a25aSBarry Smith 
1022faa75363SBarry Smith /*MC
1023faa75363SBarry Smith     PetscCeilInt - Returns the ceiling of the quotation of two positive integers
1024faa75363SBarry Smith 
1025faa75363SBarry Smith    Synopsis:
1026faa75363SBarry Smith    #include <petscmath.h>
1027faa75363SBarry Smith    PetscInt PetscCeilInt(PetscInt x,PetscInt y)
1028faa75363SBarry Smith 
1029faa75363SBarry Smith    Not Collective
1030faa75363SBarry Smith 
1031faa75363SBarry Smith    Input Parameters:
1032faa75363SBarry Smith +   x - the numerator
1033faa75363SBarry Smith -   y - the denominator
1034faa75363SBarry Smith 
1035faa75363SBarry Smith    Level: advanced
1036faa75363SBarry Smith 
1037db781477SPatrick Sanan .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
1038faa75363SBarry Smith M*/
1039faa75363SBarry Smith #define PetscCeilInt(x, y) ((((PetscInt)(x)) / ((PetscInt)(y))) + ((((PetscInt)(x)) % ((PetscInt)(y))) ? 1 : 0))
1040faa75363SBarry Smith 
1041faa75363SBarry Smith #define PetscCeilInt64(x, y) ((((PetscInt64)(x)) / ((PetscInt64)(y))) + ((((PetscInt64)(x)) % ((PetscInt64)(y))) ? 1 : 0))
1042faa75363SBarry Smith 
1043bebf13c0SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);
1044