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 #ifndef PETSCMATH_H 11 #define PETSCMATH_H 12 13 #include <math.h> 14 #include <petscmacros.h> 15 #include <petscsystypes.h> 16 17 /* SUBMANSEC = Sys */ 18 19 /* 20 21 Defines operations that are different for complex and real numbers. 22 All PETSc objects in one program are built around the object 23 PetscScalar which is either always a real or a complex. 24 25 */ 26 27 /* 28 Real number definitions 29 */ 30 #if defined(PETSC_USE_REAL_SINGLE) 31 #define PetscSqrtReal(a) sqrtf(a) 32 #define PetscCbrtReal(a) cbrtf(a) 33 #define PetscHypotReal(a, b) hypotf(a, b) 34 #define PetscAtan2Real(a, b) atan2f(a, b) 35 #define PetscPowReal(a, b) powf(a, b) 36 #define PetscExpReal(a) expf(a) 37 #define PetscLogReal(a) logf(a) 38 #define PetscLog10Real(a) log10f(a) 39 #define PetscLog2Real(a) log2f(a) 40 #define PetscSinReal(a) sinf(a) 41 #define PetscCosReal(a) cosf(a) 42 #define PetscTanReal(a) tanf(a) 43 #define PetscAsinReal(a) asinf(a) 44 #define PetscAcosReal(a) acosf(a) 45 #define PetscAtanReal(a) atanf(a) 46 #define PetscSinhReal(a) sinhf(a) 47 #define PetscCoshReal(a) coshf(a) 48 #define PetscTanhReal(a) tanhf(a) 49 #define PetscAsinhReal(a) asinhf(a) 50 #define PetscAcoshReal(a) acoshf(a) 51 #define PetscAtanhReal(a) atanhf(a) 52 #define PetscErfReal(a) erff(a) 53 #define PetscCeilReal(a) ceilf(a) 54 #define PetscFloorReal(a) floorf(a) 55 #define PetscFmodReal(a, b) fmodf(a, b) 56 #define PetscCopysignReal(a, b) copysignf(a, b) 57 #define PetscTGamma(a) tgammaf(a) 58 #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA) 59 #define PetscLGamma(a) gammaf(a) 60 #else 61 #define PetscLGamma(a) lgammaf(a) 62 #endif 63 64 #elif defined(PETSC_USE_REAL_DOUBLE) 65 #define PetscSqrtReal(a) sqrt(a) 66 #define PetscCbrtReal(a) cbrt(a) 67 #define PetscHypotReal(a, b) hypot(a, b) 68 #define PetscAtan2Real(a, b) atan2(a, b) 69 #define PetscPowReal(a, b) pow(a, b) 70 #define PetscExpReal(a) exp(a) 71 #define PetscLogReal(a) log(a) 72 #define PetscLog10Real(a) log10(a) 73 #define PetscLog2Real(a) log2(a) 74 #define PetscSinReal(a) sin(a) 75 #define PetscCosReal(a) cos(a) 76 #define PetscTanReal(a) tan(a) 77 #define PetscAsinReal(a) asin(a) 78 #define PetscAcosReal(a) acos(a) 79 #define PetscAtanReal(a) atan(a) 80 #define PetscSinhReal(a) sinh(a) 81 #define PetscCoshReal(a) cosh(a) 82 #define PetscTanhReal(a) tanh(a) 83 #define PetscAsinhReal(a) asinh(a) 84 #define PetscAcoshReal(a) acosh(a) 85 #define PetscAtanhReal(a) atanh(a) 86 #define PetscErfReal(a) erf(a) 87 #define PetscCeilReal(a) ceil(a) 88 #define PetscFloorReal(a) floor(a) 89 #define PetscFmodReal(a, b) fmod(a, b) 90 #define PetscCopysignReal(a, b) copysign(a, b) 91 #define PetscTGamma(a) tgamma(a) 92 #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA) 93 #define PetscLGamma(a) gamma(a) 94 #else 95 #define PetscLGamma(a) lgamma(a) 96 #endif 97 98 #elif defined(PETSC_USE_REAL___FLOAT128) 99 #define PetscSqrtReal(a) sqrtq(a) 100 #define PetscCbrtReal(a) cbrtq(a) 101 #define PetscHypotReal(a, b) hypotq(a, b) 102 #define PetscAtan2Real(a, b) atan2q(a, b) 103 #define PetscPowReal(a, b) powq(a, b) 104 #define PetscExpReal(a) expq(a) 105 #define PetscLogReal(a) logq(a) 106 #define PetscLog10Real(a) log10q(a) 107 #define PetscLog2Real(a) log2q(a) 108 #define PetscSinReal(a) sinq(a) 109 #define PetscCosReal(a) cosq(a) 110 #define PetscTanReal(a) tanq(a) 111 #define PetscAsinReal(a) asinq(a) 112 #define PetscAcosReal(a) acosq(a) 113 #define PetscAtanReal(a) atanq(a) 114 #define PetscSinhReal(a) sinhq(a) 115 #define PetscCoshReal(a) coshq(a) 116 #define PetscTanhReal(a) tanhq(a) 117 #define PetscAsinhReal(a) asinhq(a) 118 #define PetscAcoshReal(a) acoshq(a) 119 #define PetscAtanhReal(a) atanhq(a) 120 #define PetscErfReal(a) erfq(a) 121 #define PetscCeilReal(a) ceilq(a) 122 #define PetscFloorReal(a) floorq(a) 123 #define PetscFmodReal(a, b) fmodq(a, b) 124 #define PetscCopysignReal(a, b) copysignq(a, b) 125 #define PetscTGamma(a) tgammaq(a) 126 #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA) 127 #define PetscLGamma(a) gammaq(a) 128 #else 129 #define PetscLGamma(a) lgammaq(a) 130 #endif 131 132 #elif defined(PETSC_USE_REAL___FP16) 133 #define PetscSqrtReal(a) sqrtf(a) 134 #define PetscCbrtReal(a) cbrtf(a) 135 #define PetscHypotReal(a, b) hypotf(a, b) 136 #define PetscAtan2Real(a, b) atan2f(a, b) 137 #define PetscPowReal(a, b) powf(a, b) 138 #define PetscExpReal(a) expf(a) 139 #define PetscLogReal(a) logf(a) 140 #define PetscLog10Real(a) log10f(a) 141 #define PetscLog2Real(a) log2f(a) 142 #define PetscSinReal(a) sinf(a) 143 #define PetscCosReal(a) cosf(a) 144 #define PetscTanReal(a) tanf(a) 145 #define PetscAsinReal(a) asinf(a) 146 #define PetscAcosReal(a) acosf(a) 147 #define PetscAtanReal(a) atanf(a) 148 #define PetscSinhReal(a) sinhf(a) 149 #define PetscCoshReal(a) coshf(a) 150 #define PetscTanhReal(a) tanhf(a) 151 #define PetscAsinhReal(a) asinhf(a) 152 #define PetscAcoshReal(a) acoshf(a) 153 #define PetscAtanhReal(a) atanhf(a) 154 #define PetscErfReal(a) erff(a) 155 #define PetscCeilReal(a) ceilf(a) 156 #define PetscFloorReal(a) floorf(a) 157 #define PetscFmodReal(a, b) fmodf(a, b) 158 #define PetscCopySignReal(a, b) copysignf(a, b) 159 #define PetscTGamma(a) tgammaf(a) 160 #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA) 161 #define PetscLGamma(a) gammaf(a) 162 #else 163 #define PetscLGamma(a) lgammaf(a) 164 #endif 165 166 #endif /* PETSC_USE_REAL_* */ 167 168 static inline PetscReal PetscSignReal(PetscReal a) 169 { 170 return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0)); 171 } 172 173 #if !defined(PETSC_HAVE_LOG2) 174 #undef PetscLog2Real 175 static inline PetscReal PetscLog2Real(PetscReal a) 176 { 177 return PetscLogReal(a) / PetscLogReal((PetscReal)2); 178 } 179 #endif 180 181 #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128) 182 PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128); 183 #endif 184 #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16) 185 PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16); 186 #endif 187 188 /*MC 189 MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in 190 191 Notes: 192 In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value. 193 194 Level: beginner 195 196 .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT` 197 M*/ 198 #if defined(PETSC_USE_REAL_SINGLE) 199 #define MPIU_REAL MPI_FLOAT 200 #elif defined(PETSC_USE_REAL_DOUBLE) 201 #define MPIU_REAL MPI_DOUBLE 202 #elif defined(PETSC_USE_REAL___FLOAT128) 203 #define MPIU_REAL MPIU___FLOAT128 204 #elif defined(PETSC_USE_REAL___FP16) 205 #define MPIU_REAL MPIU___FP16 206 #endif /* PETSC_USE_REAL_* */ 207 208 /* 209 Complex number definitions 210 */ 211 #if defined(PETSC_HAVE_COMPLEX) 212 #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128) 213 /* C++ support of complex number */ 214 215 #define PetscRealPartComplex(a) (a).real() 216 #define PetscImaginaryPartComplex(a) (a).imag() 217 #define PetscAbsComplex(a) petsccomplexlib::abs(a) 218 #define PetscArgComplex(a) petsccomplexlib::arg(a) 219 #define PetscConjComplex(a) petsccomplexlib::conj(a) 220 #define PetscSqrtComplex(a) petsccomplexlib::sqrt(a) 221 #define PetscPowComplex(a, b) petsccomplexlib::pow(a, b) 222 #define PetscExpComplex(a) petsccomplexlib::exp(a) 223 #define PetscLogComplex(a) petsccomplexlib::log(a) 224 #define PetscSinComplex(a) petsccomplexlib::sin(a) 225 #define PetscCosComplex(a) petsccomplexlib::cos(a) 226 #define PetscTanComplex(a) petsccomplexlib::tan(a) 227 #define PetscAsinComplex(a) petsccomplexlib::asin(a) 228 #define PetscAcosComplex(a) petsccomplexlib::acos(a) 229 #define PetscAtanComplex(a) petsccomplexlib::atan(a) 230 #define PetscSinhComplex(a) petsccomplexlib::sinh(a) 231 #define PetscCoshComplex(a) petsccomplexlib::cosh(a) 232 #define PetscTanhComplex(a) petsccomplexlib::tanh(a) 233 #define PetscAsinhComplex(a) petsccomplexlib::asinh(a) 234 #define PetscAcoshComplex(a) petsccomplexlib::acosh(a) 235 #define PetscAtanhComplex(a) petsccomplexlib::atanh(a) 236 237 /* TODO: Add configure tests 238 239 #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX) 240 #undef PetscTanComplex 241 static inline PetscComplex PetscTanComplex(PetscComplex z) 242 { 243 return PetscSinComplex(z)/PetscCosComplex(z); 244 } 245 #endif 246 247 #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX) 248 #undef PetscTanhComplex 249 static inline PetscComplex PetscTanhComplex(PetscComplex z) 250 { 251 return PetscSinhComplex(z)/PetscCoshComplex(z); 252 } 253 #endif 254 255 #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX) 256 #undef PetscAsinComplex 257 static inline PetscComplex PetscAsinComplex(PetscComplex z) 258 { 259 const PetscComplex j(0,1); 260 return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z)); 261 } 262 #endif 263 264 #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX) 265 #undef PetscAcosComplex 266 static inline PetscComplex PetscAcosComplex(PetscComplex z) 267 { 268 const PetscComplex j(0,1); 269 return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z)); 270 } 271 #endif 272 273 #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX) 274 #undef PetscAtanComplex 275 static inline PetscComplex PetscAtanComplex(PetscComplex z) 276 { 277 const PetscComplex j(0,1); 278 return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z)); 279 } 280 #endif 281 282 #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX) 283 #undef PetscAsinhComplex 284 static inline PetscComplex PetscAsinhComplex(PetscComplex z) 285 { 286 return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f)); 287 } 288 #endif 289 290 #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX) 291 #undef PetscAcoshComplex 292 static inline PetscComplex PetscAcoshComplex(PetscComplex z) 293 { 294 return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f)); 295 } 296 #endif 297 298 #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX) 299 #undef PetscAtanhComplex 300 static inline PetscComplex PetscAtanhComplex(PetscComplex z) 301 { 302 return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z)); 303 } 304 #endif 305 306 */ 307 308 #else /* C99 support of complex number */ 309 310 #if defined(PETSC_USE_REAL_SINGLE) 311 #define PetscRealPartComplex(a) crealf(a) 312 #define PetscImaginaryPartComplex(a) cimagf(a) 313 #define PetscAbsComplex(a) cabsf(a) 314 #define PetscArgComplex(a) cargf(a) 315 #define PetscConjComplex(a) conjf(a) 316 #define PetscSqrtComplex(a) csqrtf(a) 317 #define PetscPowComplex(a, b) cpowf(a, b) 318 #define PetscExpComplex(a) cexpf(a) 319 #define PetscLogComplex(a) clogf(a) 320 #define PetscSinComplex(a) csinf(a) 321 #define PetscCosComplex(a) ccosf(a) 322 #define PetscTanComplex(a) ctanf(a) 323 #define PetscAsinComplex(a) casinf(a) 324 #define PetscAcosComplex(a) cacosf(a) 325 #define PetscAtanComplex(a) catanf(a) 326 #define PetscSinhComplex(a) csinhf(a) 327 #define PetscCoshComplex(a) ccoshf(a) 328 #define PetscTanhComplex(a) ctanhf(a) 329 #define PetscAsinhComplex(a) casinhf(a) 330 #define PetscAcoshComplex(a) cacoshf(a) 331 #define PetscAtanhComplex(a) catanhf(a) 332 333 #elif defined(PETSC_USE_REAL_DOUBLE) 334 #define PetscRealPartComplex(a) creal(a) 335 #define PetscImaginaryPartComplex(a) cimag(a) 336 #define PetscAbsComplex(a) cabs(a) 337 #define PetscArgComplex(a) carg(a) 338 #define PetscConjComplex(a) conj(a) 339 #define PetscSqrtComplex(a) csqrt(a) 340 #define PetscPowComplex(a, b) cpow(a, b) 341 #define PetscExpComplex(a) cexp(a) 342 #define PetscLogComplex(a) clog(a) 343 #define PetscSinComplex(a) csin(a) 344 #define PetscCosComplex(a) ccos(a) 345 #define PetscTanComplex(a) ctan(a) 346 #define PetscAsinComplex(a) casin(a) 347 #define PetscAcosComplex(a) cacos(a) 348 #define PetscAtanComplex(a) catan(a) 349 #define PetscSinhComplex(a) csinh(a) 350 #define PetscCoshComplex(a) ccosh(a) 351 #define PetscTanhComplex(a) ctanh(a) 352 #define PetscAsinhComplex(a) casinh(a) 353 #define PetscAcoshComplex(a) cacosh(a) 354 #define PetscAtanhComplex(a) catanh(a) 355 356 #elif defined(PETSC_USE_REAL___FLOAT128) 357 #define PetscRealPartComplex(a) crealq(a) 358 #define PetscImaginaryPartComplex(a) cimagq(a) 359 #define PetscAbsComplex(a) cabsq(a) 360 #define PetscArgComplex(a) cargq(a) 361 #define PetscConjComplex(a) conjq(a) 362 #define PetscSqrtComplex(a) csqrtq(a) 363 #define PetscPowComplex(a, b) cpowq(a, b) 364 #define PetscExpComplex(a) cexpq(a) 365 #define PetscLogComplex(a) clogq(a) 366 #define PetscSinComplex(a) csinq(a) 367 #define PetscCosComplex(a) ccosq(a) 368 #define PetscTanComplex(a) ctanq(a) 369 #define PetscAsinComplex(a) casinq(a) 370 #define PetscAcosComplex(a) cacosq(a) 371 #define PetscAtanComplex(a) catanq(a) 372 #define PetscSinhComplex(a) csinhq(a) 373 #define PetscCoshComplex(a) ccoshq(a) 374 #define PetscTanhComplex(a) ctanhq(a) 375 #define PetscAsinhComplex(a) casinhq(a) 376 #define PetscAcoshComplex(a) cacoshq(a) 377 #define PetscAtanhComplex(a) catanhq(a) 378 379 #endif /* PETSC_USE_REAL_* */ 380 #endif /* (__cplusplus) */ 381 382 /* 383 PETSC_i is the imaginary number, i 384 */ 385 PETSC_EXTERN PetscComplex PETSC_i; 386 387 /* 388 Try to do the right thing for complex number construction: see 389 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm 390 for details 391 */ 392 static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y) 393 { 394 #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128) 395 return PetscComplex(x, y); 396 #elif defined(_Imaginary_I) 397 return x + y * _Imaginary_I; 398 #else 399 { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5), 400 401 "For each floating type there is a corresponding real type, which is always a real floating 402 type. For real floating types, it is the same type. For complex types, it is the type given 403 by deleting the keyword _Complex from the type name." 404 405 So type punning should be portable. */ 406 union 407 { 408 PetscComplex z; 409 PetscReal f[2]; 410 } uz; 411 412 uz.f[0] = x; 413 uz.f[1] = y; 414 return uz.z; 415 } 416 #endif 417 } 418 419 #define MPIU_C_COMPLEX MPI_C_COMPLEX PETSC_DEPRECATED_MACRO("GCC warning \"MPIU_C_COMPLEX macro is deprecated use MPI_C_COMPLEX (since version 3.15)\"") 420 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO("GCC warning \"MPIU_C_DOUBLE_COMPLEX macro is deprecated use MPI_C_DOUBLE_COMPLEX (since version 3.15)\"") 421 422 #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128) 423 // if complex is not used, then quadmath.h won't be included by petscsystypes.h 424 #if defined(PETSC_USE_COMPLEX) 425 #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128) 426 #else 427 #define MPIU___COMPLEX128_ATTR_TAG 428 #endif 429 430 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG; 431 432 #undef MPIU___COMPLEX128_ATTR_TAG 433 #endif /* PETSC_HAVE_REAL___FLOAT128 */ 434 435 /*MC 436 MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex` 437 438 Notes: 439 In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value. 440 441 Level: beginner 442 443 .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i` 444 M*/ 445 #if defined(PETSC_USE_REAL_SINGLE) 446 #define MPIU_COMPLEX MPI_C_COMPLEX 447 #elif defined(PETSC_USE_REAL_DOUBLE) 448 #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX 449 #elif defined(PETSC_USE_REAL___FLOAT128) 450 #define MPIU_COMPLEX MPIU___COMPLEX128 451 #elif defined(PETSC_USE_REAL___FP16) 452 #define MPIU_COMPLEX MPI_C_COMPLEX 453 #endif /* PETSC_USE_REAL_* */ 454 455 #endif /* PETSC_HAVE_COMPLEX */ 456 457 /* 458 Scalar number definitions 459 */ 460 #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX) 461 /*MC 462 MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar` 463 464 Notes: 465 In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value. 466 467 Level: beginner 468 469 .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT` 470 M*/ 471 #define MPIU_SCALAR MPIU_COMPLEX 472 473 /*MC 474 PetscRealPart - Returns the real part of a `PetscScalar` 475 476 Synopsis: 477 #include <petscmath.h> 478 PetscReal PetscRealPart(PetscScalar v) 479 480 Not Collective 481 482 Input Parameter: 483 . v - value to find the real part of 484 485 Level: beginner 486 487 .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()` 488 489 M*/ 490 #define PetscRealPart(a) PetscRealPartComplex(a) 491 492 /*MC 493 PetscImaginaryPart - Returns the imaginary part of a `PetscScalar` 494 495 Synopsis: 496 #include <petscmath.h> 497 PetscReal PetscImaginaryPart(PetscScalar v) 498 499 Not Collective 500 501 Input Parameter: 502 . v - value to find the imaginary part of 503 504 Level: beginner 505 506 Notes: 507 If PETSc was configured for real numbers then this always returns the value 0 508 509 .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()` 510 511 M*/ 512 #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a) 513 514 #define PetscAbsScalar(a) PetscAbsComplex(a) 515 #define PetscArgScalar(a) PetscArgComplex(a) 516 #define PetscConj(a) PetscConjComplex(a) 517 #define PetscSqrtScalar(a) PetscSqrtComplex(a) 518 #define PetscPowScalar(a, b) PetscPowComplex(a, b) 519 #define PetscExpScalar(a) PetscExpComplex(a) 520 #define PetscLogScalar(a) PetscLogComplex(a) 521 #define PetscSinScalar(a) PetscSinComplex(a) 522 #define PetscCosScalar(a) PetscCosComplex(a) 523 #define PetscTanScalar(a) PetscTanComplex(a) 524 #define PetscAsinScalar(a) PetscAsinComplex(a) 525 #define PetscAcosScalar(a) PetscAcosComplex(a) 526 #define PetscAtanScalar(a) PetscAtanComplex(a) 527 #define PetscSinhScalar(a) PetscSinhComplex(a) 528 #define PetscCoshScalar(a) PetscCoshComplex(a) 529 #define PetscTanhScalar(a) PetscTanhComplex(a) 530 #define PetscAsinhScalar(a) PetscAsinhComplex(a) 531 #define PetscAcoshScalar(a) PetscAcoshComplex(a) 532 #define PetscAtanhScalar(a) PetscAtanhComplex(a) 533 534 #else /* PETSC_USE_COMPLEX */ 535 #define MPIU_SCALAR MPIU_REAL 536 #define PetscRealPart(a) (a) 537 #define PetscImaginaryPart(a) ((PetscReal)0) 538 #define PetscAbsScalar(a) PetscAbsReal(a) 539 #define PetscArgScalar(a) (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0) 540 #define PetscConj(a) (a) 541 #define PetscSqrtScalar(a) PetscSqrtReal(a) 542 #define PetscPowScalar(a, b) PetscPowReal(a, b) 543 #define PetscExpScalar(a) PetscExpReal(a) 544 #define PetscLogScalar(a) PetscLogReal(a) 545 #define PetscSinScalar(a) PetscSinReal(a) 546 #define PetscCosScalar(a) PetscCosReal(a) 547 #define PetscTanScalar(a) PetscTanReal(a) 548 #define PetscAsinScalar(a) PetscAsinReal(a) 549 #define PetscAcosScalar(a) PetscAcosReal(a) 550 #define PetscAtanScalar(a) PetscAtanReal(a) 551 #define PetscSinhScalar(a) PetscSinhReal(a) 552 #define PetscCoshScalar(a) PetscCoshReal(a) 553 #define PetscTanhScalar(a) PetscTanhReal(a) 554 #define PetscAsinhScalar(a) PetscAsinhReal(a) 555 #define PetscAcoshScalar(a) PetscAcoshReal(a) 556 #define PetscAtanhScalar(a) PetscAtanhReal(a) 557 558 #endif /* PETSC_USE_COMPLEX */ 559 560 /* 561 Certain objects may be created using either single or double precision. 562 This is currently not used. 563 */ 564 typedef enum { 565 PETSC_SCALAR_DOUBLE, 566 PETSC_SCALAR_SINGLE, 567 PETSC_SCALAR_LONG_DOUBLE, 568 PETSC_SCALAR_HALF 569 } PetscScalarPrecision; 570 571 /* --------------------------------------------------------------------------*/ 572 573 /*MC 574 PetscAbs - Returns the absolute value of a number 575 576 Synopsis: 577 #include <petscmath.h> 578 type PetscAbs(type v) 579 580 Not Collective 581 582 Input Parameter: 583 . v - the number 584 585 Note: 586 The type can be integer or real floating point value, but cannot be complex 587 588 Level: beginner 589 590 .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()` 591 592 M*/ 593 #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a))) 594 595 /*MC 596 PetscSign - Returns the sign of a number as an integer 597 598 Synopsis: 599 #include <petscmath.h> 600 int PetscSign(type v) 601 602 Not Collective 603 604 Input Parameter: 605 . v - the number 606 607 Note: 608 The type can be integer or real floating point value 609 610 Level: beginner 611 612 M*/ 613 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 614 615 /*MC 616 PetscMin - Returns minimum of two numbers 617 618 Synopsis: 619 #include <petscmath.h> 620 type PetscMin(type v1,type v2) 621 622 Not Collective 623 624 Input Parameters: 625 + v1 - first value to find minimum of 626 - v2 - second value to find minimum of 627 628 Note: 629 The type can be integer or floating point value 630 631 Level: beginner 632 633 .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()` 634 635 M*/ 636 #define PetscMin(a, b) (((a) < (b)) ? (a) : (b)) 637 638 /*MC 639 PetscMax - Returns maximum of two numbers 640 641 Synopsis: 642 #include <petscmath.h> 643 type max PetscMax(type v1,type v2) 644 645 Not Collective 646 647 Input Parameters: 648 + v1 - first value to find maximum of 649 - v2 - second value to find maximum of 650 651 Note: 652 The type can be integer or floating point value 653 654 Level: beginner 655 656 .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()` 657 658 M*/ 659 #define PetscMax(a, b) (((a) < (b)) ? (b) : (a)) 660 661 /*MC 662 PetscClipInterval - Returns a number clipped to be within an interval 663 664 Synopsis: 665 #include <petscmath.h> 666 type clip PetscClipInterval(type x,type a,type b) 667 668 Not Collective 669 670 Input Parameters: 671 + x - value to use if within interval [a,b] 672 . a - lower end of interval 673 - b - upper end of interval 674 675 Note: 676 The type can be integer or floating point value 677 678 Level: beginner 679 680 .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()` 681 682 M*/ 683 #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b)))) 684 685 /*MC 686 PetscAbsInt - Returns the absolute value of an integer 687 688 Synopsis: 689 #include <petscmath.h> 690 int abs PetscAbsInt(int v1) 691 692 Input Parameter: 693 . v1 - the integer 694 695 Level: beginner 696 697 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()` 698 699 M*/ 700 #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a)) 701 702 /*MC 703 PetscAbsReal - Returns the absolute value of an real number 704 705 Synopsis: 706 #include <petscmath.h> 707 Real abs PetscAbsReal(PetscReal v1) 708 709 Input Parameter: 710 . v1 - the double 711 712 Level: beginner 713 714 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()` 715 716 M*/ 717 #if defined(PETSC_USE_REAL_SINGLE) 718 #define PetscAbsReal(a) fabsf(a) 719 #elif defined(PETSC_USE_REAL_DOUBLE) 720 #define PetscAbsReal(a) fabs(a) 721 #elif defined(PETSC_USE_REAL___FLOAT128) 722 #define PetscAbsReal(a) fabsq(a) 723 #elif defined(PETSC_USE_REAL___FP16) 724 #define PetscAbsReal(a) fabsf(a) 725 #endif 726 727 /*MC 728 PetscSqr - Returns the square of a number 729 730 Synopsis: 731 #include <petscmath.h> 732 type sqr PetscSqr(type v1) 733 734 Not Collective 735 736 Input Parameter: 737 . v1 - the value 738 739 Note: 740 The type can be integer or floating point value 741 742 Level: beginner 743 744 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()` 745 746 M*/ 747 #define PetscSqr(a) ((a) * (a)) 748 749 /* ----------------------------------------------------------------------------*/ 750 751 #if defined(PETSC_USE_REAL_SINGLE) 752 #define PetscRealConstant(constant) constant##F 753 #elif defined(PETSC_USE_REAL_DOUBLE) 754 #define PetscRealConstant(constant) constant 755 #elif defined(PETSC_USE_REAL___FLOAT128) 756 #define PetscRealConstant(constant) constant##Q 757 #elif defined(PETSC_USE_REAL___FP16) 758 #define PetscRealConstant(constant) constant##F 759 #endif 760 761 /* 762 Basic constants 763 */ 764 #define PETSC_PI PetscRealConstant(3.1415926535897932384626433832795029) 765 #define PETSC_PHI PetscRealConstant(1.6180339887498948482045868343656381) 766 #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981) 767 768 #if defined(PETSC_USE_REAL_SINGLE) 769 #define PETSC_MAX_REAL 3.40282346638528860e+38F 770 #define PETSC_MIN_REAL (-PETSC_MAX_REAL) 771 #define PETSC_MACHINE_EPSILON 1.19209290e-07F 772 #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F 773 #define PETSC_SMALL 1.e-5F 774 #elif defined(PETSC_USE_REAL_DOUBLE) 775 #define PETSC_MAX_REAL 1.7976931348623157e+308 776 #define PETSC_MIN_REAL (-PETSC_MAX_REAL) 777 #define PETSC_MACHINE_EPSILON 2.2204460492503131e-16 778 #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08 779 #define PETSC_SMALL 1.e-10 780 #elif defined(PETSC_USE_REAL___FLOAT128) 781 #define PETSC_MAX_REAL FLT128_MAX 782 #define PETSC_MIN_REAL (-FLT128_MAX) 783 #define PETSC_MACHINE_EPSILON FLT128_EPSILON 784 #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q 785 #define PETSC_SMALL 1.e-20Q 786 #elif defined(PETSC_USE_REAL___FP16) 787 #define PETSC_MAX_REAL 65504.0F 788 #define PETSC_MIN_REAL (-PETSC_MAX_REAL) 789 #define PETSC_MACHINE_EPSILON .0009765625F 790 #define PETSC_SQRT_MACHINE_EPSILON .03125F 791 #define PETSC_SMALL 5.e-3F 792 #endif 793 794 #define PETSC_INFINITY (PETSC_MAX_REAL / 4) 795 #define PETSC_NINFINITY (-PETSC_INFINITY) 796 797 PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal); 798 PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal); 799 PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal); 800 static inline PetscBool PetscIsInfOrNanReal(PetscReal v) 801 { 802 return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE; 803 } 804 static inline PetscBool PetscIsInfScalar(PetscScalar v) 805 { 806 return PetscIsInfReal(PetscAbsScalar(v)); 807 } 808 static inline PetscBool PetscIsNanScalar(PetscScalar v) 809 { 810 return PetscIsNanReal(PetscAbsScalar(v)); 811 } 812 static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v) 813 { 814 return PetscIsInfOrNanReal(PetscAbsScalar(v)); 815 } 816 static inline PetscBool PetscIsNormalScalar(PetscScalar v) 817 { 818 return PetscIsNormalReal(PetscAbsScalar(v)); 819 } 820 821 PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal); 822 PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal); 823 PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar); 824 825 /* 826 These macros are currently hardwired to match the regular data types, so there is no support for a different 827 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 828 */ 829 #define MPIU_MATSCALAR MPIU_SCALAR 830 typedef PetscScalar MatScalar; 831 typedef PetscReal MatReal; 832 833 struct petsc_mpiu_2scalar { 834 PetscScalar a, b; 835 }; 836 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar); 837 838 /* MPI Datatypes for composite reductions */ 839 struct petsc_mpiu_real_int { 840 PetscReal v; 841 PetscInt i; 842 }; 843 844 struct petsc_mpiu_scalar_int { 845 PetscScalar v; 846 PetscInt i; 847 }; 848 849 PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int); 850 PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int); 851 852 #if defined(PETSC_USE_64BIT_INDICES) 853 struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int { 854 PetscInt a; 855 PetscInt b; 856 }; 857 /* 858 static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), ""); 859 static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), ""); 860 static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), ""); 861 862 clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or 863 PetscInt *, even though (with everything else uncommented) both of the static_asserts above 864 pass! So we just comment it out... 865 */ 866 PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */; 867 #else 868 #define MPIU_2INT MPI_2INT 869 #endif 870 PETSC_EXTERN MPI_Datatype MPI_4INT; 871 PETSC_EXTERN MPI_Datatype MPIU_4INT; 872 873 static inline PetscInt PetscPowInt(PetscInt base, PetscInt power) 874 { 875 PetscInt result = 1; 876 while (power) { 877 if (power & 1) result *= base; 878 power >>= 1; 879 if (power) base *= base; 880 } 881 return result; 882 } 883 884 static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power) 885 { 886 PetscInt64 result = 1; 887 while (power) { 888 if (power & 1) result *= base; 889 power >>= 1; 890 if (power) base *= base; 891 } 892 return result; 893 } 894 895 static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power) 896 { 897 PetscReal result = 1; 898 if (power < 0) { 899 power = -power; 900 base = ((PetscReal)1) / base; 901 } 902 while (power) { 903 if (power & 1) result *= base; 904 power >>= 1; 905 if (power) base *= base; 906 } 907 return result; 908 } 909 910 static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power) 911 { 912 PetscScalar result = (PetscReal)1; 913 if (power < 0) { 914 power = -power; 915 base = ((PetscReal)1) / base; 916 } 917 while (power) { 918 if (power & 1) result *= base; 919 power >>= 1; 920 if (power) base *= base; 921 } 922 return result; 923 } 924 925 static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power) 926 { 927 PetscScalar cpower = power; 928 return PetscPowScalar(base, cpower); 929 } 930 931 /*MC 932 PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers 933 934 Synopsis: 935 #include <petscmath.h> 936 bool PetscApproximateLTE(PetscReal x,constant float) 937 938 Not Collective 939 940 Input Parameters: 941 + x - the variable 942 - b - the constant float it is checking if x is less than or equal to 943 944 Notes: 945 The fudge factor is the value `PETSC_SMALL` 946 947 The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2 948 949 This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact 950 floating point results. 951 952 Level: advanced 953 954 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()` 955 956 M*/ 957 #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL)) 958 959 /*MC 960 PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers 961 962 Synopsis: 963 #include <petscmath.h> 964 bool PetscApproximateGTE(PetscReal x,constant float) 965 966 Not Collective 967 968 Input Parameters: 969 + x - the variable 970 - b - the constant float it is checking if x is greater than or equal to 971 972 Notes: 973 The fudge factor is the value `PETSC_SMALL` 974 975 The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2 976 977 This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact 978 floating point results. 979 980 Level: advanced 981 982 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()` 983 984 M*/ 985 #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL)) 986 987 /*MC 988 PetscCeilInt - Returns the ceiling of the quotation of two positive integers 989 990 Synopsis: 991 #include <petscmath.h> 992 PetscInt PetscCeilInt(PetscInt x,PetscInt y) 993 994 Not Collective 995 996 Input Parameters: 997 + x - the numerator 998 - y - the denominator 999 1000 Level: advanced 1001 1002 .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()` 1003 1004 M*/ 1005 #define PetscCeilInt(x, y) ((((PetscInt)(x)) / ((PetscInt)(y))) + ((((PetscInt)(x)) % ((PetscInt)(y))) ? 1 : 0)) 1006 1007 #define PetscCeilInt64(x, y) ((((PetscInt64)(x)) / ((PetscInt64)(y))) + ((((PetscInt64)(x)) % ((PetscInt64)(y))) ? 1 : 0)) 1008 1009 PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *); 1010 #endif 1011