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 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 C90 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 extern MPI_Datatype PETSC_DLLEXPORT MPIU_COMPLEX; 108 #define MPIU_SCALAR MPIU_COMPLEX 109 #if defined(PETSC_USE_SCALAR_MAT_SINGLE) 110 #define MPIU_MATSCALAR ??Notdone 111 #else 112 #define MPIU_MATSCALAR MPIU_COMPLEX 113 #endif 114 115 116 /* Compiling for real numbers only */ 117 #else 118 # if defined(PETSC_USE_SCALAR_SINGLE) 119 # define MPIU_SCALAR MPI_FLOAT 120 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 121 # define MPIU_SCALAR MPI_LONG_DOUBLE 122 # elif defined(PETSC_USE_SCALAR_INT) 123 # define MPIU_SCALAR MPI_INT 124 # elif defined(PETSC_USE_SCALAR_QD_DD) 125 # define MPIU_SCALAR MPIU_QD_DD 126 # else 127 # define MPIU_SCALAR MPI_DOUBLE 128 # endif 129 # if defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE) 130 # define MPIU_MATSCALAR MPI_FLOAT 131 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 132 # define MPIU_MATSCALAR MPI_LONG_DOUBLE 133 # elif defined(PETSC_USE_SCALAR_INT) 134 # define MPIU_MATSCALAR MPI_INT 135 # elif defined(PETSC_USE_SCALAR_QD_DD) 136 # define MPIU_MATSCALAR MPIU_QD_DD 137 # else 138 # define MPIU_MATSCALAR MPI_DOUBLE 139 # endif 140 # define PetscRealPart(a) (a) 141 # define PetscImaginaryPart(a) (0.) 142 # define PetscAbsScalar(a) (((a)<0.0) ? -(a) : (a)) 143 # define PetscConj(a) (a) 144 # define PetscSqrtScalar(a) sqrt(a) 145 # define PetscPowScalar(a,b) pow(a,b) 146 # define PetscExpScalar(a) exp(a) 147 # define PetscLogScalar(a) log(a) 148 # define PetscSinScalar(a) sin(a) 149 # define PetscCosScalar(a) cos(a) 150 151 # if defined(PETSC_USE_SCALAR_SINGLE) 152 typedef float PetscScalar; 153 # elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 154 typedef long double PetscScalar; 155 # elif defined(PETSC_USE_SCALAR_INT) 156 typedef int PetscScalar; 157 # elif defined(PETSC_USE_SCALAR_QD_DD) 158 # include "qd/dd_real.h" 159 typedef dd_real PetscScalar; 160 # else 161 typedef double PetscScalar; 162 # endif 163 #endif 164 165 #if defined(PETSC_USE_SCALAR_SINGLE) 166 # define MPIU_REAL MPI_FLOAT 167 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 168 # define MPIU_REAL MPI_LONG_DOUBLE 169 #elif defined(PETSC_USE_SCALAR_INT) 170 # define MPIU_REAL MPI_INT 171 #elif defined(PETSC_USE_SCALAR_QD_DD) 172 # define MPIU_REAL MPIU_QD_DD 173 #else 174 # define MPIU_REAL MPI_DOUBLE 175 #endif 176 177 #if defined(PETSC_USE_SCALAR_QD_DD) 178 extern MPI_Datatype PETSC_DLLEXPORT MPIU_QD_DD; 179 #endif 180 181 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 182 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 183 /* 184 Allows compiling PETSc so that matrix values are stored in 185 single precision but all other objects still use double 186 precision. This does not work for complex numbers in that case 187 it remains double 188 189 EXPERIMENTAL! NOT YET COMPLETELY WORKING 190 */ 191 192 #if defined(PETSC_USE_SCALAR_MAT_SINGLE) 193 typedef float MatScalar; 194 #else 195 typedef PetscScalar MatScalar; 196 #endif 197 198 #if defined(PETSC_USE_SCALAR_SINGLE) 199 typedef float PetscReal; 200 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 201 typedef long double PetscReal; 202 #elif defined(PETSC_USE_SCALAR_INT) 203 typedef int PetscReal; 204 #elif defined(PETSC_USE_SCALAR_QD_DD) 205 typedef dd_real PetscReal; 206 #else 207 typedef double PetscReal; 208 #endif 209 210 #if defined(PETSC_USE_COMPLEX) 211 typedef PetscReal MatReal; 212 #elif defined(PETSC_USE_SCALAR_MAT_SINGLE) || defined(PETSC_USE_SCALAR_SINGLE) 213 typedef float MatReal; 214 #else 215 typedef PetscReal MatReal; 216 #endif 217 218 219 /* --------------------------------------------------------------------------*/ 220 221 /* 222 Certain objects may be created using either single 223 or double precision. 224 */ 225 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_QD_DD } PetscScalarPrecision; 226 227 /* PETSC_i is the imaginary number, i */ 228 extern PetscScalar PETSC_DLLEXPORT PETSC_i; 229 230 /*MC 231 PetscMin - Returns minimum of two numbers 232 233 Input Parameter: 234 + v1 - first value to find minimum of 235 - v2 - second value to find minimum of 236 237 Synopsis: 238 type PetscMin(type v1,type v2) 239 240 Notes: type can be integer or floating point value 241 242 Level: beginner 243 244 245 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 246 247 M*/ 248 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 249 250 /*MC 251 PetscMax - Returns maxium of two numbers 252 253 Input Parameter: 254 + v1 - first value to find maximum of 255 - v2 - second value to find maximum of 256 257 Synopsis: 258 type max PetscMax(type v1,type v2) 259 260 Notes: type can be integer or floating point value 261 262 Level: beginner 263 264 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 265 266 M*/ 267 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 268 269 /*MC 270 PetscAbsInt - Returns the absolute value of an integer 271 272 Input Parameter: 273 . v1 - the integer 274 275 Synopsis: 276 int abs PetscAbsInt(int v1) 277 278 279 Level: beginner 280 281 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 282 283 M*/ 284 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 285 286 /*MC 287 PetscAbsReal - Returns the absolute value of an real number 288 289 Input Parameter: 290 . v1 - the double 291 292 Synopsis: 293 int abs PetscAbsReal(PetscReal v1) 294 295 296 Level: beginner 297 298 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 299 300 M*/ 301 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 302 303 /*MC 304 PetscSqr - Returns the square of a number 305 306 Input Parameter: 307 . v1 - the value 308 309 Synopsis: 310 type sqr PetscSqr(type v1) 311 312 Notes: type can be integer or floating point value 313 314 Level: beginner 315 316 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 317 318 M*/ 319 #define PetscSqr(a) ((a)*(a)) 320 321 /* ----------------------------------------------------------------------------*/ 322 /* 323 Basic constants - These should be done much better 324 */ 325 #define PETSC_PI 3.14159265358979323846264 326 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994 327 #define PETSC_MAX_INT 2147483647 328 #define PETSC_MIN_INT -2147483647 329 330 #if defined(PETSC_USE_SCALAR_SINGLE) 331 # define PETSC_MAX 1.e30 332 # define PETSC_MIN -1.e30 333 # define PETSC_MACHINE_EPSILON 1.e-7 334 # define PETSC_SQRT_MACHINE_EPSILON 3.e-4 335 # define PETSC_SMALL 1.e-5 336 #elif defined(PETSC_USE_SCALAR_INT) 337 # define PETSC_MAX PETSC_MAX_INT 338 # define PETSC_MIN PETSC_MIN_INT 339 # define PETSC_MACHINE_EPSILON 1 340 # define PETSC_SQRT_MACHINE_EPSILON 1 341 # define PETSC_SMALL 0 342 #elif defined(PETSC_USE_SCALAR_QD_DD) 343 # define PETSC_MAX 1.e300 344 # define PETSC_MIN -1.e300 345 # define PETSC_MACHINE_EPSILON 1.e-30 346 # define PETSC_SQRT_MACHINE_EPSILON 1.e-15 347 # define PETSC_SMALL 1.e-25 348 #else 349 # define PETSC_MAX 1.e300 350 # define PETSC_MIN -1.e300 351 # define PETSC_MACHINE_EPSILON 1.e-14 352 # define PETSC_SQRT_MACHINE_EPSILON 1.e-7 353 # define PETSC_SMALL 1.e-10 354 #endif 355 356 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal*,PetscReal*,MPI_Comm); 357 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal*,PetscReal*,MPI_Comm); 358 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar*,PetscScalar*,MPI_Comm); 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