/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ /* $Log: lsfn.c,v $ Revision 1.4 2008/08/05 19:08:23 borland Added checks for null pointers in lsfn(). Revision 1.3 2002/08/14 16:48:28 soliday Added Open License Revision 1.2 2001/04/30 21:58:34 borland It is now acceptable for the sigma-y array to be NULL. Revision 1.1 2000/04/11 16:23:01 soliday Moved here from mdbmth. Revision 1.2 1995/09/05 21:20:23 saunders First test release of the SDDS1.5 package. */ /* routine: lsfn() * purpose: compute nth order polynomial least squares. * * Michael Borland, 1986. */ #include "matlib.h" #include "mdb.h" int p_merror(char *message); long lsfn( double *xd, double *yd, double *sy, /* data */ long nd, /* number of data points */ long nf, /* y = a_0 + a_1*x ... a_nf*x^nf */ double *coef, /* place to put co-efficients */ double *s_coef, /* and their sigmas */ double *chi, /* place to put reduced chi-squared */ double *diff /* place to put difference table */ ) { long i, j, nt, unweighted; double xp, *x_i, x0; static MATRIX *X, *Y, *Yp, *C, *C_1, *Xt, *A, *Ca, *XtC, *XtCX, *T, *Tt, *TC; nt = nf + 1; if (nda[i]; x0 = xd[i]; xp = 1.0; Y->a[i][0] = yd[i]; if (!unweighted) { C->a[i][i] = sqr(sy[i]); C_1->a[i][i] = 1/C->a[i][i]; } for (j=0; ja[i][0]; if (s_coef) s_coef[i] = sqrt(Ca->a[i][i]); } /* Compute Yp = X.A, use to compute chi-squared */ if (chi) { if (!m_mult(Yp, X, A)) return(p_merror("multiplying X.A")); *chi = 0; for (i=0; ia[i][0] - yd[i]); if (diff!=NULL) diff[i] = xp; xp /= sy?sy[i]:1; *chi += xp*xp; } if (nd!=nt) *chi /= (nd-nt); } m_free(&X); m_free(&Y); m_free(&Yp); m_free(&Xt); if (!unweighted) { m_free(&C); m_free(&C_1); } m_free(&A); m_free(&Ca); m_free(&XtC); m_free(&XtCX); m_free(&T); m_free(&Tt); m_free(&TC); return(1); }