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 <float.h>
 12: #include <petscmacros.h>
 13: #include <petscsystypes.h>

 15: /* SUBMANSEC = Sys */

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

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

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

 34:     Not Collective; No Fortran Support

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

 39:     Level: beginner

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

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

 51:     Not Collective; No Fortran Support

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

 56:     Level: beginner

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

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

 68:     Not Collective; No Fortran Support

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

 74:     Level: beginner

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

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

 86:     Not Collective; No Fortran Support

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

 92:     Level: beginner

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

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

104:     Not Collective; No Fortran Support

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

110:     Level: beginner

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

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

122:     Not Collective; No Fortran Support

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

127:     Level: beginner

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

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

139:     Not Collective; No Fortran Support

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

144:     Level: beginner

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

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

156:     Not Collective; No Fortran Support

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

161:     Level: beginner

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

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

173:     Not Collective; No Fortran Support

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

178:     Level: beginner

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

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

190:     Not Collective; No Fortran Support

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

195:     Level: beginner

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

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

207:     Not Collective; No Fortran Support

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

212:     Level: beginner

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

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

224:     Not Collective; No Fortran Support

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

229:     Level: beginner

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

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

241:     Not Collective; No Fortran Support

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

246:     Level: beginner

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

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

258:     Not Collective; No Fortran Support

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

263:     Level: beginner

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

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

275:     Not Collective; No Fortran Support

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

280:     Level: beginner

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

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

292:     Not Collective; No Fortran Support

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

297:     Level: beginner

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

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

309:     Not Collective; No Fortran Support

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

314:     Level: beginner

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

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

326:     Not Collective; No Fortran Support

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

331:     Level: beginner

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

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

343:     Not Collective; No Fortran Support

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

348:     Level: beginner

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

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

360:     Not Collective; No Fortran Support

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

365:     Level: beginner

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

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

377:     Not Collective; No Fortran Support

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

382:     Level: beginner

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

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

394:     Not Collective; No Fortran Support

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

399:     Level: beginner

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

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

411:     Not Collective; No Fortran Support

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

416:     Level: beginner

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

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

428:     Not Collective; No Fortran Support

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

433:     Level: beginner

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

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

445:     Not Collective; No Fortran Support

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

450:     Level: beginner

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

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

462:     Not Collective; No Fortran Support

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

468:     Level: beginner

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

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

480:     Not Collective; No Fortran Support

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

486:     Level: beginner

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

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

498:     Not Collective; No Fortran Support

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

503:     Level: beginner

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

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

516:       Not Collective; No Fortran Support

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

521:       Level: beginner

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

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

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

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

635: #endif /* PETSC_USE_REAL_* */

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

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

650: #if PetscDefined(HAVE_REAL___FLOAT128) && !PetscDefined(SKIP_REAL___FLOAT128)
651: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
652: #endif
653: #if PetscDefined(HAVE_REAL___FP16) && !PetscDefined(SKIP_REAL___FP16)
654: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
655: #endif

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

660:    Level: beginner

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

665: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
666: M*/
667: #if PetscDefined(USE_REAL_SINGLE)
668:   #define MPIU_REAL MPI_FLOAT
669: #elif PetscDefined(USE_REAL_DOUBLE)
670:   #define MPIU_REAL MPI_DOUBLE
671: #elif PetscDefined(USE_REAL___FLOAT128)
672:   #define MPIU_REAL MPIU___FLOAT128
673: #elif PetscDefined(USE_REAL___FP16)
674:   #define MPIU_REAL MPIU___FP16
675: #endif /* PETSC_USE_REAL_* */

677: /*
678:     Complex number definitions
679:  */
680: #if PetscDefined(HAVE_COMPLEX)
681:   #if defined(__cplusplus) && !PetscDefined(USE_REAL___FLOAT128)
682:   /* C++ support of complex number */

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

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

691:       Not Collective; No Fortran Support

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

696:       Level: beginner

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

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

708:       Not Collective; No Fortran Support

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

