// TE flux from Green's functions // extra factor of kp (elsewhere in the integrand) to make dimensionless // if integrate==true (default), then integral over emitter layer // done analytically. In this case xs = thickness of layer s // if integrate==false, then xs is the location of the emitter cdouble gfFluxTE(const SMatrix &S, const pwaves &pTE, int l, int s, double zl, double xs, bool integrate) { cdouble kzl = S.kz[l]; cdouble kzs = S.kz[s]; cdouble kp = S.kp; cdouble xl = II * kzl * zl; cdouble A = pTE.Al * exp(xl); cdouble B = pTE.Bl * exp(-xl); cdouble C = pTE.Cl * exp(xl); cdouble D = pTE.Dl * exp(-xl); cdouble fTE = 0; int gES[4] = {-1,-1,+1,+1}; // signs in exponent terms int gHS[4] = {+1,+1,-1,-1}; cdouble (*spaceFx)(int, int, cdouble, double); if (integrate) spaceFx = zsInt; else spaceFx = zsProd; // Note the overall neg. sign below cdouble prefac = II * kp / (4. * kzs) * conj(kzl / kzs); cdouble gEtt[4] = {A, B, C, D}; cdouble gHpt[4] = {A, -B, C, -D}; for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) fTE -= prefac * gEtt[i] * conj(gHpt[j]) * spaceFx(gES[i], gHS[j], kzs, xs); return fTE; }
void reflTrans(const mlgeo &g, double k0, double theta, int pol, cdouble *r, double *R, cdouble *t, double *T) { SMatrix S = new SMatrix(g, k0, k0 * sin(theta)); *r = S->S21(0, g.N, pol); *t = S->S11(0, g.N, pol); *R = (*r) * conj(*r); *T = real(sqrt(g.eps(N))) / real(sqrt(g.eps(0))) * (*t) * conj(*t); }
Vector<T> Vector<T>::conjugate(const Vector &vec) const { iSize = vec.size(); T *vecPtr = new T[iSize]; for(long i = 0; i < iSize; i++) vecPtr[i] = conj(vec.ptrArray[i]); return Vector<T>(iSize, vecPtr); }
// TM flux from Green's functions cdouble gfFluxTM(const SMatrix &S, const pwaves &pTM, int l, int s, double zl, double xs, bool integrate) { cdouble kzl = S.kz[l]; cdouble kzs = S.kz[s]; cdouble kl = S.k[l]; cdouble ks = S.k[s]; cdouble kp = S.kp; cdouble xl = II * kzl * zl; cdouble A = pTM.Al * exp(xl); cdouble B = pTM.Bl * exp(-xl); cdouble C = pTM.Cl * exp(xl); cdouble D = pTM.Dl * exp(-xl); cdouble fTM = 0; int gES[4] = {-1,-1,+1,+1}; // signs in exponent terms int gHS[4] = {+1,+1,-1,-1}; cdouble (*spaceFx)(int, int, cdouble, double); if (integrate) spaceFx = zsInt; else spaceFx = zsProd; // TM1 cdouble prefac = II * kzl * kp / (4. * ks * kl) * conj(kl / ks); cdouble gEpp[4] = {A, -B, -C, D}; cdouble gHtp[4] = {-A, -B, C, D}; for(int i=0; i<4; ++i) for(int j=0; j<4; ++j) fTM += prefac * gEpp[i] * conj(gHtp[j]) * spaceFx(gES[i], gHS[j], kzs, xs); // TM2 prefac *= kp * conj(kp) / (kzs * conj(kzs)); cdouble gEpz[4] = {-A, B, -C, D}; cdouble gHtz[4] = {A, B, C, D}; for(int i=0; i<4; ++i) for(int j=0; j<4; ++j) fTM += prefac * gEpz[i] * conj(gHtz[j]) * spaceFx(gES[i], gHS[j], kzs, xs); return fTM; }
/** Calculates the gradient of the Z error for THG. * * \param Esigp the magnitude replaced Esig(t,tau). * \param Et the current best guess. * \param dZ the gradient. */ void dZdE_thg(const TmexArray &Esigp, const TmexArray &Et, TmexArray &dZ) { int M = Esigp.size_M(); // The number of time points. int N = Esigp.size_N(); // The number of delay points. TReal sz = Esigp.size(); for(int t0 = 0; t0 < M; ++t0) { TCmplx T(0.0,0.0); for(int tau = 0; tau < N; ++tau) { int tp = t0 - (tau - N/2); if (tp >= 0 && tp < M) { T += (Et[t0] * Et[tp] * Et[tp] - Esigp(t0,tau)) * conj(Et[tp] * Et[tp]); } tp = t0 + (tau - N/2); if (tp >= 0 && tp < M) { T += 2.0 * conj(Et[tp] * Et[t0]) * (Et[tp] * Et[t0] * Et[t0] - Esigp(tp,tau)); } } dZ[t0] = T/sz; } }
// product of exponential terms arising in Green's function computations cdouble zsProd(int s1, int s2, cdouble kzs, double zs) { return exp(II * zs * (double(s1) * kzs + double(s2) * conj(kzs))); }