summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-01-24 23:56:11 +0000
committergoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-01-24 23:56:11 +0000
commitaea70b578fc76529f1519ce85b1b4591db01d80d (patch)
tree571569b509f8e3fa0e25d79aea05bfba8711af97
parent910923177db17fbb3f9970463ff22bc61a494939 (diff)
Patch from Yaakoub to add a complex version of the 'pow' function.
git-svn-id: http://svn.cactuscode.org/flesh/trunk@3966 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--src/include/cctk_Complex.h6
-rw-r--r--src/main/Complex.c79
2 files changed, 83 insertions, 2 deletions
diff --git a/src/include/cctk_Complex.h b/src/include/cctk_Complex.h
index e47b7e59..041884f3 100644
--- a/src/include/cctk_Complex.h
+++ b/src/include/cctk_Complex.h
@@ -31,7 +31,8 @@ cctk_complex CCTK_Cmplx##Div (cctk_complex a, cctk_complex b); \
cctk_complex CCTK_Cmplx##Sin (cctk_complex complex_number); \
cctk_complex CCTK_Cmplx##Cos (cctk_complex complex_number); \
cctk_complex CCTK_Cmplx##Exp (cctk_complex complex_number); \
-cctk_complex CCTK_Cmplx##Sqrt (cctk_complex complex_number);
+cctk_complex CCTK_Cmplx##Sqrt (cctk_complex complex_number); \
+cctk_complex CCTK_Cmplx##Pow (cctk_complex complex_number, cctk_real w);
/* declare complex functions for all available precisions */
@@ -63,6 +64,7 @@ DECLARE_CMPLX_FUNCTIONS (CCTK_Cmplx32, CCTK_REAL16, CCTK_COMPLEX32)
#define CCTK_CmplxCos CCTK_Cmplx8Cos
#define CCTK_CmplxExp CCTK_Cmplx8Exp
#define CCTK_CmplxSqrt CCTK_Cmplx8Sqrt
+#define CCTK_CmplxPow CCTK_Cmplx8Pow
#elif CCTK_REAL_PRECISION_8
#define CCTK_Cmplx CCTK_Cmplx16
#define CCTK_CmplxReal CCTK_Cmplx16Real
@@ -77,6 +79,7 @@ DECLARE_CMPLX_FUNCTIONS (CCTK_Cmplx32, CCTK_REAL16, CCTK_COMPLEX32)
#define CCTK_CmplxCos CCTK_Cmplx16Cos
#define CCTK_CmplxExp CCTK_Cmplx16Exp
#define CCTK_CmplxSqrt CCTK_Cmplx16Sqrt
+#define CCTK_CmplxPow CCTK_Cmplx16Pow
#elif CCTK_REAL_PRECISION_16
#define CCTK_Cmplx CCTK_Cmplx32
#define CCTK_CmplxReal CCTK_Cmplx32Real
@@ -91,6 +94,7 @@ DECLARE_CMPLX_FUNCTIONS (CCTK_Cmplx32, CCTK_REAL16, CCTK_COMPLEX32)
#define CCTK_CmplxCos CCTK_Cmplx32Cos
#define CCTK_CmplxExp CCTK_Cmplx32Exp
#define CCTK_CmplxSqrt CCTK_Cmplx32Sqrt
+#define CCTK_CmplxPow CCTK_Cmplx32Pow
#endif
#ifdef __cplusplus
diff --git a/src/main/Complex.c b/src/main/Complex.c
index 998978a3..9415c2f2 100644
--- a/src/main/Complex.c
+++ b/src/main/Complex.c
@@ -507,6 +507,82 @@ cctk_complex CCTK_Cmplx##Sqrt (cctk_complex complex_number) \
return (result); \
}
+ /*@@
+ @routine CCTK_CmplxPow
+ @date
+ @author Yaakoub Y El Khamra
+ @desc
+ Raises a complex number to a given power
+ @enddesc
+
+ @var complex_number
+ @vdesc The complex number
+ @vtype CCTK_COMPLEX
+ @vio in
+ @endvar
+
+ @returntype CCTK_COMPLEX
+ @returndesc
+ The square root
+ @endreturndesc
+@@*/
+#define DEFINE_CCTK_CMPLX_POW(CCTK_Cmplx, cctk_real, cctk_complex) \
+cctk_complex CCTK_Cmplx##Pow (cctk_complex complex_number, cctk_real w) \
+{ \
+ cctk_real R, theta, phi; \
+ cctk_complex result; \
+ \
+ if ( complex_number.Re > 0) \
+ { \
+ theta = 0.0; \
+ phi = atan(complex_number.Im/complex_number.Re) + theta; \
+ R = sqrt(complex_number.Re*complex_number.Re + complex_number.Im*complex_number.Im);\
+ R = pow(R,w); \
+ result.Re = R * cos (w * phi); \
+ result.Im = R * sin (w * phi); \
+ } \
+ else if ( complex_number.Re < 0 && complex_number.Im >= 0 ) \
+ { \
+ theta = 4.0 * atan (1.0); \
+ phi = atan(complex_number.Im/complex_number.Re) + theta; \
+ R = sqrt(complex_number.Re*complex_number.Re + complex_number.Im*complex_number.Im);\
+ R = pow(R,w); \
+ result.Re = R * cos (w * phi); \
+ result.Im = R * sin (w * phi); \
+ } \
+ else if ( complex_number.Re < 0 && complex_number.Im < 0 ) \
+ { \
+ theta = 4.0 * atan (1.0); \
+ phi = atan(complex_number.Im/complex_number.Re) + theta; \
+ R = sqrt(complex_number.Re*complex_number.Re + complex_number.Im*complex_number.Im);\
+ R = pow(R,w); \
+ result.Re = R * cos (w * phi); \
+ result.Im = R * sin (w * phi); \
+ } \
+ else if ( fabs(complex_number.Re) <= 1e-20 && fabs(complex_number.Im) < 1e-20 )\
+ { \
+ result.Re = 0.0; \
+ result.Im = 0.0; \
+ } \
+ else if ( fabs(complex_number.Re) <= 1e-20 && complex_number.Im < 0 ) \
+ { \
+ phi = 2.0 * atan (1.0); \
+ R = sqrt(complex_number.Re*complex_number.Re + complex_number.Im*complex_number.Im);\
+ R = pow(R,w); \
+ result.Re = R * cos (w * phi); \
+ result.Im = R * sin (w * phi); \
+ } \
+ if ( fabs(complex_number.Re) <= 1e-20 && complex_number.Im < 0 ) \
+ { \
+ phi = -2.0 * atan (1.0); \
+ R = sqrt(complex_number.Re*complex_number.Re + complex_number.Im*complex_number.Im);\
+ R = pow(R,w); \
+ result.Re = R * cos (w * phi); \
+ result.Im = R * sin (w * phi); \
+ } \
+ \
+ return (result); \
+}
/* macro to define a set of complex functions for a given precision */
#define DEFINE_CMPLX_FUNCTIONS(CCTK_Cmplx, cctk_real, cctk_complex) \
@@ -522,7 +598,8 @@ cctk_complex CCTK_Cmplx##Sqrt (cctk_complex complex_number) \
DEFINE_CCTK_CMPLX_SIN (CCTK_Cmplx, cctk_real, cctk_complex) \
DEFINE_CCTK_CMPLX_COS (CCTK_Cmplx, cctk_real, cctk_complex) \
DEFINE_CCTK_CMPLX_EXP (CCTK_Cmplx, cctk_real, cctk_complex) \
- DEFINE_CCTK_CMPLX_SQRT (CCTK_Cmplx, cctk_real, cctk_complex)
+ DEFINE_CCTK_CMPLX_SQRT (CCTK_Cmplx, cctk_real, cctk_complex) \
+ DEFINE_CCTK_CMPLX_POW (CCTK_Cmplx, cctk_real, cctk_complex) \
/* define complex functions for all available precisions */
#ifdef CCTK_REAL4