Actual source code: petscmath.h

petsc-master 2019-09-18
Report Typos and Errors
  1: /*

  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.

  7:     This file is included by petscsys.h and should not be used directly.

  9: */

 11: #if !defined(PETSCMATH_H)
 12: #define PETSCMATH_H
 13: #include <math.h>
 14:  #include <petscsystypes.h>

 16: /*

 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.

 22: */

 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)

 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)

 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)

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)

135: #endif /* PETSC_USE_REAL_* */

137: PETSC_STATIC_INLINE PetscReal PetscSignReal(PetscReal a)
138: {
139:   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
140: }

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

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

157: /*MC
158:    MPIU_REAL - MPI datatype corresponding to PetscReal

160:    Notes:
161:    In MPI calls that require an MPI datatype that matches a PetscReal or array of PetscReal values, pass this value.

163:    Level: beginner

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_* */

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 */

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)

206: /* TODO: Add configure tests

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

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

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

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

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

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

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

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

275: */

277: #elif defined(PETSC_HAVE_C99_COMPLEX) && !defined(PETSC_USE_REAL___FP16)
278: /* C99 support of complex number */

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)

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)

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)

349: #endif /* PETSC_USE_REAL_* */
350: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */

352: /*
353:    PETSC_i is the imaginary number, i
354: */
355: PETSC_EXTERN PetscComplex PETSC_i;

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),

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."

375:        So type punning should be portable. */
376:     union { PetscComplex z; PetscReal f[2]; } uz;

378:     uz.f[0] = x;
379:     uz.f[1] = y;
380:     return uz.z;
381:   }
382: #endif
383: }

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 */

406: /*MC
407:    MPIU_COMPLEX - MPI datatype corresponding to PetscComplex

409:    Notes:
410:    In MPI calls that require an MPI datatype that matches a PetscComplex or array of PetscComplex values, pass this value.

412:    Level: beginner

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_* */

426: #endif /* PETSC_HAVE_COMPLEX */

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

435:    Notes:
436:    In MPI calls that require an MPI datatype that matches a PetscScalar or array of PetscScalar values, pass this value.

438:    Level: beginner

440: .seealso: PetscReal, PetscScalar, PetscComplex, PetscInt, MPIU_REAL, MPIU_COMPLEX, MPIU_INT
441: M*/
442: #define MPIU_SCALAR MPIU_COMPLEX

444: /*MC
445:    PetscRealPart - Returns the real part of a PetscScalar

447:    Synopsis:
448:    #include <petscmath.h>
449:    PetscReal PetscRealPart(PetscScalar v)

451:    Not Collective

453:    Input Parameter:
454: .  v - value to find the real part of

456:    Level: beginner

458: .seealso: PetscScalar, PetscImaginaryPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

460: M*/
461: #define PetscRealPart(a)      PetscRealPartComplex(a)

463: /*MC
464:    PetscImaginaryPart - Returns the imaginary part of a PetscScalar

466:    Synopsis:
467:    #include <petscmath.h>
468:    PetscReal PetscImaginaryPart(PetscScalar v)

470:    Not Collective

472:    Input Parameter:
473: .  v - value to find the imaginary part of

475:    Level: beginner

477:    Notes:
478:        If PETSc was configured for real numbers then this always returns the value 0

480: .seealso: PetscScalar, PetscRealPart(), PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

482: M*/
483: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)

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)

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)

529: #endif /* PETSC_USE_COMPLEX */

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;

537: /* --------------------------------------------------------------------------*/

539: /*MC
540:    PetscAbs - Returns the absolute value of a number

542:    Synopsis:
543:    #include <petscmath.h>
544:    type PetscAbs(type v)

546:    Not Collective

548:    Input Parameter:
549: .  v - the number

551:    Notes:
552:     type can be integer or real floating point value

554:    Level: beginner

556: .seealso: PetscAbsInt(), PetscAbsReal(), PetscAbsScalar()

558: M*/
559: #define PetscAbs(a)  (((a) >= 0) ? (a) : (-(a)))

