Actual source code: petscmath.h
1: /*
2: PETSc mathematics include file. Defines certain basic mathematical
3: constants and functions for working with single, double, and quad precision
4: floating point numbers as well as complex single and double.
6: This file is included by petscsys.h and should not be used directly.
7: */
8: #pragma once
10: #include <math.h>
11: #include <float.h>
12: #include <petscmacros.h>
13: #include <petscsystypes.h>
15: /* SUBMANSEC = Sys */
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: */
23: /*
24: Real number definitions
25: */
26: #if PetscDefined(USE_REAL_SINGLE)
27: /*MC
28: PetscSqrtReal - Returns the square root of a `PetscReal` value
30: Synopsis:
31: #include <petscmath.h>
32: PetscReal PetscSqrtReal(PetscReal a)
34: Not Collective; No Fortran Support
36: Input Parameter:
37: . a - the value
39: Level: beginner
41: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtComplex()`, `PetscSqrtScalar()`
42: M*/
43: #define PetscSqrtReal(a) sqrtf(a)
44: /*MC
45: PetscCbrtReal - Returns the cube root of a `PetscReal` value
47: Synopsis:
48: #include <petscmath.h>
49: PetscReal PetscCbrtReal(PetscReal a)
51: Not Collective; No Fortran Support
53: Input Parameter:
54: . a - the value
56: Level: beginner
58: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
59: M*/
60: #define PetscCbrtReal(a) cbrtf(a)
61: /*MC
62: PetscHypotReal - Returns the Euclidean distance `sqrt(a*a + b*b)` of two `PetscReal` values, without intermediate overflow
64: Synopsis:
65: #include <petscmath.h>
66: PetscReal PetscHypotReal(PetscReal a, PetscReal b)
68: Not Collective; No Fortran Support
70: Input Parameters:
71: + a - the value
72: - b - the value
74: Level: beginner
76: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
77: M*/
78: #define PetscHypotReal(a, b) hypotf(a, b)
79: /*MC
80: PetscAtan2Real - Returns the arc tangent of `a/b`, in the range $[-\pi, \pi]$, using the signs of `a` and `b` to select the quadrant
82: Synopsis:
83: #include <petscmath.h>
84: PetscReal PetscAtan2Real(PetscReal a, PetscReal b)
86: Not Collective; No Fortran Support
88: Input Parameters:
89: + a - the value
90: - b - the value
92: Level: beginner
94: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
95: M*/
96: #define PetscAtan2Real(a, b) atan2f(a, b)
97: /*MC
98: PetscPowReal - Returns the value of `a` raised to the power `b`, both `PetscReal`
100: Synopsis:
101: #include <petscmath.h>
102: PetscReal PetscPowReal(PetscReal a, PetscReal b)
104: Not Collective; No Fortran Support
106: Input Parameters:
107: + a - the value
108: - b - the value
110: Level: beginner
112: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowComplex()`, `PetscPowScalar()`
113: M*/
114: #define PetscPowReal(a, b) powf(a, b)
115: /*MC
116: PetscExpReal - Returns the natural exponential $e^a$ of a `PetscReal` value
118: Synopsis:
119: #include <petscmath.h>
120: PetscReal PetscExpReal(PetscReal a)
122: Not Collective; No Fortran Support
124: Input Parameter:
125: . a - the value
127: Level: beginner
129: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpComplex()`, `PetscExpScalar()`
130: M*/
131: #define PetscExpReal(a) expf(a)
132: /*MC
133: PetscLogReal - Returns the natural logarithm of a `PetscReal` value
135: Synopsis:
136: #include <petscmath.h>
137: PetscReal PetscLogReal(PetscReal a)
139: Not Collective; No Fortran Support
141: Input Parameter:
142: . a - the value
144: Level: beginner
146: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogComplex()`, `PetscLogScalar()`
147: M*/
148: #define PetscLogReal(a) logf(a)
149: /*MC
150: PetscLog10Real - Returns the base-10 logarithm of a `PetscReal` value
152: Synopsis:
153: #include <petscmath.h>
154: PetscReal PetscLog10Real(PetscReal a)
156: Not Collective; No Fortran Support
158: Input Parameter:
159: . a - the value
161: Level: beginner
163: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
164: M*/
165: #define PetscLog10Real(a) log10f(a)
166: /*MC
167: PetscLog2Real - Returns the base-2 logarithm of a `PetscReal` value
169: Synopsis:
170: #include <petscmath.h>
171: PetscReal PetscLog2Real(PetscReal a)
173: Not Collective; No Fortran Support
175: Input Parameter:
176: . a - the value
178: Level: beginner
180: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
181: M*/
182: #define PetscLog2Real(a) log2f(a)
183: /*MC
184: PetscSinReal - Returns the sine of a `PetscReal` value, with argument in radians
186: Synopsis:
187: #include <petscmath.h>
188: PetscReal PetscSinReal(PetscReal a)
190: Not Collective; No Fortran Support
192: Input Parameter:
193: . a - the value
195: Level: beginner
197: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinComplex()`, `PetscSinScalar()`
198: M*/
199: #define PetscSinReal(a) sinf(a)
200: /*MC
201: PetscCosReal - Returns the cosine of a `PetscReal` value, with argument in radians
203: Synopsis:
204: #include <petscmath.h>
205: PetscReal PetscCosReal(PetscReal a)
207: Not Collective; No Fortran Support
209: Input Parameter:
210: . a - the value
212: Level: beginner
214: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosComplex()`, `PetscCosScalar()`
215: M*/
216: #define PetscCosReal(a) cosf(a)
217: /*MC
218: PetscTanReal - Returns the tangent of a `PetscReal` value, with argument in radians
220: Synopsis:
221: #include <petscmath.h>
222: PetscReal PetscTanReal(PetscReal a)
224: Not Collective; No Fortran Support
226: Input Parameter:
227: . a - the value
229: Level: beginner
231: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanComplex()`, `PetscTanScalar()`
232: M*/
233: #define PetscTanReal(a) tanf(a)
234: /*MC
235: PetscAsinReal - Returns the arc sine of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$
237: Synopsis:
238: #include <petscmath.h>
239: PetscReal PetscAsinReal(PetscReal a)
241: Not Collective; No Fortran Support
243: Input Parameter:
244: . a - the value
246: Level: beginner
248: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinComplex()`, `PetscAsinScalar()`
249: M*/
250: #define PetscAsinReal(a) asinf(a)
251: /*MC
252: PetscAcosReal - Returns the arc cosine of a `PetscReal` value, returned in radians in the range $[0, \pi]$
254: Synopsis:
255: #include <petscmath.h>
256: PetscReal PetscAcosReal(PetscReal a)
258: Not Collective; No Fortran Support
260: Input Parameter:
261: . a - the value
263: Level: beginner
265: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosComplex()`, `PetscAcosScalar()`
266: M*/
267: #define PetscAcosReal(a) acosf(a)
268: /*MC
269: PetscAtanReal - Returns the arc tangent of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$
271: Synopsis:
272: #include <petscmath.h>
273: PetscReal PetscAtanReal(PetscReal a)
275: Not Collective; No Fortran Support
277: Input Parameter:
278: . a - the value
280: Level: beginner
282: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanComplex()`, `PetscAtanScalar()`
283: M*/
284: #define PetscAtanReal(a) atanf(a)
285: /*MC
286: PetscSinhReal - Returns the hyperbolic sine of a `PetscReal` value
288: Synopsis:
289: #include <petscmath.h>
290: PetscReal PetscSinhReal(PetscReal a)
292: Not Collective; No Fortran Support
294: Input Parameter:
295: . a - the value
297: Level: beginner
299: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhComplex()`, `PetscSinhScalar()`
300: M*/
301: #define PetscSinhReal(a) sinhf(a)
302: /*MC
303: PetscCoshReal - Returns the hyperbolic cosine of a `PetscReal` value
305: Synopsis:
306: #include <petscmath.h>
307: PetscReal PetscCoshReal(PetscReal a)
309: Not Collective; No Fortran Support
311: Input Parameter:
312: . a - the value
314: Level: beginner
316: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshComplex()`, `PetscCoshScalar()`
317: M*/
318: #define PetscCoshReal(a) coshf(a)
319: /*MC
320: PetscTanhReal - Returns the hyperbolic tangent of a `PetscReal` value
322: Synopsis:
323: #include <petscmath.h>
324: PetscReal PetscTanhReal(PetscReal a)
326: Not Collective; No Fortran Support
328: Input Parameter:
329: . a - the value
331: Level: beginner
333: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhComplex()`, `PetscTanhScalar()`
334: M*/
335: #define PetscTanhReal(a) tanhf(a)
336: /*MC
337: PetscAsinhReal - Returns the inverse hyperbolic sine of a `PetscReal` value
339: Synopsis:
340: #include <petscmath.h>
341: PetscReal PetscAsinhReal(PetscReal a)
343: Not Collective; No Fortran Support
345: Input Parameter:
346: . a - the value
348: Level: beginner
350: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhComplex()`, `PetscAsinhScalar()`
351: M*/
352: #define PetscAsinhReal(a) asinhf(a)
353: /*MC
354: PetscAcoshReal - Returns the inverse hyperbolic cosine of a `PetscReal` value
356: Synopsis:
357: #include <petscmath.h>
358: PetscReal PetscAcoshReal(PetscReal a)
360: Not Collective; No Fortran Support
362: Input Parameter:
363: . a - the value
365: Level: beginner
367: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshComplex()`, `PetscAcoshScalar()`
368: M*/
369: #define PetscAcoshReal(a) acoshf(a)
370: /*MC
371: PetscAtanhReal - Returns the inverse hyperbolic tangent of a `PetscReal` value
373: Synopsis:
374: #include <petscmath.h>
375: PetscReal PetscAtanhReal(PetscReal a)
377: Not Collective; No Fortran Support
379: Input Parameter:
380: . a - the value
382: Level: beginner
384: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhComplex()`, `PetscAtanhScalar()`
385: M*/
386: #define PetscAtanhReal(a) atanhf(a)
387: /*MC
388: PetscErfReal - Returns the error function of a `PetscReal` value
390: Synopsis:
391: #include <petscmath.h>
392: PetscReal PetscErfReal(PetscReal a)
394: Not Collective; No Fortran Support
396: Input Parameter:
397: . a - the value
399: Level: beginner
401: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
402: M*/
403: #define PetscErfReal(a) erff(a)
404: /*MC
405: PetscCeilReal - Returns the smallest integer value, returned as a `PetscReal`, that is not less than `a`
407: Synopsis:
408: #include <petscmath.h>
409: PetscReal PetscCeilReal(PetscReal a)
411: Not Collective; No Fortran Support
413: Input Parameter:
414: . a - the value
416: Level: beginner
418: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
419: M*/
420: #define PetscCeilReal(a) ceilf(a)
421: /*MC
422: PetscFloorReal - Returns the largest integer value, returned as a `PetscReal`, that is not greater than `a`
424: Synopsis:
425: #include <petscmath.h>
426: PetscReal PetscFloorReal(PetscReal a)
428: Not Collective; No Fortran Support
430: Input Parameter:
431: . a - the value
433: Level: beginner
435: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
436: M*/
437: #define PetscFloorReal(a) floorf(a)
438: /*MC
439: PetscRintReal - Returns the value of `a` rounded to the nearest integer, returned as a `PetscReal` in the configured precision
441: Synopsis:
442: #include <petscmath.h>
443: PetscReal PetscRintReal(PetscReal a)
445: Not Collective; No Fortran Support
447: Input Parameter:
448: . a - the value
450: Level: beginner
452: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
453: M*/
454: #define PetscRintReal(a) rintf(a)
455: /*MC
456: PetscFmodReal - Returns the floating-point remainder of `a/b`, with the same sign as `a`, returned as a `PetscReal`
458: Synopsis:
459: #include <petscmath.h>
460: PetscReal PetscFmodReal(PetscReal a, PetscReal b)
462: Not Collective; No Fortran Support
464: Input Parameters:
465: + a - the value
466: - b - the value
468: Level: beginner
470: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
471: M*/
472: #define PetscFmodReal(a, b) fmodf(a, b)
473: /*MC
474: PetscCopysignReal - Returns the value with the magnitude of `a` and the sign of `b`, as a `PetscReal`
476: Synopsis:
477: #include <petscmath.h>
478: PetscReal PetscCopysignReal(PetscReal a, PetscReal b)
480: Not Collective; No Fortran Support
482: Input Parameters:
483: + a - the value
484: - b - the value
486: Level: beginner
488: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
489: M*/
490: #define PetscCopysignReal(a, b) copysignf(a, b)
491: /*MC
492: PetscTGamma - Returns the value of the gamma function $\Gamma(a)$ in the configured `PetscReal` precision
494: Synopsis:
495: #include <petscmath.h>
496: PetscReal PetscTGamma(PetscReal a)
498: Not Collective; No Fortran Support
500: Input Parameter:
501: . a - the value
503: Level: beginner
505: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
506: M*/
507: #define PetscTGamma(a) tgammaf(a)
508: #if PetscDefined(HAVE_LGAMMA_IS_GAMMA)
509: /*MC
510: PetscLGamma - Returns the natural logarithm of the absolute value of the gamma function in the configured `PetscReal` precision
512: Synopsis:
513: #include <petscmath.h>
514: PetscReal PetscLGamma(PetscReal a)
516: Not Collective; No Fortran Support
518: Input Parameter:
519: . a - the value
521: Level: beginner
523: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
524: M*/
525: #define PetscLGamma(a) gammaf(a)
526: #else
527: #define PetscLGamma(a) lgammaf(a)
528: #endif
530: #elif PetscDefined(USE_REAL_DOUBLE)
531: #define PetscSqrtReal(a) sqrt(a)
532: #define PetscCbrtReal(a) cbrt(a)
533: #define PetscHypotReal(a, b) hypot(a, b)
534: #define PetscAtan2Real(a, b) atan2(a, b)
535: #define PetscPowReal(a, b) pow(a, b)
536: #define PetscExpReal(a) exp(a)
537: #define PetscLogReal(a) log(a)
538: #define PetscLog10Real(a) log10(a)
539: #define PetscLog2Real(a) log2(a)
540: #define PetscSinReal(a) sin(a)
541: #define PetscCosReal(a) cos(a)
542: #define PetscTanReal(a) tan(a)
543: #define PetscAsinReal(a) asin(a)
544: #define PetscAcosReal(a) acos(a)
545: #define PetscAtanReal(a) atan(a)
546: #define PetscSinhReal(a) sinh(a)
547: #define PetscCoshReal(a) cosh(a)
548: #define PetscTanhReal(a) tanh(a)
549: #define PetscAsinhReal(a) asinh(a)
550: #define PetscAcoshReal(a) acosh(a)
551: #define PetscAtanhReal(a) atanh(a)
552: #define PetscErfReal(a) erf(a)
553: #define PetscCeilReal(a) ceil(a)
554: #define PetscFloorReal(a) floor(a)
555: #define PetscRintReal(a) rint(a)
556: #define PetscFmodReal(a, b) fmod(a, b)
557: #define PetscCopysignReal(a, b) copysign(a, b)
558: #define PetscTGamma(a) tgamma(a)
559: #if PetscDefined(HAVE_LGAMMA_IS_GAMMA)
560: #define PetscLGamma(a) gamma(a)
561: #else
562: #define PetscLGamma(a) lgamma(a)
563: #endif
565: #elif PetscDefined(USE_REAL___FLOAT128)
566: #define PetscSqrtReal(a) sqrtq(a)
567: #define PetscCbrtReal(a) cbrtq(a)
568: #define PetscHypotReal(a, b) hypotq(a, b)
569: #define PetscAtan2Real(a, b) atan2q(a, b)
570: #define PetscPowReal(a, b) powq(a, b)
571: #define PetscExpReal(a) expq(a)
572: #define PetscLogReal(a) logq(a)
573: #define PetscLog10Real(a) log10q(a)
574: #define PetscLog2Real(a) log2q(a)
575: #define PetscSinReal(a) sinq(a)
576: #define PetscCosReal(a) cosq(a)
577: #define PetscTanReal(a) tanq(a)
578: #define PetscAsinReal(a) asinq(a)
579: #define PetscAcosReal(a) acosq(a)
580: #define PetscAtanReal(a) atanq(a)
581: #define PetscSinhReal(a) sinhq(a)
582: #define PetscCoshReal(a) coshq(a)
583: #define PetscTanhReal(a) tanhq(a)
584: #define PetscAsinhReal(a) asinhq(a)
585: #define PetscAcoshReal(a) acoshq(a)
586: #define PetscAtanhReal(a) atanhq(a)
587: #define PetscErfReal(a) erfq(a)
588: #define PetscCeilReal(a) ceilq(a)
589: #define PetscFloorReal(a) floorq(a)
590: #define PetscRintReal(a) rintq(a)
591: #define PetscFmodReal(a, b) fmodq(a, b)
592: #define PetscCopysignReal(a, b) copysignq(a, b)
593: #define PetscTGamma(a) tgammaq(a)
594: #if PetscDefined(HAVE_LGAMMA_IS_GAMMA)
595: #define PetscLGamma(a) gammaq(a)
596: #else
597: #define PetscLGamma(a) lgammaq(a)
598: #endif
600: #elif PetscDefined(USE_REAL___FP16)
601: #define PetscSqrtReal(a) sqrtf(a)
602: #define PetscCbrtReal(a) cbrtf(a)
603: #define PetscHypotReal(a, b) hypotf(a, b)
604: #define PetscAtan2Real(a, b) atan2f(a, b)
605: #define PetscPowReal(a, b) powf(a, b)
606: #define PetscExpReal(a) expf(a)
607: #define PetscLogReal(a) logf(a)
608: #define PetscLog10Real(a) log10f(a)
609: #define PetscLog2Real(a) log2f(a)
610: #define PetscSinReal(a) sinf(a)
611: #define PetscCosReal(a) cosf(a)
612: #define PetscTanReal(a) tanf(a)
613: #define PetscAsinReal(a) asinf(a)
614: #define PetscAcosReal(a) acosf(a)
615: #define PetscAtanReal(a) atanf(a)
616: #define PetscSinhReal(a) sinhf(a)
617: #define PetscCoshReal(a) coshf(a)
618: #define PetscTanhReal(a) tanhf(a)
619: #define PetscAsinhReal(a) asinhf(a)
620: #define PetscAcoshReal(a) acoshf(a)
621: #define PetscAtanhReal(a) atanhf(a)
622: #define PetscErfReal(a) erff(a)
623: #define PetscCeilReal(a) ceilf(a)
624: #define PetscFloorReal(a) floorf(a)
625: #define PetscRintReal(a) rintf(a)
626: #define PetscFmodReal(a, b) fmodf(a, b)
627: #define PetscCopysignReal(a, b) copysignf(a, b)
628: #define PetscTGamma(a) tgammaf(a)
629: #if PetscDefined(HAVE_LGAMMA_IS_GAMMA)
630: #define PetscLGamma(a) gammaf(a)
631: #else
632: #define PetscLGamma(a) lgammaf(a)
633: #endif
635: #endif /* PETSC_USE_REAL_* */
637: static inline PetscReal PetscSignReal(PetscReal a)
638: {
639: return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
640: }
642: #if !PetscDefined(HAVE_LOG2)
643: #undef PetscLog2Real
644: static inline PetscReal PetscLog2Real(PetscReal a)
645: {
646: return PetscLogReal(a) / PetscLogReal((PetscReal)2);
647: }
648: #endif
650: #if PetscDefined(HAVE_REAL___FLOAT128) && !PetscDefined(SKIP_REAL___FLOAT128)
651: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
652: #endif
653: #if PetscDefined(HAVE_REAL___FP16) && !PetscDefined(SKIP_REAL___FP16)
654: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
655: #endif
657: /*MC
658: MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in
660: Level: beginner
662: Note:
663: In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
665: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
666: M*/
667: #if PetscDefined(USE_REAL_SINGLE)
668: #define MPIU_REAL MPI_FLOAT
669: #elif PetscDefined(USE_REAL_DOUBLE)
670: #define MPIU_REAL MPI_DOUBLE
671: #elif PetscDefined(USE_REAL___FLOAT128)
672: #define MPIU_REAL MPIU___FLOAT128
673: #elif PetscDefined(USE_REAL___FP16)
674: #define MPIU_REAL MPIU___FP16
675: #endif /* PETSC_USE_REAL_* */
677: /*
678: Complex number definitions
679: */
680: #if PetscDefined(HAVE_COMPLEX)
681: #if defined(__cplusplus) && !PetscDefined(USE_REAL___FLOAT128)
682: /* C++ support of complex number */
684: /*MC
685: PetscRealPartComplex - Returns the real part of a `PetscComplex` value, as a `PetscReal`
687: Synopsis:
688: #include <petscmath.h>
689: PetscReal PetscRealPartComplex(PetscComplex a)
691: Not Collective; No Fortran Support
693: Input Parameter:
694: . a - the value
696: Level: beginner
698: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
699: M*/
700: #define PetscRealPartComplex(a) (static_cast<PetscComplex>(a)).real()
701: /*MC
702: PetscImaginaryPartComplex - Returns the imaginary part of a `PetscComplex` value, as a `PetscReal`
704: Synopsis:
705: #include <petscmath.h>
706: PetscReal PetscImaginaryPartComplex(PetscComplex a)
708: Not Collective; No Fortran Support
710: Input Parameter:
711: . a - the value
713: Level: beginner
715: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
716: M*/
717: #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
718: /*MC
719: PetscAbsComplex - Returns the absolute value (magnitude) of a `PetscComplex` value, as a `PetscReal`
721: Synopsis:
722: #include <petscmath.h>
723: PetscReal PetscAbsComplex(PetscComplex a)
725: Not Collective; No Fortran Support
727: Input Parameter:
728: . a - the value
730: Level: beginner
732: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
733: M*/
734: #define PetscAbsComplex(a) petsccomplexlib::abs(static_cast<PetscComplex>(a))
735: /*MC
736: PetscArgComplex - Returns the argument (phase angle) of a `PetscComplex` value, as a `PetscReal`
738: Synopsis:
739: #include <petscmath.h>
740: PetscReal PetscArgComplex(PetscComplex a)
742: Not Collective; No Fortran Support
744: Input Parameter:
745: . a - the value
747: Level: beginner
749: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
750: M*/
751: #define PetscArgComplex(a) petsccomplexlib::arg(static_cast<PetscComplex>(a))
752: /*MC
753: PetscConjComplex - Returns the complex conjugate of a `PetscComplex` value
755: Synopsis:
756: #include <petscmath.h>
757: PetscComplex PetscConjComplex(PetscComplex a)
759: Not Collective; No Fortran Support
761: Input Parameter:
762: . a - the value
764: Level: beginner
766: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConj()`
767: M*/
768: #define PetscConjComplex(a) petsccomplexlib::conj(static_cast<PetscComplex>(a))
769: /*MC
770: PetscSqrtComplex - Returns the principal value of the square root of a `PetscComplex` value
772: Synopsis:
773: #include <petscmath.h>
774: PetscComplex PetscSqrtComplex(PetscComplex a)
776: Not Collective; No Fortran Support
778: Input Parameter:
779: . a - the value
781: Level: beginner
783: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtScalar()`
784: M*/
785: #define PetscSqrtComplex(a) petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
786: /*MC
787: PetscPowComplex - Returns the complex value `a` raised to the complex power `b`
789: Synopsis:
790: #include <petscmath.h>
791: PetscComplex PetscPowComplex(PetscComplex a, PetscComplex b)
793: Not Collective; No Fortran Support
795: Input Parameters:
796: + a - the value
797: - b - the value
799: Level: beginner
801: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowScalar()`
802: M*/
803: #define PetscPowComplex(a, b) petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
804: /*MC
805: PetscExpComplex - Returns the complex exponential $e^a$ of a `PetscComplex` value
807: Synopsis:
808: #include <petscmath.h>
809: PetscComplex PetscExpComplex(PetscComplex a)
811: Not Collective; No Fortran Support
813: Input Parameter:
814: . a - the value
816: Level: beginner
818: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpScalar()`
819: M*/
820: #define PetscExpComplex(a) petsccomplexlib::exp(static_cast<PetscComplex>(a))
821: /*MC
822: PetscLogComplex - Returns the principal value of the complex natural logarithm of a `PetscComplex` value
824: Synopsis:
825: #include <petscmath.h>
826: PetscComplex PetscLogComplex(PetscComplex a)
828: Not Collective; No Fortran Support
830: Input Parameter:
831: . a - the value
833: Level: beginner
835: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogScalar()`
836: M*/
837: #define PetscLogComplex(a) petsccomplexlib::log(static_cast<PetscComplex>(a))
838: /*MC
839: PetscSinComplex - Returns the complex sine of a `PetscComplex` value
841: Synopsis:
842: #include <petscmath.h>
843: PetscComplex PetscSinComplex(PetscComplex a)
845: Not Collective; No Fortran Support
847: Input Parameter:
848: . a - the value
850: Level: beginner
852: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinScalar()`
853: M*/
854: #define PetscSinComplex(a) petsccomplexlib::sin(static_cast<PetscComplex>(a))
855: /*MC
856: PetscCosComplex - Returns the complex cosine of a `PetscComplex` value
858: Synopsis:
859: #include <petscmath.h>
860: PetscComplex PetscCosComplex(PetscComplex a)
862: Not Collective; No Fortran Support
864: Input Parameter:
865: . a - the value
867: Level: beginner
869: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosScalar()`
870: M*/
871: #define PetscCosComplex(a) petsccomplexlib::cos(static_cast<PetscComplex>(a))
872: /*MC
873: PetscTanComplex - Returns the complex tangent of a `PetscComplex` value
875: Synopsis:
876: #include <petscmath.h>
877: PetscComplex PetscTanComplex(PetscComplex a)
879: Not Collective; No Fortran Support
881: Input Parameter:
882: . a - the value
884: Level: beginner
886: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanScalar()`
887: M*/
888: #define PetscTanComplex(a) petsccomplexlib::tan(static_cast<PetscComplex>(a))
889: /*MC
890: PetscAsinComplex - Returns the complex arc sine of a `PetscComplex` value
892: Synopsis:
893: #include <petscmath.h>
894: PetscComplex PetscAsinComplex(PetscComplex a)
896: Not Collective; No Fortran Support
898: Input Parameter:
899: . a - the value
901: Level: beginner
903: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinScalar()`
904: M*/
905: #define PetscAsinComplex(a) petsccomplexlib::asin(static_cast<PetscComplex>(a))
906: /*MC
907: PetscAcosComplex - Returns the complex arc cosine of a `PetscComplex` value
909: Synopsis:
910: #include <petscmath.h>
911: PetscComplex PetscAcosComplex(PetscComplex a)
913: Not Collective; No Fortran Support
915: Input Parameter:
916: . a - the value
918: Level: beginner
920: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosScalar()`
921: M*/
922: #define PetscAcosComplex(a) petsccomplexlib::acos(static_cast<PetscComplex>(a))
923: /*MC
924: PetscAtanComplex - Returns the complex arc tangent of a `PetscComplex` value
926: Synopsis:
927: #include <petscmath.h>
928: PetscComplex PetscAtanComplex(PetscComplex a)
930: Not Collective; No Fortran Support
932: Input Parameter:
933: . a - the value
935: Level: beginner
937: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanScalar()`
938: M*/
939: #define PetscAtanComplex(a) petsccomplexlib::atan(static_cast<PetscComplex>(a))
940: /*MC
941: PetscSinhComplex - Returns the complex hyperbolic sine of a `PetscComplex` value
943: Synopsis:
944: #include <petscmath.h>
945: PetscComplex PetscSinhComplex(PetscComplex a)
947: Not Collective; No Fortran Support
949: Input Parameter:
950: . a - the value
952: Level: beginner
954: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhScalar()`
955: M*/
956: #define PetscSinhComplex(a) petsccomplexlib::sinh(static_cast<PetscComplex>(a))
957: /*MC
958: PetscCoshComplex - Returns the complex hyperbolic cosine of a `PetscComplex` value
960: Synopsis:
961: #include <petscmath.h>
962: PetscComplex PetscCoshComplex(PetscComplex a)
964: Not Collective; No Fortran Support
966: Input Parameter:
967: . a - the value
969: Level: beginner
971: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshScalar()`
972: M*/
973: #define PetscCoshComplex(a) petsccomplexlib::cosh(static_cast<PetscComplex>(a))
974: /*MC
975: PetscTanhComplex - Returns the complex hyperbolic tangent of a `PetscComplex` value
977: Synopsis:
978: #include <petscmath.h>
979: PetscComplex PetscTanhComplex(PetscComplex a)
981: Not Collective; No Fortran Support
983: Input Parameter:
984: . a - the value
986: Level: beginner
988: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhScalar()`
989: M*/
990: #define PetscTanhComplex(a) petsccomplexlib::tanh(static_cast<PetscComplex>(a))
991: /*MC
992: PetscAsinhComplex - Returns the complex inverse hyperbolic sine of a `PetscComplex` value
994: Synopsis:
995: #include <petscmath.h>
996: PetscComplex PetscAsinhComplex(PetscComplex a)
998: Not Collective; No Fortran Support
1000: Input Parameter:
1001: . a - the value
1003: Level: beginner
1005: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhScalar()`
1006: M*/
1007: #define PetscAsinhComplex(a) petsccomplexlib::asinh(static_cast<PetscComplex>(a))
1008: /*MC
1009: PetscAcoshComplex - Returns the complex inverse hyperbolic cosine of a `PetscComplex` value
1011: Synopsis:
1012: #include <petscmath.h>
1013: PetscComplex PetscAcoshComplex(PetscComplex a)
1015: Not Collective; No Fortran Support
1017: Input Parameter:
1018: . a - the value
1020: Level: beginner
1022: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshScalar()`
1023: M*/
1024: #define PetscAcoshComplex(a) petsccomplexlib::acosh(static_cast<PetscComplex>(a))
1025: /*MC
1026: PetscAtanhComplex - Returns the complex inverse hyperbolic tangent of a `PetscComplex` value
1028: Synopsis:
1029: #include <petscmath.h>
1030: PetscComplex PetscAtanhComplex(PetscComplex a)
1032: Not Collective; No Fortran Support
1034: Input Parameter:
1035: . a - the value
1037: Level: beginner
1039: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhScalar()`
1040: M*/
1041: #define PetscAtanhComplex(a) petsccomplexlib::atanh(static_cast<PetscComplex>(a))
1043: /* TODO: Add configure tests
1045: #if !PetscDefined(HAVE_CXX_TAN_COMPLEX)
1046: #undef PetscTanComplex
1047: static inline PetscComplex PetscTanComplex(PetscComplex z)
1048: {
1049: return PetscSinComplex(z)/PetscCosComplex(z);
1050: }
1051: #endif
1053: #if !PetscDefined(HAVE_CXX_TANH_COMPLEX)
1054: #undef PetscTanhComplex
1055: static inline PetscComplex PetscTanhComplex(PetscComplex z)
1056: {
1057: return PetscSinhComplex(z)/PetscCoshComplex(z);
1058: }
1059: #endif
1061: #if !PetscDefined(HAVE_CXX_ASIN_COMPLEX)
1062: #undef PetscAsinComplex
1063: static inline PetscComplex PetscAsinComplex(PetscComplex z)
1064: {
1065: const PetscComplex j(0,1);
1066: return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
1067: }
1068: #endif
1070: #if !PetscDefined(HAVE_CXX_ACOS_COMPLEX)
1071: #undef PetscAcosComplex
1072: static inline PetscComplex PetscAcosComplex(PetscComplex z)
1073: {
1074: const PetscComplex j(0,1);
1075: return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
1076: }
1077: #endif
1079: #if !PetscDefined(HAVE_CXX_ATAN_COMPLEX)
1080: #undef PetscAtanComplex
1081: static inline PetscComplex PetscAtanComplex(PetscComplex z)
1082: {
1083: const PetscComplex j(0,1);
1084: return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
1085: }
1086: #endif
1088: #if !PetscDefined(HAVE_CXX_ASINH_COMPLEX)
1089: #undef PetscAsinhComplex
1090: static inline PetscComplex PetscAsinhComplex(PetscComplex z)
1091: {
1092: return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
1093: }
1094: #endif
1096: #if !PetscDefined(HAVE_CXX_ACOSH_COMPLEX)
1097: #undef PetscAcoshComplex
1098: static inline PetscComplex PetscAcoshComplex(PetscComplex z)
1099: {
1100: return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
1101: }
1102: #endif
1104: #if !PetscDefined(HAVE_CXX_ATANH_COMPLEX)
1105: #undef PetscAtanhComplex
1106: static inline PetscComplex PetscAtanhComplex(PetscComplex z)
1107: {
1108: return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
1109: }
1110: #endif
1112: */
1114: #else /* C99 support of complex number */
1116: #if PetscDefined(USE_REAL_SINGLE)
1117: #define PetscRealPartComplex(a) crealf(a)
1118: #define PetscImaginaryPartComplex(a) cimagf(a)
1119: #define PetscAbsComplex(a) cabsf(a)
1120: #define PetscArgComplex(a) cargf(a)
1121: #define PetscConjComplex(a) conjf(a)
1122: #define PetscSqrtComplex(a) csqrtf(a)
1123: #define PetscPowComplex(a, b) cpowf(a, b)
1124: #define PetscExpComplex(a) cexpf(a)
1125: #define PetscLogComplex(a) clogf(a)
1126: #define PetscSinComplex(a) csinf(a)
1127: #define PetscCosComplex(a) ccosf(a)
1128: #define PetscTanComplex(a) ctanf(a)
1129: #define PetscAsinComplex(a) casinf(a)
1130: #define PetscAcosComplex(a) cacosf(a)
1131: #define PetscAtanComplex(a) catanf(a)
1132: #define PetscSinhComplex(a) csinhf(a)
1133: #define PetscCoshComplex(a) ccoshf(a)
1134: #define PetscTanhComplex(a) ctanhf(a)
1135: #define PetscAsinhComplex(a) casinhf(a)
1136: #define PetscAcoshComplex(a) cacoshf(a)
1137: #define PetscAtanhComplex(a) catanhf(a)
1139: #elif PetscDefined(USE_REAL_DOUBLE)
1140: #define PetscRealPartComplex(a) creal(a)
1141: #define PetscImaginaryPartComplex(a) cimag(a)
1142: #define PetscAbsComplex(a) cabs(a)
1143: #define PetscArgComplex(a) carg(a)
1144: #define PetscConjComplex(a) conj(a)
1145: #define PetscSqrtComplex(a) csqrt(a)
1146: #define PetscPowComplex(a, b) cpow(a, b)
1147: #define PetscExpComplex(a) cexp(a)
1148: #define PetscLogComplex(a) clog(a)
1149: #define PetscSinComplex(a) csin(a)
1150: #define PetscCosComplex(a) ccos(a)
1151: #define PetscTanComplex(a) ctan(a)
1152: #define PetscAsinComplex(a) casin(a)
1153: #define PetscAcosComplex(a) cacos(a)
1154: #define PetscAtanComplex(a) catan(a)
1155: #define PetscSinhComplex(a) csinh(a)
1156: #define PetscCoshComplex(a) ccosh(a)
1157: #define PetscTanhComplex(a) ctanh(a)
1158: #define PetscAsinhComplex(a) casinh(a)
1159: #define PetscAcoshComplex(a) cacosh(a)
1160: #define PetscAtanhComplex(a) catanh(a)
1162: #elif PetscDefined(USE_REAL___FLOAT128)
1163: #define PetscRealPartComplex(a) crealq(a)
1164: #define PetscImaginaryPartComplex(a) cimagq(a)
1165: #define PetscAbsComplex(a) cabsq(a)
1166: #define PetscArgComplex(a) cargq(a)
1167: #define PetscConjComplex(a) conjq(a)
1168: #define PetscSqrtComplex(a) csqrtq(a)
1169: #define PetscPowComplex(a, b) cpowq(a, b)
1170: #define PetscExpComplex(a) cexpq(a)
1171: #define PetscLogComplex(a) clogq(a)
1172: #define PetscSinComplex(a) csinq(a)
1173: #define PetscCosComplex(a) ccosq(a)
1174: #define PetscTanComplex(a) ctanq(a)
1175: #define PetscAsinComplex(a) casinq(a)
1176: #define PetscAcosComplex(a) cacosq(a)
1177: #define PetscAtanComplex(a) catanq(a)
1178: #define PetscSinhComplex(a) csinhq(a)
1179: #define PetscCoshComplex(a) ccoshq(a)
1180: #define PetscTanhComplex(a) ctanhq(a)
1181: #define PetscAsinhComplex(a) casinhq(a)
1182: #define PetscAcoshComplex(a) cacoshq(a)
1183: #define PetscAtanhComplex(a) catanhq(a)
1185: #endif /* PETSC_USE_REAL_* */
1186: #endif /* (__cplusplus) */
1188: /*MC
1189: PETSC_i - the pure imaginary complex number i
1191: Level: intermediate
1193: .seealso: `PetscComplex`, `PetscScalar`
1194: M*/
1195: PETSC_EXTERN PetscComplex PETSC_i;
1197: /*
1198: Try to do the right thing for complex number construction: see
1199: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
1200: for details
1201: */
1202: static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
1203: {
1204: #if defined(__cplusplus) && !PetscDefined(USE_REAL___FLOAT128)
1205: return PetscComplex(x, y);
1206: #elif defined(_Imaginary_I)
1207: return x + y * _Imaginary_I;
1208: #else
1209: { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
1211: "For each floating type there is a corresponding real type, which is always a real floating
1212: type. For real floating types, it is the same type. For complex types, it is the type given
1213: by deleting the keyword _Complex from the type name."
1215: So type punning should be portable. */
1216: union
1217: {
1218: PetscComplex z;
1219: PetscReal f[2];
1220: } uz;
1222: uz.f[0] = x;
1223: uz.f[1] = y;
1224: return uz.z;
1225: }
1226: #endif
1227: }
1229: #define MPIU_C_COMPLEX MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
1230: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )
1232: #if PetscDefined(HAVE_REAL___FLOAT128) && !PetscDefined(SKIP_REAL___FLOAT128)
1233: // if complex is not used, then quadmath.h won't be included by petscsystypes.h
1234: #if PetscDefined(USE_COMPLEX)
1235: #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
1236: #else
1237: #define MPIU___COMPLEX128_ATTR_TAG
1238: #endif
1240: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;
1242: #undef MPIU___COMPLEX128_ATTR_TAG
1243: #endif /* PETSC_HAVE_REAL___FLOAT128 */
1245: /*MC
1246: MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`
1248: Level: beginner
1250: Note:
1251: In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
1253: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
1254: M*/
1255: #if PetscDefined(USE_REAL_SINGLE)
1256: #define MPIU_COMPLEX MPI_C_COMPLEX
1257: #elif PetscDefined(USE_REAL_DOUBLE)
1258: #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
1259: #elif PetscDefined(USE_REAL___FLOAT128)
1260: #define MPIU_COMPLEX MPIU___COMPLEX128
1261: #elif PetscDefined(USE_REAL___FP16)
1262: #define MPIU_COMPLEX MPI_C_COMPLEX
1263: #endif /* PETSC_USE_REAL_* */
1265: #endif /* PETSC_HAVE_COMPLEX */
1267: /*
1268: Scalar number definitions
1269: */
1270: #if PetscDefined(USE_COMPLEX) && PetscDefined(HAVE_COMPLEX)
1271: /*MC
1272: MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`
1274: Level: beginner
1276: Note:
1277: In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
1279: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
1280: M*/
1281: #define MPIU_SCALAR MPIU_COMPLEX
1283: /*MC
1284: PetscRealPart - Returns the real part of a `PetscScalar`
1286: Synopsis:
1287: #include <petscmath.h>
1288: PetscReal PetscRealPart(PetscScalar v)
1290: Not Collective
1292: Input Parameter:
1293: . v - value to find the real part of
1295: Level: beginner
1297: .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1298: M*/
1299: #define PetscRealPart(a) PetscRealPartComplex(a)
1301: /*MC
1302: PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`
1304: Synopsis:
1305: #include <petscmath.h>
1306: PetscReal PetscImaginaryPart(PetscScalar v)
1308: Not Collective
1310: Input Parameter:
1311: . v - value to find the imaginary part of
1313: Level: beginner
1315: Note:
1316: If PETSc was configured for real numbers then this always returns the value 0
1318: .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1319: M*/
1320: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
1322: /*MC
1323: PetscAbsScalar - Returns the absolute value (magnitude) of a `PetscScalar` value, as a `PetscReal`
1325: Synopsis:
1326: #include <petscmath.h>
1327: PetscReal PetscAbsScalar(PetscScalar a)
1329: Not Collective; No Fortran Support
1331: Input Parameter:
1332: . a - the value
1334: Level: beginner
1336: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1337: M*/
1338: #define PetscAbsScalar(a) PetscAbsComplex(a)
1339: /*MC
1340: PetscArgScalar - Returns the argument (phase angle) of a `PetscScalar` value, as a `PetscReal`; for real `PetscScalar` this is `0` for nonnegative values and `PETSC_PI` otherwise
1342: Synopsis:
1343: #include <petscmath.h>
1344: PetscReal PetscArgScalar(PetscScalar a)
1346: Not Collective; No Fortran Support
1348: Input Parameter:
1349: . a - the value
1351: Level: beginner
1353: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1354: M*/
1355: #define PetscArgScalar(a) PetscArgComplex(a)
1356: /*MC
1357: PetscConj - Returns the complex conjugate of a `PetscScalar` value; the identity when `PetscScalar` is real
1359: Synopsis:
1360: #include <petscmath.h>
1361: PetscScalar PetscConj(PetscScalar a)
1363: Not Collective; No Fortran Support
1365: Input Parameter:
1366: . a - the value
1368: Level: beginner
1370: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConjComplex()`
1371: M*/
1372: #define PetscConj(a) PetscConjComplex(a)
1373: /*MC
1374: PetscSqrtScalar - Returns the square root of a `PetscScalar` value
1376: Synopsis:
1377: #include <petscmath.h>
1378: PetscScalar PetscSqrtScalar(PetscScalar a)
1380: Not Collective; No Fortran Support
1382: Input Parameter:
1383: . a - the value
1385: Level: beginner
1387: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtComplex()`
1388: M*/
1389: #define PetscSqrtScalar(a) PetscSqrtComplex(a)
1390: /*MC
1391: PetscPowScalar - Returns the value of `a` raised to the power `b`, both `PetscScalar`
1393: Synopsis:
1394: #include <petscmath.h>
1395: PetscScalar PetscPowScalar(PetscScalar a, PetscScalar b)
1397: Not Collective; No Fortran Support
1399: Input Parameters:
1400: + a - the value
1401: - b - the value
1403: Level: beginner
1405: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowComplex()`
1406: M*/
1407: #define PetscPowScalar(a, b) PetscPowComplex(a, b)
1408: /*MC
1409: PetscExpScalar - Returns the exponential $e^a$ of a `PetscScalar` value
1411: Synopsis:
1412: #include <petscmath.h>
1413: PetscScalar PetscExpScalar(PetscScalar a)
1415: Not Collective; No Fortran Support
1417: Input Parameter:
1418: . a - the value
1420: Level: beginner
1422: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpComplex()`
1423: M*/
1424: #define PetscExpScalar(a) PetscExpComplex(a)
1425: /*MC
1426: PetscLogScalar - Returns the natural logarithm of a `PetscScalar` value
1428: Synopsis:
1429: #include <petscmath.h>
1430: PetscScalar PetscLogScalar(PetscScalar a)
1432: Not Collective; No Fortran Support
1434: Input Parameter:
1435: . a - the value
1437: Level: beginner
1439: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogComplex()`
1440: M*/
1441: #define PetscLogScalar(a) PetscLogComplex(a)
1442: /*MC
1443: PetscSinScalar - Returns the sine of a `PetscScalar` value
1445: Synopsis:
1446: #include <petscmath.h>
1447: PetscScalar PetscSinScalar(PetscScalar a)
1449: Not Collective; No Fortran Support
1451: Input Parameter:
1452: . a - the value
1454: Level: beginner
1456: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinComplex()`
1457: M*/
1458: #define PetscSinScalar(a) PetscSinComplex(a)
1459: /*MC
1460: PetscCosScalar - Returns the cosine of a `PetscScalar` value
1462: Synopsis:
1463: #include <petscmath.h>
1464: PetscScalar PetscCosScalar(PetscScalar a)
1466: Not Collective; No Fortran Support
1468: Input Parameter:
1469: . a - the value
1471: Level: beginner
1473: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosComplex()`
1474: M*/
1475: #define PetscCosScalar(a) PetscCosComplex(a)
1476: /*MC
1477: PetscTanScalar - Returns the tangent of a `PetscScalar` value
1479: Synopsis:
1480: #include <petscmath.h>
1481: PetscScalar PetscTanScalar(PetscScalar a)
1483: Not Collective; No Fortran Support
1485: Input Parameter:
1486: . a - the value
1488: Level: beginner
1490: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanComplex()`
1491: M*/
1492: #define PetscTanScalar(a) PetscTanComplex(a)
1493: /*MC
1494: PetscAsinScalar - Returns the arc sine of a `PetscScalar` value
1496: Synopsis:
1497: #include <petscmath.h>
1498: PetscScalar PetscAsinScalar(PetscScalar a)
1500: Not Collective; No Fortran Support
1502: Input Parameter:
1503: . a - the value
1505: Level: beginner
1507: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinComplex()`
1508: M*/
1509: #define PetscAsinScalar(a) PetscAsinComplex(a)
1510: /*MC
1511: PetscAcosScalar - Returns the arc cosine of a `PetscScalar` value
1513: Synopsis:
1514: #include <petscmath.h>
1515: PetscScalar PetscAcosScalar(PetscScalar a)
1517: Not Collective; No Fortran Support
1519: Input Parameter:
1520: . a - the value
1522: Level: beginner
1524: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosComplex()`
1525: M*/
1526: #define PetscAcosScalar(a) PetscAcosComplex(a)
1527: /*MC
1528: PetscAtanScalar - Returns the arc tangent of a `PetscScalar` value
1530: Synopsis:
1531: #include <petscmath.h>
1532: PetscScalar PetscAtanScalar(PetscScalar a)
1534: Not Collective; No Fortran Support
1536: Input Parameter:
1537: . a - the value
1539: Level: beginner
1541: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanComplex()`
1542: M*/
1543: #define PetscAtanScalar(a) PetscAtanComplex(a)
1544: /*MC
1545: PetscSinhScalar - Returns the hyperbolic sine of a `PetscScalar` value
1547: Synopsis:
1548: #include <petscmath.h>
1549: PetscScalar PetscSinhScalar(PetscScalar a)
1551: Not Collective; No Fortran Support
1553: Input Parameter:
1554: . a - the value
1556: Level: beginner
1558: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhComplex()`
1559: M*/
1560: #define PetscSinhScalar(a) PetscSinhComplex(a)
1561: /*MC
1562: PetscCoshScalar - Returns the hyperbolic cosine of a `PetscScalar` value
1564: Synopsis:
1565: #include <petscmath.h>
1566: PetscScalar PetscCoshScalar(PetscScalar a)
1568: Not Collective; No Fortran Support
1570: Input Parameter:
1571: . a - the value
1573: Level: beginner
1575: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshComplex()`
1576: M*/
1577: #define PetscCoshScalar(a) PetscCoshComplex(a)
1578: /*MC
1579: PetscTanhScalar - Returns the hyperbolic tangent of a `PetscScalar` value
1581: Synopsis:
1582: #include <petscmath.h>
1583: PetscScalar PetscTanhScalar(PetscScalar a)
1585: Not Collective; No Fortran Support
1587: Input Parameter:
1588: . a - the value
1590: Level: beginner
1592: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhComplex()`
1593: M*/
1594: #define PetscTanhScalar(a) PetscTanhComplex(a)
1595: /*MC
1596: PetscAsinhScalar - Returns the inverse hyperbolic sine of a `PetscScalar` value
1598: Synopsis:
1599: #include <petscmath.h>
1600: PetscScalar PetscAsinhScalar(PetscScalar a)
1602: Not Collective; No Fortran Support
1604: Input Parameter:
1605: . a - the value
1607: Level: beginner
1609: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhComplex()`
1610: M*/
1611: #define PetscAsinhScalar(a) PetscAsinhComplex(a)
1612: /*MC
1613: PetscAcoshScalar - Returns the inverse hyperbolic cosine of a `PetscScalar` value
1615: Synopsis:
1616: #include <petscmath.h>
1617: PetscScalar PetscAcoshScalar(PetscScalar a)
1619: Not Collective; No Fortran Support
1621: Input Parameter:
1622: . a - the value
1624: Level: beginner
1626: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshComplex()`
1627: M*/
1628: #define PetscAcoshScalar(a) PetscAcoshComplex(a)
1629: /*MC
1630: PetscAtanhScalar - Returns the inverse hyperbolic tangent of a `PetscScalar` value
1632: Synopsis:
1633: #include <petscmath.h>
1634: PetscScalar PetscAtanhScalar(PetscScalar a)
1636: Not Collective; No Fortran Support
1638: Input Parameter:
1639: . a - the value
1641: Level: beginner
1643: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhComplex()`
1644: M*/
1645: #define PetscAtanhScalar(a) PetscAtanhComplex(a)
1647: #else /* PETSC_USE_COMPLEX */
1648: #define MPIU_SCALAR MPIU_REAL
1649: #define PetscRealPart(a) (a)
1650: #define PetscImaginaryPart(a) ((PetscReal)0)
1651: #define PetscAbsScalar(a) PetscAbsReal(a)
1652: #define PetscArgScalar(a) (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
1653: #define PetscConj(a) (a)
1654: #define PetscSqrtScalar(a) PetscSqrtReal(a)
1655: #define PetscPowScalar(a, b) PetscPowReal(a, b)
1656: #define PetscExpScalar(a) PetscExpReal(a)
1657: #define PetscLogScalar(a) PetscLogReal(a)
1658: #define PetscSinScalar(a) PetscSinReal(a)
1659: #define PetscCosScalar(a) PetscCosReal(a)
1660: #define PetscTanScalar(a) PetscTanReal(a)
1661: #define PetscAsinScalar(a) PetscAsinReal(a)
1662: #define PetscAcosScalar(a) PetscAcosReal(a)
1663: #define PetscAtanScalar(a) PetscAtanReal(a)
1664: #define PetscSinhScalar(a) PetscSinhReal(a)
1665: #define PetscCoshScalar(a) PetscCoshReal(a)
1666: #define PetscTanhScalar(a) PetscTanhReal(a)
1667: #define PetscAsinhScalar(a) PetscAsinhReal(a)
1668: #define PetscAcoshScalar(a) PetscAcoshReal(a)
1669: #define PetscAtanhScalar(a) PetscAtanhReal(a)
1671: #endif /* PETSC_USE_COMPLEX */
1673: /*E
1674: PetscScalarPrecision - Names of the floating-point precisions that a `PetscScalar` could in principle be built with
1676: Values:
1677: + `PETSC_SCALAR_DOUBLE` - IEEE double precision
1678: . `PETSC_SCALAR_SINGLE` - IEEE single precision
1679: . `PETSC_SCALAR_LONG_DOUBLE` - C `long double` precision
1680: - `PETSC_SCALAR_HALF` - IEEE half precision
1682: Level: developer
1684: Note:
1685: This enum is reserved for situations where an object might be created in a precision different from `PetscScalar`; the current PETSc code does not use it.
1687: .seealso: `PetscScalar`, `PetscReal`, `PetscComplex`
1688: E*/
1689: typedef enum {
1690: PETSC_SCALAR_DOUBLE,
1691: PETSC_SCALAR_SINGLE,
1692: PETSC_SCALAR_LONG_DOUBLE,
1693: PETSC_SCALAR_HALF
1694: } PetscScalarPrecision;
1696: /*MC
1697: PetscAbs - Returns the absolute value of a number
1699: Synopsis:
1700: #include <petscmath.h>
1701: type PetscAbs(type v)
1703: Not Collective
1705: Input Parameter:
1706: . v - the number
1708: Level: beginner
1710: Note:
1711: The type can be integer or real floating point value, but cannot be complex
1713: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
1714: M*/
1715: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))
1717: /*MC
1718: PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1
1720: Synopsis:
1721: #include <petscmath.h>
1722: int PetscSign(type v)
1724: Not Collective
1726: Input Parameter:
1727: . v - the number
1729: Level: beginner
1731: Note:
1732: The type can be integer or real floating point value
1734: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
1735: M*/
1736: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
1738: /*MC
1739: PetscMin - Returns minimum of two numbers
1741: Synopsis:
1742: #include <petscmath.h>
1743: type PetscMin(type v1, type v2)
1745: Not Collective
1747: Input Parameters:
1748: + v1 - first value to find minimum of
1749: - v2 - second value to find minimum of
1751: Level: beginner
1753: Note:
1754: The type can be integer or floating point value, but cannot be complex
1756: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1757: M*/
1758: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))
1760: /*MC
1761: PetscMax - Returns maximum of two numbers
1763: Synopsis:
1764: #include <petscmath.h>
1765: type max PetscMax(type v1, type v2)
1767: Not Collective
1769: Input Parameters:
1770: + v1 - first value to find maximum of
1771: - v2 - second value to find maximum of
1773: Level: beginner
1775: Note:
1776: The type can be integer or floating point value
1778: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1779: M*/
1780: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))
1782: /*MC
1783: PetscClipInterval - Returns a number clipped to be within an interval
1785: Synopsis:
1786: #include <petscmath.h>
1787: type clip PetscClipInterval(type x, type a, type b)
1789: Not Collective
1791: Input Parameters:
1792: + x - value to use if within interval [a,b]
1793: . a - lower end of interval
1794: - b - upper end of interval
1796: Level: beginner
1798: Note:
1799: The type can be integer or floating point value
1801: Example\:
1802: .vb
1803: PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
1804: PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
1805: .ve
1807: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1808: M*/
1809: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
1811: /*MC
1812: PetscAbsInt - Returns the absolute value of an integer
1814: Synopsis:
1815: #include <petscmath.h>
1816: int abs PetscAbsInt(int v1)
1818: Input Parameter:
1819: . v1 - the integer
1821: Level: beginner
1823: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
1824: M*/
1825: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
1827: /*MC
1828: PetscAbsReal - Returns the absolute value of a real number
1830: Synopsis:
1831: #include <petscmath.h>
1832: Real abs PetscAbsReal(PetscReal v1)
1834: Input Parameter:
1835: . v1 - the `PetscReal` value
1837: Level: beginner
1839: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
1840: M*/
1841: #if PetscDefined(USE_REAL_SINGLE)
1842: #define PetscAbsReal(a) fabsf(a)
1843: #elif PetscDefined(USE_REAL_DOUBLE)
1844: #define PetscAbsReal(a) fabs(a)
1845: #elif PetscDefined(USE_REAL___FLOAT128)
1846: #define PetscAbsReal(a) fabsq(a)
1847: #elif PetscDefined(USE_REAL___FP16)
1848: #define PetscAbsReal(a) fabsf(a)
1849: #endif
1851: /*MC
1852: PetscSqr - Returns the square of a number
1854: Synopsis:
1855: #include <petscmath.h>
1856: type sqr PetscSqr(type v1)
1858: Not Collective
1860: Input Parameter:
1861: . v1 - the value
1863: Level: beginner
1865: Note:
1866: The type can be integer, floating point, or complex floating point
1868: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
1869: M*/
1870: #define PetscSqr(a) ((a) * (a))
1872: /*MC
1873: PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
1874: precision of `PetscReal` be it half, single, double or 128-bit representation
1876: Synopsis:
1877: #include <petscmath.h>
1878: PetscReal PetscRealConstant(real_number)
1880: Not Collective
1882: Input Parameter:
1883: . v1 - the real number, for example 1.5
1885: Level: beginner
1887: Note:
1888: For example, if PETSc is configured with `--with-precision=__float128` and one writes
1889: .vb
1890: PetscReal d = 1.5;
1891: .ve
1892: the result is 1.5 in double precision extended to 128 bit representation, meaning it is very far from the correct value. Hence, one should write
1893: .vb
1894: PetscReal d = PetscRealConstant(1.5);
1895: .ve
1897: .seealso: `PetscReal`
1898: M*/
1899: #if PetscDefined(USE_REAL_SINGLE)
1900: #define PetscRealConstant(constant) constant##F
1901: #elif PetscDefined(USE_REAL_DOUBLE)
1902: #define PetscRealConstant(constant) constant
1903: #elif PetscDefined(USE_REAL___FLOAT128)
1904: #define PetscRealConstant(constant) constant##Q
1905: #elif PetscDefined(USE_REAL___FP16)
1906: #define PetscRealConstant(constant) ((PetscReal)(constant))
1907: #endif
1909: /*
1910: Basic constants
1911: */
1912: /*MC
1913: PETSC_PI - the value of $\pi$ to the correct precision of `PetscReal`.
1915: Level: beginner
1917: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
1918: M*/
1920: /*MC
1921: PETSC_PHI - the value of $\phi$, the Golden Ratio, to the correct precision of `PetscReal`.
1923: Level: beginner
1925: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
1926: M*/
1928: /*MC
1929: PETSC_SQRT2 - the value of $\sqrt{2}$ to the correct precision of `PetscReal`.
1931: Level: beginner
1933: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1934: M*/
1936: /*MC
1937: PETSC_E - the value of Euler's constant $e$ to the correct precision of `PetscReal`.
1939: Level: beginner
1941: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1942: M*/
1944: #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
1945: #pragma GCC diagnostic push
1946: #pragma GCC diagnostic ignored "-Wpedantic"
1947: #endif
1949: PETSC_STATIC_CONSTEXPR PetscReal PETSC_PI = PetscRealConstant(3.141592653589793238462643383279502884);
1950: PETSC_STATIC_CONSTEXPR PetscReal PETSC_PHI = PetscRealConstant(1.618033988749894848204586834365638117);
1951: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT2 = PetscRealConstant(1.414213562373095048801688724209698079);
1952: PETSC_STATIC_CONSTEXPR PetscReal PETSC_E = PetscRealConstant(2.718281828459045235360287471352662498);
1954: /*MC
1955: PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`
1957: Level: beginner
1959: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1960: M*/
1962: /*MC
1963: PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`
1965: Level: beginner
1967: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1968: M*/
1970: /*MC
1971: PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.
1973: Level: beginner
1975: Note:
1976: See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers
1978: Developer Note:
1979: The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.
1981: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1982: M*/
1984: /*MC
1985: PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`
1987: Level: beginner
1989: Note:
1990: See <https://en.wikipedia.org/wiki/Machine_epsilon>
1992: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1993: M*/
1995: /*MC
1996: PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`
1998: Level: beginner
2000: Note:
2001: See `PETSC_MACHINE_EPSILON`
2003: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
2004: M*/
2006: /*MC
2007: PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
2008: and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.
2010: Level: beginner
2012: Note:
2013: See `PETSC_MACHINE_EPSILON`
2015: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
2016: `PETSC_SQRT_MACHINE_EPSILON`
2017: M*/
2019: #if PetscDefined(USE_REAL_SINGLE)
2020: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL = FLT_MAX;
2021: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN = FLT_MIN;
2022: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON = FLT_EPSILON;
2023: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 3.45266977e-04F;
2024: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL = PetscRealConstant(1.e-5);
2025: #elif PetscDefined(USE_REAL_DOUBLE)
2026: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL = DBL_MAX;
2027: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN = DBL_MIN;
2028: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON = DBL_EPSILON;
2029: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 1.4901161193847656e-08;
2030: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL = PetscRealConstant(1.e-10);
2031: #elif PetscDefined(USE_REAL___FLOAT128)
2032: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL = FLT128_MAX;
2033: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN = FLT128_MIN;
2034: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON = FLT128_EPSILON;
2035: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 1.38777878078144567552953958511352539e-17Q;
2036: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL = PetscRealConstant(1.e-20);
2037: #elif PetscDefined(USE_REAL___FP16)
2038: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL = __FLT16_MAX__;
2039: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN = __FLT16_MIN__;
2040: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON = __FLT16_EPSILON__;
2041: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = PetscRealConstant(3.1250e-02);
2042: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL = PetscRealConstant(5.e-3);
2043: #endif
2044: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2045: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MIN_REAL = (-PETSC_MAX_REAL);
2046: #else
2047: #define PETSC_MIN_REAL (-PETSC_MAX_REAL)
2048: #endif
2050: /*MC
2051: PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
2053: Level: intermediate
2055: Note:
2056: This is not the IEEE infinity value
2058: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2059: M*/
2060: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2061: PETSC_STATIC_CONSTEXPR PetscReal PETSC_INFINITY = PETSC_MAX_REAL / PetscRealConstant(4.0);
2062: #else
2063: #define PETSC_INFINITY (PETSC_MAX_REAL / PetscRealConstant(4.0))
2064: #endif
2066: #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
2067: #pragma GCC diagnostic pop
2068: #endif
2070: /*MC
2071: PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
2073: Level: intermediate
2075: Note:
2076: This is not the negative IEEE infinity value
2078: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2079: M*/
2080: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2081: PETSC_STATIC_CONSTEXPR PetscReal PETSC_NINFINITY = (-PETSC_INFINITY);
2082: #else
2083: #define PETSC_NINFINITY (-PETSC_INFINITY)
2084: #endif
2086: PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal);
2087: PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal);
2088: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
2089: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
2090: {
2091: return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
2092: }
2093: static inline PetscBool PetscIsInfScalar(PetscScalar v)
2094: {
2095: return PetscIsInfReal(PetscAbsScalar(v));
2096: }
2097: static inline PetscBool PetscIsNanScalar(PetscScalar v)
2098: {
2099: return PetscIsNanReal(PetscAbsScalar(v));
2100: }
2101: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
2102: {
2103: return PetscIsInfOrNanReal(PetscAbsScalar(v));
2104: }
2105: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
2106: {
2107: return PetscIsNormalReal(PetscAbsScalar(v));
2108: }
2110: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
2111: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
2112: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
2114: /*@
2115: PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
2117: Not Collective
2119: Input Parameters:
2120: + lhs - The first number
2121: . rhs - The second number
2122: . rtol - The relative tolerance
2123: - atol - The absolute tolerance
2125: Level: beginner
2127: Note:
2128: This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
2129: numbers.
2131: .seealso: `PetscIsCloseAtTol()`
2132: @*/
2133: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
2134: {
2135: PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
2137: if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
2138: return close;
2139: }
2141: /*
2142: These macros are currently hardwired to match the regular data types, so there is no support for a different
2143: MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
2144: */
2145: #define MPIU_MATSCALAR MPIU_SCALAR
2147: /*MC
2148: MatScalar - Datatype used inside matrix implementations to store matrix entries
2150: Level: developer
2152: Note:
2153: `MatScalar` is currently a synonym for `PetscScalar`. It exists so that matrix internals can, in principle, store entries in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.
2155: .seealso: `PetscScalar`, `MatReal`, `Mat`, `PETSC_USE_COMPLEX`
2156: M*/
2157: typedef PetscScalar MatScalar;
2159: /*MC
2160: MatReal - Datatype used inside matrix implementations to store real-valued matrix data
2162: Level: developer
2164: Note:
2165: `MatReal` is currently a synonym for `PetscReal`. It exists so that matrix internals can, in principle, store data in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.
2167: .seealso: `PetscReal`, `MatScalar`, `Mat`
2168: M*/
2169: typedef PetscReal MatReal;
2171: struct petsc_mpiu_2scalar {
2172: PetscScalar a, b;
2173: };
2174: /* See comments below for clang and MPIU_2INT */
2175: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar) */;
2177: /* MPI Datatypes for composite reductions */
2178: struct petsc_mpiu_real_int {
2179: PetscReal v;
2180: PetscInt i;
2181: };
2183: struct petsc_mpiu_scalar_int {
2184: PetscScalar v;
2185: PetscInt i;
2186: };
2188: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
2189: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
2191: #if PetscDefined(USE_64BIT_INDICES)
2192: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
2193: PetscInt a;
2194: PetscInt b;
2195: };
2196: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
2197: PetscInt a;
2198: PetscMPIInt b;
2199: };
2200: /*
2201: static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
2202: static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
2203: static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
2205: clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
2206: PetscInt *, even though (with everything else uncommented) both of the static_asserts above
2207: pass! So we just comment it out...
2208: */
2209: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
2210: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
2211: #else
2212: #define MPIU_2INT MPI_2INT
2213: #define MPIU_INT_MPIINT MPI_2INT
2214: #endif
2215: PETSC_EXTERN MPI_Datatype MPI_4INT;
2216: PETSC_EXTERN MPI_Datatype MPIU_4INT;
2218: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
2219: {
2220: PetscInt result = 1;
2221: while (power) {
2222: if (power & 1) result *= base;
2223: power >>= 1;
2224: if (power) base *= base;
2225: }
2226: return result;
2227: }
2229: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
2230: {
2231: PetscInt64 result = 1;
2232: while (power) {
2233: if (power & 1) result *= base;
2234: power >>= 1;
2235: if (power) base *= base;
2236: }
2237: return result;
2238: }
2240: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
2241: {
2242: PetscReal result = 1;
2243: if (power < 0) {
2244: power = -power;
2245: base = ((PetscReal)1) / base;
2246: }
2247: while (power) {
2248: if (power & 1) result *= base;
2249: power >>= 1;
2250: if (power) base *= base;
2251: }
2252: return result;
2253: }
2255: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
2256: {
2257: PetscScalar result = (PetscReal)1;
2258: if (power < 0) {
2259: power = -power;
2260: base = ((PetscReal)1) / base;
2261: }
2262: while (power) {
2263: if (power & 1) result *= base;
2264: power >>= 1;
2265: if (power) base *= base;
2266: }
2267: return result;
2268: }
2270: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
2271: {
2272: PetscScalar cpower = power;
2273: return PetscPowScalar(base, cpower);
2274: }
2276: /*MC
2277: PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
2279: Synopsis:
2280: #include <petscmath.h>
2281: bool PetscApproximateLTE(PetscReal x, constant float)
2283: Not Collective
2285: Input Parameters:
2286: + x - the variable
2287: - b - the constant float it is checking if `x` is less than or equal to
2289: Level: advanced
2291: Notes:
2292: The fudge factor is the value `PETSC_SMALL`
2294: The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
2296: This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2297: floating point results.
2299: Example\:
2300: .vb
2301: PetscReal x;
2302: if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
2303: .ve
2305: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
2306: M*/
2307: #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
2309: /*MC
2310: PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
2312: Synopsis:
2313: #include <petscmath.h>
2314: bool PetscApproximateGTE(PetscReal x, constant float)
2316: Not Collective
2318: Input Parameters:
2319: + x - the variable
2320: - b - the constant float it is checking if `x` is greater than or equal to
2322: Level: advanced
2324: Notes:
2325: The fudge factor is the value `PETSC_SMALL`
2327: The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
2329: This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2330: floating point results.
2332: Example\:
2333: .vb
2334: PetscReal x;
2335: if (PetscApproximateGTE(x, 3.2)) { // replaces if (x >= 3.2) {
2336: .ve
2338: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2339: M*/
2340: #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
2342: /*@
2343: PetscCeilInt - Returns the ceiling of the quotation of two positive integers
2345: Not Collective
2347: Input Parameters:
2348: + x - the numerator
2349: - y - the denominator
2351: Level: advanced
2353: Example\:
2354: .vb
2355: PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
2356: .ve
2358: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2359: @*/
2360: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
2361: {
2362: return x / y + (x % y ? 1 : 0);
2363: }
2365: /*@
2366: PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers
2368: Not Collective
2370: Input Parameters:
2371: + x - the numerator
2372: - y - the denominator
2374: Level: advanced
2376: Example\:
2377: .vb
2378: PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
2379: .ve
2381: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2382: @*/
2383: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
2384: {
2385: return x / y + (x % y ? 1 : 0);
2386: }
2388: /*@
2389: PetscGCD - Returns the greatest common divisor of two integers
2391: Not Collective
2393: Input Parameters:
2394: + a - first number
2395: - b - second number
2397: Level: advanced
2399: .seealso: `PetscLCM()`
2400: @*/
2401: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
2402: {
2403: a = PetscAbsInt(a);
2404: b = PetscAbsInt(b);
2405: while (b != 0) {
2406: PetscInt tmp = b;
2408: b = a % b;
2409: a = tmp;
2410: }
2411: return a;
2412: }
2414: /*@
2415: PetscLCM - Returns the least common multiple of two integers
2417: Not Collective
2419: Input Parameters:
2420: + a - first number
2421: - b - second number
2423: Level: advanced
2425: .seealso: `PetscGCD()`
2426: @*/
2427: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
2428: {
2429: PetscInt gcd;
2431: a = PetscAbsInt(a);
2432: b = PetscAbsInt(b);
2434: gcd = PetscGCD(a, b);
2435: return gcd ? a * (b / gcd) : 0;
2436: }
2438: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);