13int p_merror(
char *message);
15long lsfp(
double *xd,
double *yd,
double *sy,
24 long i, j, unweighted;
26 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;
29 if (n_pts < n_terms) {
30 printf(
"error: insufficient data for requested order of fit\n");
31 printf(
"(%ld data points, %ld terms in fit)\n", n_pts, n_terms);
37 for (i = 1; i < n_pts; i++)
44 m_alloc(&X, n_pts, n_terms);
45 m_alloc(&Y, n_pts, 1);
46 m_alloc(&Yp, n_pts, 1);
47 m_alloc(&Xt, n_terms, n_pts);
49 m_alloc(&C, n_pts, n_pts);
50 m_alloc(&C_1, n_pts, n_pts);
54 m_alloc(&A, n_terms, 1);
55 m_alloc(&Ca, n_terms, n_terms);
56 m_alloc(&XtC, n_terms, n_pts);
57 m_alloc(&XtCX, n_terms, n_terms);
58 m_alloc(&T, n_terms, n_pts);
59 m_alloc(&Tt, n_pts, n_terms);
60 m_alloc(&TC, n_terms, n_pts);
66 for (i = 0; i < n_pts; i++) {
70 C->a[i][i] = sqr(sy[i]);
71 C_1->a[i][i] = 1 / C->a[i][i];
74 for (j = 0; j < n_terms; j++)
75 x_i[j] =
ipow(x0, power[j]);
87 { status = p_merror(
"transposing X");
goto cleanup; }
88 if (!m_mult(XtCX, Xt, X))
89 { status = p_merror(
"multiplying Xt.X");
goto cleanup; }
90 if (!m_invert(XtCX, XtCX))
91 { status = p_merror(
"inverting XtCX");
goto cleanup; }
92 if (!m_mult(T, XtCX, Xt))
93 { status = p_merror(
"multiplying XtX.Xt");
goto cleanup; }
95 { status = p_merror(
"multiplying T.Y");
goto cleanup; }
99 { status = p_merror(
"computing transpose of T");
goto cleanup; }
100 if (!m_mult(Ca, T, Tt))
101 { status = p_merror(
"multiplying T.Tt");
goto cleanup; }
102 if (!m_scmul(Ca, Ca, sy ? sqr(sy[0]) : 1))
103 { status = p_merror(
"multiplying T.Tt by scalar");
goto cleanup; }
106 { status = p_merror(
"transposing X");
goto cleanup; }
107 if (!m_mult(XtC, Xt, C_1))
108 { status = p_merror(
"multiplying Xt.C_1");
goto cleanup; }
109 if (!m_mult(XtCX, XtC, X))
110 { status = p_merror(
"multiplying XtC.X");
goto cleanup; }
111 if (!m_invert(XtCX, XtCX))
112 { status = p_merror(
"inverting XtCX");
goto cleanup; }
113 if (!m_mult(T, XtCX, XtC))
114 { status = p_merror(
"multiplying XtCX.XtC");
goto cleanup; }
115 if (!m_mult(A, T, Y))
116 { status = p_merror(
"multiplying T.Y");
goto cleanup; }
119 if (!m_mult(TC, T, C))
120 { status = p_merror(
"multiplying T.C");
goto cleanup; }
122 { status = p_merror(
"computing transpose of T");
goto cleanup; }
123 if (!m_mult(Ca, TC, Tt))
124 { status = p_merror(
"multiplying TC.Tt");
goto cleanup; }
127 for (i = 0; i < n_terms; i++) {
128 coef[i] = A->a[i][0];
129 s_coef[i] = sqrt(Ca->a[i][i]);
133 if (!m_mult(Yp, X, A))
134 { status = p_merror(
"multiplying X.A");
goto cleanup; }
136 for (i = 0; i < n_pts; i++) {
137 xp = (Yp->a[i][0] - yd[i]);
140 xp /= sy ? sy[i] : 1;
143 if (n_terms != n_pts)
144 *chi /= (n_pts - n_terms);
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).