00001 // makeikk.cc 00002 // A simple program to generate the Kramers-Kronig transform of a normalized 00003 // SIS DC IV curve, such as generated by makeiv.cc. It gives good results 00004 // most of the time; Examine a plot of the output to ensure that there are 00005 // no discontinuities introduced by numerical artifacts. 00006 // 00007 // An input file name must be included on the command line; 00008 // the output will be written to the standard output stream. 00009 00010 #include "supermix.h" 00011 #include "numerical.h" 00012 00013 const char *comment = "#"; 00014 00015 // --------------------------------------------------------------------------- 00016 // Some parameters you can adjust to control the integration (see integrate.h): 00017 00018 unsigned ORDER = 3; // the order of the Rhomberg extrapolation (min 1) 00019 double ABS_TOL = 1.0e-9; // absolute error tolerance 00020 double REL_TOL = 1.0e-10; // relative error tolerance 00021 00022 // Lowering the tolerances to ~ 1.0e-7 may generate the results more quickly, but 00023 // will only work well if the DC IV curve is not very sharp at the gap. Lowering 00024 // ORDER to 1 may help, but often will not. If you run into convergence 00025 // problems, this condition will usually be indicated by an error message like 00026 // "WARNING: Recursion limit reached in adaptive interpolator build." 00027 // Ensure that you carefully examine the output in this case; if the input IV 00028 // curve is very sharp, the output may be just fine, even though the warning was 00029 // output. 00030 // If you do have convergence problems, try reducing ORDER and tightening the 00031 // error tolerances. 00032 // --------------------------------------------------------------------------- 00033 00034 real_interp IDC; 00035 double Vo; 00036 double idc(double v) { return (v < 0.0) ? -IDC(-v) : IDC(v); } 00037 00038 struct F { 00039 double x; 00040 F(double xx): x(xx) { } 00041 double operator()(double v) const 00042 { return (idc(v+x) + idc(v-x) - 2*idc(v))/v; } 00043 }; 00044 00045 integrator<double> In; 00046 double ikk_f(double x) 00047 { 00048 F f(x); 00049 return (In.open()(f, 0, Vo/3) + In.exp()(f, Vo/3, 1000))/Pi; 00050 } 00051 00052 int main(int argc, char **argv) 00053 { 00054 if(argc < 2) { 00055 cerr << "Usage: " << argv[0] << " <idc_file>" << endl; 00056 return 1; 00057 } 00058 00059 const char * name = argv[1]; 00060 IDC.file(name).quiet(); 00061 Vo = IDC.x(IDC.size()-1); // max voltage in the table 00062 00063 // Set the integrator control parameters: 00064 In.order = ORDER; 00065 In.abs_tolerance = ABS_TOL; 00066 In.rel_tolerance = REL_TOL; 00067 00068 interpolation ikk; 00069 ikk.left_slope(0); 00070 00071 // Don't set accuracies any tighter in the following, or you may see 00072 // convergence problems. Note that we generate the transform values 00073 // out to voltages double those in the DC IV data set. 00074 adaptive_fill(ikk, ikk_f, 0, 2*Vo, 1e-6, 1e-3); 00075 00076 cout << fixed << setprecision(10); 00077 cout << comment << " Normalized SIS Kramers-Kronig IV characteristic curve" << endl; 00078 cout << comment << " The DC IV file for this data: " << name << endl; 00079 cout << comment << endl; 00080 cout << comment << " V: " << "\t" << "I:" << endl; 00081 00082 for (unsigned i = 0; i < ikk.size(); ++i) 00083 cout << ikk.x(i) << "\t" << ikk[i] << endl; 00084 return 0; 00085 }
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7