Actual source code: petscmath.h

  1: /*
  2:     PETSc mathematics include file. Defines certain basic mathematical
  3:     constants and functions for working with single, double, and quad precision
  4:     floating point numbers as well as complex single and double.

  6:     This file is included by petscsys.h and should not be used directly.
  7: */
  8: #pragma once

 10: #include <math.h>
 11: #include <petscmacros.h>
 12: #include <petscsystypes.h>

 14: /* SUBMANSEC = Sys */

 16: /*
 17:    Defines operations that are different for complex and real numbers.
 18:    All PETSc objects in one program are built around the object
 19:    PetscScalar which is either always a real or a complex.
 20: */

 22: /*
 23:     Real number definitions
 24:  */
 25: #if defined(PETSC_USE_REAL_SINGLE)
 26:   /*MC
 27:     PetscSqrtReal - Returns the square root of a `PetscReal` value

 29:     Synopsis:
 30: #include <petscmath.h>
 31:     PetscReal PetscSqrtReal(PetscReal a)

 33:     Not Collective; No Fortran Support

 35:     Input Parameter:
 36:   . a - the value

 38:     Level: beginner

 40: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtComplex()`, `PetscSqrtScalar()`
 41:   M*/
 42:   #define PetscSqrtReal(a) sqrtf(a)
 43:   /*MC
 44:     PetscCbrtReal - Returns the cube root of a `PetscReal` value

 46:     Synopsis:
 47: #include <petscmath.h>
 48:     PetscReal PetscCbrtReal(PetscReal a)

 50:     Not Collective; No Fortran Support

 52:     Input Parameter:
 53:   . a - the value

 55:     Level: beginner

 57: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 58:   M*/
 59:   #define PetscCbrtReal(a) cbrtf(a)
 60:   /*MC
 61:     PetscHypotReal - Returns the Euclidean distance `sqrt(a*a + b*b)` of two `PetscReal` values, without intermediate overflow

 63:     Synopsis:
 64: #include <petscmath.h>
 65:     PetscReal PetscHypotReal(PetscReal a, PetscReal b)

 67:     Not Collective; No Fortran Support

 69:     Input Parameters:
 70:   + a - the value
 71:   - b - the value

 73:     Level: beginner

 75: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 76:   M*/
 77:   #define PetscHypotReal(a, b) hypotf(a, b)
 78:   /*MC
 79:     PetscAtan2Real - Returns the arc tangent of `a/b`, in the range $[-\pi, \pi]$, using the signs of `a` and `b` to select the quadrant

 81:     Synopsis:
 82: #include <petscmath.h>
 83:     PetscReal PetscAtan2Real(PetscReal a, PetscReal b)

 85:     Not Collective; No Fortran Support

 87:     Input Parameters:
 88:   + a - the value
 89:   - b - the value

 91:     Level: beginner

 93: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 94:   M*/
 95:   #define PetscAtan2Real(a, b) atan2f(a, b)
 96:   /*MC
 97:     PetscPowReal - Returns the value of `a` raised to the power `b`, both `PetscReal`

 99:     Synopsis:
100: #include <petscmath.h>
101:     PetscReal PetscPowReal(PetscReal a, PetscReal b)

103:     Not Collective; No Fortran Support

105:     Input Parameters:
106:   + a - the value
107:   - b - the value

109:     Level: beginner

111: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowComplex()`, `PetscPowScalar()`
112:   M*/
113:   #define PetscPowReal(a, b) powf(a, b)
114:   /*MC
115:     PetscExpReal - Returns the natural exponential $e^a$ of a `PetscReal` value

117:     Synopsis:
118: #include <petscmath.h>
119:     PetscReal PetscExpReal(PetscReal a)

121:     Not Collective; No Fortran Support

123:     Input Parameter:
124:   . a - the value

126:     Level: beginner

128: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpComplex()`, `PetscExpScalar()`
129:   M*/
130:   #define PetscExpReal(a) expf(a)
131:   /*MC
132:     PetscLogReal - Returns the natural logarithm of a `PetscReal` value

134:     Synopsis:
135: #include <petscmath.h>
136:     PetscReal PetscLogReal(PetscReal a)

138:     Not Collective; No Fortran Support

140:     Input Parameter:
141:   . a - the value

143:     Level: beginner

145: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogComplex()`, `PetscLogScalar()`
146:   M*/
147:   #define PetscLogReal(a) logf(a)
148:   /*MC
149:     PetscLog10Real - Returns the base-10 logarithm of a `PetscReal` value

151:     Synopsis:
152: #include <petscmath.h>
153:     PetscReal PetscLog10Real(PetscReal a)

155:     Not Collective; No Fortran Support

157:     Input Parameter:
158:   . a - the value

160:     Level: beginner

162: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
163:   M*/
164:   #define PetscLog10Real(a) log10f(a)
165:   /*MC
166:     PetscLog2Real - Returns the base-2 logarithm of a `PetscReal` value

168:     Synopsis:
169: #include <petscmath.h>
170:     PetscReal PetscLog2Real(PetscReal a)

172:     Not Collective; No Fortran Support

174:     Input Parameter:
175:   . a - the value

177:     Level: beginner

179: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
180:   M*/
181:   #define PetscLog2Real(a) log2f(a)
182:   /*MC
183:     PetscSinReal - Returns the sine of a `PetscReal` value, with argument in radians

185:     Synopsis:
186: #include <petscmath.h>
187:     PetscReal PetscSinReal(PetscReal a)

189:     Not Collective; No Fortran Support

191:     Input Parameter:
192:   . a - the value

194:     Level: beginner

196: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinComplex()`, `PetscSinScalar()`
197:   M*/
198:   #define PetscSinReal(a) sinf(a)
199:   /*MC
200:     PetscCosReal - Returns the cosine of a `PetscReal` value, with argument in radians

202:     Synopsis:
203: #include <petscmath.h>
204:     PetscReal PetscCosReal(PetscReal a)

206:     Not Collective; No Fortran Support

208:     Input Parameter:
209:   . a - the value

211:     Level: beginner

213: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosComplex()`, `PetscCosScalar()`
214:   M*/
215:   #define PetscCosReal(a) cosf(a)
216:   /*MC
217:     PetscTanReal - Returns the tangent of a `PetscReal` value, with argument in radians

219:     Synopsis:
220: #include <petscmath.h>
221:     PetscReal PetscTanReal(PetscReal a)

223:     Not Collective; No Fortran Support

225:     Input Parameter:
226:   . a - the value

228:     Level: beginner

230: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanComplex()`, `PetscTanScalar()`
231:   M*/
232:   #define PetscTanReal(a) tanf(a)
233:   /*MC
234:     PetscAsinReal - Returns the arc sine of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

236:     Synopsis:
237: #include <petscmath.h>
238:     PetscReal PetscAsinReal(PetscReal a)

240:     Not Collective; No Fortran Support

242:     Input Parameter:
243:   . a - the value

245:     Level: beginner

247: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinComplex()`, `PetscAsinScalar()`
248:   M*/
249:   #define PetscAsinReal(a) asinf(a)
250:   /*MC
251:     PetscAcosReal - Returns the arc cosine of a `PetscReal` value, returned in radians in the range $[0, \pi]$

253:     Synopsis:
254: #include <petscmath.h>
255:     PetscReal PetscAcosReal(PetscReal a)

257:     Not Collective; No Fortran Support

259:     Input Parameter:
260:   . a - the value

262:     Level: beginner

264: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosComplex()`, `PetscAcosScalar()`
265:   M*/
266:   #define PetscAcosReal(a) acosf(a)
267:   /*MC
268:     PetscAtanReal - Returns the arc tangent of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

270:     Synopsis:
271: #include <petscmath.h>
272:     PetscReal PetscAtanReal(PetscReal a)

274:     Not Collective; No Fortran Support

276:     Input Parameter:
277:   . a - the value

279:     Level: beginner

281: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanComplex()`, `PetscAtanScalar()`
282:   M*/
283:   #define PetscAtanReal(a) atanf(a)
284:   /*MC
285:     PetscSinhReal - Returns the hyperbolic sine of a `PetscReal` value

287:     Synopsis:
288: #include <petscmath.h>
289:     PetscReal PetscSinhReal(PetscReal a)

291:     Not Collective; No Fortran Support

293:     Input Parameter:
294:   . a - the value

296:     Level: beginner

298: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhComplex()`, `PetscSinhScalar()`
299:   M*/
300:   #define PetscSinhReal(a) sinhf(a)
301:   /*MC
302:     PetscCoshReal - Returns the hyperbolic cosine of a `PetscReal` value

304:     Synopsis:
305: #include <petscmath.h>
306:     PetscReal PetscCoshReal(PetscReal a)

308:     Not Collective; No Fortran Support

310:     Input Parameter:
311:   . a - the value

313:     Level: beginner

315: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshComplex()`, `PetscCoshScalar()`
316:   M*/
317:   #define PetscCoshReal(a) coshf(a)
318:   /*MC
319:     PetscTanhReal - Returns the hyperbolic tangent of a `PetscReal` value

321:     Synopsis:
322: #include <petscmath.h>
323:     PetscReal PetscTanhReal(PetscReal a)

325:     Not Collective; No Fortran Support

327:     Input Parameter:
328:   . a - the value

330:     Level: beginner

332: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhComplex()`, `PetscTanhScalar()`
333:   M*/
334:   #define PetscTanhReal(a) tanhf(a)
335:   /*MC
336:     PetscAsinhReal - Returns the inverse hyperbolic sine of a `PetscReal` value

338:     Synopsis:
339: #include <petscmath.h>
340:     PetscReal PetscAsinhReal(PetscReal a)

342:     Not Collective; No Fortran Support

344:     Input Parameter:
345:   . a - the value

347:     Level: beginner

349: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhComplex()`, `PetscAsinhScalar()`
350:   M*/
351:   #define PetscAsinhReal(a) asinhf(a)
352:   /*MC
353:     PetscAcoshReal - Returns the inverse hyperbolic cosine of a `PetscReal` value

355:     Synopsis:
356: #include <petscmath.h>
357:     PetscReal PetscAcoshReal(PetscReal a)

359:     Not Collective; No Fortran Support

361:     Input Parameter:
362:   . a - the value

364:     Level: beginner

366: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshComplex()`, `PetscAcoshScalar()`
367:   M*/
368:   #define PetscAcoshReal(a) acoshf(a)
369:   /*MC
370:     PetscAtanhReal - Returns the inverse hyperbolic tangent of a `PetscReal` value

372:     Synopsis:
373: #include <petscmath.h>
374:     PetscReal PetscAtanhReal(PetscReal a)

376:     Not Collective; No Fortran Support

378:     Input Parameter:
379:   . a - the value

381:     Level: beginner

383: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhComplex()`, `PetscAtanhScalar()`
384:   M*/
385:   #define PetscAtanhReal(a) atanhf(a)
386:   /*MC
387:     PetscErfReal - Returns the error function of a `PetscReal` value

389:     Synopsis:
390: #include <petscmath.h>
391:     PetscReal PetscErfReal(PetscReal a)

393:     Not Collective; No Fortran Support

395:     Input Parameter:
396:   . a - the value

398:     Level: beginner

400: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
401:   M*/
402:   #define PetscErfReal(a) erff(a)
403:   /*MC
404:     PetscCeilReal - Returns the smallest integer value, returned as a `PetscReal`, that is not less than `a`

406:     Synopsis:
407: #include <petscmath.h>
408:     PetscReal PetscCeilReal(PetscReal a)

410:     Not Collective; No Fortran Support

412:     Input Parameter:
413:   . a - the value

415:     Level: beginner

417: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
418:   M*/
419:   #define PetscCeilReal(a) ceilf(a)
420:   /*MC
421:     PetscFloorReal - Returns the largest integer value, returned as a `PetscReal`, that is not greater than `a`

423:     Synopsis:
424: #include <petscmath.h>
425:     PetscReal PetscFloorReal(PetscReal a)

427:     Not Collective; No Fortran Support

429:     Input Parameter:
430:   . a - the value

432:     Level: beginner

434: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
435:   M*/
436:   #define PetscFloorReal(a) floorf(a)
437:   /*MC
438:     PetscRintReal - Returns the value of `a` rounded to the nearest integer, returned as a `PetscReal` in the configured precision

440:     Synopsis:
441: #include <petscmath.h>
442:     PetscReal PetscRintReal(PetscReal a)

444:     Not Collective; No Fortran Support

446:     Input Parameter:
447:   . a - the value

449:     Level: beginner

451: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
452:   M*/
453:   #define PetscRintReal(a) rintf(a)
454:   /*MC
455:     PetscFmodReal - Returns the floating-point remainder of `a/b`, with the same sign as `a`, returned as a `PetscReal`

457:     Synopsis:
458: #include <petscmath.h>
459:     PetscReal PetscFmodReal(PetscReal a, PetscReal b)

461:     Not Collective; No Fortran Support

463:     Input Parameters:
464:   + a - the value
465:   - b - the value

467:     Level: beginner

469: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
470:   M*/
471:   #define PetscFmodReal(a, b) fmodf(a, b)
472:   /*MC
473:     PetscCopysignReal - Returns the value with the magnitude of `a` and the sign of `b`, as a `PetscReal`

475:     Synopsis:
476: #include <petscmath.h>
477:     PetscReal PetscCopysignReal(PetscReal a, PetscReal b)

479:     Not Collective; No Fortran Support

481:     Input Parameters:
482:   + a - the value
483:   - b - the value

485:     Level: beginner

487: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
488:   M*/
489:   #define PetscCopysignReal(a, b) copysignf(a, b)
490:   /*MC
491:     PetscTGamma - Returns the value of the gamma function $\Gamma(a)$ in the configured `PetscReal` precision

493:     Synopsis:
494: #include <petscmath.h>
495:     PetscReal PetscTGamma(PetscReal a)

497:     Not Collective; No Fortran Support

499:     Input Parameter:
500:   . a - the value

502:     Level: beginner

504: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
505:   M*/
506:   #define PetscTGamma(a) tgammaf(a)
507:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
508:     /*MC
509:       PetscLGamma - Returns the natural logarithm of the absolute value of the gamma function in the configured `PetscReal` precision

511:       Synopsis:
512: #include <petscmath.h>
513:       PetscReal PetscLGamma(PetscReal a)

515:       Not Collective; No Fortran Support

517:       Input Parameter:
518:     . a - the value

520:       Level: beginner

522: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
523:     M*/
524:     #define PetscLGamma(a) gammaf(a)
525:   #else
526:     #define PetscLGamma(a) lgammaf(a)
527:   #endif

