00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef IPPL_FFT_SCSL_FFT_H
00012 #define IPPL_FFT_SCSL_FFT_H
00013
00014
00015 #include "Utility/PAssert.h"
00016 #include "Utility/IpplInfo.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if defined(IPPL_T3E)
00029
00030 #define sgiccfft_ SGICCFFT
00031 #define sgiscfft_ SGISCFFT
00032 #define sgicsfft_ SGICSFFT
00033
00034 #endif
00035
00036
00037
00038
00039
00040 #if defined(IPPL_T3E)
00041
00042
00043 extern "C" {
00044
00045 void sgiccfft_(int& isign, int& n, double& scale, double& x, double& y,
00046 double& table, double& work, int& isys);
00047
00048 void sgiscfft_(int& isign, int& n, double& scale, double& x, double& y,
00049 double& table, double& work, int& isys);
00050
00051 void sgicsfft_(int& isign, int& n, double& scale, double& x, double& y,
00052 double& table, double& work, int& isys);
00053 }
00054
00055 #else
00056
00057
00058 extern "C" {
00059
00060 void sgizzfft_(int& isign, int& n, double& scale, double& x, double& y,
00061 double& table, double& work, int& isys);
00062
00063 void sgidzfft_(int& isign, int& n, double& scale, double& x, double& y,
00064 double& table, double& work, int& isys);
00065
00066 void sgizdfft_(int& isign, int& n, double& scale, double& x, double& y,
00067 double& table, double& work, int& isys);
00068
00069 void sgiccfft_(int& isign, int& n, float& scale, float& x, float& y,
00070 float& table, float& work, int& isys);
00071
00072 void sgiscfft_(int& isign, int& n, float& scale, float& x, float& y,
00073 float& table, float& work, int& isys);
00074
00075 void sgicsfft_(int& isign, int& n, float& scale, float& x, float& y,
00076 float& table, float& work, int& isys);
00077 }
00078
00079 #endif // defined(IPPL_T3E)
00080
00081
00082
00083
00084 template <class T>
00085 class SCSL_wrap {};
00086
00087
00088 template <>
00089 class SCSL_wrap<float> {
00090
00091 public:
00092
00093
00094
00095 static void ccfft(int isign, int n, float scale, float* x, float* y,
00096 float* table, float* work, int isys) {
00097 sgiccfft_(isign, n, scale, *x, *y, *table, *work, isys);
00098 }
00099
00100 static void rcfft(int isign, int n, float scale, float* x, float* y,
00101 float* table, float* work, int isys) {
00102 sgiscfft_(isign, n, scale, *x, *y, *table, *work, isys);
00103 }
00104
00105 static void crfft(int isign, int n, float scale, float* x, float* y,
00106 float* table, float* work, int isys) {
00107 sgicsfft_(isign, n, scale, *x, *y, *table, *work, isys);
00108 }
00109
00110 };
00111
00112
00113
00114
00115 #if defined(IPPL_T3E)
00116
00117
00118 template <>
00119 class SCSL_wrap<double> {
00120
00121 public:
00122
00123
00124
00125 static void ccfft(int isign, int n, double scale, double* x, double* y,
00126 double* table, double* work, int isys) {
00127 sgiccfft_(isign, n, scale, *x, *y, *table, *work, isys);
00128 }
00129
00130 static void rcfft(int isign, int n, double scale, double* x, double* y,
00131 double* table, double* work, int isys) {
00132 sgiscfft_(isign, n, scale, *x, *y, *table, *work, isys);
00133 }
00134
00135 static void crfft(int isign, int n, double scale, double* x, double* y,
00136 double* table, double* work, int isys) {
00137 sgicsfft_(isign, n, scale, *x, *y, *table, *work, isys);
00138 }
00139
00140 };
00141
00142 #else
00143
00144
00145 template <>
00146 class SCSL_wrap<double> {
00147
00148 public:
00149
00150
00151
00152 static void ccfft(int isign, int n, double scale, double* x, double* y,
00153 double* table, double* work, int isys) {
00154 sgizzfft_(isign, n, scale, *x, *y, *table, *work, isys);
00155 }
00156
00157 static void rcfft(int isign, int n, double scale, double* x, double* y,
00158 double* table, double* work, int isys) {
00159 sgidzfft_(isign, n, scale, *x, *y, *table, *work, isys);
00160 }
00161
00162 static void crfft(int isign, int n, double scale, double* x, double* y,
00163 double* table, double* work, int isys) {
00164 sgizdfft_(isign, n, scale, *x, *y, *table, *work, isys);
00165 }
00166
00167 };
00168
00169 #endif // defined(IPPL_T3E)
00170
00171
00172
00173 template <class T>
00174 class SCSL {
00175
00176 public:
00177
00178
00179 #ifdef IPPL_HAS_TEMPLATED_COMPLEX
00180 typedef complex<T> Complex_t;
00181 #else
00182 typedef complex Complex_t;
00183 #endif
00184
00185
00186 SCSL(void) {}
00187
00188
00189 ~SCSL(void);
00190
00191
00192 void setup(unsigned numTransformDims, const int* transformTypes,
00193 const int* axisLengths);
00194
00195
00196 void callFFT(unsigned transformDim, int direction, Complex_t* data);
00197
00198
00199 void callFFT(unsigned transformDim, int direction, T* data);
00200
00201 private:
00202
00203 unsigned numTransformDims_m;
00204 int* transformType_m;
00205 int* axisLength_m;
00206 T** table_m;
00207 T** work_m;
00208
00209 };
00210
00211
00212
00213
00214
00215 template <class T>
00216 inline
00217 SCSL<T>::~SCSL(void) {
00218
00219 for (unsigned d=0; d<numTransformDims_m; ++d) {
00220 delete [] table_m[d];
00221 delete [] work_m[d];
00222 }
00223 delete [] table_m;
00224 delete [] work_m;
00225 delete [] transformType_m;
00226 delete [] axisLength_m;
00227 }
00228
00229
00230 template <class T>
00231 inline void
00232 SCSL<T>::setup(unsigned numTransformDims, const int* transformTypes,
00233 const int* axisLengths) {
00234
00235
00236 numTransformDims_m = numTransformDims;
00237 transformType_m = new int[numTransformDims_m];
00238 axisLength_m = new int[numTransformDims_m];
00239 unsigned d;
00240 for (d=0; d<numTransformDims_m; ++d) {
00241 transformType_m[d] = transformTypes[d];
00242 axisLength_m[d] = axisLengths[d];
00243 }
00244
00245
00246
00247 table_m = new T*[numTransformDims_m];
00248 work_m = new T*[numTransformDims_m];
00249 T dummy = T();
00250 for (d=0; d<numTransformDims_m; ++d) {
00251 switch (transformType_m[d]) {
00252 case 0:
00253 #if defined(IPPL_T3E)
00254 table_m[d] = new T[2 * axisLength_m[d]];
00255 work_m[d] = new T[4 * axisLength_m[d]];
00256 #else
00257 table_m[d] = new T[2 * axisLength_m[d] + 30];
00258 work_m[d] = new T[2 * axisLength_m[d]];
00259 #endif
00260
00261 SCSL_wrap<T>::ccfft(0, axisLength_m[d], dummy, &dummy, &dummy,
00262 table_m[d], &dummy, 0);
00263 break;
00264 case 1:
00265 #if defined(IPPL_T3E)
00266 table_m[d] = new T[2 * axisLength_m[d]];
00267 work_m[d] = new T[2 * (axisLength_m[d] + 2)];
00268 #else
00269 table_m[d] = new T[axisLength_m[d] + 15];
00270 work_m[d] = new T[axisLength_m[d] + 2];
00271 #endif
00272
00273 SCSL_wrap<T>::rcfft(0, axisLength_m[d], dummy, &dummy, &dummy,
00274 table_m[d], &dummy, 0);
00275 break;
00276 case 2:
00277 ERRORMSG("No sine transforms available in SCSL!!" << endl);
00278 break;
00279 default:
00280 ERRORMSG("Unknown transform type requested!!" << endl);
00281 break;
00282 }
00283 }
00284
00285 return;
00286 }
00287
00288
00289 template <class T>
00290 inline void
00291 SCSL<T>::callFFT(unsigned transformDim, int direction,
00292 SCSL<T>::Complex_t* data) {
00293
00294
00295 PAssert(transformDim<numTransformDims_m);
00296 PAssert(direction==+1 || direction==-1);
00297
00298
00299 T* rdata = reinterpret_cast<T*>(data);
00300
00301
00302 switch (transformType_m[transformDim]) {
00303 case 0:
00304 SCSL_wrap<T>::ccfft(direction, axisLength_m[transformDim], 1.0, rdata,
00305 rdata, table_m[transformDim], work_m[transformDim], 0);
00306 break;
00307 case 1:
00308 if (direction == +1) {
00309 SCSL_wrap<T>::rcfft(+1, axisLength_m[transformDim], 1.0, rdata, rdata,
00310 table_m[transformDim], work_m[transformDim], 0);
00311 }
00312 else {
00313 SCSL_wrap<T>::crfft(-1, axisLength_m[transformDim], 1.0, rdata, rdata,
00314 table_m[transformDim], work_m[transformDim], 0);
00315 }
00316 break;
00317 case 2:
00318 ERRORMSG("No sine transforms available in SCSL!!" << endl);
00319 break;
00320 default:
00321 ERRORMSG("Unknown transform type requested!!" << endl);
00322 break;
00323 }
00324
00325 return;
00326 }
00327
00328
00329
00330 template <class T>
00331 inline void
00332 SCSL<T>::callFFT(unsigned transformDim, int direction, T* data) {
00333
00334
00335 PAssert(transformDim<numTransformDims_m);
00336
00337 switch (transformType_m[transformDim]) {
00338 case 0:
00339 ERRORMSG("complex-to-complex FFT uses complex data!!" << endl);
00340 break;
00341 case 1:
00342 ERRORMSG("real-to-complex FFT uses complex data!!" << endl);
00343 break;
00344 case 2:
00345 ERRORMSG("No sine transforms available in SCSL!!" << endl);
00346 break;
00347 default:
00348 ERRORMSG("Unknown transform type requested!!" << endl);
00349 break;
00350 }
00351
00352 return;
00353 }
00354
00355
00356 #endif // IPPL_FFT_SCSL_FFT_H
00357
00358
00359
00360
00361
00362
00363