<commit_before>#ifndef PARTICLE_SMOOTHER
#define PARTICLE_SMOOTHER

#include "particle_filter.hpp"
#include <cmath>

namespace mcmc_utilities
{
  template <typename T_p,typename T_state,typename T_obs,typename T_t>
  class particle_smoother
  {
  public:
    typedef typename element_type_trait<T_state>::element_type T_state1;
  private:
    int verbose_level;
    particle_smoother(const particle_smoother&);
  public:
    typedef typename element_type_trait<T_state>::element_type stat_element_type;
    typedef typename element_type_trait<T_obs>::element_type obs_element_type;

    
  private:
    class smoother_model
      :public pf_model<T_p,T_state,T_obs,T_t>
    {
    private:
      particle_smoother<T_p,T_state,T_obs,T_t>* pps;
      
    public:
      smoother_model(particle_smoother<T_p,T_state,T_obs,T_t>* _pps)
	:pps(_pps)
      {}

    private:
      T_p do_evol_log_prob(const T_state& x,const T_t& t,const T_state& prev_stat,const T_t& prev_t)const
      {
	return pps->evol_log_prob(x,t,prev_stat,prev_t);
      }
      
      T_p do_obs_log_prob(const T_obs& y,const T_state& x,const T_t& t)const
      {
	return pps->obs_log_prob(y,x,t);
      }

      std::pair<T_state1,T_state1> do_state_var_range(const T_t& t,const T_state& prev_state,const T_t& prev_t,size_t ndim)const
      {
	return pps->state_var_range(t,prev_state,prev_t,ndim);
      }
    
      std::vector<T_state1> do_init_points(const T_t& t,const T_state& prev_state,const T_t& prev_t,size_t ndim)const
      {
	return pps->init_points(t,prev_state,prev_t,ndim);
      }
    }sm;

    class smoother_model_reverse
      :public pf_model<T_p,T_state,T_obs,T_t>
    {
    private:
      particle_smoother<T_p,T_state,T_obs,T_t>* pps;
    public:
      smoother_model_reverse(particle_smoother<T_p,T_state,T_obs,T_t>* _pps)
	:pps(_pps)
      {}

    private:
      T_p do_evol_log_prob(const T_state& x,const T_t& t,const T_state& future_stat,const T_t& future_t)const
      {
	return pps->evol_log_prob_rev(x,t,future_stat,future_t);
      }
      
      T_p do_obs_log_prob(const T_obs& y,const T_state& x,const T_t& t)const
      {
	return pps->obs_log_prob(y,x,t);
      }

      std::pair<T_state1,T_state1> do_state_var_range(const T_t& t,const T_state& future_state,const T_t& future_t,size_t ndim)const
      {
	return pps->state_var_range(t,future_state,future_t,ndim);
      }
    
      std::vector<T_state1> do_init_points(const T_t& t,const T_state& future_state,const T_t& future_t,size_t ndim)const
      {
	return pps->init_points(t,future_state,future_t,ndim);
      }
    }sm_rev;    
  public:
    //size_t nparticles;
    std::vector<std::vector<particle<T_p,T_state> > > history;
    std::vector<T_t> t_list;
    std::vector<T_obs> obs_list;
  public:
    particle_smoother()
      :sm(this),sm_rev(this),verbose_level(0)
    {}

    virtual ~particle_smoother(){}

    void set_verbose(int n)
    {
      verbose_level=n;
    }
  public:
    void load(const std::vector<T_obs>& obs,const std::vector<T_t>& t_vec,const std::vector<particle<T_p,T_state> >& ps,T_t t0,const base_urand<T_p>& rng)
    {
      history.clear();
      obs_list.clear();
      std::vector<particle<T_p,T_state> > particles(ps);
      size_t nparticles=ps.size();
      T_t prev_t(t0);
      
      for(size_t i=0;i<obs.size();++i)
	{
	  sm.update_sir(obs.at(i),t_vec.at(i),particles,prev_t,rng);
	  history.push_back(particles);
	  t_list.push_back(t_vec[i]);
	  obs_list.push_back(obs[i]);
	  if(verbose_level)
	    {
	      std::cerr<<"loaded "<<i<<" of "<<obs.size()<<std::endl;
	    }
	}
    }

    void backward_simulate(const base_urand<T_p>& rng)
    {
      std::vector<particle<T_p,T_state> > particles(history.back());
      size_t nparticles=particles.size();
      T_t future_t(t_list.back());
      
      for(int i=obs_list.size()-1;i>=0;--i)
	{
	  sm_rev.update_sir(obs_list.at(i),t_list.at(i),particles,future_t,rng);
	  history[i]=particles;
	  if(verbose_level)
	    {
	      std::cerr<<"bs:"<<(obs_list.size()-1-i)<<" of "<<obs_list.size()<<std::endl;
	    }
	}
    }

    void forward_simulate(const base_urand<T_p>& rng)
    {
      std::vector<particle<T_p,T_state> > particles(history.front());
      size_t nparticles=particles.size();
      T_t prev_t(t_list.front());
      
      for(int i=0;i!=obs_list.size();++i)
	{
	  sm.update_sir(obs_list.at(i),t_list.at(i),particles,prev_t,rng);
	  history[i]=particles;
	  if(verbose_level)
	    {
	      std::cerr<<"fs:"<<i<<" of "<<obs_list.size()<<std::endl;
	    }
	}
    }   
    

