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