double WbGammaTone(double x,double tdres,double centerfreq, int n, double tau,double gain,int order) { static double wbphase; static COMPLEX wbgtf[4], wbgtfl[4]; double delta_phase,dtmp,c1LP,c2LP,out; int i,j; if (n==0) { wbphase = 0; for(i=0; i<=order;i++) { wbgtfl[i] = compmult(0,compexp(0)); wbgtf[i] = compmult(0,compexp(0)); } } delta_phase = -TWOPI*centerfreq*tdres; wbphase += delta_phase; dtmp = tau*2.0/tdres; c1LP = (dtmp-1)/(dtmp+1); c2LP = 1.0/(dtmp+1); wbgtf[0] = compmult(x,compexp(wbphase)); /* FREQUENCY SHIFT */ for(j = 1; j <= order; j++) /* IIR Bilinear transformation LPF */ wbgtf[j] = comp2sum(compmult(c2LP*gain,comp2sum(wbgtf[j-1],wbgtfl[j-1])), compmult(c1LP,wbgtfl[j])); out = REAL(compprod(compexp(-wbphase), wbgtf[order])); /* FREQ SHIFT BACK UP */ for(i=0; i<=order;i++) wbgtfl[i] = wbgtf[i]; return(out); }
/** Pass the signal through the gammatone filter\\ 1. shift the signal by centeral frequency of the gamma tone filter\\ 2. low pass the shifted signal \\ 3. shift back the signal \\ 4. take the real part of the signal as output @author Xuedong Zhang */ double TGammaTone::run(double x) { x = gain*x; phase += delta_phase; gtf[0] = compmult(x,compexp(phase)); // FREQUENCY SHIFT for(int j = 1; j <= gtf_order; j++) // IIR Bilinear transformation LPF gtf[j] = comp2sum(compmult(c2LP,comp2sum(gtf[j-1],gtfl[j-1])), compmult(c1LP,gtfl[j])); double out = REAL(compprod(compexp(-phase), gtf[gtf_order])); // FREQ SHIFT BACK UP for(int i=0; i<=gtf_order;i++) gtfl[i] = gtf[i]; return(out); };
int main() { struct complex z1, z2; struct complex compexp(struct complex); z1.r = 0.0; z1.i = 0.0; scanf("%lf %lf", &z1.r, &z1.i); z2 = compexp(z1); printf("[%f, %f] exp:[%f, %f]\n", z1.r, z1.i, z2.r, z2.i); }
void CReflCalc::MyRFNoOpt(double* sintheta, double* sinsquaredtheta, int datapoints, double* refl, CEDP* EDP) { MyComplex* DEDP = EDP->m_DEDP; int EDPoints = EDP->Get_EDPPointCount(); if(m_bReflInitialized == FALSE) { InitializeScratchArrays(EDP->Get_EDPPointCount()); } //Calculate some complex constants to keep them out of the loop MyComplex lengthmultiplier = -2.0*MyComplex (0.0,1.0)*EDP->Get_Dz() ; MyComplex indexsup = 1.0 - DEDP[0]/2.0; MyComplex indexsupsquared = indexsup * indexsup; MyComplex zero; #pragma omp parallel { //Figure out the number of the thread we're currently in int threadnum = omp_get_thread_num(); int arrayoffset = threadnum*EDPoints; MyComplex * kk = m_ckk+arrayoffset; MyComplex * ak = m_cak+arrayoffset; MyComplex * rj= m_crj+arrayoffset; MyComplex * Rj= m_cRj+arrayoffset; MyComplex cholder; double holder; /********Boundary conditions********/ //No reflection in the last layer Rj[EDPoints-1] = 0.0f; //The first layer and the last layer are assumed to be infinite e^-(0+i*(layerlength)) = 1+e^(-inf*i*beta) = 1 + 0*i*beta ak[EDPoints-1] = 1.0f; ak[0] = 1.0f; //In order to vectorize loops, you cannot use global variables int nlminone = EDPoints-1; int numlay = EDPoints; #pragma omp for schedule(runtime) for(int l = 0; l < datapoints;l++) { //The refractive index for air is 1, so there is no refractive index term for kk[0] kk[0] = k0 * indexsup * sintheta[l]; //Workout the wavevector k -> kk[i] = k0 *compsqrt(sinsquaredthetai[l]-2.0*nk[i]); #pragma ivdep for(int i = 1; i < numlay;i++) { kk[i] = k0 * compsqrt(indexsupsquared*sinsquaredtheta[l]-DEDP[i]+DEDP[0]); } //Make the phase factors ak -> ak[i] = compexp(-1.0*imaginary*kk[i]*dz0/2.0); #pragma ivdep for(int i = 1; i < numlay-1;i++) { ak[i] = compexp(lengthmultiplier*kk[i]); } //Make the Fresnel coefficients -> rj[i] =(kk[i]-kk[i+1])/(kk[i]+kk[i+1]); #pragma ivdep for(int i = 0; i < numlay-1;i++) { rj[i] =(kk[i]-kk[i+1])/(kk[i]+kk[i+1]); } //Parratt recursion of the amplitude reflectivity for(int i = numlay-2; i >= 0 ;i--) { Rj[i] = ak[i]*(Rj[i+1]+rj[i])/(Rj[i+1]*rj[i]+1.0); } //The magnitude of the reflection at layer 0 is the measured reflectivity of the film holder = compabs(Rj[0]); refl[l] = holder*holder; } } }
void CReflCalc::MyTransparentRF(double* sintheta, double* sinsquaredtheta, int datapoints,double* refl, CEDP* EDP) { MyComplex* DEDP = EDP->m_DEDP; int EDPoints = EDP->Get_EDPPointCount(); if(m_bReflInitialized == FALSE) { InitializeScratchArrays(EDP->Get_EDPPointCount()); } ////Calculate some complex constants to keep them out of the loop MyComplex lengthmultiplier = -2.0f*MyComplex (0.0f,1.0f)*EDP->Get_Dz(); MyComplex indexsup = 1.0 - DEDP[0]/2.0; MyComplex indexsupsquared = indexsup * indexsup; int HighOffSet = EDPoints; int LowOffset = 0; int offset = datapoints; //GetOffSets(HighOffSet, LowOffset, DEDP, EDPoints); //Find the point at which we no longer need to use complex numbers exclusively for(int i = 0; i< datapoints;i++) { int neg = 0; for(int k = 0; k<EDPoints;k++) { if((indexsupsquared.re*sinsquaredtheta[i]-DEDP[k].re+DEDP[0].re/2.0f)< 0.0f) { neg -= 1; break; } } if(neg == 0) { offset = i; break; } } //offset = 128; //In order to vectorize loops, you cannot use global variables int EDPointsMinOne = EDPoints-1; #pragma omp parallel { //Figure out the number of the thread we're currently in int threadnum = omp_get_thread_num(); int arrayoffset = threadnum*EDPoints; double* dkk = m_dkk+arrayoffset; MyComplex * kk = m_ckk+arrayoffset; MyComplex * ak = m_cak+arrayoffset; double* drj = m_drj+arrayoffset; MyComplex * rj= m_crj+arrayoffset; MyComplex * Rj= m_cRj+arrayoffset; MyComplex cholder, tempk1, tempk2, zero; double holder, dtempk1, dtempk2; /********Boundary conditions********/ //No reflection in the last layer Rj[EDPointsMinOne] = 0.0f; //The first layer and the last layer are assumed to be infinite ak[EDPointsMinOne] = 1.0f; ak[0] = 1.0f; #pragma omp for /*nowait*/ schedule(guided) for(int l = 0; l < offset;l++) { //The refractive index for air is 1, so there is no refractive index term for kk[0] kk[0] = k0 * indexsup * sintheta[l]; tempk1 = k0 * compsqrt(indexsupsquared*sinsquaredtheta[l]-DEDP[1]+DEDP[0]); tempk2 = k0 * compsqrt(indexsupsquared*sinsquaredtheta[l]-DEDP[EDPointsMinOne]+DEDP[0]); //Workout the wavevector k -> kk[i] = k0 *compsqrt(sinsquaredthetai[l]-2.0*nk[i]); #pragma ivdep for(int i = 1; i <= LowOffset;i++) { kk[i] = tempk1; } #pragma ivdep for(int i = LowOffset+1; i < HighOffSet;i++) { kk[i] = k0 * compsqrt(indexsupsquared*sinsquaredtheta[l]-DEDP[i]+DEDP[0]); } #pragma ivdep for(int i = HighOffSet; i < EDPoints; i++) { kk[i] = tempk2; } //Make the phase factors ak -> ak[i] = compexp(-1.0*imaginary*kk[i]*dz0/2.0); tempk1 = compexp(lengthmultiplier*kk[1]); tempk2 = compexp(lengthmultiplier*kk[EDPointsMinOne]); #pragma ivdep for(int i = 1; i <= LowOffset;i++) { ak[i] = tempk1; } #pragma ivdep for(int i = LowOffset+1; i < HighOffSet;i++) { ak[i] = compexp(lengthmultiplier*kk[i]); } #pragma ivdep for(int i = HighOffSet; i < EDPointsMinOne; i++) { ak[i] = tempk2; } //Make the Fresnel coefficients -> rj[i] =(kk[i]-kk[i+1])/(kk[i]+kk[i+1]); #pragma ivdep for(int i = 0; i < LowOffset;i++) { rj[i] = zero; } #pragma ivdep for(int i = LowOffset+1; i < HighOffSet;i++) { rj[i] =(kk[i]-kk[i+1])/(kk[i]+kk[i+1]); } #pragma ivdep for(int i = HighOffSet; i < EDPointsMinOne; i++) { rj[i] = zero; } //Parratt recursion of the amplitude reflectivity for(int i = EDPoints-2; i >= 0 ;i--) { Rj[i] = ak[i]*(Rj[i+1]+rj[i])/(Rj[i+1]*rj[i]+1.0); } //The magnitude of the reflection at layer 0 is the measured reflectivity of the film holder = compabs(Rj[0]); refl[l] = holder*holder; } //Now calculate the rest using doubles #pragma omp for schedule(guided) for(int l = offset; l < datapoints;l++) { //The refractive index for air is 1, so there is no refractive index term for kk[0] dkk[0] = k0 * indexsup.re * sintheta[l]; dtempk1 = k0 * sqrtf(indexsupsquared.re*sinsquaredtheta[l]-DEDP[1].re+DEDP[0].re); dtempk2 = k0 * sqrtf(indexsupsquared.re*sinsquaredtheta[l]-DEDP[EDPointsMinOne].re+DEDP[0].re); //Workout the wavevector k -> kk[i] = k0 *compsqrt(sinsquaredthetai[l]-2.0*nk[i]); #pragma ivdep for(int i = 1; i <= LowOffset;i++) { dkk[i] = dtempk1; } #pragma ivdep for(int i = LowOffset+1; i < HighOffSet;i++) { dkk[i] = k0 * sqrtf(indexsupsquared.re*sinsquaredtheta[l]-DEDP[i].re+DEDP[0].re); } #pragma ivdep for(int i = HighOffSet; i < EDPoints; i++) { dkk[i] = dtempk2; } //Make the phase factors ak -> ak[i] = compexp(-1.0*imaginary*kk[i]*dz0/2.0); tempk1 = compexp(lengthmultiplier*dkk[1]); tempk2 = compexp(lengthmultiplier*dkk[EDPointsMinOne]); #pragma ivdep for(int i = 1; i <= LowOffset;i++) { ak[i] = tempk1; } #pragma ivdep for(int i = LowOffset+1; i < HighOffSet;i++) { ak[i] = compexp(lengthmultiplier*dkk[i]); } #pragma ivdep for(int i = HighOffSet; i < EDPointsMinOne; i++) { ak[i] = tempk2; } //Make the Fresnel coefficients -> rj[i] =(kk[i]-kk[i+1])/(kk[i]+kk[i+1]); #pragma ivdep for(int i = 0; i < LowOffset;i++) { drj[i] = 0.0f; } #pragma ivdep for(int i = LowOffset; i < HighOffSet;i++) { drj[i] =(dkk[i]-dkk[i+1])/(dkk[i]+dkk[i+1]); } #pragma ivdep for(int i = HighOffSet; i < EDPointsMinOne; i++) { drj[i] = 0.0f; } //Parratt recursion of the amplitude reflectivity for(int i = EDPoints-2; i >= 0 ;i--) { Rj[i] = ak[i]*(Rj[i+1]+drj[i])/(Rj[i+1]*drj[i]+1.0); } //The magnitude of the reflection at layer 0 is the measured reflectivity of the film holder = compabs(Rj[0]); refl[l] = holder*holder; } } }
void AreaFastReflCalc::CalcRefl(double* sintheta, double* sinsquaredtheta, int datapoints, double* refl) { //Generate the Parratt reflectivity layers int nl = boxnumber+2; double k0 = 2.0*M_PI/lambda; MyComplex imaginary(0.0,1.0); int offset = 0; double suprefindex = 1-RhoArray[0]; double suprefindexsquared = suprefindex*suprefindex; double sigmacalc[20]; int neg = 0; for(int i =0; i<datapoints;i++) { for(int k = 1; k<nl;k++) { if((suprefindexsquared*sinsquaredtheta[i]-2.0*RhoArray[k]+2.0*RhoArray[0])<0) { neg -= 1; break; } } if(neg ==0) { /*if(m_dQSpread < 0.005 && neg == -5) break;*/ } else { offset = i; } } MyComplex lengthmultiplier = -2.0 * MyComplex (0.0,1.0) ; MyComplex kk[20]; double dkk[20]; MyComplex ak[20]; double drj[20]; MyComplex rj[20]; MyComplex Rj[20]; double dQj[20]; MyComplex Qj[20]; //Boundary conditions Rj[nl-1] = 0.0; ak[0] = 1.0; ak[nl-1] = 1.0; MyComplex doublenk[20]; MyComplex lengthcalc[20]; //Move some calcs out of the loop for(int i = 0; i<nl;i++) { doublenk[i]=-2.0*MyComplex (RhoArray[i],0); lengthcalc[i] = lengthmultiplier*LengthArray[i]; sigmacalc[i] = -2.0*SigmaArray[i]*SigmaArray[i]; } for(int l = 0; l <= offset ;l++) { int nlminone = nl-1; kk[0] = k0*suprefindex* sintheta[l]; //Workout the wavevector k for(int i = 1; i<nl;i++) { kk[i] = k0 *compsqrt(suprefindexsquared * sinsquaredtheta[l]+ doublenk[i] - doublenk[0]); } //Make the aj for(int i = 1; i<nlminone;i++) { ak[i] = compexp(kk[i]*lengthcalc[i]); } //Make the roughness correction term (Nevot-Croce) for(int i = 0; i< nlminone; i++) { #ifdef GIXOS Qj[i]=1; #else Qj[i] = compexp(sigmacalc[i]*kk[i]*kk[i+1]); #endif } //Make the Fresnel coefficients for(int i = 0; i <nlminone;i++) { rj[i] =Qj[i]* (kk[i]-kk[i+1])/(kk[i]+kk[i+1]); } for(int i = nl-2; i>=0;i--) { Rj[i] = ak[i]*(Rj[i+1]+rj[i])/(Rj[i+1]*rj[i]+1.0); } refl[l] = compabs(Rj[0]); refl[l] *= refl[l]; } for(int l = offset+1; l< datapoints ;l++) { //Leave for vectorization int nlminone = nl-1; //Boundary conditions dkk[0] = k0*suprefindex*sintheta[l]; //Workout the wavevector k for(int i = 1; i<nl;i++) { dkk[i] = k0 *sqrt(suprefindexsquared * sinsquaredtheta[l]+ doublenk[i].re - doublenk[0].re); } //Make the aj for(int i = 1; i<nlminone;i++) { ak[i] = compexp(lengthcalc[i]*dkk[i]); } //Make the roughness correction term (Nevot-Croce) #pragma ivdep for(int i = 0; i< nlminone; i++) { #ifdef GIXOS dQj[i]=1; #else dQj[i] = exp(sigmacalc[i]*dkk[i]*dkk[i+1]); #endif } //Make the Fresnel coefficients for(int i = 0; i < nlminone;i++) { drj[i] =dQj[i]* (dkk[i]-dkk[i+1])/(dkk[i]+dkk[i+1]); } for(int i = nl-2; i>=0;i--) { Rj[i] = ak[i]*(Rj[i+1]+drj[i])/(Rj[i+1]*drj[i]+1.0); } refl[l] = compabs(Rj[0]); refl[l] *= refl[l]; } }