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