713:       Level: beginner

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

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

725:       Not Collective; No Fortran Support

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

730:       Level: beginner

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

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

742:       Not Collective; No Fortran Support

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

747:       Level: beginner

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

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

759:       Not Collective; No Fortran Support

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

764:       Level: beginner

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

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

776:       Not Collective; No Fortran Support

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

781:       Level: beginner

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

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

793:       Not Collective; No Fortran Support

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

799:       Level: beginner

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

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

811:       Not Collective; No Fortran Support

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

816:       Level: beginner

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

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

828:       Not Collective; No Fortran Support

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

833:       Level: beginner

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

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

845:       Not Collective; No Fortran Support

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

850:       Level: beginner

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

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

862:       Not Collective; No Fortran Support

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

867:       Level: beginner

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

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

879:       Not Collective; No Fortran Support

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

884:       Level: beginner

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

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

896:       Not Collective; No Fortran Support

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

901:       Level: beginner

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

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

913:       Not Collective; No Fortran Support

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

918:       Level: beginner

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

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

930:       Not Collective; No Fortran Support

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

935:       Level: beginner

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

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

947:       Not Collective; No Fortran Support

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

952:       Level: beginner

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

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

964:       Not Collective; No Fortran Support

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

969:       Level: beginner

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

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

981:       Not Collective; No Fortran Support

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

986:       Level: beginner

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

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

998:       Not Collective; No Fortran Support

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

1003:       Level: beginner

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

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

1015:       Not Collective; No Fortran Support

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

1020:       Level: beginner

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

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

1032:       Not Collective; No Fortran Support

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

1037:       Level: beginner

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

1043:   /* TODO: Add configure tests

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

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

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

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

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

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

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

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

1112: */

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

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

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

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

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

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

1191:    Level: intermediate

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

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

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

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

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

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

1232:   #if PetscDefined(HAVE_REAL___FLOAT128) && !PetscDefined(SKIP_REAL___FLOAT128)
1233:     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
1234:     #if PetscDefined(USE_COMPLEX)
1235:       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
1236:     #else
1237:       #define MPIU___COMPLEX128_ATTR_TAG
1238:     #endif

1240: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;

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

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

1248:    Level: beginner

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

1253: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
1254: M*/
1255:   #if PetscDefined(USE_REAL_SINGLE)
1256:     #define MPIU_COMPLEX MPI_C_COMPLEX
1257:   #elif PetscDefined(USE_REAL_DOUBLE)
1258:     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
1259:   #elif PetscDefined(USE_REAL___FLOAT128)
1260:     #define MPIU_COMPLEX MPIU___COMPLEX128
1261:   #elif PetscDefined(USE_REAL___FP16)
1262:     #define MPIU_COMPLEX MPI_C_COMPLEX
1263:   #endif /* PETSC_USE_REAL_* */

1265: #endif /* PETSC_HAVE_COMPLEX */

