30long lsfg(
double *xd,
double *yd,
double *sy,
38 double (*fn)(
double x,
long ord)
40 long i, j, unweighted;
42 MATRIX *X = NULL, *Y = NULL, *Yp = NULL, *C = NULL, *C_1 = NULL, *Xt = NULL, *A = NULL, *Ca = NULL, *XtC = NULL, *XtCX = NULL, *T = NULL, *Tt = NULL, *TC = NULL;
45 if (n_pts < n_terms) {
46 printf(
"error: insufficient data for requested order of fit\n");
47 printf(
"(%ld data points, %ld terms in fit)\n", n_pts, n_terms);
53 for (i = 1; i < n_pts; i++)
60 m_alloc(&X, n_pts, n_terms);
61 m_alloc(&Y, n_pts, 1);
62 m_alloc(&Yp, n_pts, 1);
63 m_alloc(&Xt, n_terms, n_pts);
65 m_alloc(&C, n_pts, n_pts);
66 m_alloc(&C_1, n_pts, n_pts);
70 m_alloc(&A, n_terms, 1);
71 m_alloc(&Ca, n_terms, n_terms);
72 m_alloc(&XtC, n_terms, n_pts);
73 m_alloc(&XtCX, n_terms, n_terms);
74 m_alloc(&T, n_terms, n_pts);
75 m_alloc(&Tt, n_pts, n_terms);
76 m_alloc(&TC, n_terms, n_pts);
82 for (i = 0; i < n_pts; i++) {
86 C->a[i][i] = sqr(sy[i]);
87 C_1->a[i][i] = 1 / C->a[i][i];
90 for (j = 0; j < n_terms; j++)
91 x_i[j] = (*fn)(x0, order[j]);
103 { status = p_merror(
"transposing X");
goto cleanup; }
104 if (!m_mult(XtCX, Xt, X))
105 { status = p_merror(
"multiplying Xt.X");
goto cleanup; }
106 if (!m_invert(XtCX, XtCX))
107 { status = p_merror(
"inverting XtCX");
goto cleanup; }
108 if (!m_mult(T, XtCX, Xt))
109 { status = p_merror(
"multiplying XtX.Xt");
goto cleanup; }
110 if (!m_mult(A, T, Y))
111 { status = p_merror(
"multiplying T.Y");
goto cleanup; }
115 { status = p_merror(
"computing transpose of T");
goto cleanup; }
116 if (!m_mult(Ca, T, Tt))
117 { status = p_merror(
"multiplying T.Tt");
goto cleanup; }
118 if (!m_scmul(Ca, Ca, sy ? sqr(sy[0]) : 1))
119 { status = p_merror(
"multiplying T.Tt by scalar");
goto cleanup; }
122 { status = p_merror(
"transposing X");
goto cleanup; }
123 if (!m_mult(XtC, Xt, C_1))
124 { status = p_merror(
"multiplying Xt.C_1");
goto cleanup; }
125 if (!m_mult(XtCX, XtC, X))
126 { status = p_merror(
"multiplying XtC.X");
goto cleanup; }
127 if (!m_invert(XtCX, XtCX))
128 { status = p_merror(
"inverting XtCX");
goto cleanup; }
129 if (!m_mult(T, XtCX, XtC))
130 { status = p_merror(
"multiplying XtCX.XtC");
goto cleanup; }
131 if (!m_mult(A, T, Y))
132 { status = p_merror(
"multiplying T.Y");
goto cleanup; }
135 if (!m_mult(TC, T, C))
136 { status = p_merror(
"multiplying T.C");
goto cleanup; }
138 { status = p_merror(
"computing transpose of T");
goto cleanup; }
139 if (!m_mult(Ca, TC, Tt))
140 { status = p_merror(
"multiplying TC.Tt");
goto cleanup; }
143 for (i = 0; i < n_terms; i++) {
144 coef[i] = A->a[i][0];
145 s_coef[i] = sqrt(Ca->a[i][i]);
149 if (!m_mult(Yp, X, A))
150 { status = p_merror(
"multiplying X.A");
goto cleanup; }
152 for (i = 0; i < n_pts; i++) {
153 xp = (Yp->a[i][0] - yd[i]);
156 xp /= sy ? sy[i] : 1;
159 if (n_pts != n_terms)
160 *chi /= (n_pts - n_terms);
long lsfg(double *xd, double *yd, double *sy, long n_pts, long n_terms, int32_t *order, double *coef, double *s_coef, double *chi, double *diff, double(*fn)(double x, long ord))
Computes generalized least squares fits using a function passed by the caller.