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_SCALAR_SINGLE) 50 typedef std::complex<float> PetscScalar; 51 #elif defined(PETSC_USE_SCALAR_DOUBLE) 52 typedef std::complex<double> PetscScalar; 53 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 54 typedef std::complex<long double> PetscScalar; 55 #endif /* PETSC_USE_SCALAR_* */ 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_SCALAR_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_SCALAR_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_SCALAR_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_SCALAR_* */ 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_SCALAR_SINGLE) 112 #define MPIU_SCALAR MPI_C_COMPLEX 113 #elif defined(PETSC_USE_SCALAR_DOUBLE) 114 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX 115 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 116 #define MPIU_SCALAR error 117 #endif /* PETSC_USE_SCALAR_* */ 118 119 /* 120 real number definitions 121 */ 122 #else /* PETSC_USE_COMPLEX */ 123 #if defined(PETSC_USE_SCALAR_SINGLE) 124 #define MPIU_SCALAR MPI_FLOAT 125 typedef float PetscScalar; 126 #elif defined(PETSC_USE_SCALAR_DOUBLE) 127 #define MPIU_SCALAR MPI_DOUBLE 128 typedef double PetscScalar; 129 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 130 #define MPIU_SCALAR MPI_LONG_DOUBLE 131 typedef long double PetscScalar; 132 #elif defined(PETSC_USE_SCALAR___FLOAT128) 133 extern MPI_Datatype MPIU___FLOAT128; 134 #define MPIU_SCALAR MPIU___FLOAT128 135 typedef __float128 PetscScalar; 136 #endif /* PETSC_USE_SCALAR_* */ 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_SCALAR___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_SCALAR___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_SCALAR___FLOAT128 */ 157 158 #endif /* PETSC_USE_COMPLEX */ 159 160 #if defined(PETSC_USE_SCALAR_SINGLE) 161 #define MPIU_REAL MPI_FLOAT 162 typedef float PetscReal; 163 #elif defined(PETSC_USE_SCALAR_DOUBLE) 164 #define MPIU_REAL MPI_DOUBLE 165 typedef double PetscReal; 166 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 167 #define MPIU_REAL MPI_LONG_DOUBLE 168 typedef long double PetscReal; 169 #elif defined(PETSC_USE_SCALAR___FLOAT128) 170 #define MPIU_REAL MPIU___FLOAT128 171 typedef __float128 PetscReal; 172 #endif /* PETSC_USE_SCALAR_* */ 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 - These should be done much better 292 */ 293 #define PETSC_PI 3.14159265358979323846264 294 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994 295 #define PETSC_MAX_INT 2147483647 296 #define PETSC_MIN_INT -2147483647 297 298 #if defined(PETSC_USE_SCALAR_SINGLE) 299 # define PETSC_MAX 1.e30 300 # define PETSC_MIN -1.e30 301 # define PETSC_MACHINE_EPSILON 1.e-7 302 # define PETSC_SQRT_MACHINE_EPSILON 3.e-4 303 # define PETSC_SMALL 1.e-5 304 #else 305 # define PETSC_MAX 1.e300 306 # define PETSC_MIN -1.e300 307 # define PETSC_MACHINE_EPSILON 1.e-14 308 # define PETSC_SQRT_MACHINE_EPSILON 1.e-7 309 # define PETSC_SMALL 1.e-10 310 #endif 311 312 #if defined PETSC_HAVE_ADIC 313 /* Use MPI_Allreduce when ADIC is not available. */ 314 extern PetscErrorCode PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*); 315 extern PetscErrorCode PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*); 316 extern PetscErrorCode PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*); 317 #endif 318 319 /*MC 320 PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0. 321 322 Input Parameter: 323 . a - the double 324 325 326 Notes: uses the C99 standard isinf() and isnan() on systems where they exist. 327 Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile 328 out this form, thus removing the check. 329 330 Level: beginner 331 332 M*/ 333 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) 334 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 335 return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)); 336 } 337 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 338 return isinf(a) || isnan(a); 339 } 340 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN) 341 #if defined(PETSC_HAVE_FLOAT_H) 342 #include "float.h" /* Microsoft Windows defines _finite() in float.h */ 343 #endif 344 #if defined(PETSC_HAVE_IEEEFP_H) 345 #include "ieeefp.h" /* Solaris prototypes these here */ 346 #endif 347 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 348 return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)); 349 } 350 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 351 return !_finite(a) || _isnan(a); 352 } 353 #else 354 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 355 return ((a - a) != 0.0); 356 } 357 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 358 return ((a - a) != 0.0); 359 } 360 #endif 361 362 363 /* ----------------------------------------------------------------------------*/ 364 /* 365 PetscLogDouble variables are used to contain double precision numbers 366 that are not used in the numerical computations, but rather in logging, 367 timing etc. 368 */ 369 typedef double PetscLogDouble; 370 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE 371 372 #define PassiveReal PetscReal 373 #define PassiveScalar PetscScalar 374 375 /* 376 These macros are currently hardwired to match the regular data types, so there is no support for a different 377 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 378 */ 379 #define MPIU_MATSCALAR MPIU_SCALAR 380 typedef PetscScalar MatScalar; 381 typedef PetscReal MatReal; 382 383 384 PETSC_EXTERN_CXX_END 385 #endif 386