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