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