10 #include <xmmintrin.h>
16 #include "TFFTComplexReal.h"
17 #include "TFFTRealComplex.h"
39 static const
double Pi = 3.14159265358979312;
41 template<class DataType_t>
double*
WDM<DataType_t>::
Cos[
MAXBETA];
42 template<class DataType_t>
double*
WDM<DataType_t>::
Cos2[MAXBETA];
43 template<class DataType_t>
double*
WDM<DataType_t>::
SinCos[MAXBETA];
44 template<class DataType_t>
double WDM<DataType_t>::
CosSize[MAXBETA];
45 template<class DataType_t>
double WDM<DataType_t>::
Cos2Size[MAXBETA];
46 template<class DataType_t>
double WDM<DataType_t>::
SinCosSize[MAXBETA];
47 template<class DataType_t>
int WDM<DataType_t>::objCounter = 0;
50 void FFT(
double*
a,
double* b,
int n)
61 template<
class DataType_t>
67 template<
class DataType_t>
89 template<
class DataType_t>
123 printf(
"iNu too small, reset to 2\n");
127 printf(
"iNu too large, reset to 7\n");
138 double residual = 1 - tmp[0]*tmp[0];
139 double prec = pow(10., -
double(Precision));
142 residual -= 2*tmp[
N]*tmp[
N];
145 }
while(residual>prec || (N-1)%M2 || N/M2<3);
147 printf(
"Filter length = %d, norm = %.16f\n", N, 1.-residual);
157 template<
class DataType_t>
189 int K = m<0 ? M : 2*M-
int(92*M/256.);
194 double residual = 1 - tmp[0]*tmp[0];
197 for(
int i=1;
i<=
M2;
i++) {
199 residual -= 2*tmp[
i]*tmp[
i];
209 filter *= 1./sqrt(1.-residual);
225 this->m_Heterodine = 1;
226 this->m_WaveType =
WDMT;
239 TFMap00 = TFMap90 = 0;
246 for(
int i=0;
i<6; ++
i) {
247 td_halo[
i].Resize(T0[0].Last());
248 td_halo[
i].ZeroExtraElements();
254 template<
class DataType_t>
259 if(--objCounter==0) {
267 if(TFMap00)
delete [] TFMap00;
268 if(TFMap90)
delete [] TFMap90;
269 if(td_buffer)free(td_buffer);
273 template<
class DataType_t>
282 template<
class DataType_t>
294 pwdm->
m_L = this->m_L;
295 pwdm->
m_H = this->m_H;
296 pwdm->
KWDM = this->KWDM;
297 pwdm->
LWDM = this->LWDM;
298 pwdm->
nSTS = this->nSTS;
304 template<
class DataType_t>
313 int N = wdmFilter.size() ;
314 int M = this->m_Layer;
317 if(n%2)
for(
int i=-N+1;
i<
N; ++
i)w[
i] = 0;
319 for(
int i=1;
i<
N; ++
i)w[-
i] = w[
i] = wdmFilter[
i];
324 if( (n-M)%2)
for(
int i=-N+1;
i<
N; ++
i)w[
i] = 0;
326 int s = (M%2) ? -1 : 1 ;
327 w[0] = s*wdmFilter[0];
328 for(
int i=1;
i<
N; ++
i){
330 w[-
i] = w[
i] = s*wdmFilter[
i];
335 double ratio = m*
Pi/
M;
336 double sign = sqrt(2);
341 for(
int i=1;
i<
N; ++
i){
342 w[
i] = - sign*sin(
i*ratio)*wdmFilter[
i];
347 w[0] = sign*wdmFilter[0];
348 for(
int i=1;
i<
N; ++
i)
349 w[
i] = w[-
i] = sign*cos(
i*ratio)*wdmFilter[
i];
355 template<
class DataType_t>
364 int N = wdmFilter.size() ;
365 int M = this->m_Layer;
369 for(
int i=1;
i<
N; ++
i)w[-
i] = w[
i] = wdmFilter[
i];
372 else for(
int i=-N+1;
i<
N; ++
i)w[
i] = 0;
378 for(
int i=1;
i<
N; ++
i){
380 w[-
i] = w[
i] = s*wdmFilter[
i];
383 else for(
int i=-N+1;
i<
N; ++
i)w[
i] = 0;
386 double ratio = m*
Pi/
M;
387 double sign = sqrt(2);
391 w[0] = sign*wdmFilter[0];
392 for(
int i=1;
i<
N; ++
i)
393 w[
i] = w[-
i] = sign*cos(
i*ratio)*wdmFilter[
i];
397 for(
int i=1;
i<
N; ++
i){
398 w[
i] = sign*sin(
i*ratio)*wdmFilter[
i];
407 template<
class DataType_t>
416 int M1 = this->m_Layer+1;
420 int shift = Quad? getBaseWaveQ(m, n, w2) : getBaseWave(m, n, w2);
423 for(
int i=-nn;
i<=nn; ++
i) w[nn+
i] = w2[
i];
428 template<
class DataType_t>
433 int M1 = this->m_Layer+1;
434 int N = this->nWWS/2/
M1;
435 TFMap00 =
new DataType_t*[
N];
436 TFMap90 =
new DataType_t*[
N];
437 for(
int i=0;
i<
N; ++
i){
438 TFMap00[
i] = this->pWWS + M1*
i;
439 TFMap90[
i] = TFMap00[
i] + M1*
N;
444 template<
class DataType_t>
450 int M = this->m_Level;
452 int layer =
int(
fabs(index)+0.001);
455 printf(
"WDM::getSlice(): illegal argument %d. Should be no more than %d\n",layer,M);
459 if(!this->allocate()){
460 std::invalid_argument(
"WDM::getSlice(): data is not allocated");
465 size_t k = N/this->nSTS>1 ? 1 : 0;
467 size_t i = index<0 ? layer+k*N/2 : layer;
471 if(i+(n-1)*s+1 > this->nWWS){
472 std::invalid_argument(
"WaveDWT::getSlice(): invalide arguments");
479 template<
class DataType_t>
488 double* Fourier =
Cos[BetaOrder];
489 int nFourier =
CosSize[BetaOrder];
490 int M = this->m_Layer;
493 double A = (K-
M)*
Pi/2./K/M;
497 double gNorm = sqrt(2*M)/
Pi;
500 double* fourier =
new double[nFourier];
501 for(
int i=0;
i<nFourier; ++
i) fourier[
i] = Fourier[
i];
503 filter[0] = (A + fourier[0]*
B)*gNorm;
504 fNorm = filter[0]*filter[0];
505 fourier[0] /= sqrt(2);
507 for(
int i=1;
i<
n; ++
i){
510 double sumEven = 0, sumOdd = 0;
511 for(
int j=0;
j<nFourier; ++
j){
513 else if(
j==
i/K)
continue;
514 if(
j&1)sumOdd += di/(i2 -
j*
j*K2)*fourier[
j];
515 else sumEven += di/(i2 -
j*
j*K2)*fourier[
j];
520 if(
i/K < nFourier) intAB = fourier[
i/
K]*B/2*cos(
i*A);
522 intAB += 2*(sumEven*sin(
i*B/2)*cos(
i*
Pi/(2*M)) - sumOdd*sin(
i*
Pi/(2*M))*cos(
i*B/2));
523 filter[
i] = gNorm* ( sin(
i*A)/
i + sqrt(2)*intAB );
524 fNorm += 2*filter[
i]*filter[
i];
532 template<
class DataType_t>
539 double* Fourier =
Cos2[BetaOrder];
541 int M = this->m_Layer;
544 double A = (K-
M)*
Pi/2./K/M;
546 double gNorm = 2*M/
Pi;
550 double* fourier =
new double[nFourier];
551 for(
int i=0;
i<nFourier; ++
i) fourier[
i] = Fourier[
i];
553 filter[0] = (A + fourier[0]*
B)*gNorm;
554 fourier[0] /= sqrt(2);
556 for(
int i=1;
i<n*
L; ++
i){
557 double di =
i*(1./
L);
559 double sumEven = 0, sumOdd = 0;
560 for(
int j=0;
j<nFourier; ++
j){
561 if(
j*K*L==
i)
continue;
562 if(
j&1)sumOdd += di/(i2 -
j*
j*K2)*fourier[
j];
563 else sumEven += di/(i2 -
j*
j*K2)*fourier[
j];
567 if(
i%(K*L) == 0)
if(
i/(K*L) < nFourier)
568 intAB = fourier[
i/(K*L)]*B/2*cos(di*A);
569 intAB += 2*(sumEven*sin(di*B/2)*cos(di*
Pi/(2*M)) - sumOdd*sin(di*
Pi/(2*M))*cos(di*B/2));
570 filter[
i] = gNorm* ( sin(di*A)/di + sqrt(2)*intAB );
578 template<
class DataType_t>
586 double* res = tmp.
data;
587 int M = this->m_Layer;
592 double* Fourier =
SinCos[BetaOrder];
596 double aux = Fourier[0];
597 res[0] = aux*B*gNorm;
598 Fourier[0] /= sqrt(2);
599 for(
int i=1;
i<n*
L; ++
i){
600 double di =
i*(1./
L);
603 for(
int j=0;
j<=nFourier;
j+=2){
604 if(
j*K*L==
i)
continue;
605 sum += di/(i2 -
j*
j*K2)*Fourier[
j];
607 sum *= 2*sin(di*B/2);
609 if(
i/(K*L) <= nFourier) {
610 if( (
i/(2*K*L)) & 1 ) sum -= Fourier[
i/K/
L]*B/2;
611 else sum += Fourier[
i/K/
L]*B/2;
613 res[
i] = gNorm*sqrt(2)*sum;
620 template<
class DataType_t>
629 int M = this->m_Layer;
633 for(
int i=0;
i<6; ++
i) {
634 td_halo[
i].Resize(nCoeffs);
635 td_halo[
i].ZeroExtraElements();
641 for(
int i=M*L;
i>=-M*
L; --
i){
642 T0[
i].Resize(nCoeffs);
643 T0[
i][0] = tmp[abs(
i)];
644 for(
int j=1;
j<=nCoeffs; ++
j){
645 T0[
i][
j] = tmp[
i+ M*L*
j];
646 T0[
i][-
j] = tmp[M*L*
j -
i];
648 T0[
i].ZeroExtraElements();
653 for(
int i=M*L;
i>=-M*
L; --
i){
654 Tx[
i].Resize(nCoeffs);
655 Tx[
i][0] = tmp[abs(
i)]/2.;
656 for(
int j=1;
j<=nCoeffs; ++
j){
657 Tx[
i][
j] = tmp[
i+ M*L*
j]/2.;
658 Tx[
i][-
j] = tmp[M*L*
j -
i]/2.;
662 for(
int j=1;
j<=nCoeffs; ++
j)
switch(
j%4){
663 case 1: Tx[
i][-
j] *= -1;
break;
664 case 2: Tx[
i][
j] *= -1; Tx[
i][-
j] *= -1;
break;
665 case 3: Tx[
i][
j] *= -1;
667 Tx[
i].ZeroExtraElements();
674 for(
int i=0;
i<2*L*
M; ++
i){
675 sinTD[
i] = sin(
i*
Pi/(L*M));
676 cosTD[
i] = cos(
i*
Pi/(L*M));
678 sinTDx.resize(4*L*M);
679 for(
int i=0;
i<4*L*
M; ++
i)sinTDx[
i] = sin(
i*
Pi/(2*L*M));
682 template<
class DataType_t>
687 if(td_buffer)free(td_buffer);
688 switch(T0[0].SSESize()){
689 case 64: SSE_TDF =
sse_dp4; posix_memalign((
void**)&td_buffer, 16, 64+16);
break;
690 case 80: SSE_TDF =
sse_dp5; posix_memalign((
void**)&td_buffer, 16, 80+16);
break;
691 case 96: SSE_TDF =
sse_dp6; posix_memalign((
void**)&td_buffer, 16, 96+16);
break;
692 case 112: SSE_TDF =
sse_dp7; posix_memalign((
void**)&td_buffer, 16, 112+16);
break;
693 case 128: SSE_TDF =
sse_dp8; posix_memalign((
void**)&td_buffer, 16, 128+16);
break;
694 case 144: SSE_TDF =
sse_dp9; posix_memalign((
void**)&td_buffer, 16, 144+16);
break;
695 case 160: SSE_TDF =
sse_dp10; posix_memalign((
void**)&td_buffer, 16, 160+16);
break;
696 case 176: SSE_TDF =
sse_dp11; posix_memalign((
void**)&td_buffer, 16, 176+16);
break;
697 default:
printf(
"initSSEPointer error, size not found. Contact V.Necula\n"); SSE_TDF=0;
699 td_data = td_buffer + T0[0].SSESize()/8 + 4;
729 template<
class DataType_t>
740 int M = this->m_Layer;
743 bool cancelEven = odd ^ Quad;
744 double dt = dT*(1./this->LWDM);
745 if(m==0 || m==M)
if(cancelEven)
return 0;
746 DataType_t* TFMap = this->pWWS;
747 if(Quad) TFMap += this->nWWS/2;
750 DataType_t* tfc = TFMap + n*M1 +
m;
756 double sumEven = tfc[0]*sa[0];
757 for(
int i=2;
i<=sa.Last();
i+=2) sumEven += (tfc[
i*M1]*sa[
i] +tfc[-
i*M1]*sa[-
i]);
758 for(
int i=1;
i<=sa.Last();
i+=2) sumOdd += (tfc[
i*M1]*sa[
i] +tfc[-
i*M1]*sa[-
i]);
760 if(cancelEven)sumEven = 0;
765 if(odd) res = sumEven*cos((m*
Pi*dt)/M) - sumOdd*sin((m*
Pi*dt)/M);
766 else res = sumEven*cos((m*
Pi*dt)/M) + sumOdd*sin((m*
Pi*dt)/M);
774 sumEven = tfc[0]*sax[0];
775 for(
int i=2;
i<=sax.Last();
i+=2) sumEven += (tfc[
i*M1]*sax[
i] +tfc[-
i*M1]*sax[-
i]);
776 for(
int i=1;
i<=sax.Last();
i+=2) sumOdd += (tfc[
i*M1]*sax[
i] + tfc[-
i*M1]*sax[-
i]);
779 if(cancelEven)sumEven = 0;
783 if(odd) res1 = (sumEven - sumOdd)*sin((2*m-1)*dt*
Pi/(2.*
M));
784 else res1 = (sumEven + sumOdd)*sin((2*m-1)*dt*
Pi/(2.*
M));
785 if(m==1 || m == M) res1 *= sqrt(2);
786 if((m+n)&1) res -= res1;
792 tfc = TFMap + n*M1 + m + 1;
794 sumEven = tfc[0]*sax[0];
795 for(
int i=2;
i<=sax.Last();
i+=2) sumEven += (tfc[
i*M1]*sax[
i] + tfc[-
i*M1]*sax[-
i]);
796 for(
int i=1;
i<=sax.Last();
i+=2) sumOdd += (tfc[
i*M1]*sax[
i] + tfc[-
i*M1]*sax[-
i]);
799 if(cancelEven)sumEven = 0;
803 if(odd) res1 = (sumEven + sumOdd)*sin((2*m+1)*dt*
Pi/(2.*
M));
804 else res1 = (sumEven - sumOdd)*sin((2*m+1)*dt*
Pi/(2.*
M));
805 if(m==0 || m==M-1) res1 *= sqrt(2);
806 if((m+n)&1) res -= res1;
814 template<
class DataType_t>
825 static const double sqrt2 = sqrt(2);
826 int M = this->m_Layer;
830 bool cancelEven = odd ^ Quad;
832 if(m==0 || m==M)
if(cancelEven)
return 0;
833 DataType_t* TFMap = this->pWWS;
834 if(Quad) TFMap += this->nWWS/2;
835 DataType_t* tfc = TFMap + n*M1 +
m;
843 const int last = sa.
Last();
844 for(
int i=-last,
j = -last*M1;
i<=last; ++
i){td_data[
i] = tfc[
j] ;
j+=
M1;}
848 float sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
851 if(cancelEven)sumEven = 0;
857 if(index<0) index +=2*M*
L;
859 if(odd) res = sumEven*cosTD[
index] - sumOdd*sinTD[
index];
860 else res = sumEven*cosTD[
index] + sumOdd*sinTD[
index];
867 for(
int i=-last,
j = -last*M1;
i<=last; ++
i){td_data[
i] = tfc[
j] ;
j+=
M1;}
869 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
870 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
873 if(cancelEven)sumEven = 0;
877 index = (2*m-1)*dT%(4*M*L);
878 if(index<0)index += 4*M*
L;
879 if(odd) res1 = (sumEven - sumOdd)*sinTDx[index];
880 else res1 = (sumEven + sumOdd)*sinTDx[index];
882 if(m==1 || m == M) res1 *= sqrt2;
883 if((m+n)&1) res -= res1;
888 tfc = TFMap + n*M1 + m + 1;
889 for(
int i=-last,
j = -last*M1;
i<=last; ++
i){td_data[
i] = tfc[
j] ;
j+=
M1;}
892 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
893 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
896 if(cancelEven)sumEven = 0;
899 index = (2*m+1)*dT%(4*M*L);
900 if(index<0)index += 4*M*
L;
901 if(odd) res1 = (sumEven + sumOdd)*sinTDx[index];
902 else res1 = (sumEven - sumOdd)*sinTDx[index];
903 if(m==0 || m==M-1) res1 *= sqrt2;
904 if((m+n)&1) res -= res1;
910 template<
class DataType_t>
920 static const double sqrt2 = sqrt(2);
921 int M = this->m_Layer;
924 bool cancelEven = odd ^ Quad;
925 if(m==0 || m==M)
if(cancelEven)
return 0;
927 int QuadShift = Quad? 3:0;
935 float sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
938 if(cancelEven)sumEven = 0;
943 if(index<0) index +=2*M*
L;
944 if(odd) res = sumEven*cosTD[
index] - sumOdd*sinTD[
index];
945 else res = sumEven*cosTD[
index] + sumOdd*sinTD[
index];
953 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
954 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
957 if(cancelEven)sumEven = 0;
961 index = (2*m-1)*dT%(4*M*L);
962 if(index<0)index += 4*M*
L;
963 if(odd) res1 = (sumEven - sumOdd)*sinTDx[index];
964 else res1 = (sumEven + sumOdd)*sinTDx[index];
966 if(m==1 || m == M) res1 *= sqrt2;
967 if((m+n)&1) res -= res1;
974 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
975 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
978 if(cancelEven)sumEven = 0;
981 index = (2*m+1)*dT%(4*M*L);
982 if(index<0)index += 4*M*
L;
984 if(odd) res1 = (sumEven + sumOdd)*sinTDx[index];
985 else res1 = (sumEven - sumOdd)*sinTDx[index];
986 if(m==0 || m==M-1) res1 *= sqrt2;
987 if((m+n)&1) res -= res1;
993 template<
class DataType_t>
1003 static const double sqrt2 = sqrt(2);
1004 int M = this->m_Layer;
1007 bool cancelEven = odd ^ Quad;
1008 if(m==0 || m==M)
if(cancelEven){
1009 for(
int dT = t1 ;
dT<=t2; ++
dT)*r++ = 0;
1014 int QuadShift = Quad? 3:0;
1018 for(
int dT = t1 ;
dT<=t2; ++
dT){
1020 watasm_data = td_halo[QuadShift + 1].SSEPointer();
1024 float sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
1027 if(cancelEven)sumEven = 0;
1032 if(index<0) index +=_2ml;
1033 if(odd) res = sumEven*cosTD[
index] - sumOdd*sinTD[
index];
1034 else res = sumEven*cosTD[
index] + sumOdd*sinTD[
index];
1040 watasm_data = td_halo[QuadShift + 0].SSEPointer();
1042 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
1043 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
1046 if(cancelEven)sumEven = 0;
1050 index = (2*m-1)*
dT%_4ml;
1051 if(index<0)index += _4ml;
1052 if(odd) res1 = (sumEven - sumOdd)*sinTDx[index];
1053 else res1 = (sumEven + sumOdd)*sinTDx[index];
1055 if(m==1 || m == M) res1 *= sqrt2;
1056 if((m+n)&1) res -= res1;
1061 watasm_data = td_halo[QuadShift + 2].SSEPointer();
1063 sumEven = watasm_xmm0[0] + watasm_xmm0[2];
1064 sumOdd = watasm_xmm0[1] + watasm_xmm0[3];
1067 if(cancelEven)sumEven = 0;
1071 index = (2*m+1)*
dT%_4ml;
1072 if(index<0)index += _4ml;
1073 if(odd) res1 = (sumEven + sumOdd)*sinTDx[index];
1074 else res1 = (sumEven - sumOdd)*sinTDx[index];
1075 if(m==0 || m==M-1) res1 *= sqrt2;
1076 if((m+n)&1) res -= res1;
1084 template<
class DataType_t>
1093 int N = (
int)this->nWWS/2;
1094 if(this->nWWS/this->nSTS!=2) {
1095 printf(
"WDM:getTDamp() - time delays can not be produced with this TF data.");
1099 printf(
"WDM:getTDamp() - time delay filter is not set");
1104 int M = this->m_Layer;
1111 if(n<0 || n>N/(M+1)) {
1112 cout<<
"WDM::getTDamp(): index outside TF map"<<endl;
exit(1);
1118 if((n+m)%2)
return -getPixelAmplitude(m, n-wdmShift, k,
true);
1119 else return getPixelAmplitude(m, n-wdmShift, k,
true);
1121 return getPixelAmplitude(m, n-wdmShift, k,
false);
1126 if((n+m)%2)
return getPixelAmplitude(m, n-wdmShift, k,
false);
1127 else return -getPixelAmplitude(m, n-wdmShift, k,
false);
1129 return getPixelAmplitude(m, n-wdmShift, k,
true);
1132 double a00 = getPixelAmplitude(m, n-wdmShift, k,
false);
1133 double a90 = getPixelAmplitude(m, n-wdmShift, k,
true);
1134 return float(a00*a00+a90*a90)/2;
1140 template<
class DataType_t>
1152 if(this->nWWS/this->nSTS!=2) {
1153 printf(
"WDM:getTDAmp() - time delays can not be produced with this TF data.");
1157 printf(
"WDM:getTDAmp() - time delay filter is not set");
1160 if(j>=(
int)this->nWWS/2) j -= this->nWWS/2;
1162 int mode = (c==
'a' || c==
'A') ? 2 : 1;
1165 float* p00 = amp.
data;
1166 float* p90 = amp.
data + (mode-1)*(2*K+1);
1169 for(
int k=-K;
k<=
K;
k++) {
1171 p00[
i] = float(getTDamp(j,
k,
'a'));
1172 p90[
i] = float(getTDamp(j,
k,
'A'));
1174 else p00[
i] = getTDamp(j,
k,
'p');
1182 template<
class DataType_t>
1194 printf(
"WDM:getTDAmp() - time delay filter is not set");
1198 int M = this->m_Layer;
1203 int max_wdmShift = ((K + J)/(2*J))*2;
1204 int max_k = (K + J)%(2*J) - J;
1205 int min_wdmShift = (-K + J)/(2*J);
1206 int min_k = (-K + J)%(2*J);
1217 int mode = (c==
'a' || c==
'A') ? 2 : 1;
1220 if(mode==1) aux.
resize(2*K+1);
1222 float* p00 = amp.
data;
1223 float* p90 = aux.
data;
1224 if(mode==2) p90 = amp.
data + (mode-1)*(2*K+1);
1226 if(min_wdmShift==max_wdmShift){
1228 getPixelAmplitudeSSE(m, n, min_k, max_k, p00,
false);
1229 getPixelAmplitudeSSE(m, n, min_k, max_k, p90,
true);
1232 pSS->
GetSTFdata(j - min_wdmShift*(M+1), td_halo);
1233 getPixelAmplitudeSSE(m, n-min_wdmShift, min_k, J-1, p00,
false);
1234 getPixelAmplitudeSSE(m, n-min_wdmShift, min_k, J-1, p90,
true);
1238 for(
int i=min_wdmShift+2;
i<max_wdmShift;
i+=2){
1240 getPixelAmplitudeSSE(m, n-
i, -J, J-1, p00,
false);
1241 getPixelAmplitudeSSE(m, n-
i, -J, J-1, p90,
true);
1245 pSS->
GetSTFdata(j - max_wdmShift*(M+1), td_halo);
1246 getPixelAmplitudeSSE(m, n-max_wdmShift, -J, max_k, p00,
false);
1247 getPixelAmplitudeSSE(m, n-max_wdmShift, -J, max_k, p90,
true);
1253 for(
int i=0;
i<=2*K+1; ++
i)p00[
i] = (p00[
i]*p00[
i] + p90[
i]*p90[
i])/2;
1258 template<
class DataType_t>
1264 if(this->nWWS/this->nSTS!=2) {
1265 printf(
"WDM:getTDAmp() - time delays can not be produced with this TF data.");
1269 printf(
"WDM:getTDAmp() - time delay filter is not set");
1272 DataType_t* TFMap = this->pWWS;
1273 if(j>=(
int)this->nWWS/2) j -= this->nWWS/2;
1275 int M = this->m_Layer;
1278 int BlockSize = T0[0].SSESize()/4;
1280 float* data = r.
data;
1281 data += BlockSize/2;
1282 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1285 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1288 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1290 j+= this->nWWS/2 - 1;
1292 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1295 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1298 for(
int i=-L;
i<=
L; ++
i)data[
i] = TFMap[j +
i*M1];
1302 template<
class DataType_t>
1307 int M = this->m_Layer;
1308 int N = this->nWWS/2/(M+1);
1309 int nCoeff = T0[0].Last();
1310 for(
int k=0;
k<100; ++
k)
1311 for(
int i=nCoeff;
i<N-nCoeff; ++
i)
1312 for(
int j=0;
j<=
M; ++
j) res += getPixelAmplitude(
j,
i, dt);
1317 template<
class DataType_t>
1323 int M = this->m_Layer;
1324 int N = this->nWWS/2/(M+1);
1325 int nCoeff = T0[0].Last();
1326 for(
int k=0;
k<100; ++
k)
1327 for(
int i=nCoeff;
i<N-nCoeff; ++
i)
1328 for(
int j=0;
j<=
M; ++
j) res += getPixelAmplitudeSSEOld(
j,
i, dt);
1333 template<
class DataType_t>
1338 return this->m_Level;
1341 template<
class DataType_t>
1349 template<
class DataType_t>
1354 printf(
"ERROR, WDM::forward called\n");
1357 template<
class DataType_t>
1362 printf(
"ERROR, WDM::inverse called\n");
1366 template<
class DataType_t>
1373 static const double sqrt2 = sqrt(2);
1376 int M = this->m_Layer;
1379 int nWDM = this->m_H;
1380 int nTS = this->nWWS;
1386 this->nWWS += this->nWWS%MM ? MM-this->nWWS%MM : 0;
1389 m = this->nWWS+2*nWDM;
1390 double*
ts = (
double*) _mm_malloc(m*
sizeof(
double), 16);
1391 for(n=0; n<=nWDM; n++) ts[nWDM-n] = (
double)(this->pWWS[
n]);
1392 for(n=0; n < nTS; n++) ts[nWDM+n] = (
double)(this->pWWS[
n]);
1393 for(n=0; n<
int(m - nWDM-nTS); n++) ts[n+nWDM+nTS] = (
double)(this->pWWS[nTS-n-1]);
1395 double* pTS = ts + nWDM;
1399 double*
wdm = (
double*) _mm_malloc((nWDM)*
sizeof(double),16);
1400 double* INV = (
double*) _mm_malloc((nWDM)*
sizeof(double),16);
1401 for(n=0; n<nWDM; n++) {
1402 wdm[
n] = wdmFilter.data[
n];
1403 INV[
n] = wdmFilter.data[nWDM-n-1];
1405 double*
WDM = INV+nWDM-1;
1408 int N =
int(this->nWWS/MM);
1409 int L = KK<0 ? 2*N*M1 : N*
M1;
1410 this->m_L = KK<0 ? this->m_H : 0;
1411 DataType_t*
pWDM = (DataType_t *)realloc(this->pWWS,L*
sizeof(DataType_t));
1413 this->allocate(
size_t(L), pWDM);
1415 double* re =
new double[
M2];
1416 double* im =
new double[
M2];
1418 double* reX = (
double*) _mm_malloc(M2 *
sizeof(
double), 16);
1419 double* imX = (
double*) _mm_malloc(M2 *
sizeof(
double), 16);
1421 DataType_t* map00 =
pWDM;
1422 DataType_t* map90 = pWDM + N*
M1;
1425 int sign,kind; sign=0;
1426 TFFTRealComplex fft(1,&M2,
false);
1427 fft.Init(
"ES",sign, &kind);
1441 for(m=0; m<
M2; m++) {reX[
m] = 0; imX[
m] = 0.;}
1443 for(j=0; j<nWDM-1; j+=
M2) {
1446 __m128d* PR = (__m128d*) reX;
1447 for(m=0; m<
M2; m+=2) {
1448 __m128d ptj = _mm_loadu_pd(pTS+j+m);
1449 __m128d pTJ = _mm_loadu_pd(pTS-J+m);
1450 __m128d pwj = _mm_load_pd(wdm+j+m);
1451 __m128d pWJ = _mm_load_pd(WDM-J+m);
1452 __m128d pjj = _mm_mul_pd(ptj,pwj);
1453 __m128d pJJ = _mm_mul_pd(pTJ,pWJ);
1454 *PR = _mm_add_pd(*PR, _mm_add_pd(pjj,pJJ));
1460 reX[0] += wdm[J]*pTS[J];
1465 fft.GetPointsComplex(reX, imX);
1476 reX[0] = imX[0] = reX[0]/sqrt2;
1477 reX[
M] = imX[
M] = reX[
M]/sqrt2;
1482 for(
int m=0; m<=
M; ++
m) {
1484 map00[
m] = sqrt2*imX[
m];
1485 map90[
m] = sqrt2*reX[
m];
1488 map00[
m] = sqrt2*reX[
m];
1489 map90[
m] = -sqrt2*imX[
m];
1495 for(
int m=0; m<=
M; m++)
1496 map00[m] = reX[m]*reX[m]+imX[m]*imX[m];
1505 this->m_Level = this->m_Layer;
1520 template<
class DataType_t>
1531 int M = this->m_Layer;
1533 int N = this->nWWS/(M2+2);
1534 int nWDM = this->m_H;
1535 int nTS = M*N + 2*nWDM;
1537 double sqrt2 = sqrt(2.);
1538 double* reX =
new double[
M2];
1539 double* imX =
new double[
M2];
1540 double*
wdm = wdmFilter.data;
1541 DataType_t* TFmap = this->pWWS;
1543 if(M*N/this->nSTS!=1) {
1544 printf(
"WDM<DataType_t>::w2t: Inverse is not defined for the up-sampled map\n");
1549 DataType_t*
tmp = ts.
data + nWDM;
1552 int sign,kind; sign=0;
1553 TFFTComplexReal ifft(1,&M2,
false);
1554 ifft.Init(
"ES",sign, &kind);
1559 for(j = 0; j<
M2; ++
j) reX[j] = imX[j] = 0;
1561 if( (n+j) & 1 ) imX[
j] = TFmap[
j]/sqrt2;
1562 else if(j&1) reX[
j] = - TFmap[
j]/sqrt2;
1563 else reX[
j] = TFmap[
j]/sqrt2;
1573 if( (n & 1) == 0 )reX[0] = TFmap[0];
1574 if( ((n+M) & 1) == 0 )
1575 if(M&1) reX[
M] = -TFmap[
M];
1576 else reX[
M] = TFmap[
M];
1578 ifft.SetPointsComplex(reX,imX);
1580 ifft.GetPoints(reX);
1583 DataType_t*
x = tmp + n*
M;
1587 x[0] += wdm[0]*reX[
m];
1588 for(j = 1; j<nWDM; ++
j){
1591 x[
j] += wdm[
j]*reX[
m];
1592 if(mm==0)mm = 2*M - 1;
1594 x[-
j] += wdm[
j]*reX[mm];
1599 DataType_t* pTS = (DataType_t *)realloc(this->pWWS,this->nSTS*
sizeof(DataType_t));
1601 this->allocate(
size_t(this->nSTS), pTS);
1602 for(n=0; n<
int(this->nSTS); n++) pTS[n] = tmp[n];
1612 template<
class DataType_t>
1618 int M = this->m_Layer;
1621 int N = this->nWWS/(M2+2);
1622 int nWDM = this->m_H;
1623 int nTS = M*N + 2*nWDM;
1625 double sqrt2 = sqrt(2.);
1626 double* reX =
new double[
M2];
1627 double* imX =
new double[
M2];
1628 double*
wdm = wdmFilter.data;
1631 DataType_t* map90 = this->pWWS + N*
M1;
1633 if(M*N/this->nSTS!=1) {
1634 printf(
"WDM<DataType_t>::w2tQ: Inverse is not defined for the up-sampled map\n");
1639 DataType_t*
tmp = ts.
data + nWDM;
1642 int sign,kind; sign=0;
1643 TFFTComplexReal ifft(1,&M2,
false);
1644 ifft.Init(
"ES",sign, &kind);
1649 for(j = 0; j<
M2; ++
j) reX[j] = imX[j] = 0;
1651 if( (n+j) & 1 ) reX[
j] = map90[
j]/sqrt2;
1652 else if(j&1) imX[
j] = map90[
j]/sqrt2;
1653 else imX[
j] = -map90[
j]/sqrt2;
1662 if((n+M) & 1)reX[
M] = map90[
M];
1663 if(n & 1)reX[0] = map90[0];
1665 ifft.SetPointsComplex(reX,imX);
1667 ifft.GetPoints(reX);
1670 DataType_t*
x = tmp + n*
M;
1674 x[0] += wdm[0]*reX[
m];
1675 for(j = 1; j<nWDM; ++
j){
1678 x[
j] += wdm[
j]*reX[
m];
1679 if(mm==0)mm = 2*M - 1;
1681 x[-
j] += wdm[
j]*reX[mm];
1687 DataType_t* pTS = (DataType_t *)realloc(this->pWWS,this->nSTS*
sizeof(DataType_t));
1689 this->allocate(
size_t(this->nSTS), pTS);
1690 for(n=0; n<
int(this->nSTS); n++) pTS[n] = tmp[n];
1699 #define CLASS_INSTANTIATION(class_) template class WDM< class_ >;
1704 #undef CLASS_INSTANTIATION
int getBaseWave(int m, int n, SymmArray< double > &w)
printf("total live time: non-zero lags = %10.1f \n", liveTot)
wavearray< float > getTDvecSSE(int j, int K, char c, SSeries< double > *pss)
wavearray< double > a(hp.size())
cout<< endl;cout<< "ts size = "<< ts.size()<< " ts rate = "<< ts.rate()<< endl;tf.Forward(ts, wdm);int levels=tf.getLevel();cout<< "tf size = "<< tf.size()<< endl;double dF=tf.resolution();double dT=1./(2 *dF);cout<< "rate(hz) : "<< RATE<< "\t layers : "<< nLAYERS<< "\t dF(hz) : "<< dF<< "\t dT(ms) : "<< dT *1000.<< endl;int itime=TIME_PIXEL_INDEX;int ifreq=FREQ_PIXEL_INDEX;int index=(levels+1)*itime+ifreq;double time=itime *dT;double freq=(ifreq >0)?ifreq *dF:dF/4;cout<< endl;cout<< "PIXEL TIME = "<< time<< " sec "<< endl;cout<< "PIXEL FREQ = "<< freq<< " Hz "<< endl;cout<< endl;wavearray< double > x
WDM< double > wdm(nLAYERS, nLAYERS, 6, 10)
virtual WDM * Clone() const
return: Wavelet* - duplicate of *this, allocated on heap
void setTDFilter(int nCoeffs, int L=1)
SymmObjArray< SymmArraySSE< float > > Tx
double getPixelAmplitude(int, int, int, bool=false)
void getTFvec(int j, wavearray< float > &r)
wavearray< float > sinTDx
#define CLASS_INSTANTIATION(class_)
wavearray< float > getTDvec(int j, int K, char c='p')
double getPixelAmplitudeSSEOld(int, int, int, bool=false)
void wavefft(double a[], double b[], int ntot, int n, int nspan, int isn)
int getBaseWaveQ(int m, int n, SymmArray< double > &w)
bool GetSTFdata(int index, SymmArraySSE< float > *pS)
void FFT(double *a, double *b, int n)
wavearray< double > getFilter(int n)
wavearray< double > getTDFilter2(int n, int L)
DataType_t ** TFMap90
pointer to 0-phase data, by default not initialized
void InvFFT(double *a, double *b, int n)
float getPixelAmplitudeSSE(int m, int n, int dT, bool Quad)
double TimeShiftTest(int dt)
float getTDamp(int n, int m, char c='p')
wavearray< double > ts(N)
wavearray< double > wdmFilter
double fabs(const Complex &x)
virtual WDM * Init() const
std::slice getSlice(double n)
wavearray< double > getTDFilter1(int n, int L)
double TimeShiftTestSSE(int dt)
virtual void resize(unsigned int)
SymmObjArray< SymmArraySSE< float > > T0
void cpf(const wavearray< DataType_t > &, int=0, int=0, int=0)