529: #elif defined(PETSC_USE_REAL_DOUBLE)
530:   #define PetscSqrtReal(a)        sqrt(a)
531:   #define PetscCbrtReal(a)        cbrt(a)
532:   #define PetscHypotReal(a, b)    hypot(a, b)
533:   #define PetscAtan2Real(a, b)    atan2(a, b)
534:   #define PetscPowReal(a, b)      pow(a, b)
535:   #define PetscExpReal(a)         exp(a)
536:   #define PetscLogReal(a)         log(a)
537:   #define PetscLog10Real(a)       log10(a)
538:   #define PetscLog2Real(a)        log2(a)
539:   #define PetscSinReal(a)         sin(a)
540:   #define PetscCosReal(a)         cos(a)
541:   #define PetscTanReal(a)         tan(a)
542:   #define PetscAsinReal(a)        asin(a)
543:   #define PetscAcosReal(a)        acos(a)
544:   #define PetscAtanReal(a)        atan(a)
545:   #define PetscSinhReal(a)        sinh(a)
546:   #define PetscCoshReal(a)        cosh(a)
547:   #define PetscTanhReal(a)        tanh(a)
548:   #define PetscAsinhReal(a)       asinh(a)
549:   #define PetscAcoshReal(a)       acosh(a)
550:   #define PetscAtanhReal(a)       atanh(a)
551:   #define PetscErfReal(a)         erf(a)
552:   #define PetscCeilReal(a)        ceil(a)
553:   #define PetscFloorReal(a)       floor(a)
554:   #define PetscRintReal(a)        rint(a)
555:   #define PetscFmodReal(a, b)     fmod(a, b)
556:   #define PetscCopysignReal(a, b) copysign(a, b)
557:   #define PetscTGamma(a)          tgamma(a)
558:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
559:     #define PetscLGamma(a) gamma(a)
560:   #else
561:     #define PetscLGamma(a) lgamma(a)
562:   #endif

