Actual source code: petscmath.h
petsc-3.6.4 2016-04-12
1: /*
3: PETSc mathematics include file. Defines certain basic mathematical
4: constants and functions for working with single, double, and quad precision
5: floating point numbers as well as complex single and double.
7: This file is included by petscsys.h and should not be used directly.
9: */
13: #include <math.h>
15: /*
17: Defines operations that are different for complex and real numbers;
18: note that one cannot mix the use of complex and real in the same
19: PETSc program. All PETSc objects in one program are built around the object
20: PetscScalar which is either always a real or a complex.
22: */
24: #define PetscExpPassiveScalar(a) PetscExpScalar()
25: #if defined(PETSC_USE_REAL_SINGLE)
26: #define MPIU_REAL MPI_FLOAT
27: typedef float PetscReal;
28: #define PetscSqrtReal(a) sqrt(a)
29: #define PetscExpReal(a) exp(a)
30: #define PetscLogReal(a) log(a)
31: #define PetscLog10Real(a) log10(a)
32: #ifdef PETSC_HAVE_LOG2
33: #define PetscLog2Real(a) log2(a)
34: #endif
35: #define PetscSinReal(a) sin(a)
36: #define PetscCosReal(a) cos(a)
37: #define PetscTanReal(a) tan(a)
38: #define PetscAsinReal(a) asin(a)
39: #define PetscAcosReal(a) acos(a)
40: #define PetscAtanReal(a) atan(a)
41: #define PetscAtan2Real(a,b) atan2(a,b)
42: #define PetscSinhReal(a) sinh(a)
43: #define PetscCoshReal(a) cosh(a)
44: #define PetscTanhReal(a) tanh(a)
45: #define PetscPowReal(a,b) pow(a,b)
46: #define PetscCeilReal(a) ceil(a)
47: #define PetscFloorReal(a) floor(a)
48: #define PetscFmodReal(a,b) fmod(a,b)
49: #define PetscTGamma(a) tgammaf(a)
50: #elif defined(PETSC_USE_REAL_DOUBLE)
51: #define MPIU_REAL MPI_DOUBLE
52: typedef double PetscReal;
53: #define PetscSqrtReal(a) sqrt(a)
54: #define PetscExpReal(a) exp(a)
55: #define PetscLogReal(a) log(a)
56: #define PetscLog10Real(a) log10(a)
57: #ifdef PETSC_HAVE_LOG2
58: #define PetscLog2Real(a) log2(a)
59: #endif
60: #define PetscSinReal(a) sin(a)
61: #define PetscCosReal(a) cos(a)
62: #define PetscTanReal(a) tan(a)
63: #define PetscAsinReal(a) asin(a)
64: #define PetscAcosReal(a) acos(a)
65: #define PetscAtanReal(a) atan(a)
66: #define PetscAtan2Real(a,b) atan2(a,b)
67: #define PetscSinhReal(a) sinh(a)
68: #define PetscCoshReal(a) cosh(a)
69: #define PetscTanhReal(a) tanh(a)
70: #define PetscPowReal(a,b) pow(a,b)
71: #define PetscCeilReal(a) ceil(a)
72: #define PetscFloorReal(a) floor(a)
73: #define PetscFmodReal(a,b) fmod(a,b)
74: #define PetscTGamma(a) tgamma(a)
75: #elif defined(PETSC_USE_REAL___FLOAT128)
76: #if defined(__cplusplus)
77: extern "C" {
78: #endif
79: #include <quadmath.h>
80: #if defined(__cplusplus)
81: }
82: #endif
83: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PetscAttrMPITypeTag(__float128);
84: #define MPIU_REAL MPIU___FLOAT128
85: typedef __float128 PetscReal;
86: #define PetscSqrtReal(a) sqrtq(a)
87: #define PetscExpReal(a) expq(a)
88: #define PetscLogReal(a) logq(a)
89: #define PetscLog10Real(a) log10q(a)
90: #ifdef PETSC_HAVE_LOG2
91: #define PetscLog2Real(a) log2q(a)
92: #endif
93: #define PetscSinReal(a) sinq(a)
94: #define PetscCosReal(a) cosq(a)
95: #define PetscTanReal(a) tanq(a)
96: #define PetscAsinReal(a) asinq(a)
97: #define PetscAcosReal(a) acosq(a)
98: #define PetscAtanReal(a) atanq(a)
99: #define PetscAtan2Real(a,b) atan2q(a,b)
100: #define PetscSinhReal(a) sinhq(a)
101: #define PetscCoshReal(a) coshq(a)
102: #define PetscTanhReal(a) tanhq(a)
103: #define PetscPowReal(a,b) powq(a,b)
104: #define PetscCeilReal(a) ceilq(a)
105: #define PetscFloorReal(a) floorq(a)
106: #define PetscFmodReal(a,b) fmodq(a,b)
107: #define PetscTGamma(a) tgammaq(a)
108: #endif /* PETSC_USE_REAL_* */
110: /*
111: Complex number definitions
112: */
113: #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) && !defined(PETSC_USE_REAL___FLOAT128)
114: #if !defined(PETSC_SKIP_COMPLEX)
115: #define PETSC_HAVE_COMPLEX 1
116: /* C++ support of complex number */
117: #if defined(PETSC_HAVE_CUSP)
118: #define complexlib cusp
119: #include <cusp/complex.h>
120: #else
121: #define complexlib std
122: #include <complex>
123: #endif
125: #define PetscRealPartComplex(a) (a).real()
126: #define PetscImaginaryPartComplex(a) (a).imag()
127: #define PetscAbsComplex(a) complexlib::abs(a)
128: #define PetscConjComplex(a) complexlib::conj(a)
129: #define PetscSqrtComplex(a) complexlib::sqrt(a)
130: #define PetscPowComplex(a,b) complexlib::pow(a,b)
131: #define PetscExpComplex(a) complexlib::exp(a)
132: #define PetscLogComplex(a) complexlib::log(a)
133: #define PetscSinComplex(a) complexlib::sin(a)
134: #define PetscCosComplex(a) complexlib::cos(a)
135: #define PetscAsinComplex(a) complexlib::asin(a)
136: #define PetscAcosComplex(a) complexlib::acos(a)
137: #define PetscTanComplex(a) complexlib::tan(a)
138: #define PetscSinhComplex(a) complexlib::sinh(a)
139: #define PetscCoshComplex(a) complexlib::cosh(a)
140: #define PetscTanhComplex(a) complexlib::tanh(a)
142: #if defined(PETSC_USE_REAL_SINGLE)
143: typedef complexlib::complex<float> PetscComplex;
144: #elif defined(PETSC_USE_REAL_DOUBLE)
145: typedef complexlib::complex<double> PetscComplex;
146: #elif defined(PETSC_USE_REAL___FLOAT128)
147: typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */
148: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128;
149: #endif /* PETSC_USE_REAL_ */
150: #endif /* ! PETSC_SKIP_COMPLEX */
152: #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
153: #if !defined(PETSC_SKIP_COMPLEX)
154: #define PETSC_HAVE_COMPLEX 1
155: #include <complex.h>
157: #if defined(PETSC_USE_REAL_SINGLE)
158: typedef float _Complex PetscComplex;
160: #define PetscRealPartComplex(a) crealf(a)
161: #define PetscImaginaryPartComplex(a) cimagf(a)
162: #define PetscAbsComplex(a) cabsf(a)
163: #define PetscConjComplex(a) conjf(a)
164: #define PetscSqrtComplex(a) csqrtf(a)
165: #define PetscPowComplex(a,b) cpowf(a,b)
166: #define PetscExpComplex(a) cexpf(a)
167: #define PetscLogComplex(a) clogf(a)
168: #define PetscSinComplex(a) csinf(a)
169: #define PetscCosComplex(a) ccosf(a)
170: #define PetscAsinComplex(a) casinf(a)
171: #define PetscAcosComplex(a) cacosf(a)
172: #define PetscTanComplex(a) ctanf(a)
173: #define PetscSinhComplex(a) csinhf(a)
174: #define PetscCoshComplex(a) ccoshf(a)
175: #define PetscTanhComplex(a) ctanhf(a)
177: #elif defined(PETSC_USE_REAL_DOUBLE)
178: typedef double _Complex PetscComplex;
180: #define PetscRealPartComplex(a) creal(a)
181: #define PetscImaginaryPartComplex(a) cimag(a)
182: #define PetscAbsComplex(a) cabs(a)
183: #define PetscConjComplex(a) conj(a)
184: #define PetscSqrtComplex(a) csqrt(a)
185: #define PetscPowComplex(a,b) cpow(a,b)
186: #define PetscExpComplex(a) cexp(a)
187: #define PetscLogComplex(a) clog(a)
188: #define PetscSinComplex(a) csin(a)
189: #define PetscCosComplex(a) ccos(a)
190: #define PetscAsinComplex(a) casin(a)
191: #define PetscAcosComplex(a) cacos(a)
192: #define PetscTanComplex(a) ctan(a)
193: #define PetscSinhComplex(a) csinh(a)
194: #define PetscCoshComplex(a) ccosh(a)
195: #define PetscTanhComplex(a) ctanh(a)
197: #elif defined(PETSC_USE_REAL___FLOAT128)
198: typedef __complex128 PetscComplex;
199: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 PetscAttrMPITypeTag(__complex128);
201: #define PetscRealPartComplex(a) crealq(a)
202: #define PetscImaginaryPartComplex(a) cimagq(a)
203: #define PetscAbsComplex(a) cabsq(a)
204: #define PetscConjComplex(a) conjq(a)
205: #define PetscSqrtComplex(a) csqrtq(a)
206: #define PetscPowComplex(a,b) cpowq(a,b)
207: #define PetscExpComplex(a) cexpq(a)
208: #define PetscLogComplex(a) clogq(a)
209: #define PetscSinComplex(a) csinq(a)
210: #define PetscCosComplex(a) ccosq(a)
211: #define PetscAsinComplex(a) casinq(a)
212: #define PetscAcosComplex(a) cacosq(a)
213: #define PetscTanComplex(a) ctanq(a)
214: #define PetscSinhComplex(a) csinhq(a)
215: #define PetscCoshComplex(a) ccoshq(a)
216: #define PetscTanhComplex(a) ctanhq(a)
218: #endif /* PETSC_USE_REAL_* */
219: #elif (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
220: #error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available"
221: #endif /* !PETSC_SKIP_COMPLEX */
222: #endif /* (__cplusplus && PETSC_HAVE_CXX_COMPLEX) else-if (!__cplusplus && PETSC_HAVE_C99_COMPLEX) */
224: #if defined(PETSC_HAVE_COMPLEX)
225: #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
226: #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX
227: #define MPIU_C_COMPLEX MPI_C_COMPLEX
228: #else
229: # if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX)
230: typedef complexlib::complex<double> petsc_mpiu_c_double_complex;
231: typedef complexlib::complex<float> petsc_mpiu_c_complex;
232: # elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX)
233: typedef double _Complex petsc_mpiu_c_double_complex;
234: typedef float _Complex petsc_mpiu_c_complex;
235: # else
236: typedef struct {double real,imag;} petsc_mpiu_c_double_complex;
237: typedef struct {float real,imag;} petsc_mpiu_c_complex;
238: # endif
239: PETSC_EXTERN MPI_Datatype MPIU_C_DOUBLE_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_double_complex);
240: PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX PetscAttrMPITypeTagLayoutCompatible(petsc_mpiu_c_complex);
241: #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */
242: #endif /* PETSC_HAVE_COMPLEX */
244: #if defined(PETSC_HAVE_COMPLEX)
245: # if defined(PETSC_USE_REAL_SINGLE)
246: # define MPIU_COMPLEX MPIU_C_COMPLEX
247: # elif defined(PETSC_USE_REAL_DOUBLE)
248: # define MPIU_COMPLEX MPIU_C_DOUBLE_COMPLEX
249: # elif defined(PETSC_USE_REAL___FLOAT128)
250: # define MPIU_COMPLEX MPIU___COMPLEX128
251: # endif /* PETSC_USE_REAL_* */
252: #endif
254: #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_SKIP_COMPLEX))
255: typedef PetscComplex PetscScalar;
256: #define PetscRealPart(a) PetscRealPartComplex(a)
257: #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)
258: #define PetscAbsScalar(a) PetscAbsComplex(a)
259: #define PetscConj(a) PetscConjComplex(a)
260: #define PetscSqrtScalar(a) PetscSqrtComplex(a)
261: #define PetscPowScalar(a,b) PetscPowComplex(a,b)
262: #define PetscExpScalar(a) PetscExpComplex(a)
263: #define PetscLogScalar(a) PetscLogComplex(a)
264: #define PetscSinScalar(a) PetscSinComplex(a)
265: #define PetscCosScalar(a) PetscCosComplex(a)
266: #define PetscAsinScalar(a) PetscAsinComplex(a)
267: #define PetscAcosScalar(a) PetscAcosComplex(a)
268: #define PetscTanScalar(a) PetscTanComplex(a)
269: #define PetscSinhScalar(a) PetscSinhComplex(a)
270: #define PetscCoshScalar(a) PetscCoshComplex(a)
271: #define PetscTanhScalar(a) PetscTanhComplex(a)
272: #define MPIU_SCALAR MPIU_COMPLEX
274: /*
275: real number definitions
276: */
277: #else /* PETSC_USE_COMPLEX */
278: typedef PetscReal PetscScalar;
279: #define MPIU_SCALAR MPIU_REAL
281: #define PetscRealPart(a) (a)
282: #define PetscImaginaryPart(a) ((PetscReal)0.)
283: PETSC_STATIC_INLINE PetscReal PetscAbsScalar(PetscScalar a) {return a < 0.0 ? -a : a;}
284: #define PetscConj(a) (a)
285: #if !defined(PETSC_USE_REAL___FLOAT128)
286: #define PetscSqrtScalar(a) sqrt(a)
287: #define PetscPowScalar(a,b) pow(a,b)
288: #define PetscExpScalar(a) exp(a)
289: #define PetscLogScalar(a) log(a)
290: #define PetscSinScalar(a) sin(a)
291: #define PetscCosScalar(a) cos(a)
292: #define PetscAsinScalar(a) asin(a)
293: #define PetscAcosScalar(a) acos(a)
294: #define PetscTanScalar(a) tan(a)
295: #define PetscSinhScalar(a) sinh(a)
296: #define PetscCoshScalar(a) cosh(a)
297: #define PetscTanhScalar(a) tanh(a)
298: #else /* PETSC_USE_REAL___FLOAT128 */
299: #define PetscSqrtScalar(a) sqrtq(a)
300: #define PetscPowScalar(a,b) powq(a,b)
301: #define PetscExpScalar(a) expq(a)
302: #define PetscLogScalar(a) logq(a)
303: #define PetscSinScalar(a) sinq(a)
304: #define PetscCosScalar(a) cosq(a)
305: #define PetscAsinScalar(a) asinq(a)
306: #define PetscAcosScalar(a) acosq(a)
307: #define PetscTanScalar(a) tanq(a)
308: #define PetscSinhScalar(a) sinhq(a)
309: #define PetscCoshScalar(a) coshq(a)
310: #define PetscTanhScalar(a) tanhq(a)
311: #endif /* PETSC_USE_REAL___FLOAT128 */
313: #endif /* PETSC_USE_COMPLEX */
315: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)
316: #define PetscAbs(a) (((a) >= 0) ? (a) : -(a))
318: /* --------------------------------------------------------------------------*/
320: /*
321: Certain objects may be created using either single or double precision.
322: This is currently not used.
323: */
324: typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision;
326: #if defined(PETSC_HAVE_COMPLEX)
327: /* PETSC_i is the imaginary number, i */
328: PETSC_EXTERN PetscComplex PETSC_i;
329: #endif
331: /*MC
332: PetscMin - Returns minimum of two numbers
334: Synopsis:
335: #include <petscmath.h>
336: type PetscMin(type v1,type v2)
338: Not Collective
340: Input Parameter:
341: + v1 - first value to find minimum of
342: - v2 - second value to find minimum of
344: Notes: type can be integer or floating point value
346: Level: beginner
348: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
350: M*/
351: #define PetscMin(a,b) (((a)<(b)) ? (a) : (b))
353: /*MC
354: PetscMax - Returns maxium of two numbers
356: Synopsis:
357: #include <petscmath.h>
358: type max PetscMax(type v1,type v2)
360: Not Collective
362: Input Parameter:
363: + v1 - first value to find maximum of
364: - v2 - second value to find maximum of
366: Notes: type can be integer or floating point value
368: Level: beginner
370: .seealso: PetscMin(), PetscClipInterval(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
372: M*/
373: #define PetscMax(a,b) (((a)<(b)) ? (b) : (a))
375: /*MC
376: PetscClipInterval - Returns a number clipped to be within an interval
378: Synopsis:
379: #include <petscmath.h>
380: type clip PetscClipInterval(type x,type a,type b)
382: Not Collective
384: Input Parameter:
385: + x - value to use if within interval (a,b)
386: . a - lower end of interval
387: - b - upper end of interval
389: Notes: type can be integer or floating point value
391: Level: beginner
393: .seealso: PetscMin(), PetscMax(), PetscAbsInt(), PetscAbsReal(), PetscSqr()
395: M*/
396: #define PetscClipInterval(x,a,b) (PetscMax((a),PetscMin((x),(b))))
398: /*MC
399: PetscAbsInt - Returns the absolute value of an integer
401: Synopsis:
402: #include <petscmath.h>
403: int abs PetscAbsInt(int v1)
405: Not Collective
407: Input Parameter:
408: . v1 - the integer
410: Level: beginner
412: .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr()
414: M*/
415: #define PetscAbsInt(a) (((a)<0) ? -(a) : (a))
417: /*MC
418: PetscAbsReal - Returns the absolute value of an real number
420: Synopsis:
421: #include <petscmath.h>
422: Real abs PetscAbsReal(PetscReal v1)
424: Not Collective
426: Input Parameter:
427: . v1 - the double
430: Level: beginner
432: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr()
434: M*/
435: #define PetscAbsReal(a) (((a)<0) ? -(a) : (a))
437: /*MC
438: PetscSqr - Returns the square of a number
440: Synopsis:
441: #include <petscmath.h>
442: type sqr PetscSqr(type v1)
444: Not Collective
446: Input Parameter:
447: . v1 - the value
449: Notes: type can be integer or floating point value
451: Level: beginner
453: .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal()
455: M*/
456: #define PetscSqr(a) ((a)*(a))
458: /* ----------------------------------------------------------------------------*/
459: /*
460: Basic constants
461: */
462: #if defined(PETSC_USE_REAL___FLOAT128)
463: #define PETSC_PI M_PIq
464: #elif defined(M_PI)
465: #define PETSC_PI M_PI
466: #else
467: #define PETSC_PI 3.14159265358979323846264338327950288419716939937510582
468: #endif
470: #if !defined(PETSC_USE_64BIT_INDICES)
471: #define PETSC_MAX_INT 2147483647
472: #define PETSC_MIN_INT (-PETSC_MAX_INT - 1)
473: #else
474: #define PETSC_MAX_INT 9223372036854775807L
475: #define PETSC_MIN_INT (-PETSC_MAX_INT - 1)
476: #endif
478: #if defined(PETSC_USE_REAL_SINGLE)
479: # define PETSC_MAX_REAL 3.40282346638528860e+38F
480: # define PETSC_MIN_REAL -PETSC_MAX_REAL
481: # define PETSC_MACHINE_EPSILON 1.19209290e-07F
482: # define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
483: # define PETSC_SMALL 1.e-5
484: #elif defined(PETSC_USE_REAL_DOUBLE)
485: # define PETSC_MAX_REAL 1.7976931348623157e+308
486: # define PETSC_MIN_REAL -PETSC_MAX_REAL
487: # define PETSC_MACHINE_EPSILON 2.2204460492503131e-16
488: # define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
489: # define PETSC_SMALL 1.e-10
490: #elif defined(PETSC_USE_REAL___FLOAT128)
491: # define PETSC_MAX_REAL FLT128_MAX
492: # define PETSC_MIN_REAL -FLT128_MAX
493: # define PETSC_MACHINE_EPSILON FLT128_EPSILON
494: # define PETSC_SQRT_MACHINE_EPSILON 1.38777878078e-17
495: # define PETSC_SMALL 1.e-20
496: #endif
498: #define PETSC_INFINITY PETSC_MAX_REAL/4.0
499: #define PETSC_NINFINITY -PETSC_INFINITY
501: PETSC_EXTERN PetscErrorCode PetscIsInfOrNanReal(PetscReal);
502: PETSC_EXTERN PetscBool PetscIsNormalReal(PetscReal);
503: PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar v) {return PetscIsInfOrNanReal(PetscAbsScalar(v));}
504: PETSC_STATIC_INLINE PetscErrorCode PetscIsNormalScalar(PetscScalar v) {return PetscIsNormalReal(PetscAbsScalar(v));}
506: /* ----------------------------------------------------------------------------*/
507: #define PassiveReal PetscReal
508: #define PassiveScalar PetscScalar
510: /*
511: These macros are currently hardwired to match the regular data types, so there is no support for a different
512: MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
513: */
514: #define MPIU_MATSCALAR MPIU_SCALAR
515: typedef PetscScalar MatScalar;
516: typedef PetscReal MatReal;
518: struct petsc_mpiu_2scalar {PetscScalar a,b;};
519: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2scalar);
520: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
521: struct petsc_mpiu_2int {PetscInt a,b;};
522: PETSC_EXTERN MPI_Datatype MPIU_2INT PetscAttrMPITypeTagLayoutCompatible(struct petsc_mpiu_2int);
523: #else
524: #define MPIU_2INT MPI_2INT
525: #endif
527: PETSC_STATIC_INLINE PetscInt PetscPowInt(PetscInt base,PetscInt power)
528: {
529: PetscInt result = 1;
530: while (power) {
531: if (power & 1) result *= base;
532: power >>= 1;
533: base *= base;
534: }
535: return result;
536: }
538: PETSC_STATIC_INLINE PetscReal PetscPowRealInt(PetscReal base,PetscInt power)
539: {
540: PetscReal result = 1;
541: if (power < 0) {
542: power = -power;
543: if (base != 0.0) base = 1./base;
544: }
545: while (power) {
546: if (power & 1) result *= base;
547: power >>= 1;
548: base *= base;
549: }
550: return result;
551: }
553: PETSC_STATIC_INLINE PetscScalar PetscPowScalarInt(PetscScalar base,PetscInt power)
554: {
555: PetscScalar result = 1;
556: if (power < 0) {
557: power = -power;
558: if (base != 0.0) base = 1./base;
559: }
560: while (power) {
561: if (power & 1) result *= base;
562: power >>= 1;
563: base *= base;
564: }
565: return result;
566: }
568: PETSC_STATIC_INLINE PetscScalar PetscPowScalarReal(PetscScalar base,PetscReal power)
569: {
570: PetscScalar cpower = power;
571: return PetscPowScalar(base,cpower);
572: }
574: #ifndef PETSC_HAVE_LOG2
575: PETSC_STATIC_INLINE PetscReal PetscLog2Real(PetscReal n)
576: {
577: return PetscLogReal(n)/PetscLogReal(2.0);
578: }
579: #endif
580: #endif