void Objectness::meanStdDev(CMat &data1f, Mat &mean1f, Mat &stdDev1f) { const int DIM = data1f.cols, NUM = data1f.rows; mean1f = Mat::zeros(1, DIM, CV_32F), stdDev1f = Mat::zeros(1, DIM, CV_32F); for (int i = 0; i < NUM; i++) mean1f += data1f.row(i); mean1f /= NUM; for (int i = 0; i < NUM; i++) { Mat tmp; pow(data1f.row(i) - mean1f, 2, tmp); stdDev1f += tmp; } pow(stdDev1f/NUM, 0.5, stdDev1f); }
int S4r::Simulation::GetSMatrix( size_t layer_start, size_t layer_end, CMat &S ){ S4R_TRACE("> Simulation::GetSMatrix(start = %lu, end = %lu)\n", layer_start, layer_end ); const size_t n0 = layers[layer_start]->GetNumModes(); // Ultimately, S will have dimensions: // // n0 n1 // n1 [ S11 S12 ] // S = [ ] // n0 [ S21 S22 ] // S.resize(n0+n0,n0+n0); // S starts off at layer_start S.setIdentity(); for(size_t l = layer_start; l < layer_end; ++l){ const size_t lp1 = l+1; const size_t nl = layers[l]->GetNumModes(); const size_t nlp1 = layers[lp1]->GetNumModes(); const Layer &Ll = (*layers[l]); const Layer &Llp1 = (*layers[lp1]); // At this point, S is // n0 nl // nl [ S11 S12 ] // S = [ ] // n0 [ S21 S22 ] // Make the interface matrices. They will have dimensions: // nlp1 nlp1 // nl [ I11 I12 ] [ in1 in2 ] // I = [ ] = [ ] // nl [ I21 I22 ] [ in2 in1 ] // CMat in1, in2; { // The interface matrix is the inverse of the mode-to-field matrix of layer l // times the mode-to-field matrix of layer l+1 (lp1). // The mode-to-field matrix is of the form // [ B -B ] where A = phi // [ A A ] where B = kp*phi*inv(diag(q)) = G*A/q // So we want // Interface = 0.5 * [ iBl iAl ] [ Blp1 -Blp1 ] // [ -iBl iAl ] [ Alp1 Alp1 ] // where iBl = inv(Bl), etc. // Multiplying out gives // 0.5 * [ P+Q P-Q ] // where P = iAl*Alp1, and i in front means inverse // [ P-Q P+Q ] // where Q = iBl*Blp1 // Making P is easy, since A is a single matrix. // Making Q is as follows: // Q = iBl*Blp1 // = ql*iAl*iGl * Gl*Alp1*iqlp1 // We will only store I11 and I21 { // Make Blp1 in in2 CMat t1(Llp1.modes.kp * Llp1.modes.phi); // Make Q in in1 // Take care when inverting t1, since it may be singular at a // diffraction threshold. Eigen::ColPivHouseholderQR<CMat> iBl(Ll.modes.kp * Ll.modes.phi); in1 = Ll.modes.q.asDiagonal() * iBl.solve(t1); { // Take special care since an element of q may be zero double maxel = 0; for(size_t i = 0; i < nlp1; ++i){ double el = std::abs(Llp1.modes.q[i]); if(el > maxel){ maxel = el; } } for(size_t i = 0; i < nlp1; ++i){ double el = std::abs(Llp1.modes.q[i]); if(el > maxel * DBL_EPSILON){ in1.col(i) *= 1./Llp1.modes.q[i]; }else{ in1.col(i).setZero(); } } } } // Make P in in2 { Eigen::ColPivHouseholderQR<CMat> iAl(Ll.modes.phi); // t1 may become singular for planewaves at diffraction thresholds // with a z-directed polarization. in2 = iAl.solve(Llp1.modes.phi); } CMat t1(in2); // in2 = P, t1 = P, in1 = Q in2 = 0.5*(t1-in1); in1 = 0.5*(t1+in1); // The inverse of the Interface matrix is // inv(Interface) = 0.5 * [ iP+iQ iP-iQ ] // [ iP-iQ iP+iQ ] // where iP = inv(P), etc. } CMat SI = T2Sblocks(nl, nlp1, in1, in2); for(size_t i = 0; i < nl; ++i){ S.row(i) *= std::exp(Ll.modes.q[i] * std::complex<double>(0,Ll.description.thickness)); } for(size_t i = 0; i < nlp1; ++i){ SI.col(nl+i) *= std::exp(Llp1.modes.q[i] * std::complex<double>(0,Llp1.description.thickness)); } CMat Snew = StarProduct(n0, nl, nlp1, S, SI); S = Snew; } S4R_TRACE("< Simulation::GetSMatrix\n"); return 0; }