From 08c74b8f41e2f6ee0d1c78d31da692542d5900a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Scylla=29?=
 <stephane.adjemian@univ-lemans.fr>
Date: Fri, 29 Aug 2014 12:56:05 +0200
Subject: [PATCH] Added option resampling_threshold (estimation command, non
 linear filters).

---
 doc/dynare.texi                                         | 5 ++++-
 matlab/global_initialization.m                          | 3 +--
 matlab/particle/conditional_particle_filter.m           | 2 +-
 matlab/particle/online_auxiliary_filter.m               | 2 +-
 matlab/particle/sequential_importance_particle_filter.m | 2 +-
 preprocessor/DynareBison.yy                             | 4 +++-
 preprocessor/DynareFlex.ll                              | 1 +
 7 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/doc/dynare.texi b/doc/dynare.texi
index 82b0dfa3bf..118c8807ae 100644
--- a/doc/dynare.texi
+++ b/doc/dynare.texi
@@ -5317,10 +5317,13 @@ No resampling.
 Resampling at each iteration, this is the default value.
 
 @item generic
-Resampling if and only if the effective sample size is below a certain level defined by @code{resampling_threshold*number_of_particles}.
+Resampling if and only if the effective sample size is below a certain level defined by @ref{resampling_threshold}*@ref{number_of_particles}.
 
 @end table
 
+@item resampling_threshold = @var{DOUBLE}
+@anchor{resampling_threshold}
+A real number between zero and one. The resampling step is triggered as soon as the effective number of particles is less than this number times the total number of particles (as set by @ref{number_of_particles}). This option is effective if and only if option @ref{resampling} has value @code{generic}.
 
 @end table
 
diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m
index f7afd262a4..1ebaebc225 100644
--- a/matlab/global_initialization.m
+++ b/matlab/global_initialization.m
@@ -239,8 +239,7 @@ particle.unscented.kappa = 0;
 particle.resampling.status.systematic = 1;
 particle.resampling.status.none = 0;
 particle.resampling.status.generic = 0;
-
-particle.resampling.neff_threshold = .5;
+particle.resampling.threshold = .5;
 % Choice of the resampling method
 particle.resampling.method1 = 'traditional' ;
 particle.resampling.method2 = 'kitagawa';
diff --git a/matlab/particle/conditional_particle_filter.m b/matlab/particle/conditional_particle_filter.m
index 36244809b0..3f365f85c1 100644
--- a/matlab/particle/conditional_particle_filter.m
+++ b/matlab/particle/conditional_particle_filter.m
@@ -113,7 +113,7 @@ for t=1:sample_size
     SumSampleWeights = sum(SampleWeights) ;
     lik(t) = log(SumSampleWeights) ; 
     SampleWeights = SampleWeights./SumSampleWeights ;		
-    if (DynareOptions.particle.resampling.status.generic && neff(SampleWeights)<DynareOptions.particle.resampling.neff_threshold*sample_size) || DynareOptions.particle.resampling.status.systematic
+    if (DynareOptions.particle.resampling.status.generic && neff(SampleWeights)<DynareOptions.particle.resampling.threshold*sample_size) || DynareOptions.particle.resampling.status.systematic
         ks = ks + 1 ;
         StateParticles = resample(StateParticles',SampleWeights',DynareOptions)';
         SampleWeights = ones(1,number_of_particles)/number_of_particles ;
diff --git a/matlab/particle/online_auxiliary_filter.m b/matlab/particle/online_auxiliary_filter.m
index 7089a90389..4a8243a2df 100644
--- a/matlab/particle/online_auxiliary_filter.m
+++ b/matlab/particle/online_auxiliary_filter.m
@@ -206,7 +206,7 @@ for t=1:sample_size
     wtilde = lnw./wtilde ;
     % normalization 
     weights = wtilde/sum(wtilde);
