Example #1
0
/**
 * Return the minimum size of input points for linear interpolation.
 * @return the minimum number of points
 */
size_t minSizeForLinearInterpolation() {
  return gsl_interp_type_min_size(gsl_interp_linear);
}
Example #2
0
File: build.c Project: IlariaD/ssm
ssm_calc_t *ssm_calc_new(json_t *jdata, ssm_nav_t *nav, ssm_data_t *data, ssm_fitness_t *fitness, ssm_options_t *opts, int thread_id)
{
    ssm_calc_t *calc = malloc(sizeof (ssm_calc_t));
    if (calc==NULL) {
        char str[SSM_STR_BUFFSIZE];
        snprintf(str, SSM_STR_BUFFSIZE, "Allocation impossible for ssm_calc_t (thread_id: %d)", thread_id);
        ssm_print_err(str);
        exit(EXIT_FAILURE);
    }

    /***********/
    /* threads */
    /***********/

    calc->threads_length = ssm_sanitize_n_threads(opts->n_thread, fitness);
    calc->thread_id = thread_id;

    /******************/
    /* random numbers */
    /******************/

    //  random number generator and parallel MC simulations:
    //
    //  idea using one different seed per thread but is it realy uncorelated ???
    //  Should I go through the trouble of changing from GSL to SPRNG????
    //  answer:
    //  I would recommend using ranlxd.  The seeds should give 2^31
    //  effectively independent streams of length 10^171.  A discussion of the
    //  seeding procedure can be found in the file notes.ps at
    //  http://www.briangough.ukfsn.org/ranlux_2.2/
    //  --
    //  Brian Gough
    //
    //  => we create as many rng as parallel threads *but* note that for
    //  the operations not prarallelized, we always use
    //  cacl[0].randgsl


    const gsl_rng_type *Type;
    if (calc->threads_length == 1){ //we don't need a rng supporting parallel computing, we use mt19937 that is way faster than ranlxs0 (1754 k ints/sec vs 565 k ints/sec)
        Type = gsl_rng_mt19937; /*MT19937 generator of Makoto Matsumoto and Takuji Nishimura*/
    } else {
        Type = gsl_rng_ranlxs0; //gsl_rng_ranlxs2 is better than gsl_rng_ranlxs0 but 2 times slower
    }

    unsigned long int seed;
    if(opts->flag_seed_time){
        seed = (unsigned) time(NULL);
    } else{
        seed=2;
    }
    calc->seed =  seed + opts->id; /*we ensure uniqueness of seed in case of parrallel runs*/

    calc->randgsl = gsl_rng_alloc(Type);
    gsl_rng_set(calc->randgsl, calc->seed + thread_id);

    /*******************/
    /* implementations */
    /*******************/
    int dim = _ssm_dim_X(nav);

    if (nav->implementation == SSM_ODE || nav->implementation == SSM_EKF){

        calc->T = gsl_odeiv2_step_rkf45;
        calc->control = gsl_odeiv2_control_y_new(opts->eps_abs, opts->eps_rel);
        calc->step = gsl_odeiv2_step_alloc(calc->T, dim);
        calc->evolve = gsl_odeiv2_evolve_alloc(dim);
        (calc->sys).function =  (nav->implementation == SSM_ODE) ? &ssm_step_ode: &ssm_step_ekf;
        (calc->sys).jacobian = NULL;
        (calc->sys).dimension= dim;
        (calc->sys).params= calc;

        if(nav->implementation == SSM_EKF){

            int can_run;

            if ( (nav->noises_off & (SSM_NO_DEM_STO)) && (nav->noises_off & (SSM_NO_WHITE_NOISE)) )  {
                calc->eval_Q = &ssm_eval_Q_no_dem_sto_no_env_sto;
                can_run = 0;
            } else if ((nav->noises_off & SSM_NO_DEM_STO) && !(nav->noises_off & SSM_NO_WHITE_NOISE)) {
                calc->eval_Q = &ssm_eval_Q_no_dem_sto;
                can_run = nav->par_noise->length;
            } else if (!(nav->noises_off & SSM_NO_DEM_STO) && (nav->noises_off & SSM_NO_WHITE_NOISE)) {
                calc->eval_Q = &ssm_eval_Q_no_env_sto;
                can_run = 1;
            } else {
                calc->eval_Q = &ssm_eval_Q_full;
                can_run = 1;
            }

            if(!(nav->noises_off & SSM_NO_DIFF)){
                can_run += nav->states_diff->length;
            }

            if(!can_run){
                ssm_print_err("Kalman methods must be used with at least one source of stochasticity in the process.");
                exit(EXIT_FAILURE);
            }

            int n_s = nav->states_sv_inc->length + nav->states_diff->length;
            int n_o = nav->observed_length;
            calc->_pred_error = gsl_vector_calloc(n_o);
            calc->_zero = gsl_vector_calloc(n_o);
            calc->_St = gsl_matrix_calloc(n_o, n_o);
            calc->_Stm1 = gsl_matrix_calloc(n_o, n_o);
            calc->_Rt = gsl_matrix_calloc(n_o, n_o);
            calc->_Ht = gsl_matrix_calloc(n_s, n_o);
            calc->_Kt = gsl_matrix_calloc(n_s, n_o);
            calc->_Tmp_N_SV_N_TS = gsl_matrix_calloc(n_s, n_o);
            calc->_Tmp_N_TS_N_SV = gsl_matrix_calloc(n_o, n_s);
            calc->_Q = gsl_matrix_calloc(n_s, n_s);
            calc->_FtCt = gsl_matrix_calloc(n_s, n_s);
            calc->_Ft = gsl_matrix_calloc(n_s, n_s);
            calc->_eval = gsl_vector_calloc(n_s);
            calc->_evec = gsl_matrix_calloc(n_s, n_s);
            calc->_w_eigen_vv = gsl_eigen_symmv_alloc(n_s);
        }

    } else if (nav->implementation == SSM_SDE){
        calc->y_pred = ssm_d1_new(dim);
    } else if (nav->implementation == SSM_PSR){
        ssm_psr_new(calc);
    }

    /**************************/
    /* multi-threaded sorting */
    /**************************/

    calc->J = fitness->J;
    calc->to_be_sorted = ssm_d1_new(fitness->J);
    calc->index_sorted = ssm_st1_new(fitness->J);

    /**************/
    /* references */
    /**************/
    calc->_par = NULL;
    calc->_nav = nav;

    /**************/
    /* covariates */
    /**************/

    json_t *jcovariates = json_object_get(jdata, "covariates");
    calc->covariates_length = json_array_size(jcovariates);

    if(calc->covariates_length){

        calc->acc = malloc(calc->covariates_length * sizeof(gsl_interp_accel *));
        if (calc->acc == NULL) {
            char str[SSM_STR_BUFFSIZE];
            snprintf(str, SSM_STR_BUFFSIZE, "Allocation impossible in file :%s line : %d",__FILE__,__LINE__);
            ssm_print_err(str);
            exit(EXIT_FAILURE);
        }

        calc->spline = malloc(calc->covariates_length * sizeof(gsl_spline *));
        if (calc->spline == NULL) {
            char str[SSM_STR_BUFFSIZE];
            snprintf(str, SSM_STR_BUFFSIZE, "Allocation impossible in file :%s line : %d",__FILE__,__LINE__);
            ssm_print_err(str);
            exit(EXIT_FAILURE);
        }

        const gsl_interp_type *my_gsl_interp_type = ssm_str_to_interp_type(opts->interpolator);

        int k, z;

        double freeze_forcing; // the time (in days) to freeze (i.e only take metadata from this time) (ignored if freeze_forcing < 0.0)
        double t_max; //t_max the highest possible time in days when interpolated metadata will be requested (negative values default to last point of metadata).

        //assess freeze_forcing and t_max...
        struct tm tm_start;
        memset(&tm_start, 0, sizeof(struct tm));
        strptime(data->date_t0, "%Y-%m-%d", &tm_start);
        time_t t_start = timegm(&tm_start);

        if(strcmp("", opts->end)!=0){
            struct tm tm_freeze;
            memset(&tm_freeze, 0, sizeof(struct tm));
            strptime(opts->freeze_forcing, "%Y-%m-%d", &tm_freeze);
            time_t t_freeze = timegm(&tm_freeze);
            freeze_forcing = difftime(t_freeze, t_start)/(24.0*60.0*60.0);
        } else {
            freeze_forcing = -1.0;
        }

        if(strcmp("", opts->end)!=0){
            struct tm tm_end;
            memset(&tm_end, 0, sizeof(struct tm));
            strptime(opts->end, "%Y-%m-%d", &tm_end);
            time_t t_end = timegm(&tm_end);
            t_max = difftime(t_end, t_start)/(24.0*60.0*60.0);
        } else {
            t_max = -1.0;
        }

        for (k=0; k< calc->covariates_length; k++) {
            json_t *jcovariate = json_array_get(jcovariates, k);

            double *x = ssm_load_jd1_new(jcovariate, "x");
            double *y = ssm_load_jd1_new(jcovariate, "y");
            int size = json_array_size(json_object_get(jcovariate, "x"));

            if((freeze_forcing < 0.0) && (t_max > x[size-1])){ //no freeze but t_max > x[size-1] repeat last value
                int prev_size = size ;
                size += ((int) t_max - x[prev_size-1]) ;

                double *tmp_x = realloc(x, size * sizeof (double) );
                if ( tmp_x == NULL ) {
                    ssm_print_err("Reallocation impossible"); free(x); exit(EXIT_FAILURE);
                } else {
                    x = tmp_x;
                }

                double *tmp_y = realloc(y, size * sizeof (double) );
                if ( tmp_y == NULL ) {
                    ssm_print_err("Reallocation impossible"); free(y); exit(EXIT_FAILURE);
                } else {
                    y = tmp_y;
                }

                //repeat last value
                double xlast = x[prev_size-1];
                for(z = prev_size;  z < size ; z++ ){
                    x[z] = xlast + z;
                    y[z] = y[prev_size - 1];
                }
            }

            if( (freeze_forcing>=0.0) || (size == 1) ){ //only 1 value: make it 2
                double x_all[2];
                x_all[0] = x[0];
                x_all[1] = GSL_MAX( GSL_MAX( t_max, ((data->n_obs>=1) ? (double) data->rows[data->n_obs-1]->time: 0.0) ),  x[size-1]);

                double y_all[2];
                y_all[0] = (size == 1) ? y[0]: gsl_spline_eval(calc->spline[k], GSL_MIN(freeze_forcing, x[size-1]), calc->acc[k]); //interpolate y for time freeze_forcing requested (if possible)
                y_all[1] = y_all[0];

                calc->acc[k] = gsl_interp_accel_alloc ();
                calc->spline[k]  = gsl_spline_alloc (gsl_interp_linear, 2);
                gsl_spline_init (calc->spline[k], x_all, y_all, 2);

            } else if (size >= gsl_interp_type_min_size(my_gsl_interp_type)) {

                calc->acc[k] = gsl_interp_accel_alloc ();
                calc->spline[k]  = gsl_spline_alloc(my_gsl_interp_type, size);
                gsl_spline_init (calc->spline[k], x, y, size);

            } else {

                ssm_print_warning("insufficient data points for required metadata interpolator, switching to linear");
                calc->acc[k] = gsl_interp_accel_alloc ();
                calc->spline[k] = gsl_spline_alloc (gsl_interp_linear, size);
                gsl_spline_init(calc->spline[k], x, y, size);

            }

            free(x);
            free(y);
        }
    }
    return calc;
}
Example #3
0
/**
 * Return the minimum size of input points for cpline interpolation.
 * @return the minimum number of points
 */
