-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathfitsvd.h
executable file
·65 lines (59 loc) · 1.55 KB
/
fitsvd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
struct Fitsvd {
Int ndat, ma;
Doub tol;
VecDoub_I *x,&y,&sig;
VecDoub (*funcs)(const Doub);
VecDoub a;
MatDoub covar;
Doub chisq;
Fitsvd(VecDoub_I &xx, VecDoub_I &yy, VecDoub_I &ssig,
VecDoub funks(const Doub), const Doub TOL=1.e-12)
: ndat(yy.size()), x(&xx), xmd(NULL), y(yy), sig(ssig),
funcs(funks), tol(TOL) {}
void fit() {
Int i,j,k;
Doub tmp,thresh,sum;
if (x) ma = funcs((*x)[0]).size();
else ma = funcsmd(row(*xmd,0)).size();
a.resize(ma);
covar.resize(ma,ma);
MatDoub aa(ndat,ma);
VecDoub b(ndat),afunc(ma);
for (i=0;i<ndat;i++) {
if (x) afunc=funcs((*x)[i]);
else afunc=funcsmd(row(*xmd,i));
tmp=1.0/sig[i];
for (j=0;j<ma;j++) aa[i][j]=afunc[j]*tmp;
b[i]=y[i]*tmp;
}
SVD svd(aa);
thresh = (tol > 0. ? tol*svd.w[0] : -1.);
svd.solve(b,a,thresh);
chisq=0.0;
for (i=0;i<ndat;i++) {
sum=0.;
for (j=0;j<ma;j++) sum += aa[i][j]*a[j];
chisq += SQR(sum-b[i]);
}
for (i=0;i<ma;i++) {
for (j=0;j<i+1;j++) {
sum=0.0;
for (k=0;k<ma;k++) if (svd.w[k] > svd.tsh)
sum += svd.v[i][k]*svd.v[j][k]/SQR(svd.w[k]);
covar[j][i]=covar[i][j]=sum;
}
}
}
MatDoub_I *xmd;
VecDoub (*funcsmd)(VecDoub_I &);
Fitsvd(MatDoub_I &xx, VecDoub_I &yy, VecDoub_I &ssig,
VecDoub funks(VecDoub_I &), const Doub TOL=1.e-12)
: ndat(yy.size()), x(NULL), xmd(&xx), y(yy), sig(ssig),
funcsmd(funks), tol(TOL) {}
VecDoub row(MatDoub_I &a, const Int i) {
Int j,n=a.ncols();
VecDoub ans(n);
for (j=0;j<n;j++) ans[j] = a[i][j];
return ans;
}
};