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