W dniu 07.04.2011 23:22, Dominik Wójt pisze:
> W dniu 07.04.2011 23:12, Dominik Wójt pisze:
>   
>> Hello,
>>
>> I have a problem with smoothing out my data when it is more than 3000
>> points long. Code is copied from example in documentation.
>>
>> I attach the data set which I want to smooth out. Its enough to shorten
>> it to e.g. 800 point and it works properly.
>> The source code is also attached.
>>
>> Is there a way around? Should I divide the data into chunks? If so is
>> there a way not to get discontinuities on the joints?
>>
>> Thank you in advance, regards,
>> Dominik Wójt
>>
>> _______________________________________________
>> Help-gsl mailing list
>> Help-gsl@gnu.org
>> http://lists.gnu.org/mailman/listinfo/help-gsl
>>   
>>     
> As usually forgot the attachment ;)
>   
>
>
> _______________________________________________
> Help-gsl mailing list
> Help-gsl@gnu.org
> http://lists.gnu.org/mailman/listinfo/help-gsl
>   
I'm back. The solution I found might not be perfect but it works for me.
I divided my data into chunks 100 points each + 2*20 points overlapping
with neighbours to keep my curve smooth. I attach the modified smooth.cc

I think this is quite common problem, shouldn't there exist a solution
in the library?

Sorry if I create unnecessary  load on the list. Maybe someone will
benefit from the solution.

Regards,
Dominik Wójt
#include "smooth.h"
#include "vicinity.h"

#include <iostream>
#include <algorithm>

#include <gsl/gsl_vector.h>
#include <gsl/gsl_bspline.h>
#include <gsl/gsl_multifit.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_statistics.h>

void smooth( const std::vector<double> &x, const std::vector<double> &y, std::vector<double> &smoothed_y, int param ) throw ( TError_Generic_error ) {
    if( x.size() < size_t( param*2 ) )
        throw TError_Generic_error( "Not enough elements in vecotr x" );
    if( x.size() != y.size() )
        throw TError_Generic_error( "x.size() != y.size() in smooth(...)" );

    using std::max;
    using std::min;

    const size_t chunk_size = 100,
                 chunk_overlap = 20;

    smoothed_y.resize( y.size() );

    for( size_t k=0; k<x.size(); k+=chunk_size )
    {
        // this part will be written
        size_t chunk_start = k;
        size_t chunk_end   = min( k+chunk_size, x.size() );
        // this part is used in calculation to ensure continuity
        // chunk_overlap_end - chunk_overlap_start is guaranteed to be at least chunk_overlap long provided the x.size()>=chunk_overlap
        size_t chunk_overlap_start = max( chunk_overlap, chunk_start )-chunk_overlap;
        size_t chunk_overlap_end   = min( chunk_end+chunk_overlap, x.size() );

        size_t n = chunk_overlap_end-chunk_overlap_start;
        gsl_vector_const_view gV_x  = gsl_vector_const_view_array( &x[chunk_overlap_start], n );
        gsl_vector_const_view gV_y  = gsl_vector_const_view_array( &y[chunk_overlap_start], n );
        gsl_vector_view       gV_sy = gsl_vector_view_array      ( &smoothed_y[chunk_overlap_start], n );


        size_t ncoeffs = n/param;
        size_t nbreak = ncoeffs - 2;
        gsl_bspline_workspace *bw;
        gsl_vector *B;
        gsl_vector *c;
        const gsl_vector *gx, *gy;
        gsl_matrix *X, *cov;
        gsl_multifit_linear_workspace *mw;
        double chisq;//, Rsq, dof, tss;

        /* allocate a cubic bspline workspace (k = 4) */
        bw = gsl_bspline_alloc(4, nbreak);
        B = gsl_vector_alloc(ncoeffs);

        gx = &gV_x.vector;
        gy = &gV_y.vector;

        X = gsl_matrix_alloc(n, ncoeffs);
        c = gsl_vector_alloc(ncoeffs);
        cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
        mw = gsl_multifit_linear_alloc(n, ncoeffs);

        /* use uniform breakpoints */
        gsl_bspline_knots_uniform(x[chunk_overlap_start], x[chunk_overlap_end-1], bw);

        /* construct the fit matrix X */
        for( size_t i = 0; i < n; ++i ) {
            double xi = gsl_vector_get(gx, i);

            /* compute B_j(xi) for all j */
            gsl_bspline_eval(xi, B, bw);

            /* fill in row i of X */
            for( size_t j=0; j < ncoeffs; ++j ) {
                double Bj = gsl_vector_get(B, j);
                gsl_matrix_set(X, i, j, Bj);
            }
        }

        /* do the fit */
        //size_t rank;
        gsl_multifit_linear(X, gy, c, cov, &chisq, mw);

        /*        dof = n - ncoeffs;
                tss = gsl_stats_wtss(w->data, 1, gy->data, 1, gy->size);
                Rsq = 1.0 - chisq / tss;

                fprintf(stderr, "chisq/dof = %e, Rsq = %f\n",
                        chisq / dof, Rsq);
        */
        /* output the smoothed curve */
        {
            double yi, yerr;

            //printf("#m=1,S=0\n");
            for( size_t i=chunk_start; i<chunk_end; i++ ) {
                gsl_bspline_eval(x[i], B, bw);
                gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
                smoothed_y[i] = yi;
            }
        }

        gsl_bspline_free(bw);
        gsl_vector_free(B);
        gsl_matrix_free(X);
        gsl_vector_free(c);
        gsl_matrix_free(cov);
        gsl_multifit_linear_free(mw);

    }
}
_______________________________________________
Help-gsl mailing list
Help-gsl@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gsl

Reply via email to