564: #elif defined(PETSC_USE_REAL___FLOAT128)
565:   #define PetscSqrtReal(a)        sqrtq(a)
566:   #define PetscCbrtReal(a)        cbrtq(a)
567:   #define PetscHypotReal(a, b)    hypotq(a, b)
568:   #define PetscAtan2Real(a, b)    atan2q(a, b)
569:   #define PetscPowReal(a, b)      powq(a, b)
570:   #define PetscExpReal(a)         expq(a)
571:   #define PetscLogReal(a)         logq(a)
572:   #define PetscLog10Real(a)       log10q(a)
573:   #define PetscLog2Real(a)        log2q(a)
574:   #define PetscSinReal(a)         sinq(a)
575:   #define PetscCosReal(a)         cosq(a)
576:   #define PetscTanReal(a)         tanq(a)
577:   #define PetscAsinReal(a)        asinq(a)
578:   #define PetscAcosReal(a)        acosq(a)
579:   #define PetscAtanReal(a)        atanq(a)
580:   #define PetscSinhReal(a)        sinhq(a)
581:   #define PetscCoshReal(a)        coshq(a)
582:   #define PetscTanhReal(a)        tanhq(a)
583:   #define PetscAsinhReal(a)       asinhq(a)
584:   #define PetscAcoshReal(a)       acoshq(a)
585:   #define PetscAtanhReal(a)       atanhq(a)
586:   #define PetscErfReal(a)         erfq(a)
587:   #define PetscCeilReal(a)        ceilq(a)
588:   #define PetscFloorReal(a)       floorq(a)
589:   #define PetscRintReal(a)        rintq(a)
590:   #define PetscFmodReal(a, b)     fmodq(a, b)
591:   #define PetscCopysignReal(a, b) copysignq(a, b)
592:   #define PetscTGamma(a)          tgammaq(a)
593:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
594:     #define PetscLGamma(a) gammaq(a)
595:   #else
596:     #define PetscLGamma(a) lgammaq(a)
597:   #endif

599: #elif defined(PETSC_USE_REAL___FP16)
600:   #define PetscSqrtReal(a)        sqrtf(a)
601:   #define PetscCbrtReal(a)        cbrtf(a)
602:   #define PetscHypotReal(a, b)    hypotf(a, b)
603:   #define PetscAtan2Real(a, b)    atan2f(a, b)
604:   #define PetscPowReal(a, b)      powf(a, b)
605:   #define PetscExpReal(a)         expf(a)
606:   #define PetscLogReal(a)         logf(a)
607:   #define PetscLog10Real(a)       log10f(a)
608:   #define PetscLog2Real(a)        log2f(a)
609:   #define PetscSinReal(a)         sinf(a)
610:   #define PetscCosReal(a)         cosf(a)
611:   #define PetscTanReal(a)         tanf(a)
612:   #define PetscAsinReal(a)        asinf(a)
613:   #define PetscAcosReal(a)        acosf(a)
614:   #define PetscAtanReal(a)        atanf(a)
615:   #define PetscSinhReal(a)        sinhf(a)
616:   #define PetscCoshReal(a)        coshf(a)
617:   #define PetscTanhReal(a)        tanhf(a)
618:   #define PetscAsinhReal(a)       asinhf(a)
619:   #define PetscAcoshReal(a)       acoshf(a)
620:   #define PetscAtanhReal(a)       atanhf(a)
621:   #define PetscErfReal(a)         erff(a)
622:   #define PetscCeilReal(a)        ceilf(a)
623:   #define PetscFloorReal(a)       floorf(a)
624:   #define PetscRintReal(a)        rintf(a)
625:   #define PetscFmodReal(a, b)     fmodf(a, b)
626:   #define PetscCopysignReal(a, b) copysignf(a, b)
627:   #define PetscTGamma(a)          tgammaf(a)
628:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
629:     #define PetscLGamma(a) gammaf(a)
630:   #else
631:     #define PetscLGamma(a) lgammaf(a)
632:   #endif

634: #endif /* PETSC_USE_REAL_* */

636: static inline PetscReal PetscSignReal(PetscReal a)
637: {
638:   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
639: }

641: #if !defined(PETSC_HAVE_LOG2)
642:   #undef PetscLog2Real
643: static inline PetscReal PetscLog2Real(PetscReal a)
644: {
645:   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
646: }
647: #endif

649: #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
650: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
651: #endif
652: #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
653: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
654: #endif

656: /*MC
657:    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in

659:    Level: beginner

661:    Note:
662:    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.

664: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
665: M*/
666: #if defined(PETSC_USE_REAL_SINGLE)
667:   #define MPIU_REAL MPI_FLOAT
668: #elif defined(PETSC_USE_REAL_DOUBLE)
669:   #define MPIU_REAL MPI_DOUBLE
670: #elif defined(PETSC_USE_REAL___FLOAT128)
671:   #define MPIU_REAL MPIU___FLOAT128
672: #elif defined(PETSC_USE_REAL___FP16)
673:   #define MPIU_REAL MPIU___FP16
674: #endif /* PETSC_USE_REAL_* */

676: /*
677:     Complex number definitions
678:  */
679: #if defined(PETSC_HAVE_COMPLEX)
680:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
681:   /* C++ support of complex number */

