add numerical recipes library
This commit is contained in:
64
lib/nr/cpp/recipes/ratlsq.cpp
Normal file
64
lib/nr/cpp/recipes/ratlsq.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "nr.h"
|
||||
using namespace std;
|
||||
|
||||
void NR::ratlsq(DP fn(const DP), const DP a, const DP b, const int mm,
|
||||
const int kk, Vec_O_DP &cof, DP &dev)
|
||||
{
|
||||
const int NPFAC=8,MAXIT=5;
|
||||
const DP BIG=1.0e30,PIO2=1.570796326794896619;
|
||||
int i,it,j,ncof,npt;
|
||||
DP devmax,e,hth,power,sum;
|
||||
|
||||
ncof=mm+kk+1;
|
||||
npt=NPFAC*ncof;
|
||||
Vec_DP bb(npt),coff(ncof),ee(npt),fs(npt),w(ncof),wt(npt),xs(npt);
|
||||
Mat_DP u(npt,ncof),v(ncof,ncof);
|
||||
dev=BIG;
|
||||
for (i=0;i<npt;i++) {
|
||||
if (i < (npt/2)-1) {
|
||||
hth=PIO2*i/(npt-1.0);
|
||||
xs[i]=a+(b-a)*SQR(sin(hth));
|
||||
} else {
|
||||
hth=PIO2*(npt-i)/(npt-1.0);
|
||||
xs[i]=b-(b-a)*SQR(sin(hth));
|
||||
}
|
||||
fs[i]=fn(xs[i]);
|
||||
wt[i]=1.0;
|
||||
ee[i]=1.0;
|
||||
}
|
||||
e=0.0;
|
||||
for (it=0;it<MAXIT;it++) {
|
||||
for (i=0;i<npt;i++) {
|
||||
power=wt[i];
|
||||
bb[i]=power*(fs[i]+SIGN(e,ee[i]));
|
||||
for (j=0;j<mm+1;j++) {
|
||||
u[i][j]=power;
|
||||
power *= xs[i];
|
||||
}
|
||||
power = -bb[i];
|
||||
for (j=mm+1;j<ncof;j++) {
|
||||
power *= xs[i];
|
||||
u[i][j]=power;
|
||||
}
|
||||
}
|
||||
svdcmp(u,w,v);
|
||||
svbksb(u,w,v,bb,coff);
|
||||
devmax=sum=0.0;
|
||||
for (j=0;j<npt;j++) {
|
||||
ee[j]=ratval(xs[j],coff,mm,kk)-fs[j];
|
||||
wt[j]=fabs(ee[j]);
|
||||
sum += wt[j];
|
||||
if (wt[j] > devmax) devmax=wt[j];
|
||||
}
|
||||
e=sum/npt;
|
||||
if (devmax <= dev) {
|
||||
for (j=0;j<ncof;j++) cof[j]=coff[j];
|
||||
dev=devmax;
|
||||
}
|
||||
cout << " ratlsq iteration= " << it;
|
||||
cout << " max error= " << setw(10) << devmax << endl;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user