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 21 Defines operations that are different for complex and real numbers; 22 note that one cannot really mix the use of complex and real in the same 23 PETSc program. All PETSc objects in one program are built around the object 24 PetscScalar which is either always a real or a complex. 25 26 */ 27 28 #define PetscExpPassiveScalar(a) PetscExpScalar() 29 30 /* 31 Complex number definitions 32 */ 33 #if defined(PETSC_USE_COMPLEX) 34 #if defined(PETSC_CLANGUAGE_CXX) 35 /* C++ support of complex number */ 36 #include <complex> 37 38 #define PetscRealPart(a) (a).real() 39 #define PetscImaginaryPart(a) (a).imag() 40 #define PetscAbsScalar(a) std::abs(a) 41 #define PetscConj(a) std::conj(a) 42 #define PetscSqrtScalar(a) std::sqrt(a) 43 #define PetscPowScalar(a,b) std::pow(a,b) 44 #define PetscExpScalar(a) std::exp(a) 45 #define PetscLogScalar(a) std::log(a) 46 #define PetscSinScalar(a) std::sin(a) 47 #define PetscCosScalar(a) std::cos(a) 48 49 #if defined(PETSC_USE_REAL_SINGLE) 50 typedef std::complex<float> PetscScalar; 51 #elif defined(PETSC_USE_REAL_DOUBLE) 52 typedef std::complex<double> PetscScalar; 53 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 54 typedef std::complex<long double> PetscScalar; 55 #endif /* PETSC_USE_REAL_* */ 56 57 #else /* PETSC_CLANGUAGE_CXX */ 58 /* C support of complex numbers: Requires C99 compliant compiler*/ 59 #include <complex.h> 60 61 #if defined(PETSC_USE_REAL_SINGLE) 62 typedef float complex PetscScalar; 63 64 #define PetscRealPart(a) crealf(a) 65 #define PetscImaginaryPart(a) cimagf(a) 66 #define PetscAbsScalar(a) cabsf(a) 67 #define PetscConj(a) conjf(a) 68 #define PetscSqrtScalar(a) csqrtf(a) 69 #define PetscPowScalar(a,b) cpowf(a,b) 70 #define PetscExpScalar(a) cexpf(a) 71 #define PetscLogScalar(a) clogf(a) 72 #define PetscSinScalar(a) csinf(a) 73 #define PetscCosScalar(a) ccosf(a) 74 75 #elif defined(PETSC_USE_REAL_DOUBLE) 76 typedef double complex PetscScalar; 77 78 #define PetscRealPart(a) creal(a) 79 #define PetscImaginaryPart(a) cimag(a) 80 #define PetscAbsScalar(a) cabs(a) 81 #define PetscConj(a) conj(a) 82 #define PetscSqrtScalar(a) csqrt(a) 83 #define PetscPowScalar(a,b) cpow(a,b) 84 #define PetscExpScalar(a) cexp(a) 85 #define PetscLogScalar(a) clog(a) 86 #define PetscSinScalar(a) csin(a) 87 #define PetscCosScalar(a) ccos(a) 88 89 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 90 typedef long double complex PetscScalar; 91 92 #define PetscRealPart(a) creall(a) 93 #define PetscImaginaryPart(a) cimagl(a) 94 #define PetscAbsScalar(a) cabsl(a) 95 #define PetscConj(a) conjl(a) 96 #define PetscSqrtScalar(a) csqrtl(a) 97 #define PetscPowScalar(a,b) cpowl(a,b) 98 #define PetscExpScalar(a) cexpl(a) 99 #define PetscLogScalar(a) clogl(a) 100 #define PetscSinScalar(a) csinl(a) 101 #define PetscCosScalar(a) ccosl(a) 102 103 #endif /* PETSC_USE_REAL_* */ 104 #endif /* PETSC_CLANGUAGE_CXX */ 105 106 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 107 extern MPI_Datatype MPI_C_DOUBLE_COMPLEX; 108 extern MPI_Datatype MPI_C_COMPLEX; 109 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */ 110 111 #if defined(PETSC_USE_REAL_SINGLE) 112 #define MPIU_SCALAR MPI_C_COMPLEX 113 #elif defined(PETSC_USE_REAL_DOUBLE) 114 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX 115 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 116 #define MPIU_SCALAR error 117 #endif /* PETSC_USE_REAL_* */ 118 119 /* 120 real number definitions 121 */ 122 #else /* PETSC_USE_COMPLEX */ 123 #if defined(PETSC_USE_REAL_SINGLE) 124 #define MPIU_SCALAR MPI_FLOAT 125 typedef float PetscScalar; 126 #elif defined(PETSC_USE_REAL_DOUBLE) 127 #define MPIU_SCALAR MPI_DOUBLE 128 typedef double PetscScalar; 129 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 130 #define MPIU_SCALAR MPI_LONG_DOUBLE 131 typedef long double PetscScalar; 132 #elif defined(PETSC_USE_REAL___FLOAT128) 133 extern MPI_Datatype MPIU___FLOAT128; 134 #define MPIU_SCALAR MPIU___FLOAT128 135 typedef __float128 PetscScalar; 136 #endif /* PETSC_USE_REAL_* */ 137 #define PetscRealPart(a) (a) 138 #define PetscImaginaryPart(a) (0.) 139 #define PetscAbsScalar(a) (((a)<0.0) ? -(a) : (a)) 140 #define PetscConj(a) (a) 141 #if !defined(PETSC_USE_REAL___FLOAT128) 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 #else /* PETSC_USE_REAL___FLOAT128 */ 149 #include <quadmath.h> 150 #define PetscSqrtScalar(a) sqrtq(a) 151 #define PetscPowScalar(a,b) powq(a,b) 152 #define PetscExpScalar(a) expq(a) 153 #define PetscLogScalar(a) logq(a) 154 #define PetscSinScalar(a) sinq(a) 155 #define PetscCosScalar(a) cosq(a) 156 #endif /* PETSC_USE_REAL___FLOAT128 */ 157 158 #endif /* PETSC_USE_COMPLEX */ 159 160 #if defined(PETSC_USE_REAL_SINGLE) 161 #define MPIU_REAL MPI_FLOAT 162 typedef float PetscReal; 163 #elif defined(PETSC_USE_REAL_DOUBLE) 164 #define MPIU_REAL MPI_DOUBLE 165 typedef double PetscReal; 166 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 167 #define MPIU_REAL MPI_LONG_DOUBLE 168 typedef long double PetscReal; 169 #elif defined(PETSC_USE_REAL___FLOAT128) 170 #define MPIU_REAL MPIU___FLOAT128 171 typedef __float128 PetscReal; 172 #endif /* PETSC_USE_REAL_* */ 173 174 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 175 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 176 177 /* --------------------------------------------------------------------------*/ 178 179 /* 180 Certain objects may be created using either single or double precision. 181 This is currently not used. 182 */ 183 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; 184 185 /* PETSC_i is the imaginary number, i */ 186 extern PetscScalar PETSC_i; 187 188 /*MC 189 PetscMin - Returns minimum of two numbers 190 191 Synopsis: 192 type PetscMin(type v1,type v2) 193 194 Not Collective 195 196 Input Parameter: 197 + v1 - first value to find minimum of 198 - v2 - second value to find minimum of 199 200 201 Notes: type can be integer or floating point value 202 203 Level: beginner 204 205 206 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 207 208 M*/ 209 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 210 211 /*MC 212 PetscMax - Returns maxium of two numbers 213 214 Synopsis: 215 type max PetscMax(type v1,type v2) 216 217 Not Collective 218 219 Input Parameter: 220 + v1 - first value to find maximum of 221 - v2 - second value to find maximum of 222 223 Notes: type can be integer or floating point value 224 225 Level: beginner 226 227 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 228 229 M*/ 230 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 231 232 /*MC 233 PetscAbsInt - Returns the absolute value of an integer 234 235 Synopsis: 236 int abs PetscAbsInt(int v1) 237 238 Not Collective 239 240 Input Parameter: 241 . v1 - the integer 242 243 Level: beginner 244 245 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 246 247 M*/ 248 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 249 250 /*MC 251 PetscAbsReal - Returns the absolute value of an real number 252 253 Synopsis: 254 Real abs PetscAbsReal(PetscReal v1) 255 256 Not Collective 257 258 Input Parameter: 259 . v1 - the double 260 261 262 Level: beginner 263 264 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 265 266 M*/ 267 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 268 269 /*MC 270 PetscSqr - Returns the square of a number 271 272 Synopsis: 273 type sqr PetscSqr(type v1) 274 275 Not Collective 276 277 Input Parameter: 278 . v1 - the value 279 280 Notes: type can be integer or floating point value 281 282 Level: beginner 283 284 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 285 286 M*/ 287 #define PetscSqr(a) ((a)*(a)) 288 289 /* ----------------------------------------------------------------------------*/ 290 /* 291 Basic constants 292 */ 293 #if defined(PETSC_USE_REAL___FLOAT128) 294 #define PETSC_PI M_PIq 295 #elif defined(M_PI) 296 #define PETSC_PI M_PI 297 #else 298 #define PETSC_PI 3.14159265358979323846264 299 #endif 300 301 302 #define PETSC_MAX_INT 2147483647 303 #define PETSC_MIN_INT -2147483647 304 305 #if defined(PETSC_USE_REAL_SINGLE) 306 #if defined(MAXFLOAT) 307 # define PETSC_MAX_REAL MAXFLOAT 308 #else 309 # define PETSC_MAX_REAL 1.e30 310 #endif 311 # define PETSC_MIN_REAL -PETSC_MAX_REAL 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_REAL_DOUBLE) 316 # define PETSC_MAX_REAL 1.e300 317 # define PETSC_MIN_REAL -PETSC_MAX_REAL 318 # define PETSC_MACHINE_EPSILON 1.e-14 319 # define PETSC_SQRT_MACHINE_EPSILON 1.e-7 320 # define PETSC_SMALL 1.e-10 321 #elif defined(PETSC_USE_REAL_LONG_DOUBLE) 322 # define PETSC_MAX_REAL 1.e4900L 323 # define PETSC_MIN_REAL -PETSC_MAX_REAL 324 # define PETSC_MACHINE_EPSILON 1.e-18 325 # define PETSC_SQRT_MACHINE_EPSILON 1.e-9 326 # define PETSC_SMALL 1.e-13 327 #elif defined(PETSC_USE_REAL___FLOAT128) 328 # define PETSC_MAX_REAL FLT128_MAX 329 # define PETSC_MIN_REAL -FLT128_MAX 330 # define PETSC_MACHINE_EPSILON FLT128_EPSILON 331 # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078e-17 332 # define PETSC_SMALL 1.e-20 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_USE_REAL___FLOAT128) 357 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 358 return isinfq(PetscAbsScalar(a)) || isnanq(PetscAbsScalar(a)); 359 } 360 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 361 return isinfq(a) || isnanq(a); 362 } 363 #elif defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) && !defined(_GLIBCXX_CMATH) 364 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 365 return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)); 366 } 367 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 368 return isinf(a) || isnan(a); 369 } 370 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN) 371 #if defined(PETSC_HAVE_FLOAT_H) 372 #include "float.h" /* Microsoft Windows defines _finite() in float.h */ 373 #endif 374 #if defined(PETSC_HAVE_IEEEFP_H) 375 #include "ieeefp.h" /* Solaris prototypes these here */ 376 #endif 377 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 378 return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)); 379 } 380 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 381 return !_finite(a) || _isnan(a); 382 } 383 #else 384 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 385 return ((a - a) != 0.0); 386 } 387 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 388 return ((a - a) != 0.0); 389 } 390 #endif 391 392 393 /* ----------------------------------------------------------------------------*/ 394 /* 395 PetscLogDouble variables are used to contain double precision numbers 396 that are not used in the numerical computations, but rather in logging, 397 timing etc. 398 */ 399 typedef double PetscLogDouble; 400 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE 401 402 #define PassiveReal PetscReal 403 #define PassiveScalar PetscScalar 404 405 /* 406 These macros are currently hardwired to match the regular data types, so there is no support for a different 407 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 408 */ 409 #define MPIU_MATSCALAR MPIU_SCALAR 410 typedef PetscScalar MatScalar; 411 typedef PetscReal MatReal; 412 413 414 PETSC_EXTERN_CXX_END 415 #endif 416