00001
00002
00003
00004
00005
00006
00007 #include "globals.hh"
00008 #include "BDSSpline.hh"
00009
00010 BDSSpline::BDSSpline(G4int nIn):n(nIn)
00011 {
00012 G4int i;
00013 u= *(new vDbl(n));
00014 tab=*(new vTab(n));
00015 for(i=0;i<n;i++) tab[i]=new BDSSpline_tab_entry();
00016
00017 }
00018
00019 void BDSSpline::initialise(vDbl* xIn,G4int xscalIn,
00020 vDbl* yIn,G4int yscalIn)
00021 {
00022 G4int i;
00023 G4double sig,p;
00024
00025 xscal=xscalIn;
00026 yscal=yscalIn;
00027
00028 BDSSpline_tab_entry* tabEntry=tab[0];
00029
00030 tabEntry->y2=0.0;
00031
00032
00033 for (i=0;i<n;i++)
00034 {
00035 BDSSpline_tab_entry* tabEntry=tab[i];
00036 switch (xscal){
00037 case 0:
00038 tabEntry->x=(*xIn)[i];
00039 break;
00040 case 1:
00041 tabEntry->x=log((*xIn)[i]);
00042 break;
00043 }
00044 switch (yscal){
00045 case 0:
00046 tabEntry->y=(*yIn)[i];
00047 break;
00048 case 1:
00049 tabEntry->y=log((*yIn)[i]);
00050 break;
00051 }
00052 }
00053
00054 u[0]=0.0;
00055 for (i=1;i<n-1;i++)
00056 {
00057 BDSSpline_tab_entry* tab_i=tab[i];
00058 BDSSpline_tab_entry* tab_im1=tab[i-1];
00059 BDSSpline_tab_entry* tab_ip1=tab[i+1];
00060
00061 sig=(tab_i->x-tab_im1->x)/(tab_ip1->x-tab_im1->x);
00062
00063 p=1.0/(sig*tab_im1->y2+2.0);
00064
00065 tab_i->y2=(sig-1.0)*p;
00066 u[i]=
00067 (6.0*((tab_ip1->y-tab_i->y)/(tab_ip1->x-tab_i->x)
00068 -(tab_i->y-tab_im1->y)/(tab_i->x-tab_im1->x))
00069 /(tab_ip1->x -tab_im1->x) - sig*u[i-1])*p;
00070 }
00071
00072 BDSSpline_tab_entry* tab_nm1=tab[n-1];
00073
00074 tab_nm1->y2=0.0;
00075 for (i=n-2;i>=0;i--)
00076 {
00077 BDSSpline_tab_entry* tab_i=tab[i];
00078 BDSSpline_tab_entry* tab_ip1=tab[i+1];
00079
00080 tab_i->y2=tab_i->y2*tab_ip1->y2+u[i];
00081 }
00082 }
00083
00084 G4double BDSSpline::integrate(G4double xIn)
00085 {
00086 int kmin,kmax,kpoint;
00087 double a,b,w;
00088
00089 kmin=0;
00090 kmax=n-1;
00091
00092 BDSSpline_tab_entry* tab_kmx=tab[kmax];
00093 BDSSpline_tab_entry* tab_kmn=tab[kmin];
00094 BDSSpline_tab_entry* tab_0=tab[0];
00095
00096 switch(xscal){
00097 case 0:
00098 break;
00099 case 1:
00100 xIn=log(xIn);
00101 break;
00102 }
00103
00104 if (xIn>tab_kmx->x)
00105 {
00106 if (yscal)return exp(tab_kmx->y);
00107 else return tab_kmx->y;
00108 }
00109 if (xIn<tab_0->x)
00110 {
00111 if (yscal) return exp(tab_0->y);
00112 else return tab_0->y;
00113 }
00114 while (kmax-kmin>1){
00115 kpoint=(kmax+kmin)/2;
00116 BDSSpline_tab_entry* tab_kpt=tab[kpoint];
00117
00118 if (tab_kpt->x>xIn) kmax=kpoint;
00119 else kmin=kpoint;
00120 }
00121
00122 w=tab_kmx->x - tab_kmn->x;
00123
00124 a=(tab_kmx->x-xIn)/w;
00125
00126 b=(xIn-tab_kmn->x)/w;
00127 G4double x=a*tab_kmn->y+b*tab_kmx->y+
00128 (a*(a*a-1.0)*tab_kmn->y2
00129 +b*(b*b-1.0)*tab_kmx->y2)*w*w/6.0;
00130
00131 switch (yscal){
00132 case 0:
00133 return x;
00134 case 1:
00135 return exp(x);
00136 }
00137 return x;
00138 }
00139
00140
00141 BDSSpline::~BDSSpline()
00142 {
00143 size_t i;
00144 for(i=0;i<tab.size();i++)
00145 if(tab[i]) delete tab[i];
00146 if(&tab)delete &tab;
00147
00148 if(&u) delete &u;
00149
00150 }
00151