683:     /*MC
684:       PetscRealPartComplex - Returns the real part of a `PetscComplex` value, as a `PetscReal`

686:       Synopsis:
687: #include <petscmath.h>
688:       PetscReal PetscRealPartComplex(PetscComplex a)

690:       Not Collective; No Fortran Support

692:       Input Parameter:
693:     . a - the value

695:       Level: beginner

697: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
698:     M*/
699:     #define PetscRealPartComplex(a) (static_cast<PetscComplex>(a)).real()
700:     /*MC
701:       PetscImaginaryPartComplex - Returns the imaginary part of a `PetscComplex` value, as a `PetscReal`

703:       Synopsis:
704: #include <petscmath.h>
705:       PetscReal PetscImaginaryPartComplex(PetscComplex a)

707:       Not Collective; No Fortran Support

709:       Input Parameter:
710:     . a - the value

712:       Level: beginner

714: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
715:     M*/
716:     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
717:     /*MC
718:       PetscAbsComplex - Returns the absolute value (magnitude) of a `PetscComplex` value, as a `PetscReal`

720:       Synopsis:
721: #include <petscmath.h>
722:       PetscReal PetscAbsComplex(PetscComplex a)

724:       Not Collective; No Fortran Support

726:       Input Parameter:
727:     . a - the value

729:       Level: beginner

731: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
732:     M*/
733:     #define PetscAbsComplex(a) petsccomplexlib::abs(static_cast<PetscComplex>(a))
734:     /*MC
735:       PetscArgComplex - Returns the argument (phase angle) of a `PetscComplex` value, as a `PetscReal`

737:       Synopsis:
738: #include <petscmath.h>
739:       PetscReal PetscArgComplex(PetscComplex a)

741:       Not Collective; No Fortran Support

743:       Input Parameter:
744:     . a - the value

746:       Level: beginner

748: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
749:     M*/
750:     #define PetscArgComplex(a) petsccomplexlib::arg(static_cast<PetscComplex>(a))
751:     /*MC
752:       PetscConjComplex - Returns the complex conjugate of a `PetscComplex` value

754:       Synopsis:
755: #include <petscmath.h>
756:       PetscComplex PetscConjComplex(PetscComplex a)

758:       Not Collective; No Fortran Support

760:       Input Parameter:
761:     . a - the value

763:       Level: beginner

765: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConj()`
766:     M*/
767:     #define PetscConjComplex(a) petsccomplexlib::conj(static_cast<PetscComplex>(a))
768:     /*MC
769:       PetscSqrtComplex - Returns the principal value of the square root of a `PetscComplex` value

771:       Synopsis:
772: #include <petscmath.h>
773:       PetscComplex PetscSqrtComplex(PetscComplex a)

775:       Not Collective; No Fortran Support

777:       Input Parameter:
778:     . a - the value

780:       Level: beginner

782: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtScalar()`
783:     M*/
784:     #define PetscSqrtComplex(a) petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
785:     /*MC
786:       PetscPowComplex - Returns the complex value `a` raised to the complex power `b`

788:       Synopsis:
789: #include <petscmath.h>
790:       PetscComplex PetscPowComplex(PetscComplex a, PetscComplex b)

792:       Not Collective; No Fortran Support

794:       Input Parameters:
795:     + a - the value
796:     - b - the value

798:       Level: beginner

800: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowScalar()`
801:     M*/
802:     #define PetscPowComplex(a, b) petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
803:     /*MC
804:       PetscExpComplex - Returns the complex exponential $e^a$ of a `PetscComplex` value

806:       Synopsis:
807: #include <petscmath.h>
808:       PetscComplex PetscExpComplex(PetscComplex a)

810:       Not Collective; No Fortran Support

812:       Input Parameter:
813:     . a - the value

815:       Level: beginner

817: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpScalar()`
818:     M*/
819:     #define PetscExpComplex(a) petsccomplexlib::exp(static_cast<PetscComplex>(a))
820:     /*MC
821:       PetscLogComplex - Returns the principal value of the complex natural logarithm of a `PetscComplex` value

823:       Synopsis:
824: #include <petscmath.h>
825:       PetscComplex PetscLogComplex(PetscComplex a)

827:       Not Collective; No Fortran Support

829:       Input Parameter:
830:     . a - the value

832:       Level: beginner

834: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogScalar()`
835:     M*/
836:     #define PetscLogComplex(a) petsccomplexlib::log(static_cast<PetscComplex>(a))
837:     /*MC
838:       PetscSinComplex - Returns the complex sine of a `PetscComplex` value

840:       Synopsis:
841: #include <petscmath.h>
842:       PetscComplex PetscSinComplex(PetscComplex a)

844:       Not Collective; No Fortran Support

846:       Input Parameter:
847:     . a - the value

849:       Level: beginner

851: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinScalar()`
852:     M*/
853:     #define PetscSinComplex(a) petsccomplexlib::sin(static_cast<PetscComplex>(a))
854:     /*MC
855:       PetscCosComplex - Returns the complex cosine of a `PetscComplex` value

857:       Synopsis:
858: #include <petscmath.h>
859:       PetscComplex PetscCosComplex(PetscComplex a)

861:       Not Collective; No Fortran Support

863:       Input Parameter:
864:     . a - the value

866:       Level: beginner

868: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosScalar()`
869:     M*/
870:     #define PetscCosComplex(a) petsccomplexlib::cos(static_cast<PetscComplex>(a))
871:     /*MC
872:       PetscTanComplex - Returns the complex tangent of a `PetscComplex` value

874:       Synopsis:
875: #include <petscmath.h>
876:       PetscComplex PetscTanComplex(PetscComplex a)

878:       Not Collective; No Fortran Support

880:       Input Parameter:
881:     . a - the value

883:       Level: beginner

885: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanScalar()`
886:     M*/
887:     #define PetscTanComplex(a) petsccomplexlib::tan(static_cast<PetscComplex>(a))
888:     /*MC
889:       PetscAsinComplex - Returns the complex arc sine of a `PetscComplex` value

891:       Synopsis:
892: #include <petscmath.h>
893:       PetscComplex PetscAsinComplex(PetscComplex a)

895:       Not Collective; No Fortran Support

897:       Input Parameter:
898:     . a - the value

900:       Level: beginner

902: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinScalar()`
903:     M*/
904:     #define PetscAsinComplex(a) petsccomplexlib::asin(static_cast<PetscComplex>(a))
905:     /*MC
906:       PetscAcosComplex - Returns the complex arc cosine of a `PetscComplex` value

908:       Synopsis:
909: #include <petscmath.h>
910:       PetscComplex PetscAcosComplex(PetscComplex a)

912:       Not Collective; No Fortran Support

914:       Input Parameter:
915:     . a - the value

917:       Level: beginner

919: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosScalar()`
920:     M*/
921:     #define PetscAcosComplex(a) petsccomplexlib::acos(static_cast<PetscComplex>(a))
922:     /*MC
923:       PetscAtanComplex - Returns the complex arc tangent of a `PetscComplex` value

925:       Synopsis:
926: #include <petscmath.h>
927:       PetscComplex PetscAtanComplex(PetscComplex a)

929:       Not Collective; No Fortran Support

931:       Input Parameter:
932:     . a - the value

934:       Level: beginner

936: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanScalar()`
937:     M*/
938:     #define PetscAtanComplex(a) petsccomplexlib::atan(static_cast<PetscComplex>(a))
939:     /*MC
940:       PetscSinhComplex - Returns the complex hyperbolic sine of a `PetscComplex` value

942:       Synopsis:
943: #include <petscmath.h>
944:       PetscComplex PetscSinhComplex(PetscComplex a)

946:       Not Collective; No Fortran Support

948:       Input Parameter:
949:     . a - the value

951:       Level: beginner

953: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhScalar()`
954:     M*/
955:     #define PetscSinhComplex(a) petsccomplexlib::sinh(static_cast<PetscComplex>(a))
956:     /*MC
957:       PetscCoshComplex - Returns the complex hyperbolic cosine of a `PetscComplex` value

959:       Synopsis:
960: #include <petscmath.h>
961:       PetscComplex PetscCoshComplex(PetscComplex a)

963:       Not Collective; No Fortran Support

965:       Input Parameter:
966:     . a - the value

968:       Level: beginner

970: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshScalar()`
971:     M*/
972:     #define PetscCoshComplex(a) petsccomplexlib::cosh(static_cast<PetscComplex>(a))
973:     /*MC
974:       PetscTanhComplex - Returns the complex hyperbolic tangent of a `PetscComplex` value

976:       Synopsis:
977: #include <petscmath.h>
978:       PetscComplex PetscTanhComplex(PetscComplex a)

980:       Not Collective; No Fortran Support

982:       Input Parameter:
983:     . a - the value

985:       Level: beginner

987: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhScalar()`
988:     M*/
989:     #define PetscTanhComplex(a) petsccomplexlib::tanh(static_cast<PetscComplex>(a))
990:     /*MC
991:       PetscAsinhComplex - Returns the complex inverse hyperbolic sine of a `PetscComplex` value

993:       Synopsis:
994: #include <petscmath.h>
995:       PetscComplex PetscAsinhComplex(PetscComplex a)

997:       Not Collective; No Fortran Support

999:       Input Parameter:
1000:     . a - the value

1002:       Level: beginner

1004: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhScalar()`
1005:     M*/
1006:     #define PetscAsinhComplex(a) petsccomplexlib::asinh(static_cast<PetscComplex>(a))
1007:     /*MC
1008:       PetscAcoshComplex - Returns the complex inverse hyperbolic cosine of a `PetscComplex` value

1010:       Synopsis:
1011: #include <petscmath.h>
1012:       PetscComplex PetscAcoshComplex(PetscComplex a)

1014:       Not Collective; No Fortran Support

1016:       Input Parameter:
1017:     . a - the value

1019:       Level: beginner

1021: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshScalar()`
1022:     M*/
1023:     #define PetscAcoshComplex(a) petsccomplexlib::acosh(static_cast<PetscComplex>(a))
1024:     /*MC
1025:       PetscAtanhComplex - Returns the complex inverse hyperbolic tangent of a `PetscComplex` value

1027:       Synopsis:
1028: #include <petscmath.h>
1029:       PetscComplex PetscAtanhComplex(PetscComplex a)

1031:       Not Collective; No Fortran Support

1033:       Input Parameter:
1034:     . a - the value

1036:       Level: beginner

1038: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhScalar()`
1039:     M*/
1040:     #define PetscAtanhComplex(a) petsccomplexlib::atanh(static_cast<PetscComplex>(a))

1042:   /* TODO: Add configure tests

1044: #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
1045: #undef PetscTanComplex
1046: static inline PetscComplex PetscTanComplex(PetscComplex z)
1047: {
1048:   return PetscSinComplex(z)/PetscCosComplex(z);
1049: }
1050: #endif

1052: #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
1053: #undef PetscTanhComplex
1054: static inline PetscComplex PetscTanhComplex(PetscComplex z)
1055: {
1056:   return PetscSinhComplex(z)/PetscCoshComplex(z);
1057: }
1058: #endif

1060: #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
1061: #undef PetscAsinComplex
1062: static inline PetscComplex PetscAsinComplex(PetscComplex z)
1063: {
1064:   const PetscComplex j(0,1);
1065:   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
1066: }
1067: #endif

1069: #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
1070: #undef PetscAcosComplex
1071: static inline PetscComplex PetscAcosComplex(PetscComplex z)
1072: {
1073:   const PetscComplex j(0,1);
1074:   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
1075: }
1076: #endif

1078: #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
1079: #undef PetscAtanComplex
1080: static inline PetscComplex PetscAtanComplex(PetscComplex z)
1081: {
1082:   const PetscComplex j(0,1);
1083:   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
1084: }
1085: #endif

1087: #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
1088: #undef PetscAsinhComplex
1089: static inline PetscComplex PetscAsinhComplex(PetscComplex z)
1090: {
1091:   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
1092: }
1093: #endif

1095: #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
1096: #undef PetscAcoshComplex
1097: static inline PetscComplex PetscAcoshComplex(PetscComplex z)
1098: {
1099:   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
1100: }
1101: #endif

1103: #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
1104: #undef PetscAtanhComplex
1105: static inline PetscComplex PetscAtanhComplex(PetscComplex z)
1106: {
1107:   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
1108: }
1109: #endif

1111: */

1113:   #else /* C99 support of complex number */

