00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef USE_INTEL_MATH
00033 #include <mathimf.h>
00034 #else
00035 #include <math.h>
00036 #endif
00037 #include <float.h>
00038
00039 #include "dsp/Hankel.hh"
00040
00041
00042 #define ABEL_NSE 9
00043 const float fpH[ABEL_NSE] = {
00044 1.000000000000000000f,
00045 0.610926299405048390f,
00046 0.895089852938535935f,
00047 1.34082948787002865f,
00048 2.02532848558443890f,
00049 3.18110895533701843f,
00050 5.90898360396353794f,
00051 77.6000213494180286f,
00052 528.221800846070892f
00053 };
00054 const double dpH[ABEL_NSE] = {
00055 1.000000000000000000,
00056 0.610926299405048390,
00057 0.895089852938535935,
00058 1.34082948787002865,
00059 2.02532848558443890,
00060 3.18110895533701843,
00061 5.90898360396353794,
00062 77.6000213494180286,
00063 528.221800846070892
00064 };
00065 const float fpLambda[ABEL_NSE] = {
00066 0.000000000000000000f,
00067 -2.08424632126539366f,
00068 -5.78928630565552371f,
00069 -14.6268676854951032f,
00070 -35.0617158334443104f,
00071 -83.3258406398958158f,
00072 -210.358805421311445f,
00073 -6673.64911325382036f,
00074 -34897.7050244132261f
00075 };
00076 const double dpLambda[ABEL_NSE] = {
00077 0.000000000000000000,
00078 -2.08424632126539366,
00079 -5.78928630565552371,
00080 -14.6268676854951032,
00081 -35.0617158334443104,
00082 -83.3258406398958158,
00083 -210.358805421311445,
00084 -6673.64911325382036,
00085 -34897.7050244132261
00086 };
00087
00088
00089 void clHankel::InitAbel (const float *fpNullPtr)
00090 {
00091 long i, j;
00092 float *a, *b0, *b1, fi, hj, lambdaj, scale, temp;
00093
00094 a = (float *) A.Size(ABEL_NSE * lSize * sizeof(float));
00095 b0 = (float *) B0.Size(ABEL_NSE * lSize * sizeof(float));
00096 b1 = (float *) B1.Size(ABEL_NSE * lSize * sizeof(float));
00097 for (i = 1; i < lSize; ++i)
00098 {
00099 fi = i + 1.0f;
00100 for (j = 0; j < ABEL_NSE; ++j)
00101 {
00102 hj = fpH[j];
00103 lambdaj = fpLambda[j];
00104 a[i * ABEL_NSE + j] = temp =
00105 powf(fi / (fi - 1.0f), lambdaj);
00106 temp *= fi / (fi - 1.0f);
00107 scale = 2.0f * hj * (fi - 1.0f) /
00108 ((lambdaj + 1.0f) * (lambdaj + 2.0f));
00109 b0[i * ABEL_NSE + j] =
00110 scale * (fi - 1.0f + (lambdaj + 2.0f - fi) * temp);
00111 b1[i * ABEL_NSE + j] =
00112 -scale * (lambdaj + 1.0f + fi - fi * temp);
00113 }
00114 }
00115 }
00116
00117
00118 void clHankel::InitAbel (const double *dpNullPtr)
00119 {
00120 long i, j;
00121 double *a, *b0, *b1, fi, hj, lambdaj, scale, temp;
00122
00123 a = (double *) A.Size(ABEL_NSE * lSize * sizeof(double));
00124 b0 = (double *) B0.Size(ABEL_NSE * lSize * sizeof(double));
00125 b1 = (double *) B1.Size(ABEL_NSE * lSize * sizeof(double));
00126 for (i = 1; i < lSize; ++i)
00127 {
00128 fi = i + 1.0;
00129 for (j = 0; j < ABEL_NSE; ++j)
00130 {
00131 hj = fpH[j];
00132 lambdaj = fpLambda[j];
00133 a[i * ABEL_NSE + j] = temp =
00134 pow(fi / (fi - 1.0), lambdaj);
00135 temp *= fi / (fi - 1.0);
00136 scale = 2.0 * hj * (fi - 1.0) /
00137 ((lambdaj + 1.0) * (lambdaj + 2.0));
00138 b0[i * ABEL_NSE + j] =
00139 scale * (fi - 1.0 + (lambdaj + 2.0 - fi) * temp);
00140 b1[i * ABEL_NSE + j] =
00141 -scale * (lambdaj + 1.0 + fi - fi * temp);
00142 }
00143 }
00144 }
00145
00146
00147 void clHankel::DoAbel (float *fpRes, const float *fpSrc)
00148 {
00149 long i, j;
00150 float sum, fi, fip1;
00151 float *a, *b0, *b1, xi[ABEL_NSE];
00152
00153 a = (float *) A.GetPtr();
00154 b0 = (float *) B0.GetPtr();
00155 b1 = (float *) B1.GetPtr();
00156 fi = fpSrc[lSize - 1];
00157 fpRes[0] = 0.5f * fpSrc[0] + fi;
00158 sum = 0.0f;
00159 for (j = 0; j < ABEL_NSE; ++j)
00160 {
00161 xi[j] = b1[(lSize - 1) * ABEL_NSE + j] * fi;
00162 sum += xi[j];
00163 }
00164 fpRes[lSize - 1] = sum;
00165 for (i = lSize - 2; i > 0; --i)
00166 {
00167 fip1 = fi;
00168 fi = fpSrc[i];
00169 fpRes[0] += fi;
00170 sum = 0.0f;
00171 for (j = 0; j < ABEL_NSE; ++j)
00172 {
00173 xi[j] = a[i * ABEL_NSE + j] * xi[j] +
00174 b0[i * ABEL_NSE + j] * fip1 +
00175 b1[i * ABEL_NSE + j] * fi;
00176 sum += xi[j];
00177 }
00178 fpRes[i] = sum;
00179 }
00180 fpRes[0] *= 2.0f;
00181 }
00182
00183
00184 void clHankel::DoAbel (double *dpRes, const double *dpSrc)
00185 {
00186 long i, j;
00187 double sum, fi, fip1;
00188 double *a, *b0, *b1, xi[ABEL_NSE];
00189
00190 a = (double *) A.GetPtr();
00191 b0 = (double *) B0.GetPtr();
00192 b1 = (double *) B1.GetPtr();
00193 fi = dpSrc[lSize - 1];
00194 dpRes[0] = 0.5 * dpSrc[0] + fi;
00195 sum = 0.0;
00196 for (j = 0; j < ABEL_NSE; ++j)
00197 {
00198 xi[j] = b1[(lSize - 1) * ABEL_NSE + j] * fi;
00199 sum += xi[j];
00200 }
00201 dpRes[lSize - 1] = sum;
00202 for (i = lSize - 2; i > 0; --i)
00203 {
00204 fip1 = fi;
00205 fi = dpSrc[i];
00206 dpRes[0] += fi;
00207 sum = 0.0;
00208 for (j = 0; j < ABEL_NSE; ++j)
00209 {
00210 xi[j] = a[i * ABEL_NSE + j] * xi[j] +
00211 b0[i * ABEL_NSE + j] * fip1 +
00212 b1[i * ABEL_NSE + j] * fi;
00213 sum += xi[j];
00214 }
00215 dpRes[i] = sum;
00216 }
00217 dpRes[0] *= 2.0;
00218 }
00219
00220
00221 void clHankel::UninitAbel ()
00222 {
00223 A.Free();
00224 B0.Free();
00225 B1.Free();
00226 }
00227
00228
00229 clHankel::clHankel ()
00230 {
00231 lSize = 0;
00232 }
00233
00234
00235 clHankel::~clHankel ()
00236 {
00237 if (lSize != 0) Uninitialize();
00238 }
00239
00240
00241 void clHankel::Initialize (long lNewSize, const float *fpNullPtr)
00242 {
00243 lSize = lNewSize / 2 + 1;
00244 lFFTSize = lNewSize;
00245 InitAbel(fpNullPtr);
00246 GX.Size(lFFTSize * sizeof(float));
00247
00248 GK.Size(lFFTSize * sizeof(stSCplx));
00249 fOutScale0 = (float) (1.0 / (2.0 * acos(-1.0)));
00250 fOutScale1 = (float) (-1.0 / (2.0 * acos(-1.0)));
00251 DSP.FFTInitialize(lFFTSize, false);
00252 }
00253
00254
00255 void clHankel::Initialize (long lNewSize, const double *dpNullPtr)
00256 {
00257 lSize = lNewSize / 2 + 1;
00258 lFFTSize = lNewSize;
00259 InitAbel(dpNullPtr);
00260 GX.Size(lFFTSize * sizeof(double));
00261
00262 GK.Size(lFFTSize * sizeof(stDCplx));
00263 dOutScale0 = 1.0 / (2.0 * acos(-1.0));
00264 dOutScale1 = -1.0 / (2.0 * acos(-1.0));
00265 DSP.FFTInitialize(lFFTSize, false);
00266 }
00267
00268
00269 void clHankel::Uninitialize ()
00270 {
00271 UninitAbel();
00272 GX.Free();
00273 GK.Free();
00274 lSize = 0;
00275 }
00276
00277
00278 void clHankel::Process0 (float *fpRes, const float *fpSrc)
00279 {
00280 long i;
00281 float fPreScale;
00282 float *gx;
00283
00284 stpSCplx gk;
00285 # ifdef __GNUG__
00286 stSCplx spTemp[lFFTSize];
00287 # else
00288 clDSPAlloc Temp(lFFTSize * sizeof(stSCplx));
00289 stpSCplx spTemp = Temp;
00290 # endif
00291
00292 gx = GX;
00293 gk = GK;
00294 DoAbel(gx, fpSrc);
00295
00296
00297
00298
00299
00300 fPreScale = 2.0f / lSize;
00301 for (i = 0; i < (lFFTSize >> 1); i++)
00302 {
00303 spTemp[i].R = gx[i] * fPreScale;
00304 spTemp[i].I = 0;
00305 }
00306 for (i = (lFFTSize >> 1); i < lFFTSize; i++)
00307 {
00308 spTemp[i].R = gx[lFFTSize - i] * fPreScale;
00309 spTemp[i].I = 0;
00310 }
00311 DSP.IFFTo(gk, spTemp);
00312 for (i = 0; i < lSize; i++)
00313 {
00314 fpRes[i] = sqrt(gk[i].R * gk[i].R + gk[i].I * gk[i].I);
00315 }
00316 }
00317
00318
00319 void clHankel::Process0 (double *dpRes, const double *dpSrc)
00320 {
00321 long i;
00322 double dPreScale;
00323 double *gx;
00324
00325 stpDCplx gk;
00326 # ifdef __GNUG__
00327 stDCplx spTemp[lFFTSize];
00328 # else
00329 clDSPAlloc Temp(lFFTSize * sizeof(stDCplx));
00330 stpDCplx spTemp = Temp;
00331 # endif
00332
00333 gx = GX;
00334 gk = GK;
00335 DoAbel(gx, dpSrc);
00336
00337
00338
00339
00340
00341 dPreScale = 2.0 / lSize;
00342 for (i = 0; i < (lFFTSize >> 1); i++)
00343 {
00344 spTemp[i].R = gx[i] * dPreScale;
00345 spTemp[i].I = 0;
00346 }
00347 for (i = (lFFTSize >> 1); i < lFFTSize; i++)
00348 {
00349 spTemp[i].R = gx[lFFTSize - i] * dPreScale;
00350 spTemp[i].I = 0;
00351 }
00352 DSP.IFFTo(gk, spTemp);
00353 for (i = 0; i < lSize; i++)
00354 {
00355 dpRes[i] = sqrt(gk[i].R * gk[i].R + gk[i].I * gk[i].I);
00356 }
00357 }
00358
00359
00360 void clHankel::Process1 (float *fpRes, const float *fpSrc)
00361 {
00362 long i;
00363 float fPreScale;
00364 float *gx;
00365
00366 stpSCplx gk;
00367 # ifdef __GNUG__
00368 stSCplx spTemp[lFFTSize];
00369 # else
00370 clDSPAlloc Temp(lFFTSize * sizeof(stSCplx));
00371 stpSCplx spTemp = Temp;
00372 # endif
00373
00374 gx = GX;
00375 gk = GK;
00376 for (i = 1; i < lSize; ++i)
00377 gx[i] = fpSrc[i] / i;
00378 DoAbel(gx, gx);
00379 for (i = 0; i < lSize; ++i)
00380 gx[i] *= i;
00381 for (i = lSize; i < lFFTSize; ++i)
00382 gx[i] = -gx[lFFTSize - i];
00383 gx[lFFTSize / 2] = 0.0f;
00384
00385
00386
00387 fPreScale = 2.0f / lSize;
00388 for (i = 0; i < lFFTSize; i++)
00389 {
00390 spTemp[i].R = gx[i] * fPreScale;
00391 spTemp[i].I = 0;
00392 }
00393 DSP.IFFTo(gk, spTemp);
00394 for (i = 0; i < lSize; i++)
00395 {
00396 fpRes[i] = sqrt(gk[i].R * gk[i].R + gk[i].I * gk[i].I);
00397 }
00398 }
00399
00400
00401 void clHankel::Process1 (double *dpRes, const double *dpSrc)
00402 {
00403 long i;
00404 double dPreScale;
00405 double *gx;
00406
00407 stpDCplx gk;
00408 # ifdef __GNUG__
00409 stDCplx spTemp[lFFTSize];
00410 # else
00411 clDSPAlloc Temp(lFFTSize * sizeof(stDCplx));
00412 stpDCplx spTemp = Temp;
00413 # endif
00414
00415 gx = GX;
00416 gk = GK;
00417 for (i = 1; i < lSize; ++i)
00418 gx[i] = dpSrc[i] / i;
00419 DoAbel(gx, gx);
00420 for (i = 0; i < lSize; ++i)
00421 gx[i] *= i;
00422 for (i = lSize; i < lFFTSize; ++i)
00423 gx[i] = -gx[lFFTSize - i];
00424 gx[lFFTSize / 2] = 0.0;
00425
00426
00427
00428 dPreScale = 2.0 / lSize;
00429 for (i = 0; i < lFFTSize; i++)
00430 {
00431 spTemp[i].R = gx[i] * dPreScale;
00432 spTemp[i].I = 0;
00433 }
00434 DSP.IFFTo(gk, spTemp);
00435 for (i = 0; i < lSize; i++)
00436 {
00437 dpRes[i] = sqrt(gk[i].R * gk[i].R + gk[i].I * gk[i].I);
00438 }
00439 }