void NR::gauleg(const DP x1, const DP x2, Vec_O_DP &x, Vec_O_DP &w) { const DP EPS=1.0e-14; int m,j,i; DP z1,z,xm,xl,pp,p3,p2,p1; int n=x.size(); m=(n+1)/2; xm=0.5*(x2+x1); xl=0.5*(x2-x1); for (i=0;i<m;i++) { z=cos(3.141592654*(i+0.75)/(n+0.5)); do { p1=1.0; p2=0.0; for (j=0;j<n;j++) { p3=p2; p2=p1; p1=((2.0*j+1.0)*z*p2-j*p3)/(j+1); } pp=n*(z*p1-p2)/(z*z-1.0); z1=z; z=z1-p1/pp; } while (fabs(z-z1) > EPS); x[i]=xm-xl*z; x[n-1-i]=xm+xl*z; w[i]=2.0*xl/((1.0-z*z)*pp*pp); w[n-1-i]=w[i]; } }
void NR::svdfit(Vec_I_DP &x, Vec_I_DP &y, Vec_I_DP &sig, Vec_O_DP &a, Mat_O_DP &u, Mat_O_DP &v, Vec_O_DP &w, DP &chisq, void funcs(const DP, Vec_O_DP &)) { int i,j; const DP TOL=1.0e-13; DP wmax,tmp,thresh,sum; int ndata=x.size(); int ma=a.size(); Vec_DP b(ndata),afunc(ma); for (i=0;i<ndata;i++) { funcs(x[i],afunc); tmp=1.0/sig[i]; for (j=0;j<ma;j++) u[i][j]=afunc[j]*tmp; b[i]=y[i]*tmp; } svdcmp(u,w,v); wmax=0.0; for (j=0;j<ma;j++) if (w[j] > wmax) wmax=w[j]; thresh=TOL*wmax; for (j=0;j<ma;j++) if (w[j] < thresh) w[j]=0.0; svbksb(u,w,v,b,a); chisq=0.0; for (i=0;i<ndata;i++) { funcs(x[i],afunc); sum=0.0; for (j=0;j<ma;j++) sum += a[j]*afunc[j]; chisq += (tmp=(y[i]-sum)/sig[i],tmp*tmp); } }
void NR::sprstm(Vec_I_DP &sa, Vec_I_INT &ija, Vec_I_DP &sb, Vec_I_INT &ijb, const DP thresh, Vec_O_DP &sc, Vec_O_INT &ijc) { int i,ijma,ijmb,j,k,ma,mb,mbb; DP sum; if (ija[0] != ijb[0]) nrerror("sprstm: sizes do not match"); int nmax=sc.size(); ijc[0]=k=ija[0]; for (i=0;i<ija[0]-1;i++) { for (j=0;j<ijb[0]-1;j++) { if (i == j) sum=sa[i]*sb[j]; else sum=0.0e0; mb=ijb[j]; for (ma=ija[i];ma<ija[i+1];ma++) { ijma=ija[ma]; if (ijma == j) sum += sa[ma]*sb[j]; else { while (mb < ijb[j+1]) { ijmb=ijb[mb]; if (ijmb == i) { sum += sa[i]*sb[mb++]; continue; } else if (ijmb < ijma) { mb++; continue; } else if (ijmb == ijma) { sum += sa[ma]*sb[mb++]; continue; } break; } } } for (mbb=mb;mbb<ijb[j+1];mbb++) { if (ijb[mbb] == i) sum += sa[i]*sb[mbb]; } if (i == j) sc[i]=sum; else if (fabs(sum) > thresh) { if (k > nmax-1) nrerror("sprstm: sc and ijc too small"); sc[k]=sum; ijc[k++]=j; } } ijc[i+1]=k; } }
void NR::predic(Vec_I_DP &data, Vec_I_DP &d, Vec_O_DP &future) { int k,j; DP sum,discrp; int ndata=data.size(); int m=d.size(); int nfut=future.size(); Vec_DP reg(m); for (j=0;j<m;j++) reg[j]=data[ndata-1-j]; for (j=0;j<nfut;j++) { discrp=0.0; sum=discrp; for (k=0;k<m;k++) sum += d[k]*reg[k]; for (k=m-1;k>=1;k--) reg[k]=reg[k-1]; future[j]=reg[0]=sum; } }
void NR::fred2(const DP a, const DP b, Vec_O_DP &t, Vec_O_DP &f, Vec_O_DP &w, DP g(const DP), DP ak(const DP, const DP)) { int i,j; DP d; int n=t.size(); Mat_DP omk(n,n); Vec_INT indx(n); gauleg(a,b,t,w); for (i=0;i<n;i++) { for (j=0;j<n;j++) omk[i][j]=DP(i == j)-ak(t[i],t[j])*w[j]; f[i]=g(t[i]); } ludcmp(omk,indx,d); lubksb(omk,indx,f); }
void NR::sprsin(Mat_I_DP &a, const DP thresh, Vec_O_DP &sa, Vec_O_INT &ija) { int i,j,k; int n=a.nrows(); int nmax=sa.size(); for (j=0;j<n;j++) sa[j]=a[j][j]; ija[0]=n+1; k=n; for (i=0;i<n;i++) { for (j=0;j<n;j++) { if (fabs(a[i][j]) >= thresh && i != j) { if (++k > nmax) nrerror("sprsin: sa and ija too small"); sa[k]=a[i][j]; ija[k]=j; } } ija[i+1]=k+1; } }
void NR::zbrak(DP fx(const DP), const DP x1, const DP x2, const int n, Vec_O_DP &xb1, Vec_O_DP &xb2, int &nroot) { int i; DP x,fp,fc,dx; int nb=xb1.size(); nroot=0; dx=(x2-x1)/n; fp=fx(x=x1); for (i=0;i<n;i++) { fc=fx(x += dx); if (fc*fp <= 0.0) { xb1[nroot]=x-dx; xb2[nroot++]=x; if(nroot == nb) return; } fp=fc; } }
void NR::gauher(Vec_O_DP &x, Vec_O_DP &w) { const DP EPS=1.0e-14,PIM4=0.7511255444649425; const int MAXIT=10; int i,its,j,m; DP p1,p2,p3,pp,z,z1; int n=x.size(); m=(n+1)/2; for (i=0;i<m;i++) { if (i == 0) { z=sqrt(DP(2*n+1))-1.85575*pow(DP(2*n+1),-0.16667); } else if (i == 1) { z -= 1.14*pow(DP(n),0.426)/z; } else if (i == 2) { z=1.86*z-0.86*x[0]; } else if (i == 3) { z=1.91*z-0.91*x[1]; } else { z=2.0*z-x[i-2]; } for (its=0;its<MAXIT;its++) { p1=PIM4; p2=0.0; for (j=0;j<n;j++) { p3=p2; p2=p1; p1=z*sqrt(2.0/(j+1))*p2-sqrt(DP(j)/(j+1))*p3; } pp=sqrt(DP(2*n))*p2; z1=z; z=z1-p1/pp; if (fabs(z-z1) <= EPS) break; } if (its >= MAXIT) nrerror("too many iterations in gauher"); x[i]=z; x[n-1-i] = -z; w[i]=2.0/(pp*pp); w[n-1-i]=w[i]; } }
void NR::memcof(Vec_I_DP &data, DP &xms, Vec_O_DP &d) { int k,j,i; DP p=0.0; int n=data.size(); int m=d.size(); Vec_DP wk1(n),wk2(n),wkm(m); for (j=0;j<n;j++) p += SQR(data[j]); xms=p/n; wk1[0]=data[0]; wk2[n-2]=data[n-1]; for (j=1;j<n-1;j++) { wk1[j]=data[j]; wk2[j-1]=data[j]; } for (k=0;k<m;k++) { DP num=0.0,denom=0.0; for (j=0;j<(n-k-1);j++) { num += (wk1[j]*wk2[j]); denom += (SQR(wk1[j])+SQR(wk2[j])); } d[k]=2.0*num/denom; xms *= (1.0-SQR(d[k])); for (i=0;i<k;i++) d[i]=wkm[i]-d[k]*wkm[k-1-i]; if (k == m-1) return; for (i=0;i<=k;i++) wkm[i]=d[i]; for (j=0;j<(n-k-2);j++) { wk1[j] -= (wkm[k]*wk2[j]); wk2[j]=wk2[j+1]-wkm[k]*wk1[j+1]; } } nrerror("never get here in memcof."); }
void NR::period(Vec_I_DP &x, Vec_I_DP &y, const DP ofac, const DP hifac, Vec_O_DP &px, Vec_O_DP &py, int &nout, int &jmax, DP &prob) { const DP TWOPI=6.283185307179586476; int i,j; DP ave,c,cc,cwtau,effm,expy,pnow,pymax,s,ss,sumc,sumcy,sums,sumsh, sumsy,swtau,var,wtau,xave,xdif,xmax,xmin,yy,arg,wtemp; int n=x.size(); int np=px.size(); Vec_DP wi(n),wpi(n),wpr(n),wr(n); nout=0.5*ofac*hifac*n; if (nout > np) nrerror("output arrays too short in period"); avevar(y,ave,var); if (var == 0.0) nrerror("zero variance in period"); xmax=xmin=x[0]; for (j=0;j<n;j++) { if (x[j] > xmax) xmax=x[j]; if (x[j] < xmin) xmin=x[j]; } xdif=xmax-xmin; xave=0.5*(xmax+xmin); pymax=0.0; pnow=1.0/(xdif*ofac); for (j=0;j<n;j++) { arg=TWOPI*((x[j]-xave)*pnow); wpr[j]= -2.0*SQR(sin(0.5*arg)); wpi[j]=sin(arg); wr[j]=cos(arg); wi[j]=wpi[j]; } for (i=0;i<nout;i++) { px[i]=pnow; sumsh=sumc=0.0; for (j=0;j<n;j++) { c=wr[j]; s=wi[j]; sumsh += s*c; sumc += (c-s)*(c+s); } wtau=0.5*atan2(2.0*sumsh,sumc); swtau=sin(wtau); cwtau=cos(wtau); sums=sumc=sumsy=sumcy=0.0; for (j=0;j<n;j++) { s=wi[j]; c=wr[j]; ss=s*cwtau-c*swtau; cc=c*cwtau+s*swtau; sums += ss*ss; sumc += cc*cc; yy=y[j]-ave; sumsy += yy*ss; sumcy += yy*cc; wr[j]=((wtemp=wr[j])*wpr[j]-wi[j]*wpi[j])+wr[j]; wi[j]=(wi[j]*wpr[j]+wtemp*wpi[j])+wi[j]; } py[i]=0.5*(sumcy*sumcy/sumc+sumsy*sumsy/sums)/var; if (py[i] >= pymax) pymax=py[jmax=i]; pnow += 1.0/(ofac*xdif); } expy=exp(-pymax); effm=2.0*nout/ofac; prob=effm*expy; if (prob > 0.01) prob=1.0-pow(1.0-expy,effm); }