vec2r Fresnel::eval(real theta0, real kappa0, real a, real s) { real c1 = kappa0 / a; real theta = theta0 - kappa0 * kappa0 / (rl(2.0) * a); if (isnan(c1) || isinf(c1) || isnan(theta) || isinf(theta)) // This is a circle or a line { real r = rl(1) / kappa0; if (isinf(r)) // This is a line { return vec2r(s * cos(theta0), s * sin(theta0)); } else // This is a circle { // Note that negative kappa is handled magically by itself real angle = s * kappa0; vec2r result = { r * sin(angle), r - r * cos(angle) }; result.rot(theta0); return result; } } else // This is the normal case { real c0 = sqrt(abs(a) / PI); real s0 = c0 * (s + c1); real s1 = c0 * c1; vec2r result = (eval(s0) - eval(s1)) / c0; if (a < 0) result.y = -result.y; result.rot(theta0 - kappa0 * kappa0 / (rl(2.0) * a)); return result; } }
vec2r Fresnel::eval1(real a, real s) { const real c0 = sqrt(abs(a) / PI); const real c1 = rl(1) / a; if (isinf(c1)) // This is circle return vec2r(sin(s), 1 - cos(s)); real s0 = c0 * (s + c1); real s1 = c0 * c1; vec2r result = (eval(s0) - eval(s1)) / c0; if (a < 0) result.y = -result.y; result.rot(-rl(1) / (rl(2) * a)); return result; }
static void testnsevdproblem(const ap::real_2d_array& a, int n, double& vecerr, double& valonlydiff, bool& wfailed) { double mx; int i; int j; int k; int vjob; bool needl; bool needr; ap::real_1d_array wr0; ap::real_1d_array wi0; ap::real_1d_array wr1; ap::real_1d_array wi1; ap::real_1d_array wr0s; ap::real_1d_array wi0s; ap::real_1d_array wr1s; ap::real_1d_array wi1s; ap::real_2d_array vl; ap::real_2d_array vr; ap::real_1d_array vec1r; ap::real_1d_array vec1i; ap::real_1d_array vec2r; ap::real_1d_array vec2i; ap::real_1d_array vec3r; ap::real_1d_array vec3i; double curwr; double curwi; double vt; double tmp; vec1r.setbounds(0, n-1); vec2r.setbounds(0, n-1); vec3r.setbounds(0, n-1); vec1i.setbounds(0, n-1); vec2i.setbounds(0, n-1); vec3i.setbounds(0, n-1); wr0s.setbounds(0, n-1); wr1s.setbounds(0, n-1); wi0s.setbounds(0, n-1); wi1s.setbounds(0, n-1); mx = 0; for(i = 0; i <= n-1; i++) { for(j = 0; j <= n-1; j++) { if( fabs(a(i,j))>mx ) { mx = fabs(a(i,j)); } } } if( mx==0 ) { mx = 1; } // // Load values-only // if( !rmatrixevd(a, n, 0, wr0, wi0, vl, vr) ) { wfailed = false; return; } // // Test different jobs // for(vjob = 1; vjob <= 3; vjob++) { needr = vjob==1||vjob==3; needl = vjob==2||vjob==3; if( !rmatrixevd(a, n, vjob, wr1, wi1, vl, vr) ) { wfailed = false; return; } // // Test values: // 1. sort by real part // 2. test // ap::vmove(&wr0s(0), &wr0(0), ap::vlen(0,n-1)); ap::vmove(&wi0s(0), &wi0(0), ap::vlen(0,n-1)); for(i = 0; i <= n-1; i++) { for(j = 0; j <= n-2-i; j++) { if( wr0s(j)>wr0s(j+1) ) { tmp = wr0s(j); wr0s(j) = wr0s(j+1); wr0s(j+1) = tmp; tmp = wi0s(j); wi0s(j) = wi0s(j+1); wi0s(j+1) = tmp; } } } ap::vmove(&wr1s(0), &wr1(0), ap::vlen(0,n-1)); ap::vmove(&wi1s(0), &wi1(0), ap::vlen(0,n-1)); for(i = 0; i <= n-1; i++) { for(j = 0; j <= n-2-i; j++) { if( wr1s(j)>wr1s(j+1) ) { tmp = wr1s(j); wr1s(j) = wr1s(j+1); wr1s(j+1) = tmp; tmp = wi1s(j); wi1s(j) = wi1s(j+1); wi1s(j+1) = tmp; } } } for(i = 0; i <= n-1; i++) { valonlydiff = ap::maxreal(valonlydiff, fabs(wr0s(i)-wr1s(i))); valonlydiff = ap::maxreal(valonlydiff, fabs(wi0s(i)-wi1s(i))); } // // Test right vectors // if( needr ) { k = 0; while(k<=n-1) { if( wi1(k)==0 ) { ap::vmove(vec1r.getvector(0, n-1), vr.getcolumn(k, 0, n-1)); for(i = 0; i <= n-1; i++) { vec1i(i) = 0; } curwr = wr1(k); curwi = 0; } if( wi1(k)>0 ) { ap::vmove(vec1r.getvector(0, n-1), vr.getcolumn(k, 0, n-1)); ap::vmove(vec1i.getvector(0, n-1), vr.getcolumn(k+1, 0, n-1)); curwr = wr1(k); curwi = wi1(k); } if( wi1(k)<0 ) { ap::vmove(vec1r.getvector(0, n-1), vr.getcolumn(k-1, 0, n-1)); ap::vmoveneg(vec1i.getvector(0, n-1), vr.getcolumn(k, 0, n-1)); curwr = wr1(k); curwi = wi1(k); } for(i = 0; i <= n-1; i++) { vt = ap::vdotproduct(&a(i, 0), &vec1r(0), ap::vlen(0,n-1)); vec2r(i) = vt; vt = ap::vdotproduct(&a(i, 0), &vec1i(0), ap::vlen(0,n-1)); vec2i(i) = vt; } ap::vmove(&vec3r(0), &vec1r(0), ap::vlen(0,n-1), curwr); ap::vsub(&vec3r(0), &vec1i(0), ap::vlen(0,n-1), curwi); ap::vmove(&vec3i(0), &vec1r(0), ap::vlen(0,n-1), curwi); ap::vadd(&vec3i(0), &vec1i(0), ap::vlen(0,n-1), curwr); for(i = 0; i <= n-1; i++) { vecerr = ap::maxreal(vecerr, fabs(vec2r(i)-vec3r(i))); vecerr = ap::maxreal(vecerr, fabs(vec2i(i)-vec3i(i))); } k = k+1; } } // // Test left vectors // if( needl ) { k = 0; while(k<=n-1) { if( wi1(k)==0 ) { ap::vmove(vec1r.getvector(0, n-1), vl.getcolumn(k, 0, n-1)); for(i = 0; i <= n-1; i++) { vec1i(i) = 0; } curwr = wr1(k); curwi = 0; } if( wi1(k)>0 ) { ap::vmove(vec1r.getvector(0, n-1), vl.getcolumn(k, 0, n-1)); ap::vmove(vec1i.getvector(0, n-1), vl.getcolumn(k+1, 0, n-1)); curwr = wr1(k); curwi = wi1(k); } if( wi1(k)<0 ) { ap::vmove(vec1r.getvector(0, n-1), vl.getcolumn(k-1, 0, n-1)); ap::vmoveneg(vec1i.getvector(0, n-1), vl.getcolumn(k, 0, n-1)); curwr = wr1(k); curwi = wi1(k); } for(j = 0; j <= n-1; j++) { vt = ap::vdotproduct(vec1r.getvector(0, n-1), a.getcolumn(j, 0, n-1)); vec2r(j) = vt; vt = ap::vdotproduct(vec1i.getvector(0, n-1), a.getcolumn(j, 0, n-1)); vec2i(j) = -vt; } ap::vmove(&vec3r(0), &vec1r(0), ap::vlen(0,n-1), curwr); ap::vadd(&vec3r(0), &vec1i(0), ap::vlen(0,n-1), curwi); ap::vmove(&vec3i(0), &vec1r(0), ap::vlen(0,n-1), curwi); ap::vsub(&vec3i(0), &vec1i(0), ap::vlen(0,n-1), curwr); for(i = 0; i <= n-1; i++) { vecerr = ap::maxreal(vecerr, fabs(vec2r(i)-vec3r(i))); vecerr = ap::maxreal(vecerr, fabs(vec2i(i)-vec3i(i))); } k = k+1; } } } }