xref: /petsc/include/petscmath.h (revision 5117d392cb5fabee9cf43885a0f7e8e87bdf1551)
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 */
10e489efc1SBarry Smith 
1126bd1501SBarry Smith #if !defined(PETSCMATH_H)
1226bd1501SBarry Smith #define PETSCMATH_H
130a5f7794SBarry Smith #include <math.h>
14df4397b0SStefano Zampini #include <petscsystypes.h>
15df4397b0SStefano Zampini 
16*5117d392SLisandro Dalcin /*
17*5117d392SLisandro Dalcin 
18*5117d392SLisandro Dalcin    Defines operations that are different for complex and real numbers.
19*5117d392SLisandro Dalcin    All PETSc objects in one program are built around the object
20*5117d392SLisandro Dalcin    PetscScalar which is either always a real or a complex.
21*5117d392SLisandro Dalcin 
22*5117d392SLisandro Dalcin */
23*5117d392SLisandro Dalcin 
24*5117d392SLisandro Dalcin /*
25*5117d392SLisandro Dalcin     Real number definitions
26*5117d392SLisandro Dalcin  */
27*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
28*5117d392SLisandro Dalcin #define PetscSqrtReal(a)    sqrtf(a)
29*5117d392SLisandro Dalcin #define PetscCbrtReal(a)    cbrtf(a)
30*5117d392SLisandro Dalcin #define PetscHypotReal(a,b) hypotf(a,b)
31*5117d392SLisandro Dalcin #define PetscAtan2Real(a,b) atan2f(a,b)
32*5117d392SLisandro Dalcin #define PetscPowReal(a,b)   powf(a,b)
33*5117d392SLisandro Dalcin #define PetscExpReal(a)     expf(a)
34*5117d392SLisandro Dalcin #define PetscLogReal(a)     logf(a)
35*5117d392SLisandro Dalcin #define PetscLog10Real(a)   log10f(a)
36*5117d392SLisandro Dalcin #define PetscLog2Real(a)    log2f(a)
37*5117d392SLisandro Dalcin #define PetscSinReal(a)     sinf(a)
38*5117d392SLisandro Dalcin #define PetscCosReal(a)     cosf(a)
39*5117d392SLisandro Dalcin #define PetscTanReal(a)     tanf(a)
40*5117d392SLisandro Dalcin #define PetscAsinReal(a)    asinf(a)
41*5117d392SLisandro Dalcin #define PetscAcosReal(a)    acosf(a)
42*5117d392SLisandro Dalcin #define PetscAtanReal(a)    atanf(a)
43*5117d392SLisandro Dalcin #define PetscSinhReal(a)    sinhf(a)
44*5117d392SLisandro Dalcin #define PetscCoshReal(a)    coshf(a)
45*5117d392SLisandro Dalcin #define PetscTanhReal(a)    tanhf(a)
46*5117d392SLisandro Dalcin #define PetscAsinhReal(a)   asinhf(a)
47*5117d392SLisandro Dalcin #define PetscAcoshReal(a)   acoshf(a)
48*5117d392SLisandro Dalcin #define PetscAtanhReal(a)   atanhf(a)
49*5117d392SLisandro Dalcin #define PetscRoundReal(a)   roundf(a)
50*5117d392SLisandro Dalcin #define PetscCeilReal(a)    ceilf(a)
51*5117d392SLisandro Dalcin #define PetscFloorReal(a)   floorf(a)
52*5117d392SLisandro Dalcin #define PetscFmodReal(a,b)  fmodf(a,b)
53*5117d392SLisandro Dalcin #define PetscTGamma(a)      tgammaf(a)
54*5117d392SLisandro Dalcin 
55*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
56*5117d392SLisandro Dalcin #define PetscSqrtReal(a)    sqrt(a)
57*5117d392SLisandro Dalcin #define PetscCbrtReal(a)    cbrt(a)
58*5117d392SLisandro Dalcin #define PetscHypotReal(a,b) hypot(a,b)
59*5117d392SLisandro Dalcin #define PetscAtan2Real(a,b) atan2(a,b)
60*5117d392SLisandro Dalcin #define PetscPowReal(a,b)   pow(a,b)
61*5117d392SLisandro Dalcin #define PetscExpReal(a)     exp(a)
62*5117d392SLisandro Dalcin #define PetscLogReal(a)     log(a)
63*5117d392SLisandro Dalcin #define PetscLog10Real(a)   log10(a)
64*5117d392SLisandro Dalcin #define PetscLog2Real(a)    log2(a)
65*5117d392SLisandro Dalcin #define PetscSinReal(a)     sin(a)
66*5117d392SLisandro Dalcin #define PetscCosReal(a)     cos(a)
67*5117d392SLisandro Dalcin #define PetscTanReal(a)     tan(a)
68*5117d392SLisandro Dalcin #define PetscAsinReal(a)    asin(a)
69*5117d392SLisandro Dalcin #define PetscAcosReal(a)    acos(a)
70*5117d392SLisandro Dalcin #define PetscAtanReal(a)    atan(a)
71*5117d392SLisandro Dalcin #define PetscSinhReal(a)    sinh(a)
72*5117d392SLisandro Dalcin #define PetscCoshReal(a)    cosh(a)
73*5117d392SLisandro Dalcin #define PetscTanhReal(a)    tanh(a)
74*5117d392SLisandro Dalcin #define PetscAsinhReal(a)   asinh(a)
75*5117d392SLisandro Dalcin #define PetscAcoshReal(a)   acosh(a)
76*5117d392SLisandro Dalcin #define PetscAtanhReal(a)   atanh(a)
77*5117d392SLisandro Dalcin #define PetscRoundReal(a)   round(a)
78*5117d392SLisandro Dalcin #define PetscCeilReal(a)    ceil(a)
79*5117d392SLisandro Dalcin #define PetscFloorReal(a)   floor(a)
80*5117d392SLisandro Dalcin #define PetscFmodReal(a,b)  fmod(a,b)
81*5117d392SLisandro Dalcin #define PetscTGamma(a)      tgamma(a)
82*5117d392SLisandro Dalcin 
83*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
84*5117d392SLisandro Dalcin #define PetscSqrtReal(a)    sqrtq(a)
85*5117d392SLisandro Dalcin #define PetscCbrtReal(a)    cbrtq(a)
86*5117d392SLisandro Dalcin #define PetscHypotReal(a,b) hypotq(a,b)
87*5117d392SLisandro Dalcin #define PetscAtan2Real(a,b) atan2q(a,b)
88*5117d392SLisandro Dalcin #define PetscPowReal(a,b)   powq(a,b)
89*5117d392SLisandro Dalcin #define PetscExpReal(a)     expq(a)
90*5117d392SLisandro Dalcin #define PetscLogReal(a)     logq(a)
91*5117d392SLisandro Dalcin #define PetscLog10Real(a)   log10q(a)
92*5117d392SLisandro Dalcin #define PetscLog2Real(a)    log2q(a)
93*5117d392SLisandro Dalcin #define PetscSinReal(a)     sinq(a)
94*5117d392SLisandro Dalcin #define PetscCosReal(a)     cosq(a)
95*5117d392SLisandro Dalcin #define PetscTanReal(a)     tanq(a)
96*5117d392SLisandro Dalcin #define PetscAsinReal(a)    asinq(a)
97*5117d392SLisandro Dalcin #define PetscAcosReal(a)    acosq(a)
98*5117d392SLisandro Dalcin #define PetscAtanReal(a)    atanq(a)
99*5117d392SLisandro Dalcin #define PetscSinhReal(a)    sinhq(a)
100*5117d392SLisandro Dalcin #define PetscCoshReal(a)    coshq(a)
101*5117d392SLisandro Dalcin #define PetscTanhReal(a)    tanhq(a)
102*5117d392SLisandro Dalcin #define PetscAsinhReal(a)   asinhq(a)
103*5117d392SLisandro Dalcin #define PetscAcoshReal(a)   acoshq(a)
104*5117d392SLisandro Dalcin #define PetscAtanhReal(a)   atanhq(a)
105*5117d392SLisandro Dalcin #define PetscRoundReal(a)   roundq(a)
106*5117d392SLisandro Dalcin #define PetscCeilReal(a)    ceilq(a)
107*5117d392SLisandro Dalcin #define PetscFloorReal(a)   floorq(a)
108*5117d392SLisandro Dalcin #define PetscFmodReal(a,b)  fmodq(a,b)
109*5117d392SLisandro Dalcin #define PetscTGamma(a)      tgammaq(a)
110*5117d392SLisandro Dalcin 
111*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
112*5117d392SLisandro Dalcin #define PetscSqrtReal(a)    sqrtf(a)
113*5117d392SLisandro Dalcin #define PetscCbrtReal(a)    cbrtf(a)
114*5117d392SLisandro Dalcin #define PetscHypotReal(a,b) hypotf(a,b)
115*5117d392SLisandro Dalcin #define PetscAtan2Real(a,b) atan2f(a,b)
116*5117d392SLisandro Dalcin #define PetscPowReal(a,b)   powf(a,b)
117*5117d392SLisandro Dalcin #define PetscExpReal(a)     expf(a)
118*5117d392SLisandro Dalcin #define PetscLogReal(a)     logf(a)
119*5117d392SLisandro Dalcin #define PetscLog10Real(a)   log10f(a)
120*5117d392SLisandro Dalcin #define PetscLog2Real(a)    log2f(a)
121*5117d392SLisandro Dalcin #define PetscSinReal(a)     sinf(a)
122*5117d392SLisandro Dalcin #define PetscCosReal(a)     cosf(a)
123*5117d392SLisandro Dalcin #define PetscTanReal(a)     tanf(a)
124*5117d392SLisandro Dalcin #define PetscAsinReal(a)    asinf(a)
125*5117d392SLisandro Dalcin #define PetscAcosReal(a)    acosf(a)
126*5117d392SLisandro Dalcin #define PetscAtanReal(a)    atanf(a)
127*5117d392SLisandro Dalcin #define PetscSinhReal(a)    sinhf(a)
128*5117d392SLisandro Dalcin #define PetscCoshReal(a)    coshf(a)
129*5117d392SLisandro Dalcin #define PetscTanhReal(a)    tanhf(a)
130*5117d392SLisandro Dalcin #define PetscAsinhReal(a)   asinhf(a)
131*5117d392SLisandro Dalcin #define PetscAcoshReal(a)   acoshf(a)
132*5117d392SLisandro Dalcin #define PetscAtanhReal(a)   atanhf(a)
133*5117d392SLisandro Dalcin #define PetscRoundReal(a)   roundf(a)
134*5117d392SLisandro Dalcin #define PetscCeilReal(a)    ceilf(a)
135*5117d392SLisandro Dalcin #define PetscFloorReal(a)   floorf(a)
136*5117d392SLisandro Dalcin #define PetscFmodReal(a,b)  fmodf(a,b)
137*5117d392SLisandro Dalcin #define PetscTGamma(a)      tgammaf(a)
138*5117d392SLisandro Dalcin 
139*5117d392SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
140*5117d392SLisandro Dalcin 
141*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscReal PetscSignReal(PetscReal a)
142*5117d392SLisandro Dalcin {
143*5117d392SLisandro Dalcin   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
144*5117d392SLisandro Dalcin }
145*5117d392SLisandro Dalcin 
146*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_LOG2)
147*5117d392SLisandro Dalcin #undef PetscLog2Real
148*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal a)
149*5117d392SLisandro Dalcin {
150*5117d392SLisandro Dalcin   return PetscLogReal(a)/PetscLogReal((PetscReal)2);
151*5117d392SLisandro Dalcin }
152*5117d392SLisandro Dalcin #endif
153*5117d392SLisandro Dalcin 
154*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
155*5117d392SLisandro Dalcin PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
156*5117d392SLisandro Dalcin #endif
157*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL___FP16)
158*5117d392SLisandro Dalcin PETSC_EXTERN MPI_Datatype MPIU___FP16 PetscAttrMPITypeTag(__fp16);
159*5117d392SLisandro Dalcin #endif
160*5117d392SLisandro Dalcin 
161df4397b0SStefano Zampini /*MC
162df4397b0SStefano Zampini    MPIU_REAL - MPI datatype corresponding to PetscReal
163df4397b0SStefano Zampini 
164df4397b0SStefano Zampini    Notes:
165df4397b0SStefano Zampini    In MPI calls that require an MPI datatype that matches a PetscReal or array of PetscReal values, pass this value.
166df4397b0SStefano Zampini 
167df4397b0SStefano Zampini    Level: beginner
168df4397b0SStefano Zampini 
169df4397b0SStefano Zampini .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_SCALAR, MPIU_COMPLEX, MPIU_INT
170df4397b0SStefano Zampini M*/
171c1d390e3SJed Brown #if defined(PETSC_USE_REAL_SINGLE)
172c1d390e3SJed Brown #  define MPIU_REAL MPI_FLOAT
173c1d390e3SJed Brown #elif defined(PETSC_USE_REAL_DOUBLE)
174c1d390e3SJed Brown #  define MPIU_REAL MPI_DOUBLE
175c1d390e3SJed Brown #elif defined(PETSC_USE_REAL___FLOAT128)
176c1d390e3SJed Brown #  define MPIU_REAL MPIU___FLOAT128
177570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16)
178570b7f6dSBarry Smith #  define MPIU_REAL MPIU___FP16
179c1d390e3SJed Brown #endif /* PETSC_USE_REAL_* */
18059cb5930SBarry Smith 
1811093a601SBarry Smith /*
1821093a601SBarry Smith     Complex number definitions
1831093a601SBarry Smith  */
184df4397b0SStefano Zampini #if defined(PETSC_HAVE_COMPLEX)
185*5117d392SLisandro Dalcin #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
1861093a601SBarry Smith /* C++ support of complex number */
187b7940d39SSatish Balay 
18850f81f78SJed Brown #define PetscRealPartComplex(a)      (a).real()
18950f81f78SJed Brown #define PetscImaginaryPartComplex(a) (a).imag()
190df4397b0SStefano Zampini #define PetscAbsComplex(a)           petsccomplexlib::abs(a)
191*5117d392SLisandro Dalcin #define PetscArgComplex(a)           petsccomplexlib::arg(a)
192df4397b0SStefano Zampini #define PetscConjComplex(a)          petsccomplexlib::conj(a)
193df4397b0SStefano Zampini #define PetscSqrtComplex(a)          petsccomplexlib::sqrt(a)
194df4397b0SStefano Zampini #define PetscPowComplex(a,b)         petsccomplexlib::pow(a,b)
195df4397b0SStefano Zampini #define PetscExpComplex(a)           petsccomplexlib::exp(a)
196df4397b0SStefano Zampini #define PetscLogComplex(a)           petsccomplexlib::log(a)
197df4397b0SStefano Zampini #define PetscSinComplex(a)           petsccomplexlib::sin(a)
198df4397b0SStefano Zampini #define PetscCosComplex(a)           petsccomplexlib::cos(a)
199*5117d392SLisandro Dalcin #define PetscTanComplex(a)           petsccomplexlib::tan(a)
200df4397b0SStefano Zampini #define PetscAsinComplex(a)          petsccomplexlib::asin(a)
201df4397b0SStefano Zampini #define PetscAcosComplex(a)          petsccomplexlib::acos(a)
202*5117d392SLisandro Dalcin #define PetscAtanComplex(a)          petsccomplexlib::atan(a)
203df4397b0SStefano Zampini #define PetscSinhComplex(a)          petsccomplexlib::sinh(a)
204df4397b0SStefano Zampini #define PetscCoshComplex(a)          petsccomplexlib::cosh(a)
205df4397b0SStefano Zampini #define PetscTanhComplex(a)          petsccomplexlib::tanh(a)
206*5117d392SLisandro Dalcin #define PetscAsinhComplex(a)         petsccomplexlib::asinh(a)
207*5117d392SLisandro Dalcin #define PetscAcoshComplex(a)         petsccomplexlib::acosh(a)
208*5117d392SLisandro Dalcin #define PetscAtanhComplex(a)         petsccomplexlib::atanh(a)
209*5117d392SLisandro Dalcin 
210*5117d392SLisandro Dalcin /* TODO: Add configure tests
211*5117d392SLisandro Dalcin 
212*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
213*5117d392SLisandro Dalcin #undef PetscTanComplex
214*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscTanComplex(PetscComplex z)
215*5117d392SLisandro Dalcin {
216*5117d392SLisandro Dalcin   return PetscSinComplex(z)/PetscCosComplex(z);
217*5117d392SLisandro Dalcin }
218027d9794SBarry Smith #endif
219debe9ee2SPaul Mullowney 
220*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
221*5117d392SLisandro Dalcin #undef PetscTanhComplex
222*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscTanhComplex(PetscComplex z)
223*5117d392SLisandro Dalcin {
224*5117d392SLisandro Dalcin   return PetscSinhComplex(z)/PetscCoshComplex(z);
225*5117d392SLisandro Dalcin }
226*5117d392SLisandro Dalcin #endif
227*5117d392SLisandro Dalcin 
228*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
229*5117d392SLisandro Dalcin #undef PetscAsinComplex
230*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAsinComplex(PetscComplex z)
231*5117d392SLisandro Dalcin {
232*5117d392SLisandro Dalcin   const PetscComplex j(0,1);
233*5117d392SLisandro Dalcin   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
234*5117d392SLisandro Dalcin }
235*5117d392SLisandro Dalcin #endif
236*5117d392SLisandro Dalcin 
237*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
238*5117d392SLisandro Dalcin #undef PetscAcosComplex
239*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAcosComplex(PetscComplex z)
240*5117d392SLisandro Dalcin {
241*5117d392SLisandro Dalcin   const PetscComplex j(0,1);
242*5117d392SLisandro Dalcin   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
243*5117d392SLisandro Dalcin }
244*5117d392SLisandro Dalcin #endif
245*5117d392SLisandro Dalcin 
246*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
247*5117d392SLisandro Dalcin #undef PetscAtanComplex
248*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAtanComplex(PetscComplex z)
249*5117d392SLisandro Dalcin {
250*5117d392SLisandro Dalcin   const PetscComplex j(0,1);
251*5117d392SLisandro Dalcin   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
252*5117d392SLisandro Dalcin }
253*5117d392SLisandro Dalcin #endif
254*5117d392SLisandro Dalcin 
255*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
256*5117d392SLisandro Dalcin #undef PetscAsinhComplex
257*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAsinhComplex(PetscComplex z)
258*5117d392SLisandro Dalcin {
259*5117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
260*5117d392SLisandro Dalcin }
261*5117d392SLisandro Dalcin #endif
262*5117d392SLisandro Dalcin 
263*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
264*5117d392SLisandro Dalcin #undef PetscAcoshComplex
265*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAcoshComplex(PetscComplex z)
266*5117d392SLisandro Dalcin {
267*5117d392SLisandro Dalcin   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
268*5117d392SLisandro Dalcin }
269*5117d392SLisandro Dalcin #endif
270*5117d392SLisandro Dalcin 
271*5117d392SLisandro Dalcin #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
272*5117d392SLisandro Dalcin #undef PetscAtanhComplex
273*5117d392SLisandro Dalcin PETSC_STATIC_INLINE PetscComplex PetscAtanhComplex(PetscComplex z)
274*5117d392SLisandro Dalcin {
275*5117d392SLisandro Dalcin   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
276*5117d392SLisandro Dalcin }
277*5117d392SLisandro Dalcin #endif
278*5117d392SLisandro Dalcin 
279*5117d392SLisandro Dalcin */
280*5117d392SLisandro Dalcin 
2813be776deSLisandro Dalcin #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND)
282*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
2833be776deSLisandro Dalcin static inline PetscComplex operator+(const PetscComplex& lhs, const double& rhs) { return lhs + float(rhs); }
2843be776deSLisandro Dalcin static inline PetscComplex operator+(const double& lhs, const PetscComplex& rhs) { return float(lhs) + rhs; }
2853be776deSLisandro Dalcin static inline PetscComplex operator-(const PetscComplex& lhs, const double& rhs) { return lhs - float(rhs); }
2863be776deSLisandro Dalcin static inline PetscComplex operator-(const double& lhs, const PetscComplex& rhs) { return float(lhs) - rhs; }
2873be776deSLisandro Dalcin static inline PetscComplex operator*(const PetscComplex& lhs, const double& rhs) { return lhs * float(rhs); }
2883be776deSLisandro Dalcin static inline PetscComplex operator*(const double& lhs, const PetscComplex& rhs) { return float(lhs) * rhs; }
2893be776deSLisandro Dalcin static inline PetscComplex operator/(const PetscComplex& lhs, const double& rhs) { return lhs / float(rhs); }
2903be776deSLisandro Dalcin static inline PetscComplex operator/(const double& lhs, const PetscComplex& rhs) { return float(lhs) / rhs; }
2913be776deSLisandro Dalcin static inline bool operator==(const PetscComplex& lhs, const double& rhs) { return lhs.imag() == float(0) && lhs.real() == float(rhs); }
2923be776deSLisandro Dalcin static inline bool operator==(const double& lhs, const PetscComplex& rhs) { return rhs.imag() == float(0) && rhs.real() == float(lhs); }
2933be776deSLisandro Dalcin static inline bool operator!=(const PetscComplex& lhs, const double& rhs) { return lhs.imag() != float(0) || lhs.real() != float(rhs); }
2943be776deSLisandro Dalcin static inline bool operator!=(const double& lhs, const PetscComplex& rhs) { return rhs.imag() != float(0) || rhs.real() != float(lhs); }
295debe9ee2SPaul Mullowney #elif defined(PETSC_USE_REAL_DOUBLE)
2961a9c6b96SLisandro Dalcin static inline PetscComplex operator+(const PetscComplex& lhs, const PetscInt& rhs) { return lhs + double(rhs); }
2971a9c6b96SLisandro Dalcin static inline PetscComplex operator+(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) + rhs; }
2981a9c6b96SLisandro Dalcin static inline PetscComplex operator-(const PetscComplex& lhs, const PetscInt& rhs) { return lhs - double(rhs); }
2991a9c6b96SLisandro Dalcin static inline PetscComplex operator-(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) - rhs; }
3001a9c6b96SLisandro Dalcin static inline PetscComplex operator*(const PetscComplex& lhs, const PetscInt& rhs) { return lhs * double(rhs); }
3011a9c6b96SLisandro Dalcin static inline PetscComplex operator*(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) * rhs; }
3021a9c6b96SLisandro Dalcin static inline PetscComplex operator/(const PetscComplex& lhs, const PetscInt& rhs) { return lhs / double(rhs); }
3031a9c6b96SLisandro Dalcin static inline PetscComplex operator/(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) / rhs; }
3041a9c6b96SLisandro Dalcin static inline bool operator==(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() == double(0) && lhs.real() == double(rhs); }
3051a9c6b96SLisandro Dalcin static inline bool operator==(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() == double(0) && rhs.real() == double(lhs); }
3061a9c6b96SLisandro Dalcin static inline bool operator!=(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() != double(0) || lhs.real() != double(rhs); }
3071a9c6b96SLisandro Dalcin static inline bool operator!=(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() != double(0) || rhs.real() != double(lhs); }
308*5117d392SLisandro Dalcin #endif  /* PETSC_USE_REAL_* */
3091a9c6b96SLisandro Dalcin #endif  /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */
310debe9ee2SPaul Mullowney 
311546cf897SSatish Balay #elif defined(PETSC_HAVE_C99_COMPLEX) && !defined(PETSC_USE_REAL___FP16)
312*5117d392SLisandro Dalcin /* C99 support of complex number */
313519e2a1fSPaul Mullowney 
314570b7f6dSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16)
31550f81f78SJed Brown #define PetscRealPartComplex(a)      crealf(a)
31650f81f78SJed Brown #define PetscImaginaryPartComplex(a) cimagf(a)
31750f81f78SJed Brown #define PetscAbsComplex(a)           cabsf(a)
318*5117d392SLisandro Dalcin #define PetscArgComplex(a)           cargf(a)
31950f81f78SJed Brown #define PetscConjComplex(a)          conjf(a)
32050f81f78SJed Brown #define PetscSqrtComplex(a)          csqrtf(a)
32150f81f78SJed Brown #define PetscPowComplex(a,b)         cpowf(a,b)
32250f81f78SJed Brown #define PetscExpComplex(a)           cexpf(a)
32350f81f78SJed Brown #define PetscLogComplex(a)           clogf(a)
32450f81f78SJed Brown #define PetscSinComplex(a)           csinf(a)
32550f81f78SJed Brown #define PetscCosComplex(a)           ccosf(a)
326*5117d392SLisandro Dalcin #define PetscTanComplex(a)           ctanf(a)
327255453a1SBarry Smith #define PetscAsinComplex(a)          casinf(a)
328255453a1SBarry Smith #define PetscAcosComplex(a)          cacosf(a)
329*5117d392SLisandro Dalcin #define PetscAtanComplex(a)          catanf(a)
330a4bea5a6SPeter Brune #define PetscSinhComplex(a)          csinhf(a)
331a4bea5a6SPeter Brune #define PetscCoshComplex(a)          ccoshf(a)
332a4bea5a6SPeter Brune #define PetscTanhComplex(a)          ctanhf(a)
333*5117d392SLisandro Dalcin #define PetscAsinhComplex(a)         casinhf(a)
334*5117d392SLisandro Dalcin #define PetscAcoshComplex(a)         cacoshf(a)
335*5117d392SLisandro Dalcin #define PetscAtanhComplex(a)         catanhf(a)
3361093a601SBarry Smith 
337ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE)
33850f81f78SJed Brown #define PetscRealPartComplex(a)      creal(a)
33950f81f78SJed Brown #define PetscImaginaryPartComplex(a) cimag(a)
34050f81f78SJed Brown #define PetscAbsComplex(a)           cabs(a)
341*5117d392SLisandro Dalcin #define PetscArgComplex(a)           carg(a)
34250f81f78SJed Brown #define PetscConjComplex(a)          conj(a)
34350f81f78SJed Brown #define PetscSqrtComplex(a)          csqrt(a)
34450f81f78SJed Brown #define PetscPowComplex(a,b)         cpow(a,b)
34550f81f78SJed Brown #define PetscExpComplex(a)           cexp(a)
34650f81f78SJed Brown #define PetscLogComplex(a)           clog(a)
34750f81f78SJed Brown #define PetscSinComplex(a)           csin(a)
34850f81f78SJed Brown #define PetscCosComplex(a)           ccos(a)
349*5117d392SLisandro Dalcin #define PetscTanComplex(a)           ctan(a)
350255453a1SBarry Smith #define PetscAsinComplex(a)          casin(a)
351255453a1SBarry Smith #define PetscAcosComplex(a)          cacos(a)
352*5117d392SLisandro Dalcin #define PetscAtanComplex(a)          catan(a)
353a4bea5a6SPeter Brune #define PetscSinhComplex(a)          csinh(a)
354a4bea5a6SPeter Brune #define PetscCoshComplex(a)          ccosh(a)
355a4bea5a6SPeter Brune #define PetscTanhComplex(a)          ctanh(a)
356*5117d392SLisandro Dalcin #define PetscAsinhComplex(a)         casinh(a)
357*5117d392SLisandro Dalcin #define PetscAcoshComplex(a)         cacosh(a)
358*5117d392SLisandro Dalcin #define PetscAtanhComplex(a)         catanh(a)
3591093a601SBarry Smith 
3608c764dc5SJose Roman #elif defined(PETSC_USE_REAL___FLOAT128)
36150f81f78SJed Brown #define PetscRealPartComplex(a)      crealq(a)
36250f81f78SJed Brown #define PetscImaginaryPartComplex(a) cimagq(a)
36350f81f78SJed Brown #define PetscAbsComplex(a)           cabsq(a)
364*5117d392SLisandro Dalcin #define PetscArgComplex(a)           cargq(a)
36550f81f78SJed Brown #define PetscConjComplex(a)          conjq(a)
36650f81f78SJed Brown #define PetscSqrtComplex(a)          csqrtq(a)
36750f81f78SJed Brown #define PetscPowComplex(a,b)         cpowq(a,b)
36850f81f78SJed Brown #define PetscExpComplex(a)           cexpq(a)
36950f81f78SJed Brown #define PetscLogComplex(a)           clogq(a)
37050f81f78SJed Brown #define PetscSinComplex(a)           csinq(a)
37150f81f78SJed Brown #define PetscCosComplex(a)           ccosq(a)
372*5117d392SLisandro Dalcin #define PetscTanComplex(a)           ctanq(a)
373255453a1SBarry Smith #define PetscAsinComplex(a)          casinq(a)
374255453a1SBarry Smith #define PetscAcosComplex(a)          cacosq(a)
375*5117d392SLisandro Dalcin #define PetscAtanComplex(a)          catanq(a)
376a4bea5a6SPeter Brune #define PetscSinhComplex(a)          csinhq(a)
377a4bea5a6SPeter Brune #define PetscCoshComplex(a)          ccoshq(a)
378a4bea5a6SPeter Brune #define PetscTanhComplex(a)          ctanhq(a)
379*5117d392SLisandro Dalcin #define PetscAsinhComplex(a)         casinhq(a)
380*5117d392SLisandro Dalcin #define PetscAcoshComplex(a)         cacoshq(a)
381*5117d392SLisandro Dalcin #define PetscAtanhComplex(a)         catanhq(a)
382a4bea5a6SPeter Brune 
383ce63c4c1SBarry Smith #endif /* PETSC_USE_REAL_* */
3842f217381SBarry Smith #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */
385e489efc1SBarry Smith 
3861093a601SBarry Smith /*
387*5117d392SLisandro Dalcin    PETSC_i is the imaginary number, i
3881093a601SBarry Smith */
38950f81f78SJed Brown PETSC_EXTERN PetscComplex PETSC_i;
3908a351411SToby Isaac 
391*5117d392SLisandro Dalcin /*
392*5117d392SLisandro Dalcin    Try to do the right thing for complex number construction: see
3938a351411SToby Isaac    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
3948a351411SToby Isaac    for details
3958a351411SToby Isaac */
39619e222d7SToby Isaac PETSC_STATIC_INLINE PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
3978a351411SToby Isaac {
3980e1bea35STristan Konolige #if   defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
3998a351411SToby Isaac   return PetscComplex(x,y);
4008a351411SToby Isaac #elif defined(_Imaginary_I)
4018a351411SToby Isaac   return x + y * _Imaginary_I;
4028a351411SToby Isaac #else
403616d7c5eSToby Isaac   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
404616d7c5eSToby Isaac 
405616d7c5eSToby Isaac        "For each floating type there is a corresponding real type, which is always a real floating
406616d7c5eSToby Isaac        type. For real floating types, it is the same type. For complex types, it is the type given
407616d7c5eSToby Isaac        by deleting the keyword _Complex from the type name."
408616d7c5eSToby Isaac 
409616d7c5eSToby Isaac        So type punning should be portable. */
410616d7c5eSToby Isaac     union { PetscComplex z; PetscReal f[2]; } uz;
411616d7c5eSToby Isaac 
412616d7c5eSToby Isaac     uz.f[0] = x;
413616d7c5eSToby Isaac     uz.f[1] = y;
414616d7c5eSToby Isaac     return uz.z;
415616d7c5eSToby Isaac   }
41650f81f78SJed Brown #endif
4178a351411SToby Isaac }
4188a351411SToby Isaac 
419*5117d392SLisandro Dalcin #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
420*5117d392SLisandro Dalcin #define MPIU_C_COMPLEX MPI_C_COMPLEX
421*5117d392SLisandro Dalcin #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
422*5117d392SLisandro Dalcin #else
423*5117d392SLisandro Dalcin # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
424*5117d392SLisandro Dalcin   typedef petsccomplexlib::complex<double> petsc_mpiu_c_double_complex;
425*5117d392SLisandro Dalcin   typedef petsccomplexlib::complex<float> petsc_mpiu_c_complex;
426*5117d392SLisandro Dalcin # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
427*5117d392SLisandro Dalcin   typedef double _Complex petsc_mpiu_c_double_complex;
428*5117d392SLisandro Dalcin   typedef float _Complex petsc_mpiu_c_complex;
429*5117d392SLisandro Dalcin # else
430*5117d392SLisandro Dalcin   typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
431*5117d392SLisandro Dalcin   typedef struct {float real,imag;} petsc_mpiu_c_complex;
432*5117d392SLisandro Dalcin # endif
433*5117d392SLisandro Dalcin PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
434*5117d392SLisandro Dalcin PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
435*5117d392SLisandro Dalcin #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
436*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
437*5117d392SLisandro Dalcin PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);
438*5117d392SLisandro Dalcin #endif /* PETSC_USE_REAL___FLOAT128 */
439*5117d392SLisandro Dalcin 
440*5117d392SLisandro Dalcin /*MC
441*5117d392SLisandro Dalcin    MPIU_COMPLEX - MPI datatype corresponding to PetscComplex
442*5117d392SLisandro Dalcin 
443*5117d392SLisandro Dalcin    Notes:
444*5117d392SLisandro Dalcin    In MPI calls that require an MPI datatype that matches a PetscComplex or array of PetscComplex values, pass this value.
445*5117d392SLisandro Dalcin 
446*5117d392SLisandro Dalcin    Level: beginner
447*5117d392SLisandro Dalcin 
448*5117d392SLisandro Dalcin .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_REAL, MPIU_SCALAR, MPIU_COMPLEX, MPIU_INT, PETSC_i
449*5117d392SLisandro Dalcin M*/
450*5117d392SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
451*5117d392SLisandro Dalcin #  define MPIU_COMPLEX MPIU_C_COMPLEX
452*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
453*5117d392SLisandro Dalcin #  define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
454*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
455*5117d392SLisandro Dalcin #  define MPIU_COMPLEX MPIU___COMPLEX128
456*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
457*5117d392SLisandro Dalcin #  define MPIU_COMPLEX MPIU_C_COMPLEX
458*5117d392SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
459*5117d392SLisandro Dalcin 
460*5117d392SLisandro Dalcin #endif /* PETSC_HAVE_COMPLEX */
461*5117d392SLisandro Dalcin 
462*5117d392SLisandro Dalcin /*
463*5117d392SLisandro Dalcin     Scalar number definitions
464*5117d392SLisandro Dalcin  */
465*5117d392SLisandro Dalcin #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)
466*5117d392SLisandro Dalcin /*MC
467*5117d392SLisandro Dalcin    MPIU_SCALAR - MPI datatype corresponding to PetscScalar
468*5117d392SLisandro Dalcin 
469*5117d392SLisandro Dalcin    Notes:
470*5117d392SLisandro Dalcin    In MPI calls that require an MPI datatype that matches a PetscScalar or array of PetscScalar values, pass this value.
471*5117d392SLisandro Dalcin 
472*5117d392SLisandro Dalcin    Level: beginner
473*5117d392SLisandro Dalcin 
474*5117d392SLisandro Dalcin .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_REAL, MPIU_COMPLEX, MPIU_INT
475*5117d392SLisandro Dalcin M*/
476*5117d392SLisandro Dalcin #define MPIU_SCALAR MPIU_COMPLEX
477*5117d392SLisandro Dalcin 
478*5117d392SLisandro Dalcin /*MC
479*5117d392SLisandro Dalcin    PetscRealPart - Returns the real part of a PetscScalar
480*5117d392SLisandro Dalcin 
481*5117d392SLisandro Dalcin    Synopsis:
482*5117d392SLisandro Dalcin    #include <petscmath.h>
483*5117d392SLisandro Dalcin    PetscReal PetscRealPart(PetscScalar v)
484*5117d392SLisandro Dalcin 
485*5117d392SLisandro Dalcin    Not Collective
486*5117d392SLisandro Dalcin 
487*5117d392SLisandro Dalcin    Input Parameter:
488*5117d392SLisandro Dalcin .  v - value to find the real part of
489*5117d392SLisandro Dalcin 
490*5117d392SLisandro Dalcin    Level: beginner
491*5117d392SLisandro Dalcin 
492*5117d392SLisandro Dalcin .seealso: PetscScalar, PetscImaginaryPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
493*5117d392SLisandro Dalcin 
494*5117d392SLisandro Dalcin M*/
495*5117d392SLisandro Dalcin #define PetscRealPart(a)      PetscRealPartComplex(a)
496*5117d392SLisandro Dalcin 
497*5117d392SLisandro Dalcin /*MC
498*5117d392SLisandro Dalcin    PetscImaginaryPart - Returns the imaginary part of a PetscScalar
499*5117d392SLisandro Dalcin 
500*5117d392SLisandro Dalcin    Synopsis:
501*5117d392SLisandro Dalcin    #include <petscmath.h>
502*5117d392SLisandro Dalcin    PetscReal PetscImaginaryPart(PetscScalar v)
503*5117d392SLisandro Dalcin 
504*5117d392SLisandro Dalcin    Not Collective
505*5117d392SLisandro Dalcin 
506*5117d392SLisandro Dalcin    Input Parameter:
507*5117d392SLisandro Dalcin .  v - value to find the imaginary part of
508*5117d392SLisandro Dalcin 
509*5117d392SLisandro Dalcin    Level: beginner
510*5117d392SLisandro Dalcin 
511*5117d392SLisandro Dalcin    Notes:
512*5117d392SLisandro Dalcin        If PETSc was configured for real numbers then this always returns the value 0
513*5117d392SLisandro Dalcin 
514*5117d392SLisandro Dalcin .seealso: PetscScalar, PetscRealPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
515*5117d392SLisandro Dalcin 
516*5117d392SLisandro Dalcin M*/
517*5117d392SLisandro Dalcin #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
518*5117d392SLisandro Dalcin 
519*5117d392SLisandro Dalcin #define PetscAbsScalar(a)     PetscAbsComplex(a)
520*5117d392SLisandro Dalcin #define PetscArgScalar(a)     PetscArgComplex(a)
521*5117d392SLisandro Dalcin #define PetscConj(a)          PetscConjComplex(a)
522*5117d392SLisandro Dalcin #define PetscSqrtScalar(a)    PetscSqrtComplex(a)
523*5117d392SLisandro Dalcin #define PetscPowScalar(a,b)   PetscPowComplex(a,b)
524*5117d392SLisandro Dalcin #define PetscExpScalar(a)     PetscExpComplex(a)
525*5117d392SLisandro Dalcin #define PetscLogScalar(a)     PetscLogComplex(a)
526*5117d392SLisandro Dalcin #define PetscSinScalar(a)     PetscSinComplex(a)
527*5117d392SLisandro Dalcin #define PetscCosScalar(a)     PetscCosComplex(a)
528*5117d392SLisandro Dalcin #define PetscTanScalar(a)     PetscTanComplex(a)
529*5117d392SLisandro Dalcin #define PetscAsinScalar(a)    PetscAsinComplex(a)
530*5117d392SLisandro Dalcin #define PetscAcosScalar(a)    PetscAcosComplex(a)
531*5117d392SLisandro Dalcin #define PetscAtanScalar(a)    PetscAtanComplex(a)
532*5117d392SLisandro Dalcin #define PetscSinhScalar(a)    PetscSinhComplex(a)
533*5117d392SLisandro Dalcin #define PetscCoshScalar(a)    PetscCoshComplex(a)
534*5117d392SLisandro Dalcin #define PetscTanhScalar(a)    PetscTanhComplex(a)
535*5117d392SLisandro Dalcin #define PetscAsinhScalar(a)   PetscAsinhComplex(a)
536*5117d392SLisandro Dalcin #define PetscAcoshScalar(a)   PetscAcoshComplex(a)
537*5117d392SLisandro Dalcin #define PetscAtanhScalar(a)   PetscAtanhComplex(a)
538*5117d392SLisandro Dalcin 
539*5117d392SLisandro Dalcin #else /* PETSC_USE_COMPLEX */
540*5117d392SLisandro Dalcin #define MPIU_SCALAR MPIU_REAL
541*5117d392SLisandro Dalcin #define PetscRealPart(a)      (a)
542*5117d392SLisandro Dalcin #define PetscImaginaryPart(a) ((PetscReal)0)
543*5117d392SLisandro Dalcin #define PetscAbsScalar(a)     PetscAbsReal(a)
544*5117d392SLisandro Dalcin #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
545*5117d392SLisandro Dalcin #define PetscConj(a)          (a)
546*5117d392SLisandro Dalcin #define PetscSqrtScalar(a)    PetscSqrtReal(a)
547*5117d392SLisandro Dalcin #define PetscPowScalar(a,b)   PetscPowReal(a,b)
548*5117d392SLisandro Dalcin #define PetscExpScalar(a)     PetscExpReal(a)
549*5117d392SLisandro Dalcin #define PetscLogScalar(a)     PetscLogReal(a)
550*5117d392SLisandro Dalcin #define PetscSinScalar(a)     PetscSinReal(a)
551*5117d392SLisandro Dalcin #define PetscCosScalar(a)     PetscCosReal(a)
552*5117d392SLisandro Dalcin #define PetscTanScalar(a)     PetscTanReal(a)
553*5117d392SLisandro Dalcin #define PetscAsinScalar(a)    PetscAsinReal(a)
554*5117d392SLisandro Dalcin #define PetscAcosScalar(a)    PetscAcosReal(a)
555*5117d392SLisandro Dalcin #define PetscAtanScalar(a)    PetscAtanReal(a)
556*5117d392SLisandro Dalcin #define PetscSinhScalar(a)    PetscSinhReal(a)
557*5117d392SLisandro Dalcin #define PetscCoshScalar(a)    PetscCoshReal(a)
558*5117d392SLisandro Dalcin #define PetscTanhScalar(a)    PetscTanhReal(a)
559*5117d392SLisandro Dalcin #define PetscAsinhScalar(a)   PetscAsinhReal(a)
560*5117d392SLisandro Dalcin #define PetscAcoshScalar(a)   PetscAcoshReal(a)
561*5117d392SLisandro Dalcin #define PetscAtanhScalar(a)   PetscAtanhReal(a)
562*5117d392SLisandro Dalcin 
563*5117d392SLisandro Dalcin #endif /* PETSC_USE_COMPLEX */
564*5117d392SLisandro Dalcin 
565*5117d392SLisandro Dalcin /*
566*5117d392SLisandro Dalcin    Certain objects may be created using either single or double precision.
567*5117d392SLisandro Dalcin    This is currently not used.
568*5117d392SLisandro Dalcin */
569*5117d392SLisandro Dalcin typedef enum { PETSC_SCALAR_DOUBLE, PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_HALF } PetscScalarPrecision;
570*5117d392SLisandro Dalcin 
571*5117d392SLisandro Dalcin /* --------------------------------------------------------------------------*/
572*5117d392SLisandro Dalcin 
573*5117d392SLisandro Dalcin /*MC
574*5117d392SLisandro Dalcin    PetscAbs - Returns the absolute value of a number
575*5117d392SLisandro Dalcin 
576*5117d392SLisandro Dalcin    Synopsis:
577*5117d392SLisandro Dalcin    #include <petscmath.h>
578*5117d392SLisandro Dalcin    type PetscAbs(type v)
579*5117d392SLisandro Dalcin 
580*5117d392SLisandro Dalcin    Not Collective
581*5117d392SLisandro Dalcin 
582*5117d392SLisandro Dalcin    Input Parameter:
583*5117d392SLisandro Dalcin .  v - the number
584*5117d392SLisandro Dalcin 
585*5117d392SLisandro Dalcin    Notes:
586*5117d392SLisandro Dalcin     type can be integer or real floating point value
587*5117d392SLisandro Dalcin 
588*5117d392SLisandro Dalcin    Level: beginner
589*5117d392SLisandro Dalcin 
590*5117d392SLisandro Dalcin .seealso: PetscAbsInt(), PetscAbsReal(), PetscAbsScalar()
591*5117d392SLisandro Dalcin 
592*5117d392SLisandro Dalcin M*/
593*5117d392SLisandro Dalcin #define PetscAbs(a)  (((a) >= 0) ? (a) : (-(a)))
594*5117d392SLisandro Dalcin 
595*5117d392SLisandro Dalcin /*MC
596*5117d392SLisandro Dalcin    PetscSign - Returns the sign of a number as an integer
597*5117d392SLisandro Dalcin 
598*5117d392SLisandro Dalcin    Synopsis:
599*5117d392SLisandro Dalcin    #include <petscmath.h>
600*5117d392SLisandro Dalcin    int PetscSign(type v)
601*5117d392SLisandro Dalcin 
602*5117d392SLisandro Dalcin    Not Collective
603*5117d392SLisandro Dalcin 
604*5117d392SLisandro Dalcin    Input Parameter:
605*5117d392SLisandro Dalcin .  v - the number
606*5117d392SLisandro Dalcin 
607*5117d392SLisandro Dalcin    Notes:
608*5117d392SLisandro Dalcin     type can be integer or real floating point value
609*5117d392SLisandro Dalcin 
610*5117d392SLisandro Dalcin    Level: beginner
611*5117d392SLisandro Dalcin 
612*5117d392SLisandro Dalcin M*/
613*5117d392SLisandro Dalcin #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
614e489efc1SBarry Smith 
615b6a5bde7SBarry Smith /*MC
616b6a5bde7SBarry Smith    PetscMin - Returns minimum of two numbers
617b6a5bde7SBarry Smith 
618eca87e8dSBarry Smith    Synopsis:
619aaa7dc30SBarry Smith    #include <petscmath.h>
620eca87e8dSBarry Smith    type PetscMin(type v1,type v2)
621eca87e8dSBarry Smith 
622eca87e8dSBarry Smith    Not Collective
623eca87e8dSBarry Smith 
624b6a5bde7SBarry Smith    Input Parameter:
625b6a5bde7SBarry Smith +  v1 - first value to find minimum of
626b6a5bde7SBarry Smith -  v2 - second value to find minimum of
627b6a5bde7SBarry Smith 
62895452b02SPatrick Sanan    Notes:
62995452b02SPatrick Sanan     type can be integer or floating point value
630b6a5bde7SBarry Smith 
631b6a5bde7SBarry Smith    Level: beginner
632b6a5bde7SBarry Smith 
6331175f9beSHong Zhang .seealso: PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
634b6a5bde7SBarry Smith 
635b6a5bde7SBarry Smith M*/
636e489efc1SBarry Smith #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))
637b6a5bde7SBarry Smith 
638b6a5bde7SBarry Smith /*MC
639b6a5bde7SBarry Smith    PetscMax - Returns maxium of two numbers
640b6a5bde7SBarry Smith 
641eca87e8dSBarry Smith    Synopsis:
642aaa7dc30SBarry Smith    #include <petscmath.h>
643eca87e8dSBarry Smith    type max PetscMax(type v1,type v2)
644eca87e8dSBarry Smith 
645eca87e8dSBarry Smith    Not Collective
646eca87e8dSBarry Smith 
647b6a5bde7SBarry Smith    Input Parameter:
648b6a5bde7SBarry Smith +  v1 - first value to find maximum of
649b6a5bde7SBarry Smith -  v2 - second value to find maximum of
650b6a5bde7SBarry Smith 
65195452b02SPatrick Sanan    Notes:
65295452b02SPatrick Sanan     type can be integer or floating point value
653b6a5bde7SBarry Smith 
654b6a5bde7SBarry Smith    Level: beginner
655b6a5bde7SBarry Smith 
656d9a4bb16SJed Brown .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
657b6a5bde7SBarry Smith 
658b6a5bde7SBarry Smith M*/
659e489efc1SBarry Smith #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))
660b6a5bde7SBarry Smith 
661b6a5bde7SBarry Smith /*MC
662d9a4bb16SJed Brown    PetscClipInterval - Returns a number clipped to be within an interval
663d9a4bb16SJed Brown 
664d9a4bb16SJed Brown    Synopsis:
665aaa7dc30SBarry Smith    #include <petscmath.h>
666d9a4bb16SJed Brown    type clip PetscClipInterval(type x,type a,type b)
667d9a4bb16SJed Brown 
668d9a4bb16SJed Brown    Not Collective
669d9a4bb16SJed Brown 
670d9a4bb16SJed Brown    Input Parameter:
671d9a4bb16SJed Brown +  x - value to use if within interval (a,b)
672d9a4bb16SJed Brown .  a - lower end of interval
673d9a4bb16SJed Brown -  b - upper end of interval
674d9a4bb16SJed Brown 
67595452b02SPatrick Sanan    Notes:
67695452b02SPatrick Sanan     type can be integer or floating point value
677d9a4bb16SJed Brown 
678d9a4bb16SJed Brown    Level: beginner
679d9a4bb16SJed Brown 
680d9a4bb16SJed Brown .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
681d9a4bb16SJed Brown 
682d9a4bb16SJed Brown M*/
683d9a4bb16SJed Brown #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))
684d9a4bb16SJed Brown 
685d9a4bb16SJed Brown /*MC
686b6a5bde7SBarry Smith    PetscAbsInt - Returns the absolute value of an integer
687b6a5bde7SBarry Smith 
688b6a5bde7SBarry Smith    Synopsis:
689aaa7dc30SBarry Smith    #include <petscmath.h>
690b6a5bde7SBarry Smith    int abs PetscAbsInt(int v1)
691b6a5bde7SBarry Smith 
692eca87e8dSBarry Smith    Not Collective
693eca87e8dSBarry Smith 
694eca87e8dSBarry Smith    Input Parameter:
695eca87e8dSBarry Smith .   v1 - the integer
696b6a5bde7SBarry Smith 
697b6a5bde7SBarry Smith    Level: beginner
698b6a5bde7SBarry Smith 
699b6a5bde7SBarry Smith .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
700b6a5bde7SBarry Smith 
701b6a5bde7SBarry Smith M*/
7029fa7d148SSatish Balay #define PetscAbsInt(a)  (((a)<0)   ? (-(a)) : (a))
703b6a5bde7SBarry Smith 
704b6a5bde7SBarry Smith /*MC
705b6a5bde7SBarry Smith    PetscAbsReal - Returns the absolute value of an real number
706b6a5bde7SBarry Smith 
707eca87e8dSBarry Smith    Synopsis:
708aaa7dc30SBarry Smith    #include <petscmath.h>
709eca87e8dSBarry Smith    Real abs PetscAbsReal(PetscReal v1)
710eca87e8dSBarry Smith 
711eca87e8dSBarry Smith    Not Collective
712eca87e8dSBarry Smith 
713b6a5bde7SBarry Smith    Input Parameter:
714b6a5bde7SBarry Smith .   v1 - the double
715b6a5bde7SBarry Smith 
716b6a5bde7SBarry Smith 
717b6a5bde7SBarry Smith    Level: beginner
718b6a5bde7SBarry Smith 
719b6a5bde7SBarry Smith .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
720b6a5bde7SBarry Smith 
721b6a5bde7SBarry Smith M*/
7221118d4bcSLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
7231118d4bcSLisandro Dalcin #define PetscAbsReal(a) fabsf(a)
7241118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
7251118d4bcSLisandro Dalcin #define PetscAbsReal(a) fabs(a)
7261118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
7271118d4bcSLisandro Dalcin #define PetscAbsReal(a) fabsq(a)
7281118d4bcSLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
7291118d4bcSLisandro Dalcin #define PetscAbsReal(a) fabsf(a)
7301118d4bcSLisandro Dalcin #endif
731b6a5bde7SBarry Smith 
732b6a5bde7SBarry Smith /*MC
733b6a5bde7SBarry Smith    PetscSqr - Returns the square of a number
734b6a5bde7SBarry Smith 
735b6a5bde7SBarry Smith    Synopsis:
736aaa7dc30SBarry Smith    #include <petscmath.h>
737b6a5bde7SBarry Smith    type sqr PetscSqr(type v1)
738b6a5bde7SBarry Smith 
739eca87e8dSBarry Smith    Not Collective
740eca87e8dSBarry Smith 
741eca87e8dSBarry Smith    Input Parameter:
742eca87e8dSBarry Smith .   v1 - the value
743eca87e8dSBarry Smith 
74495452b02SPatrick Sanan    Notes:
74595452b02SPatrick Sanan     type can be integer or floating point value
746b6a5bde7SBarry Smith 
747b6a5bde7SBarry Smith    Level: beginner
748b6a5bde7SBarry Smith 
749b6a5bde7SBarry Smith .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
750b6a5bde7SBarry Smith 
751b6a5bde7SBarry Smith M*/
7524ebda54eSMatthew Knepley #define PetscSqr(a)     ((a)*(a))
753e489efc1SBarry Smith 
754314da920SBarry Smith /* ----------------------------------------------------------------------------*/
755ee223c85SLisandro Dalcin 
756ee223c85SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
757ee223c85SLisandro Dalcin #define PetscRealConstant(constant) constant##F
758*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
759*5117d392SLisandro Dalcin #define PetscRealConstant(constant) constant
760ee223c85SLisandro Dalcin #elif defined(PETSC_USE_REAL___FLOAT128)
761ee223c85SLisandro Dalcin #define PetscRealConstant(constant) constant##Q
762*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
763*5117d392SLisandro Dalcin #define PetscRealConstant(constant) constant##F
764ee223c85SLisandro Dalcin #endif
765ee223c85SLisandro Dalcin 
766314da920SBarry Smith /*
767d34fcf5fSBarry Smith      Basic constants
768314da920SBarry Smith */
7692fab75feSLisandro Dalcin #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
7702fab75feSLisandro Dalcin #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
7717b156302SMatthew G. Knepley #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
772d34fcf5fSBarry Smith 
773ab824b78SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
77471fd2e92SBarry Smith #define PETSC_MAX_INT            2147483647
775ab824b78SBarry Smith #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
776ab824b78SBarry Smith #else
777ab824b78SBarry Smith #define PETSC_MAX_INT            9223372036854775807L
778ab824b78SBarry Smith #define PETSC_MIN_INT            (-PETSC_MAX_INT - 1)
779ab824b78SBarry Smith #endif
780e489efc1SBarry Smith 
781ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
782ab824b78SBarry Smith #  define PETSC_MAX_REAL                3.40282346638528860e+38F
7839fa7d148SSatish Balay #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
78482a7e548SBarry Smith #  define PETSC_MACHINE_EPSILON         1.19209290e-07F
78582a7e548SBarry Smith #  define PETSC_SQRT_MACHINE_EPSILON    3.45266983e-04F
786ee223c85SLisandro Dalcin #  define PETSC_SMALL                   1.e-5F
787ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE)
788ab824b78SBarry Smith #  define PETSC_MAX_REAL                1.7976931348623157e+308
7899fa7d148SSatish Balay #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
79082a7e548SBarry Smith #  define PETSC_MACHINE_EPSILON         2.2204460492503131e-16
79182a7e548SBarry Smith #  define PETSC_SQRT_MACHINE_EPSILON    1.490116119384766e-08
792cf6e855fSSatish Balay #  define PETSC_SMALL                   1.e-10
793ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128)
794ea345e14SBarry Smith #  define PETSC_MAX_REAL                FLT128_MAX
7959fa7d148SSatish Balay #  define PETSC_MIN_REAL                (-FLT128_MAX)
796d34fcf5fSBarry Smith #  define PETSC_MACHINE_EPSILON         FLT128_EPSILON
797ee223c85SLisandro Dalcin #  define PETSC_SQRT_MACHINE_EPSILON    1.38777878078144567552953958511352539e-17Q
798ee223c85SLisandro Dalcin #  define PETSC_SMALL                   1.e-20Q
799*5117d392SLisandro Dalcin #elif defined(PETSC_USE_REAL___FP16)
800*5117d392SLisandro Dalcin #  define PETSC_MAX_REAL                65504.0F
8019fa7d148SSatish Balay #  define PETSC_MIN_REAL                (-PETSC_MAX_REAL)
802*5117d392SLisandro Dalcin #  define PETSC_MACHINE_EPSILON         .0009765625F
803*5117d392SLisandro Dalcin #  define PETSC_SQRT_MACHINE_EPSILON    .03125F
804*5117d392SLisandro Dalcin #  define PETSC_SMALL                   5.e-3F
8059cf09972SJed Brown #endif
8063e523bebSBarry Smith 
80725d0f998SSatish Balay #define PETSC_INFINITY               (PETSC_MAX_REAL/4)
8089fa7d148SSatish Balay #define PETSC_NINFINITY              (-PETSC_INFINITY)
809e270355aSBarry Smith 
8109f4f8022SLisandro Dalcin PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal);
8113948c36eSLisandro Dalcin PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal);
8128b49ba18SBarry Smith PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
8139f4f8022SLisandro Dalcin PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanReal(PetscReal v) {return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;}
8149f4f8022SLisandro Dalcin PETSC_STATIC_INLINE PetscBool PetscIsInfScalar(PetscScalar v) {return PetscIsInfReal(PetscAbsScalar(v));}
8153948c36eSLisandro Dalcin PETSC_STATIC_INLINE PetscBool PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));}
8169f4f8022SLisandro Dalcin PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
8173948c36eSLisandro Dalcin PETSC_STATIC_INLINE PetscBool PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}
8189a25a3ccSBarry Smith 
819b10005b4SLisandro Dalcin PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal,PetscReal,PetscReal,PetscReal);
820ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualReal(PetscReal,PetscReal);
821ce4818fdSLisandro Dalcin PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar,PetscScalar);
822ce4818fdSLisandro Dalcin 
82398725619SBarry Smith /*
82498725619SBarry Smith     These macros are currently hardwired to match the regular data types, so there is no support for a different
82598725619SBarry Smith     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
82698725619SBarry Smith  */
82798725619SBarry Smith #define MPIU_MATSCALAR MPIU_SCALAR
82898725619SBarry Smith typedef PetscScalar MatScalar;
82998725619SBarry Smith typedef PetscReal MatReal;
83098725619SBarry Smith 
8318ad47952SJed Brown struct petsc_mpiu_2scalar {PetscScalar a,b;};
8328ad47952SJed Brown PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
833df4397b0SStefano Zampini 
834a616ada9SVaclav Hapla #if defined(PETSC_USE_64BIT_INDICES)
8358ad47952SJed Brown struct petsc_mpiu_2int {PetscInt a,b;};
8368ad47952SJed Brown PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
8378ad47952SJed Brown #else
8388ad47952SJed Brown #define MPIU_2INT MPI_2INT
8398ad47952SJed Brown #endif
840e9fa29b7SSatish Balay 
841b2fb0278SBarry Smith PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
842b2fb0278SBarry Smith {
843fa711258SJed Brown   PetscInt result = 1;
844fa711258SJed Brown   while (power) {
845fa711258SJed Brown     if (power & 1) result *= base;
846fa711258SJed Brown     power >>= 1;
847fa711258SJed Brown     base *= base;
848fa711258SJed Brown   }
849fa711258SJed Brown   return result;
850fa711258SJed Brown }
851b2fb0278SBarry Smith 
852b2fb0278SBarry Smith PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
853b2fb0278SBarry Smith {
854fa711258SJed Brown   PetscReal result = 1;
855d98d5da7SBarry Smith   if (power < 0) {
856d98d5da7SBarry Smith     power = -power;
85710d40e53SLisandro Dalcin     base  = ((PetscReal)1)/base;
858d98d5da7SBarry Smith   }
859fa711258SJed Brown   while (power) {
860fa711258SJed Brown     if (power & 1) result *= base;
861fa711258SJed Brown     power >>= 1;
862fa711258SJed Brown     base *= base;
863fa711258SJed Brown   }
864fa711258SJed Brown   return result;
865fa711258SJed Brown }
866fa711258SJed Brown 
867b2fb0278SBarry Smith PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
868b2fb0278SBarry Smith {
869*5117d392SLisandro Dalcin   PetscScalar result = (PetscReal)1;
8708b49ba18SBarry Smith   if (power < 0) {
8718b49ba18SBarry Smith     power = -power;
87210d40e53SLisandro Dalcin     base  = ((PetscReal)1)/base;
8738b49ba18SBarry Smith   }
8748b49ba18SBarry Smith   while (power) {
8758b49ba18SBarry Smith     if (power & 1) result *= base;
8768b49ba18SBarry Smith     power >>= 1;
8778b49ba18SBarry Smith     base *= base;
8788b49ba18SBarry Smith   }
8798b49ba18SBarry Smith   return result;
8808b49ba18SBarry Smith }
8818b49ba18SBarry Smith 
882b2fb0278SBarry Smith PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
883b2fb0278SBarry Smith {
884b2fb0278SBarry Smith   PetscScalar cpower = power;
885b2fb0278SBarry Smith   return PetscPowScalar(base,cpower);
886b2fb0278SBarry Smith }
88778a59e97SMatthew G. Knepley 
888bebf13c0SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt,const PetscReal[],const PetscReal[],PetscReal*,PetscReal*);
889e489efc1SBarry Smith #endif
890