sdis_estimator_buffer_X_obs.h (3892B)
1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 /* Define functions on estimator buffer generic to the observable type. */ 17 18 #ifndef SDIS_ESTIMATOR_BUFFER_X_OBS_H 19 #define SDIS_ESTIMATOR_BUFFER_X_OBS_H 20 21 #include "sdis.h" 22 #include "sdis_estimator_c.h" 23 #include "sdis_estimator_buffer_c.h" 24 #include "sdis_misc.h" 25 26 #endif /* SDIS_ESTIMATOR_BUFFER_X_OBS_H */ 27 28 /* Check the generic observable parameter */ 29 #ifndef SDIS_X_OBS 30 #error "The SDIS_X_OBS macro must be defined." 31 #endif 32 33 #define X_OBS(Name) CONCAT(CONCAT(Name, _), SDIS_X_OBS) 34 #define SDIS_SOLVE_X_OBS_ARGS CONCAT(CONCAT(sdis_solve_, SDIS_X_OBS),_args) 35 36 res_T 37 X_OBS(estimator_buffer_create_from_observable_list) 38 (struct sdis_device* dev, 39 struct ssp_rng_proxy* rng_proxy, 40 const struct SDIS_SOLVE_X_OBS_ARGS obs_list_args[], 41 const struct accum* per_obs_acc_temp, 42 const struct accum* per_obs_acc_time, 43 const size_t nobs, /* #observables */ 44 struct sdis_estimator_buffer** out_estim_buffer) 45 { 46 /* Accumulators throughout the buffer */ 47 struct accum acc_temp = ACCUM_NULL; 48 struct accum acc_time = ACCUM_NULL; 49 size_t nrealisations = 0; 50 51 struct sdis_estimator_buffer* estim_buf = NULL; 52 size_t iobs = 0; 53 res_T res = RES_OK; 54 55 ASSERT(dev && rng_proxy); 56 ASSERT(obs_list_args || !nobs); 57 ASSERT(per_obs_acc_time && per_obs_acc_time && out_estim_buffer); 58 59 res = estimator_buffer_create(dev, nobs, 1, &estim_buf); 60 if(res != RES_OK) { 61 log_err(dev, "Unable to allocate the estimator buffer.\n"); 62 goto error; 63 } 64 65 FOR_EACH(iobs, 0, nobs) { 66 const struct SDIS_SOLVE_X_OBS_ARGS* obs_args = NULL; 67 const struct accum* obs_acc_temp = NULL; 68 const struct accum* obs_acc_time = NULL; 69 struct sdis_estimator* estim = NULL; 70 71 /* Get observable data */ 72 obs_args = obs_list_args + iobs; 73 obs_acc_temp = per_obs_acc_temp + iobs; 74 obs_acc_time = per_obs_acc_time + iobs; 75 ASSERT(obs_acc_temp->count == obs_acc_time->count); 76 77 /* Setup the estimator of the current observable */ 78 estim = estimator_buffer_grab(estim_buf, iobs, 0); 79 estimator_setup_realisations_count 80 (estim, obs_args->nrealisations, obs_acc_temp->count); 81 estimator_setup_temperature 82 (estim, obs_acc_temp->sum, obs_acc_temp->sum2); 83 estimator_setup_realisation_time 84 (estim, obs_acc_time->sum, obs_acc_time->sum2); 85 86 /* Update global accumulators */ 87 acc_temp.sum += obs_acc_temp->sum; 88 acc_temp.sum2 += obs_acc_temp->sum2; 89 acc_temp.count += obs_acc_temp->count; 90 acc_time.sum += obs_acc_time->sum; 91 acc_time.sum2 += obs_acc_time->sum2; 92 acc_time.count += obs_acc_time->count; 93 nrealisations += obs_args->nrealisations; 94 } 95 96 ASSERT(acc_temp.count == acc_time.count); 97 98 /* Setup global estimator */ 99 estimator_buffer_setup_realisations_count 100 (estim_buf, nrealisations, acc_temp.count); 101 estimator_buffer_setup_temperature 102 (estim_buf, acc_temp.sum, acc_temp.sum2); 103 estimator_buffer_setup_realisation_time 104 (estim_buf, acc_time.sum, acc_time.sum2); 105 106 res = estimator_buffer_save_rng_state(estim_buf, rng_proxy); 107 if(res != RES_OK) goto error; 108 109 exit: 110 *out_estim_buffer = estim_buf; 111 return res; 112 error: 113 goto exit; 114 } 115 116 #undef X_OBS 117 #undef SDIS_SOLVE_X_OBS_ARGS 118 #undef SDIS_X_OBS