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