1267: /*
1268:     Scalar number definitions
1269:  */
1270: #if PetscDefined(USE_COMPLEX) && PetscDefined(HAVE_COMPLEX)
1271:   /*MC
1272:    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`

1274:    Level: beginner

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

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

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

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

1290:    Not Collective

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

1295:    Level: beginner

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

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

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

1308:    Not Collective

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

1313:    Level: beginner

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

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

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

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

1329:     Not Collective; No Fortran Support

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

1334:     Level: beginner

1336: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1337:   M*/
1338:   #define PetscAbsScalar(a) PetscAbsComplex(a)
1339:   /*MC
1340:     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

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

1346:     Not Collective; No Fortran Support

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

1351:     Level: beginner

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

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

1363:     Not Collective; No Fortran Support

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

1368:     Level: beginner

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

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

1380:     Not Collective; No Fortran Support

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

1385:     Level: beginner

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

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

1397:     Not Collective; No Fortran Support

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

1403:     Level: beginner

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

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

1415:     Not Collective; No Fortran Support

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

1420:     Level: beginner

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

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

1432:     Not Collective; No Fortran Support

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

1437:     Level: beginner

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

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

1449:     Not Collective; No Fortran Support

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

1454:     Level: beginner

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

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

1466:     Not Collective; No Fortran Support

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

1471:     Level: beginner

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

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

1483:     Not Collective; No Fortran Support

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

1488:     Level: beginner

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

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

1500:     Not Collective; No Fortran Support

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

1505:     Level: beginner

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

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

1517:     Not Collective; No Fortran Support

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

1522:     Level: beginner

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

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

1534:     Not Collective; No Fortran Support

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

1539:     Level: beginner

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

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

1551:     Not Collective; No Fortran Support

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

1556:     Level: beginner

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

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

1568:     Not Collective; No Fortran Support

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

1573:     Level: beginner

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

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

1585:     Not Collective; No Fortran Support

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

1590:     Level: beginner

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

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

1602:     Not Collective; No Fortran Support

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

1607:     Level: beginner

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

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

1619:     Not Collective; No Fortran Support

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

1624:     Level: beginner

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

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

1636:     Not Collective; No Fortran Support

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

1641:     Level: beginner

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

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

1671: #endif /* PETSC_USE_COMPLEX */

1673: /*E
1674:    PetscScalarPrecision - Names of the floating-point precisions that a `PetscScalar` could in principle be built with

1676:    Values:
1677: +   `PETSC_SCALAR_DOUBLE`      - IEEE double precision
1678: .   `PETSC_SCALAR_SINGLE`      - IEEE single precision
1679: .   `PETSC_SCALAR_LONG_DOUBLE` - C `long double` precision
1680: -   `PETSC_SCALAR_HALF`        - IEEE half precision

1682:    Level: developer

1684:    Note:
1685:    This enum is reserved for situations where an object might be created in a precision different from `PetscScalar`; the current PETSc code does not use it.

1687: .seealso: `PetscScalar`, `PetscReal`, `PetscComplex`
1688: E*/
1689: typedef enum {
1690:   PETSC_SCALAR_DOUBLE,
1691:   PETSC_SCALAR_SINGLE,
1692:   PETSC_SCALAR_LONG_DOUBLE,
1693:   PETSC_SCALAR_HALF
1694: } PetscScalarPrecision;

1696: /*MC
1697:    PetscAbs - Returns the absolute value of a number

1699:    Synopsis:
1700: #include <petscmath.h>
1701:    type PetscAbs(type v)

1703:    Not Collective

1705:    Input Parameter:
1706: .  v - the number

1708:    Level: beginner

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

1713: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
1714: M*/
1715: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))

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

1720:    Synopsis:
1721: #include <petscmath.h>
1722:    int PetscSign(type v)

1724:    Not Collective

1726:    Input Parameter:
1727: .  v - the number

1729:    Level: beginner

1731:    Note:
1732:    The type can be integer or real floating point value

1734: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
1735: M*/
1736: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

1738: /*MC
1739:    PetscMin - Returns minimum of two numbers

1741:    Synopsis:
1742: #include <petscmath.h>
1743:    type PetscMin(type v1, type v2)

1745:    Not Collective

1747:    Input Parameters:
1748: +  v1 - first value to find minimum of
1749: -  v2 - second value to find minimum of

1751:    Level: beginner

1753:    Note:
1754:    The type can be integer or floating point value, but cannot be complex

1756: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1757: M*/
1758: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))

1760: /*MC
1761:    PetscMax - Returns maximum of two numbers

1763:    Synopsis:
1764: #include <petscmath.h>
1765:    type max PetscMax(type v1, type v2)

1767:    Not Collective

1769:    Input Parameters:
1770: +  v1 - first value to find maximum of
1771: -  v2 - second value to find maximum of

1773:    Level: beginner

1775:    Note:
1776:    The type can be integer or floating point value

1778: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1779: M*/
1780: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))

