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