/*************************************************************************\ * 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: savitzkyGolay.c,v $ Revision 1.10 2009/12/02 22:21:27 soliday Removed old complex.h header include statement. Revision 1.9 2007/10/01 20:38:02 ywang25 fixed the bug for the cases when the derivative is not zero Revision 1.7 2007/09/05 14:38:10 ywang25 The smoothing procedure will be done the time domain, which is more efficient than in the frequency domain, especially for order=1. Revision 1.6 2007/04/16 18:48:28 soliday Removed SDDS calls. Revision 1.5 2003/08/28 22:12:31 soliday Cleaned up the code. Revision 1.4 2002/08/14 16:48:28 soliday Added Open License Revision 1.3 2002/06/19 23:12:36 borland Fixed spelling of Savitzky-Golay. Revision 1.2 2000/08/09 22:15:32 soliday Commited the changes made my Borland. Revision 1.1 2000/04/11 16:23:45 soliday Moved here from mdbmth. Revision 1.2 1999/07/16 14:06:04 borland Added padding of the data prior to smoothing to avoid end effects. Revision 1.1 1999/06/21 20:39:27 borland First version. * Michael Borland, 1999. */ #include "matlib.h" #include "mdb.h" #include "fftpackC.h" long SavitzkyGolaySmooth(double *data, long rows, long order, long nLeft, long nRight, long derivativeOrder) { static double *FFTdata=NULL, *FFTfilter=NULL, *TMPdata=NULL; static long arraySize = 0, TMParraySize = 0; long i, nfreq, sizeNeeded; if (order<0) { fprintf(stderr, "order<0 (SavitzkyGolaySmooth)\n"); return(0); } if (nLeft<0) { fprintf(stderr, "nLeft<0 (SavitzkyGolaySmooth)\n"); return(0); } if (nRight<0) { fprintf(stderr, "nRight<0 (SavitzkyGolaySmooth)\n"); return(0); } if (derivativeOrder<0) { fprintf(stderr, "derivativeOrder<0 (SavitzkyGolaySmooth)\n"); return(0); } if (derivativeOrder>order) { fprintf(stderr, "derivativeOrder>order (SavitzkyGolaySmooth)\n"); return(0); } if ((nLeft+nRight)order || (nLeft+nRight)a[i+nLeft][j] = factor; factor *= i; } } if (!m_trans(At, A) || !m_mult(AtA, At, A) || !m_invert(AtA, AtA)) { fprintf(stderr, "Error: matrix manipulation problem (savitzkyGolayCoefficients)\n"); exit(1); } if (!(svCoef = realloc(svCoef, sizeof(*svCoef)*(nSVCoef+1))) || !(svCoef[nSVCoef].coef = malloc(sizeof(*svCoef[nSVCoef].coef)*(nRight+nLeft+1)))) { fprintf(stderr, "Error: memory allocation failure (savitzkyGolayCoefficients)\n"); exit(1); } svCoef[nSVCoef].left = nLeft; svCoef[nSVCoef].right = nRight; svCoef[nSVCoef].derivOrder = derivativeOrder; svCoef[nSVCoef].order = order; for (i=-nLeft; i<=nRight; i++) { if (wrapAround) { if (i<=0) iStore = -i; else iStore = maxCoefs-i; } else iStore = i+nLeft; coef[iStore] = 0; factor = 1; for (m=0; m<=order; m++) { coef[iStore] += AtA->a[derivativeOrder][m]*factor; factor *= i; } svCoef[nSVCoef].coef[i+nLeft] = coef[iStore]; } nSVCoef ++; m_free(&A); m_free(&At); m_free(&AtA); }