1782: /*MC
1783:    PetscClipInterval - Returns a number clipped to be within an interval

1785:    Synopsis:
1786: #include <petscmath.h>
1787:    type clip PetscClipInterval(type x, type a, type b)

1789:    Not Collective

1791:    Input Parameters:
1792: +  x - value to use if within interval [a,b]
1793: .  a - lower end of interval
1794: -  b - upper end of interval

1796:    Level: beginner

1798:    Note:
1799:    The type can be integer or floating point value

1801:    Example\:
1802: .vb
1803:   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
1804:   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
1805: .ve

1807: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1808: M*/
1809: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))

1811: /*MC
1812:    PetscAbsInt - Returns the absolute value of an integer

1814:    Synopsis:
1815: #include <petscmath.h>
1816:    int abs PetscAbsInt(int v1)

1818:    Input Parameter:
1819: .   v1 - the integer

1821:    Level: beginner

1823: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
1824: M*/
1825: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))

1827: /*MC
1828:    PetscAbsReal - Returns the absolute value of a real number

1830:    Synopsis:
1831: #include <petscmath.h>
1832:    Real abs PetscAbsReal(PetscReal v1)

1834:    Input Parameter:
1835: .   v1 - the `PetscReal` value

1837:    Level: beginner

1839: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
1840: M*/
1841: #if PetscDefined(USE_REAL_SINGLE)
1842:   #define PetscAbsReal(a) fabsf(a)
1843: #elif PetscDefined(USE_REAL_DOUBLE)
1844:   #define PetscAbsReal(a) fabs(a)
1845: #elif PetscDefined(USE_REAL___FLOAT128)
1846:   #define PetscAbsReal(a) fabsq(a)
1847: #elif PetscDefined(USE_REAL___FP16)
1848:   #define PetscAbsReal(a) fabsf(a)
1849: #endif

1851: /*MC
1852:    PetscSqr - Returns the square of a number

1854:    Synopsis:
1855: #include <petscmath.h>
1856:    type sqr PetscSqr(type v1)

1858:    Not Collective

1860:    Input Parameter:
1861: .   v1 - the value

1863:    Level: beginner

1865:    Note:
1866:    The type can be integer, floating point, or complex floating point

1868: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
1869: M*/
1870: #define PetscSqr(a) ((a) * (a))

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

1876:    Synopsis:
1877: #include <petscmath.h>
1878:    PetscReal PetscRealConstant(real_number)

1880:    Not Collective

1882:    Input Parameter:
1883: .   v1 - the real number, for example 1.5

1885:    Level: beginner

1887:    Note:
1888:    For example, if PETSc is configured with `--with-precision=__float128` and one writes
1889: .vb
1890:    PetscReal d = 1.5;
1891: .ve
1892:    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
1893: .vb
1894:    PetscReal d = PetscRealConstant(1.5);
1895: .ve

1897: .seealso: `PetscReal`
1898: M*/
1899: #if PetscDefined(USE_REAL_SINGLE)
1900:   #define PetscRealConstant(constant) constant##F
1901: #elif PetscDefined(USE_REAL_DOUBLE)
1902:   #define PetscRealConstant(constant) constant
1903: #elif PetscDefined(USE_REAL___FLOAT128)
1904:   #define PetscRealConstant(constant) constant##Q
1905: #elif PetscDefined(USE_REAL___FP16)
1906:   #define PetscRealConstant(constant) ((PetscReal)(constant))
1907: #endif

1909: /*
1910:      Basic constants
1911: */
1912: /*MC
1913:   PETSC_PI - the value of $\pi$ to the correct precision of `PetscReal`.

1915:   Level: beginner

1917: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
1918: M*/

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

1923:   Level: beginner

1925: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
1926: M*/

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

1931:   Level: beginner

1933: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1934: M*/

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

1939:   Level: beginner

1941: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1942: M*/

1944: #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
1945:   #pragma GCC diagnostic push
1946:   #pragma GCC diagnostic ignored "-Wpedantic"
1947: #endif

