diff --git a/README.md b/README.md
index 9d5ec4aeaaba24f97227a791f1a0e653488288d0..5edd2eadc2db551270e01afe5c71ac877a63303c 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ a 32-bit Octave.
 1. [**General Instructions**](#general-instructions)
 1. [**Debian or Ubuntu**](#debian-or-ubuntu)
 1. [**Fedora, CentOS or RHEL**](#fedora-centos-or-rhel)
+1. [**Arch Linux**](#arch-linux)
 1. [**Windows**](#windows)
 1. [**macOS**](#macos)
 1. [**Docker**](#docker)
@@ -264,7 +265,8 @@ make -f makefile.gf FFLAGS="-O2 -std=legacy" PROGRAM=x13as
 sudo cp x13as /usr/bin/
 ```
 
-If you use MATLAB, we strongly advise to also rename or exclude the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by Fedora, see e.g. [Matlab on Fedora 33](https://mutschler.eu/linux/install-guides/fedora-post-install/#matlab) or [MATLAB-ArchWiki](https://wiki.archlinux.org/index.php/MATLAB) for instructions.
+If you use MATLAB, we strongly advise to also rename or exclude the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by Fedora, see e.g. the [OpenGL Section of the ArchWiki article on MATLAB](https://wiki.archlinux.org/title/MATLAB#OpenGL_acceleration) for instructions.
+
 
 Now use the following commands if using MATLAB (adapt them for Octave, see above):
 ```sh
@@ -291,6 +293,43 @@ bison --version # bison (GNU Bison) 3.6.4
 ```
 Now configure dynare as above.
 
+## Arch Linux
+
+The following steps show how to install Dynare on Arch Linux from source. 
+- Install all needed dependencies:
+```sh
+pacman -S git make meson boost blas gsl libmatio gcc-fortran gcc-libs
+```
+- Compile and install SLICOT:
+```sh
+wget https://github.com/SLICOT/SLICOT-Reference/archive/refs/tags/v5.9.tar.gz
+tar xf v5.9.tar.gz
+cd SLICOT-Reference-5.9
+make -f makefile_Unix FORTRAN=gfortran OPTS="-O2 -fno-underscoring -fdefault-integer-8" LOADER=gfortran lib
+mkdir -p /usr/local/lib
+cp slicot.a /usr/local/lib/libslicot64_pic.a
+cd ..
+```
+- Install `x13as-bin` from the AUR ([link to PKGBUILD](https://aur.archlinux.org/packages/x13as-bin)), either by using your favorite AUR-helper or by following the [Arch wiki](https://wiki.archlinux.org/title/Arch_User_Repository)
+- Prepare the Dynare sources:
+```sh
+git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git
+cd dynare
+```
+- Configure Dynare from the source directory (adjust `matlab_path` if you use a different version than R2024a):
+```sh
+meson setup -Dmatlab_path=/usr/local/MATLAB/R2024a -Dbuildtype=debugoptimized build-matlab  
+```
+- Compile:
+```sh
+meson compile -C build-matlab
+```
+- Optionally, run the testsuite:
+```sh
+meson test -C build-matlab
+```
+If you run into errors with GCC libraries/`libstdc++`, you need to prevent MATLAB from using the libraries it is shipping. For example, you could follow the [OpenGL Section of the ArchWiki article on MATLAB](https://wiki.archlinux.org/title/MATLAB#OpenGL_acceleration) by setting/exporting `LD_PRELOAD` and `LD_LIBRARY` (the exports could also be placed in your `.zprofile`). If necessary, add `java.opts` as described in the section.
+
 ## Windows
 
 - Install [MSYS2](http://www.msys2.org)
diff --git a/doc/manual/source/bibliography.rst b/doc/manual/source/bibliography.rst
index 90ec693d0b9e1fd54fd56a67c18b82c76e1ad44f..9e17ff619a4dba24360f6f1d9716e3e807fa29ce 100644
--- a/doc/manual/source/bibliography.rst
+++ b/doc/manual/source/bibliography.rst
@@ -14,6 +14,7 @@ Bibliography
 * Backus, David K., Patrick J. Kehoe, and Finn E. Kydland (1992): “International Real Business Cycles,” *Journal of Political Economy*, 100(4), 745–775.
 * Baxter, Marianne and Robert G. King (1999): “Measuring Business Cycles: Approximate Band-pass Filters for Economic Time Series,” *Review of Economics and Statistics*, 81(4), 575–593.
 * Bini, Dario A., Guy Latouche, and Beatrice Meini (2002): “Solving matrix polynomial equations arising in queueing problems,” *Linear Algebra and its Applications*, 340, 225–244.
+* Boehl, Gregor (2022): “DIME MCMC: A Swiss Army Knife for Bayesian Inference”, *SSRN No. 4250395*
 * Born, Benjamin and Johannes Pfeifer (2014): “Policy risk and the business cycle”, *Journal of Monetary Economics*, 68, 68-85.
 * Boucekkine, Raouf (1995): “An alternative methodology for solving nonlinear forward-looking models,” *Journal of Economic Dynamics and Control*, 19, 711–734.
 * Brayton, Flint and Peter Tinsley (1996): “A Guide to FRB/US: A Macroeconomic Model of the United States,” *Finance and Economics Discussion Series*, 1996-42.
diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst
index 8c0b4b72bf7c2a3c316d736930456573fa7640f9..68c9871d4909fbe6556b2e78d2ba563b2c2537ee 100644
--- a/doc/manual/source/the-model-file.rst
+++ b/doc/manual/source/the-model-file.rst
@@ -7462,6 +7462,12 @@ observed variables.
                density is recentered to the previous draw in every
                step.
 
+           ``'dime_mcmc'``
+
+               Instructs Dynare to use the Differential-Independence Mixture Ensemble ("DIME") MCMC sampler of *Boehl (2022)* instead of the standard Random-Walk Metropolis-Hastings. DIME is robust for odd shaped, multimodal, black-box distributions and shown to require significantly less likelihood evaluations than alternative samplers. Many chains run simultaneously, thereby further increasing sampling speed. The algorithm is based on a gradient-free global multi-start optimizer and does not require any posterior mode density maximization prior to MCMC sampling. DIME proposals are generated from an endogenous and adaptive proposal distribution, thereby providing close-to-optimal proposal distributions for black box target distributions without manual fine-tuning. Does not yet support ``moments_varendo``, ``bayesian_irf``, and ``smoother``. 
+
+               Note that, since DIME is using parameter transformations, setting parameter bounds is often counterproductive. The ``prior_trunc`` option is disabled and set to zero.
+
            ``'tailored_random_block_metropolis_hastings'``
 
                Instructs Dynare to use the Tailored randomized block
@@ -7578,6 +7584,42 @@ observed variables.
                   the draws when the current ``_mh*_blck`` file is
                   full. Default: ``0``
 
+           ``'dime_mcmc'``
+
+               Available options are:           
+           
+                  ``'niter'``
+
+                  Number of iterations. Default value is 1500.
+
+                  ``'nchain'``
+
+                  Number of chains/particles. A range between :math:`4 ndim` and :math:`6 ndim` is recommended. For very difficult problems, double the number of chains. Default value is: :math:`5 ndim`. 
+
+                  ``'tune'``
+
+                  Number of ensemble iterations to keep after burnin. Default value is chosen to obtain at least 50,000 samples.
+
+                  ``'aimh_prob'``
+
+                  Probability to draw a global transition kernel. By default this is set to :math:`0.1`. It is usually not necessary to change this value.
+
+                  ``'df_proposal_dist'``
+
+                  Degrees of freedom of the multivariate t distribution used for global kernel proposals. Defaults to :math:`10`.
+
+                  ``'rho'``
+
+                  Decay parameter for the mean and covariances of the global transistion kernel. Defaults to :math:`0.999`.
+
+                  ``'gamma'``
+
+                  Mean stretch factor for the proposal vector. By default, it is :math:`2.38 / \sqrt{2\,\mathrm{ndim}}` as recommended by *ter Braak (2006)*
+
+                  ``'sigma'``
+
+                  Standard deviation of the Gaussian used to stretch the proposal vector. This is normally negligible. Defaults to :math:`1e-5`.
+
            ``'independent_metropolis_hastings'``
 
                Takes the same options as in the case of ``random_walk_metropolis_hastings``.
diff --git a/license.txt b/license.txt
index 45842121d569505d897dd14c9757fb9a3424cf2b..51b37da97b0b9067955540c6c0ec037bc28f0454 100644
--- a/license.txt
+++ b/license.txt
@@ -118,6 +118,10 @@ Copyright: 2011 Lawrence J. Christiano, Mathias Trabandt and Karl Walentin
            2013-2017 Dynare Team
 License: GPL-3+
 
+Files: matlab/estimation/smc/logsumexp.m
+Copyright: 2020 Nicholas J. Higham 
+License: BSD-2-clause
+
 Files: matlab/one_sided_hp_filter.m
 Copyright: 2010-2015 Alexander Meyer-Gohde
            2015-2017 Dynare Team
diff --git a/matlab/default_option_values.m b/matlab/default_option_values.m
index 5af50faa2733af6b162b2bdf53e44d596f64a64a..9e6b685ac83f528558a918dc5f387b7d959fa18b 100644
--- a/matlab/default_option_values.m
+++ b/matlab/default_option_values.m
@@ -498,6 +498,13 @@ options_.posterior_sampler_options.hssmc.particles = 20000;
 options_.posterior_sampler_options.hssmc.scale = 0.5;
 options_.posterior_sampler_options.hssmc.acpt = 1.00;
 options_.posterior_sampler_options.hssmc.target = 0.25;
+% DIME MCMC Sampler
+options_.posterior_sampler_options.dime.niter = 1500;
+options_.posterior_sampler_options.dime.parallel = false;
+options_.posterior_sampler_options.dime.aimh_prob = .1;
+options_.posterior_sampler_options.dime.sigma = 1e-5;
+options_.posterior_sampler_options.dime.df_proposal_dist = 10;
+options_.posterior_sampler_options.dime.rho = 0.999;
 % DSMH: Dynamic Striated Metropolis-Hastings algorithm
 options_.posterior_sampler_options.dsmh.H = 25 ;
 options_.posterior_sampler_options.dsmh.N = 20 ;
diff --git a/matlab/estimation/GetAllPosteriorDraws.m b/matlab/estimation/GetAllPosteriorDraws.m
index dcb6e80dc7eb25919b2388bc5c3581dc2988f915..fd6cdce1cdbf6b93c02d86fed1db3587e46692e2 100644
--- a/matlab/estimation/GetAllPosteriorDraws.m
+++ b/matlab/estimation/GetAllPosteriorDraws.m
@@ -42,6 +42,16 @@ if ishssmc(options_)
     pfiles = dir(sprintf('%s/hssmc/particles-*.mat', dname));
     posterior = load(sprintf('%s/hssmc/particles-%u-%u.mat', dname, length(pfiles), length(pfiles)));
     draws = transpose(posterior.particles(column,:));
+elseif isdime(options_)
+    posterior = load(sprintf('%s%s%s%schains.mat', dname, filesep(), 'dime', filesep()));
+    tune = posterior.tune;
+    chains = posterior.chains(end-tune:end,:,:);
+    if column>0
+        chains = reshape(chains, [], size(chains, 3));
+        draws = chains(:,column);
+    else
+        draws = posterior.lprobs;
+    end
 else
     iline = FirstLine;
     linee = 1;
diff --git a/matlab/estimation/GetPosteriorParametersStatistics.m b/matlab/estimation/GetPosteriorParametersStatistics.m
index cd791de522c7007e206bf6dd883783c9f2a369c9..299ccdaca07cc4fafb3cc257e63b3c69336d3bc3 100644
--- a/matlab/estimation/GetPosteriorParametersStatistics.m
+++ b/matlab/estimation/GetPosteriorParametersStatistics.m
@@ -69,6 +69,8 @@ if ishssmc(options_)
     dprintf('Log data density is %f.', oo_.MarginalDensity.hssmc);
     % Set function handle for GetAllPosteriorDraws
     getalldraws = @(i) GetAllPosteriorDraws(options_, M_.dname, [], i);
+elseif isdime(options_)
+    getalldraws = @(i) GetAllPosteriorDraws(options_, M_.dname, [], i);
 else
     if ~isfield(oo_,'MarginalDensity') || (issmc(options_) && ~isfield(oo_.MarginalDensity,'ModifiedHarmonicMean'))
         [~, oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_);
@@ -81,6 +83,11 @@ end
 if ishssmc(options_)
     num_draws = options_.posterior_sampler_options.hssmc.particles;
     hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
+elseif isdime(options_)
+    nchain = options_.posterior_sampler_options.current_options.nchain;
+    tune = options_.posterior_sampler_options.current_options.tune;
+    num_draws = nchain*tune;
+    hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
 else
     num_draws=NumberOfDraws*mh_nblck;
     hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
diff --git a/matlab/estimation/check_posterior_sampler_options.m b/matlab/estimation/check_posterior_sampler_options.m
index 29de7cf6891de044ffe52e957f037e37262597fa..e93510075baf1f6956c47beb1a5c148f9eefc3a7 100644
--- a/matlab/estimation/check_posterior_sampler_options.m
+++ b/matlab/estimation/check_posterior_sampler_options.m
@@ -405,6 +405,49 @@ if init
             options_.mh_replic = 0;
             options_.mh_posterior_mode_estimation = false;
 
+          case 'dime_mcmc'
+
+            % default options
+            posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dime);
+
+            % user defined options
+            if ~isempty(options_.posterior_sampler_options.sampling_opt)
+                options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
+                for i=1:rows(options_list)
+                    switch options_list{i,1}
+                      case 'nchain'
+                        posterior_sampler_options.nchain = options_list{i,2};
+                      case 'niter'
+                        posterior_sampler_options.niter = options_list{i,2};
+                      case 'parallel'
+                        posterior_sampler_options.parallel = options_list{i,2};
+                      case 'tune'
+                        posterior_sampler_options.tune = options_list{i,2};
+                      case 'aimh_prob'
+                        posterior_sampler_options.aimh_prob = options_list{i,2};
+                      case 'sigma'
+                        posterior_sampler_options.sigma = options_list{i,2};
+                      case 'gamma'
+                        posterior_sampler_options.gamma = options_list{i,2};
+                      case 'df_proposal_dist'
+                        posterior_sampler_options.df_proposal_dist = options_list{i,2};
+                      case 'rho'
+                        posterior_sampler_options.rho = options_list{i,2};
+                      otherwise
+                        warning(['dime: Unknown option (' options_list{i,1} ')!'])
+                    end
+                end
+            end
+
+            if ~isfield(posterior_sampler_options,'tune')
+                posterior_sampler_options.tune = ceil(50000 / posterior_sampler_options.nchain);
+                dprintf('dime: setting number of ensemble iterations to keep (`tune`) to %d.', posterior_sampler_options.tune)
+            end
+            options_.mode_compute = 0;
+            options_.cova_compute = 0;
+            options_.mh_replic = 0;
+            options_.mh_posterior_mode_estimation = false;
+
       case 'dsmh'
 
         % default options
diff --git a/matlab/estimation/dynare_estimation_1.m b/matlab/estimation/dynare_estimation_1.m
index 444280a79a80e026feb8fd3357e55a92c0800342..52a51a4cf5862903152be09b763afef77b5c07d7 100644
--- a/matlab/estimation/dynare_estimation_1.m
+++ b/matlab/estimation/dynare_estimation_1.m
@@ -31,6 +31,8 @@ function dynare_estimation_1(var_list_,dname)
 
 global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info
 
+dispString = 'Estimation::mcmc';
+
 if issmc(options_)
     options_.mode_compute = 0;
     options_.mh_replic = 0;
@@ -38,8 +40,10 @@ if issmc(options_)
     options_.load_mh_file = false;
     options_.load_results_after_load_mh = false;
 end
-
-dispString = 'Estimation::mcmc';
+if isdime(options_) && options_.prior_trunc
+    options_.prior_trunc = 0;
+    fprintf('%s: DIME requires no prior truncation. Resetting options_.prior_trunc=0.\n', dispString);
+end
 
 if ~exist([M_.dname filesep 'Output'],'dir')
     mkdir(M_.dname,'Output');
@@ -396,6 +400,10 @@ if ishssmc(options_)
     [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_, bounds, bayestopt_);
     options_.posterior_sampler_options.current_options = posterior_sampler_options;
     oo_.MarginalDensity.hssmc = hssmc(objective_function, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
+elseif isdime(options_)
+    [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_, bounds, bayestopt_);
+    options_.posterior_sampler_options.current_options = posterior_sampler_options;
+    dime(objective_function, xparam1, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
 elseif isdsmh(options_)
     dsmh(objective_function, xparam1, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_)
 end
@@ -456,9 +464,12 @@ if issmc(options_) || (any(bayestopt_.pshape>0) && options_.mh_replic) ||  (any(
                     oo_.convergence=oo_load_mh.oo_.convergence;
                 end
             end
+        elseif isdime(options_) && ~options_.nodiagnostic
+            % provide plot of log densities over iterations
+            oo_.lprob = trace_plot_dime(options_, M_);
         end
         % Estimation of the marginal density from the Mh draws:
-        if ishssmc(options_) || options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
+        if ishssmc(options_) || isdime(options_) || options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
             if ~issmc(options_)
                 [~, oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_);
             end
@@ -469,8 +480,9 @@ if issmc(options_) || (any(bayestopt_.pshape>0) && options_.mh_replic) ||  (any(
             end
             % Store posterior mean in a vector and posterior variance in
             % a matrix
-            [oo_.posterior.metropolis.mean,oo_.posterior.metropolis.Variance] ...
-                = GetPosteriorMeanVariance(options_, M_);
+            if ~isdime(options_)
+                [oo_.posterior.metropolis.mean,oo_.posterior.metropolis.Variance] = GetPosteriorMeanVariance(options_, M_);
+            end
         elseif options_.load_mh_file && options_.load_results_after_load_mh
             % load fields from previous MCMC run stored in results-file
             field_names={'posterior_mode','posterior_std_at_mode',...% fields set by marginal_density
@@ -537,7 +549,7 @@ if issmc(options_) || (any(bayestopt_.pshape>0) && options_.mh_replic) ||  (any(
                 end
             end
             if options_.smoother || ~isempty(options_.filter_step_ahead) || options_.forecast
-                if ~ishssmc(options_)
+                if ~ishssmc(options_) && ~isdime(options_)
                     if error_flag
                         error('%s: I cannot compute the posterior statistics!',dispString)
                     end
diff --git a/matlab/estimation/dynare_estimation_init.m b/matlab/estimation/dynare_estimation_init.m
index 8378285dcef48104ed10faa21c451afb73407a1a..13c1c9e8328ec63c1e0fd124b7b2fbd2f421279f 100644
--- a/matlab/estimation/dynare_estimation_init.m
+++ b/matlab/estimation/dynare_estimation_init.m
@@ -372,6 +372,9 @@ end
 k = find(isnan(bayestopt_.jscale));
 bayestopt_.jscale(k) = options_.mh_jscale;
 
+% set default number of chains for DIME
+options_.posterior_sampler_options.dime.nchain = 5 * length(xparam1);
+
 % Build the dataset
 if ~isempty(options_.datafile)
     [~,name] = fileparts(options_.datafile);
diff --git a/matlab/estimation/generate_trace_plots.m b/matlab/estimation/generate_trace_plots.m
index 409ab22bdfa78eb09635cd34672a809640509446..b6e6c8b62f70c3495822dab56d2e9341f9e1a58a 100644
--- a/matlab/estimation/generate_trace_plots.m
+++ b/matlab/estimation/generate_trace_plots.m
@@ -30,6 +30,9 @@ function generate_trace_plots(chain_number)
 
 global M_ options_ estim_params_
 
+if issmc(options_)
+    error('generate_trace_plots:: SMC methods do not support trace plots')
+end
 
 % Get informations about the posterior draws:
 MetropolisFolder = CheckPath('metropolis', M_.dname);
@@ -65,4 +68,4 @@ for ii=1:size(estim_params_.corrx, 1)
     parameter_name_1 = M_.exo_names{estim_params_.corrx(ii,1)};
     parameter_name_2 = M_.exo_names{estim_params_.corrx(ii,2)};
     trace_plot(options_, M_, estim_params_, 'StructuralShock', chain_number, parameter_name_1, parameter_name_2)
-end
\ No newline at end of file
+end
diff --git a/matlab/estimation/smc/dime.m b/matlab/estimation/smc/dime.m
new file mode 100644
index 0000000000000000000000000000000000000000..bb2e5886e5f4bd639e979dba661b23fc14bf8a23
--- /dev/null
+++ b/matlab/estimation/smc/dime.m
@@ -0,0 +1,245 @@
+function dime(TargetFun, init_x, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, dr , steady_state, exo_steady_state, exo_det_steady_state)
+
+% Differential-Independence Mixture Ensemble ("DIME") MCMC sampling 
+% as proposed in "Ensemble MCMC Sampling for Robust Bayesian Inference" 
+% (Gregor Boehl, 2022, SSRN No. 4250395):
+%
+%   https://gregorboehl.com/live/dime_mcmc_boehl.pdf
+%
+% INPUTS
+% - TargetFun               [char]     string specifying the name of the objective function (posterior kernel).
+% - init_x                  [double]   p×1 vector of parameters to be estimated (initial values, not used).
+% - mh_bounds               [double]   p×2 matrix defining lower and upper bounds for the parameters.
+% - dataset_                [dseries]  sample
+% - dataset_info            [struct]   informations about the dataset
+% - options_                [struct]   Dynare's options
+% - M_                      [struct]   model description
+% - estim_params_           [struct]   estimated parameters
+% - bayestopt_              [struct]   describing the priors
+% - steady_state            [double]   steady state of endogenous variables
+% - exo_steady_state        [double]   steady state of exogenous variables
+% - exo_det_steady_state    [double]   steady state of exogenous deterministic variables
+%
+% SPECIAL REQUIREMENTS
+% None.
+
+% Copyright © 2024 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+    % initialize
+    ndim = length(init_x);
+    prop_cov = eye(ndim);
+    prop_mean = zeros(1,ndim);
+    naccepted = 1;
+    cumlweight = -inf;
+    fixPSD = 1e-16*prop_cov;
+
+    % get options & assign problem specific default value 
+    opts = options_.posterior_sampler_options.current_options;
+    if isfield(opts,'gamma')
+        g0 = opts.gamma;
+    else
+        g0 = 2.38 / sqrt(2 * ndim);
+    end
+    nchain = opts.nchain;
+    dft = opts.df_proposal_dist;
+    tune = opts.tune;
+    if tune > opts.niter
+        error('dime: number of ensemble iterations to keep (tune=%d) exceeds number of iterations (niter=%d)!', tune, opts.niter)
+    end
+
+    % temporary workaround to deal with parallelization
+    if opts.parallel
+        % check if parallel is possible
+        installed_toolboxes = ver;
+        toolbox_installed = any(strcmp("Parallel Computing Toolbox", {installed_toolboxes.Name}));
+        if ~toolbox_installed || feature('numcores') == 1
+            error('dime: parallel processing option is chosen but Parallel Computing Toolbox is not installed or machine has only one core')
+        end
+    end
+
+    % Set location for the simulated particles.
+    SimulationFolder = CheckPath('dime', M_.dname);
+    % Define prior distribution
+    Prior = dprior(bayestopt_, options_.prior_trunc);
+    bounds = check_bounds(Prior, mh_bounds);
+
+    % Set function handle for the objective
+    eval(sprintf('%s = @(x) %s(x, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, mh_bounds, dr , steady_state, exo_steady_state, exo_det_steady_state, []);', 'funobj', func2str(TargetFun)));
+
+    % Initialization of the sampler (draws from the prior distribution with finite logged likelihood)
+    t0 = tic;
+    [x, ~, lprob] = ...
+        smc_samplers_initialization(funobj, 'dime', nchain, Prior, SimulationFolder, opts.niter);
+    tt = toc(t0);
+    x = ptransform(x', bounds, true);
+
+    disp_verbose(sprintf('Estimation:dime: log-posterior standard deviation (post.std) of a multivariate normal would be %.2f.\n', sqrt(0.5*ndim)), options_.verbosity);
+
+    % preallocate
+    chains = zeros(opts.niter, nchain, ndim);
+    lprobs = zeros(opts.niter, nchain);
+    isplit = fix(nchain/2) + 1;
+
+    for iter = 1:opts.niter
+
+        for complementary_ensemble = [false true]
+
+            % define current ensemble
+            if complementary_ensemble
+                idcur = 1:isplit;
+                idref = (isplit+1):nchain;
+            else
+                idcur = (isplit+1):nchain;
+                idref = 1:isplit;
+            end
+            cursize = length(idcur);
+            refsize = nchain - cursize;
+
+            % get differential evolution proposal
+            % draw the indices of the complementary chains
+            i1 = (0:cursize-1) + randi([1 cursize-1], 1, cursize);
+            i2 = (0:cursize-1) + randi([1 cursize-2], 1, cursize);
+            i2(i2 >= i1) = i2(i2 >= i1) + 1;
+
+            % add small noise and calculate proposal
+            f = opts.sigma*randn(cursize, 1);
+            q = x(idcur,:) + g0 .* (x(idref(mod(i1, refsize) + 1),:) - x(idref(mod(i2, refsize) + 1),:)) + f;
+            factors = zeros(cursize,1);
+
+            % get AIMH proposal
+            xchnge = rand(cursize,1) <= opts.aimh_prob;
+
+            % draw alternative candidates and calculate their proposal density
+            prop_cov_chol = chol(prop_cov*(dft - 2)/dft + fixPSD);
+            xcand = rand_multivariate_student(prop_mean, prop_cov_chol, dft, sum(xchnge));
+            lprop_old = log(multivariate_student_pdf(x(idcur(xchnge),:), prop_mean, prop_cov_chol, dft));
+            lprop_new = log(multivariate_student_pdf(xcand, prop_mean, prop_cov_chol, dft));
+
+            % update proposals and factors
+            q(xchnge,:) = xcand;
+            factors(xchnge) = lprop_old - lprop_new;
+
+            % Metropolis-Hasings 
+            newlprob = log_prob_fun(funobj, Prior, bounds, opts.parallel, q);
+            lnpdiff = factors + newlprob - lprob(idcur);
+            accepted = lnpdiff > log(rand(cursize,1));
+            naccepted = naccepted + sum(accepted);
+
+            % update chains
+            x(idcur(accepted),:) = q(accepted,:);
+            lprob(idcur(accepted)) = newlprob(accepted);
+        end
+
+        % store
+        chains(iter,:,:) = ptransform(x, bounds, false);
+        lprobs(iter,:) = lprob;
+
+        % log weight of current ensemble
+        lweight = logsumexp(lprob) + log(naccepted) - log(nchain);
+
+        % calculate stats for current ensemble
+        ncov = cov(x);
+        nmean = mean(x);
+
+        % update AIMH proposal distribution
+        newcumlweight = logsumexp([cumlweight lweight]);
+        prop_cov = exp(cumlweight - newcumlweight) .* prop_cov + exp(lweight - newcumlweight) .* ncov;
+        prop_mean = exp(cumlweight - newcumlweight) .* prop_mean + exp(lweight - newcumlweight) .* nmean;
+        cumlweight = newcumlweight + log(opts.rho);
+
+        % be informative
+        tt = toc(t0);
+        if iter == 1 | ~mod(iter,15)
+            disp_verbose('     #iter.      post.mode     post.std    %accept     lapsed', options_.verbosity)
+            disp_verbose('     ------      ---------     --------    -------     ------', options_.verbosity)
+        end
+        counter = sprintf('%u/%u', iter, opts.niter);
+        disp_verbose(sprintf('%11s     %10.3f     %1.2e     %5.2f%%     %5.2fs', counter, max(lprob), std(lprob), 100*naccepted/nchain, tt), options_.verbosity)
+        naccepted = 0;
+    end
+
+    save(sprintf('%s%schains.mat', SimulationFolder, filesep()), 'chains', 'lprobs', 'tune')
+end
+
+function lprobs = log_prob_fun(loglikefun, Prior, bounds, runs_in_parallel, x)
+
+    dim = length(x);
+    x = ptransform(x, bounds, false);
+    lprobs = zeros(dim,1);
+    if runs_in_parallel
+        parfor i=1:dim
+            par = x(i,:)';
+            loglikelihood = -loglikefun(par);
+            % temporary workaround for bug #1930
+            logprior = Prior.density(par);
+            lprobs(i) = loglikelihood + logprior;
+        end
+    else
+        for i=1:dim
+            lprobs(i) = -loglikefun(x(i,:)');
+        end
+    end
+end
+
+function nbounds = check_bounds(Prior, bounds)
+
+    % ensure that prior is continous at bounds
+    nbounds = bounds;
+    prior_at_mean = Prior.density(Prior.mean);
+    dim = length(Prior.mean);
+    for j = 1:dim
+        if ~isinf(bounds.ub(j))
+            x = Prior.mean;
+            x(j) = bounds.ub(j);
+            if Prior.density(x - 1e-16) - prior_at_mean > log(1e-16)
+                nbounds.ub(j) = nbounds.ub(j) + 1e-2;
+            end
+            x = Prior.mean;
+            x(j) = bounds.lb(j);
+            if Prior.density(x + 1e-16) - prior_at_mean > log(1e-16)
+                nbounds.lb(j) = nbounds.lb(j) - 1e-2;
+            end
+        end
+    end
+end
+
+function x = ptransform(x, bounds, con2unc)
+
+    % parameter transformation
+    lb = bounds.lb;
+    ub = bounds.ub;
+    dim = size(x,2);
+    for j = 1:dim
+        % one-sided
+        if ~isinf(lb(j)) && isinf(ub(j))           
+            if con2unc
+                x(:,j) = log(x(:,j) - lb(j));
+            else
+                x(:,j) = lb(j) + exp(x(:,j));
+            end
+        % two-sided
+        elseif ~isinf(lb(j)) && ~isinf(ub(j))      
+            if con2unc
+                y = (x(:,j) - lb(j))/(ub(j) - lb(j));
+                x(:,j) = log(y ./ (1 - y));
+            else
+                x(:,j) = lb(j) + (ub(j) - lb(j)) ./ (1 + exp(-x(:,j)));
+            end
+        end
+    end
+end
diff --git a/matlab/estimation/smc/isdime.m b/matlab/estimation/smc/isdime.m
new file mode 100644
index 0000000000000000000000000000000000000000..11f6a4ba9b92dbdf41dec34b9562ff9e1e40acc1
--- /dev/null
+++ b/matlab/estimation/smc/isdime.m
@@ -0,0 +1,25 @@
+function bool = isdime(options_)
+
+% Copyright © 2024 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+bool = false;
+if isfield(options_, 'posterior_sampler_options')
+    if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'dime_mcmc')
+        bool = true;
+    end
+end
diff --git a/matlab/estimation/smc/logsumexp.m b/matlab/estimation/smc/logsumexp.m
new file mode 100644
index 0000000000000000000000000000000000000000..cad3165568cdaee5daf6eae798e432b60f9cae85
--- /dev/null
+++ b/matlab/estimation/smc/logsumexp.m
@@ -0,0 +1,56 @@
+function [lse,sm] = logsumexp(x)
+%LOGSUMEXP  Log-sum-exp function.
+%    lse = LOGSUMEXP(x) returns the log-sum-exp function evaluated at 
+%    the vector x, defined by lse = log(sum(exp(x)).
+%    [lse,sm] = LOGSUMEXP(x) also returns the softmax function evaluated
+%    at x, defined by sm = exp(x)/sum(exp(x)).
+%    The functions are computed in a way that avoids overflow and 
+%    optimizes numerical stability.   
+%
+%    Reference:
+%    P. Blanchard, D. J. Higham, and N. J. Higham.  
+%    Accurately computing the log-sum-exp and softmax functions. 
+%    IMA J. Numer. Anal., Advance access, 2020.
+%
+%    Taken from https://de.mathworks.com/matlabcentral/fileexchange/84892-logsumexp-softmax
+%
+% Copyright (c) 2020, Nicholas J. Higham 
+% All rights reserved.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions are met:
+%
+% * Redistributions of source code must retain the above copyright notice, this
+%   list of conditions and the following disclaimer.
+%
+% * Redistributions in binary form must reproduce the above copyright notice,
+%   this list of conditions and the following disclaimer in the documentation
+%   and/or other materials provided with the distribution.
+%
+% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+% DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+if ~isvector(x), error('Input x must be a vector.'), end
+
+n = length(x);
+s = 0; e = zeros(n,1);
+[xmax,k] = max(x); a = xmax;
+s = 0;
+for i = 1:n
+    e(i) = exp(x(i)-xmax);
+    if i ~= k
+       s = s + e(i);
+    end   
+end
+lse = a + log1p(s);
+if nargout > 1
+   sm = e/(1+s);
+end  
diff --git a/matlab/estimation/smc/trace_plot_dime.m b/matlab/estimation/smc/trace_plot_dime.m
new file mode 100644
index 0000000000000000000000000000000000000000..02719db9903a88c8de026f82b799f881500e6698
--- /dev/null
+++ b/matlab/estimation/smc/trace_plot_dime.m
@@ -0,0 +1,70 @@
+function lprobs_sample = trace_plot_dime(options_, M_)
+
+% Plot the history of the densities of an ensemble to visually inspect convergence.
+%
+% INPUTS
+% - options_         [struct]   dynare's options
+% - M_               [struct]   model description
+% - oo_              [struct]   outputs
+%
+% SPECIAL REQUIREMENTS
+% None.
+
+% Copyright © 2022-2023 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+lprobs = GetAllPosteriorDraws(options_, M_.dname, [], 0);
+tune = options_.posterior_sampler_options.current_options.tune;
+[niter, nchain] = size(lprobs);
+
+if max(lprobs(end,:)) > 0
+    ulim = max(lprobs(end,:))*1.2;
+else
+    ulim = max(lprobs(end,:))/1.2;
+end
+if min(lprobs(end,:)) > 0
+    llim = min(lprobs(end,:))/5;
+else
+    llim = min(lprobs(end,:))*5;
+end
+
+graphFolder = CheckPath('graphs',M_.dname);
+latexFolder = CheckPath('latex',M_.dname);
+hh_fig = dyn_figure(options_.nodisplay,'Name','DIME Convergence Diagnostics');
+
+hold on
+lines_tune = plot(1:niter-tune, lprobs(1:end-tune,:), 'Color', '#D95319');
+lines_sample = plot(niter-tune:niter, lprobs(end-tune:end,:), 'Color', '#0072BD');
+for i = 1:nchain
+    lines_tune(i).Color(4) = min(1,10/nchain);
+    lines_sample(i).Color(4) = min(1,10/nchain);
+end
+ylim([llim, ulim])
+hold off
+
+dyn_saveas(hh_fig,[graphFolder '/' M_.fname '_trace_lprob'],options_.nodisplay,options_.graph_format);
+if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
+    fprintf(fidTeX,'\\begin{figure}[H]\n');
+    fprintf(fidTeX,'\\centering \n');
+    fprintf(fidTeX,'\\includegraphics[width=0.8\\textwidth]{%s_trace_lprob}\n',[graphFolder '/' M_.fname]);
+    fprintf(fidTeX,'\\caption{Ensemble traces of posterior densities for DIME.\n');
+    fprintf(fidTeX,'\\label{Fig:DIME_trace}\n');
+    fprintf(fidTeX,'\\end{figure}\n');
+    fprintf(fidTeX,'\n');
+end
+
+lprobs_sample = lprobs(end-tune:end,:);
diff --git a/matlab/issmc.m b/matlab/issmc.m
index a79d444db9239152acc6d962a0b7345b8309138d..0f80730a55635be528e9fc6cf648921ff57b5957 100644
--- a/matlab/issmc.m
+++ b/matlab/issmc.m
@@ -17,4 +17,4 @@ function bool = issmc(options_)
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
-bool = ishssmc(options_) || isdsmh(options_);
+bool = ishssmc(options_) || isdsmh(options_) || isdime(options_);
diff --git a/meson.build b/meson.build
index 8bd67e600f125b63617bacfe8c81ed5415ad4ced..e2466bca8b58519a22f87ea9d72553a05c046283 100644
--- a/meson.build
+++ b/meson.build
@@ -845,6 +845,8 @@ mod_and_m_tests = [
                 'estimation/fsdat_simul.m' ] },
   { 'test' : [ 'estimation/fs2000.mod' ],
     'extra' : [ 'estimation/fsdat_simul.m' ] },
+  { 'test' : [ 'estimation/dime_mcmc/fs2000.mod' ],
+    'extra' : [ 'estimation/fsdat_simul.m' ] },
   { 'test' : [ 'estimation/hssmc/fs2000.mod' ],
     'extra' : [ 'estimation/fsdat_simul.m' ] },
   { 'test' : [ 'gsa/ls2003a.mod',
diff --git a/tests/estimation/dime_mcmc/fs2000.mod b/tests/estimation/dime_mcmc/fs2000.mod
new file mode 100644
index 0000000000000000000000000000000000000000..3491ce5c5a832eda88c090faa3ec5449f265a9d5
--- /dev/null
+++ b/tests/estimation/dime_mcmc/fs2000.mod
@@ -0,0 +1,89 @@
+// See fs2000.mod in the examples/ directory for details on the model
+
+var m P c e W R k d n l gy_obs gp_obs y dA;
+varexo e_a e_m;
+
+parameters alp bet gam mst rho psi del;
+
+alp = 0.33;
+bet = 0.99;
+gam = 0.003;
+mst = 1.011;
+rho = 0.7;
+psi = 0.787;
+del = 0.02;
+
+model;
+dA = exp(gam+e_a);
+log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m;
+-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0;
+W = l/n;
+-(psi/(1-psi))*(c*P/(1-n))+l/n = 0;
+R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W;
+1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0;
+c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1);
+P*c = m;
+m-1+d = l;
+e = exp(e_a);
+y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a));
+gy_obs = dA*y/y(-1);
+gp_obs = (P/P(-1))*m(-1)/dA;
+end;
+
+steady_state_model;
+  dA = exp(gam);
+  gst = 1/dA;
+  m = mst;
+  khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1));
+  xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1);
+  nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp );
+  n  = xist/(nust+xist);
+  P  = xist + nust;
+  k  = khst*n;
+
+  l  = psi*mst*n/( (1-psi)*(1-n) );
+  c  = mst/P;
+  d  = l - mst + 1;
+  y  = k^alp*n^(1-alp)*gst^alp;
+  R  = mst/bet;
+  W  = l/n;
+  ist  = y-c;
+  q  = 1 - d;
+
+  e = 1;
+
+  gp_obs = m/dA;
+  gy_obs = dA;
+end;
+
+
+shocks;
+var e_a; stderr 0.014;
+var e_m; stderr 0.005;
+end;
+
+steady;
+
+check;
+
+estimated_params;
+alp, beta_pdf, 0.356, 0.02;
+bet, beta_pdf, 0.993, 0.002;
+gam, normal_pdf, 0.0085, 0.003;
+mst, normal_pdf, 1.0002, 0.007;
+rho, beta_pdf, 0.129, 0.223;
+psi, beta_pdf, 0.65, 0.05;
+del, beta_pdf, 0.01, 0.005;
+stderr e_a, inv_gamma_pdf, 0.035449, inf;
+stderr e_m, inv_gamma_pdf, 0.008862, inf;
+end;
+
+varobs gp_obs gy_obs;
+
+options_.solve_tolf = 1e-12;
+
+estimation(order=1, datafile='../fsdat_simul.m', nobs=192, loglinear,
+           posterior_sampling_method='dime_mcmc',
+           posterior_sampler_options=('tune',200, 'niter',400),
+bayesian_irf, smoother, moments_varendo,consider_all_endogenous
+);