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 <petscmacros.h>
12: #include <petscsystypes.h>
14: /* SUBMANSEC = Sys */
16: /*
17: Defines operations that are different for complex and real numbers.
18: All PETSc objects in one program are built around the object
19: PetscScalar which is either always a real or a complex.
20: */
22: /*
23: Real number definitions
24: */
25: #if defined(PETSC_USE_REAL_SINGLE)
26: /*MC
27: PetscSqrtReal - Returns the square root of a `PetscReal` value
29: Synopsis:
30: #include <petscmath.h>
31: PetscReal PetscSqrtReal(PetscReal a)
33: Not Collective; No Fortran Support
35: Input Parameter:
36: . a - the value
38: Level: beginner
40: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtComplex()`, `PetscSqrtScalar()`
41: M*/
42: #define PetscSqrtReal(a) sqrtf(a)
43: /*MC
44: PetscCbrtReal - Returns the cube root of a `PetscReal` value
46: Synopsis:
47: #include <petscmath.h>
48: PetscReal PetscCbrtReal(PetscReal a)
50: Not Collective; No Fortran Support
52: Input Parameter:
53: . a - the value
55: Level: beginner
57: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
58: M*/
59: #define PetscCbrtReal(a) cbrtf(a)
60: /*MC
61: PetscHypotReal - Returns the Euclidean distance `sqrt(a*a + b*b)` of two `PetscReal` values, without intermediate overflow
63: Synopsis:
64: #include <petscmath.h>
65: PetscReal PetscHypotReal(PetscReal a, PetscReal b)
67: Not Collective; No Fortran Support
69: Input Parameters:
70: + a - the value
71: - b - the value
73: Level: beginner
75: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
76: M*/
77: #define PetscHypotReal(a, b) hypotf(a, b)
78: /*MC
79: PetscAtan2Real - Returns the arc tangent of `a/b`, in the range $[-\pi, \pi]$, using the signs of `a` and `b` to select the quadrant
81: Synopsis:
82: #include <petscmath.h>
83: PetscReal PetscAtan2Real(PetscReal a, PetscReal b)
85: Not Collective; No Fortran Support
87: Input Parameters:
88: + a - the value
89: - b - the value
91: Level: beginner
93: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
94: M*/
95: #define PetscAtan2Real(a, b) atan2f(a, b)
96: /*MC
97: PetscPowReal - Returns the value of `a` raised to the power `b`, both `PetscReal`
99: Synopsis:
100: #include <petscmath.h>
101: PetscReal PetscPowReal(PetscReal a, PetscReal b)
103: Not Collective; No Fortran Support
105: Input Parameters:
106: + a - the value
107: - b - the value
109: Level: beginner
111: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowComplex()`, `PetscPowScalar()`
112: M*/
113: #define PetscPowReal(a, b) powf(a, b)
114: /*MC
115: PetscExpReal - Returns the natural exponential $e^a$ of a `PetscReal` value
117: Synopsis:
118: #include <petscmath.h>
119: PetscReal PetscExpReal(PetscReal a)
121: Not Collective; No Fortran Support
123: Input Parameter:
124: . a - the value
126: Level: beginner
128: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpComplex()`, `PetscExpScalar()`
129: M*/
130: #define PetscExpReal(a) expf(a)
131: /*MC
132: PetscLogReal - Returns the natural logarithm of a `PetscReal` value
134: Synopsis:
135: #include <petscmath.h>
136: PetscReal PetscLogReal(PetscReal a)
138: Not Collective; No Fortran Support
140: Input Parameter:
141: . a - the value
143: Level: beginner
145: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogComplex()`, `PetscLogScalar()`
146: M*/
147: #define PetscLogReal(a) logf(a)
148: /*MC
149: PetscLog10Real - Returns the base-10 logarithm of a `PetscReal` value
151: Synopsis:
152: #include <petscmath.h>
153: PetscReal PetscLog10Real(PetscReal a)
155: Not Collective; No Fortran Support
157: Input Parameter:
158: . a - the value
160: Level: beginner
162: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
163: M*/
164: #define PetscLog10Real(a) log10f(a)
165: /*MC
166: PetscLog2Real - Returns the base-2 logarithm of a `PetscReal` value
168: Synopsis:
169: #include <petscmath.h>
170: PetscReal PetscLog2Real(PetscReal a)
172: Not Collective; No Fortran Support
174: Input Parameter:
175: . a - the value
177: Level: beginner
179: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
180: M*/
181: #define PetscLog2Real(a) log2f(a)
182: /*MC
183: PetscSinReal - Returns the sine of a `PetscReal` value, with argument in radians
185: Synopsis:
186: #include <petscmath.h>
187: PetscReal PetscSinReal(PetscReal a)
189: Not Collective; No Fortran Support
191: Input Parameter:
192: . a - the value
194: Level: beginner
196: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinComplex()`, `PetscSinScalar()`
197: M*/
198: #define PetscSinReal(a) sinf(a)
199: /*MC
200: PetscCosReal - Returns the cosine of a `PetscReal` value, with argument in radians
202: Synopsis:
203: #include <petscmath.h>
204: PetscReal PetscCosReal(PetscReal a)
206: Not Collective; No Fortran Support
208: Input Parameter:
209: . a - the value
211: Level: beginner
213: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosComplex()`, `PetscCosScalar()`
214: M*/
215: #define PetscCosReal(a) cosf(a)
216: /*MC
217: PetscTanReal - Returns the tangent of a `PetscReal` value, with argument in radians
219: Synopsis:
220: #include <petscmath.h>
221: PetscReal PetscTanReal(PetscReal a)
223: Not Collective; No Fortran Support
225: Input Parameter:
226: . a - the value
228: Level: beginner
230: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanComplex()`, `PetscTanScalar()`
231: M*/
232: #define PetscTanReal(a) tanf(a)
233: /*MC
234: PetscAsinReal - Returns the arc sine of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$
236: Synopsis:
237: #include <petscmath.h>
238: PetscReal PetscAsinReal(PetscReal a)
240: Not Collective; No Fortran Support
242: Input Parameter:
243: . a - the value
245: Level: beginner
247: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinComplex()`, `PetscAsinScalar()`
248: M*/
249: #define PetscAsinReal(a) asinf(a)
250: /*MC
251: PetscAcosReal - Returns the arc cosine of a `PetscReal` value, returned in radians in the range $[0, \pi]$
253: Synopsis:
254: #include <petscmath.h>
255: PetscReal PetscAcosReal(PetscReal a)
257: Not Collective; No Fortran Support
259: Input Parameter:
260: . a - the value
262: Level: beginner
264: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosComplex()`, `PetscAcosScalar()`
265: M*/
266: #define PetscAcosReal(a) acosf(a)
267: /*MC
268: PetscAtanReal - Returns the arc tangent of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$
270: Synopsis:
271: #include <petscmath.h>
272: PetscReal PetscAtanReal(PetscReal a)
274: Not Collective; No Fortran Support
276: Input Parameter:
277: . a - the value
279: Level: beginner
281: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanComplex()`, `PetscAtanScalar()`
282: M*/
283: #define PetscAtanReal(a) atanf(a)
284: /*MC
285: PetscSinhReal - Returns the hyperbolic sine of a `PetscReal` value
287: Synopsis:
288: #include <petscmath.h>
289: PetscReal PetscSinhReal(PetscReal a)
291: Not Collective; No Fortran Support
293: Input Parameter:
294: . a - the value
296: Level: beginner
298: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhComplex()`, `PetscSinhScalar()`
299: M*/
300: #define PetscSinhReal(a) sinhf(a)
301: /*MC
302: PetscCoshReal - Returns the hyperbolic cosine of a `PetscReal` value
304: Synopsis:
305: #include <petscmath.h>
306: PetscReal PetscCoshReal(PetscReal a)
308: Not Collective; No Fortran Support
310: Input Parameter:
311: . a - the value
313: Level: beginner
315: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshComplex()`, `PetscCoshScalar()`
316: M*/
317: #define PetscCoshReal(a) coshf(a)
318: /*MC
319: PetscTanhReal - Returns the hyperbolic tangent of a `PetscReal` value
321: Synopsis:
322: #include <petscmath.h>
323: PetscReal PetscTanhReal(PetscReal a)
325: Not Collective; No Fortran Support
327: Input Parameter:
328: . a - the value
330: Level: beginner
332: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhComplex()`, `PetscTanhScalar()`
333: M*/
334: #define PetscTanhReal(a) tanhf(a)
335: /*MC
336: PetscAsinhReal - Returns the inverse hyperbolic sine of a `PetscReal` value
338: Synopsis:
339: #include <petscmath.h>
340: PetscReal PetscAsinhReal(PetscReal a)
342: Not Collective; No Fortran Support
344: Input Parameter:
345: . a - the value
347: Level: beginner
349: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhComplex()`, `PetscAsinhScalar()`
350: M*/
351: #define PetscAsinhReal(a) asinhf(a)
352: /*MC
353: PetscAcoshReal - Returns the inverse hyperbolic cosine of a `PetscReal` value
355: Synopsis:
356: #include <petscmath.h>
357: PetscReal PetscAcoshReal(PetscReal a)
359: Not Collective; No Fortran Support
361: Input Parameter:
362: . a - the value
364: Level: beginner
366: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshComplex()`, `PetscAcoshScalar()`
367: M*/
368: #define PetscAcoshReal(a) acoshf(a)
369: /*MC
370: PetscAtanhReal - Returns the inverse hyperbolic tangent of a `PetscReal` value
372: Synopsis:
373: #include <petscmath.h>
374: PetscReal PetscAtanhReal(PetscReal a)
376: Not Collective; No Fortran Support
378: Input Parameter:
379: . a - the value
381: Level: beginner
383: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhComplex()`, `PetscAtanhScalar()`
384: M*/
385: #define PetscAtanhReal(a) atanhf(a)
386: /*MC
387: PetscErfReal - Returns the error function of a `PetscReal` value
389: Synopsis:
390: #include <petscmath.h>
391: PetscReal PetscErfReal(PetscReal a)
393: Not Collective; No Fortran Support
395: Input Parameter:
396: . a - the value
398: Level: beginner
400: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
401: M*/
402: #define PetscErfReal(a) erff(a)
403: /*MC
404: PetscCeilReal - Returns the smallest integer value, returned as a `PetscReal`, that is not less than `a`
406: Synopsis:
407: #include <petscmath.h>
408: PetscReal PetscCeilReal(PetscReal a)
410: Not Collective; No Fortran Support
412: Input Parameter:
413: . a - the value
415: Level: beginner
417: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
418: M*/
419: #define PetscCeilReal(a) ceilf(a)
420: /*MC
421: PetscFloorReal - Returns the largest integer value, returned as a `PetscReal`, that is not greater than `a`
423: Synopsis:
424: #include <petscmath.h>
425: PetscReal PetscFloorReal(PetscReal a)
427: Not Collective; No Fortran Support
429: Input Parameter:
430: . a - the value
432: Level: beginner
434: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
435: M*/
436: #define PetscFloorReal(a) floorf(a)
437: /*MC
438: PetscRintReal - Returns the value of `a` rounded to the nearest integer, returned as a `PetscReal` in the configured precision
440: Synopsis:
441: #include <petscmath.h>
442: PetscReal PetscRintReal(PetscReal a)
444: Not Collective; No Fortran Support
446: Input Parameter:
447: . a - the value
449: Level: beginner
451: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
452: M*/
453: #define PetscRintReal(a) rintf(a)
454: /*MC
455: PetscFmodReal - Returns the floating-point remainder of `a/b`, with the same sign as `a`, returned as a `PetscReal`
457: Synopsis:
458: #include <petscmath.h>
459: PetscReal PetscFmodReal(PetscReal a, PetscReal b)
461: Not Collective; No Fortran Support
463: Input Parameters:
464: + a - the value
465: - b - the value
467: Level: beginner
469: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
470: M*/
471: #define PetscFmodReal(a, b) fmodf(a, b)
472: /*MC
473: PetscCopysignReal - Returns the value with the magnitude of `a` and the sign of `b`, as a `PetscReal`
475: Synopsis:
476: #include <petscmath.h>
477: PetscReal PetscCopysignReal(PetscReal a, PetscReal b)
479: Not Collective; No Fortran Support
481: Input Parameters:
482: + a - the value
483: - b - the value
485: Level: beginner
487: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
488: M*/
489: #define PetscCopysignReal(a, b) copysignf(a, b)
490: /*MC
491: PetscTGamma - Returns the value of the gamma function $\Gamma(a)$ in the configured `PetscReal` precision
493: Synopsis:
494: #include <petscmath.h>
495: PetscReal PetscTGamma(PetscReal a)
497: Not Collective; No Fortran Support
499: Input Parameter:
500: . a - the value
502: Level: beginner
504: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
505: M*/
506: #define PetscTGamma(a) tgammaf(a)
507: #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
508: /*MC
509: PetscLGamma - Returns the natural logarithm of the absolute value of the gamma function in the configured `PetscReal` precision
511: Synopsis:
512: #include <petscmath.h>
513: PetscReal PetscLGamma(PetscReal a)
515: Not Collective; No Fortran Support
517: Input Parameter:
518: . a - the value
520: Level: beginner
522: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
523: M*/
524: #define PetscLGamma(a) gammaf(a)
525: #else
526: #define PetscLGamma(a) lgammaf(a)
527: #endif
529: #elif defined(PETSC_USE_REAL_DOUBLE)
530: #define PetscSqrtReal(a) sqrt(a)
531: #define PetscCbrtReal(a) cbrt(a)
532: #define PetscHypotReal(a, b) hypot(a, b)
533: #define PetscAtan2Real(a, b) atan2(a, b)
534: #define PetscPowReal(a, b) pow(a, b)
535: #define PetscExpReal(a) exp(a)
536: #define PetscLogReal(a) log(a)
537: #define PetscLog10Real(a) log10(a)
538: #define PetscLog2Real(a) log2(a)
539: #define PetscSinReal(a) sin(a)
540: #define PetscCosReal(a) cos(a)
541: #define PetscTanReal(a) tan(a)
542: #define PetscAsinReal(a) asin(a)
543: #define PetscAcosReal(a) acos(a)
544: #define PetscAtanReal(a) atan(a)
545: #define PetscSinhReal(a) sinh(a)
546: #define PetscCoshReal(a) cosh(a)
547: #define PetscTanhReal(a) tanh(a)
548: #define PetscAsinhReal(a) asinh(a)
549: #define PetscAcoshReal(a) acosh(a)
550: #define PetscAtanhReal(a) atanh(a)
551: #define PetscErfReal(a) erf(a)
552: #define PetscCeilReal(a) ceil(a)
553: #define PetscFloorReal(a) floor(a)
554: #define PetscRintReal(a) rint(a)
555: #define PetscFmodReal(a, b) fmod(a, b)
556: #define PetscCopysignReal(a, b) copysign(a, b)
557: #define PetscTGamma(a) tgamma(a)
558: #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
559: #define PetscLGamma(a) gamma(a)
560: #else
561: #define PetscLGamma(a) lgamma(a)
562: #endif
564: #elif defined(PETSC_USE_REAL___FLOAT128)
565: #define PetscSqrtReal(a) sqrtq(a)
566: #define PetscCbrtReal(a) cbrtq(a)
567: #define PetscHypotReal(a, b) hypotq(a, b)
568: #define PetscAtan2Real(a, b) atan2q(a, b)
569: #define PetscPowReal(a, b) powq(a, b)
570: #define PetscExpReal(a) expq(a)
571: #define PetscLogReal(a) logq(a)
572: #define PetscLog10Real(a) log10q(a)
573: #define PetscLog2Real(a) log2q(a)
574: #define PetscSinReal(a) sinq(a)
575: #define PetscCosReal(a) cosq(a)
576: #define PetscTanReal(a) tanq(a)
577: #define PetscAsinReal(a) asinq(a)
578: #define PetscAcosReal(a) acosq(a)
579: #define PetscAtanReal(a) atanq(a)
580: #define PetscSinhReal(a) sinhq(a)
581: #define PetscCoshReal(a) coshq(a)
582: #define PetscTanhReal(a) tanhq(a)
583: #define PetscAsinhReal(a) asinhq(a)
584: #define PetscAcoshReal(a) acoshq(a)
585: #define PetscAtanhReal(a) atanhq(a)
586: #define PetscErfReal(a) erfq(a)
587: #define PetscCeilReal(a) ceilq(a)
588: #define PetscFloorReal(a) floorq(a)
589: #define PetscRintReal(a) rintq(a)
590: #define PetscFmodReal(a, b) fmodq(a, b)
591: #define PetscCopysignReal(a, b) copysignq(a, b)
592: #define PetscTGamma(a) tgammaq(a)
593: #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
594: #define PetscLGamma(a) gammaq(a)
595: #else
596: #define PetscLGamma(a) lgammaq(a)
597: #endif
599: #elif defined(PETSC_USE_REAL___FP16)
600: #define PetscSqrtReal(a) sqrtf(a)
601: #define PetscCbrtReal(a) cbrtf(a)
602: #define PetscHypotReal(a, b) hypotf(a, b)
603: #define PetscAtan2Real(a, b) atan2f(a, b)
604: #define PetscPowReal(a, b) powf(a, b)
605: #define PetscExpReal(a) expf(a)
606: #define PetscLogReal(a) logf(a)
607: #define PetscLog10Real(a) log10f(a)
608: #define PetscLog2Real(a) log2f(a)
609: #define PetscSinReal(a) sinf(a)
610: #define PetscCosReal(a) cosf(a)
611: #define PetscTanReal(a) tanf(a)
612: #define PetscAsinReal(a) asinf(a)
613: #define PetscAcosReal(a) acosf(a)
614: #define PetscAtanReal(a) atanf(a)
615: #define PetscSinhReal(a) sinhf(a)
616: #define PetscCoshReal(a) coshf(a)
617: #define PetscTanhReal(a) tanhf(a)
618: #define PetscAsinhReal(a) asinhf(a)
619: #define PetscAcoshReal(a) acoshf(a)
620: #define PetscAtanhReal(a) atanhf(a)
621: #define PetscErfReal(a) erff(a)
622: #define PetscCeilReal(a) ceilf(a)
623: #define PetscFloorReal(a) floorf(a)
624: #define PetscRintReal(a) rintf(a)
625: #define PetscFmodReal(a, b) fmodf(a, b)
626: #define PetscCopysignReal(a, b) copysignf(a, b)
627: #define PetscTGamma(a) tgammaf(a)
628: #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
629: #define PetscLGamma(a) gammaf(a)
630: #else
631: #define PetscLGamma(a) lgammaf(a)
632: #endif
634: #endif /* PETSC_USE_REAL_* */
636: static inline PetscReal PetscSignReal(PetscReal a)
637: {
638: return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
639: }
641: #if !defined(PETSC_HAVE_LOG2)
642: #undef PetscLog2Real
643: static inline PetscReal PetscLog2Real(PetscReal a)
644: {
645: return PetscLogReal(a) / PetscLogReal((PetscReal)2);
646: }
647: #endif
649: #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
650: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
651: #endif
652: #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
653: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
654: #endif
656: /*MC
657: MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in
659: Level: beginner
661: Note:
662: In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.
664: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
665: M*/
666: #if defined(PETSC_USE_REAL_SINGLE)
667: #define MPIU_REAL MPI_FLOAT
668: #elif defined(PETSC_USE_REAL_DOUBLE)
669: #define MPIU_REAL MPI_DOUBLE
670: #elif defined(PETSC_USE_REAL___FLOAT128)
671: #define MPIU_REAL MPIU___FLOAT128
672: #elif defined(PETSC_USE_REAL___FP16)
673: #define MPIU_REAL MPIU___FP16
674: #endif /* PETSC_USE_REAL_* */
676: /*
677: Complex number definitions
678: */
679: #if defined(PETSC_HAVE_COMPLEX)
680: #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
681: /* C++ support of complex number */
683: /*MC
684: PetscRealPartComplex - Returns the real part of a `PetscComplex` value, as a `PetscReal`
686: Synopsis:
687: #include <petscmath.h>
688: PetscReal PetscRealPartComplex(PetscComplex a)
690: Not Collective; No Fortran Support
692: Input Parameter:
693: . a - the value
695: Level: beginner
697: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
698: M*/
699: #define PetscRealPartComplex(a) (static_cast<PetscComplex>(a)).real()
700: /*MC
701: PetscImaginaryPartComplex - Returns the imaginary part of a `PetscComplex` value, as a `PetscReal`
703: Synopsis:
704: #include <petscmath.h>
705: PetscReal PetscImaginaryPartComplex(PetscComplex a)
707: Not Collective; No Fortran Support
709: Input Parameter:
710: . a - the value
712: Level: beginner
714: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
715: M*/
716: #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
717: /*MC
718: PetscAbsComplex - Returns the absolute value (magnitude) of a `PetscComplex` value, as a `PetscReal`
720: Synopsis:
721: #include <petscmath.h>
722: PetscReal PetscAbsComplex(PetscComplex a)
724: Not Collective; No Fortran Support
726: Input Parameter:
727: . a - the value
729: Level: beginner
731: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
732: M*/
733: #define PetscAbsComplex(a) petsccomplexlib::abs(static_cast<PetscComplex>(a))
734: /*MC
735: PetscArgComplex - Returns the argument (phase angle) of a `PetscComplex` value, as a `PetscReal`
737: Synopsis:
738: #include <petscmath.h>
739: PetscReal PetscArgComplex(PetscComplex a)
741: Not Collective; No Fortran Support
743: Input Parameter:
744: . a - the value
746: Level: beginner
748: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
749: M*/
750: #define PetscArgComplex(a) petsccomplexlib::arg(static_cast<PetscComplex>(a))
751: /*MC
752: PetscConjComplex - Returns the complex conjugate of a `PetscComplex` value
754: Synopsis:
755: #include <petscmath.h>
756: PetscComplex PetscConjComplex(PetscComplex a)
758: Not Collective; No Fortran Support
760: Input Parameter:
761: . a - the value
763: Level: beginner
765: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConj()`
766: M*/
767: #define PetscConjComplex(a) petsccomplexlib::conj(static_cast<PetscComplex>(a))
768: /*MC
769: PetscSqrtComplex - Returns the principal value of the square root of a `PetscComplex` value
771: Synopsis:
772: #include <petscmath.h>
773: PetscComplex PetscSqrtComplex(PetscComplex a)
775: Not Collective; No Fortran Support
777: Input Parameter:
778: . a - the value
780: Level: beginner
782: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtScalar()`
783: M*/
784: #define PetscSqrtComplex(a) petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
785: /*MC
786: PetscPowComplex - Returns the complex value `a` raised to the complex power `b`
788: Synopsis:
789: #include <petscmath.h>
790: PetscComplex PetscPowComplex(PetscComplex a, PetscComplex b)
792: Not Collective; No Fortran Support
794: Input Parameters:
795: + a - the value
796: - b - the value
798: Level: beginner
800: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowScalar()`
801: M*/
802: #define PetscPowComplex(a, b) petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
803: /*MC
804: PetscExpComplex - Returns the complex exponential $e^a$ of a `PetscComplex` value
806: Synopsis:
807: #include <petscmath.h>
808: PetscComplex PetscExpComplex(PetscComplex a)
810: Not Collective; No Fortran Support
812: Input Parameter:
813: . a - the value
815: Level: beginner
817: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpScalar()`
818: M*/
819: #define PetscExpComplex(a) petsccomplexlib::exp(static_cast<PetscComplex>(a))
820: /*MC
821: PetscLogComplex - Returns the principal value of the complex natural logarithm of a `PetscComplex` value
823: Synopsis:
824: #include <petscmath.h>
825: PetscComplex PetscLogComplex(PetscComplex a)
827: Not Collective; No Fortran Support
829: Input Parameter:
830: . a - the value
832: Level: beginner
834: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogScalar()`
835: M*/
836: #define PetscLogComplex(a) petsccomplexlib::log(static_cast<PetscComplex>(a))
837: /*MC
838: PetscSinComplex - Returns the complex sine of a `PetscComplex` value
840: Synopsis:
841: #include <petscmath.h>
842: PetscComplex PetscSinComplex(PetscComplex a)
844: Not Collective; No Fortran Support
846: Input Parameter:
847: . a - the value
849: Level: beginner
851: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinScalar()`
852: M*/
853: #define PetscSinComplex(a) petsccomplexlib::sin(static_cast<PetscComplex>(a))
854: /*MC
855: PetscCosComplex - Returns the complex cosine of a `PetscComplex` value
857: Synopsis:
858: #include <petscmath.h>
859: PetscComplex PetscCosComplex(PetscComplex a)
861: Not Collective; No Fortran Support
863: Input Parameter:
864: . a - the value
866: Level: beginner
868: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosScalar()`
869: M*/
870: #define PetscCosComplex(a) petsccomplexlib::cos(static_cast<PetscComplex>(a))
871: /*MC
872: PetscTanComplex - Returns the complex tangent of a `PetscComplex` value
874: Synopsis:
875: #include <petscmath.h>
876: PetscComplex PetscTanComplex(PetscComplex a)
878: Not Collective; No Fortran Support
880: Input Parameter:
881: . a - the value
883: Level: beginner
885: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanScalar()`
886: M*/
887: #define PetscTanComplex(a) petsccomplexlib::tan(static_cast<PetscComplex>(a))
888: /*MC
889: PetscAsinComplex - Returns the complex arc sine of a `PetscComplex` value
891: Synopsis:
892: #include <petscmath.h>
893: PetscComplex PetscAsinComplex(PetscComplex a)
895: Not Collective; No Fortran Support
897: Input Parameter:
898: . a - the value
900: Level: beginner
902: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinScalar()`
903: M*/
904: #define PetscAsinComplex(a) petsccomplexlib::asin(static_cast<PetscComplex>(a))
905: /*MC
906: PetscAcosComplex - Returns the complex arc cosine of a `PetscComplex` value
908: Synopsis:
909: #include <petscmath.h>
910: PetscComplex PetscAcosComplex(PetscComplex a)
912: Not Collective; No Fortran Support
914: Input Parameter:
915: . a - the value
917: Level: beginner
919: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosScalar()`
920: M*/
921: #define PetscAcosComplex(a) petsccomplexlib::acos(static_cast<PetscComplex>(a))
922: /*MC
923: PetscAtanComplex - Returns the complex arc tangent of a `PetscComplex` value
925: Synopsis:
926: #include <petscmath.h>
927: PetscComplex PetscAtanComplex(PetscComplex a)
929: Not Collective; No Fortran Support
931: Input Parameter:
932: . a - the value
934: Level: beginner
936: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanScalar()`
937: M*/
938: #define PetscAtanComplex(a) petsccomplexlib::atan(static_cast<PetscComplex>(a))
939: /*MC
940: PetscSinhComplex - Returns the complex hyperbolic sine of a `PetscComplex` value
942: Synopsis:
943: #include <petscmath.h>
944: PetscComplex PetscSinhComplex(PetscComplex a)
946: Not Collective; No Fortran Support
948: Input Parameter:
949: . a - the value
951: Level: beginner
953: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhScalar()`
954: M*/
955: #define PetscSinhComplex(a) petsccomplexlib::sinh(static_cast<PetscComplex>(a))
956: /*MC
957: PetscCoshComplex - Returns the complex hyperbolic cosine of a `PetscComplex` value
959: Synopsis:
960: #include <petscmath.h>
961: PetscComplex PetscCoshComplex(PetscComplex a)
963: Not Collective; No Fortran Support
965: Input Parameter:
966: . a - the value
968: Level: beginner
970: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshScalar()`
971: M*/
972: #define PetscCoshComplex(a) petsccomplexlib::cosh(static_cast<PetscComplex>(a))
973: /*MC
974: PetscTanhComplex - Returns the complex hyperbolic tangent of a `PetscComplex` value
976: Synopsis:
977: #include <petscmath.h>
978: PetscComplex PetscTanhComplex(PetscComplex a)
980: Not Collective; No Fortran Support
982: Input Parameter:
983: . a - the value
985: Level: beginner
987: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhScalar()`
988: M*/
989: #define PetscTanhComplex(a) petsccomplexlib::tanh(static_cast<PetscComplex>(a))
990: /*MC
991: PetscAsinhComplex - Returns the complex inverse hyperbolic sine of a `PetscComplex` value
993: Synopsis:
994: #include <petscmath.h>
995: PetscComplex PetscAsinhComplex(PetscComplex a)
997: Not Collective; No Fortran Support
999: Input Parameter:
1000: . a - the value
1002: Level: beginner
1004: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhScalar()`
1005: M*/
1006: #define PetscAsinhComplex(a) petsccomplexlib::asinh(static_cast<PetscComplex>(a))
1007: /*MC
1008: PetscAcoshComplex - Returns the complex inverse hyperbolic cosine of a `PetscComplex` value
1010: Synopsis:
1011: #include <petscmath.h>
1012: PetscComplex PetscAcoshComplex(PetscComplex a)
1014: Not Collective; No Fortran Support
1016: Input Parameter:
1017: . a - the value
1019: Level: beginner
1021: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshScalar()`
1022: M*/
1023: #define PetscAcoshComplex(a) petsccomplexlib::acosh(static_cast<PetscComplex>(a))
1024: /*MC
1025: PetscAtanhComplex - Returns the complex inverse hyperbolic tangent of a `PetscComplex` value
1027: Synopsis:
1028: #include <petscmath.h>
1029: PetscComplex PetscAtanhComplex(PetscComplex a)
1031: Not Collective; No Fortran Support
1033: Input Parameter:
1034: . a - the value
1036: Level: beginner
1038: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhScalar()`
1039: M*/
1040: #define PetscAtanhComplex(a) petsccomplexlib::atanh(static_cast<PetscComplex>(a))
1042: /* TODO: Add configure tests
1044: #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
1045: #undef PetscTanComplex
1046: static inline PetscComplex PetscTanComplex(PetscComplex z)
1047: {
1048: return PetscSinComplex(z)/PetscCosComplex(z);
1049: }
1050: #endif
1052: #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
1053: #undef PetscTanhComplex
1054: static inline PetscComplex PetscTanhComplex(PetscComplex z)
1055: {
1056: return PetscSinhComplex(z)/PetscCoshComplex(z);
1057: }
1058: #endif
1060: #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
1061: #undef PetscAsinComplex
1062: static inline PetscComplex PetscAsinComplex(PetscComplex z)
1063: {
1064: const PetscComplex j(0,1);
1065: return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
1066: }
1067: #endif
1069: #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
1070: #undef PetscAcosComplex
1071: static inline PetscComplex PetscAcosComplex(PetscComplex z)
1072: {
1073: const PetscComplex j(0,1);
1074: return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
1075: }
1076: #endif
1078: #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
1079: #undef PetscAtanComplex
1080: static inline PetscComplex PetscAtanComplex(PetscComplex z)
1081: {
1082: const PetscComplex j(0,1);
1083: return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
1084: }
1085: #endif
1087: #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
1088: #undef PetscAsinhComplex
1089: static inline PetscComplex PetscAsinhComplex(PetscComplex z)
1090: {
1091: return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
1092: }
1093: #endif
1095: #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
1096: #undef PetscAcoshComplex
1097: static inline PetscComplex PetscAcoshComplex(PetscComplex z)
1098: {
1099: return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
1100: }
1101: #endif
1103: #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
1104: #undef PetscAtanhComplex
1105: static inline PetscComplex PetscAtanhComplex(PetscComplex z)
1106: {
1107: return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
1108: }
1109: #endif
1111: */
1113: #else /* C99 support of complex number */
1115: #if defined(PETSC_USE_REAL_SINGLE)
1116: #define PetscRealPartComplex(a) crealf(a)
1117: #define PetscImaginaryPartComplex(a) cimagf(a)
1118: #define PetscAbsComplex(a) cabsf(a)
1119: #define PetscArgComplex(a) cargf(a)
1120: #define PetscConjComplex(a) conjf(a)
1121: #define PetscSqrtComplex(a) csqrtf(a)
1122: #define PetscPowComplex(a, b) cpowf(a, b)
1123: #define PetscExpComplex(a) cexpf(a)
1124: #define PetscLogComplex(a) clogf(a)
1125: #define PetscSinComplex(a) csinf(a)
1126: #define PetscCosComplex(a) ccosf(a)
1127: #define PetscTanComplex(a) ctanf(a)
1128: #define PetscAsinComplex(a) casinf(a)
1129: #define PetscAcosComplex(a) cacosf(a)
1130: #define PetscAtanComplex(a) catanf(a)
1131: #define PetscSinhComplex(a) csinhf(a)
1132: #define PetscCoshComplex(a) ccoshf(a)
1133: #define PetscTanhComplex(a) ctanhf(a)
1134: #define PetscAsinhComplex(a) casinhf(a)
1135: #define PetscAcoshComplex(a) cacoshf(a)
1136: #define PetscAtanhComplex(a) catanhf(a)
1138: #elif defined(PETSC_USE_REAL_DOUBLE)
1139: #define PetscRealPartComplex(a) creal(a)
1140: #define PetscImaginaryPartComplex(a) cimag(a)
1141: #define PetscAbsComplex(a) cabs(a)
1142: #define PetscArgComplex(a) carg(a)
1143: #define PetscConjComplex(a) conj(a)
1144: #define PetscSqrtComplex(a) csqrt(a)
1145: #define PetscPowComplex(a, b) cpow(a, b)
1146: #define PetscExpComplex(a) cexp(a)
1147: #define PetscLogComplex(a) clog(a)
1148: #define PetscSinComplex(a) csin(a)
1149: #define PetscCosComplex(a) ccos(a)
1150: #define PetscTanComplex(a) ctan(a)
1151: #define PetscAsinComplex(a) casin(a)
1152: #define PetscAcosComplex(a) cacos(a)
1153: #define PetscAtanComplex(a) catan(a)
1154: #define PetscSinhComplex(a) csinh(a)
1155: #define PetscCoshComplex(a) ccosh(a)
1156: #define PetscTanhComplex(a) ctanh(a)
1157: #define PetscAsinhComplex(a) casinh(a)
1158: #define PetscAcoshComplex(a) cacosh(a)
1159: #define PetscAtanhComplex(a) catanh(a)
1161: #elif defined(PETSC_USE_REAL___FLOAT128)
1162: #define PetscRealPartComplex(a) crealq(a)
1163: #define PetscImaginaryPartComplex(a) cimagq(a)
1164: #define PetscAbsComplex(a) cabsq(a)
1165: #define PetscArgComplex(a) cargq(a)
1166: #define PetscConjComplex(a) conjq(a)
1167: #define PetscSqrtComplex(a) csqrtq(a)
1168: #define PetscPowComplex(a, b) cpowq(a, b)
1169: #define PetscExpComplex(a) cexpq(a)
1170: #define PetscLogComplex(a) clogq(a)
1171: #define PetscSinComplex(a) csinq(a)
1172: #define PetscCosComplex(a) ccosq(a)
1173: #define PetscTanComplex(a) ctanq(a)
1174: #define PetscAsinComplex(a) casinq(a)
1175: #define PetscAcosComplex(a) cacosq(a)
1176: #define PetscAtanComplex(a) catanq(a)
1177: #define PetscSinhComplex(a) csinhq(a)
1178: #define PetscCoshComplex(a) ccoshq(a)
1179: #define PetscTanhComplex(a) ctanhq(a)
1180: #define PetscAsinhComplex(a) casinhq(a)
1181: #define PetscAcoshComplex(a) cacoshq(a)
1182: #define PetscAtanhComplex(a) catanhq(a)
1184: #endif /* PETSC_USE_REAL_* */
1185: #endif /* (__cplusplus) */
1187: /*MC
1188: PETSC_i - the pure imaginary complex number i
1190: Level: intermediate
1192: .seealso: `PetscComplex`, `PetscScalar`
1193: M*/
1194: PETSC_EXTERN PetscComplex PETSC_i;
1196: /*
1197: Try to do the right thing for complex number construction: see
1198: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
1199: for details
1200: */
1201: static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
1202: {
1203: #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
1204: return PetscComplex(x, y);
1205: #elif defined(_Imaginary_I)
1206: return x + y * _Imaginary_I;
1207: #else
1208: { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),
1210: "For each floating type there is a corresponding real type, which is always a real floating
1211: type. For real floating types, it is the same type. For complex types, it is the type given
1212: by deleting the keyword _Complex from the type name."
1214: So type punning should be portable. */
1215: union
1216: {
1217: PetscComplex z;
1218: PetscReal f[2];
1219: } uz;
1221: uz.f[0] = x;
1222: uz.f[1] = y;
1223: return uz.z;
1224: }
1225: #endif
1226: }
1228: #define MPIU_C_COMPLEX MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
1229: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )
1231: #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
1232: // if complex is not used, then quadmath.h won't be included by petscsystypes.h
1233: #if defined(PETSC_USE_COMPLEX)
1234: #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
1235: #else
1236: #define MPIU___COMPLEX128_ATTR_TAG
1237: #endif
1239: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;
1241: #undef MPIU___COMPLEX128_ATTR_TAG
1242: #endif /* PETSC_HAVE_REAL___FLOAT128 */
1244: /*MC
1245: MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`
1247: Level: beginner
1249: Note:
1250: In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.
1252: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
1253: M*/
1254: #if defined(PETSC_USE_REAL_SINGLE)
1255: #define MPIU_COMPLEX MPI_C_COMPLEX
1256: #elif defined(PETSC_USE_REAL_DOUBLE)
1257: #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
1258: #elif defined(PETSC_USE_REAL___FLOAT128)
1259: #define MPIU_COMPLEX MPIU___COMPLEX128
1260: #elif defined(PETSC_USE_REAL___FP16)
1261: #define MPIU_COMPLEX MPI_C_COMPLEX
1262: #endif /* PETSC_USE_REAL_* */
1264: #endif /* PETSC_HAVE_COMPLEX */
1266: /*
1267: Scalar number definitions
1268: */
1269: #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
1270: /*MC
1271: MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`
1273: Level: beginner
1275: Note:
1276: In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.
1278: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
1279: M*/
1280: #define MPIU_SCALAR MPIU_COMPLEX
1282: /*MC
1283: PetscRealPart - Returns the real part of a `PetscScalar`
1285: Synopsis:
1286: #include <petscmath.h>
1287: PetscReal PetscRealPart(PetscScalar v)
1289: Not Collective
1291: Input Parameter:
1292: . v - value to find the real part of
1294: Level: beginner
1296: .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1297: M*/
1298: #define PetscRealPart(a) PetscRealPartComplex(a)
1300: /*MC
1301: PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`
1303: Synopsis:
1304: #include <petscmath.h>
1305: PetscReal PetscImaginaryPart(PetscScalar v)
1307: Not Collective
1309: Input Parameter:
1310: . v - value to find the imaginary part of
1312: Level: beginner
1314: Note:
1315: If PETSc was configured for real numbers then this always returns the value 0
1317: .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1318: M*/
1319: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
1321: /*MC
1322: PetscAbsScalar - Returns the absolute value (magnitude) of a `PetscScalar` value, as a `PetscReal`
1324: Synopsis:
1325: #include <petscmath.h>
1326: PetscReal PetscAbsScalar(PetscScalar a)
1328: Not Collective; No Fortran Support
1330: Input Parameter:
1331: . a - the value
1333: Level: beginner
1335: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1336: M*/
1337: #define PetscAbsScalar(a) PetscAbsComplex(a)
1338: /*MC
1339: 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
1341: Synopsis:
1342: #include <petscmath.h>
1343: PetscReal PetscArgScalar(PetscScalar a)
1345: Not Collective; No Fortran Support
1347: Input Parameter:
1348: . a - the value
1350: Level: beginner
1352: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1353: M*/
1354: #define PetscArgScalar(a) PetscArgComplex(a)
1355: /*MC
1356: PetscConj - Returns the complex conjugate of a `PetscScalar` value; the identity when `PetscScalar` is real
1358: Synopsis:
1359: #include <petscmath.h>
1360: PetscScalar PetscConj(PetscScalar a)
1362: Not Collective; No Fortran Support
1364: Input Parameter:
1365: . a - the value
1367: Level: beginner
1369: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConjComplex()`
1370: M*/
1371: #define PetscConj(a) PetscConjComplex(a)
1372: /*MC
1373: PetscSqrtScalar - Returns the square root of a `PetscScalar` value
1375: Synopsis:
1376: #include <petscmath.h>
1377: PetscScalar PetscSqrtScalar(PetscScalar a)
1379: Not Collective; No Fortran Support
1381: Input Parameter:
1382: . a - the value
1384: Level: beginner
1386: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtComplex()`
1387: M*/
1388: #define PetscSqrtScalar(a) PetscSqrtComplex(a)
1389: /*MC
1390: PetscPowScalar - Returns the value of `a` raised to the power `b`, both `PetscScalar`
1392: Synopsis:
1393: #include <petscmath.h>
1394: PetscScalar PetscPowScalar(PetscScalar a, PetscScalar b)
1396: Not Collective; No Fortran Support
1398: Input Parameters:
1399: + a - the value
1400: - b - the value
1402: Level: beginner
1404: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowComplex()`
1405: M*/
1406: #define PetscPowScalar(a, b) PetscPowComplex(a, b)
1407: /*MC
1408: PetscExpScalar - Returns the exponential $e^a$ of a `PetscScalar` value
1410: Synopsis:
1411: #include <petscmath.h>
1412: PetscScalar PetscExpScalar(PetscScalar a)
1414: Not Collective; No Fortran Support
1416: Input Parameter:
1417: . a - the value
1419: Level: beginner
1421: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpComplex()`
1422: M*/
1423: #define PetscExpScalar(a) PetscExpComplex(a)
1424: /*MC
1425: PetscLogScalar - Returns the natural logarithm of a `PetscScalar` value
1427: Synopsis:
1428: #include <petscmath.h>
1429: PetscScalar PetscLogScalar(PetscScalar a)
1431: Not Collective; No Fortran Support
1433: Input Parameter:
1434: . a - the value
1436: Level: beginner
1438: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogComplex()`
1439: M*/
1440: #define PetscLogScalar(a) PetscLogComplex(a)
1441: /*MC
1442: PetscSinScalar - Returns the sine of a `PetscScalar` value
1444: Synopsis:
1445: #include <petscmath.h>
1446: PetscScalar PetscSinScalar(PetscScalar a)
1448: Not Collective; No Fortran Support
1450: Input Parameter:
1451: . a - the value
1453: Level: beginner
1455: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinComplex()`
1456: M*/
1457: #define PetscSinScalar(a) PetscSinComplex(a)
1458: /*MC
1459: PetscCosScalar - Returns the cosine of a `PetscScalar` value
1461: Synopsis:
1462: #include <petscmath.h>
1463: PetscScalar PetscCosScalar(PetscScalar a)
1465: Not Collective; No Fortran Support
1467: Input Parameter:
1468: . a - the value
1470: Level: beginner
1472: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosComplex()`
1473: M*/
1474: #define PetscCosScalar(a) PetscCosComplex(a)
1475: /*MC
1476: PetscTanScalar - Returns the tangent of a `PetscScalar` value
1478: Synopsis:
1479: #include <petscmath.h>
1480: PetscScalar PetscTanScalar(PetscScalar a)
1482: Not Collective; No Fortran Support
1484: Input Parameter:
1485: . a - the value
1487: Level: beginner
1489: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanComplex()`
1490: M*/
1491: #define PetscTanScalar(a) PetscTanComplex(a)
1492: /*MC
1493: PetscAsinScalar - Returns the arc sine of a `PetscScalar` value
1495: Synopsis:
1496: #include <petscmath.h>
1497: PetscScalar PetscAsinScalar(PetscScalar a)
1499: Not Collective; No Fortran Support
1501: Input Parameter:
1502: . a - the value
1504: Level: beginner
1506: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinComplex()`
1507: M*/
1508: #define PetscAsinScalar(a) PetscAsinComplex(a)
1509: /*MC
1510: PetscAcosScalar - Returns the arc cosine of a `PetscScalar` value
1512: Synopsis:
1513: #include <petscmath.h>
1514: PetscScalar PetscAcosScalar(PetscScalar a)
1516: Not Collective; No Fortran Support
1518: Input Parameter:
1519: . a - the value
1521: Level: beginner
1523: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosComplex()`
1524: M*/
1525: #define PetscAcosScalar(a) PetscAcosComplex(a)
1526: /*MC
1527: PetscAtanScalar - Returns the arc tangent of a `PetscScalar` value
1529: Synopsis:
1530: #include <petscmath.h>
1531: PetscScalar PetscAtanScalar(PetscScalar a)
1533: Not Collective; No Fortran Support
1535: Input Parameter:
1536: . a - the value
1538: Level: beginner
1540: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanComplex()`
1541: M*/
1542: #define PetscAtanScalar(a) PetscAtanComplex(a)
1543: /*MC
1544: PetscSinhScalar - Returns the hyperbolic sine of a `PetscScalar` value
1546: Synopsis:
1547: #include <petscmath.h>
1548: PetscScalar PetscSinhScalar(PetscScalar a)
1550: Not Collective; No Fortran Support
1552: Input Parameter:
1553: . a - the value
1555: Level: beginner
1557: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhComplex()`
1558: M*/
1559: #define PetscSinhScalar(a) PetscSinhComplex(a)
1560: /*MC
1561: PetscCoshScalar - Returns the hyperbolic cosine of a `PetscScalar` value
1563: Synopsis:
1564: #include <petscmath.h>
1565: PetscScalar PetscCoshScalar(PetscScalar a)
1567: Not Collective; No Fortran Support
1569: Input Parameter:
1570: . a - the value
1572: Level: beginner
1574: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshComplex()`
1575: M*/
1576: #define PetscCoshScalar(a) PetscCoshComplex(a)
1577: /*MC
1578: PetscTanhScalar - Returns the hyperbolic tangent of a `PetscScalar` value
1580: Synopsis:
1581: #include <petscmath.h>
1582: PetscScalar PetscTanhScalar(PetscScalar a)
1584: Not Collective; No Fortran Support
1586: Input Parameter:
1587: . a - the value
1589: Level: beginner
1591: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhComplex()`
1592: M*/
1593: #define PetscTanhScalar(a) PetscTanhComplex(a)
1594: /*MC
1595: PetscAsinhScalar - Returns the inverse hyperbolic sine of a `PetscScalar` value
1597: Synopsis:
1598: #include <petscmath.h>
1599: PetscScalar PetscAsinhScalar(PetscScalar a)
1601: Not Collective; No Fortran Support
1603: Input Parameter:
1604: . a - the value
1606: Level: beginner
1608: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhComplex()`
1609: M*/
1610: #define PetscAsinhScalar(a) PetscAsinhComplex(a)
1611: /*MC
1612: PetscAcoshScalar - Returns the inverse hyperbolic cosine of a `PetscScalar` value
1614: Synopsis:
1615: #include <petscmath.h>
1616: PetscScalar PetscAcoshScalar(PetscScalar a)
1618: Not Collective; No Fortran Support
1620: Input Parameter:
1621: . a - the value
1623: Level: beginner
1625: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshComplex()`
1626: M*/
1627: #define PetscAcoshScalar(a) PetscAcoshComplex(a)
1628: /*MC
1629: PetscAtanhScalar - Returns the inverse hyperbolic tangent of a `PetscScalar` value
1631: Synopsis:
1632: #include <petscmath.h>
1633: PetscScalar PetscAtanhScalar(PetscScalar a)
1635: Not Collective; No Fortran Support
1637: Input Parameter:
1638: . a - the value
1640: Level: beginner
1642: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhComplex()`
1643: M*/
1644: #define PetscAtanhScalar(a) PetscAtanhComplex(a)
1646: #else /* PETSC_USE_COMPLEX */
1647: #define MPIU_SCALAR MPIU_REAL
1648: #define PetscRealPart(a) (a)
1649: #define PetscImaginaryPart(a) ((PetscReal)0)
1650: #define PetscAbsScalar(a) PetscAbsReal(a)
1651: #define PetscArgScalar(a) (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
1652: #define PetscConj(a) (a)
1653: #define PetscSqrtScalar(a) PetscSqrtReal(a)
1654: #define PetscPowScalar(a, b) PetscPowReal(a, b)
1655: #define PetscExpScalar(a) PetscExpReal(a)
1656: #define PetscLogScalar(a) PetscLogReal(a)
1657: #define PetscSinScalar(a) PetscSinReal(a)
1658: #define PetscCosScalar(a) PetscCosReal(a)
1659: #define PetscTanScalar(a) PetscTanReal(a)
1660: #define PetscAsinScalar(a) PetscAsinReal(a)
1661: #define PetscAcosScalar(a) PetscAcosReal(a)
1662: #define PetscAtanScalar(a) PetscAtanReal(a)
1663: #define PetscSinhScalar(a) PetscSinhReal(a)
1664: #define PetscCoshScalar(a) PetscCoshReal(a)
1665: #define PetscTanhScalar(a) PetscTanhReal(a)
1666: #define PetscAsinhScalar(a) PetscAsinhReal(a)
1667: #define PetscAcoshScalar(a) PetscAcoshReal(a)
1668: #define PetscAtanhScalar(a) PetscAtanhReal(a)
1670: #endif /* PETSC_USE_COMPLEX */
1672: /*
1673: Certain objects may be created using either single or double precision.
1674: This is currently not used.
1675: */
1676: typedef enum {
1677: PETSC_SCALAR_DOUBLE,
1678: PETSC_SCALAR_SINGLE,
1679: PETSC_SCALAR_LONG_DOUBLE,
1680: PETSC_SCALAR_HALF
1681: } PetscScalarPrecision;
1683: /*MC
1684: PetscAbs - Returns the absolute value of a number
1686: Synopsis:
1687: #include <petscmath.h>
1688: type PetscAbs(type v)
1690: Not Collective
1692: Input Parameter:
1693: . v - the number
1695: Level: beginner
1697: Note:
1698: The type can be integer or real floating point value, but cannot be complex
1700: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
1701: M*/
1702: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))
1704: /*MC
1705: PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1
1707: Synopsis:
1708: #include <petscmath.h>
1709: int PetscSign(type v)
1711: Not Collective
1713: Input Parameter:
1714: . v - the number
1716: Level: beginner
1718: Note:
1719: The type can be integer or real floating point value
1721: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
1722: M*/
1723: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
1725: /*MC
1726: PetscMin - Returns minimum of two numbers
1728: Synopsis:
1729: #include <petscmath.h>
1730: type PetscMin(type v1,type v2)
1732: Not Collective
1734: Input Parameters:
1735: + v1 - first value to find minimum of
1736: - v2 - second value to find minimum of
1738: Level: beginner
1740: Note:
1741: The type can be integer or floating point value, but cannot be complex
1743: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1744: M*/
1745: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))
1747: /*MC
1748: PetscMax - Returns maximum of two numbers
1750: Synopsis:
1751: #include <petscmath.h>
1752: type max PetscMax(type v1,type v2)
1754: Not Collective
1756: Input Parameters:
1757: + v1 - first value to find maximum of
1758: - v2 - second value to find maximum of
1760: Level: beginner
1762: Note:
1763: The type can be integer or floating point value
1765: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1766: M*/
1767: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))
1769: /*MC
1770: PetscClipInterval - Returns a number clipped to be within an interval
1772: Synopsis:
1773: #include <petscmath.h>
1774: type clip PetscClipInterval(type x,type a,type b)
1776: Not Collective
1778: Input Parameters:
1779: + x - value to use if within interval [a,b]
1780: . a - lower end of interval
1781: - b - upper end of interval
1783: Level: beginner
1785: Note:
1786: The type can be integer or floating point value
1788: Example\:
1789: .vb
1790: PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
1791: PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
1792: .ve
1794: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1795: M*/
1796: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))
1798: /*MC
1799: PetscAbsInt - Returns the absolute value of an integer
1801: Synopsis:
1802: #include <petscmath.h>
1803: int abs PetscAbsInt(int v1)
1805: Input Parameter:
1806: . v1 - the integer
1808: Level: beginner
1810: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
1811: M*/
1812: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))
1814: /*MC
1815: PetscAbsReal - Returns the absolute value of a real number
1817: Synopsis:
1818: #include <petscmath.h>
1819: Real abs PetscAbsReal(PetscReal v1)
1821: Input Parameter:
1822: . v1 - the `PetscReal` value
1824: Level: beginner
1826: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
1827: M*/
1828: #if defined(PETSC_USE_REAL_SINGLE)
1829: #define PetscAbsReal(a) fabsf(a)
1830: #elif defined(PETSC_USE_REAL_DOUBLE)
1831: #define PetscAbsReal(a) fabs(a)
1832: #elif defined(PETSC_USE_REAL___FLOAT128)
1833: #define PetscAbsReal(a) fabsq(a)
1834: #elif defined(PETSC_USE_REAL___FP16)
1835: #define PetscAbsReal(a) fabsf(a)
1836: #endif
1838: /*MC
1839: PetscSqr - Returns the square of a number
1841: Synopsis:
1842: #include <petscmath.h>
1843: type sqr PetscSqr(type v1)
1845: Not Collective
1847: Input Parameter:
1848: . v1 - the value
1850: Level: beginner
1852: Note:
1853: The type can be integer, floating point, or complex floating point
1855: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
1856: M*/
1857: #define PetscSqr(a) ((a) * (a))
1859: /*MC
1860: PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
1861: precision of `PetscReal` be it half, single, double or 128-bit representation
1863: Synopsis:
1864: #include <petscmath.h>
1865: PetscReal PetscRealConstant(real_number)
1867: Not Collective
1869: Input Parameter:
1870: . v1 - the real number, for example 1.5
1872: Level: beginner
1874: Note:
1875: For example, if PETSc is configured with `--with-precision=__float128` and one writes
1876: .vb
1877: PetscReal d = 1.5;
1878: .ve
1879: 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
1880: .vb
1881: PetscReal d = PetscRealConstant(1.5);
1882: .ve
1884: .seealso: `PetscReal`
1885: M*/
1886: #if defined(PETSC_USE_REAL_SINGLE)
1887: #define PetscRealConstant(constant) constant##F
1888: #elif defined(PETSC_USE_REAL_DOUBLE)
1889: #define PetscRealConstant(constant) constant
1890: #elif defined(PETSC_USE_REAL___FLOAT128)
1891: #define PetscRealConstant(constant) constant##Q
1892: #elif defined(PETSC_USE_REAL___FP16)
1893: #define PetscRealConstant(constant) constant##F
1894: #endif
1896: /*
1897: Basic constants
1898: */
1899: /*MC
1900: PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.
1902: Level: beginner
1904: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
1905: M*/
1907: /*MC
1908: PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.
1910: Level: beginner
1912: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
1913: M*/
1915: /*MC
1916: PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.
1918: Level: beginner
1920: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1921: M*/
1923: /*MC
1924: PETSC_E - the value of Euler's constant $ e $ to the correct precision of `PetscReal`.
1926: Level: beginner
1928: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1929: M*/
1931: #define PETSC_PI PetscRealConstant(3.1415926535897932384626433832795029)
1932: #define PETSC_PHI PetscRealConstant(1.6180339887498948482045868343656381)
1933: #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
1934: #define PETSC_E PetscRealConstant(2.7182818284590452353602874713526625)
1936: /*MC
1937: PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`
1939: Level: beginner
1941: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1942: M*/
1944: /*MC
1945: PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`
1947: Level: beginner
1949: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1950: M*/
1952: /*MC
1953: PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.
1955: Level: beginner
1957: Note:
1958: See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers
1960: Developer Note:
1961: The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.
1963: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1964: M*/
1966: /*MC
1967: PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`
1969: Level: beginner
1971: Note:
1972: See <https://en.wikipedia.org/wiki/Machine_epsilon>
1974: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1975: M*/
1977: /*MC
1978: PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`
1980: Level: beginner
1982: Note:
1983: See `PETSC_MACHINE_EPSILON`
1985: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
1986: M*/
1988: /*MC
1989: PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
1990: and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.
1992: Level: beginner
1994: Note:
1995: See `PETSC_MACHINE_EPSILON`
1997: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
1998: `PETSC_SQRT_MACHINE_EPSILON`
1999: M*/
2001: #if defined(PETSC_USE_REAL_SINGLE)
2002: #define PETSC_MAX_REAL 3.40282346638528860e+38F
2003: #define PETSC_MIN_REAL (-PETSC_MAX_REAL)
2004: #define PETSC_REAL_MIN 1.1754944e-38F
2005: #define PETSC_MACHINE_EPSILON 1.19209290e-07F
2006: #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
2007: #define PETSC_SMALL 1.e-5F
2008: #elif defined(PETSC_USE_REAL_DOUBLE)
2009: #define PETSC_MAX_REAL 1.7976931348623157e+308
2010: #define PETSC_MIN_REAL (-PETSC_MAX_REAL)
2011: #define PETSC_REAL_MIN 2.225073858507201e-308
2012: #define PETSC_MACHINE_EPSILON 2.2204460492503131e-16
2013: #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
2014: #define PETSC_SMALL 1.e-10
2015: #elif defined(PETSC_USE_REAL___FLOAT128)
2016: #define PETSC_MAX_REAL FLT128_MAX
2017: #define PETSC_MIN_REAL (-FLT128_MAX)
2018: #define PETSC_REAL_MIN FLT128_MIN
2019: #define PETSC_MACHINE_EPSILON FLT128_EPSILON
2020: #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
2021: #define PETSC_SMALL 1.e-20Q
2022: #elif defined(PETSC_USE_REAL___FP16)
2023: #define PETSC_MAX_REAL 65504.0F
2024: #define PETSC_MIN_REAL (-PETSC_MAX_REAL)
2025: #define PETSC_REAL_MIN .00006103515625F
2026: #define PETSC_MACHINE_EPSILON .0009765625F
2027: #define PETSC_SQRT_MACHINE_EPSILON .03125F
2028: #define PETSC_SMALL 5.e-3F
2029: #endif
2031: /*MC
2032: PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`
2034: Level: intermediate
2036: Note:
2037: This is not the IEEE infinity value
2039: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2040: M*/
2041: #define PETSC_INFINITY (PETSC_MAX_REAL / 4)
2043: /*MC
2044: PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`
2046: Level: intermediate
2048: Note:
2049: This is not the negative IEEE infinity value
2051: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2052: M*/
2053: #define PETSC_NINFINITY (-PETSC_INFINITY)
2055: PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal);
2056: PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal);
2057: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
2058: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
2059: {
2060: return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
2061: }
2062: static inline PetscBool PetscIsInfScalar(PetscScalar v)
2063: {
2064: return PetscIsInfReal(PetscAbsScalar(v));
2065: }
2066: static inline PetscBool PetscIsNanScalar(PetscScalar v)
2067: {
2068: return PetscIsNanReal(PetscAbsScalar(v));
2069: }
2070: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
2071: {
2072: return PetscIsInfOrNanReal(PetscAbsScalar(v));
2073: }
2074: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
2075: {
2076: return PetscIsNormalReal(PetscAbsScalar(v));
2077: }
2079: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
2080: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
2081: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);
2083: /*@C
2084: PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`
2086: Input Parameters:
2087: + lhs - The first number
2088: . rhs - The second number
2089: . rtol - The relative tolerance
2090: - atol - The absolute tolerance
2092: Level: beginner
2094: Note:
2095: This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
2096: numbers.
2098: .seealso: `PetscIsCloseAtTol()`
2099: @*/
2100: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
2101: {
2102: PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);
2104: if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
2105: return close;
2106: }
2108: /*
2109: These macros are currently hardwired to match the regular data types, so there is no support for a different
2110: MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
2111: */
2112: #define MPIU_MATSCALAR MPIU_SCALAR
2113: typedef PetscScalar MatScalar;
2114: typedef PetscReal MatReal;
2116: struct petsc_mpiu_2scalar {
2117: PetscScalar a, b;
2118: };
2119: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);
2121: /* MPI Datatypes for composite reductions */
2122: struct petsc_mpiu_real_int {
2123: PetscReal v;
2124: PetscInt i;
2125: };
2127: struct petsc_mpiu_scalar_int {
2128: PetscScalar v;
2129: PetscInt i;
2130: };
2132: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
2133: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);
2135: #if defined(PETSC_USE_64BIT_INDICES)
2136: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
2137: PetscInt a;
2138: PetscInt b;
2139: };
2140: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
2141: PetscInt a;
2142: PetscMPIInt b;
2143: };
2144: /*
2145: static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
2146: static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
2147: static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");
2149: clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
2150: PetscInt *, even though (with everything else uncommented) both of the static_asserts above
2151: pass! So we just comment it out...
2152: */
2153: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
2154: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
2155: #else
2156: #define MPIU_2INT MPI_2INT
2157: #define MPIU_INT_MPIINT MPI_2INT
2158: #endif
2159: PETSC_EXTERN MPI_Datatype MPI_4INT;
2160: PETSC_EXTERN MPI_Datatype MPIU_4INT;
2162: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
2163: {
2164: PetscInt result = 1;
2165: while (power) {
2166: if (power & 1) result *= base;
2167: power >>= 1;
2168: if (power) base *= base;
2169: }
2170: return result;
2171: }
2173: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
2174: {
2175: PetscInt64 result = 1;
2176: while (power) {
2177: if (power & 1) result *= base;
2178: power >>= 1;
2179: if (power) base *= base;
2180: }
2181: return result;
2182: }
2184: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
2185: {
2186: PetscReal result = 1;
2187: if (power < 0) {
2188: power = -power;
2189: base = ((PetscReal)1) / base;
2190: }
2191: while (power) {
2192: if (power & 1) result *= base;
2193: power >>= 1;
2194: if (power) base *= base;
2195: }
2196: return result;
2197: }
2199: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
2200: {
2201: PetscScalar result = (PetscReal)1;
2202: if (power < 0) {
2203: power = -power;
2204: base = ((PetscReal)1) / base;
2205: }
2206: while (power) {
2207: if (power & 1) result *= base;
2208: power >>= 1;
2209: if (power) base *= base;
2210: }
2211: return result;
2212: }
2214: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
2215: {
2216: PetscScalar cpower = power;
2217: return PetscPowScalar(base, cpower);
2218: }
2220: /*MC
2221: PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers
2223: Synopsis:
2224: #include <petscmath.h>
2225: bool PetscApproximateLTE(PetscReal x,constant float)
2227: Not Collective
2229: Input Parameters:
2230: + x - the variable
2231: - b - the constant float it is checking if `x` is less than or equal to
2233: Level: advanced
2235: Notes:
2236: The fudge factor is the value `PETSC_SMALL`
2238: The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
2240: This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2241: floating point results.
2243: Example\:
2244: .vb
2245: PetscReal x;
2246: if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
2247: .ve
2249: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
2250: M*/
2251: #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))
2253: /*MC
2254: PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers
2256: Synopsis:
2257: #include <petscmath.h>
2258: bool PetscApproximateGTE(PetscReal x,constant float)
2260: Not Collective
2262: Input Parameters:
2263: + x - the variable
2264: - b - the constant float it is checking if `x` is greater than or equal to
2266: Level: advanced
2268: Notes:
2269: The fudge factor is the value `PETSC_SMALL`
2271: The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2
2273: This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2274: floating point results.
2276: Example\:
2277: .vb
2278: PetscReal x;
2279: if (PetscApproximateGTE(x, 3.2)) { // replaces if (x >= 3.2) {
2280: .ve
2282: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2283: M*/
2284: #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))
2286: /*@C
2287: PetscCeilInt - Returns the ceiling of the quotation of two positive integers
2289: Not Collective
2291: Input Parameters:
2292: + x - the numerator
2293: - y - the denominator
2295: Level: advanced
2297: Example\:
2298: .vb
2299: PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
2300: .ve
2302: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2303: @*/
2304: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
2305: {
2306: return x / y + (x % y ? 1 : 0);
2307: }
2309: /*@C
2310: PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers
2312: Not Collective
2314: Input Parameters:
2315: + x - the numerator
2316: - y - the denominator
2318: Level: advanced
2320: Example\:
2321: .vb
2322: PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
2323: .ve
2325: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2326: @*/
2327: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
2328: {
2329: return x / y + (x % y ? 1 : 0);
2330: }
2332: /*@C
2333: PetscGCD - Returns the greatest common divisor of two integers
2335: Not Collective
2337: Input Parameters:
2338: + a - first number
2339: - b - second number
2341: Level: advanced
2343: .seealso: `PetscLCM()`
2344: @*/
2345: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
2346: {
2347: a = PetscAbsInt(a);
2348: b = PetscAbsInt(b);
2349: while (b != 0) {
2350: PetscInt tmp = b;
2352: b = a % b;
2353: a = tmp;
2354: }
2355: return a;
2356: }
2358: /*@C
2359: PetscLCM - Returns the least common multiple of two integers
2361: Not Collective
2363: Input Parameters:
2364: + a - first number
2365: - b - second number
2367: Level: advanced
2369: .seealso: `PetscGCD()`
2370: @*/
2371: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
2372: {
2373: PetscInt gcd;
2375: a = PetscAbsInt(a);
2376: b = PetscAbsInt(b);
2378: gcd = PetscGCD(a, b);
2379: return gcd ? a * (b / gcd) : 0;
2380: }
2382: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);