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