Actual source code: petscmath.h
1: /*
2:
3: PETSc mathematics include file. Defines certain basic mathematical
4: constants and functions for working with single and double precision
5: floating point numbers as well as complex and integers.
7: This file is included by petsc.h and should not be used directly.
9: */
13: #include <math.h>
18: /*
20: Defines operations that are different for complex and real numbers;
21: note that one cannot really mix the use of complex and real in the same
22: PETSc program. All PETSc objects in one program are built around the object
23: PetscScalar which is either always a double or a complex.
25: */
27: #define PetscExpPassiveScalar(a) PetscExpScalar()
29: #if defined(PETSC_USE_COMPLEX)
30: #if defined(PETSC_CLANGUAGE_CXX)
31: /*
32: C++ support of complex numbers: Original support
33: */
34: #include <complex>
36: #define PetscRealPart(a) (a).real()
37: #define PetscImaginaryPart(a) (a).imag()
38: #define PetscAbsScalar(a) std::abs(a)
39: #define PetscConj(a) std::conj(a)
40: #define PetscSqrtScalar(a) std::sqrt(a)
41: #define PetscPowScalar(a,b) std::pow(a,b)
42: #define PetscExpScalar(a) std::exp(a)
43: #define PetscSinScalar(a) std::sin(a)
44: #define PetscCosScalar(a) std::cos(a)
46: #if defined(PETSC_USE_SINGLE)
47: typedef std::complex<float> PetscScalar;
48: #elif defined(PETSC_USE_LONG_DOUBLE)
49: typedef std::complex<long double> PetscScalar;
50: #elif defined(PETSC_USE_INT)
51: typedef std::complex<int> PetscScalar;
52: #else
53: typedef std::complex<double> PetscScalar;
54: #endif
55: #else
56: #include <complex.h>
58: /*
59: C support of complex numbers: Warning it needs a
60: C90 compliant compiler to work...
61: */
63: #if defined(PETSC_USE_SINGLE)
64: typedef float complex PetscScalar;
66: #define PetscRealPart(a) crealf(a)
67: #define PetscImaginaryPart(a) cimagf(a)
68: #define PetscAbsScalar(a) cabsf(a)
69: #define PetscConj(a) conjf(a)
70: #define PetscSqrtScalar(a) csqrtf(a)
71: #define PetscPowScalar(a,b) cpowf(a,b)
72: #define PetscExpScalar(a) cexpf(a)
73: #define PetscSinScalar(a) csinf(a)
74: #define PetscCosScalar(a) ccosf(a)
75: #elif defined(PETSC_USE_LONG_DOUBLE)
76: typedef long double complex PetscScalar;
78: #define PetscRealPart(a) creall(a)
79: #define PetscImaginaryPart(a) cimagl(a)
80: #define PetscAbsScalar(a) cabsl(a)
81: #define PetscConj(a) conjl(a)
82: #define PetscSqrtScalar(a) csqrtl(a)
83: #define PetscPowScalar(a,b) cpowl(a,b)
84: #define PetscExpScalar(a) cexpl(a)
85: #define PetscSinScalar(a) csinl(a)
86: #define PetscCosScalar(a) ccosl(a)
88: #else
89: typedef double complex PetscScalar;
91: #define PetscRealPart(a) creal(a)
92: #define PetscImaginaryPart(a) cimag(a)
93: #define PetscAbsScalar(a) cabs(a)
94: #define PetscConj(a) conj(a)
95: #define PetscSqrtScalar(a) csqrt(a)
96: #define PetscPowScalar(a,b) cpow(a,b)
97: #define PetscExpScalar(a) cexp(a)
98: #define PetscSinScalar(a) csin(a)
99: #define PetscCosScalar(a) ccos(a)
100: #endif
101: #endif
104: #define MPIU_SCALAR MPIU_COMPLEX
105: #if defined(PETSC_USE_MAT_SINGLE)
106: #define MPIU_MATSCALAR ??Notdone
107: #else
108: #define MPIU_MATSCALAR MPIU_COMPLEX
109: #endif
111: /* Compiling for real numbers only */
112: #else
113: # if defined(PETSC_USE_SINGLE)
114: # define MPIU_SCALAR MPI_FLOAT
115: # elif defined(PETSC_USE_LONG_DOUBLE)
116: # define MPIU_SCALAR MPI_LONG_DOUBLE
117: # elif defined(PETSC_INT)
118: # define MPIU_INT MPI_INT
119: # else
120: # define MPIU_SCALAR MPI_DOUBLE
121: # endif
122: # if defined(PETSC_USE_MAT_SINGLE) || defined(PETSC_USE_SINGLE)
123: # define MPIU_MATSCALAR MPI_FLOAT
124: # elif defined(PETSC_USE_LONG_DOUBLE)
125: # define MPIU_MATSCALAR MPI_LONG_DOUBLE
126: # elif defined(PETSC_USE_INT)
127: # define MPIU_MATSCALAR MPI_INT
128: # else
129: # define MPIU_MATSCALAR MPI_DOUBLE
130: # endif
131: # define PetscRealPart(a) (a)
132: # define PetscImaginaryPart(a) (0)
133: # define PetscAbsScalar(a) (((a)<0.0) ? -(a) : (a))
134: # define PetscConj(a) (a)
135: # define PetscSqrtScalar(a) sqrt(a)
136: # define PetscPowScalar(a,b) pow(a,b)
137: # define PetscExpScalar(a) exp(a)
138: # define PetscSinScalar(a) sin(a)
139: # define PetscCosScalar(a) cos(a)
141: # if defined(PETSC_USE_SINGLE)
142: typedef float PetscScalar;
143: # elif defined(PETSC_USE_LONG_DOUBLE)
144: typedef long double PetscScalar;
145: # elif defined(PETSC_USE_INT)
146: typedef int PetscScalar;
147: # else
148: typedef double PetscScalar;
149: # endif
150: #endif
152: #if defined(PETSC_USE_SINGLE)
153: # define MPIU_REAL MPI_FLOAT
154: #elif defined(PETSC_USE_LONG_DOUBLE)
155: # define MPIU_REAL MPI_LONG_DOUBLE
156: #elif defined(PETSC_USE_INT)
157: # define MPIU_REAL MPI_INT
158: #else
159: # define MPIU_REAL MPI_DOUBLE
160: #endif
162: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
163: #define PetscAbs(a) (((a) >= 0) ? (a) : -(a))
164: /*
165: Allows compiling PETSc so that matrix values are stored in
166: single precision but all other objects still use double
167: precision. This does not work for complex numbers in that case
168: it remains double
170: EXPERIMENTAL! NOT YET COMPLETELY WORKING
171: */
173: #if defined(PETSC_USE_MAT_SINGLE)
174: typedef float MatScalar;
175: #else
176: typedef PetscScalar MatScalar;
177: #endif
179: #if defined(PETSC_USE_SINGLE)
180: typedef float PetscReal;
181: #elif defined(PETSC_USE_LONG_DOUBLE)
182: typedef long double PetscReal;
183: #elif defined(PETSC_USE_INT)
184: typedef int PetscReal;
185: #else
186: typedef double PetscReal;
187: #endif
189: #if defined(PETSC_USE_COMPLEX)
190: typedef PetscReal MatReal;
191: #elif defined(PETSC_USE_MAT_SINGLE) || defined(PETSC_USE_SINGLE)
192: typedef float MatReal;
193: #else
194: typedef PetscReal MatReal;
195: #endif
198: /* --------------------------------------------------------------------------*/
200: /*
201: Certain objects may be created using either single
202: or double precision.
203: */
204: typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
206: /* PETSC_i is the imaginary number, i */
209: /*MC
210: PetscMin - Returns minimum of two numbers
212: Input Parameter:
213: + v1 - first value to find minimum of
214: - v2 - second value to find minimum of
216: Synopsis:
217: type PetscMin(type v1,type v2)
219: Notes: type can be integer or floating point value
221: Level: beginner
224: .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
226: M*/
227: #define PetscMin(a,b) (((a)<(b)) ? (a) : (b))
229: /*MC
230: PetscMax - Returns maxium of two numbers
232: Input Parameter:
233: + v1 - first value to find maximum of
234: - v2 - second value to find maximum of
236: Synopsis:
237: type max PetscMax(type v1,type v2)
239: Notes: type can be integer or floating point value
241: Level: beginner
243: .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
245: M*/
246: #define PetscMax(a,b) (((a)<(b)) ? (b) : (a))
248: /*MC
249: PetscAbsInt - Returns the absolute value of an integer
251: Input Parameter:
252: . v1 - the integer
254: Synopsis:
255: int abs PetscAbsInt(int v1)
258: Level: beginner
260: .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
262: M*/
263: #define PetscAbsInt(a) (((a)<0) ? -(a) : (a))
265: /*MC
266: PetscAbsReal - Returns the absolute value of an real number
268: Input Parameter:
269: . v1 - the double
271: Synopsis:
272: int abs PetscAbsReal(PetscReal v1)
275: Level: beginner
277: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
279: M*/
280: #define PetscAbsReal(a) (((a)<0) ? -(a) : (a))
282: /*MC
283: PetscSqr - Returns the square of a number
285: Input Parameter:
286: . v1 - the value
288: Synopsis:
289: type sqr PetscSqr(type v1)
291: Notes: type can be integer or floating point value
293: Level: beginner
295: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
297: M*/
298: #define PetscSqr(a) ((a)*(a))
300: /* ----------------------------------------------------------------------------*/
301: /*
302: Basic constants - These should be done much better
303: */
304: #define PETSC_PI 3.14159265358979323846264
305: #define PETSC_DEGREES_TO_RADIANS 0.01745329251994
306: #define PETSC_MAX_INT 1000000000
307: #define PETSC_MIN_INT -1000000000
309: #if defined(PETSC_USE_SINGLE)
310: # define PETSC_MAX 1.e30
311: # define PETSC_MIN -1.e30
312: # define PETSC_MACHINE_EPSILON 1.e-7
313: # define PETSC_SQRT_MACHINE_EPSILON 3.e-4
314: # define PETSC_SMALL 1.e-5
315: #elif defined(PETSC_USE_INT)
316: # define PETSC_MAX PETSC_MAX_INT
317: # define PETSC_MIN PETSC_MIN_INT
318: # define PETSC_MACHINE_EPSILON 1
319: # define PETSC_SQRT_MACHINE_EPSILON 1
320: # define PETSC_SMALL 0
321: #else
322: # define PETSC_MAX 1.e300
323: # define PETSC_MIN -1.e300
324: # define PETSC_MACHINE_EPSILON 1.e-14
325: # define PETSC_SQRT_MACHINE_EPSILON 1.e-7
326: # define PETSC_SMALL 1.e-10
327: #endif
329: EXTERN PetscErrorCode PetscGlobalMax(PetscReal*,PetscReal*,MPI_Comm);
330: EXTERN PetscErrorCode PetscGlobalMin(PetscReal*,PetscReal*,MPI_Comm);
331: EXTERN PetscErrorCode PetscGlobalSum(PetscScalar*,PetscScalar*,MPI_Comm);
334: /* ----------------------------------------------------------------------------*/
335: /*
336: PetscLogDouble variables are used to contain double precision numbers
337: that are not used in the numerical computations, but rather in logging,
338: timing etc.
339: */
340: typedef double PetscLogDouble;
341: #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE
343: #define PassiveReal PetscReal
344: #define PassiveScalar PetscScalar
348: #endif