예제 #1
0
파일: resamp2.c 프로젝트: GRDSP/grdsp
// create a resamp2 object
//  _m      :   filter semi-length (effective length: 4*_m+1)
//  _fc     :   center frequency of half-band filter
//  _As     :   stop-band attenuation [dB], _As > 0
RESAMP2() RESAMP2(_create)(unsigned int _m,
                           float        _fc,
                           float        _As)
{
    // validate input
    if (_m < 2) {
        fprintf(stderr,"error: resamp2_%s_create(), filter semi-length must be at least 2\n", EXTENSION_FULL);
        exit(1);
    }

    RESAMP2() q = (RESAMP2()) malloc(sizeof(struct RESAMP2(_s)));
    q->m  = _m;
    q->fc = _fc;
    q->As = _As;
    if ( q->fc < -0.5f || q->fc > 0.5f ) {
        fprintf(stderr,"error: resamp2_%s_create(), fc (%12.4e) must be in (-1,1)\n", EXTENSION_FULL, q->fc);
        exit(1);
    }

    // change filter length as necessary
    q->h_len = 4*(q->m) + 1;
    q->h = (TC *) malloc((q->h_len)*sizeof(TC));

    q->h1_len = 2*(q->m);
    q->h1 = (TC *) malloc((q->h1_len)*sizeof(TC));

    // design filter prototype
    unsigned int i;
    float t, h1, h2;
    TC h3;
    float beta = kaiser_beta_As(q->As);
    for (i=0; i<q->h_len; i++) {
        t = (float)i - (float)(q->h_len-1)/2.0f;
        h1 = sincf(t/2.0f);
        h2 = kaiser(i,q->h_len,beta,0);
#if TC_COMPLEX == 1
        h3 = cosf(2.0f*M_PI*t*q->fc) + _Complex_I*sinf(2.0f*M_PI*t*q->fc);
#else
        h3 = cosf(2.0f*M_PI*t*q->fc);
#endif
        q->h[i] = h1*h2*h3;
    }

    // resample, alternate sign, [reverse direction]
    unsigned int j=0;
    for (i=1; i<q->h_len; i+=2)
        q->h1[j++] = q->h[q->h_len - i - 1];

    // create dotprod object
    q->dp = DOTPROD(_create)(q->h1, 2*q->m);

    // create window buffers
    q->w0 = WINDOW(_create)(2*(q->m));
    q->w1 = WINDOW(_create)(2*(q->m));

    RESAMP2(_clear)(q);

    return q;
}
// parameterized function
float gsfunc(float _x, float * _v)
{
    float c0 = _v[0];
    float c1 = _v[1];
    float c2 = _v[2];

    return c0 + sincf(c1*(_x-c2));
}
예제 #3
0
파일: firdes.c 프로젝트: 0xLeo/liquid-dsp
// Design FIR using kaiser window
//  _n      : filter length, _n > 0
//  _fc     : cutoff frequency, 0 < _fc < 0.5
//  _As     : stop-band attenuation [dB], _As > 0
//  _mu     : fractional sample offset, -0.5 < _mu < 0.5
//  _h      : output coefficient buffer, [size: _n x 1]
void liquid_firdes_kaiser(unsigned int _n,
                          float _fc,
                          float _As,
                          float _mu,
                          float *_h)
{
    // validate inputs
    if (_mu < -0.5f || _mu > 0.5f) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), _mu (%12.4e) out of range [-0.5,0.5]\n", _mu);
        exit(1);
    } else if (_fc < 0.0f || _fc > 0.5f) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), cutoff frequency (%12.4e) out of range (0, 0.5)\n", _fc);
        exit(1);
    } else if (_n == 0) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), filter length must be greater than zero\n");
        exit(1);
    }

    // choose kaiser beta parameter (approximate)
    float beta = kaiser_beta_As(_As);

    float t, h1, h2; 
    unsigned int i;
    for (i=0; i<_n; i++) {
        t = (float)i - (float)(_n-1)/2 + _mu;
     
        // sinc prototype
        h1 = sincf(2.0f*_fc*t);

        // kaiser window
        h2 = kaiser(i,_n,beta,_mu);

        //printf("t = %f, h1 = %f, h2 = %f\n", t, h1, h2);

        // composite
        _h[i] = h1*h2;
    }
}
int main() {
    // options
    unsigned int num_samples = 400;     // number of samples
    float sig = 0.1f;                   // noise variance
    unsigned int num_iterations = 1000; // number of iterations to run

    float v[3] = {1, 1, 1};
    unsigned int i;

    // range
    float xmin = 0.0f;
    float xmax = 6.0f;
    float dx = (xmax - xmin) / (num_samples-1);

    // generate data set
    float x[num_samples];
    float y[num_samples];
    for (i=0; i<num_samples; i++) {
        x[i] = xmin + i*dx;
        y[i] = sincf(x[i]) + randnf()*sig;
    }
    struct gsdataset q = {x, y, num_samples};

    // create gradsearch object
    gradsearchprops_s gsprops;
    gradsearchprops_init_default(&gsprops);
    gsprops.delta = 1e-6f;  // gradient approximation step size
    gsprops.gamma = 0.002f; // vector step size
    gsprops.alpha = 0.1f;   // momentum parameter
    gsprops.mu    = 0.999f; // decremental gamma paramter (best if not exactly 1.0)

    gradsearch gs = gradsearch_create((void*)&q, v, 3, gserror, LIQUID_OPTIM_MINIMIZE, &gsprops);

    float rmse;

    // execute search
    //rmse = gradsearch_run(gs, num_iterations, -1e-6f);

     // open output file
    FILE*fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n");

   // execute search one iteration at a time
    fprintf(fid,"u = zeros(1,%u);\n", num_iterations);
    for (i=0; i<num_iterations; i++) {
        rmse = gserror((void*)&q,v,3);
        fprintf(fid,"u(%3u) = %12.4e;\n", i+1, rmse);

        gradsearch_step(gs);

        if (((i+1)%100)==0)
            gradsearch_print(gs);
    }

    // print results
    printf("\n");
    gradsearch_print(gs);
    printf("  c0 = %12.8f, opt = 1\n", v[0]);
    printf("  c1 = %12.8f, opt = 0\n", v[1]);
    printf("  c2 = %12.8f, opt = 1\n", v[2]);
    printf("  rmse = %12.4e\n", rmse);

    fprintf(fid,"figure;\n");
    fprintf(fid,"semilogy(u);\n");
    fprintf(fid,"xlabel('iteration');\n");
    fprintf(fid,"ylabel('error');\n");
    fprintf(fid,"title('gradient search results');\n");
    fprintf(fid,"grid on;\n");

    // save sampled data set
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"  x(%4u) = %12.8f;\n", i+1, x[i]);
        fprintf(fid,"  y(%4u) = %12.8f;\n", i+1, y[i]);
        fprintf(fid,"  y_hat(%4u) = %12.8f;\n", i+1, gsfunc(x[i],v));
    }
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(x,y,'x', x,y_hat,'-');\n");
    fprintf(fid,"xlabel('x');\n");
    fprintf(fid,"ylabel('f(x)');\n");
    fprintf(fid,"grid on;\n");
    fprintf(fid,"legend('data','fit',1);\n");


    fclose(fid);
    printf("results written to %s.\n", OUTPUT_FILENAME);

    gradsearch_destroy(gs);

    return 0;
}
예제 #5
0
//
// AUTOTEST: sincf
//
void autotest_sincf()
{
    float tol = 1e-3f;
    CONTEND_DELTA(sincf(0.0f), 1.0f, tol);
}