1115:     #if defined(PETSC_USE_REAL_SINGLE)
1116:       #define PetscRealPartComplex(a)      crealf(a)
1117:       #define PetscImaginaryPartComplex(a) cimagf(a)
1118:       #define PetscAbsComplex(a)           cabsf(a)
1119:       #define PetscArgComplex(a)           cargf(a)
1120:       #define PetscConjComplex(a)          conjf(a)
1121:       #define PetscSqrtComplex(a)          csqrtf(a)
1122:       #define PetscPowComplex(a, b)        cpowf(a, b)
1123:       #define PetscExpComplex(a)           cexpf(a)
1124:       #define PetscLogComplex(a)           clogf(a)
1125:       #define PetscSinComplex(a)           csinf(a)
1126:       #define PetscCosComplex(a)           ccosf(a)
1127:       #define PetscTanComplex(a)           ctanf(a)
1128:       #define PetscAsinComplex(a)          casinf(a)
1129:       #define PetscAcosComplex(a)          cacosf(a)
1130:       #define PetscAtanComplex(a)          catanf(a)
1131:       #define PetscSinhComplex(a)          csinhf(a)
1132:       #define PetscCoshComplex(a)          ccoshf(a)
1133:       #define PetscTanhComplex(a)          ctanhf(a)
1134:       #define PetscAsinhComplex(a)         casinhf(a)
1135:       #define PetscAcoshComplex(a)         cacoshf(a)
1136:       #define PetscAtanhComplex(a)         catanhf(a)

1138:     #elif defined(PETSC_USE_REAL_DOUBLE)
1139:       #define PetscRealPartComplex(a)      creal(a)
1140:       #define PetscImaginaryPartComplex(a) cimag(a)
1141:       #define PetscAbsComplex(a)           cabs(a)
1142:       #define PetscArgComplex(a)           carg(a)
1143:       #define PetscConjComplex(a)          conj(a)
1144:       #define PetscSqrtComplex(a)          csqrt(a)
1145:       #define PetscPowComplex(a, b)        cpow(a, b)
1146:       #define PetscExpComplex(a)           cexp(a)
1147:       #define PetscLogComplex(a)           clog(a)
1148:       #define PetscSinComplex(a)           csin(a)
1149:       #define PetscCosComplex(a)           ccos(a)
1150:       #define PetscTanComplex(a)           ctan(a)
1151:       #define PetscAsinComplex(a)          casin(a)
1152:       #define PetscAcosComplex(a)          cacos(a)
1153:       #define PetscAtanComplex(a)          catan(a)
1154:       #define PetscSinhComplex(a)          csinh(a)
1155:       #define PetscCoshComplex(a)          ccosh(a)
1156:       #define PetscTanhComplex(a)          ctanh(a)
1157:       #define PetscAsinhComplex(a)         casinh(a)
1158:       #define PetscAcoshComplex(a)         cacosh(a)
1159:       #define PetscAtanhComplex(a)         catanh(a)

1161:     #elif defined(PETSC_USE_REAL___FLOAT128)
1162:       #define PetscRealPartComplex(a)      crealq(a)
1163:       #define PetscImaginaryPartComplex(a) cimagq(a)
1164:       #define PetscAbsComplex(a)           cabsq(a)
1165:       #define PetscArgComplex(a)           cargq(a)
1166:       #define PetscConjComplex(a)          conjq(a)
1167:       #define PetscSqrtComplex(a)          csqrtq(a)
1168:       #define PetscPowComplex(a, b)        cpowq(a, b)
1169:       #define PetscExpComplex(a)           cexpq(a)
1170:       #define PetscLogComplex(a)           clogq(a)
1171:       #define PetscSinComplex(a)           csinq(a)
1172:       #define PetscCosComplex(a)           ccosq(a)
1173:       #define PetscTanComplex(a)           ctanq(a)
1174:       #define PetscAsinComplex(a)          casinq(a)
1175:       #define PetscAcosComplex(a)          cacosq(a)
1176:       #define PetscAtanComplex(a)          catanq(a)
1177:       #define PetscSinhComplex(a)          csinhq(a)
1178:       #define PetscCoshComplex(a)          ccoshq(a)
1179:       #define PetscTanhComplex(a)          ctanhq(a)
1180:       #define PetscAsinhComplex(a)         casinhq(a)
1181:       #define PetscAcoshComplex(a)         cacoshq(a)
1182:       #define PetscAtanhComplex(a)         catanhq(a)

1184:     #endif /* PETSC_USE_REAL_* */
1185:   #endif   /* (__cplusplus) */

1187: /*MC
1188:    PETSC_i - the pure imaginary complex number i

1190:    Level: intermediate

1192: .seealso: `PetscComplex`, `PetscScalar`
1193: M*/
1194: PETSC_EXTERN PetscComplex PETSC_i;

1196: /*
1197:    Try to do the right thing for complex number construction: see
1198:    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
1199:    for details
1200: */
1201: static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
1202: {
1203:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
1204:   return PetscComplex(x, y);
1205:   #elif defined(_Imaginary_I)
1206:   return x + y * _Imaginary_I;
1207:   #else
1208:   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),

1210:        "For each floating type there is a corresponding real type, which is always a real floating
1211:        type. For real floating types, it is the same type. For complex types, it is the type given
1212:        by deleting the keyword _Complex from the type name."

1214:        So type punning should be portable. */
1215:     union
1216:     {
1217:       PetscComplex z;
1218:       PetscReal    f[2];
1219:     } uz;

1221:     uz.f[0] = x;
1222:     uz.f[1] = y;
1223:     return uz.z;
1224:   }
1225:   #endif
1226: }

1228:   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
1229:   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )

1231:   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
1232:     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
1233:     #if defined(PETSC_USE_COMPLEX)
1234:       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
1235:     #else
1236:       #define MPIU___COMPLEX128_ATTR_TAG
1237:     #endif

1239: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;

1241:     #undef MPIU___COMPLEX128_ATTR_TAG
1242:   #endif /* PETSC_HAVE_REAL___FLOAT128 */

1244:   /*MC
1245:    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`

1247:    Level: beginner

1249:    Note:
1250:    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.

1252: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
1253: M*/
1254:   #if defined(PETSC_USE_REAL_SINGLE)
1255:     #define MPIU_COMPLEX MPI_C_COMPLEX
1256:   #elif defined(PETSC_USE_REAL_DOUBLE)
1257:     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
1258:   #elif defined(PETSC_USE_REAL___FLOAT128)
1259:     #define MPIU_COMPLEX MPIU___COMPLEX128
1260:   #elif defined(PETSC_USE_REAL___FP16)
1261:     #define MPIU_COMPLEX MPI_C_COMPLEX
1262:   #endif /* PETSC_USE_REAL_* */

1264: #endif /* PETSC_HAVE_COMPLEX */

1266: /*
1267:     Scalar number definitions
1268:  */
1269: #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
1270:   /*MC
1271:    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`

1273:    Level: beginner

1275:    Note:
1276:    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.

1278: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
1279: M*/
1280:   #define MPIU_SCALAR MPIU_COMPLEX

1282:   /*MC
1283:    PetscRealPart - Returns the real part of a `PetscScalar`

1285:    Synopsis:
1286: #include <petscmath.h>
1287:    PetscReal PetscRealPart(PetscScalar v)

1289:    Not Collective

1291:    Input Parameter:
1292: .  v - value to find the real part of

1294:    Level: beginner

1296: .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1297: M*/
1298:   #define PetscRealPart(a) PetscRealPartComplex(a)

1300:   /*MC
1301:    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`

1303:    Synopsis:
1304: #include <petscmath.h>
1305:    PetscReal PetscImaginaryPart(PetscScalar v)

1307:    Not Collective

1309:    Input Parameter:
1310: .  v - value to find the imaginary part of

1312:    Level: beginner

1314:    Note:
1315:    If PETSc was configured for real numbers then this always returns the value 0

1317: .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1318: M*/
1319:   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)