-    if (variance_update==1) && (neff(weights)<DynareOptions.particle.resampling.neff_threshold*sample_size)
+    if (variance_update==1) && (neff(weights)<DynareOptions.particle.resampling.threshold*sample_size)
         variance_update = 0 ;
     end
     % final resampling (advised)
diff --git a/matlab/particle/sequential_importance_particle_filter.m b/matlab/particle/sequential_importance_particle_filter.m
index 3c86f17462..eadaeba41f 100644
--- a/matlab/particle/sequential_importance_particle_filter.m
+++ b/matlab/particle/sequential_importance_particle_filter.m
@@ -158,7 +158,7 @@ for t=1:sample_size
     wtilde = weights.*exp(lnw-dfac);
     lik(t) = log(sum(wtilde))+dfac;
     weights = wtilde/sum(wtilde);
-    if (DynareOptions.particle.resampling.status.generic && neff(weights)<DynareOptions.particle.resampling.neff_threshold*sample_size) || DynareOptions.particle.resampling.status.systematic
+    if (DynareOptions.particle.resampling.status.generic && neff(weights)<DynareOptions.particle.resampling.threshold*sample_size) || DynareOptions.particle.resampling.status.systematic
         if pruning
             temp = resample([tmp(mf0,:)' tmp_(mf0,:)'],weights',DynareOptions);
             StateVectors = temp(:,1:number_of_state_variables)';
diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy
index 2362e0f1ec..f73e5f6b35 100644
--- a/preprocessor/DynareBison.yy
+++ b/preprocessor/DynareBison.yy
@@ -107,7 +107,7 @@ class ParsingDriver;
 %token MFS MH_CONF_SIG MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS
 %token MODE_CHECK MODE_CHECK_NEIGHBOURHOOD_SIZE MODE_CHECK_SYMMETRIC_PLOTS MODE_CHECK_NUMBER_OF_POINTS MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN
 %token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION
-%token NUMBER_OF_PARTICLES RESAMPLING SYSTEMATIC GENERIC
+%token NUMBER_OF_PARTICLES RESAMPLING SYSTEMATIC GENERIC RESAMPLING_THRESHOLD
 %token <string_val> NAME
 %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY
 %token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS
@@ -1679,6 +1679,7 @@ estimation_options : o_datafile
                    | o_consider_only_observed
 		   | o_number_of_particles
 		   | o_resampling
+		   | o_resampling_threshold
                    ;
 
 list_optim_option : QUOTED_STRING COMMA QUOTED_STRING
@@ -2645,6 +2646,7 @@ o_number_of_particles : NUMBER_OF_PARTICLES EQUAL INT_NUMBER { driver.option_num
 o_resampling : RESAMPLING EQUAL SYSTEMATIC
               | RESAMPLING EQUAL NONE {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.none", "1"); }
               | RESAMPLING EQUAL GENERIC {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.generic", "1"); };
+o_resampling_threshold : RESAMPLING_THRESHOLD EQUAL non_negative_number { driver.option_num("particle.resampling.threshold", $3); };
 
 o_gsa_identification : IDENTIFICATION EQUAL INT_NUMBER { driver.option_num("identification", $3); }; /*not in doc */
 o_gsa_morris : MORRIS EQUAL INT_NUMBER { driver.option_num("morris", $3); };
diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll
index f1fab51561..b533a0098c 100644
--- a/preprocessor/DynareFlex.ll
+++ b/preprocessor/DynareFlex.ll
@@ -358,6 +358,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
 <DYNARE_STATEMENT>systematic {return token::SYSTEMATIC;}
 <DYNARE_STATEMENT>none {return token::NONE;}
 <DYNARE_STATEMENT>generic {return token::GENERIC;}
+<DYNARE_STATEMENT>resampling_threshold 	{return token::RESAMPLING_THRESHOLD;}
 
 <DYNARE_STATEMENT>alpha {
   yylval->string_val = new string(yytext);
-- 
GitLab