#include #include #include #include "utils.h" extern float pi; extern no_error; #define MAX_ORDER 20 /*....................................................................... This routine decomposes the fourier series from data supplied by the user. The x and y data arrays are passed to the function along with the number of points in them and the period of the fundamental. The max_order, amplitudes and phases are returned in arrays asum[] and bsum[] (asum[] and bsum[] are also used to accumulate the fourier A and B coefficients from which the amplitudes and phases are then determined. The data need not be sampled upon a regular grid. To ensure orthogonality, the integrations are performed assuming that straight lines connect each data point. Thus for instance to integrate data(x=XA) to data(x=XB) multiplied by sin(x) the integral of (line_connecting_XA_to_XB)*sin(x) is evaluated from XA to XB. The output of the routine goes to the user variables AMP(n) and PHASE(n), each element of said holding the fourier n'th component. The user may then evaluate the Fourier series using these components via the user function FVAL(x). (Subroutine FEVAL). */ int fourier_series(float x_data[], float y_data[], int npts, float period, float asum[], float bsum[], int max_order) { /* Local declarations. */ float xa, xb, ya, yb, yend,pgrad,rl, omega,xstart; double ph_a, ph_b; const float twopi = 6.2831853; int last,k,l; /* Check the PERIOD value. */ if(period <= 0.0) { lprintf(stderr, "four: Illegal period given: %f\n", period); return -1; }; /* Check that the data are in increasing order. */ for(k=1; k=1, the series value, the integral, or the first derivatives are returned respectively. */ int fourier_series_value(float xval, float *yval, int differential_order, float period, float amp[], float phase[], float filter[], int max_order) { /* Local declarations. */ static float omega,tmp,harm,ampl; static int l; const float twopi = 6.2831853; /* Check the period value. */ if(period <= 0.0) { lprintf(stderr, "fsval: Illegal period given: %f\n", period); return -1; }; /* Evaluate the fourier series on the input time grid. */ omega = twopi/period; /* Start with the contribution from the DC (freq=0) term. Get the relevant value depending upon the diffential order. -ve orders mean integrate. */ switch (differential_order) { /* 0'th order. DC term contributes directly. */ case 0: *yval = amp[0] * filter[0]; break; /* For derivatives the zero frequency term makes no contribution. */ case 1: case 2: *yval = 0.0; break; /* In the integral the DC term integrates to amplitude * time. */ case -1: *yval = amp[0] * filter[0] * (xval-phase[0]); break; default: lprintf(stderr, "fsval: Unsupported differential order: %d\n", differential_order); return -1; break; }; /* Add in the subsequent harmonics one at a time. */ for(l=1; l