561: /*MC
562:    PetscSign - Returns the sign of a number as an integer

564:    Synopsis:
565:    #include <petscmath.h>
566:    int PetscSign(type v)

568:    Not Collective

570:    Input Parameter:
571: .  v - the number

573:    Notes:
574:     type can be integer or real floating point value

576:    Level: beginner

578: M*/
579: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

581: /*MC
582:    PetscMin - Returns minimum of two numbers

584:    Synopsis:
585:    #include <petscmath.h>
586:    type PetscMin(type v1,type v2)

588:    Not Collective

590:    Input Parameter:
591: +  v1 - first value to find minimum of
592: -  v2 - second value to find minimum of

594:    Notes:
595:     type can be integer or floating point value

597:    Level: beginner

599: .seealso: PetscMax(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

601: M*/
602: #define PetscMin(a,b)   (((a)<(b)) ?  (a) : (b))

604: /*MC
605:    PetscMax - Returns maxium of two numbers

607:    Synopsis:
608:    #include <petscmath.h>
609:    type max PetscMax(type v1,type v2)

611:    Not Collective

613:    Input Parameter:
614: +  v1 - first value to find maximum of
615: -  v2 - second value to find maximum of

617:    Notes:
618:     type can be integer or floating point value

620:    Level: beginner

622: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

624: M*/
625: #define PetscMax(a,b)   (((a)<(b)) ?  (b) : (a))

627: /*MC
628:    PetscClipInterval - Returns a number clipped to be within an interval

630:    Synopsis:
631:    #include <petscmath.h>
632:    type clip PetscClipInterval(type x,type a,type b)

634:    Not Collective

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

641:    Notes:
642:     type can be integer or floating point value

644:    Level: beginner

646: .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()

648: M*/
649: #define PetscClipInterval(x,a,b)   (PetscMax((a),PetscMin((x),(b))))

651: /*MC
652:    PetscAbsInt - Returns the absolute value of an integer

654:    Synopsis:
655:    #include <petscmath.h>
656:    int abs PetscAbsInt(int v1)

658:    Not Collective

660:    Input Parameter:
661: .   v1 - the integer

663:    Level: beginner

665: .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()

667: M*/
668: #define PetscAbsInt(a)  (((a)<0)   ? (-(a)) : (a))

670: /*MC
671:    PetscAbsReal - Returns the absolute value of an real number

673:    Synopsis:
674:    #include <petscmath.h>
675:    Real abs PetscAbsReal(PetscReal v1)

677:    Not Collective

679:    Input Parameter:
680: .   v1 - the double


683:    Level: beginner

685: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()

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

698: /*MC
699:    PetscSqr - Returns the square of a number

701:    Synopsis:
702:    #include <petscmath.h>
703:    type sqr PetscSqr(type v1)

705:    Not Collective

707:    Input Parameter:
708: .   v1 - the value

710:    Notes:
711:     type can be integer or floating point value

713:    Level: beginner

715: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()

717: M*/
718: #define PetscSqr(a)     ((a)*(a))

720: /* ----------------------------------------------------------------------------*/

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

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)

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

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

773: #define PETSC_INFINITY               (PETSC_MAX_REAL/4)
774: #define PETSC_NINFINITY              (-PETSC_INFINITY)

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));}

785: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal,PetscReal,PetscReal,PetscReal);
786: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal,PetscReal);
787: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar,PetscScalar);

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;

797: struct petsc_mpiu_2scalar {PetscScalar a,b;};
798: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);

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

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: }

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: }

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: }

848: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
849: {
850:   PetscScalar cpower = power;
851:   return PetscPowScalar(base,cpower);
852: }

854: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt,const PetscReal[],const PetscReal[],PetscReal*,PetscReal*);
855: #endif