/** * 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); }
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; }
/** * 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 } }