1321:   /*MC
1322:     PetscAbsScalar - Returns the absolute value (magnitude) of a `PetscScalar` value, as a `PetscReal`

1324:     Synopsis:
1325: #include <petscmath.h>
1326:     PetscReal PetscAbsScalar(PetscScalar a)

1328:     Not Collective; No Fortran Support

1330:     Input Parameter:
1331:   . a - the value

1333:     Level: beginner

1335: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1336:   M*/
1337:   #define PetscAbsScalar(a) PetscAbsComplex(a)
1338:   /*MC
1339:     PetscArgScalar - Returns the argument (phase angle) of a `PetscScalar` value, as a `PetscReal`; for real `PetscScalar` this is `0` for nonnegative values and `PETSC_PI` otherwise

1341:     Synopsis:
1342: #include <petscmath.h>
1343:     PetscReal PetscArgScalar(PetscScalar a)

1345:     Not Collective; No Fortran Support

1347:     Input Parameter:
1348:   . a - the value

1350:     Level: beginner

1352: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1353:   M*/
1354:   #define PetscArgScalar(a) PetscArgComplex(a)
1355:   /*MC
1356:     PetscConj - Returns the complex conjugate of a `PetscScalar` value; the identity when `PetscScalar` is real

1358:     Synopsis:
1359: #include <petscmath.h>
1360:     PetscScalar PetscConj(PetscScalar a)

1362:     Not Collective; No Fortran Support

1364:     Input Parameter:
1365:   . a - the value

1367:     Level: beginner

1369: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConjComplex()`
1370:   M*/
1371:   #define PetscConj(a) PetscConjComplex(a)
1372:   /*MC
1373:     PetscSqrtScalar - Returns the square root of a `PetscScalar` value

1375:     Synopsis:
1376: #include <petscmath.h>
1377:     PetscScalar PetscSqrtScalar(PetscScalar a)

1379:     Not Collective; No Fortran Support

1381:     Input Parameter:
1382:   . a - the value

1384:     Level: beginner

1386: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtComplex()`
1387:   M*/
1388:   #define PetscSqrtScalar(a) PetscSqrtComplex(a)
1389:   /*MC
1390:     PetscPowScalar - Returns the value of `a` raised to the power `b`, both `PetscScalar`

1392:     Synopsis:
1393: #include <petscmath.h>
1394:     PetscScalar PetscPowScalar(PetscScalar a, PetscScalar b)

1396:     Not Collective; No Fortran Support

1398:     Input Parameters:
1399:   + a - the value
1400:   - b - the value

1402:     Level: beginner

1404: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowComplex()`
1405:   M*/
1406:   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
1407:   /*MC
1408:     PetscExpScalar - Returns the exponential $e^a$ of a `PetscScalar` value

1410:     Synopsis:
1411: #include <petscmath.h>
1412:     PetscScalar PetscExpScalar(PetscScalar a)

1414:     Not Collective; No Fortran Support

1416:     Input Parameter:
1417:   . a - the value

1419:     Level: beginner

1421: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpComplex()`
1422:   M*/
1423:   #define PetscExpScalar(a) PetscExpComplex(a)
1424:   /*MC
1425:     PetscLogScalar - Returns the natural logarithm of a `PetscScalar` value

1427:     Synopsis:
1428: #include <petscmath.h>
1429:     PetscScalar PetscLogScalar(PetscScalar a)

1431:     Not Collective; No Fortran Support

1433:     Input Parameter:
1434:   . a - the value

1436:     Level: beginner

1438: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogComplex()`
1439:   M*/
1440:   #define PetscLogScalar(a) PetscLogComplex(a)
1441:   /*MC
1442:     PetscSinScalar - Returns the sine of a `PetscScalar` value

1444:     Synopsis:
1445: #include <petscmath.h>
1446:     PetscScalar PetscSinScalar(PetscScalar a)

1448:     Not Collective; No Fortran Support

1450:     Input Parameter:
1451:   . a - the value

1453:     Level: beginner

1455: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinComplex()`
1456:   M*/
1457:   #define PetscSinScalar(a) PetscSinComplex(a)
1458:   /*MC
1459:     PetscCosScalar - Returns the cosine of a `PetscScalar` value

1461:     Synopsis:
1462: #include <petscmath.h>
1463:     PetscScalar PetscCosScalar(PetscScalar a)

1465:     Not Collective; No Fortran Support

1467:     Input Parameter:
1468:   . a - the value

1470:     Level: beginner

1472: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosComplex()`
1473:   M*/
1474:   #define PetscCosScalar(a) PetscCosComplex(a)
1475:   /*MC
1476:     PetscTanScalar - Returns the tangent of a `PetscScalar` value

1478:     Synopsis:
1479: #include <petscmath.h>
1480:     PetscScalar PetscTanScalar(PetscScalar a)

1482:     Not Collective; No Fortran Support

1484:     Input Parameter:
1485:   . a - the value

1487:     Level: beginner

1489: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanComplex()`
1490:   M*/
1491:   #define PetscTanScalar(a) PetscTanComplex(a)
1492:   /*MC
1493:     PetscAsinScalar - Returns the arc sine of a `PetscScalar` value

1495:     Synopsis:
1496: #include <petscmath.h>
1497:     PetscScalar PetscAsinScalar(PetscScalar a)

1499:     Not Collective; No Fortran Support

1501:     Input Parameter:
1502:   . a - the value

1504:     Level: beginner

1506: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinComplex()`
1507:   M*/
1508:   #define PetscAsinScalar(a) PetscAsinComplex(a)
1509:   /*MC
1510:     PetscAcosScalar - Returns the arc cosine of a `PetscScalar` value

1512:     Synopsis:
1513: #include <petscmath.h>
1514:     PetscScalar PetscAcosScalar(PetscScalar a)

1516:     Not Collective; No Fortran Support

1518:     Input Parameter:
1519:   . a - the value

1521:     Level: beginner

1523: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosComplex()`
1524:   M*/
1525:   #define PetscAcosScalar(a) PetscAcosComplex(a)
1526:   /*MC
1527:     PetscAtanScalar - Returns the arc tangent of a `PetscScalar` value

1529:     Synopsis:
1530: #include <petscmath.h>
1531:     PetscScalar PetscAtanScalar(PetscScalar a)

1533:     Not Collective; No Fortran Support

1535:     Input Parameter:
1536:   . a - the value

1538:     Level: beginner

1540: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanComplex()`
1541:   M*/
1542:   #define PetscAtanScalar(a) PetscAtanComplex(a)
1543:   /*MC
1544:     PetscSinhScalar - Returns the hyperbolic sine of a `PetscScalar` value

1546:     Synopsis:
1547: #include <petscmath.h>
1548:     PetscScalar PetscSinhScalar(PetscScalar a)

1550:     Not Collective; No Fortran Support

1552:     Input Parameter:
1553:   . a - the value

1555:     Level: beginner

1557: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhComplex()`
1558:   M*/
1559:   #define PetscSinhScalar(a) PetscSinhComplex(a)
1560:   /*MC
1561:     PetscCoshScalar - Returns the hyperbolic cosine of a `PetscScalar` value

1563:     Synopsis:
1564: #include <petscmath.h>
1565:     PetscScalar PetscCoshScalar(PetscScalar a)

1567:     Not Collective; No Fortran Support

1569:     Input Parameter:
1570:   . a - the value

1572:     Level: beginner

1574: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshComplex()`
1575:   M*/
1576:   #define PetscCoshScalar(a) PetscCoshComplex(a)
1577:   /*MC
1578:     PetscTanhScalar - Returns the hyperbolic tangent of a `PetscScalar` value

1580:     Synopsis:
1581: #include <petscmath.h>
1582:     PetscScalar PetscTanhScalar(PetscScalar a)

1584:     Not Collective; No Fortran Support

1586:     Input Parameter:
1587:   . a - the value

1589:     Level: beginner

1591: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhComplex()`
1592:   M*/
1593:   #define PetscTanhScalar(a) PetscTanhComplex(a)
1594:   /*MC
1595:     PetscAsinhScalar - Returns the inverse hyperbolic sine of a `PetscScalar` value

1597:     Synopsis:
1598: #include <petscmath.h>
1599:     PetscScalar PetscAsinhScalar(PetscScalar a)

1601:     Not Collective; No Fortran Support

1603:     Input Parameter:
1604:   . a - the value

1606:     Level: beginner

1608: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhComplex()`
1609:   M*/
1610:   #define PetscAsinhScalar(a) PetscAsinhComplex(a)
1611:   /*MC
1612:     PetscAcoshScalar - Returns the inverse hyperbolic cosine of a `PetscScalar` value

1614:     Synopsis:
1615: #include <petscmath.h>
1616:     PetscScalar PetscAcoshScalar(PetscScalar a)

1618:     Not Collective; No Fortran Support

1620:     Input Parameter:
1621:   . a - the value

1623:     Level: beginner

1625: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshComplex()`
1626:   M*/
1627:   #define PetscAcoshScalar(a) PetscAcoshComplex(a)
1628:   /*MC
1629:     PetscAtanhScalar - Returns the inverse hyperbolic tangent of a `PetscScalar` value

1631:     Synopsis:
1632: #include <petscmath.h>
1633:     PetscScalar PetscAtanhScalar(PetscScalar a)

1635:     Not Collective; No Fortran Support

1637:     Input Parameter:
1638:   . a - the value

1640:     Level: beginner

1642: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhComplex()`
1643:   M*/
1644:   #define PetscAtanhScalar(a) PetscAtanhComplex(a)

