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 PetscRoundReal(a) roundf(a) 28 #define PetscSqrtReal(a) sqrtf(a) 29 #define PetscExpReal(a) expf(a) 30 #define PetscLogReal(a) logf(a) 31 #define PetscLog10Real(a) log10f(a) 32 #ifdef PETSC_HAVE_LOG2 33 #define PetscLog2Real(a) log2f(a) 34 #endif 35 #define PetscSinReal(a) sinf(a) 36 #define PetscCosReal(a) cosf(a) 37 #define PetscTanReal(a) tanf(a) 38 #define PetscAsinReal(a) asinf(a) 39 #define PetscAcosReal(a) acosf(a) 40 #define PetscAtanReal(a) atanf(a) 41 #define PetscAtan2Real(a,b) atan2f(a,b) 42 #define PetscSinhReal(a) sinhf(a) 43 #define PetscCoshReal(a) coshf(a) 44 #define PetscTanhReal(a) tanhf(a) 45 #define PetscPowReal(a,b) powf(a,b) 46 #define PetscCeilReal(a) ceilf(a) 47 #define PetscFloorReal(a) floorf(a) 48 #define PetscFmodReal(a,b) fmodf(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 PetscRoundReal(a) round(a) 54 #define PetscSqrtReal(a) sqrt(a) 55 #define PetscExpReal(a) exp(a) 56 #define PetscLogReal(a) log(a) 57 #define PetscLog10Real(a) log10(a) 58 #ifdef PETSC_HAVE_LOG2 59 #define PetscLog2Real(a) log2(a) 60 #endif 61 #define PetscSinReal(a) sin(a) 62 #define PetscCosReal(a) cos(a) 63 #define PetscTanReal(a) tan(a) 64 #define PetscAsinReal(a) asin(a) 65 #define PetscAcosReal(a) acos(a) 66 #define PetscAtanReal(a) atan(a) 67 #define PetscAtan2Real(a,b) atan2(a,b) 68 #define PetscSinhReal(a) sinh(a) 69 #define PetscCoshReal(a) cosh(a) 70 #define PetscTanhReal(a) tanh(a) 71 #define PetscPowReal(a,b) pow(a,b) 72 #define PetscCeilReal(a) ceil(a) 73 #define PetscFloorReal(a) floor(a) 74 #define PetscFmodReal(a,b) fmod(a,b) 75 #define PetscTGamma(a) tgamma(a) 76 #elif defined(PETSC_USE_REAL___FLOAT128) 77 #if defined(__cplusplus) 78 extern "C" { 79 #endif 80 #include <quadmath.h> 81 #if defined(__cplusplus) 82 } 83 #endif 84 PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128); 85 #define MPIU_REAL MPIU___FLOAT128 86 typedef __float128 PetscReal; 87 #define PetscRoundReal(a) roundq(a) 88 #define PetscSqrtReal(a) sqrtq(a) 89 #define PetscExpReal(a) expq(a) 90 #define PetscLogReal(a) logq(a) 91 #define PetscLog10Real(a) log10q(a) 92 #ifdef PETSC_HAVE_LOG2 93 #define PetscLog2Real(a) log2q(a) 94 #endif 95 #define PetscSinReal(a) sinq(a) 96 #define PetscCosReal(a) cosq(a) 97 #define PetscTanReal(a) tanq(a) 98 #define PetscAsinReal(a) asinq(a) 99 #define PetscAcosReal(a) acosq(a) 100 #define PetscAtanReal(a) atanq(a) 101 #define PetscAtan2Real(a,b) atan2q(a,b) 102 #define PetscSinhReal(a) sinhq(a) 103 #define PetscCoshReal(a) coshq(a) 104 #define PetscTanhReal(a) tanhq(a) 105 #define PetscPowReal(a,b) powq(a,b) 106 #define PetscCeilReal(a) ceilq(a) 107 #define PetscFloorReal(a) floorq(a) 108 #define PetscFmodReal(a,b) fmodq(a,b) 109 #define PetscTGamma(a) tgammaq(a) 110 #elif defined(PETSC_USE_REAL___FP16) 111 PETSC_EXTERN MPI_Datatype MPIU___FP16 PetscAttrMPITypeTag(__fp16); 112 #define MPIU_REAL MPIU___FP16 113 typedef __fp16 PetscReal; 114 #define PetscRound(a) roundf(a) 115 #define PetscSqrtReal(a) sqrtf(a) 116 #define PetscExpReal(a) expf(a) 117 #define PetscLogReal(a) logf(a) 118 #define PetscLog10Real(a) log10f(a) 119 #ifdef PETSC_HAVE_LOG2 120 #define PetscLog2Real(a) log2f(a) 121 #endif 122 #define PetscSinReal(a) sinf(a) 123 #define PetscCosReal(a) cosf(a) 124 #define PetscTanReal(a) tanf(a) 125 #define PetscAsinReal(a) asinf(a) 126 #define PetscAcosReal(a) acosf(a) 127 #define PetscAtanReal(a) atanf(a) 128 #define PetscAtan2Real(a,b) atan2f(a,b) 129 #define PetscSinhReal(a) sinhf(a) 130 #define PetscCoshReal(a) coshf(a) 131 #define PetscTanhReal(a) tanhf(a) 132 #define PetscPowReal(a,b) powf(a,b) 133 #define PetscCeilReal(a) ceilf(a) 134 #define PetscFloorReal(a) floorf(a) 135 #define PetscFmodReal(a,b) fmodf(a,b) 136 #define PetscTGamma(a) tgammaf(a) 137 #endif /* PETSC_USE_REAL_* */ 138 139 /* 140 Complex number definitions 141 */ 142 #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128) 143 #if !defined(PETSC_SKIP_COMPLEX) 144 #define PETSC_HAVE_COMPLEX 1 145 /* C++ support of complex number */ 146 #if defined(PETSC_HAVE_CUSP) 147 #define complexlib cusp 148 #include <cusp/complex.h> 149 #elif defined(PETSC_HAVE_VECCUDA) && __CUDACC_VER_MAJOR__ > 6 150 /* complex headers in thrust only available in CUDA 7.0 and above */ 151 #define complexlib thrust 152 #include <thrust/complex.h> 153 #else 154 #define complexlib std 155 #include <complex> 156 #endif 157 158 #define PetscRealPartComplex(a) (a).real() 159 #define PetscImaginaryPartComplex(a) (a).imag() 160 #define PetscAbsComplex(a) complexlib::abs(a) 161 #define PetscConjComplex(a) complexlib::conj(a) 162 #define PetscSqrtComplex(a) complexlib::sqrt(a) 163 #define PetscPowComplex(a,b) complexlib::pow(a,b) 164 #define PetscExpComplex(a) complexlib::exp(a) 165 #define PetscLogComplex(a) complexlib::log(a) 166 #define PetscSinComplex(a) complexlib::sin(a) 167 #define PetscCosComplex(a) complexlib::cos(a) 168 #define PetscAsinComplex(a) complexlib::asin(a) 169 #define PetscAcosComplex(a) complexlib::acos(a) 170 #if defined(PETSC_HAVE_TANCOMPLEX) 171 #define PetscTanComplex(a) complexlib::tan(a) 172 #else 173 #define PetscTanComplex(a) PetscSinComplex(a)/PetscCosComplex(a) 174 #endif 175 #define PetscSinhComplex(a) complexlib::sinh(a) 176 #define PetscCoshComplex(a) complexlib::cosh(a) 177 #if defined(PETSC_HAVE_TANHCOMPLEX) 178 #define PetscTanhComplex(a) complexlib::tanh(a) 179 #else 180 #define PetscTanhComplex(a) PetscSinhComplex(a)/PetscCoshComplex(a) 181 #endif 182 183 #if defined(PETSC_USE_REAL_SINGLE) 184 typedef complexlib::complex<float> PetscComplex; 185 #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND) 186 static inline PetscComplex operator+(const PetscComplex& lhs, const double& rhs) { return lhs + float(rhs); } 187 static inline PetscComplex operator+(const double& lhs, const PetscComplex& rhs) { return float(lhs) + rhs; } 188 static inline PetscComplex operator-(const PetscComplex& lhs, const double& rhs) { return lhs - float(rhs); } 189 static inline PetscComplex operator-(const double& lhs, const PetscComplex& rhs) { return float(lhs) - rhs; } 190 static inline PetscComplex operator*(const PetscComplex& lhs, const double& rhs) { return lhs * float(rhs); } 191 static inline PetscComplex operator*(const double& lhs, const PetscComplex& rhs) { return float(lhs) * rhs; } 192 static inline PetscComplex operator/(const PetscComplex& lhs, const double& rhs) { return lhs / float(rhs); } 193 static inline PetscComplex operator/(const double& lhs, const PetscComplex& rhs) { return float(lhs) / rhs; } 194 static inline bool operator==(const PetscComplex& lhs, const double& rhs) { return lhs.imag() == float(0) && lhs.real() == float(rhs); } 195 static inline bool operator==(const double& lhs, const PetscComplex& rhs) { return rhs.imag() == float(0) && rhs.real() == float(lhs); } 196 static inline bool operator!=(const PetscComplex& lhs, const double& rhs) { return lhs.imag() != float(0) || lhs.real() != float(rhs); } 197 static inline bool operator!=(const double& lhs, const PetscComplex& rhs) { return rhs.imag() != float(0) || rhs.real() != float(lhs); } 198 #endif /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */ 199 #elif defined(PETSC_USE_REAL_DOUBLE) 200 typedef complexlib::complex<double> PetscComplex; 201 #if defined(PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND) 202 static inline PetscComplex operator+(const PetscComplex& lhs, const PetscInt& rhs) { return lhs + double(rhs); } 203 static inline PetscComplex operator+(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) + rhs; } 204 static inline PetscComplex operator-(const PetscComplex& lhs, const PetscInt& rhs) { return lhs - double(rhs); } 205 static inline PetscComplex operator-(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) - rhs; } 206 static inline PetscComplex operator*(const PetscComplex& lhs, const PetscInt& rhs) { return lhs * double(rhs); } 207 static inline PetscComplex operator*(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) * rhs; } 208 static inline PetscComplex operator/(const PetscComplex& lhs, const PetscInt& rhs) { return lhs / double(rhs); } 209 static inline PetscComplex operator/(const PetscInt& lhs, const PetscComplex& rhs) { return double(lhs) / rhs; } 210 static inline bool operator==(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() == double(0) && lhs.real() == double(rhs); } 211 static inline bool operator==(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() == double(0) && rhs.real() == double(lhs); } 212 static inline bool operator!=(const PetscComplex& lhs, const PetscInt& rhs) { return lhs.imag() != double(0) || lhs.real() != double(rhs); } 213 static inline bool operator!=(const PetscInt& lhs, const PetscComplex& rhs) { return rhs.imag() != double(0) || rhs.real() != double(lhs); } 214 #endif /* PETSC_USE_CXX_COMPLEX_FLOAT_WORKAROUND */ 215 #elif defined(PETSC_USE_REAL___FLOAT128) 216 typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */ 217 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128; 218 #endif /* PETSC_USE_REAL_ */ 219 #endif /* ! PETSC_SKIP_COMPLEX */ 220 221 #elif defined(PETSC_HAVE_C99_COMPLEX) && !defined(PETSC_USE_REAL___FP16) 222 #if !defined(PETSC_SKIP_COMPLEX) 223 #define PETSC_HAVE_COMPLEX 1 224 #include <complex.h> 225 226 #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16) 227 typedef float _Complex PetscComplex; 228 229 #define PetscRealPartComplex(a) crealf(a) 230 #define PetscImaginaryPartComplex(a) cimagf(a) 231 #define PetscAbsComplex(a) cabsf(a) 232 #define PetscConjComplex(a) conjf(a) 233 #define PetscSqrtComplex(a) csqrtf(a) 234 #define PetscPowComplex(a,b) cpowf(a,b) 235 #define PetscExpComplex(a) cexpf(a) 236 #define PetscLogComplex(a) clogf(a) 237 #define PetscSinComplex(a) csinf(a) 238 #define PetscCosComplex(a) ccosf(a) 239 #define PetscAsinComplex(a) casinf(a) 240 #define PetscAcosComplex(a) cacosf(a) 241 #define PetscTanComplex(a) ctanf(a) 242 #define PetscSinhComplex(a) csinhf(a) 243 #define PetscCoshComplex(a) ccoshf(a) 244 #define PetscTanhComplex(a) ctanhf(a) 245 246 #elif defined(PETSC_USE_REAL_DOUBLE) 247 typedef double _Complex PetscComplex; 248 249 #define PetscRealPartComplex(a) creal(a) 250 #define PetscImaginaryPartComplex(a) cimag(a) 251 #define PetscAbsComplex(a) cabs(a) 252 #define PetscConjComplex(a) conj(a) 253 #define PetscSqrtComplex(a) csqrt(a) 254 #define PetscPowComplex(a,b) cpow(a,b) 255 #define PetscExpComplex(a) cexp(a) 256 #define PetscLogComplex(a) clog(a) 257 #define PetscSinComplex(a) csin(a) 258 #define PetscCosComplex(a) ccos(a) 259 #define PetscAsinComplex(a) casin(a) 260 #define PetscAcosComplex(a) cacos(a) 261 #define PetscTanComplex(a) ctan(a) 262 #define PetscSinhComplex(a) csinh(a) 263 #define PetscCoshComplex(a) ccosh(a) 264 #define PetscTanhComplex(a) ctanh(a) 265 266 #elif defined(PETSC_USE_REAL___FLOAT128) 267 typedef __complex128 PetscComplex; 268 PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128); 269 270 #define PetscRealPartComplex(a) crealq(a) 271 #define PetscImaginaryPartComplex(a) cimagq(a) 272 #define PetscAbsComplex(a) cabsq(a) 273 #define PetscConjComplex(a) conjq(a) 274 #define PetscSqrtComplex(a) csqrtq(a) 275 #define PetscPowComplex(a,b) cpowq(a,b) 276 #define PetscExpComplex(a) cexpq(a) 277 #define PetscLogComplex(a) clogq(a) 278 #define PetscSinComplex(a) csinq(a) 279 #define PetscCosComplex(a) ccosq(a) 280 #define PetscAsinComplex(a) casinq(a) 281 #define PetscAcosComplex(a) cacosq(a) 282 #define PetscTanComplex(a) ctanq(a) 283 #define PetscSinhComplex(a) csinhq(a) 284 #define PetscCoshComplex(a) ccoshq(a) 285 #define PetscTanhComplex(a) ctanhq(a) 286 287 #endif /* PETSC_USE_REAL_* */ 288 #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 289 #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available" 290 #endif /* !PETSC_SKIP_COMPLEX */ 291 #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */ 292 293 #if defined(PETSC_HAVE_COMPLEX) 294 #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 295 #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX 296 #define MPIU_C_COMPLEX MPI_C_COMPLEX 297 #else 298 # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128) 299 typedef complexlib::complex<double> petsc_mpiu_c_double_complex; 300 typedef complexlib::complex<float> petsc_mpiu_c_complex; 301 # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) 302 typedef double _Complex petsc_mpiu_c_double_complex; 303 typedef float _Complex petsc_mpiu_c_complex; 304 # else 305 typedef struct {double real,imag;} petsc_mpiu_c_double_complex; 306 typedef struct {float real,imag;} petsc_mpiu_c_complex; 307 # endif 308 PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex); 309 PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex); 310 #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */ 311 #endif /* PETSC_HAVE_COMPLEX */ 312 313 #if defined(PETSC_HAVE_COMPLEX) 314 # if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16) 315 # define MPIU_COMPLEX MPIU_C_COMPLEX 316 # elif defined(PETSC_USE_REAL_DOUBLE) 317 # define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX 318 # elif defined(PETSC_USE_REAL___FLOAT128) 319 # define MPIU_COMPLEX MPIU___COMPLEX128 320 # endif /* PETSC_USE_REAL_* */ 321 #endif 322 323 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX)) 324 typedef PetscComplex PetscScalar; 325 #define PetscRealPart(a) PetscRealPartComplex(a) 326 #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a) 327 #define PetscAbsScalar(a) PetscAbsComplex(a) 328 #define PetscConj(a) PetscConjComplex(a) 329 #define PetscSqrtScalar(a) PetscSqrtComplex(a) 330 #define PetscPowScalar(a,b) PetscPowComplex(a,b) 331 #define PetscExpScalar(a) PetscExpComplex(a) 332 #define PetscLogScalar(a) PetscLogComplex(a) 333 #define PetscSinScalar(a) PetscSinComplex(a) 334 #define PetscCosScalar(a) PetscCosComplex(a) 335 #define PetscAsinScalar(a) PetscAsinComplex(a) 336 #define PetscAcosScalar(a) PetscAcosComplex(a) 337 #define PetscTanScalar(a) PetscTanComplex(a) 338 #define PetscSinhScalar(a) PetscSinhComplex(a) 339 #define PetscCoshScalar(a) PetscCoshComplex(a) 340 #define PetscTanhScalar(a) PetscTanhComplex(a) 341 #define MPIU_SCALAR MPIU_COMPLEX 342 343 /* 344 real number definitions 345 */ 346 #else /* PETSC_USE_COMPLEX */ 347 typedef PetscReal PetscScalar; 348 #define MPIU_SCALAR MPIU_REAL 349 350 #define PetscRealPart(a) (a) 351 #define PetscImaginaryPart(a) ((PetscReal)0.) 352 PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;} 353 #define PetscConj(a) (a) 354 #if !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 355 #define PetscSqrtScalar(a) sqrt(a) 356 #define PetscPowScalar(a,b) pow(a,b) 357 #define PetscExpScalar(a) exp(a) 358 #define PetscLogScalar(a) log(a) 359 #define PetscSinScalar(a) sin(a) 360 #define PetscCosScalar(a) cos(a) 361 #define PetscAsinScalar(a) asin(a) 362 #define PetscAcosScalar(a) acos(a) 363 #define PetscTanScalar(a) tan(a) 364 #define PetscSinhScalar(a) sinh(a) 365 #define PetscCoshScalar(a) cosh(a) 366 #define PetscTanhScalar(a) tanh(a) 367 #elif defined(PETSC_USE_REAL___FP16) 368 #define PetscSqrtScalar(a) sqrtf(a) 369 #define PetscPowScalar(a,b) powf(a,b) 370 #define PetscExpScalar(a) expf(a) 371 #define PetscLogScalar(a) logf(a) 372 #define PetscSinScalar(a) sinf(a) 373 #define PetscCosScalar(a) cosf(a) 374 #define PetscAsinScalar(a) asinf(a) 375 #define PetscAcosScalar(a) acosf(a) 376 #define PetscTanScalar(a) tanf(a) 377 #define PetscSinhScalar(a) sinhf(a) 378 #define PetscCoshScalar(a) coshf(a) 379 #define PetscTanhScalar(a) tanhf(a) 380 #else /* PETSC_USE_REAL___FLOAT128 */ 381 #define PetscSqrtScalar(a) sqrtq(a) 382 #define PetscPowScalar(a,b) powq(a,b) 383 #define PetscExpScalar(a) expq(a) 384 #define PetscLogScalar(a) logq(a) 385 #define PetscSinScalar(a) sinq(a) 386 #define PetscCosScalar(a) cosq(a) 387 #define PetscAsinScalar(a) asinq(a) 388 #define PetscAcosScalar(a) acosq(a) 389 #define PetscTanScalar(a) tanq(a) 390 #define PetscSinhScalar(a) sinhq(a) 391 #define PetscCoshScalar(a) coshq(a) 392 #define PetscTanhScalar(a) tanhq(a) 393 #endif /* PETSC_USE_REAL___FLOAT128 */ 394 395 #endif /* PETSC_USE_COMPLEX */ 396 397 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 398 #define PetscSignReal(a) (((a) >= 0.0) ? ((a) == 0.0 ? 0.0 : 1.0) : -1.0) 399 #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a))) 400 401 /* --------------------------------------------------------------------------*/ 402 403 /* 404 Certain objects may be created using either single or double precision. 405 This is currently not used. 406 */ 407 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE, PETSC_SCALAR_HALF } PetscScalarPrecision; 408 409 #if defined(PETSC_HAVE_COMPLEX) 410 /* PETSC_i is the imaginary number, i */ 411 PETSC_EXTERN PetscComplex PETSC_i; 412 413 /* Try to do the right thing for complex number construction: see 414 415 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm 416 417 for details 418 */ 419 PETSC_STATIC_INLINE PetscComplex PetscCMPLX(PetscReal x, PetscReal y) 420 { 421 #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128) 422 return PetscComplex(x,y); 423 #elif defined(_Imaginary_I) 424 return x + y * _Imaginary_I; 425 #else 426 { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5), 427 428 "For each floating type there is a corresponding real type, which is always a real floating 429 type. For real floating types, it is the same type. For complex types, it is the type given 430 by deleting the keyword _Complex from the type name." 431 432 So type punning should be portable. */ 433 union { PetscComplex z; PetscReal f[2]; } uz; 434 435 uz.f[0] = x; 436 uz.f[1] = y; 437 return uz.z; 438 } 439 #endif 440 } 441 #endif 442 443 444 /*MC 445 PetscMin - Returns minimum of two numbers 446 447 Synopsis: 448 #include <petscmath.h> 449 type PetscMin(type v1,type v2) 450 451 Not Collective 452 453 Input Parameter: 454 + v1 - first value to find minimum of 455 - v2 - second value to find minimum of 456 457 Notes: type can be integer or floating point value 458 459 Level: beginner 460 461 .seealso: PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 462 463 M*/ 464 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 465 466 /*MC 467 PetscMax - Returns maxium of two numbers 468 469 Synopsis: 470 #include <petscmath.h> 471 type max PetscMax(type v1,type v2) 472 473 Not Collective 474 475 Input Parameter: 476 + v1 - first value to find maximum of 477 - v2 - second value to find maximum of 478 479 Notes: type can be integer or floating point value 480 481 Level: beginner 482 483 .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 484 485 M*/ 486 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 487 488 /*MC 489 PetscClipInterval - Returns a number clipped to be within an interval 490 491 Synopsis: 492 #include <petscmath.h> 493 type clip PetscClipInterval(type x,type a,type b) 494 495 Not Collective 496 497 Input Parameter: 498 + x - value to use if within interval (a,b) 499 . a - lower end of interval 500 - b - upper end of interval 501 502 Notes: type can be integer or floating point value 503 504 Level: beginner 505 506 .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 507 508 M*/ 509 #define PetscClipInterval(x,a,b) (PetscMax((a),PetscMin((x),(b)))) 510 511 /*MC 512 PetscAbsInt - Returns the absolute value of an integer 513 514 Synopsis: 515 #include <petscmath.h> 516 int abs PetscAbsInt(int v1) 517 518 Not Collective 519 520 Input Parameter: 521 . v1 - the integer 522 523 Level: beginner 524 525 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 526 527 M*/ 528 #define PetscAbsInt(a) (((a)<0) ? (-(a)) : (a)) 529 530 /*MC 531 PetscAbsReal - Returns the absolute value of an real number 532 533 Synopsis: 534 #include <petscmath.h> 535 Real abs PetscAbsReal(PetscReal v1) 536 537 Not Collective 538 539 Input Parameter: 540 . v1 - the double 541 542 543 Level: beginner 544 545 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 546 547 M*/ 548 #if defined(PETSC_USE_REAL_SINGLE) 549 #define PetscAbsReal(a) fabsf(a) 550 #elif defined(PETSC_USE_REAL_DOUBLE) 551 #define PetscAbsReal(a) fabs(a) 552 #elif defined(PETSC_USE_REAL___FLOAT128) 553 #define PetscAbsReal(a) fabsq(a) 554 #elif defined(PETSC_USE_REAL___FP16) 555 #define PetscAbsReal(a) fabsf(a) 556 #endif 557 558 /*MC 559 PetscSqr - Returns the square of a number 560 561 Synopsis: 562 #include <petscmath.h> 563 type sqr PetscSqr(type v1) 564 565 Not Collective 566 567 Input Parameter: 568 . v1 - the value 569 570 Notes: type can be integer or floating point value 571 572 Level: beginner 573 574 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 575 576 M*/ 577 #define PetscSqr(a) ((a)*(a)) 578 579 /* ----------------------------------------------------------------------------*/ 580 581 #if defined(PETSC_USE_REAL_SINGLE) 582 #define PetscRealConstant(constant) constant##F 583 #elif defined(PETSC_USE_REAL___FLOAT128) 584 #define PetscRealConstant(constant) constant##Q 585 #else 586 #define PetscRealConstant(constant) constant 587 #endif 588 589 /* 590 Basic constants 591 */ 592 #define PETSC_PI PetscRealConstant(3.1415926535897932384626433832795029) 593 #define PETSC_PHI PetscRealConstant(1.6180339887498948482045868343656381) 594 595 #if !defined(PETSC_USE_64BIT_INDICES) 596 #define PETSC_MAX_INT 2147483647 597 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 598 #else 599 #define PETSC_MAX_INT 9223372036854775807L 600 #define PETSC_MIN_INT (-PETSC_MAX_INT - 1) 601 #endif 602 603 #if defined(PETSC_USE_REAL_SINGLE) 604 # define PETSC_MAX_REAL 3.40282346638528860e+38F 605 # define PETSC_MIN_REAL (-PETSC_MAX_REAL) 606 # define PETSC_MACHINE_EPSILON 1.19209290e-07F 607 # define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F 608 # define PETSC_SMALL 1.e-5F 609 #elif defined(PETSC_USE_REAL_DOUBLE) 610 # define PETSC_MAX_REAL 1.7976931348623157e+308 611 # define PETSC_MIN_REAL (-PETSC_MAX_REAL) 612 # define PETSC_MACHINE_EPSILON 2.2204460492503131e-16 613 # define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08 614 # define PETSC_SMALL 1.e-10 615 #elif defined(PETSC_USE_REAL___FLOAT128) 616 # define PETSC_MAX_REAL FLT128_MAX 617 # define PETSC_MIN_REAL (-FLT128_MAX) 618 # define PETSC_MACHINE_EPSILON FLT128_EPSILON 619 # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q 620 # define PETSC_SMALL 1.e-20Q 621 #elif defined(PETSC_USE_REAL___FP16) /* maybe should use single precision values for these? */ 622 # define PETSC_MAX_REAL 65504. 623 # define PETSC_MIN_REAL (-PETSC_MAX_REAL) 624 # define PETSC_MACHINE_EPSILON .00097656 625 # define PETSC_SQRT_MACHINE_EPSILON .0312 626 # define PETSC_SMALL 5.e-3 627 #endif 628 629 #define PETSC_INFINITY (PETSC_MAX_REAL/4) 630 #define PETSC_NINFINITY (-PETSC_INFINITY) 631 632 PETSC_EXTERN PetscBool PetscIsInfReal(PetscReal); 633 PETSC_EXTERN PetscBool PetscIsNanReal(PetscReal); 634 PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal); 635 PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanReal(PetscReal v) {return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;} 636 PETSC_STATIC_INLINE PetscBool PetscIsInfScalar(PetscScalar v) {return PetscIsInfReal(PetscAbsScalar(v));} 637 PETSC_STATIC_INLINE PetscBool PetscIsNanScalar(PetscScalar v) {return PetscIsNanReal(PetscAbsScalar(v));} 638 PETSC_STATIC_INLINE PetscBool PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));} 639 PETSC_STATIC_INLINE PetscBool PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));} 640 641 PETSC_EXTERN PetscBool PetscEqualReal(PetscReal,PetscReal); 642 PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar,PetscScalar); 643 644 /* 645 These macros are currently hardwired to match the regular data types, so there is no support for a different 646 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 647 */ 648 #define MPIU_MATSCALAR MPIU_SCALAR 649 typedef PetscScalar MatScalar; 650 typedef PetscReal MatReal; 651 652 struct petsc_mpiu_2scalar {PetscScalar a,b;}; 653 PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar); 654 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT) 655 struct petsc_mpiu_2int {PetscInt a,b;}; 656 PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int); 657 #else 658 #define MPIU_2INT MPI_2INT 659 #endif 660 661 PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power) 662 { 663 PetscInt result = 1; 664 while (power) { 665 if (power & 1) result *= base; 666 power >>= 1; 667 base *= base; 668 } 669 return result; 670 } 671 672 PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power) 673 { 674 PetscReal result = 1; 675 if (power < 0) { 676 power = -power; 677 base = ((PetscReal)1)/base; 678 } 679 while (power) { 680 if (power & 1) result *= base; 681 power >>= 1; 682 base *= base; 683 } 684 return result; 685 } 686 687 PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power) 688 { 689 PetscScalar result = 1; 690 if (power < 0) { 691 power = -power; 692 base = ((PetscReal)1)/base; 693 } 694 while (power) { 695 if (power & 1) result *= base; 696 power >>= 1; 697 base *= base; 698 } 699 return result; 700 } 701 702 PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power) 703 { 704 PetscScalar cpower = power; 705 return PetscPowScalar(base,cpower); 706 } 707 708 #ifndef PETSC_HAVE_LOG2 709 PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n) 710 { 711 return PetscLogReal(n)/PetscLogReal(2.0); 712 } 713 #endif 714 #endif 715