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