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. 6 7 This file is included by petscsys.h and should not be used directly. 8 9 */ 10 11 #if !defined(__PETSCMATH_H) 12 #define __PETSCMATH_H 13 #include <math.h> 14 PETSC_EXTERN_CXX_BEGIN 15 16 extern MPI_Datatype MPIU_2SCALAR; 17 extern MPI_Datatype MPIU_2INT; 18 /* 19 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. 24 25 */ 26 27 #define PetscExpPassiveScalar(a) PetscExpScalar() 28 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> 35 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 PetscLogScalar(a) std::log(a) 44 #define PetscSinScalar(a) std::sin(a) 45 #define PetscCosScalar(a) std::cos(a) 46 47 #if defined(PETSC_USE_SCALAR_SINGLE) 48 typedef std::complex<float> PetscScalar; 49 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 50 typedef std::complex<long double> PetscScalar; 51 #else 52 typedef std::complex<double> PetscScalar; 53 #endif 54 #else 55 #include <complex.h> 56 57 /* 58 C support of complex numbers: Warning it needs a 59 C99 compliant compiler to work... 60 */ 61 62 #if defined(PETSC_USE_SCALAR_SINGLE) 63 typedef float complex PetscScalar; 64 65 #define PetscRealPart(a) crealf(a) 66 #define PetscImaginaryPart(a) cimagf(a) 67 #define PetscAbsScalar(a) cabsf(a) 68 #define PetscConj(a) conjf(a) 69 #define PetscSqrtScalar(a) csqrtf(a) 70 #define PetscPowScalar(a,b) cpowf(a,b) 71 #define PetscExpScalar(a) cexpf(a) 72 #define PetscLogScalar(a) clogf(a) 73 #define PetscSinScalar(a) csinf(a) 74 #define PetscCosScalar(a) ccosf(a) 75 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 76 typedef long double complex PetscScalar; 77 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 PetscLogScalar(a) clogl(a) 86 #define PetscSinScalar(a) csinl(a) 87 #define PetscCosScalar(a) ccosl(a) 88 89 #else 90 typedef double complex PetscScalar; 91 92 #define PetscRealPart(a) creal(a) 93 #define PetscImaginaryPart(a) cimag(a) 94 #define PetscAbsScalar(a) cabs(a) 95 #define PetscConj(a) conj(a) 96 #define PetscSqrtScalar(a) csqrt(a) 97 #define PetscPowScalar(a,b) cpow(a,b) 98 #define PetscExpScalar(a) cexp(a) 99 #define PetscLogScalar(a) clog(a) 100 #define PetscSinScalar(a) csin(a) 101 #define PetscCosScalar(a) ccos(a) 102 #endif 103 #endif 104 105 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 106 extern MPI_Datatype MPI_C_DOUBLE_COMPLEX; 107 extern MPI_Datatype MPI_C_COMPLEX; 108 #endif 109 110 #if defined(PETSC_USE_SCALAR_SINGLE) 111 #define MPIU_SCALAR MPI_C_COMPLEX 112 #else 113 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX 114 #endif 115 #if defined(PETSC_USE_SCALAR_MAT_SINGLE) 116 #define MPIU_MATSCALAR ??Notdone 117 #else 118 #define MPIU_MATSCALAR MPI_C_DOUBLE_COMPLEX 119 #endif 120 121 122 /* Compiling for real numbers only */ 123 #else 124 # if defined(PETSC_USE_SCALAR_SINGLE) 125 # define MPIU_SCALAR MPI_FLOAT 126 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 127 # define MPIU_SCALAR MPI_LONG_DOUBLE 128 # else 129 # define MPIU_SCALAR MPI_DOUBLE 130 # endif 131 # if defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE) 132 # define MPIU_MATSCALAR MPI_FLOAT 133 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 134 # define MPIU_MATSCALAR MPI_LONG_DOUBLE 135 # else 136 # define MPIU_MATSCALAR MPI_DOUBLE 137 # endif 138 # define PetscRealPart(a) (a) 139 # define PetscImaginaryPart(a) (0.) 140 # define PetscAbsScalar(a) (((a)<0.0) ? -(a) : (a)) 141 # define PetscConj(a) (a) 142 # define PetscSqrtScalar(a) sqrt(a) 143 # define PetscPowScalar(a,b) pow(a,b) 144 # define PetscExpScalar(a) exp(a) 145 # define PetscLogScalar(a) log(a) 146 # define PetscSinScalar(a) sin(a) 147 # define PetscCosScalar(a) cos(a) 148 149 # if defined(PETSC_USE_SCALAR_SINGLE) 150 typedef float PetscScalar; 151 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 152 typedef long double PetscScalar; 153 # else 154 typedef double PetscScalar; 155 # endif 156 #endif 157 158 #if defined(PETSC_USE_SCALAR_SINGLE) 159 # define MPIU_REAL MPI_FLOAT 160 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 161 # define MPIU_REAL MPI_LONG_DOUBLE 162 #else 163 # define MPIU_REAL MPI_DOUBLE 164 #endif 165 166 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 167 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 168 /* 169 Allows compiling PETSc so that matrix values are stored in 170 single precision but all other objects still use double 171 precision. This does not work for complex numbers in that case 172 it remains double 173 174 EXPERIMENTAL! NOT YET COMPLETELY WORKING 175 */ 176 177 #if defined(PETSC_USE_SCALAR_MAT_SINGLE) 178 typedef float MatScalar; 179 #else 180 typedef PetscScalar MatScalar; 181 #endif 182 183 #if defined(PETSC_USE_SCALAR_SINGLE) 184 typedef float PetscReal; 185 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 186 typedef long double PetscReal; 187 #else 188 typedef double PetscReal; 189 #endif 190 191 #if defined(PETSC_USE_COMPLEX) 192 typedef PetscReal MatReal; 193 #elif defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE) 194 typedef float MatReal; 195 #else 196 typedef PetscReal MatReal; 197 #endif 198 199 200 /* --------------------------------------------------------------------------*/ 201 202 /* 203 Certain objects may be created using either single or double precision. 204 This is currently not used. 205 */ 206 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; 207 208 /* PETSC_i is the imaginary number, i */ 209 extern PetscScalar PETSC_i; 210 211 /*MC 212 PetscMin - Returns minimum of two numbers 213 214 Synopsis: 215 type PetscMin(type v1,type v2) 216 217 Not Collective 218 219 Input Parameter: 220 + v1 - first value to find minimum of 221 - v2 - second value to find minimum of 222 223 224 Notes: type can be integer or floating point value 225 226 Level: beginner 227 228 229 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 230 231 M*/ 232 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 233 234 /*MC 235 PetscMax - Returns maxium of two numbers 236 237 Synopsis: 238 type max PetscMax(type v1,type v2) 239 240 Not Collective 241 242 Input Parameter: 243 + v1 - first value to find maximum of 244 - v2 - second value to find maximum of 245 246 Notes: type can be integer or floating point value 247 248 Level: beginner 249 250 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 251 252 M*/ 253 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 254 255 /*MC 256 PetscAbsInt - Returns the absolute value of an integer 257 258 Synopsis: 259 int abs PetscAbsInt(int v1) 260 261 Not Collective 262 263 Input Parameter: 264 . v1 - the integer 265 266 Level: beginner 267 268 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 269 270 M*/ 271 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 272 273 /*MC 274 PetscAbsReal - Returns the absolute value of an real number 275 276 Synopsis: 277 Real abs PetscAbsReal(PetscReal v1) 278 279 Not Collective 280 281 Input Parameter: 282 . v1 - the double 283 284 285 Level: beginner 286 287 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 288 289 M*/ 290 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 291 292 /*MC 293 PetscSqr - Returns the square of a number 294 295 Synopsis: 296 type sqr PetscSqr(type v1) 297 298 Not Collective 299 300 Input Parameter: 301 . v1 - the value 302 303 Notes: type can be integer or floating point value 304 305 Level: beginner 306 307 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 308 309 M*/ 310 #define PetscSqr(a) ((a)*(a)) 311 312 /* ----------------------------------------------------------------------------*/ 313 /* 314 Basic constants - These should be done much better 315 */ 316 #define PETSC_PI 3.14159265358979323846264 317 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994 318 #define PETSC_MAX_INT 2147483647 319 #define PETSC_MIN_INT -2147483647 320 321 #if defined(PETSC_USE_SCALAR_SINGLE) 322 # define PETSC_MAX 1.e30 323 # define PETSC_MIN -1.e30 324 # define PETSC_MACHINE_EPSILON 1.e-7 325 # define PETSC_SQRT_MACHINE_EPSILON 3.e-4 326 # define PETSC_SMALL 1.e-5 327 #else 328 # define PETSC_MAX 1.e300 329 # define PETSC_MIN -1.e300 330 # define PETSC_MACHINE_EPSILON 1.e-14 331 # define PETSC_SQRT_MACHINE_EPSILON 1.e-7 332 # define PETSC_SMALL 1.e-10 333 #endif 334 335 #if defined PETSC_HAVE_ADIC 336 /* Use MPI_Allreduce when ADIC is not available. */ 337 extern PetscErrorCode PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*); 338 extern PetscErrorCode PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*); 339 extern PetscErrorCode PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*); 340 #endif 341 342 /*MC 343 PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0. 344 345 Input Parameter: 346 . a - the double 347 348 349 Notes: uses the C99 standard isinf() and isnan() on systems where they exist. 350 Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile 351 out this form, thus removing the check. 352 353 Level: beginner 354 355 M*/ 356 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) 357 /* I had to introduce these inline functions because the C++ <valarray> header invalidates isinf(), making it std::isinf() */ 358 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 359 return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)); 360 } 361 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 362 return isinf(a) || isnan(a); 363 } 364 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN) 365 #if defined(PETSC_HAVE_FLOAT_H) 366 #include "float.h" /* windows defines _finite() in float.h */ 367 #endif 368 #if defined(PETSC_HAVE_IEEEFP_H) 369 #include "ieeefp.h" /* Solaris prototypes these here */ 370 #endif 371 #define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a))) 372 #define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a)) 373 #else 374 #define PetscIsInfOrNanScalar(a) ((a - a) != 0.0) 375 #define PetscIsInfOrNanReal(a) ((a - a) != 0.0) 376 #endif 377 378 379 /* ----------------------------------------------------------------------------*/ 380 /* 381 PetscLogDouble variables are used to contain double precision numbers 382 that are not used in the numerical computations, but rather in logging, 383 timing etc. 384 */ 385 typedef double PetscLogDouble; 386 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE 387 388 #define PassiveReal PetscReal 389 #define PassiveScalar PetscScalar 390 391 392 PETSC_EXTERN_CXX_END 393 #endif 394