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