inline Tv cubic(Tf f, const Tv& w, const Tv& x, const Tv& y, const Tv& z){ // Tv c3 = (x - y)*(Tf)1.5 + (z - w)*(Tf)0.5; // Tv c2 = w - x*(Tf)2.5 + y*(Tf)2. - z*(Tf)0.5; // Tv c1 = (y - w)*(Tf)0.5; // return ((c3 * f + c2) * f + c1) * f + x; // -w + 3x - 3y + z // 2w - 5x + 4y - z // c2 = w - 2x + y - c3 // Tv c3 = (x - y)*(Tf)3 + z - w; // Tv c2 = w - x*(Tf)2 + y - c3; // Tv c1 = y - w; // return (((c3 * f + c2) * f + c1)) * f * (Tf)0.5 + x; // Tv c3 = (x - y)*(Tf)1.5 + (z - w)*(Tf)0.5; // Tv c2 = (y + w)*(Tf)0.5 - x - c3; // Tv c1 = (y - w)*(Tf)0.5; // return ((c3 * f + c2) * f + c1) * f + x; Tv c1 = (y - w)*Tf(0.5); Tv c3 = (x - y)*Tf(1.5) + (z - w)*Tf(0.5); Tv c2 = c1 + w - x - c3; return ((c3 * f + c2) * f + c1) * f + x; }
inline Tv allpassFixed(Tf f, const Tv& x, const Tv& y, Tv& o1){ // f = 1.f-f; // f = allpassCoef(f); // compute allpass coefficient // return allpass(f, x, xp1, ym1); // apply filter //f = f / (2.f - f); // warp down f = (Tf(2) * f) / (Tf(1) + f); // warp up //f = (1.5f * f) / (0.5f + f); f -= Tf(0.1); // avoid pole near z = -1 return allpass(f, x, y, o1); // apply filter }
inline Tv bezier(Tf d, const Tv& x2, const Tv& x1, const Tv& x0){ Tf d2 = d * d; Tf dm1 = Tf(1) - d; Tf dm12 = dm1 * dm1; return dm12 * x2 + Tf(2)*dm1*d * x1 + d2 * x0; // x2 (1-d)(1-d) + 2 x1 (1-d) d + x0 d d // x2 - d 2 x2 + d d x2 + d 2 x1 - d d 2 x1 + d d x0 // x2 - d (2 x2 + d x2 + 2 x1 - d 2 x1 + d x0) // x2 - d (2 (x2 + x1) + d (x2 - 2 x1 + x0)) // float c2 = x2 - 2.f * x1 + x0; // float c1 = 2.f * (x2 + x1); // return x2 - (d * c2 + c1) * d; }
template<typename T, typename Tf> void test_sdec(T num, const char *fmt, const char *fmtp, const char *fmts) { char buf[256]; size_t len; { std::sprintf(buf, fmt, Tf(num)); len = std::strlen(buf); NTL::String test = NTL::dec(num); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 0); if(*buf == '-')*buf = '='; test = NTL::dec<'Z'>(num, "="); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 1); std::sprintf(buf, fmtp, Tf(num)); len = std::strlen(buf); test = NTL::dec(num, "-", "+"); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 1); std::sprintf(buf, fmts, Tf(num)); len = std::strlen(buf); if(*buf == '-')*buf = '_'; test = NTL::dec<'8'>(num, "_", " "); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 1); std::sprintf(buf + 2, fmtp, Tf(num)); buf[0] = buf[1] = buf[2]; len = std::strlen(buf); NTL::String test1 = NTL::dec<'*'>(num, "---", "+++"); assert(test1.length() == len && !std::memcmp(test1.data(), buf, len + 1)); mem_handler.check(1, 0); } mem_handler.check(0, 2); }
template<typename T, typename Tf> void test_dec(T num, const char *fmt) { char buf[256]; std::sprintf(buf, fmt, Tf(num)); size_t len = std::strlen(buf); { NTL::String test = NTL::dec(num); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 0); test = NTL::dec<'Z'>(num); assert(test.length() == len && !std::memcmp(test.data(), buf, len + 1)); mem_handler.check(1, 1); } mem_handler.check(0, 1); }
inline Tv quadratic(Tf f, const Tv& x, const Tv& y, const Tv& z){ Tv c2 = (x + z)*Tf(0.5) - y; //Tv c1 = x*(Tf)-1.5 + y*(Tf)2 - z*(Tf)0.5; Tv c1 = -x + y - c2; return (c2 * f + c1) * f + x; }
inline Tv nearest(Tf f, const Tv& x, const Tv& y){ return (f < Tf(0.5)) ? x : y; }
inline Tv linearCyclic(Tf frac, const Tv& x, const Tv& y, const Tv& z){ frac *= Tf(3); if(frac <= Tf(1)) return ipl::linear(frac, x,y); else if(frac >= Tf(2)) return ipl::linear(frac-Tf(2), z,x); return ipl::linear(frac-Tf(1), y,z); }
inline Tv linear(Tf frac, const Tv& x, const Tv& y, const Tv& z){ frac *= Tf(2); if(frac<Tf(1)) return ipl::linear(frac, x,y); return ipl::linear(frac-Tf(1), y,z); }
inline Tv bezier(Tf d, const Tv& x3, const Tv& x2, const Tv& x1, const Tv& x0){ Tv c1 = Tf(3) * (x2 - x3); Tv c2 = Tf(3) * (x1 - x2) - c1; Tv c3 = x0 - x3 - c1 - c2; return ((c3 * d + c2) * d + c1) * d + x3; }
int main(int argc, char* argv []) { // check for verbosity flag: bool verbose = false; if( argc >= 2 ) { for(int i=1; i < argc; i++) { std::string flag(argv[i]); if(flag == "--verbose") verbose = true; } } bool pass = true; // Do some output std::cout << "========== Test Suite 2 ==========" << std::endl; std::cout << " Testing plot generators " << std::endl; // create a model to use for the test: std::string fname("SRIM/Hydrogen in Aluminum.txt"); //StopPow::StopPow_SRIM s(fname); std::vector<double> mf(2); mf[0] = 1.0; mf[1] = 1/1800.; std::vector<double> Zf(2); Zf[0] = 1.0; Zf[1] = -1.; std::vector<double> Tf(2); Tf[0] = 1.0; Tf[1] = 1.0; std::vector<double> nf(2); nf[0] = 1e24; nf[1] = 1e24; nf[0] = 1e24; nf[1] = 1e24; StopPow::StopPow_LP s(1,1,mf,Zf,Tf,nf); std::vector< std::vector<double> > dEdx_plot; bool ret = StopPow::get_dEdx_vs_E( s , dEdx_plot ); if(ret) std::cout << "dE/dx plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate dE/dx plot" << std::endl; pass &= ret; std::vector< std::vector<double> > Range_plot; ret = StopPow::get_Range_vs_E( s , Range_plot ); if(ret) std::cout << "Range plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Range plot" << std::endl; pass &= ret; double thickness = 100; // um std::vector< std::vector<double> > Eout_plot_1; ret = StopPow::get_Eout_vs_Ein( s , thickness , Eout_plot_1 ); if(ret) std::cout << "Eout vs Ein plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Eout vs Ein plot" << std::endl; pass &= ret; double Ein = 15; // MeV std::vector< std::vector<double> > Eout_plot_2; ret = StopPow::get_Eout_vs_Thickness( s , Ein , Eout_plot_2 ); if(ret) std::cout << "Eout vs Thickness plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Eout vs Thickness plot" << std::endl; pass &= ret; thickness = 100; // um std::vector< std::vector<double> > Ein_plot_1; ret = StopPow::get_Ein_vs_Eout( s , thickness , Ein_plot_1 ); if(ret) std::cout << "Ein vs Eout plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Ein vs Eout plot" << std::endl; pass &= ret; double Eout = 15; // MeV std::vector< std::vector<double> > Ein_plot_2; ret = StopPow::get_Ein_vs_Thickness( s , Eout , Ein_plot_2 ); if(ret) std::cout << "Ein vs Thickness plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Ein vs Thickness plot" << std::endl; pass &= ret; Ein = 15; std::vector< std::vector<double> > Thickness_plot_1; ret = StopPow::get_Thickness_vs_Eout( s , Ein , Thickness_plot_1 ); if(ret) std::cout << "Thickness vs Eout plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Thickness vs Eout plot" << std::endl; pass &= ret; Eout = 5; std::vector< std::vector<double> > Thickness_plot_2; ret = StopPow::get_Thickness_vs_Ein( s , Eout , Thickness_plot_2 ); if(ret) std::cout << "Thickness vs Ein plot generated successfully" << std::endl; else std::cout << "ERROR: could not generate Thickness vs Ein plot" << std::endl; pass &= ret; // print if requested if( verbose) { std::cout << "E (MeV) , dE/dx" << std::endl; for(int j=0; j<dEdx_plot[0].size(); j++) { std::cout << dEdx_plot[0][j] << "," << dEdx_plot[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "E (MeV) , Range" << std::endl; for(int j=0; j<Range_plot[0].size(); j++) { std::cout << Range_plot[0][j] << "," << Range_plot[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Ein (MeV) , Eout (MeV)" << std::endl; for(int j=0; j<Eout_plot_1[0].size(); j++) { std::cout << Eout_plot_1[0][j] << "," << Eout_plot_1[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Thickness , Eout (MeV)" << std::endl; for(int j=0; j<Eout_plot_2[0].size(); j++) { std::cout << Eout_plot_2[0][j] << "," << Eout_plot_2[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Eout (MeV) , Ein (MeV)" << std::endl; for(int j=0; j<Ein_plot_1[0].size(); j++) { std::cout << Ein_plot_1[0][j] << "," << Ein_plot_1[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Thickness , Ein (MeV)" << std::endl; for(int j=0; j<Ein_plot_2[0].size(); j++) { std::cout << Ein_plot_2[0][j] << "," << Ein_plot_2[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Eout (MeV) , Thickness" << std::endl; for(int j=0; j<Thickness_plot_1[0].size(); j++) { std::cout << Thickness_plot_1[0][j] << "," << Thickness_plot_1[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; std::cout << "Ein (MeV) , Thickness" << std::endl; for(int j=0; j<Thickness_plot_2[0].size(); j++) { std::cout << Thickness_plot_2[0][j] << "," << Thickness_plot_2[1][j] << std::endl; } std::cout << "--------------------------------" << std::endl; } // --------------------------------------- // Speed tests // --------------------------------------- std::cout << "Speed tests (ms / generation):" << std::endl; int n = 10; std::clock_t start; double duration; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_dEdx_vs_E( s , dEdx_plot ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "dE/dx vs E = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Range_vs_E( s , Range_plot ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Range vs E = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Eout_vs_Ein( s , thickness , Eout_plot_1 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Eout vs Ein = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Eout_vs_Thickness( s , Ein , Eout_plot_2 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Eout vs Thickness = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Ein_vs_Eout( s , thickness , Ein_plot_1 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Ein vs Eout = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Ein_vs_Thickness( s , Eout , Ein_plot_2 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Ein vs Thickness = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Thickness_vs_Eout( s , Ein , Thickness_plot_1 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Thickness vs Eout = " << duration << " ms" << std::endl; start = std::clock(); for(int i=0; i<n; i++) ret = StopPow::get_Thickness_vs_Ein( s , Eout , Thickness_plot_2 ); // duration per call in ms: duration = (1000./n)*(std::clock()-start) / (double) CLOCKS_PER_SEC; std::cout << "Thickness vs Ein = " << duration << " ms" << std::endl; if(pass) { std::cout << "PASS" << std::endl; return 0; } std::cout << "FAIL!" << std::endl; return 1; }