30long lsfg(
double *xd,
double *yd,
double *sy,
38 double (*fn)(
double x,
long ord)
40 long i, j, unweighted;
42 static MATRIX *X, *Y, *Yp, *C, *C_1, *Xt, *A, *Ca, *XtC, *XtCX, *T, *Tt, *TC;
44 if (n_pts < n_terms) {
45 printf(
"error: insufficient data for requested order of fit\n");
46 printf(
"(%ld data points, %ld terms in fit)\n", n_pts, n_terms);
52 for (i = 1; i < n_pts; i++)
59 m_alloc(&X, n_pts, n_terms);
60 m_alloc(&Y, n_pts, 1);
61 m_alloc(&Yp, n_pts, 1);
62 m_alloc(&Xt, n_terms, n_pts);
64 m_alloc(&C, n_pts, n_pts);
65 m_alloc(&C_1, n_pts, n_pts);
69 m_alloc(&A, n_terms, 1);
70 m_alloc(&Ca, n_terms, n_terms);
71 m_alloc(&XtC, n_terms, n_pts);
72 m_alloc(&XtCX, n_terms, n_terms);
73 m_alloc(&T, n_terms, n_pts);
74 m_alloc(&Tt, n_pts, n_terms);
75 m_alloc(&TC, n_terms, n_pts);
81 for (i = 0; i < n_pts; i++) {
85 C->a[i][i] = sqr(sy[i]);
86 C_1->a[i][i] = 1 / C->a[i][i];
89 for (j = 0; j < n_terms; j++)
90 x_i[j] = (*fn)(x0, order[j]);
102 return (p_merror(
"transposing X"));
103 if (!m_mult(XtCX, Xt, X))
104 return (p_merror(
"multiplying Xt.X"));
105 if (!m_invert(XtCX, XtCX))
106 return (p_merror(
"inverting XtCX"));
107 if (!m_mult(T, XtCX, Xt))
108 return (p_merror(
"multiplying XtX.Xt"));
109 if (!m_mult(A, T, Y))
110 return (p_merror(
"multiplying T.Y"));
114 return (p_merror(
"computing transpose of T"));
115 if (!m_mult(Ca, T, Tt))
116 return (p_merror(
"multiplying T.Tt"));
117 if (!m_scmul(Ca, Ca, sy ? sqr(sy[0]) : 1))
118 return (p_merror(
"multiplying T.Tt by scalar"));
121 return (p_merror(
"transposing X"));
122 if (!m_mult(XtC, Xt, C_1))
123 return (p_merror(
"multiplying Xt.C_1"));
124 if (!m_mult(XtCX, XtC, X))
125 return (p_merror(
"multiplying XtC.X"));
126 if (!m_invert(XtCX, XtCX))
127 return (p_merror(
"inverting XtCX"));
128 if (!m_mult(T, XtCX, XtC))
129 return (p_merror(
"multiplying XtCX.XtC"));
130 if (!m_mult(A, T, Y))
131 return (p_merror(
"multiplying T.Y"));
134 if (!m_mult(TC, T, C))
135 return (p_merror(
"multiplying T.C"));
137 return (p_merror(
"computing transpose of T"));
138 if (!m_mult(Ca, TC, Tt))
139 return (p_merror(
"multiplying TC.Tt"));
142 for (i = 0; i < n_terms; i++) {
143 coef[i] = A->a[i][0];
144 s_coef[i] = sqrt(Ca->a[i][i]);
148 if (!m_mult(Yp, X, A))
149 return (p_merror(
"multiplying X.A"));
151 for (i = 0; i < n_pts; i++) {
152 xp = (Yp->a[i][0] - yd[i]);
155 xp /= sy ? sy[i] : 1;
158 if (n_pts != n_terms)
159 *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.