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 #elif defined(PETSC_USE_REAL_DOUBLE) 152 typedef complexlib::complex<double> PetscComplex; 153 #elif defined(PETSC_USE_REAL___FLOAT128) 154 typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */ 155 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128; 156 #endif /* PETSC_USE_REAL_ */ 157 #endif /* ! PETSC_SKIP_COMPLEX */ 158 159 #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) 160 #if !defined(PETSC_SKIP_COMPLEX) 161 #define PETSC_HAVE_COMPLEX 1 162 #include <complex.h> 163 164 #if defined(PETSC_USE_REAL_SINGLE) 165 typedef float _Complex PetscComplex; 166 167 #define PetscRealPartComplex(a) crealf(a) 168 #define PetscImaginaryPartComplex(a) cimagf(a) 169 #define PetscAbsComplex(a) cabsf(a) 170 #define PetscConjComplex(a) conjf(a) 171 #define PetscSqrtComplex(a) csqrtf(a) 172 #define PetscPowComplex(a,b) cpowf(a,b) 173 #define PetscExpComplex(a) cexpf(a) 174 #define PetscLogComplex(a) clogf(a) 175 #define PetscSinComplex(a) csinf(a) 176 #define PetscCosComplex(a) ccosf(a) 177 #define PetscAsinComplex(a) casinf(a) 178 #define PetscAcosComplex(a) cacosf(a) 179 #define PetscTanComplex(a) ctanf(a) 180 #define PetscSinhComplex(a) csinhf(a) 181 #define PetscCoshComplex(a) ccoshf(a) 182 #define PetscTanhComplex(a) ctanhf(a) 183 184 #elif defined(PETSC_USE_REAL_DOUBLE) 185 typedef double _Complex PetscComplex; 186 187 #define PetscRealPartComplex(a) creal(a) 188 #define PetscImaginaryPartComplex(a) cimag(a) 189 #define PetscAbsComplex(a) cabs(a) 190 #define PetscConjComplex(a) conj(a) 191 #define PetscSqrtComplex(a) csqrt(a) 192 #define PetscPowComplex(a,b) cpow(a,b) 193 #define PetscExpComplex(a) cexp(a) 194 #define PetscLogComplex(a) clog(a) 195 #define PetscSinComplex(a) csin(a) 196 #define PetscCosComplex(a) ccos(a) 197 #define PetscAsinComplex(a) casin(a) 198 #define PetscAcosComplex(a) cacos(a) 199 #define PetscTanComplex(a) ctan(a) 200 #define PetscSinhComplex(a) csinh(a) 201 #define PetscCoshComplex(a) ccosh(a) 202 #define PetscTanhComplex(a) ctanh(a) 203 204 #elif defined(PETSC_USE_REAL___FLOAT128) 205 typedef __complex128 PetscComplex; 206 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128); 207 208 #define PetscRealPartComplex(a) crealq(a) 209 #define PetscImaginaryPartComplex(a) cimagq(a) 210 #define PetscAbsComplex(a) cabsq(a) 211 #define PetscConjComplex(a) conjq(a) 212 #define PetscSqrtComplex(a) csqrtq(a) 213 #define PetscPowComplex(a,b) cpowq(a,b) 214 #define PetscExpComplex(a) cexpq(a) 215 #define PetscLogComplex(a) clogq(a) 216 #define PetscSinComplex(a) csinq(a) 217 #define PetscCosComplex(a) ccosq(a) 218 #define PetscAsinComplex(a) casinq(a) 219 #define PetscAcosComplex(a) cacosq(a) 220 #define PetscTanComplex(a) ctanq(a) 221 #define PetscSinhComplex(a) csinhq(a) 222 #define PetscCoshComplex(a) ccoshq(a) 223 #define PetscTanhComplex(a) ctanhq(a) 224 225 #endif /* PETSC_USE_REAL_* */ 226 #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 227 #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available" 228 #endif /* !PETSC_SKIP_COMPLEX */ 229 #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */ 230 231 #if defined(PETSC_HAVE_COMPLEX) 232 #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 233 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX 234 #define MPIU_C_COMPLEX MPI_C_COMPLEX 235 #else 236 # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) 237 typedef complexlib::complex<double> petsc_mpiu_c_double_complex; 238 typedef complexlib::complex<float> petsc_mpiu_c_complex; 239 # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) 240 typedef double _Complex petsc_mpiu_c_double_complex; 241 typedef float _Complex petsc_mpiu_c_complex; 242 # else 243 typedef struct {double real,imag;} petsc_mpiu_c_double_complex; 244 typedef struct {float real,imag;} petsc_mpiu_c_complex; 245 # endif 246 PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex); 247 PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex); 248 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */ 249 #endif /* PETSC_HAVE_COMPLEX */ 250 251 #if defined(PETSC_HAVE_COMPLEX) 252 # if defined(PETSC_USE_REAL_SINGLE) 253 # define MPIU_COMPLEX MPIU_C_COMPLEX 254 # elif defined(PETSC_USE_REAL_DOUBLE) 255 # define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX 256 # elif defined(PETSC_USE_REAL___FLOAT128) 257 # define MPIU_COMPLEX MPIU___COMPLEX128 258 # endif /* PETSC_USE_REAL_* */ 259 #endif 260 261 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 262 typedef PetscComplex PetscScalar; 263 #define PetscRealPart(a) PetscRealPartComplex(a) 264 #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a) 265 #define PetscAbsScalar(a) PetscAbsComplex(a) 266 #define PetscConj(a) PetscConjComplex(a) 267 #define PetscSqrtScalar(a) PetscSqrtComplex(a) 268 #define PetscPowScalar(a,b) PetscPowComplex(a,b) 269 #define PetscExpScalar(a) PetscExpComplex(a) 270 #define PetscLogScalar(a) PetscLogComplex(a) 271 #define PetscSinScalar(a) PetscSinComplex(a) 272 #define PetscCosScalar(a) PetscCosComplex(a) 273 #define PetscAsinScalar(a) PetscAsinComplex(a) 274 #define PetscAcosScalar(a) PetscAcosComplex(a) 275 #define PetscTanScalar(a) PetscTanComplex(a) 276 #define PetscSinhScalar(a) PetscSinhComplex(a) 277 #define PetscCoshScalar(a) PetscCoshComplex(a) 278 #define PetscTanhScalar(a) PetscTanhComplex(a) 279 #define MPIU_SCALAR MPIU_COMPLEX 280 281 /* 282 real number definitions 283 */ 284 #else /* PETSC_USE_COMPLEX */ 285 typedef PetscReal PetscScalar; 286 #define MPIU_SCALAR MPIU_REAL 287 288 #define PetscRealPart(a) (a) 289 #define PetscImaginaryPart(a) ((PetscReal)0.) 290 PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;} 291 #define PetscConj(a) (a) 292 #if !defined(PETSC_USE_REAL___FLOAT128) 293 #define PetscSqrtScalar(a) sqrt(a) 294 #define PetscPowScalar(a,b) pow(a,b) 295 #define PetscExpScalar(a) exp(a) 296 #define PetscLogScalar(a) log(a) 297 #define PetscSinScalar(a) sin(a) 298 #define PetscCosScalar(a) cos(a) 299 #define PetscAsinScalar(a) asin(a) 300 #define PetscAcosScalar(a) acos(a) 301 #define PetscTanScalar(a) tan(a) 302 #define PetscSinhScalar(a) sinh(a) 303 #define PetscCoshScalar(a) cosh(a) 304 #define PetscTanhScalar(a) tanh(a) 305 #else /* PETSC_USE_REAL___FLOAT128 */ 306 #define PetscSqrtScalar(a) sqrtq(a) 307 #define PetscPowScalar(a,b) powq(a,b) 308 #define PetscExpScalar(a) expq(a) 309 #define PetscLogScalar(a) logq(a) 310 #define PetscSinScalar(a) sinq(a) 311 #define PetscCosScalar(a) cosq(a) 312 #define PetscAsinScalar(a) asinq(a) 313 #define PetscAcosScalar(a) acosq(a) 314 #define PetscTanScalar(a) tanq(a) 315 #define PetscSinhScalar(a) sinhq(a) 316 #define PetscCoshScalar(a) coshq(a) 317 #define PetscTanhScalar(a) tanhq(a) 318 #endif /* PETSC_USE_REAL___FLOAT128 */ 319 320 #endif /* PETSC_USE_COMPLEX */ 321 322 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 323 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 324 325 /* --------------------------------------------------------------------------*/ 326 327 /* 328 Certain objects may be created using either single or double precision. 329 This is currently not used. 330 */ 331 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; 332 333 #if defined(PETSC_HAVE_COMPLEX) 334 /* PETSC_i is the imaginary number, i */ 335 PETSC_EXTERN PetscComplex PETSC_i; 336 #endif 337 338 /*MC 339 PetscMin - Returns minimum of two numbers 340 341 Synopsis: 342 #include <petscmath.h> 343 type PetscMin(type v1,type v2) 344 345 Not Collective 346 347 Input Parameter: 348 + v1 - first value to find minimum of 349 - v2 - second value to find minimum of 350 351 Notes: type can be integer or floating point value 352 353 Level: beginner 354 355 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 356 357 M*/ 358 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 359 360 /*MC 361 PetscMax - Returns maxium of two numbers 362 363 Synopsis: 364 #include <petscmath.h> 365 type max PetscMax(type v1,type v2) 366 367 Not Collective 368 369 Input Parameter: 370 + v1 - first value to find maximum of 371 - v2 - second value to find maximum of 372 373 Notes: type can be integer or floating point value 374 375 Level: beginner 376 377 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 378 379 M*/ 380 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 381 382 /*MC 383 PetscClipInterval - Returns a number clipped to be within an interval 384 385 Synopsis: 386 #include <petscmath.h> 387 type clip PetscClipInterval(type x,type a,type b) 388 389 Not Collective 390 391 Input Parameter: 392 + x - value to use if within interval (a,b) 393 . a - lower end of interval 394 - b - upper end of interval 395 396 Notes: type can be integer or floating point value 397 398 Level: beginner 399 400 .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 401 402 M*/ 403 #define PetscClipInterval(x,a,b) (PetscMax((a),PetscMin((x),(b)))) 404 405 /*MC 406 PetscAbsInt - Returns the absolute value of an integer 407 408 Synopsis: 409 #include <petscmath.h> 410 int abs PetscAbsInt(int v1) 411 412 Not Collective 413 414 Input Parameter: 415 . v1 - the integer 416 417 Level: beginner 418 419 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 420 421 M*/ 422 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 423 424 /*MC 425 PetscAbsReal - Returns the absolute value of an real number 426 427 Synopsis: 428 #include <petscmath.h> 429 Real abs PetscAbsReal(PetscReal v1) 430 431 Not Collective 432 433 Input Parameter: 434 . v1 - the double 435 436 437 Level: beginner 438 439 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 440 441 M*/ 442 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 443 444 /*MC 445 PetscSqr - Returns the square of a number 446 447 Synopsis: 448 #include <petscmath.h> 449 type sqr PetscSqr(type v1) 450 451 Not Collective 452 453 Input Parameter: 454 . v1 - the value 455 456 Notes: type can be integer or floating point value 457 458 Level: beginner 459 460 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 461 462 M*/ 463 #define PetscSqr(a) ((a)*(a)) 464 465 /* ----------------------------------------------------------------------------*/ 466 /* 467 Basic constants 468 */ 469 #if defined(PETSC_USE_REAL___FLOAT128) 470 #define PETSC_PI M_PIq 471 #elif defined(M_PI) 472 #define PETSC_PI M_PI 473 #else 474 #define PETSC_PI 3.14159265358979323846264338327950288419716939937510582 475 #endif 476 477 #if !defined(PETSC_USE_64BIT_INDICES) 478 #define PETSC_MAX_INT 2147483647 479 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 480 #else 481 #define PETSC_MAX_INT 9223372036854775807L 482 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 483 #endif 484 485 #if defined(PETSC_USE_REAL_SINGLE) 486 # define PETSC_MAX_REAL 3.40282346638528860e+38F 487 # define PETSC_MIN_REAL -PETSC_MAX_REAL 488 # define PETSC_MACHINE_EPSILON 1.19209290e-07F 489 # define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F 490 # define PETSC_SMALL 1.e-5 491 #elif defined(PETSC_USE_REAL_DOUBLE) 492 # define PETSC_MAX_REAL 1.7976931348623157e+308 493 # define PETSC_MIN_REAL -PETSC_MAX_REAL 494 # define PETSC_MACHINE_EPSILON 2.2204460492503131e-16 495 # define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08 496 # define PETSC_SMALL 1.e-10 497 #elif defined(PETSC_USE_REAL___FLOAT128) 498 # define PETSC_MAX_REAL FLT128_MAX 499 # define PETSC_MIN_REAL -FLT128_MAX 500 # define PETSC_MACHINE_EPSILON FLT128_EPSILON 501 # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078e-17q 502 # define PETSC_SMALL 1.e-20q 503 #endif 504 505 #define PETSC_INFINITY PETSC_MAX_REAL/4.0 506 #define PETSC_NINFINITY -PETSC_INFINITY 507 508 PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal); 509 PETSC_EXTERN PetscErrorCode PetscIsNanReal(PetscReal); 510 PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal); 511 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));} 512 PETSC_STATIC_INLINE PetscErrorCode PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));} 513 PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));} 514 515 /* 516 These macros are currently hardwired to match the regular data types, so there is no support for a different 517 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 518 */ 519 #define MPIU_MATSCALAR MPIU_SCALAR 520 typedef PetscScalar MatScalar; 521 typedef PetscReal MatReal; 522 523 struct petsc_mpiu_2scalar {PetscScalar a,b;}; 524 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar); 525 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT) 526 struct petsc_mpiu_2int {PetscInt a,b;}; 527 PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int); 528 #else 529 #define MPIU_2INT MPI_2INT 530 #endif 531 532 PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power) 533 { 534 PetscInt result = 1; 535 while (power) { 536 if (power & 1) result *= base; 537 power >>= 1; 538 base *= base; 539 } 540 return result; 541 } 542 543 PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power) 544 { 545 PetscReal result = 1; 546 if (power < 0) { 547 power = -power; 548 if (base != (PetscReal)0.0) base = ((PetscReal)1.)/base; 549 } 550 while (power) { 551 if (power & 1) result *= base; 552 power >>= 1; 553 base *= base; 554 } 555 return result; 556 } 557 558 PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power) 559 { 560 PetscScalar result = 1; 561 if (power < 0) { 562 power = -power; 563 if (base != (PetscScalar)0.0) base = ((PetscScalar)1.)/base; 564 } 565 while (power) { 566 if (power & 1) result *= base; 567 power >>= 1; 568 base *= base; 569 } 570 return result; 571 } 572 573 PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power) 574 { 575 PetscScalar cpower = power; 576 return PetscPowScalar(base,cpower); 577 } 578 579 #ifndef PETSC_HAVE_LOG2 580 PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n) 581 { 582 return PetscLogReal(n)/PetscLogReal(2.0); 583 } 584 #endif 585 #endif 586