27 static double *vector(
int n) {
30 b = (
double *) malloc(
sizeof(
double) *
n);
38 static double **matrix(
int n1,
int n2)
45 m = (
double **) malloc(
sizeof(
double *) * (n1 + 1));
51 for(i = 0; i < n1; i++) {
52 m[i] = (
double *) malloc(
sizeof(
double) * n2);
62 static void free_matrix(
double **m)
83 double **u,
double w[],
double **v,
int m,
int n,
double b[],
double x[]) {
88 for(j = 1; j <=
n; j++) {
91 for(i = 1; i <= m; i++) s += u[i][j] * b[i];
96 for(j = 1; j <=
n; j++) {
98 for(jj = 1; jj <=
n; jj++) s += v[j][jj] * tmp[jj];
112 static double maxarg1, maxarg2;
113 #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
114 (maxarg1) : (maxarg2))
116 static int iminarg1, iminarg2;
117 #define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\
118 (iminarg1) : (iminarg2))
120 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
122 static double sqrarg;
123 #define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
125 static double pythag(
double a,
double b) {
129 if(absa > absb)
return absa *
sqrt(1.0 +
SQR(absb / absa));
130 else return (absb == 0.0 ? 0.0 : absb *
sqrt(1.0 +
SQR(absa / absb)));
133 static void svdcmp(
double **a,
int m,
int n,
double w[],
double **v) {
134 int flag, i, its, j, jj, k, l, nm = 0;
135 double anorm,
c, f, g, h, s, scale, x, y, z, *rv1;
138 g = scale = anorm = 0.0;
139 for(i = 1; i <=
n; i++) {
144 for(k = i; k <= m; k++) scale +=
fabs(a[k][i]);
146 for(k = i; k <= m; k++) {
148 s += a[k][i] * a[k][i];
154 for(j = l; j <=
n; j++) {
155 for(s = 0.0, k = i; k <= m; k++) s += a[k][i] * a[k][j];
157 for(k = i; k <= m; k++) a[k][j] += f * a[k][i];
159 for(k = i; k <= m; k++) a[k][i] *= scale;
164 if(i <= m && i != n) {
165 for(k = l; k <=
n; k++) scale +=
fabs(a[i][k]);
167 for(k = l; k <=
n; k++) {
169 s += a[i][k] * a[i][k];
175 for(k = l; k <=
n; k++) rv1[k] = a[i][k] / h;
176 for(j = l; j <= m; j++) {
177 for(s = 0.0, k = l; k <=
n; k++) s += a[j][k] * a[i][k];
178 for(k = l; k <=
n; k++) a[j][k] += s * rv1[k];
180 for(k = l; k <=
n; k++) a[i][k] *= scale;
185 for(i = n; i >= 1; i--) {
188 for(j = l; j <=
n; j++)
189 v[j][i] = (a[i][j] / a[i][l]) / g;
190 for(j = l; j <=
n; j++) {
191 for(s = 0.0, k = l; k <=
n; k++) s += a[i][k] * v[k][j];
192 for(k = l; k <=
n; k++) v[k][j] += s * v[k][i];
195 for(j = l; j <=
n; j++) v[i][j] = v[j][i] = 0.0;
201 for(i =
IMIN(m, n); i >= 1; i--) {
204 for(j = l; j <=
n; j++) a[i][j] = 0.0;
207 for(j = l; j <=
n; j++) {
208 for(s = 0.0, k = l; k <= m; k++) s += a[k][i] * a[k][j];
209 f = (s / a[i][i]) * g;
210 for(k = i; k <= m; k++) a[k][j] += f * a[k][i];
212 for(j = i; j <= m; j++) a[j][i] *= g;
213 }
else for(j = i; j <= m; j++) a[j][i] = 0.0;
216 for(k = n; k >= 1; k--) {
217 for(its = 1; its <= 30; its++) {
219 for(l = k; l >= 1; l--) {
221 if((
double)(
fabs(rv1[l]) + anorm) == anorm) {
225 if((
double)(
fabs(w[nm]) + anorm) == anorm)
break;
230 for(i = l; i <= k; i++) {
233 if((
double)(
fabs(f) + anorm) == anorm)
break;
240 for(j = 1; j <= m; j++) {
243 a[j][nm] = y * c + z * s;
244 a[j][i] = z * c - y * s;
252 for(j = 1; j <=
n; j++) v[j][k] = -v[j][k];
258 writeBetError(
"svdfit() no convergence in 30 svdcmp iterations");
265 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
267 f = ((x - z) * (x + z) + h * ((y / (f +
SIGN(g, f))) - h)) / x;
269 for(j = l; j <= nm; j++) {
283 for(jj = 1; jj <=
n; jj++) {
286 v[jj][j] = x * c + z * s;
287 v[jj][i] = z * c - x * s;
298 for(jj = 1; jj <= m; jj++) {
301 a[jj][j] = y * c + z * s;
302 a[jj][i] = z * c - y * s;
332 double x[],
double y[],
double sig[],
int ndata,
double a[],
int ma,
333 double **u,
double **v,
double w[],
double *chisq,
334 void (*funcs)(
double,
double [],
int)) {
336 double wmax, tmp, thresh,
sum, *b, *afunc;
338 b = vector(ndata + 1);
339 afunc = vector(ma + 1);
340 for(i = 1; i <= ndata; i++) {
341 (*funcs)(x[i], afunc, ma);
343 for(j = 1; j <= ma; j++) u[i][j] = afunc[j] * tmp;
346 svdcmp(u, ndata, ma, w, v);
348 for(j = 1; j <= ma; j++)
349 if(w[j] > wmax) wmax = w[j];
351 for(j = 1; j <= ma; j++)
352 if(w[j] < thresh) w[j] = 0.0;
353 svbksb(u, w, v, ndata, ma, b, a);
355 for(i = 1; i <= ndata; i++) {
356 (*funcs)(x[i], afunc, ma);
357 for(sum = 0.0, j = 1; j <= ma; j++) sum += a[j] * afunc[j];
358 *chisq += (tmp = (y[i] -
sum) / sig[i], tmp * tmp);
370 void svdvar(
double **v,
int ma,
double w[],
double **cvm) {
374 wti = vector(ma + 1);
375 for(i = 1; i <= ma; i++) {
377 if(w[i]) wti[i] = 1.0 / (w[i] * w[i]);
379 for(i = 1; i <= ma; i++) {
380 for(j = 1; j <= i; j++) {
381 for(sum = 0.0, k = 1; k <= ma; k++) sum += v[i][k] * v[j][k] * wti[k];
382 cvm[j][i] = cvm[i][j] =
sum;
402 static void (*theFuncs)(double,
double *, int);
404 static void locFuncs(
double x,
double *p,
int n) {
405 theFuncs(x, p + 1, n);
410 double *x,
double *y,
double *sig,
int ndata,
double *a,
int ma,
411 double *err,
double *chisq,
412 void (*funcs)(
double,
double *,
int)) {
416 *w = vector(ndata + 1),
417 **u = matrix(ndata + 1, ma + 1),
418 **v = matrix(ndata + 1, ma + 1),
419 **cvm = matrix(ma + 1, ma + 1);
426 svdfit1(x - 1, y - 1, sig - 1, ndata, a - 1, ma, u, v, w, chisq, locFuncs);
431 for(i = 0; i < ma; i++) {
432 err[i] = cvm[i+1][i+1];
445 double *x,
double *y,
int ndata,
double *a,
int ma,
446 double *err,
double *chisq,
447 void (*funcs)(
double,
double *,
int)) {
450 *sig = (
double *) malloc(
sizeof(
double) * ndata);
452 for(i = 0; i < ndata; i++) sig[i] = 1.0;
454 svdfit(x, y, sig, ndata, a, ma, err, chisq, funcs);
462 static void fpoly(
double x,
double p[],
int np) {
466 for(j = 1; j < np; j++) p[j] = p[j-1] * x;
472 double *x,
double *y,
int ndata,
double *a,
int ma,
473 double *err,
double *chisq) {
474 svdfit(x, y, ndata, a, ma, err, chisq, fpoly);
void svdvar(double **v, int ma, double w[], double **cvm)
void svdfitP(double *x, double *y, int ndata, double *a, int ma, double *err, double *chisq)
void writeBetError(std::string err)
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
void svdfit(double *x, double *y, double *sig, int ndata, double *a, int ma, double *err, double *chisq, void(*funcs)(double, double *, int))
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
constexpr double c
The velocity of light in m/s.
Tps< T > sqrt(const Tps< T > &x)
Square root.