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