1949: PETSC_STATIC_CONSTEXPR PetscReal PETSC_PI    = PetscRealConstant(3.141592653589793238462643383279502884);
1950: PETSC_STATIC_CONSTEXPR PetscReal PETSC_PHI   = PetscRealConstant(1.618033988749894848204586834365638117);
1951: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT2 = PetscRealConstant(1.414213562373095048801688724209698079);
1952: PETSC_STATIC_CONSTEXPR PetscReal PETSC_E     = PetscRealConstant(2.718281828459045235360287471352662498);

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

1957:   Level: beginner

1959: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1960: M*/

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

1965:   Level: beginner

1967: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1968: M*/

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

1973:   Level: beginner

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

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

1981: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1982: M*/

1984: /*MC
1985:   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`

1987:   Level: beginner

1989:   Note:
1990:   See <https://en.wikipedia.org/wiki/Machine_epsilon>

1992: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1993: M*/

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

1998:   Level: beginner

2000:   Note:
2001:   See `PETSC_MACHINE_EPSILON`

2003: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
2004: M*/

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

2010:   Level: beginner

2012:   Note:
2013:   See `PETSC_MACHINE_EPSILON`

2015: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
2016:          `PETSC_SQRT_MACHINE_EPSILON`
2017: M*/

2019: #if PetscDefined(USE_REAL_SINGLE)
2020: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL             = FLT_MAX;
2021: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN             = FLT_MIN;
2022: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON      = FLT_EPSILON;
2023: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 3.45266977e-04F;
2024: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL                = PetscRealConstant(1.e-5);
2025: #elif PetscDefined(USE_REAL_DOUBLE)
2026: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL             = DBL_MAX;
2027: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN             = DBL_MIN;
2028: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON      = DBL_EPSILON;
2029: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 1.4901161193847656e-08;
2030: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL                = PetscRealConstant(1.e-10);
2031: #elif PetscDefined(USE_REAL___FLOAT128)
2032: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL             = FLT128_MAX;
2033: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN             = FLT128_MIN;
2034: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON      = FLT128_EPSILON;
2035: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = 1.38777878078144567552953958511352539e-17Q;
2036: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL                = PetscRealConstant(1.e-20);
2037: #elif PetscDefined(USE_REAL___FP16)
2038: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MAX_REAL             = __FLT16_MAX__;
2039: PETSC_STATIC_CONSTEXPR PetscReal PETSC_REAL_MIN             = __FLT16_MIN__;
2040: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MACHINE_EPSILON      = __FLT16_EPSILON__;
2041: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SQRT_MACHINE_EPSILON = PetscRealConstant(3.1250e-02);
2042: PETSC_STATIC_CONSTEXPR PetscReal PETSC_SMALL                = PetscRealConstant(5.e-3);
2043: #endif
2044: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2045: PETSC_STATIC_CONSTEXPR PetscReal PETSC_MIN_REAL = (-PETSC_MAX_REAL);
2046: #else
2047:   #define PETSC_MIN_REAL (-PETSC_MAX_REAL)
2048: #endif

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

2053:   Level: intermediate

2055:   Note:
2056:   This is not the IEEE infinity value

2058: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2059: M*/
2060: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2061: PETSC_STATIC_CONSTEXPR PetscReal PETSC_INFINITY = PETSC_MAX_REAL / PetscRealConstant(4.0);
2062: #else
2063:   #define PETSC_INFINITY (PETSC_MAX_REAL / PetscRealConstant(4.0))
2064: #endif

2066: #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
2067:   #pragma GCC diagnostic pop
2068: #endif

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

2073:   Level: intermediate

2075:   Note:
2076:   This is not the negative IEEE infinity value

2078: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2079: M*/
2080: #if PetscDefined(HAVE_STATIC_CONST_INIT)
2081: PETSC_STATIC_CONSTEXPR PetscReal PETSC_NINFINITY = (-PETSC_INFINITY);
2082: #else
2083:   #define PETSC_NINFINITY (-PETSC_INFINITY)
2084: #endif