size_t minSizeForCSplineInterpolation() {
  return gsl_interp_type_min_size(gsl_interp_cspline);
}
void XYInterpolationCurveDock::xDataColumnChanged(const QModelIndex& index) {
	AbstractAspect* aspect = static_cast<AbstractAspect*>(index.internalPointer());
	AbstractColumn* column = 0;
	if (aspect) {
		column = dynamic_cast<AbstractColumn*>(aspect);
		Q_ASSERT(column);
	}

	foreach(XYCurve* curve, m_curvesList)
		dynamic_cast<XYInterpolationCurve*>(curve)->setXDataColumn(column);

	// disable types that need more data points
	if(column != 0) {
		unsigned int n=0;
		for(int row=0;row < column->rowCount();row++)
			if (!std::isnan(column->valueAt(row)) && !column->isMasked(row)) 
				n++;

		const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(uiGeneralTab.cbType->model());
		QStandardItem* item = model->item(XYInterpolationCurve::Polynomial);
		if(n < gsl_interp_type_min_size(gsl_interp_polynomial) || n>100) {	// not good for many points
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::Polynomial)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

		item = model->item(XYInterpolationCurve::CSpline);
		if(n < gsl_interp_type_min_size(gsl_interp_cspline)) {
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::CSpline)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

		item = model->item(XYInterpolationCurve::CSplinePeriodic);
		if(n < gsl_interp_type_min_size(gsl_interp_cspline_periodic)) {
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::CSplinePeriodic)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

		item = model->item(XYInterpolationCurve::Akima);
		if(n < gsl_interp_type_min_size(gsl_interp_akima)) {
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::Akima)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

		item = model->item(XYInterpolationCurve::AkimaPeriodic);
		if(n < gsl_interp_type_min_size(gsl_interp_akima_periodic)) {
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::AkimaPeriodic)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

#if GSL_MAJOR_VERSION >= 2
		item = model->item(XYInterpolationCurve::Steffen);
		if(n < gsl_interp_type_min_size(gsl_interp_steffen)) {
			item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
			if(uiGeneralTab.cbType->currentIndex() == XYInterpolationCurve::Steffen)
				uiGeneralTab.cbType->setCurrentIndex(0);
		}
		else
			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
#endif
		// own types work with 2 or more points
	}
}