    std::vector<T_state> draw_realization(const base_urand<T_p>& rng)<commit_msg>	修改：     core/particle_smoother.hpp<commit_after>#ifndef PARTICLE_SMOOTHER
#define PARTICLE_SMOOTHER

#include "particle_filter.hpp"
#include <cmath>

namespace mcmc_utilities
{
  template <typename T_p,typename T_state,typename T_obs,typename T_t>
  class particle_smoother
  {
  public:
    typedef typename element_type_trait<T_state>::element_type T_state1;
  private:
    int verbose_level;
    particle_smoother(const particle_smoother&);
  public:
    typedef typename element_type_trait<T_state>::element_type stat_element_type;
    typedef typename element_type_trait<T_obs>::element_type obs_element_type;

    
  private:
    class smoother_model
      :public pf_model<T_p,T_state,T_obs,T_t>
    {
    private:
      particle_smoother<T_p,T_state,T_obs,T_t>* pps;
      
    public:
      smoother_model(particle_smoother<T_p,T_state,T_obs,T_t>* _pps)
	:pps(_pps)
      {}

    private:
      T_p do_evol_log_prob(const T_state& x,const T_t& t,const T_state& prev_stat,const T_t& prev_t)const
      {
	return pps->evol_log_prob(x,t,prev_stat,prev_t);
      }
      
      T_p do_obs_log_prob(const T_obs& y,const T_state& x,const T_t& t)const
      {
	return pps->obs_log_prob(y,x,t);
      }

      std::pair<T_state1,T_state1> do_state_var_range(const T_t& t,const T_state& prev_state,const T_t& prev_t,size_t ndim)const
      {
	return pps->state_var_range(t,prev_state,prev_t,ndim);
      }
    
      std::vector<T_state1> do_init_points(const T_t& t,const T_state& prev_state,const T_t& prev_t,size_t ndim)const
      {
	return pps->init_points(t,prev_state,prev_t,ndim);
      }
    }sm;

    class smoother_model_reverse
      :public pf_model<T_p,T_state,T_obs,T_t>
    {
    private:
      particle_smoother<T_p,T_state,T_obs,T_t>* pps;
    public:
      smoother_model_reverse(particle_smoother<T_p,T_state,T_obs,T_t>* _pps)
	:pps(_pps)
      {}

    private:
      T_p do_evol_log_prob(const T_state& x,const T_t& t,const T_state& future_stat,const T_t& future_t)const
      {
	return pps->evol_log_prob_rev(x,t,future_stat,future_t);
      }
      
      T_p do_obs_log_prob(const T_obs& y,const T_state& x,const T_t& t)const
      {
	return pps->obs_log_prob(y,x,t);
      }

      std::pair<T_state1,T_state1> do_state_var_range(const T_t& t,const T_state& future_state,const T_t& future_t,size_t ndim)const
      {
	return pps->state_var_range(t,future_state,future_t,ndim);
      }
    
      std::vector<T_state1> do_init_points(const T_t& t,const T_state& future_state,const T_t& future_t,size_t ndim)const
      {
	return pps->init_points(t,future_state,future_t,ndim);
      }
    }sm_rev;    
  public:
    //size_t nparticles;
    std::vector<std::vector<particle<T_p,T_state> > > history;
    std::vector<T_t> t_list;
    std::vector<T_obs> obs_list;
  public:
    particle_smoother()
      :sm(this),sm_rev(this),verbose_level(0)
    {}

    virtual ~particle_smoother(){}

    void set_verbose(int n)
    {
      verbose_level=n;
    }
  public:
    void load(const std::vector<T_obs>& obs,const std::vector<T_t>& t_vec,const std::vector<particle<T_p,T_state> >& ps,T_t t0,const std::vector<std::shared_ptr< base_urand<T_p> > >& rng_array)
    {
      history.clear();
      obs_list.clear();
      std::vector<particle<T_p,T_state> > particles(ps);
      size_t nparticles=ps.size();
      T_t prev_t(t0);
      
      for(size_t i=0;i<obs.size();++i)
	{
	  sm.update_sir(obs.at(i),t_vec.at(i),particles,prev_t,rng_array);
	  history.push_back(particles);
	  t_list.push_back(t_vec[i]);
	  obs_list.push_back(obs[i]);
	  if(verbose_level)
	    {
	      std::cerr<<"loaded "<<i<<" of "<<obs.size()<<std::endl;
	    }
	}
    }

    void backward_simulate(const std::vector<std::shared_ptr< base_urand<T_p> > >& rng_array)
    {
      std::vector<particle<T_p,T_state> > particles(history.back());
      size_t nparticles=particles.size();
      T_t future_t(t_list.back());
      
      for(int i=obs_list.size()-1;i>=0;--i)
	{
	  sm_rev.update_sir(obs_list.at(i),t_list.at(i),particles,future_t,rng_array);
	  history[i]=particles;
	  if(verbose_level)
	    {
	      std::cerr<<"bs:"<<(obs_list.size()-1-i)<<" of "<<obs_list.size()<<std::endl;
	    }
	}
    }

    void forward_simulate(const std::vector<std::shared_ptr< base_urand<T_p> > >& rng_array)
    {
      std::vector<particle<T_p,T_state> > particles(history.front());
      size_t nparticles=particles.size();
      T_t prev_t(t_list.front());
      
      for(int i=0;i!=obs_list.size();++i)
	{
	  sm.update_sir(obs_list.at(i),t_list.at(i),particles,prev_t,rng_array);
	  history[i]=particles;
	  if(verbose_level)
	    {
	      std::cerr<<"fs:"<<i<<" of "<<obs_list.size()<<std::endl;
	    }
	}
    }   
    

    std::vector<T_state> draw_realization(const base_urand<T_p>& rng)
{'fraction_non_alphanumeric': 0.1389686337054758, 'fraction_numerical': 0.003189792663476874, 'mean_word_length': 3.798979591836735, 'pattern_counts': {'":': 0, '<': 141, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5185906', 'n_tokens_mistral': 4008, 'n_tokens_neox': 3894, 'n_words': 486}