[710] | 1 | #include "fftservintf.h"
|
---|
| 2 |
|
---|
| 3 |
|
---|
[1371] | 4 | /*!
|
---|
| 5 | \class SOPHYA::FFTServerInterface
|
---|
| 6 | \ingroup NTools
|
---|
| 7 | Defines the interface for FFT (Fast Fourier Transform) operations.
|
---|
| 8 | */
|
---|
[710] | 9 |
|
---|
| 10 | /* --Methode-- */
|
---|
| 11 | FFTServerInterface::FFTServerInterface(string info)
|
---|
| 12 | {
|
---|
| 13 | _info = info;
|
---|
[717] | 14 | _fgnorm = true;
|
---|
[710] | 15 | }
|
---|
| 16 |
|
---|
| 17 | /* --Methode-- */
|
---|
| 18 | FFTServerInterface::~FFTServerInterface()
|
---|
| 19 | {
|
---|
| 20 | }
|
---|
| 21 |
|
---|
[1390] | 22 | // ----------------- Transforme pour les double -------------------
|
---|
| 23 |
|
---|
[710] | 24 | /* --Methode-- */
|
---|
[1390] | 25 | void FFTServerInterface::FFTForward(TArray< complex<r_8> > const &, TArray< complex<r_8> > &)
|
---|
[710] | 26 | {
|
---|
[1390] | 27 | throw NotAvailableOperation("FFTServer::FFTForward(TArray...) Unsupported operation !");
|
---|
[710] | 28 | }
|
---|
| 29 |
|
---|
| 30 | /* --Methode-- */
|
---|
[1390] | 31 | void FFTServerInterface::FFTBackward(TArray< complex<r_8> > const &, TArray< complex<r_8> > &)
|
---|
[710] | 32 | {
|
---|
[1390] | 33 | throw NotAvailableOperation("FFTServer::FFTBackward(TArray...) Unsupported operation !");
|
---|
[710] | 34 | }
|
---|
| 35 |
|
---|
| 36 | /* --Methode-- */
|
---|
[1390] | 37 | void FFTServerInterface::FFTForward(TArray< r_8 > const &, TArray< complex<r_8> > &)
|
---|
[710] | 38 | {
|
---|
[1390] | 39 | throw NotAvailableOperation("FFTServer::FFTForward(TArray...) Unsupported operation !");
|
---|
[710] | 40 | }
|
---|
| 41 |
|
---|
| 42 | /* --Methode-- */
|
---|
[1390] | 43 | void FFTServerInterface::FFTBackward(TArray< complex<r_8> > const &, TArray< r_8 > &)
|
---|
[710] | 44 | {
|
---|
[1390] | 45 | throw NotAvailableOperation("FFTServer::FFTBackward(TArray...) Unsupported operation !");
|
---|
[710] | 46 | }
|
---|
| 47 |
|
---|
[1390] | 48 |
|
---|
| 49 | // ----------------- Transforme pour les float -------------------
|
---|
| 50 |
|
---|
[710] | 51 | /* --Methode-- */
|
---|
[1390] | 52 | void FFTServerInterface::FFTForward(TArray< complex<r_4> > const &, TArray< complex<r_4> > &)
|
---|
[710] | 53 | {
|
---|
[1390] | 54 | throw NotAvailableOperation("FFTServer::FFTForward(TArray r_4 ... ) Unsupported operation !");
|
---|
[710] | 55 | }
|
---|
| 56 |
|
---|
| 57 | /* --Methode-- */
|
---|
[1390] | 58 | void FFTServerInterface::FFTBackward(TArray< complex<r_4> > const &, TArray< complex<r_4> > &)
|
---|
[710] | 59 | {
|
---|
[1390] | 60 | throw NotAvailableOperation("FFTServer::FFTBackward(TArray r_4 ... ) Unsupported operation !");
|
---|
[710] | 61 | }
|
---|
| 62 |
|
---|
| 63 | /* --Methode-- */
|
---|
[1390] | 64 | void FFTServerInterface::FFTForward(TArray< r_4 > const &, TArray< complex<r_4> > &)
|
---|
[710] | 65 | {
|
---|
[1390] | 66 | throw NotAvailableOperation("FFTServer::FFTForward(TArray r_4 ... ) Unsupported operation !");
|
---|
[710] | 67 | }
|
---|
| 68 |
|
---|
| 69 | /* --Methode-- */
|
---|
[1390] | 70 | void FFTServerInterface::FFTBackward(TArray< complex<r_4> > const &, TArray< r_4 > &)
|
---|
[710] | 71 | {
|
---|
[1390] | 72 | throw NotAvailableOperation("FFTServer::FFTBackward(TArray r_4 ... ) Unsupported operation !");
|
---|
[710] | 73 | }
|
---|
| 74 |
|
---|
| 75 |
|
---|
| 76 |
|
---|
| 77 | /* --Methode-- */
|
---|
[1390] | 78 | template <class T>
|
---|
[1394] | 79 | FFTArrayChecker<T>::FFTArrayChecker(string msg, bool checkpack, bool onedonly)
|
---|
[710] | 80 | {
|
---|
[1394] | 81 | _msg = msg + " FFTArrayChecker::";
|
---|
[1390] | 82 | _checkpack = checkpack;
|
---|
| 83 | _onedonly = onedonly;
|
---|
[710] | 84 | }
|
---|
| 85 |
|
---|
| 86 | /* --Methode-- */
|
---|
[1390] | 87 | template <class T>
|
---|
| 88 | FFTArrayChecker<T>::~FFTArrayChecker()
|
---|
[710] | 89 | {
|
---|
| 90 | }
|
---|
| 91 |
|
---|
[1394] | 92 | template <class T>
|
---|
| 93 | T FFTArrayChecker<T>::ZeroThreshold()
|
---|
| 94 | {
|
---|
| 95 | return(0);
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | r_8 FFTArrayChecker< r_8 >::ZeroThreshold()
|
---|
| 99 | {
|
---|
| 100 | return(1.e-18);
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | r_4 FFTArrayChecker< r_4 >::ZeroThreshold()
|
---|
| 104 | {
|
---|
| 105 | return(1.e-9);
|
---|
| 106 | }
|
---|
| 107 |
|
---|
| 108 |
|
---|
| 109 |
|
---|
[710] | 110 | /* --Methode-- */
|
---|
[1390] | 111 | template <class T>
|
---|
| 112 | int FFTArrayChecker<T>::CheckResize(TArray< complex<T> > const & in, TArray< complex<T> > & out)
|
---|
[710] | 113 | {
|
---|
[1390] | 114 | int k;
|
---|
[1394] | 115 | string msg;
|
---|
| 116 | if (in.Size() < 1) {
|
---|
| 117 | msg = _msg + "CheckResize(complex in, complex out) - Unallocated input array !";
|
---|
| 118 | throw(SzMismatchError(msg));
|
---|
| 119 | }
|
---|
[1390] | 120 | if (_checkpack)
|
---|
[1394] | 121 | if ( !in.IsPacked() ) {
|
---|
| 122 | msg = _msg + "CheckResize(complex in, complex out) - Not packed input array !";
|
---|
| 123 | throw(SzMismatchError(msg));
|
---|
| 124 | }
|
---|
[1390] | 125 | int ndg1 = 0;
|
---|
| 126 | for(k=0; k<in.NbDimensions(); k++)
|
---|
| 127 | if (in.Size(k) > 1) ndg1++;
|
---|
| 128 | if (_onedonly)
|
---|
[1394] | 129 | if (ndg1 > 1) {
|
---|
| 130 | msg = _msg + "CheckResize(complex in, complex out) - Only 1-D array accepted !";
|
---|
| 131 | throw(SzMismatchError(msg));
|
---|
| 132 | }
|
---|
| 133 | out.ReSize(in);
|
---|
| 134 | // sa_size_t sz[BASEARRAY_MAXNDIMS];
|
---|
| 135 | // for(k=0; k<in.NbDimensions(); k++)
|
---|
| 136 | // sz[k] = in.Size(k);
|
---|
| 137 | // out.ReSize(in.NbDimensions(), sz);
|
---|
[1390] | 138 |
|
---|
| 139 | return(ndg1);
|
---|
[710] | 140 | }
|
---|
| 141 |
|
---|
| 142 | /* --Methode-- */
|
---|
[1390] | 143 | template <class T>
|
---|
| 144 | int FFTArrayChecker<T>::CheckResize(TArray< T > const & in, TArray< complex<T> > & out)
|
---|
[710] | 145 | {
|
---|
[1390] | 146 | int k;
|
---|
[1394] | 147 | string msg;
|
---|
| 148 | if (in.Size() < 1) {
|
---|
| 149 | msg = _msg + "CheckResize(real in, complex out) - Unallocated input array !";
|
---|
| 150 | throw(SzMismatchError(msg));
|
---|
| 151 | }
|
---|
[1390] | 152 | if (_checkpack)
|
---|
[1394] | 153 | if ( !in.IsPacked() ) {
|
---|
| 154 | msg = _msg + "CheckResize(real in, complex out) - Not packed input array !";
|
---|
| 155 | throw(SzMismatchError(msg));
|
---|
| 156 | }
|
---|
[1390] | 157 | int ndg1 = 0;
|
---|
| 158 | for(k=0; k<in.NbDimensions(); k++)
|
---|
| 159 | if (in.Size(k) > 1) ndg1++;
|
---|
| 160 | if (_onedonly)
|
---|
[1394] | 161 | if (ndg1 > 1) {
|
---|
| 162 | msg = _msg + "CheckResize(real in, complex out) - Only 1-D array accepted !";
|
---|
| 163 | throw(SzMismatchError(msg));
|
---|
| 164 | }
|
---|
[1390] | 165 | sa_size_t sz[BASEARRAY_MAXNDIMS];
|
---|
[1400] | 166 | //
|
---|
| 167 | if (ndg1 > 1) {
|
---|
| 168 | sz[0] = in.Size(0)/2+1;
|
---|
| 169 | for(k=1; k<in.NbDimensions(); k++)
|
---|
| 170 | sz[k] = in.Size(k);
|
---|
| 171 | }
|
---|
| 172 | else {
|
---|
| 173 | for(k=0; k<BASEARRAY_MAXNDIMS; k++) sz[k] = 1;
|
---|
| 174 | sz[in.MaxSizeKA()] = in.Size(in.MaxSizeKA())/2+1;
|
---|
| 175 | // sz[k] = in.Size(k)/2+1;
|
---|
| 176 | // sz[k] = (in.Size(k)%2 != 0) ? in.Size(k)/2+1 : in.Size(k)/2;
|
---|
| 177 | }
|
---|
[1390] | 178 | out.ReSize(in.NbDimensions(), sz);
|
---|
| 179 |
|
---|
| 180 | return(ndg1);
|
---|
[710] | 181 | }
|
---|
| 182 |
|
---|
| 183 | /* --Methode-- */
|
---|
[1390] | 184 | template <class T>
|
---|
| 185 | int FFTArrayChecker<T>::CheckResize(TArray< complex<T> > const & in, TArray< T > & out)
|
---|
[710] | 186 | {
|
---|
[1390] | 187 | int k;
|
---|
[1394] | 188 | string msg;
|
---|
| 189 | if (in.Size() < 1) {
|
---|
| 190 | msg = _msg + "CheckResize(complex in, real out) - Unallocated input array !";
|
---|
| 191 | throw(SzMismatchError(msg));
|
---|
| 192 | }
|
---|
[1390] | 193 | if (_checkpack)
|
---|
[1394] | 194 | if ( !in.IsPacked() ) {
|
---|
| 195 | msg = _msg + "CheckResize(complex in, real out) - Not packed input array !";
|
---|
| 196 | throw(SzMismatchError(msg));
|
---|
| 197 | }
|
---|
[1390] | 198 | int ndg1 = 0;
|
---|
| 199 | for(k=0; k<in.NbDimensions(); k++)
|
---|
| 200 | if (in.Size(k) > 1) ndg1++;
|
---|
| 201 | if (_onedonly)
|
---|
[1394] | 202 | if (ndg1 > 1) {
|
---|
| 203 | msg = _msg + "CheckResize(complex in, real out) - Only 1-D array accepted !";
|
---|
| 204 | throw(SzMismatchError(msg));
|
---|
| 205 | }
|
---|
[1390] | 206 | sa_size_t sz[BASEARRAY_MAXNDIMS];
|
---|
[1394] | 207 | if (ndg1 > 1) {
|
---|
[1400] | 208 | sz[0] = 2*in.Size(0)-1;
|
---|
| 209 | for(k=1; k<in.NbDimensions(); k++)
|
---|
| 210 | sz[k] = in.Size(k);
|
---|
| 211 | // sz[k] = in.Size(k)*2-1;
|
---|
[1394] | 212 | }
|
---|
| 213 | else {
|
---|
| 214 | for(k=0; k<BASEARRAY_MAXNDIMS; k++) sz[k] = 1;
|
---|
| 215 | T thr = ZeroThreshold();
|
---|
| 216 | sa_size_t n = in.Size(in.MaxSizeKA());
|
---|
| 217 | sa_size_t ncs = ( (in[n-1].imag() < -thr) || (in[n-1].imag() > thr) ) ?
|
---|
| 218 | ncs = 2*n-1 : ncs = 2*n-2;
|
---|
| 219 | sz[in.MaxSizeKA()] = ncs;
|
---|
| 220 | }
|
---|
| 221 |
|
---|
[1390] | 222 | out.ReSize(in.NbDimensions(), sz);
|
---|
[710] | 223 |
|
---|
[1390] | 224 | return(ndg1);
|
---|
| 225 |
|
---|
[710] | 226 | }
|
---|
| 227 |
|
---|
[1394] | 228 | /* --Methode--
|
---|
[1390] | 229 | template <class T>
|
---|
| 230 | void FFTArrayChecker<T>::ReShapetoReal( TArray< complex<T> > const & in, TArray< T > & out)
|
---|
[710] | 231 | {
|
---|
[1390] | 232 | sa_size_t n = in.Size();
|
---|
| 233 | // int ncs = (fabs(in(n-1).imag()) > 1.e-12) ? ncs = 2*n-1 : ncs = n*2-2;
|
---|
| 234 | sa_size_t ncs = 2*n-1;
|
---|
| 235 | sa_size_t k;
|
---|
| 236 | out[0] = in[0].real();
|
---|
| 237 | for(k=1;k<n-1;k++) {
|
---|
| 238 | out[2*k-1] = in[k].real();
|
---|
| 239 | out[2*k] = in[k].imag();
|
---|
| 240 | }
|
---|
| 241 | // if (ncs == n*2-2) out[ncs-1] = in[n-1].real();
|
---|
| 242 | // else { out[ncs-2] = in[n-1].real(); out[ncs-1] = in[n-1].imag(); }
|
---|
| 243 | out[ncs-2] = in[n-1].real(); out[ncs-1] = in[n-1].imag();
|
---|
[710] | 244 | }
|
---|
[1394] | 245 | */
|
---|
[710] | 246 |
|
---|
[1394] | 247 | /* --Methode--
|
---|
[1390] | 248 | template <class T>
|
---|
| 249 | void FFTArrayChecker<T>::ReShapetoCompl(TArray< T > const & in, TArray< complex<T> > & out)
|
---|
[710] | 250 | {
|
---|
[1390] | 251 | sa_size_t n = in.Size();
|
---|
| 252 | sa_size_t ncs = n/2+1;
|
---|
| 253 | sa_size_t nc = (n%2 != 0) ? n/2+1 : n/2;
|
---|
| 254 | out[0] = complex<T> (in[0],0.);
|
---|
| 255 | for(int k=1;k<nc;k++)
|
---|
| 256 | out[k] = complex<T> (in[2*k-1], in[2*k]);
|
---|
| 257 | if (n%2 == 0) out[ncs-1] = complex<r_8>(in[n-1], 0.);
|
---|
[710] | 258 | }
|
---|
[1394] | 259 | */
|
---|
[710] | 260 |
|
---|
[1390] | 261 | #ifdef __CXX_PRAGMA_TEMPLATES__
|
---|
| 262 | #pragma define_template FFTArrayChecker<r_4>
|
---|
| 263 | #pragma define_template FFTArrayChecker<r_8>
|
---|
| 264 | #endif
|
---|
| 265 |
|
---|
| 266 | #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
|
---|
| 267 | template class FFTArrayChecker<r_4>;
|
---|
| 268 | template class FFTArrayChecker<r_8>;
|
---|
| 269 | #endif
|
---|