2086: PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
2087: PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
2088: PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
2089: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
2090: {
2091:   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
2092: }
2093: static inline PetscBool PetscIsInfScalar(PetscScalar v)
2094: {
2095:   return PetscIsInfReal(PetscAbsScalar(v));
2096: }
2097: static inline PetscBool PetscIsNanScalar(PetscScalar v)
2098: {
2099:   return PetscIsNanReal(PetscAbsScalar(v));
2100: }
2101: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
2102: {
2103:   return PetscIsInfOrNanReal(PetscAbsScalar(v));
2104: }
2105: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
2106: {
2107:   return PetscIsNormalReal(PetscAbsScalar(v));
2108: }

2110: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
2111: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
2112: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);

2114: /*@
2115:   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`

2117:   Not Collective

2119:   Input Parameters:
2120: + lhs  - The first number
2121: . rhs  - The second number
2122: . rtol - The relative tolerance
2123: - atol - The absolute tolerance

2125:   Level: beginner

2127:   Note:
2128:   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
2129:   numbers.

2131: .seealso: `PetscIsCloseAtTol()`
2132: @*/
2133: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
2134: {
2135:   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);

2137:   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
2138:   return close;
2139: }

2141: /*
2142:     These macros are currently hardwired to match the regular data types, so there is no support for a different
2143:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
2144:  */
2145: #define MPIU_MATSCALAR MPIU_SCALAR

2147: /*MC
2148:    MatScalar - Datatype used inside matrix implementations to store matrix entries

2150:    Level: developer

2152:    Note:
2153:    `MatScalar` is currently a synonym for `PetscScalar`. It exists so that matrix internals can, in principle, store entries in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

2155: .seealso: `PetscScalar`, `MatReal`, `Mat`, `PETSC_USE_COMPLEX`
2156: M*/
2157: typedef PetscScalar MatScalar;

2159: /*MC
2160:    MatReal - Datatype used inside matrix implementations to store real-valued matrix data

2162:    Level: developer

2164:    Note:
2165:    `MatReal` is currently a synonym for `PetscReal`. It exists so that matrix internals can, in principle, store data in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

2167: .seealso: `PetscReal`, `MatScalar`, `Mat`
2168: M*/
2169: typedef PetscReal MatReal;

2171: struct petsc_mpiu_2scalar {
2172:   PetscScalar a, b;
2173: };
2174: /* See comments below for clang and MPIU_2INT */
2175: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar) */;

2177: /* MPI Datatypes for composite reductions */
2178: struct petsc_mpiu_real_int {
2179:   PetscReal v;
2180:   PetscInt  i;
2181: };

2183: struct petsc_mpiu_scalar_int {
2184:   PetscScalar v;
2185:   PetscInt    i;
2186: };

2188: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
2189: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);

2191: #if PetscDefined(USE_64BIT_INDICES)
2192: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
2193:   PetscInt a;
2194:   PetscInt b;
2195: };
2196: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
2197:   PetscInt    a;
2198:   PetscMPIInt b;
2199: };
2200: /*
2201:  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
2202:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
2203:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");

2205:  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
2206:  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
2207:  pass! So we just comment it out...
2208: */
2209: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
2210: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
2211: #else
2212:   #define MPIU_2INT       MPI_2INT
2213:   #define MPIU_INT_MPIINT MPI_2INT
2214: #endif
2215: PETSC_EXTERN MPI_Datatype MPI_4INT;
2216: PETSC_EXTERN MPI_Datatype MPIU_4INT;

2218: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
2219: {
2220:   PetscInt result = 1;
2221:   while (power) {
2222:     if (power & 1) result *= base;
2223:     power >>= 1;
2224:     if (power) base *= base;
2225:   }
2226:   return result;
2227: }

2229: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
2230: {
2231:   PetscInt64 result = 1;
2232:   while (power) {
2233:     if (power & 1) result *= base;
2234:     power >>= 1;
2235:     if (power) base *= base;
2236:   }
2237:   return result;
2238: }

