1 /* 2 3 PETSc mathematics include file. Defines certain basic mathematical 4 constants and functions for working with single, double, and quad precision 5 floating point numbers as well as complex single and double. 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 15 /* 16 17 Defines operations that are different for complex and real numbers; 18 note that one cannot mix the use of complex and real in the same 19 PETSc program. All PETSc objects in one program are built around the object 20 PetscScalar which is either always a real or a complex. 21 22 */ 23 24 #if defined(PETSC_USE_REAL_SINGLE) 25 #define MPIU_REAL MPI_FLOAT 26 typedef float PetscReal; 27 #define PetscSqrtReal(a) sqrt(a) 28 #define PetscExpReal(a) exp(a) 29 #define PetscLogReal(a) log(a) 30 #define PetscLog10Real(a) log10(a) 31 #ifdef PETSC_HAVE_LOG2 32 #define PetscLog2Real(a) log2(a) 33 #endif 34 #define PetscSinReal(a) sin(a) 35 #define PetscCosReal(a) cos(a) 36 #define PetscTanReal(a) tan(a) 37 #define PetscAsinReal(a) asin(a) 38 #define PetscAcosReal(a) acos(a) 39 #define PetscAtanReal(a) atan(a) 40 #define PetscAtan2Real(a,b) atan2(a,b) 41 #define PetscSinhReal(a) sinh(a) 42 #define PetscCoshReal(a) cosh(a) 43 #define PetscTanhReal(a) tanh(a) 44 #define PetscPowReal(a,b) pow(a,b) 45 #define PetscCeilReal(a) ceil(a) 46 #define PetscFloorReal(a) floor(a) 47 #define PetscFmodReal(a,b) fmod(a,b) 48 #define PetscTGamma(a) tgammaf(a) 49 #elif defined(PETSC_USE_REAL_DOUBLE) 50 #define MPIU_REAL MPI_DOUBLE 51 typedef double PetscReal; 52 #define PetscSqrtReal(a) sqrt(a) 53 #define PetscExpReal(a) exp(a) 54 #define PetscLogReal(a) log(a) 55 #define PetscLog10Real(a) log10(a) 56 #ifdef PETSC_HAVE_LOG2 57 #define PetscLog2Real(a) log2(a) 58 #endif 59 #define PetscSinReal(a) sin(a) 60 #define PetscCosReal(a) cos(a) 61 #define PetscTanReal(a) tan(a) 62 #define PetscAsinReal(a) asin(a) 63 #define PetscAcosReal(a) acos(a) 64 #define PetscAtanReal(a) atan(a) 65 #define PetscAtan2Real(a,b) atan2(a,b) 66 #define PetscSinhReal(a) sinh(a) 67 #define PetscCoshReal(a) cosh(a) 68 #define PetscTanhReal(a) tanh(a) 69 #define PetscPowReal(a,b) pow(a,b) 70 #define PetscCeilReal(a) ceil(a) 71 #define PetscFloorReal(a) floor(a) 72 #define PetscFmodReal(a,b) fmod(a,b) 73 #define PetscTGamma(a) tgamma(a) 74 #elif defined(PETSC_USE_REAL___FLOAT128) 75 #if defined(__cplusplus) 76 extern "C" { 77 #endif 78 #include <quadmath.h> 79 #if defined(__cplusplus) 80 } 81 #endif 82 PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128); 83 #define MPIU_REAL MPIU___FLOAT128 84 typedef __float128 PetscReal; 85 #define PetscSqrtReal(a) sqrtq(a) 86 #define PetscExpReal(a) expq(a) 87 #define PetscLogReal(a) logq(a) 88 #define PetscLog10Real(a) log10q(a) 89 #ifdef PETSC_HAVE_LOG2 90 #define PetscLog2Real(a) log2q(a) 91 #endif 92 #define PetscSinReal(a) sinq(a) 93 #define PetscCosReal(a) cosq(a) 94 #define PetscTanReal(a) tanq(a) 95 #define PetscAsinReal(a) asinq(a) 96 #define PetscAcosReal(a) acosq(a) 97 #define PetscAtanReal(a) atanq(a) 98 #define PetscAtan2Real(a,b) atan2q(a,b) 99 #define PetscSinhReal(a) sinhq(a) 100 #define PetscCoshReal(a) coshq(a) 101 #define PetscTanhReal(a) tanhq(a) 102 #define PetscPowReal(a,b) powq(a,b) 103 #define PetscCeilReal(a) ceilq(a) 104 #define PetscFloorReal(a) floorq(a) 105 #define PetscFmodReal(a,b) fmodq(a,b) 106 #define PetscTGamma(a) tgammaq(a) 107 #endif /* PETSC_USE_REAL_* */ 108 109 /* 110 Complex number definitions 111 */ 112 #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128) 113 #if !defined(PETSC_SKIP_COMPLEX) 114 #define PETSC_HAVE_COMPLEX 1 115 /* C++ support of complex number */ 116 #if defined(PETSC_HAVE_CUSP) 117 #define complexlib cusp 118 #include <cusp/complex.h> 119 #else 120 #define complexlib std 121 #include <complex> 122 #endif 123 124 #define PetscRealPartComplex(a) (a).real() 125 #define PetscImaginaryPartComplex(a) (a).imag() 126 #define PetscAbsComplex(a) complexlib::abs(a) 127 #define PetscConjComplex(a) complexlib::conj(a) 128 #define PetscSqrtComplex(a) complexlib::sqrt(a) 129 #define PetscPowComplex(a,b) complexlib::pow(a,b) 130 #define PetscExpComplex(a) complexlib::exp(a) 131 #define PetscLogComplex(a) complexlib::log(a) 132 #define PetscSinComplex(a) complexlib::sin(a) 133 #define PetscCosComplex(a) complexlib::cos(a) 134 #define PetscAsinComplex(a) complexlib::asin(a) 135 #define PetscAcosComplex(a) complexlib::acos(a) 136 #if defined(PETSC_HAVE_TANCOMPLEX) 137 #define PetscTanComplex(a) complexlib::tan(a) 138 #else 139 #define PetscTanComplex(a) PetscSinComplex(a)/PetscCosComplex(a) 140 #endif 141 #define PetscSinhComplex(a) complexlib::sinh(a) 142 #define PetscCoshComplex(a) complexlib::cosh(a) 143 #if defined(PETSC_HAVE_TANHCOMPLEX) 144 #define PetscTanhComplex(a) complexlib::tanh(a) 145 #else 146 #define PetscTanhComplex(a) PetscSinhComplex(a)/PetscCoshComplex(a) 147 #endif 148 149 #if defined(PETSC_USE_REAL_SINGLE) 150 typedef complexlib::complex<float> PetscComplex; 151 #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND) 152 static inline PetscComplex operator+(const PetscComplex& lhs, const double& rhs) { return lhs + float(rhs); } 153 static inline PetscComplex operator+(const double& lhs, const PetscComplex& rhs) { return float(lhs) + rhs; } 154 static inline PetscComplex operator-(const PetscComplex& lhs, const double& rhs) { return lhs - float(rhs); } 155 static inline PetscComplex operator-(const double& lhs, const PetscComplex& rhs) { return float(lhs) - rhs; } 156 static inline PetscComplex operator*(const PetscComplex& lhs, const double& rhs) { return lhs * float(rhs); } 157 static inline PetscComplex operator*(const double& lhs, const PetscComplex& rhs) { return float(lhs) * rhs; } 158 static inline PetscComplex operator/(const PetscComplex& lhs, const double& rhs) { return lhs / float(rhs); } 159 static inline PetscComplex operator/(const double& lhs, const PetscComplex& rhs) { return float(lhs) / rhs; } 160 static inline bool operator==(const PetscComplex& lhs, const double& rhs) { return lhs.imag() == float(0) && lhs.real() == float(rhs); } 161 static inline bool operator==(const double& lhs, const PetscComplex& rhs) { return rhs.imag() == float(0) && rhs.real() == float(lhs); } 162 static inline bool operator!=(const PetscComplex& lhs, const double& rhs) { return lhs.imag() != float(0) || lhs.real() != float(rhs); } 163 static inline bool operator!=(const double& lhs, const PetscComplex& rhs) { return rhs.imag() != float(0) || rhs.real() != float(lhs); } 164 #endif /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */ 165 #elif defined(PETSC_USE_REAL_DOUBLE) 166 typedef complexlib::complex<double> PetscComplex; 167 #elif defined(PETSC_USE_REAL___FLOAT128) 168 typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */ 169 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128; 170 #endif /* PETSC_USE_REAL_ */ 171 #endif /* ! PETSC_SKIP_COMPLEX */ 172 173 #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) 174 #if !defined(PETSC_SKIP_COMPLEX) 175 #define PETSC_HAVE_COMPLEX 1 176 #include <complex.h> 177 178 #if defined(PETSC_USE_REAL_SINGLE) 179 typedef float _Complex PetscComplex; 180 181 #define PetscRealPartComplex(a) crealf(a) 182 #define PetscImaginaryPartComplex(a) cimagf(a) 183 #define PetscAbsComplex(a) cabsf(a) 184 #define PetscConjComplex(a) conjf(a) 185 #define PetscSqrtComplex(a) csqrtf(a) 186 #define PetscPowComplex(a,b) cpowf(a,b) 187 #define PetscExpComplex(a) cexpf(a) 188 #define PetscLogComplex(a) clogf(a) 189 #define PetscSinComplex(a) csinf(a) 190 #define PetscCosComplex(a) ccosf(a) 191 #define PetscAsinComplex(a) casinf(a) 192 #define PetscAcosComplex(a) cacosf(a) 193 #define PetscTanComplex(a) ctanf(a) 194 #define PetscSinhComplex(a) csinhf(a) 195 #define PetscCoshComplex(a) ccoshf(a) 196 #define PetscTanhComplex(a) ctanhf(a) 197 198 #elif defined(PETSC_USE_REAL_DOUBLE) 199 typedef double _Complex PetscComplex; 200 201 #define PetscRealPartComplex(a) creal(a) 202 #define PetscImaginaryPartComplex(a) cimag(a) 203 #define PetscAbsComplex(a) cabs(a) 204 #define PetscConjComplex(a) conj(a) 205 #define PetscSqrtComplex(a) csqrt(a) 206 #define PetscPowComplex(a,b) cpow(a,b) 207 #define PetscExpComplex(a) cexp(a) 208 #define PetscLogComplex(a) clog(a) 209 #define PetscSinComplex(a) csin(a) 210 #define PetscCosComplex(a) ccos(a) 211 #define PetscAsinComplex(a) casin(a) 212 #define PetscAcosComplex(a) cacos(a) 213 #define PetscTanComplex(a) ctan(a) 214 #define PetscSinhComplex(a) csinh(a) 215 #define PetscCoshComplex(a) ccosh(a) 216 #define PetscTanhComplex(a) ctanh(a) 217 218 #elif defined(PETSC_USE_REAL___FLOAT128) 219 typedef __complex128 PetscComplex; 220 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128); 221 222 #define PetscRealPartComplex(a) crealq(a) 223 #define PetscImaginaryPartComplex(a) cimagq(a) 224 #define PetscAbsComplex(a) cabsq(a) 225 #define PetscConjComplex(a) conjq(a) 226 #define PetscSqrtComplex(a) csqrtq(a) 227 #define PetscPowComplex(a,b) cpowq(a,b) 228 #define PetscExpComplex(a) cexpq(a) 229 #define PetscLogComplex(a) clogq(a) 230 #define PetscSinComplex(a) csinq(a) 231 #define PetscCosComplex(a) ccosq(a) 232 #define PetscAsinComplex(a) casinq(a) 233 #define PetscAcosComplex(a) cacosq(a) 234 #define PetscTanComplex(a) ctanq(a) 235 #define PetscSinhComplex(a) csinhq(a) 236 #define PetscCoshComplex(a) ccoshq(a) 237 #define PetscTanhComplex(a) ctanhq(a) 238 239 #endif /* PETSC_USE_REAL_* */ 240 #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 241 #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available" 242 #endif /* !PETSC_SKIP_COMPLEX */ 243 #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */ 244 245 #if defined(PETSC_HAVE_COMPLEX) 246 #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 247 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX 248 #define MPIU_C_COMPLEX MPI_C_COMPLEX 249 #else 250 # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) 251 typedef complexlib::complex<double> petsc_mpiu_c_double_complex; 252 typedef complexlib::complex<float> petsc_mpiu_c_complex; 253 # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) 254 typedef double _Complex petsc_mpiu_c_double_complex; 255 typedef float _Complex petsc_mpiu_c_complex; 256 # else 257 typedef struct {double real,imag;} petsc_mpiu_c_double_complex; 258 typedef struct {float real,imag;} petsc_mpiu_c_complex; 259 # endif 260 PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex); 261 PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex); 262 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */ 263 #endif /* PETSC_HAVE_COMPLEX */ 264 265 #if defined(PETSC_HAVE_COMPLEX) 266 # if defined(PETSC_USE_REAL_SINGLE) 267 # define MPIU_COMPLEX MPIU_C_COMPLEX 268 # elif defined(PETSC_USE_REAL_DOUBLE) 269 # define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX 270 # elif defined(PETSC_USE_REAL___FLOAT128) 271 # define MPIU_COMPLEX MPIU___COMPLEX128 272 # endif /* PETSC_USE_REAL_* */ 273 #endif 274 275 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 276 typedef PetscComplex PetscScalar; 277 #define PetscRealPart(a) PetscRealPartComplex(a) 278 #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a) 279 #define PetscAbsScalar(a) PetscAbsComplex(a) 280 #define PetscConj(a) PetscConjComplex(a) 281 #define PetscSqrtScalar(a) PetscSqrtComplex(a) 282 #define PetscPowScalar(a,b) PetscPowComplex(a,b) 283 #define PetscExpScalar(a) PetscExpComplex(a) 284 #define PetscLogScalar(a) PetscLogComplex(a) 285 #define PetscSinScalar(a) PetscSinComplex(a) 286 #define PetscCosScalar(a) PetscCosComplex(a) 287 #define PetscAsinScalar(a) PetscAsinComplex(a) 288 #define PetscAcosScalar(a) PetscAcosComplex(a) 289 #define PetscTanScalar(a) PetscTanComplex(a) 290 #define PetscSinhScalar(a) PetscSinhComplex(a) 291 #define PetscCoshScalar(a) PetscCoshComplex(a) 292 #define PetscTanhScalar(a) PetscTanhComplex(a) 293 #define MPIU_SCALAR MPIU_COMPLEX 294 295 /* 296 real number definitions 297 */ 298 #else /* PETSC_USE_COMPLEX */ 299 typedef PetscReal PetscScalar; 300 #define MPIU_SCALAR MPIU_REAL 301 302 #define PetscRealPart(a) (a) 303 #define PetscImaginaryPart(a) ((PetscReal)0.) 304 PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;} 305 #define PetscConj(a) (a) 306 #if !defined(PETSC_USE_REAL___FLOAT128) 307 #define PetscSqrtScalar(a) sqrt(a) 308 #define PetscPowScalar(a,b) pow(a,b) 309 #define PetscExpScalar(a) exp(a) 310 #define PetscLogScalar(a) log(a) 311 #define PetscSinScalar(a) sin(a) 312 #define PetscCosScalar(a) cos(a) 313 #define PetscAsinScalar(a) asin(a) 314 #define PetscAcosScalar(a) acos(a) 315 #define PetscTanScalar(a) tan(a) 316 #define PetscSinhScalar(a) sinh(a) 317 #define PetscCoshScalar(a) cosh(a) 318 #define PetscTanhScalar(a) tanh(a) 319 #else /* PETSC_USE_REAL___FLOAT128 */ 320 #define PetscSqrtScalar(a) sqrtq(a) 321 #define PetscPowScalar(a,b) powq(a,b) 322 #define PetscExpScalar(a) expq(a) 323 #define PetscLogScalar(a) logq(a) 324 #define PetscSinScalar(a) sinq(a) 325 #define PetscCosScalar(a) cosq(a) 326 #define PetscAsinScalar(a) asinq(a) 327 #define PetscAcosScalar(a) acosq(a) 328 #define PetscTanScalar(a) tanq(a) 329 #define PetscSinhScalar(a) sinhq(a) 330 #define PetscCoshScalar(a) coshq(a) 331 #define PetscTanhScalar(a) tanhq(a) 332 #endif /* PETSC_USE_REAL___FLOAT128 */ 333 334 #endif /* PETSC_USE_COMPLEX */ 335 336 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 337 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 338 339 /* --------------------------------------------------------------------------*/ 340 341 /* 342 Certain objects may be created using either single or double precision. 343 This is currently not used. 344 */ 345 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; 346 347 #if defined(PETSC_HAVE_COMPLEX) 348 /* PETSC_i is the imaginary number, i */ 349 PETSC_EXTERN PetscComplex PETSC_i; 350 #endif 351 352 /*MC 353 PetscMin - Returns minimum of two numbers 354 355 Synopsis: 356 #include <petscmath.h> 357 type PetscMin(type v1,type v2) 358 359 Not Collective 360 361 Input Parameter: 362 + v1 - first value to find minimum of 363 - v2 - second value to find minimum of 364 365 Notes: type can be integer or floating point value 366 367 Level: beginner 368 369 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 370 371 M*/ 372 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 373 374 /*MC 375 PetscMax - Returns maxium of two numbers 376 377 Synopsis: 378 #include <petscmath.h> 379 type max PetscMax(type v1,type v2) 380 381 Not Collective 382 383 Input Parameter: 384 + v1 - first value to find maximum of 385 - v2 - second value to find maximum of 386 387 Notes: type can be integer or floating point value 388 389 Level: beginner 390 391 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 392 393 M*/ 394 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 395 396 /*MC 397 PetscClipInterval - Returns a number clipped to be within an interval 398 399 Synopsis: 400 #include <petscmath.h> 401 type clip PetscClipInterval(type x,type a,type b) 402 403 Not Collective 404 405 Input Parameter: 406 + x - value to use if within interval (a,b) 407 . a - lower end of interval 408 - b - upper end of interval 409 410 Notes: type can be integer or floating point value 411 412 Level: beginner 413 414 .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 415 416 M*/ 417 #define PetscClipInterval(x,a,b) (PetscMax((a),PetscMin((x),(b)))) 418 419 /*MC 420 PetscAbsInt - Returns the absolute value of an integer 421 422 Synopsis: 423 #include <petscmath.h> 424 int abs PetscAbsInt(int v1) 425 426 Not Collective 427 428 Input Parameter: 429 . v1 - the integer 430 431 Level: beginner 432 433 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 434 435 M*/ 436 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 437 438 /*MC 439 PetscAbsReal - Returns the absolute value of an real number 440 441 Synopsis: 442 #include <petscmath.h> 443 Real abs PetscAbsReal(PetscReal v1) 444 445 Not Collective 446 447 Input Parameter: 448 . v1 - the double 449 450 451 Level: beginner 452 453 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 454 455 M*/ 456 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 457 458 /*MC 459 PetscSqr - Returns the square of a number 460 461 Synopsis: 462 #include <petscmath.h> 463 type sqr PetscSqr(type v1) 464 465 Not Collective 466 467 Input Parameter: 468 . v1 - the value 469 470 Notes: type can be integer or floating point value 471 472 Level: beginner 473 474 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 475 476 M*/ 477 #define PetscSqr(a) ((a)*(a)) 478 479 /* ----------------------------------------------------------------------------*/ 480 /* 481 Basic constants 482 */ 483 #if defined(PETSC_USE_REAL___FLOAT128) 484 #define PETSC_PI M_PIq 485 #elif defined(M_PI) 486 #define PETSC_PI M_PI 487 #else 488 #define PETSC_PI 3.14159265358979323846264338327950288419716939937510582 489 #endif 490 491 #if !defined(PETSC_USE_64BIT_INDICES) 492 #define PETSC_MAX_INT 2147483647 493 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 494 #else 495 #define PETSC_MAX_INT 9223372036854775807L 496 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 497 #endif 498 499 #if defined(PETSC_USE_REAL_SINGLE) 500 # define PETSC_MAX_REAL 3.40282346638528860e+38F 501 # define PETSC_MIN_REAL -PETSC_MAX_REAL 502 # define PETSC_MACHINE_EPSILON 1.19209290e-07F 503 # define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F 504 # define PETSC_SMALL 1.e-5 505 #elif defined(PETSC_USE_REAL_DOUBLE) 506 # define PETSC_MAX_REAL 1.7976931348623157e+308 507 # define PETSC_MIN_REAL -PETSC_MAX_REAL 508 # define PETSC_MACHINE_EPSILON 2.2204460492503131e-16 509 # define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08 510 # define PETSC_SMALL 1.e-10 511 #elif defined(PETSC_USE_REAL___FLOAT128) 512 # define PETSC_MAX_REAL FLT128_MAX 513 # define PETSC_MIN_REAL -FLT128_MAX 514 # define PETSC_MACHINE_EPSILON FLT128_EPSILON 515 # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078e-17q 516 # define PETSC_SMALL 1.e-20q 517 #endif 518 519 #define PETSC_INFINITY PETSC_MAX_REAL/4.0 520 #define PETSC_NINFINITY -PETSC_INFINITY 521 522 PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal); 523 PETSC_EXTERN PetscErrorCode PetscIsNanReal(PetscReal); 524 PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal); 525 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));} 526 PETSC_STATIC_INLINE PetscErrorCode PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));} 527 PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));} 528 529 /* 530 These macros are currently hardwired to match the regular data types, so there is no support for a different 531 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 532 */ 533 #define MPIU_MATSCALAR MPIU_SCALAR 534 typedef PetscScalar MatScalar; 535 typedef PetscReal MatReal; 536 537 struct petsc_mpiu_2scalar {PetscScalar a,b;}; 538 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar); 539 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT) 540 struct petsc_mpiu_2int {PetscInt a,b;}; 541 PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int); 542 #else 543 #define MPIU_2INT MPI_2INT 544 #endif 545 546 PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power) 547 { 548 PetscInt result = 1; 549 while (power) { 550 if (power & 1) result *= base; 551 power >>= 1; 552 base *= base; 553 } 554 return result; 555 } 556 557 PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power) 558 { 559 PetscReal result = 1; 560 if (power < 0) { 561 power = -power; 562 base = ((PetscReal)1)/base; 563 } 564 while (power) { 565 if (power & 1) result *= base; 566 power >>= 1; 567 base *= base; 568 } 569 return result; 570 } 571 572 PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power) 573 { 574 PetscScalar result = 1; 575 if (power < 0) { 576 power = -power; 577 base = ((PetscReal)1)/base; 578 } 579 while (power) { 580 if (power & 1) result *= base; 581 power >>= 1; 582 base *= base; 583 } 584 return result; 585 } 586 587 PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power) 588 { 589 PetscScalar cpower = power; 590 return PetscPowScalar(base,cpower); 591 } 592 593 #ifndef PETSC_HAVE_LOG2 594 PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n) 595 { 596 return PetscLogReal(n)/PetscLogReal(2.0); 597 } 598 #endif 599 #endif 600