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