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