1646: #else /* PETSC_USE_COMPLEX */
1647:   #define MPIU_SCALAR           MPIU_REAL
1648:   #define PetscRealPart(a)      (a)
1649:   #define PetscImaginaryPart(a) ((PetscReal)0)
1650:   #define PetscAbsScalar(a)     PetscAbsReal(a)
1651:   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
1652:   #define PetscConj(a)          (a)
1653:   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
1654:   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
1655:   #define PetscExpScalar(a)     PetscExpReal(a)
1656:   #define PetscLogScalar(a)     PetscLogReal(a)
1657:   #define PetscSinScalar(a)     PetscSinReal(a)
1658:   #define PetscCosScalar(a)     PetscCosReal(a)
1659:   #define PetscTanScalar(a)     PetscTanReal(a)
1660:   #define PetscAsinScalar(a)    PetscAsinReal(a)
1661:   #define PetscAcosScalar(a)    PetscAcosReal(a)
1662:   #define PetscAtanScalar(a)    PetscAtanReal(a)
1663:   #define PetscSinhScalar(a)    PetscSinhReal(a)
1664:   #define PetscCoshScalar(a)    PetscCoshReal(a)
1665:   #define PetscTanhScalar(a)    PetscTanhReal(a)
1666:   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
1667:   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
1668:   #define PetscAtanhScalar(a)   PetscAtanhReal(a)

1670: #endif /* PETSC_USE_COMPLEX */

1672: /*
1673:    Certain objects may be created using either single or double precision.
1674:    This is currently not used.
1675: */
1676: typedef enum {
1677:   PETSC_SCALAR_DOUBLE,
1678:   PETSC_SCALAR_SINGLE,
1679:   PETSC_SCALAR_LONG_DOUBLE,
1680:   PETSC_SCALAR_HALF
1681: } PetscScalarPrecision;

1683: /*MC
1684:    PetscAbs - Returns the absolute value of a number

1686:    Synopsis:
1687: #include <petscmath.h>
1688:    type PetscAbs(type v)

1690:    Not Collective

1692:    Input Parameter:
1693: .  v - the number

1695:    Level: beginner

1697:    Note:
1698:    The type can be integer or real floating point value, but cannot be complex

1700: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
1701: M*/
1702: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))

1704: /*MC
1705:    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1

1707:    Synopsis:
1708: #include <petscmath.h>
1709:    int PetscSign(type v)

1711:    Not Collective

1713:    Input Parameter:
1714: .  v - the number

1716:    Level: beginner

1718:    Note:
1719:    The type can be integer or real floating point value

1721: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
1722: M*/
1723: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

1725: /*MC
1726:    PetscMin - Returns minimum of two numbers

1728:    Synopsis:
1729: #include <petscmath.h>
1730:    type PetscMin(type v1,type v2)

1732:    Not Collective

1734:    Input Parameters:
1735: +  v1 - first value to find minimum of
1736: -  v2 - second value to find minimum of

1738:    Level: beginner

1740:    Note:
1741:    The type can be integer or floating point value, but cannot be complex

1743: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1744: M*/
1745: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))

1747: /*MC
1748:    PetscMax - Returns maximum of two numbers

1750:    Synopsis:
1751: #include <petscmath.h>
1752:    type max PetscMax(type v1,type v2)

1754:    Not Collective

1756:    Input Parameters:
1757: +  v1 - first value to find maximum of
1758: -  v2 - second value to find maximum of

1760:    Level: beginner

1762:    Note:
1763:    The type can be integer or floating point value

1765: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1766: M*/
1767: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))

1769: /*MC
1770:    PetscClipInterval - Returns a number clipped to be within an interval

1772:    Synopsis:
1773: #include <petscmath.h>
1774:    type clip PetscClipInterval(type x,type a,type b)

1776:    Not Collective

1778:    Input Parameters:
1779: +  x - value to use if within interval [a,b]
1780: .  a - lower end of interval
1781: -  b - upper end of interval

1783:    Level: beginner

1785:    Note:
1786:    The type can be integer or floating point value

1788:    Example\:
1789: .vb
1790:   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
1791:   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
1792: .ve

1794: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1795: M*/
1796: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))

1798: /*MC
1799:    PetscAbsInt - Returns the absolute value of an integer

1801:    Synopsis:
1802: #include <petscmath.h>
1803:    int abs PetscAbsInt(int v1)

1805:    Input Parameter:
1806: .   v1 - the integer

1808:    Level: beginner

1810: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
1811: M*/
1812: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))

1814: /*MC
1815:    PetscAbsReal - Returns the absolute value of a real number

1817:    Synopsis:
1818: #include <petscmath.h>
1819:    Real abs PetscAbsReal(PetscReal v1)

1821:    Input Parameter:
1822: .   v1 - the `PetscReal` value

1824:    Level: beginner

1826: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
1827: M*/
1828: #if defined(PETSC_USE_REAL_SINGLE)
1829:   #define PetscAbsReal(a) fabsf(a)
1830: #elif defined(PETSC_USE_REAL_DOUBLE)
1831:   #define PetscAbsReal(a) fabs(a)
1832: #elif defined(PETSC_USE_REAL___FLOAT128)
1833:   #define PetscAbsReal(a) fabsq(a)
1834: #elif defined(PETSC_USE_REAL___FP16)
1835:   #define PetscAbsReal(a) fabsf(a)
1836: #endif

1838: /*MC
1839:    PetscSqr - Returns the square of a number

1841:    Synopsis:
1842: #include <petscmath.h>
1843:    type sqr PetscSqr(type v1)

1845:    Not Collective

1847:    Input Parameter:
1848: .   v1 - the value

1850:    Level: beginner

1852:    Note:
1853:    The type can be integer, floating point, or complex floating point

1855: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
1856: M*/
1857: #define PetscSqr(a) ((a) * (a))

1859: /*MC
1860:    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
1861:    precision of `PetscReal` be it half, single, double or 128-bit representation

1863:    Synopsis:
1864: #include <petscmath.h>
1865:    PetscReal PetscRealConstant(real_number)

1867:    Not Collective

1869:    Input Parameter:
1870: .   v1 - the real number, for example 1.5

1872:    Level: beginner

1874:    Note:
1875:    For example, if PETSc is configured with `--with-precision=__float128` and one writes
1876: .vb
1877:    PetscReal d = 1.5;
1878: .ve
1879:    the result is 1.5 in double precision extended to 128 bit representation, meaning it is very far from the correct value. Hence, one should write
1880: .vb
1881:    PetscReal d = PetscRealConstant(1.5);
1882: .ve

1884: .seealso: `PetscReal`
1885: M*/
1886: #if defined(PETSC_USE_REAL_SINGLE)
1887:   #define PetscRealConstant(constant) constant##F
1888: #elif defined(PETSC_USE_REAL_DOUBLE)
1889:   #define PetscRealConstant(constant) constant
1890: #elif defined(PETSC_USE_REAL___FLOAT128)
1891:   #define PetscRealConstant(constant) constant##Q
1892: #elif defined(PETSC_USE_REAL___FP16)
1893:   #define PetscRealConstant(constant) constant##F
1894: #endif

1896: /*
1897:      Basic constants
1898: */
1899: /*MC
1900:   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.

1902:   Level: beginner

1904: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
1905: M*/

1907: /*MC
1908:   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.

1910:   Level: beginner

1912: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
1913: M*/

1915: /*MC
1916:   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.

1918:   Level: beginner

1920: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1921: M*/

1923: /*MC
1924:   PETSC_E - the value of Euler's constant $ e $ to the correct precision of `PetscReal`.

1926:   Level: beginner

1928: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1929: M*/

1931: #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
1932: #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
1933: #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
1934: #define PETSC_E     PetscRealConstant(2.7182818284590452353602874713526625)

1936: /*MC
1937:   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`

1939:   Level: beginner

1941: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1942: M*/

1944: /*MC
1945:   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`

1947:   Level: beginner

1949: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1950: M*/

1952: /*MC
1953:   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.

1955:   Level: beginner

1957:   Note:
1958:   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers

1960:   Developer Note:
1961:   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.

1963: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1964: M*/

1966: /*MC
1967:   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`

1969:   Level: beginner

1971:   Note:
1972:   See <https://en.wikipedia.org/wiki/Machine_epsilon>

1974: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1975: M*/

1977: /*MC
1978:   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`

1980:   Level: beginner

1982:   Note:
1983:   See `PETSC_MACHINE_EPSILON`

1985: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
1986: M*/

1988: /*MC
1989:   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
1990:   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.

1992:   Level: beginner

1994:   Note:
1995:   See `PETSC_MACHINE_EPSILON`

1997: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
1998:          `PETSC_SQRT_MACHINE_EPSILON`
1999: M*/