2240: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
2241: {
2242:   PetscReal result = 1;
2243:   if (power < 0) {
2244:     power = -power;
2245:     base  = ((PetscReal)1) / base;
2246:   }
2247:   while (power) {
2248:     if (power & 1) result *= base;
2249:     power >>= 1;
2250:     if (power) base *= base;
2251:   }
2252:   return result;
2253: }

2255: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
2256: {
2257:   PetscScalar result = (PetscReal)1;
2258:   if (power < 0) {
2259:     power = -power;
2260:     base  = ((PetscReal)1) / base;
2261:   }
2262:   while (power) {
2263:     if (power & 1) result *= base;
2264:     power >>= 1;
2265:     if (power) base *= base;
2266:   }
2267:   return result;
2268: }

2270: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
2271: {
2272:   PetscScalar cpower = power;
2273:   return PetscPowScalar(base, cpower);
2274: }

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

2279:    Synopsis:
2280: #include <petscmath.h>
2281:    bool PetscApproximateLTE(PetscReal x, constant float)

2283:    Not Collective

2285:    Input Parameters:
2286: +   x - the variable
2287: -   b - the constant float it is checking if `x` is less than or equal to

2289:    Level: advanced

2291:    Notes:
2292:    The fudge factor is the value `PETSC_SMALL`

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

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

2299:    Example\:
2300: .vb
2301:   PetscReal x;
2302:   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
2303: .ve

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

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

2312:    Synopsis:
2313: #include <petscmath.h>
2314:    bool PetscApproximateGTE(PetscReal x, constant float)

2316:    Not Collective

2318:    Input Parameters:
2319: +   x - the variable
2320: -   b - the constant float it is checking if `x` is greater than or equal to

2322:    Level: advanced

2324:    Notes:
2325:    The fudge factor is the value `PETSC_SMALL`

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

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

2332:    Example\:
2333: .vb
2334:   PetscReal x;
2335:   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
2336: .ve

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

2342: /*@
2343:   PetscCeilInt - Returns the ceiling of the quotation of two positive integers

2345:   Not Collective

2347:   Input Parameters:
2348: + x - the numerator
2349: - y - the denominator

2351:   Level: advanced

2353:   Example\:
2354: .vb
2355:   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
2356: .ve

2358: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2359: @*/
2360: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
2361: {
2362:   return x / y + (x % y ? 1 : 0);
2363: }

2365: /*@
2366:   PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers

2368:   Not Collective

2370:   Input Parameters:
2371: + x - the numerator
2372: - y - the denominator

2374:   Level: advanced

2376:   Example\:
2377: .vb
2378:   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
2379: .ve

2381: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2382: @*/
2383: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
2384: {
2385:   return x / y + (x % y ? 1 : 0);
2386: }

2388: /*@
2389:   PetscGCD - Returns the greatest common divisor of two integers

2391:   Not Collective

2393:   Input Parameters:
2394: + a - first number
2395: - b - second number

2397:   Level: advanced

2399: .seealso: `PetscLCM()`
2400: @*/
2401: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
2402: {
2403:   a = PetscAbsInt(a);
2404:   b = PetscAbsInt(b);
2405:   while (b != 0) {
2406:     PetscInt tmp = b;

2408:     b = a % b;
2409:     a = tmp;
2410:   }
2411:   return a;
2412: }

2414: /*@
2415:   PetscLCM - Returns the least common multiple of two integers

2417:   Not Collective

2419:   Input Parameters:
2420: + a - first number
2421: - b - second number

2423:   Level: advanced

2425: .seealso: `PetscGCD()`
2426: @*/
2427: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
2428: {
2429:   PetscInt gcd;

2431:   a = PetscAbsInt(a);
2432:   b = PetscAbsInt(b);

2434:   gcd = PetscGCD(a, b);
2435:   return gcd ? a * (b / gcd) : 0;
2436: }

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