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