2001: #if defined(PETSC_USE_REAL_SINGLE)
2002:   #define PETSC_MAX_REAL             3.40282346638528860e+38F
2003:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2004:   #define PETSC_REAL_MIN             1.1754944e-38F
2005:   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
2006:   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
2007:   #define PETSC_SMALL                1.e-5F
2008: #elif defined(PETSC_USE_REAL_DOUBLE)
2009:   #define PETSC_MAX_REAL             1.7976931348623157e+308
2010:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2011:   #define PETSC_REAL_MIN             2.225073858507201e-308
2012:   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
2013:   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
2014:   #define PETSC_SMALL                1.e-10
2015: #elif defined(PETSC_USE_REAL___FLOAT128)
2016:   #define PETSC_MAX_REAL             FLT128_MAX
2017:   #define PETSC_MIN_REAL             (-FLT128_MAX)
2018:   #define PETSC_REAL_MIN             FLT128_MIN
2019:   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
2020:   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
2021:   #define PETSC_SMALL                1.e-20Q
2022: #elif defined(PETSC_USE_REAL___FP16)
2023:   #define PETSC_MAX_REAL             65504.0F
2024:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2025:   #define PETSC_REAL_MIN             .00006103515625F
2026:   #define PETSC_MACHINE_EPSILON      .0009765625F
2027:   #define PETSC_SQRT_MACHINE_EPSILON .03125F
2028:   #define PETSC_SMALL                5.e-3F
2029: #endif

2031: /*MC
2032:   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`

2034:   Level: intermediate

2036:   Note:
2037:   This is not the IEEE infinity value

2039: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2040: M*/
2041: #define PETSC_INFINITY (PETSC_MAX_REAL / 4)

2043: /*MC
2044:   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`

2046:   Level: intermediate

2048:   Note:
2049:   This is not the negative IEEE infinity value

2051: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2052: M*/
2053: #define PETSC_NINFINITY (-PETSC_INFINITY)

2055: PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
2056: PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
2057: PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
2058: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
2059: {
2060:   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
2061: }
2062: static inline PetscBool PetscIsInfScalar(PetscScalar v)
2063: {
2064:   return PetscIsInfReal(PetscAbsScalar(v));
2065: }
2066: static inline PetscBool PetscIsNanScalar(PetscScalar v)
2067: {
2068:   return PetscIsNanReal(PetscAbsScalar(v));
2069: }
2070: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
2071: {
2072:   return PetscIsInfOrNanReal(PetscAbsScalar(v));
2073: }
2074: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
2075: {
2076:   return PetscIsNormalReal(PetscAbsScalar(v));
2077: }

2079: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
2080: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
2081: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);

2083: /*@C
2084:   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`

2086:   Input Parameters:
2087: + lhs  - The first number
2088: . rhs  - The second number
2089: . rtol - The relative tolerance
2090: - atol - The absolute tolerance

2092:   Level: beginner

2094:   Note:
2095:   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
2096:   numbers.

2098: .seealso: `PetscIsCloseAtTol()`
2099: @*/
2100: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
2101: {
2102:   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);

2104:   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
2105:   return close;
2106: }

2108: /*
2109:     These macros are currently hardwired to match the regular data types, so there is no support for a different
2110:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
2111:  */
2112: #define MPIU_MATSCALAR MPIU_SCALAR
2113: typedef PetscScalar MatScalar;
2114: typedef PetscReal   MatReal;

2116: struct petsc_mpiu_2scalar {
2117:   PetscScalar a, b;
2118: };
2119: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);

2121: /* MPI Datatypes for composite reductions */
2122: struct petsc_mpiu_real_int {
2123:   PetscReal v;
2124:   PetscInt  i;
2125: };

2127: struct petsc_mpiu_scalar_int {
2128:   PetscScalar v;
2129:   PetscInt    i;
2130: };

2132: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
2133: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);

2135: #if defined(PETSC_USE_64BIT_INDICES)
2136: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
2137:   PetscInt a;
2138:   PetscInt b;
2139: };
2140: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
2141:   PetscInt    a;
2142:   PetscMPIInt b;
2143: };
2144: /*
2145:  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
2146:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
2147:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");

2149:  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
2150:  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
2151:  pass! So we just comment it out...
2152: */
2153: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
2154: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
2155: #else
2156:   #define MPIU_2INT       MPI_2INT
2157:   #define MPIU_INT_MPIINT MPI_2INT
2158: #endif
2159: PETSC_EXTERN MPI_Datatype MPI_4INT;
2160: PETSC_EXTERN MPI_Datatype MPIU_4INT;

2162: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
2163: {
2164:   PetscInt result = 1;
2165:   while (power) {
2166:     if (power & 1) result *= base;
2167:     power >>= 1;
2168:     if (power) base *= base;
2169:   }
2170:   return result;
2171: }

2173: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
2174: {
2175:   PetscInt64 result = 1;
2176:   while (power) {
2177:     if (power & 1) result *= base;
2178:     power >>= 1;
2179:     if (power) base *= base;
2180:   }
2181:   return result;
2182: }

2184: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
2185: {
2186:   PetscReal result = 1;
2187:   if (power < 0) {
2188:     power = -power;
2189:     base  = ((PetscReal)1) / base;
2190:   }
2191:   while (power) {
2192:     if (power & 1) result *= base;
2193:     power >>= 1;
2194:     if (power) base *= base;
2195:   }
2196:   return result;
2197: }

2199: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
2200: {
2201:   PetscScalar result = (PetscReal)1;
2202:   if (power < 0) {
2203:     power = -power;
2204:     base  = ((PetscReal)1) / base;
2205:   }
2206:   while (power) {
2207:     if (power & 1) result *= base;
2208:     power >>= 1;
2209:     if (power) base *= base;
2210:   }
2211:   return result;
2212: }

2214: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
2215: {
2216:   PetscScalar cpower = power;
2217:   return PetscPowScalar(base, cpower);
2218: }

2220: /*MC
2221:    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers

2223:    Synopsis:
2224: #include <petscmath.h>
2225:    bool PetscApproximateLTE(PetscReal x,constant float)

2227:    Not Collective

2229:    Input Parameters:
2230: +   x - the variable
2231: -   b - the constant float it is checking if `x` is less than or equal to

2233:    Level: advanced

2235:    Notes:
2236:    The fudge factor is the value `PETSC_SMALL`

2238:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

2240:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2241:    floating point results.

2243:    Example\:
2244: .vb
2245:   PetscReal x;
2246:   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
2247: .ve

2249: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
2250: M*/
2251: #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))

2253: /*MC
2254:    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers

2256:    Synopsis:
2257: #include <petscmath.h>
2258:    bool PetscApproximateGTE(PetscReal x,constant float)

2260:    Not Collective

2262:    Input Parameters:
2263: +   x - the variable
2264: -   b - the constant float it is checking if `x` is greater than or equal to

2266:    Level: advanced

2268:    Notes:
2269:    The fudge factor is the value `PETSC_SMALL`

2271:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

2273:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2274:    floating point results.

2276:    Example\:
2277: .vb
2278:   PetscReal x;
2279:   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
2280: .ve

2282: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2283: M*/
2284: #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))

2286: /*@C
2287:    PetscCeilInt - Returns the ceiling of the quotation of two positive integers

2289:    Not Collective

2291:    Input Parameters:
2292: +   x - the numerator
2293: -   y - the denominator

2295:    Level: advanced

2297:   Example\:
2298: .vb
2299:   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
2300: .ve

2302: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2303: @*/
2304: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
2305: {
2306:   return x / y + (x % y ? 1 : 0);
2307: }

2309: /*@C
2310:    PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers

2312:    Not Collective

2314:    Input Parameters:
2315: +   x - the numerator
2316: -   y - the denominator

2318:    Level: advanced

2320:   Example\:
2321: .vb
2322:   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
2323: .ve

2325: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2326: @*/
2327: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
2328: {
2329:   return x / y + (x % y ? 1 : 0);
2330: }

2332: /*@C
2333:    PetscGCD - Returns the greatest common divisor of two integers

2335:    Not Collective

2337:    Input Parameters:
2338: +   a - first number
2339: -   b - second number

2341:    Level: advanced

2343: .seealso: `PetscLCM()`
2344: @*/
2345: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
2346: {
2347:   a = PetscAbsInt(a);
2348:   b = PetscAbsInt(b);
2349:   while (b != 0) {
2350:     PetscInt tmp = b;

2352:     b = a % b;
2353:     a = tmp;
2354:   }
2355:   return a;
2356: }

2358: /*@C
2359:    PetscLCM - Returns the least common multiple of two integers

2361:    Not Collective

2363:    Input Parameters:
2364: +   a - first number
2365: -   b - second number

2367:    Level: advanced

2369: .seealso: `PetscGCD()`
2370: @*/
2371: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
2372: {
2373:   PetscInt gcd;

2375:   a = PetscAbsInt(a);
2376:   b = PetscAbsInt(b);

2378:   gcd = PetscGCD(a, b);
2379:   return gcd ? a * (b / gcd) : 0;
2380: }

2382: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);