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