diff --git a/dynare++/extern/matlab/dynare_simul.cc b/dynare++/extern/matlab/dynare_simul.cc
index 6036090a2db84caf7d12ed9e4f398c4a075a92ef..56486d608fea5fe6ea144e956aaa152f6c3176e1 100644
--- a/dynare++/extern/matlab/dynare_simul.cc
+++ b/dynare++/extern/matlab/dynare_simul.cc
@@ -113,12 +113,10 @@ extern "C" {
         ConstTwoDMatrix vcov_mat(nexog, nexog, ConstVector{vcov});
         GenShockRealization sr(vcov_mat, shocks_mat, seed);
         // simulate and copy the results
-        TwoDMatrix *res_mat
-          = dr.simulate(DecisionRule::horner, nper,
-                        ConstVector{ystart}, sr);
+        TwoDMatrix res_mat{dr.simulate(DecisionRule::emethod::horner, nper,
+                                       ConstVector{ystart}, sr)};
         TwoDMatrix res_tmp_mat{ny, nper, Vector{res}};
-        res_tmp_mat = (const TwoDMatrix &) (*res_mat);
-        delete res_mat;
+        res_tmp_mat = const_cast<const TwoDMatrix &>(res_mat);
         plhs[1] = res;
       }
     catch (const KordException &e)
diff --git a/dynare++/kord/approximation.cc b/dynare++/kord/approximation.cc
index b4eb7975700002895d9af23dc4c0a6ce0293556e..12c0dd0c9eece64ba7c1573984e8ee3960a1e6d4 100644
--- a/dynare++/kord/approximation.cc
+++ b/dynare++/kord/approximation.cc
@@ -10,8 +10,7 @@
 ZAuxContainer::ZAuxContainer(const _Ctype *gss, int ngss, int ng, int ny, int nu)
   : StackContainer<FGSTensor>(4, 1)
 {
-  stack_sizes[0] = ngss; stack_sizes[1] = ng;
-  stack_sizes[2] = ny; stack_sizes[3] = nu;
+  stack_sizes = { ngss, ng, ny, nu };
   conts[0] = gss;
   calculateOffsets();
 }
@@ -32,34 +31,21 @@ ZAuxContainer::getType(int i, const Symmetry &s) const
 }
 
 Approximation::Approximation(DynamicModel &m, Journal &j, int ns, bool dr_centr, double qz_crit)
-  : model(m), journal(j), rule_ders(nullptr), rule_ders_ss(nullptr), fdr(nullptr), udr(nullptr),
+  : model(m), journal(j),
     ypart(model.nstat(), model.npred(), model.nboth(), model.nforw()),
-    mom(UNormalMoments(model.order(), model.getVcov())), nvs(4), steps(ns),
+    mom(UNormalMoments(model.order(), model.getVcov())),
+    nvs{ypart.nys(), model.nexog(), model.nexog(), 1 },
+    steps(ns),
     dr_centralize(dr_centr), qz_criterium(qz_crit), ss(ypart.ny(), steps+1)
 {
-  nvs[0] = ypart.nys(); nvs[1] = model.nexog();
-  nvs[2] = model.nexog(); nvs[3] = 1;
-
   ss.nans();
 }
 
-Approximation::~Approximation()
-{
-  if (rule_ders_ss)
-    delete rule_ders_ss;
-  if (rule_ders)
-    delete rule_ders;
-  if (fdr)
-    delete fdr;
-  if (udr)
-    delete udr;
-}
-
 /* This just returns |fdr| with a check that it is created. */
 const FoldDecisionRule &
 Approximation::getFoldDecisionRule() const
 {
-  KORD_RAISE_IF(fdr == nullptr,
+  KORD_RAISE_IF(!fdr,
                 "Folded decision rule has not been created in Approximation::getFoldDecisionRule");
   return *fdr;
 }
@@ -68,7 +54,7 @@ Approximation::getFoldDecisionRule() const
 const UnfoldDecisionRule &
 Approximation::getUnfoldDecisionRule() const
 {
-  KORD_RAISE_IF(udr == nullptr,
+  KORD_RAISE_IF(!udr,
                 "Unfolded decision rule has not been created in Approximation::getUnfoldDecisionRule");
   return *udr;
 }
@@ -147,7 +133,7 @@ Approximation::walkStochSteady()
   model.solveDeterministicSteady();
   approxAtSteady();
   Vector steady0{ss.getCol(0)};
-  steady0 = (const Vector &) model.getSteady();
+  steady0 = model.getSteady();
 
   double sigma_so_far = 0.0;
   double dsigma = (steps == 0) ? 0.0 : 1.0/steps;
@@ -156,14 +142,14 @@ Approximation::walkStochSteady()
       JournalRecordPair pa(journal);
       pa << "Approximation about stochastic steady for sigma=" << sigma_so_far+dsigma << endrec;
 
-      Vector last_steady((const Vector &)model.getSteady());
+      Vector last_steady(model.getSteady());
 
       // calculate fix-point of the last rule for |dsigma|
       /* We form the |DRFixPoint| object from the last rule with
          $\sigma=dsigma$. Then we save the steady state to |ss|. The new steady
          is also put to |model.getSteady()|. */
       DRFixPoint<KOrder::fold> fp(*rule_ders, ypart, model.getSteady(), dsigma);
-      bool converged = fp.calcFixPoint(DecisionRule::horner, model.getSteady());
+      bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
       JournalRecord rec(journal);
       rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
           << fp.getNewtonTotalIter() << ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
@@ -175,14 +161,14 @@ Approximation::walkStochSteady()
           KORD_RAISE_X("Fix point calculation not converged", KORD_FP_NOT_CONV);
         }
       Vector steadyi{ss.getCol(i)};
-      steadyi = (const Vector &) model.getSteady();
+      steadyi = model.getSteady();
 
       // calculate |hh| as expectations of the last $g^{**}$
       /* We form the steady state shift |dy|, which is the new steady state
          minus the old steady state. Then we create |StochForwardDerivs|
          object, which calculates the derivatives of $g^{**}$ expectations at
          new sigma and new steady. */
-      Vector dy((const Vector &)model.getSteady());
+      Vector dy(model.getSteady());
       dy.add(-1.0, last_steady);
 
       StochForwardDerivs<KOrder::fold> hh(ypart, model.nexog(), *rule_ders_ss, mom, dy,
@@ -197,9 +183,8 @@ Approximation::walkStochSteady()
       KOrderStoch korder_stoch(ypart, model.nexog(), model.getModelDerivatives(),
                                hh, journal);
       for (int d = 1; d <= model.order(); d++)
-        {
-          korder_stoch.performStep<KOrder::fold>(d);
-        }
+        korder_stoch.performStep<KOrder::fold>(d);
+
       saveRuleDerivs(korder_stoch.getFoldDers());
 
       check(sigma_so_far+dsigma);
@@ -207,24 +192,14 @@ Approximation::walkStochSteady()
     }
 
   // construct the resulting decision rules
-  if (fdr)
-    {
-      delete fdr;
-      fdr = nullptr;
-    }
-  if (udr)
-    {
-      delete udr;
-      udr = nullptr;
-    }
-
-  fdr = new FoldDecisionRule(*rule_ders, ypart, model.nexog(),
-                             model.getSteady(), 1.0-sigma_so_far);
+  udr.reset();
+  fdr = std::make_unique<FoldDecisionRule>(*rule_ders, ypart, model.nexog(),
+                                           model.getSteady(), 1.0-sigma_so_far);
   if (steps == 0 && dr_centralize)
     {
       // centralize decision rule for zero steps
       DRFixPoint<KOrder::fold> fp(*rule_ders, ypart, model.getSteady(), 1.0);
-      bool converged = fp.calcFixPoint(DecisionRule::horner, model.getSteady());
+      bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
       JournalRecord rec(journal);
       rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
           << fp.getNewtonTotalIter() << ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
@@ -239,9 +214,7 @@ Approximation::walkStochSteady()
       {
         JournalRecordPair recp(journal);
         recp << "Centralizing about fix-point." << endrec;
-        FoldDecisionRule *dr_backup = fdr;
-        fdr = new FoldDecisionRule(*dr_backup, model.getSteady());
-        delete dr_backup;
+        fdr = std::make_unique<FoldDecisionRule>(*fdr, model.getSteady());
       }
     }
 }
@@ -254,14 +227,9 @@ Approximation::walkStochSteady()
 void
 Approximation::saveRuleDerivs(const FGSContainer &g)
 {
-  if (rule_ders)
-    {
-      delete rule_ders;
-      delete rule_ders_ss;
-    }
-  rule_ders = new FGSContainer(g);
-  rule_ders_ss = new FGSContainer(4);
-  for (auto & run : (*rule_ders))
+  rule_ders = std::make_unique<FGSContainer>(g);
+  rule_ders_ss = std::make_unique<FGSContainer>(4);
+  for (auto &run : *rule_ders)
     {
       auto ten = std::make_unique<FGSTensor>(ypart.nstat+ypart.npred, ypart.nyss(), *(run.second));
       rule_ders_ss->insert(std::move(ten));
@@ -287,7 +255,7 @@ Approximation::calcStochShift(Vector &out, double at_sigma) const
                 "Wrong length of output vector for Approximation::calcStochShift");
   out.zeros();
 
-  ZAuxContainer zaux(rule_ders_ss, ypart.nyss(), ypart.ny(),
+  ZAuxContainer zaux(rule_ders_ss.get(), ypart.nyss(), ypart.ny(),
                      ypart.nys(), model.nexog());
 
   int dfac = 1;
@@ -298,7 +266,7 @@ Approximation::calcStochShift(Vector &out, double at_sigma) const
           Symmetry sym{0, d, 0, 0};
 
           // calculate $F_{u'^d}$ via |ZAuxContainer|
-          FGSTensor *ten = new FGSTensor(ypart.ny(), TensorDimens(sym, nvs));
+          auto ten = std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(sym, nvs));
           ten->zeros();
           for (int l = 1; l <= d; l++)
             {
@@ -307,13 +275,11 @@ Approximation::calcStochShift(Vector &out, double at_sigma) const
             }
 
           // multiply with shocks and add to result
-          FGSTensor *tmp = new FGSTensor(ypart.ny(), TensorDimens(Symmetry{0, 0, 0, 0}, nvs));
+          auto tmp = std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(Symmetry{0, 0, 0, 0}, nvs));
           tmp->zeros();
           ten->contractAndAdd(1, *tmp, mom.get(Symmetry{d}));
 
           out.add(pow(at_sigma, d)/dfac, tmp->getData());
-          delete ten;
-          delete tmp;
         }
     }
 }
@@ -359,7 +325,7 @@ Approximation::check(double at_sigma) const
    So we invoke the Sylvester solver for the first dimension with $A=I$,
    $B=-G$, $C=G^T$ and $D=g_u\Sigma g_u^T$. */
 
-TwoDMatrix *
+TwoDMatrix
 Approximation::calcYCov() const
 {
   const TwoDMatrix &gy = rule_ders->get(Symmetry{1, 0, 0, 0});
@@ -367,7 +333,7 @@ Approximation::calcYCov() const
   TwoDMatrix G(model.numeq(), model.numeq());
   G.zeros();
   G.place(gy, 0, model.nstat());
-  TwoDMatrix B((const TwoDMatrix &)G);
+  TwoDMatrix B(const_cast<const TwoDMatrix &>(G));
   B.mult(-1.0);
   TwoDMatrix C(transpose(G));
   TwoDMatrix A(model.numeq(), model.numeq());
@@ -375,10 +341,10 @@ Approximation::calcYCov() const
   for (int i = 0; i < model.numeq(); i++)
     A.get(i, i) = 1.0;
 
-  TwoDMatrix *X = new TwoDMatrix((gu * model.getVcov()) * transpose(gu));
+  TwoDMatrix X((gu * model.getVcov()) * transpose(gu));
 
   GeneralSylvester gs(1, model.numeq(), model.numeq(), 0,
-                      A.getData(), B.getData(), C.getData(), X->getData());
+                      A.getData(), B.getData(), C.getData(), X.getData());
   gs.solve();
 
   return X;
diff --git a/dynare++/kord/approximation.hh b/dynare++/kord/approximation.hh
index 2df8641557131b4c8634ef5be5ffbba2a7818451..0cc77f9f58e65c2f760020dbf85ea83bd6a9c2b3 100644
--- a/dynare++/kord/approximation.hh
+++ b/dynare++/kord/approximation.hh
@@ -55,6 +55,8 @@
 #include "korder.hh"
 #include "journal.hh"
 
+#include <memory>
+
 /* This class is used to calculate derivatives by faa Di Bruno of the
    $$f(g^{**}(g^*(y^*,u,\sigma),u',\sigma),g(y^*,u,\sigma),y^*,u)$$ with
    respect $u'$. In order to keep it as simple as possible, the class
@@ -108,10 +110,10 @@ class Approximation
 {
   DynamicModel &model;
   Journal &journal;
-  FGSContainer *rule_ders;
-  FGSContainer *rule_ders_ss;
-  FoldDecisionRule *fdr;
-  UnfoldDecisionRule *udr;
+  std::unique_ptr<FGSContainer> rule_ders;
+  std::unique_ptr<FGSContainer> rule_ders_ss;
+  std::unique_ptr<FoldDecisionRule> fdr;
+  std::unique_ptr<UnfoldDecisionRule> udr;
   const PartitionY ypart;
   const FNormalMoments mom;
   IntSequence nvs;
@@ -121,11 +123,9 @@ class Approximation
   TwoDMatrix ss;
 public:
   Approximation(DynamicModel &m, Journal &j, int ns, bool dr_centr, double qz_crit);
-  virtual
-  ~Approximation();
 
-  const FoldDecisionRule&getFoldDecisionRule() const;
-  const UnfoldDecisionRule&getUnfoldDecisionRule() const;
+  const FoldDecisionRule &getFoldDecisionRule() const;
+  const UnfoldDecisionRule &getUnfoldDecisionRule() const;
   const TwoDMatrix &
   getSS() const
   {
@@ -138,16 +138,16 @@ public:
   }
 
   void walkStochSteady();
-  TwoDMatrix *calcYCov() const;
-  const FGSContainer *
+  TwoDMatrix calcYCov() const;
+  const FGSContainer &
   get_rule_ders() const
   {
-    return rule_ders;
+    return *rule_ders;
   }
-  const FGSContainer *
+  const FGSContainer &
   get_rule_ders_ss() const
   {
-    return rule_ders;
+    return *rule_ders_ss;
   }
 protected:
   void approxAtSteady();
diff --git a/dynare++/kord/decision_rule.cc b/dynare++/kord/decision_rule.cc
index 6e86cce92dbba82c9fc12d73a997e00aa0b00870..10de34f239d88b010b35aefb59f8cb8b003dfc36 100644
--- a/dynare++/kord/decision_rule.cc
+++ b/dynare++/kord/decision_rule.cc
@@ -13,29 +13,12 @@
 #include <utility>
 #include <memory>
 
-template <>
-int DRFixPoint<KOrder::fold>::max_iter = 10000;
-template <>
-int DRFixPoint<KOrder::unfold>::max_iter = 10000;
-template <>
-double DRFixPoint<KOrder::fold>::tol = 1.e-10;
-template <>
-double DRFixPoint<KOrder::unfold>::tol = 1.e-10;
-template <>
-int DRFixPoint<KOrder::fold>::max_newton_iter = 50;
-template <>
-int DRFixPoint<KOrder::unfold>::max_newton_iter = 50;
-template <>
-int DRFixPoint<KOrder::fold>::newton_pause = 100;
-template <>
-int DRFixPoint<KOrder::unfold>::newton_pause = 100;
-
 // |FoldDecisionRule| conversion from |UnfoldDecisionRule|
 FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr)
   : DecisionRuleImpl<KOrder::fold>(ctraits<KOrder::fold>::Tpol(udr.nrows(), udr.nvars()),
                                    udr.ypart, udr.nu, udr.ysteady)
 {
-  for (const auto & it : udr)
+  for (const auto &it : udr)
     insert(std::make_unique<ctraits<KOrder::fold>::Ttensym>(*(it.second)));
 }
 
@@ -44,19 +27,10 @@ UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule &fdr)
   : DecisionRuleImpl<KOrder::unfold>(ctraits<KOrder::unfold>::Tpol(fdr.nrows(), fdr.nvars()),
                                      fdr.ypart, fdr.nu, fdr.ysteady)
 {
-  for (const auto & it : fdr)
+  for (const auto &it : fdr)
     insert(std::make_unique<ctraits<KOrder::unfold>::Ttensym>(*(it.second)));
 }
 
-SimResults::~SimResults()
-{
-  for (int i = 0; i < getNumSets(); i++)
-    {
-      delete data[i];
-      delete shocks[i];
-    }
-}
-
 /* This runs simulations with an output to journal file. Note that we
    report how many simulations had to be thrown out due to Nan or Inf. */
 
@@ -92,7 +66,7 @@ SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
     {
       RandomShockRealization sr(vcov, seed_generator::get_new_seed());
       rsrs.push_back(sr);
-      gr.insert(std::make_unique<SimulationWorker>(*this, dr, DecisionRule::horner,
+      gr.insert(std::make_unique<SimulationWorker>(*this, dr, DecisionRule::emethod::horner,
                                                    num_per+num_burn, start, rsrs.back()));
     }
   gr.run();
@@ -103,39 +77,35 @@ SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
    and shocks are thrown away. */
 
 bool
-SimResults::addDataSet(TwoDMatrix *d, ExplicitShockRealization *sr, const ConstVector &st)
+SimResults::addDataSet(const TwoDMatrix &d, const ExplicitShockRealization &sr, const ConstVector &st)
 {
-  KORD_RAISE_IF(d->nrows() != num_y,
+  KORD_RAISE_IF(d.nrows() != num_y,
                 "Incompatible number of rows for SimResults::addDataSets");
-  KORD_RAISE_IF(d->ncols() != num_per+num_burn,
+  KORD_RAISE_IF(d.ncols() != num_per+num_burn,
                 "Incompatible number of cols for SimResults::addDataSets");
   bool ret = false;
-  if (d->isFinite())
+  if (d.isFinite())
     {
-      data.push_back(new TwoDMatrix((const TwoDMatrix &) (*d), num_burn, num_per));
-      shocks.push_back(new ExplicitShockRealization(
-                                                    ConstTwoDMatrix(sr->getShocks(), num_burn, num_per)));
+      data.emplace_back(d, num_burn, num_per);
+      shocks.emplace_back(ConstTwoDMatrix(sr.getShocks(), num_burn, num_per));
       if (num_burn == 0)
         start.emplace_back(st);
       else
-        start.emplace_back(d->getCol(num_burn-1));
+        start.emplace_back(d.getCol(num_burn-1));
       ret = true;
     }
 
-  delete d;
-  delete sr;
   return ret;
 }
 
 void
-SimResults::writeMat(const char *base, const char *lname) const
+SimResults::writeMat(const std::string &base, const std::string &lname) const
 {
-  char matfile_name[100];
-  sprintf(matfile_name, "%s.mat", base);
-  mat_t *matfd = Mat_Create(matfile_name, nullptr);
-  if (matfd != nullptr)
+  std::string matfile_name = base + ".mat";
+  mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr);
+  if (matfd)
     {
-      writeMat(matfd, lname);
+      writeMat(matfd, lname.c_str());
       Mat_Close(matfd);
     }
 }
@@ -144,17 +114,14 @@ SimResults::writeMat(const char *base, const char *lname) const
    appended. If there is only one matrix, the index is not appended. */
 
 void
-SimResults::writeMat(mat_t *fd, const char *lname) const
+SimResults::writeMat(mat_t *fd, const std::string &lname) const
 {
-  char tmp[100];
   for (int i = 0; i < getNumSets(); i++)
     {
+      std::string tmp = lname + "_data";
       if (getNumSets() > 1)
-        sprintf(tmp, "%s_data%d", lname, i+1);
-      else
-        sprintf(tmp, "%s_data", lname);
-      ConstTwoDMatrix m(*(data[i]));
-      m.writeMat(fd, tmp);
+        tmp += std::to_string(i+1);
+      data[i].writeMat(fd, tmp);
     }
 }
 
@@ -178,14 +145,10 @@ SimResultsStats::simulate(int num_sim, const DecisionRule &dr,
 
 /* Here we do not save the data itself, we save only mean and vcov. */
 void
-SimResultsStats::writeMat(mat_t *fd, const char *lname) const
+SimResultsStats::writeMat(mat_t *fd, const std::string &lname) const
 {
-  char tmp[100];
-  sprintf(tmp, "%s_mean", lname);
-  ConstTwoDMatrix m(num_y, 1, mean);
-  m.writeMat(fd, tmp);
-  sprintf(tmp, "%s_vcov", lname);
-  ConstTwoDMatrix(vcov).writeMat(fd, tmp);
+  ConstTwoDMatrix(num_y, 1, mean).writeMat(fd, lname + "_mean");;
+  vcov.writeMat(fd, lname + "_vcov");
 }
 
 void
@@ -195,11 +158,11 @@ SimResultsStats::calcMean()
   if (data.size()*num_per > 0)
     {
       double mult = 1.0/data.size()/num_per;
-      for (auto & i : data)
+      for (const auto &i : data)
         {
           for (int j = 0; j < num_per; j++)
             {
-              ConstVector col{i->getCol(j)};
+              ConstVector col{i.getCol(j)};
               mean.add(mult, col);
             }
         }
@@ -213,28 +176,19 @@ SimResultsStats::calcVcov()
     {
       vcov.zeros();
       double mult = 1.0/(data.size()*num_per - 1);
-      for (auto & i : data)
-        {
-          const TwoDMatrix &d = *i;
-          for (int j = 0; j < num_per; j++)
-            {
-              for (int m = 0; m < num_y; m++)
-                {
-                  for (int n = m; n < num_y; n++)
-                    {
-                      double s = (d.get(m, j)-mean[m])*(d.get(n, j)-mean[n]);
-                      vcov.get(m, n) += mult*s;
-                      if (m != n)
-                        vcov.get(n, m) += mult*s;
-                    }
-                }
-            }
-        }
+      for (const auto &d : data)
+        for (int j = 0; j < num_per; j++)
+          for (int m = 0; m < num_y; m++)
+            for (int n = m; n < num_y; n++)
+              {
+                double s = (d.get(m, j)-mean[m])*(d.get(n, j)-mean[n]);
+                vcov.get(m, n) += mult*s;
+                if (m != n)
+                  vcov.get(n, m) += mult*s;
+              }
     }
   else
-    {
-      vcov.infs();
-    }
+    vcov.infs();
 }
 
 void
@@ -256,13 +210,10 @@ SimResultsDynamicStats::simulate(int num_sim, const DecisionRule &dr,
 }
 
 void
-SimResultsDynamicStats::writeMat(mat_t *fd, const char *lname) const
+SimResultsDynamicStats::writeMat(mat_t *fd, const std::string &lname) const
 {
-  char tmp[100];
-  sprintf(tmp, "%s_cond_mean", lname);
-  ConstTwoDMatrix(mean).writeMat(fd, tmp);
-  sprintf(tmp, "%s_cond_variance", lname);
-  ConstTwoDMatrix(variance).writeMat(fd, tmp);
+  mean.writeMat(fd, lname + "_cond_mean");
+  variance.writeMat(fd, lname + "_cond_variance");
 }
 
 void
@@ -275,9 +226,9 @@ SimResultsDynamicStats::calcMean()
       for (int j = 0; j < num_per; j++)
         {
           Vector meanj{mean.getCol(j)};
-          for (auto & i : data)
+          for (const auto &i : data)
             {
-              ConstVector col{i->getCol(j)};
+              ConstVector col{i.getCol(j)};
               meanj.add(mult, col);
             }
         }
@@ -295,9 +246,9 @@ SimResultsDynamicStats::calcVariance()
         {
           ConstVector meanj{mean.getCol(j)};
           Vector varj{variance.getCol(j)};
-          for (auto & i : data)
+          for (const auto &i : data)
             {
-              Vector col{i->getCol(j)};
+              Vector col{i.getCol(j)};
               col.add(-1.0, meanj);
               for (int k = 0; k < col.length(); k++)
                 col[k] = col[k]*col[k];
@@ -306,9 +257,7 @@ SimResultsDynamicStats::calcVariance()
         }
     }
   else
-    {
-      variance.infs();
-    }
+    variance.infs();
 }
 
 void
@@ -334,7 +283,7 @@ SimResultsIRF::simulate(const DecisionRule &dr)
 {
   sthread::detach_thread_group gr;
   for (int idata = 0; idata < control.getNumSets(); idata++)
-    gr.insert(std::make_unique<SimulationIRFWorker>(*this, dr, DecisionRule::horner,
+    gr.insert(std::make_unique<SimulationIRFWorker>(*this, dr, DecisionRule::emethod::horner,
                                                     num_per, idata, ishock, imp));
   gr.run();
 }
@@ -345,8 +294,8 @@ SimResultsIRF::calcMeans()
   means.zeros();
   if (data.size() > 0)
     {
-      for (auto & i : data)
-        means.add(1.0, *i);
+      for (const auto &i : data)
+        means.add(1.0, i);
       means.mult(1.0/data.size());
     }
 }
@@ -357,9 +306,9 @@ SimResultsIRF::calcVariances()
   if (data.size() > 1)
     {
       variances.zeros();
-      for (auto & i : data)
+      for (const auto &i : data)
         {
-          TwoDMatrix d((const TwoDMatrix &)(*i));
+          TwoDMatrix d(i);
           d.add(-1.0, means);
           for (int j = 0; j < d.nrows(); j++)
             for (int k = 0; k < d.ncols(); k++)
@@ -368,19 +317,14 @@ SimResultsIRF::calcVariances()
         }
     }
   else
-    {
-      variances.infs();
-    }
+    variances.infs();
 }
 
 void
-SimResultsIRF::writeMat(mat_t *fd, const char *lname) const
+SimResultsIRF::writeMat(mat_t *fd, const std::string &lname) const
 {
-  char tmp[100];
-  sprintf(tmp, "%s_mean", lname);
-  means.writeMat(fd, tmp);
-  sprintf(tmp, "%s_var", lname);
-  variances.writeMat(fd, tmp);
+  means.writeMat(fd, lname + "_mean");
+  variances.writeMat(fd, lname + "_var");
 }
 
 void
@@ -416,21 +360,17 @@ RTSimResultsStats::simulate(int num_sim, const DecisionRule &dr, const Vector &s
     {
       RandomShockRealization sr(vcov, seed_generator::get_new_seed());
       rsrs.push_back(sr);
-      gr.insert(std::make_unique<RTSimulationWorker>(*this, dr, DecisionRule::horner,
+      gr.insert(std::make_unique<RTSimulationWorker>(*this, dr, DecisionRule::emethod::horner,
                                                      num_per, start, rsrs.back()));
     }
   gr.run();
 }
 
 void
-RTSimResultsStats::writeMat(mat_t *fd, const char *lname)
+RTSimResultsStats::writeMat(mat_t *fd, const std::string &lname)
 {
-  char tmp[100];
-  sprintf(tmp, "%s_rt_mean", lname);
-  ConstTwoDMatrix m(nc.getDim(), 1, mean);
-  m.writeMat(fd, tmp);
-  sprintf(tmp, "%s_rt_vcov", lname);
-  ConstTwoDMatrix(vcov).writeMat(fd, tmp);
+  ConstTwoDMatrix(nc.getDim(), 1, mean).writeMat(fd, lname + "_rt_mean");
+  vcov.writeMat(fd, lname + "_rt_vcov");
 }
 
 IRFResults::IRFResults(const DynamicModel &mod, const DecisionRule &dr,
@@ -440,51 +380,42 @@ IRFResults::IRFResults(const DynamicModel &mod, const DecisionRule &dr,
 {
   int num_per = control.getNumPer();
   JournalRecordPair pa(journal);
-  pa << "Calculating IRFs against control for " << (int) irf_list_ind.size() << " shocks and for "
+  pa << "Calculating IRFs against control for " << static_cast<int>(irf_list_ind.size()) << " shocks and for "
      << num_per << " periods" << endrec;
   const TwoDMatrix &vcov = mod.getVcov();
   for (int ishock : irf_list_ind)
     {
       double stderror = sqrt(vcov.get(ishock, ishock));
-      irf_res.push_back(new SimResultsIRF(control, model.numeq(), num_per,
-                                          ishock, stderror));
-      irf_res.push_back(new SimResultsIRF(control, model.numeq(), num_per,
-                                          ishock, -stderror));
+      irf_res.emplace_back(control, model.numeq(), num_per,
+                           ishock, stderror);
+      irf_res.emplace_back(control, model.numeq(), num_per,
+                           ishock, -stderror);
     }
 
   for (unsigned int ii = 0; ii < irf_list_ind.size(); ii++)
     {
-      irf_res[2*ii]->simulate(dr, journal);
-      irf_res[2*ii+1]->simulate(dr, journal);
+      irf_res[2*ii].simulate(dr, journal);
+      irf_res[2*ii+1].simulate(dr, journal);
     }
 }
 
-IRFResults::~IRFResults()
-{
-  for (auto & irf_re : irf_res)
-    delete irf_re;
-}
-
 void
-IRFResults::writeMat(mat_t *fd, const char *prefix) const
+IRFResults::writeMat(mat_t *fd, const std::string &prefix) const
 {
   for (unsigned int i = 0; i < irf_list_ind.size(); i++)
     {
-      char tmp[100];
       int ishock = irf_list_ind[i];
-      const char *shockname = model.getExogNames().getName(ishock);
-      sprintf(tmp, "%s_irfp_%s", prefix, shockname);
-      irf_res[2*i]->writeMat(fd, tmp);
-      sprintf(tmp, "%s_irfm_%s", prefix, shockname);
-      irf_res[2*i+1]->writeMat(fd, tmp);
+      auto shockname = model.getExogNames().getName(ishock);
+      irf_res[2*i].writeMat(fd, prefix + "_irfp_" + shockname);
+      irf_res[2*i+1].writeMat(fd, prefix + "_irfm_" + shockname);
     }
 }
 
 void
 SimulationWorker::operator()(std::mutex &mut)
 {
-  auto *esr = new ExplicitShockRealization(sr, np);
-  TwoDMatrix *m = dr.simulate(em, np, st, *esr);
+  ExplicitShockRealization esr(sr, np);
+  TwoDMatrix m{dr.simulate(em, np, st, esr)};
   {
     std::unique_lock<std::mutex> lk{mut};
     res.addDataSet(m, esr, st);
@@ -497,11 +428,10 @@ SimulationWorker::operator()(std::mutex &mut)
 void
 SimulationIRFWorker::operator()(std::mutex &mut)
 {
-  auto *esr
-    = new ExplicitShockRealization(res.control.getShocks(idata));
-  esr->addToShock(ishock, 0, imp);
-  TwoDMatrix *m = dr.simulate(em, np, res.control.getStart(idata), *esr);
-  m->add(-1.0, res.control.getData(idata));
+  ExplicitShockRealization esr(res.control.getShocks(idata));
+  esr.addToShock(ishock, 0, imp);
+  TwoDMatrix m{dr.simulate(em, np, res.control.getStart(idata), esr)};
+  m.add(-1.0, res.control.getData(idata));
   {
     std::unique_lock<std::mutex> lk{mut};
     res.addDataSet(m, esr, res.control.getStart(idata));
@@ -579,8 +509,7 @@ RandomShockRealization::choleskyFactor(const ConstTwoDMatrix &v)
 void
 RandomShockRealization::schurFactor(const ConstTwoDMatrix &v)
 {
-  SymSchurDecomp ssd(v);
-  ssd.getFactor(factor);
+  SymSchurDecomp(v).getFactor(factor);
 }
 
 void
diff --git a/dynare++/kord/decision_rule.hh b/dynare++/kord/decision_rule.hh
index 97a92df675894677ea0d7b8444ba6636e2b7fa40..ed0165c7f827608b18d8acbc0fe51058fb8a7f8a 100644
--- a/dynare++/kord/decision_rule.hh
+++ b/dynare++/kord/decision_rule.hh
@@ -23,7 +23,9 @@
 #include "korder.hh"
 #include "normal_conjugate.hh"
 
+#include <memory>
 #include <random>
+#include <string>
 
 /* This is a general interface to a shock realizations. The interface
    has only one method returning the shock realizations at the given
@@ -33,8 +35,7 @@
 class ShockRealization
 {
 public:
-  virtual ~ShockRealization()
-  = default;
+  virtual ~ShockRealization() = default;
   virtual void get(int n, Vector &out) = 0;
   virtual int numShocks() const = 0;
 };
@@ -55,19 +56,18 @@ public:
 class DecisionRule
 {
 public:
-  enum emethod { horner, trad };
-  virtual ~DecisionRule()
-  = default;
-  virtual TwoDMatrix *simulate(emethod em, int np, const ConstVector &ystart,
-                               ShockRealization &sr) const = 0;
+  enum class emethod { horner, trad };
+  virtual ~DecisionRule() = default;
+  virtual TwoDMatrix simulate(emethod em, int np, const ConstVector &ystart,
+                              ShockRealization &sr) const = 0;
   virtual void eval(emethod em, Vector &out, const ConstVector &v) const = 0;
   virtual void evaluate(emethod em, Vector &out, const ConstVector &ys,
                         const ConstVector &u) const = 0;
-  virtual void writeMat(mat_t *fd, const char *prefix) const = 0;
-  virtual DecisionRule *centralizedClone(const Vector &fixpoint) const = 0;
-  virtual const Vector&getSteady() const = 0;
+  virtual void writeMat(mat_t *fd, const std::string &prefix) const = 0;
+  virtual std::unique_ptr<DecisionRule> centralizedClone(const Vector &fixpoint) const = 0;
+  virtual const Vector &getSteady() const = 0;
   virtual int nexog() const = 0;
-  virtual const PartitionY&getYPart() const = 0;
+  virtual const PartitionY &getYPart() const = 0;
 };
 
 /* The main purpose of this class is to implement |DecisionRule|
@@ -131,12 +131,12 @@ public:
   {
     return ysteady;
   }
-  TwoDMatrix *simulate(emethod em, int np, const ConstVector &ystart,
-                       ShockRealization &sr) const override;
+  TwoDMatrix simulate(emethod em, int np, const ConstVector &ystart,
+                      ShockRealization &sr) const override;
   void evaluate(emethod em, Vector &out, const ConstVector &ys,
                 const ConstVector &u) const override;
-  DecisionRule *centralizedClone(const Vector &fixpoint) const override;
-  void writeMat(mat_t *fd, const char *prefix) const override;
+  std::unique_ptr<DecisionRule> centralizedClone(const Vector &fixpoint) const override;
+  void writeMat(mat_t *fd, const std::string &prefix) const override;
 
   int
   nexog() const override
@@ -279,13 +279,13 @@ DecisionRuleImpl<t>::centralize(const DecisionRuleImpl &dr)
    |ysteady| is added to all columns of the result. */
 
 template <int t>
-TwoDMatrix *
+TwoDMatrix
 DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
                               ShockRealization &sr) const
 {
   KORD_RAISE_IF(ysteady.length() != ystart.length(),
                 "Start and steady lengths differ in DecisionRuleImpl::simulate");
-  auto *res = new TwoDMatrix(ypart.ny(), np);
+  TwoDMatrix res(ypart.ny(), np);
 
   // initialize vectors and subvectors for simulation
   /* Here allocate the stack vector $(\Delta y^*, u)$, define the
@@ -303,7 +303,7 @@ DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
   dy = ystart_pred;
   dy.add(-1.0, ysteady_pred);
   sr.get(0, u);
-  Vector out{res->getCol(0)};
+  Vector out{res.getCol(0)};
   eval(em, out, dyu);
 
   // perform all other steps of simulations
@@ -312,17 +312,17 @@ DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
   int i = 1;
   while (i < np)
     {
-      ConstVector ym{res->getCol(i-1)};
+      ConstVector ym{res.getCol(i-1)};
       ConstVector dym(ym, ypart.nstat, ypart.nys());
       dy = dym;
       sr.get(i, u);
-      Vector out{res->getCol(i)};
+      Vector out{res.getCol(i)};
       eval(em, out, dyu);
       if (!out.isFinite())
         {
           if (i+1 < np)
             {
-              TwoDMatrix rest(*res, i+1, np-i-1);
+              TwoDMatrix rest(res, i+1, np-i-1);
               rest.zeros();
             }
           break;
@@ -335,7 +335,7 @@ DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
      and leave the padded columns to zero. */
   for (int j = 0; j < i; j++)
     {
-      Vector col{res->getCol(j)};
+      Vector col{res.getCol(j)};
       col.add(1.0, ysteady);
     }
 
@@ -371,10 +371,10 @@ DecisionRuleImpl<t>::evaluate(emethod em, Vector &out, const ConstVector &ys,
    centralized constructor. */
 
 template <int t>
-DecisionRule *
+std::unique_ptr<DecisionRule>
 DecisionRuleImpl<t>::centralizedClone(const Vector &fixpoint) const
 {
-  return new DecisionRuleImpl<t>(*this, fixpoint);
+  return std::make_unique<DecisionRuleImpl<t>>(*this, fixpoint);
 }
 
 /* Here we only encapsulate two implementations to one, deciding
@@ -384,7 +384,7 @@ template <int t>
 void
 DecisionRuleImpl<t>::eval(emethod em, Vector &out, const ConstVector &v) const
 {
-  if (em == DecisionRule::horner)
+  if (em == emethod::horner)
     _Tparent::evalHorner(out, v);
   else
     _Tparent::evalTrad(out, v);
@@ -394,14 +394,12 @@ DecisionRuleImpl<t>::eval(emethod em, Vector &out, const ConstVector &v) const
 
 template <int t>
 void
-DecisionRuleImpl<t>::writeMat(mat_t *fd, const char *prefix) const
+DecisionRuleImpl<t>::writeMat(mat_t *fd, const std::string &prefix) const
 {
   ctraits<t>::Tpol::writeMat(fd, prefix);
   TwoDMatrix dum(ysteady.length(), 1);
   dum.getData() = ysteady;
-  char tmp[100];
-  sprintf(tmp, "%s_ss", prefix);
-  ConstTwoDMatrix(dum).writeMat(fd, tmp);
+  ConstTwoDMatrix(dum).writeMat(fd, prefix + "_ss");
 }
 
 /* This is exactly the same as |DecisionRuleImpl<KOrder::fold>|. The
@@ -483,20 +481,18 @@ template <int t>
 class DRFixPoint : public ctraits<t>::Tpol
 {
   using _Tparent = typename ctraits<t>::Tpol;
-  static int max_iter;
-  static int max_newton_iter;
-  static int newton_pause;
-  static double tol;
+  constexpr static int max_iter = 10000;
+  constexpr static int max_newton_iter = 50;
+  constexpr static int newton_pause = 100;
+  constexpr static double tol = 1e-10;
   const Vector ysteady;
   const PartitionY ypart;
-  _Tparent *bigf;
-  _Tparent *bigfder;
+  std::unique_ptr<_Tparent> bigf;
+  std::unique_ptr<_Tparent> bigfder;
 public:
   using emethod = typename DecisionRule::emethod;
   DRFixPoint(const _Tg &g, const PartitionY &yp,
              const Vector &ys, double sigma);
-  
-  ~DRFixPoint() override;
 
   bool calcFixPoint(emethod em, Vector &out);
 
@@ -534,24 +530,15 @@ template <int t>
 DRFixPoint<t>::DRFixPoint(const _Tg &g, const PartitionY &yp,
                           const Vector &ys, double sigma)
   : ctraits<t>::Tpol(yp.ny(), yp.nys()),
-  ysteady(ys), ypart(yp), bigf(nullptr), bigfder(nullptr)
+  ysteady(ys), ypart(yp)
 {
   fillTensors(g, sigma);
   _Tparent yspol(ypart.nstat, ypart.nys(), *this);
-  bigf = new _Tparent((const _Tparent &) yspol);
+  bigf = std::make_unique<_Tparent>(const_cast<const _Tparent &>(yspol));
   _Ttensym &frst = bigf->get(Symmetry{1});
   for (int i = 0; i < ypart.nys(); i++)
     frst.get(i, i) = frst.get(i, i) - 1;
-  bigfder = new _Tparent(*bigf, 0);
-}
-
-template <int t>
-DRFixPoint<t>::~DRFixPoint()
-{
-  if (bigf)
-    delete bigf;
-  if (bigfder)
-    delete bigfder;
+  bigfder = std::make_unique<_Tparent>(*bigf, 0);
 }
 
 /* Here we fill the tensors for the |DRFixPoint| class. We ignore the
@@ -602,7 +589,7 @@ bool
 DRFixPoint<t>::solveNewton(Vector &y)
 {
   const double urelax_threshold = 1.e-5;
-  Vector sol((const Vector &)y);
+  Vector sol(const_cast<const Vector &>(y));
   Vector delta(y.length());
   newton_iter_last = 0;
   bool delta_finite = true;
@@ -632,7 +619,7 @@ DRFixPoint<t>::solveNewton(Vector &y)
           urelax = 1.0;
           while (!urelax_found && urelax > urelax_threshold)
             {
-              Vector soltmp((const Vector &)sol);
+              Vector soltmp(const_cast<const Vector &>(sol));
               soltmp.add(-urelax, delta);
               Vector f(sol.length());
               bigf->evalHorner(f, soltmp);
@@ -656,7 +643,7 @@ DRFixPoint<t>::solveNewton(Vector &y)
   newton_iter_total += newton_iter_last;
   if (!converged)
     newton_iter_last = 0;
-  y = (const Vector &) sol;
+  y = const_cast<const Vector &>(sol);
   return converged;
 }
 
@@ -727,16 +714,14 @@ protected:
   int num_y;
   int num_per;
   int num_burn;
-  std::vector<TwoDMatrix *> data;
-  std::vector<ExplicitShockRealization *> shocks;
+  std::vector<TwoDMatrix> data;
+  std::vector<ExplicitShockRealization> shocks;
   std::vector<ConstVector> start;
 public:
   SimResults(int ny, int nper, int nburn = 0)
     : num_y(ny), num_per(nper), num_burn(nburn)
   {
   }
-  virtual
-  ~SimResults();
   void simulate(int num_sim, const DecisionRule &dr, const Vector &start,
                 const TwoDMatrix &vcov, Journal &journal);
   void simulate(int num_sim, const DecisionRule &dr, const Vector &start,
@@ -754,17 +739,17 @@ public:
   int
   getNumSets() const
   {
-    return (int) data.size();
+    return static_cast<int>(data.size());
   }
   const TwoDMatrix &
   getData(int i) const
   {
-    return *(data[i]);
+    return data[i];
   }
   const ExplicitShockRealization &
   getShocks(int i) const
   {
-    return *(shocks[i]);
+    return shocks[i];
   }
   const ConstVector &
   getStart(int i) const
@@ -772,9 +757,9 @@ public:
     return start[i];
   }
 
-  bool addDataSet(TwoDMatrix *d, ExplicitShockRealization *sr, const ConstVector &st);
-  void writeMat(const char *base, const char *lname) const;
-  void writeMat(mat_t *fd, const char *lname) const;
+  bool addDataSet(const TwoDMatrix &d, const ExplicitShockRealization &sr, const ConstVector &st);
+  void writeMat(const std::string &base, const std::string &lname) const;
+  void writeMat(mat_t *fd, const std::string &lname) const;
 };
 
 /* This does the same as |SimResults| plus it calculates means and
@@ -792,7 +777,7 @@ public:
   }
   void simulate(int num_sim, const DecisionRule &dr, const Vector &start,
                 const TwoDMatrix &vcov, Journal &journal);
-  void writeMat(mat_t *fd, const char *lname) const;
+  void writeMat(mat_t *fd, const std::string &lname) const;
 protected:
   void calcMean();
   void calcVcov();
@@ -814,7 +799,7 @@ public:
   }
   void simulate(int num_sim, const DecisionRule &dr, const Vector &start,
                 const TwoDMatrix &vcov, Journal &journal);
-  void writeMat(mat_t *fd, const char *lname) const;
+  void writeMat(mat_t *fd, const std::string &lname) const;
 protected:
   void calcMean();
   void calcVariance();
@@ -846,7 +831,7 @@ public:
   }
   void simulate(const DecisionRule &dr, Journal &journal);
   void simulate(const DecisionRule &dr);
-  void writeMat(mat_t *fd, const char *lname) const;
+  void writeMat(mat_t *fd, const std::string &lname) const;
 protected:
   void calcMeans();
   void calcVariances();
@@ -881,7 +866,7 @@ public:
                 const TwoDMatrix &vcov, Journal &journal);
   void simulate(int num_sim, const DecisionRule &dr, const Vector &start,
                 const TwoDMatrix &vcov);
-  void writeMat(mat_t *fd, const char *lname);
+  void writeMat(mat_t *fd, const std::string &lname);
 };
 
 /* For each shock, this simulates plus and minus impulse. The class
@@ -901,15 +886,14 @@ public:
 class DynamicModel;
 class IRFResults
 {
-  std::vector<SimResultsIRF *> irf_res;
+  std::vector<SimResultsIRF> irf_res;
   const DynamicModel &model;
   std::vector<int> irf_list_ind;
 public:
   IRFResults(const DynamicModel &mod, const DecisionRule &dr,
              const SimResults &control, std::vector<int> ili,
              Journal &journal);
-  ~IRFResults();
-  void writeMat(mat_t *fd, const char *prefix) const;
+  void writeMat(mat_t *fd, const std::string &prefix) const;
 };
 
 /* This worker simulates the given decision rule and inserts the result
@@ -1003,12 +987,6 @@ public:
   {
     schurFactor(v);
   }
-  RandomShockRealization(const RandomShockRealization &sr)
-    : mtwister(sr.mtwister), factor(sr.factor)
-  {
-  }
-  ~RandomShockRealization()
-  override = default;
   void get(int n, Vector &out) override;
   int
   numShocks() const override
@@ -1027,14 +1005,10 @@ class ExplicitShockRealization : virtual public ShockRealization
 {
   TwoDMatrix shocks;
 public:
-  ExplicitShockRealization(const ConstTwoDMatrix &sh)
+  explicit ExplicitShockRealization(const ConstTwoDMatrix &sh)
     : shocks(sh)
   {
   }
-  ExplicitShockRealization(const ExplicitShockRealization &sr)
-    : shocks(sr.shocks)
-  {
-  }
   ExplicitShockRealization(ShockRealization &sr, int num_per);
   void get(int n, Vector &out) override;
   int
@@ -1043,7 +1017,7 @@ public:
     return shocks.nrows();
   }
   const TwoDMatrix &
-  getShocks()
+  getShocks() const
   {
     return shocks;
   }
diff --git a/dynare++/kord/global_check.cc b/dynare++/kord/global_check.cc
index 298eababc6531b2057e2c8bd88f63ffd833e333f..43027d5e5e05eea0ea6dd7c4bb627ed42417fe75 100644
--- a/dynare++/kord/global_check.cc
+++ b/dynare++/kord/global_check.cc
@@ -69,7 +69,7 @@ ResidFunction::setYU(const ConstVector &ys, const ConstVector &xx)
   ystar = new Vector(ys);
   u = new Vector(xx);
   yplus = new Vector(model->numeq());
-  approx.getFoldDecisionRule().evaluate(DecisionRule::horner,
+  approx.getFoldDecisionRule().evaluate(DecisionRule::emethod::horner,
                                         *yplus, *ystar, *u);
 
   // make a tensor polynomial of in-place subtensors from decision rule
@@ -309,10 +309,9 @@ GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const char *prefix,
   /* Here we set |ycovfac| to the symmetric Schur decomposition factor of
      a submatrix of covariances of all endogenous variables. The submatrix
      corresponds to state variables (predetermined plus both). */
-  TwoDMatrix *ycov = approx.calcYCov();
-  TwoDMatrix ycovpred((const TwoDMatrix &)*ycov, model.nstat(), model.nstat(),
+  TwoDMatrix ycov{approx.calcYCov()};
+  TwoDMatrix ycovpred((const TwoDMatrix &) ycov, model.nstat(), model.nstat(),
                       model.npred()+model.nboth(), model.npred()+model.nboth());
-  delete ycov;
   SymSchurDecomp ssd(ycovpred);
   ssd.correctDefinitness(1.e-05);
   TwoDMatrix ycovfac(ycovpred.nrows(), ycovpred.ncols());
@@ -400,18 +399,16 @@ GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const char *prefix,
   pa << "Calculating errors at " << m
      << " simulated points" << endrec;
   RandomShockRealization sr(model.getVcov(), seed_generator::get_new_seed());
-  TwoDMatrix *y = approx.getFoldDecisionRule().simulate(DecisionRule::horner,
-                                                        m, model.getSteady(), sr);
+  TwoDMatrix y{approx.getFoldDecisionRule().simulate(DecisionRule::emethod::horner,
+                                                     m, model.getSteady(), sr)};
   TwoDMatrix x(model.nexog(), m);
   x.zeros();
   TwoDMatrix out(model.numeq(), m);
-  check(max_evals, *y, x, out);
+  check(max_evals, y, x, out);
 
   char tmp[100];
   sprintf(tmp, "%s_simul_points", prefix);
-  y->writeMat(fd, tmp);
+  y.writeMat(fd, tmp);
   sprintf(tmp, "%s_simul_errors", prefix);
   out.writeMat(fd, tmp);
-
-  delete y;
 }
diff --git a/dynare++/kord/journal.cc b/dynare++/kord/journal.cc
index 825f730374fc4933b23f93bd37188a21cfe484ee..5f42e3384bcc5a1fa20260e10265b033092606e4 100644
--- a/dynare++/kord/journal.cc
+++ b/dynare++/kord/journal.cc
@@ -3,110 +3,85 @@
 #include "journal.hh"
 #include "kord_exception.hh"
 
-#if !defined(__MINGW32__)
-# include <sys/resource.h>
-# include <sys/utsname.h>
-#endif
-#include <cstdlib>
-#include <unistd.h>
+#include <iomanip>
+#include <cmath>
 #include <ctime>
 
-SystemResources _sysres;
-#if defined(__MINGW32__)
-//|sysconf| Win32 implementation
-/* Here we implement |sysconf| for MinGW. We implement only page size,
-   number of physial pages, and a number of available physical pages. The
-   pagesize is set to 1024 bytes, real pagesize can differ but it is not
-   important. We can do this since Windows kernel32 |GlobalMemoryStatus|
-   call returns number of bytes.
-
-   Number of online processors is not implemented and returns -1, since
-   Windows kernel32 |GetSystemInfo| call is too complicated. */
+#ifndef __MINGW32__
+# include <sys/time.h>     // For getrusage()
+# include <sys/resource.h> // For getrusage()
+# include <sys/utsname.h>  // For uname()
+# include <cstdlib>        // For getloadavg()
+# include <unistd.h>       // For sysconf()
+#else
 # ifndef NOMINMAX
-#  define NOMINMAX // Do not define "min" and "max" macros
+#  define NOMINMAX         // Do not define "min" and "max" macros
 # endif
-# include <windows.h>
-
-# define _SC_PAGESIZE 1
-# define _SC_PHYS_PAGES 2
-# define _SC_AVPHYS_PAGES 3
-# define _SC_NPROCESSORS_ONLN 4
-
-long
-sysconf(int name)
-{
-  switch (name)
-    {
-    case _SC_PAGESIZE:
-      return 1024;
-    case _SC_PHYS_PAGES:
-      {
-        MEMORYSTATUS memstat;
-        GlobalMemoryStatus(&memstat);
-        return memstat.dwTotalPhys/1024;
-      }
-    case _SC_AVPHYS_PAGES:
-      {
-        MEMORYSTATUS memstat;
-        GlobalMemoryStatus(&memstat);
-        return memstat.dwAvailPhys/1024;
-      }
-    case _SC_NPROCESSORS_ONLN:
-      return -1;
-    default:
-      KORD_RAISE("Not implemented in Win32 sysconf.");
-      return -1;
-    }
-}
+# include <windows.h>      // For GlobalMemoryStatus()
 #endif
 
-#if defined(__APPLE__)
-# define _SC_PHYS_PAGES 2
-# define _SC_AVPHYS_PAGES 3
-#endif
+const std::chrono::time_point<std::chrono::high_resolution_clock> SystemResources::start = std::chrono::high_resolution_clock::now();
 
-SystemResources::SystemResources()
-{
-  gettimeofday(&start, nullptr);
-}
-
-long int
+/* The pagesize is set to 1024 bytes on Windows. Real pagesize can differ but
+   it is not important. We can do this since Windows kernel32
+   GlobalMemoryStatus() call returns a number of bytes. */
+long
 SystemResources::pageSize()
 {
+#ifndef __MINGW32__
   return sysconf(_SC_PAGESIZE);
+#else
+  return 1024;
+#endif
 }
 
-long int
+long
 SystemResources::physicalPages()
 {
+#ifndef __MINGW32__
   return sysconf(_SC_PHYS_PAGES);
+#else
+  MEMORYSTATUS memstat;
+  GlobalMemoryStatus(&memstat);
+  return memstat.dwTotalPhys/1024;
+#endif
+}
+
+long
+SystemResources::availablePhysicalPages()
+{
+#ifndef __MINGW32__
+  return sysconf(_SC_AVPHYS_PAGES);
+#else
+  MEMORYSTATUS memstat;
+  GlobalMemoryStatus(&memstat);
+  return memstat.dwAvailPhys/1024;
+#endif
 }
 
-long int
+long
 SystemResources::onlineProcessors()
 {
+#ifndef __MINGW32__
   return sysconf(_SC_NPROCESSORS_ONLN);
+#else
+  return -1;
+#endif
 }
 
-long int
+long
 SystemResources::availableMemory()
 {
-  return pageSize()*sysconf(_SC_AVPHYS_PAGES);
+  return pageSize()*availablePhysicalPages();
 }
 
-/* Here we read the current values of resource usage. For MinGW, we
-   implement only a number of available physical memory pages. */
-
-void
-SystemResources::getRUS(double &load_avg, long int &pg_avail,
-                        double &utime, double &stime, double &elapsed,
-                        long int &idrss, long int &majflt)
+SystemResources::SystemResources()
 {
-  struct timeval now;
-  gettimeofday(&now, nullptr);
-  elapsed = now.tv_sec-start.tv_sec + (now.tv_usec-start.tv_usec)*1.0e-6;
+  auto now = std::chrono::high_resolution_clock::now();
+  std::chrono::duration<double> duration = now - start;
+  elapsed = duration.count();
 
-#if !defined(__MINGW32__)
+#ifndef __MINGW32__
   struct rusage rus;
   getrusage(RUSAGE_SELF, &rus);
   utime = rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6;
@@ -120,26 +95,17 @@ SystemResources::getRUS(double &load_avg, long int &pg_avail,
   majflt = -1;
 #endif
 
-#define MINGCYGTMP (!defined(__MINGW32__) && !defined(__CYGWIN32__) && !defined(__CYGWIN__))
-#define MINGCYG (MINGCYGTMP && !defined(__MINGW64__) && !defined(__CYGWIN64__))
-
-#if MINGCYG
+#ifndef __MINGW32__
   getloadavg(&load_avg, 1);
 #else
   load_avg = -1.0;
 #endif
 
-  pg_avail = sysconf(_SC_AVPHYS_PAGES);
-}
-
-SystemResourcesFlash::SystemResourcesFlash()
-{
-  _sysres.getRUS(load_avg, pg_avail, utime, stime,
-                 elapsed, idrss, majflt);
+  pg_avail = availablePhysicalPages();
 }
 
 void
-SystemResourcesFlash::diff(const SystemResourcesFlash &pre)
+SystemResources::diff(const SystemResources &pre)
 {
   utime -= pre.utime;
   stime -= pre.stime;
@@ -152,50 +118,63 @@ SystemResourcesFlash::diff(const SystemResourcesFlash &pre)
 JournalRecord &
 JournalRecord::operator<<(const IntSequence &s)
 {
-  operator<<("[");
+  operator<<('[');
   for (int i = 0; i < s.size(); i++)
     {
       operator<<(s[i]);
       if (i < s.size()-1)
-        operator<<(",");
+        operator<<(',');
     }
-  operator<<("]");
+  operator<<(']');
   return *this;
 }
 
 void
-JournalRecord::writePrefix(const SystemResourcesFlash &f)
+JournalRecord::writeFloatTabular(std::ostream &s, double d, int width)
 {
-  for (char & i : prefix)
-    i = ' ';
-  double mb = 1024*1024;
-  sprintf(prefix, "%07.6g", f.elapsed);
-  sprintf(prefix+7, ":%c%05d", recChar, ord);
-  sprintf(prefix+14, ":%1.1f", f.load_avg);
-  sprintf(prefix+18, ":%05.4g", f.pg_avail*_sysres.pageSize()/mb);
-  sprintf(prefix+24, "%s", ":      : ");
+  // Number of digits of integer part
+  int intdigits = std::max(static_cast<int>(std::floor(log10(d))+1), 1);
+
+  int prec = std::max(width - 1 - intdigits, 0);
+  s << std::fixed << std::setw(width) << std::setprecision(prec) << d;
+}
+
+void
+JournalRecord::writePrefix(const SystemResources &f)
+{
+  constexpr double mb = 1024*1024;
+  std::ostringstream s;
+  s << std::setfill('0');
+  writeFloatTabular(s, f.elapsed, 7);
+  s  << ':' << recChar << std::setw(5) << ord << ':';
+  writeFloatTabular(s, f.load_avg, 3);
+  s << ':';
+  writeFloatTabular(s, f.pg_avail*SystemResources::pageSize()/mb, 5);
+  s << ":      : ";
   for (int i = 0; i < 2*journal.getDepth(); i++)
-    prefix[i+33] = ' ';
-  prefix[2*journal.getDepth()+33] = '\0';
+    s << ' ';
+  prefix = s.str();
 }
 
 void
-JournalRecordPair::writePrefixForEnd(const SystemResourcesFlash &f)
+JournalRecordPair::writePrefixForEnd(const SystemResources &f)
 {
-  for (char & i : prefix_end)
-    i = ' ';
-  double mb = 1024*1024;
-  SystemResourcesFlash difnow;
+  constexpr double mb = 1024*1024;
+  SystemResources difnow;
   difnow.diff(f);
-  sprintf(prefix_end, "%07.6g", f.elapsed+difnow.elapsed);
-  sprintf(prefix_end+7, ":E%05d", ord);
-  sprintf(prefix_end+14, ":%1.1f", difnow.load_avg);
-  sprintf(prefix_end+18, ":%05.4g", difnow.pg_avail*_sysres.pageSize()/mb);
-  sprintf(prefix_end+24, ":%06.5g", difnow.majflt*_sysres.pageSize()/mb);
-  sprintf(prefix_end+31, "%s", ": ");
+  std::ostringstream s;
+  s << std::setfill('0');
+  writeFloatTabular(s, f.elapsed+difnow.elapsed, 7);
+  s << ":E" << std::setw(5) << ord << ':';
+  writeFloatTabular(s, difnow.load_avg, 3);
+  s << ':';
+  writeFloatTabular(s, difnow.pg_avail*SystemResources::pageSize()/mb, 5);
+  s << ':';
+  writeFloatTabular(s, difnow.majflt*SystemResources::pageSize()/mb, 6);
+  s << ": ";
   for (int i = 0; i < 2*journal.getDepth(); i++)
-    prefix_end[i+33] = ' ';
-  prefix_end[2*journal.getDepth()+33] = '\0';
+    s << ' ';
+  prefix_end = s.str();
 }
 
 JournalRecordPair::~JournalRecordPair()
@@ -222,39 +201,32 @@ endrec(JournalRecord &rec)
 void
 Journal::printHeader()
 {
-  (*this)<< "This is Dynare++, Copyright (C) 2004-2011, Ondra Kamenik\n"
-         << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"
-         << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"
-         << "LGPL: modules parser, utils\n"
-         << " for GPL  see http://www.gnu.org/licenses/gpl.html\n"
-         << " for LGPL see http://www.gnu.org/licenses/lgpl.html\n"
-         << "\n\n";
-
-#if !defined(__MINGW32__)
+  *this << "This is Dynare++, Copyright (C) 2004-2011, Ondra Kamenik\n"
+        << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"
+        << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"
+        << "LGPL: modules parser, utils\n"
+        << " for GPL  see http://www.gnu.org/licenses/gpl.html\n"
+        << " for LGPL see http://www.gnu.org/licenses/lgpl.html\n"
+        << "\n\n"
+        << "System info: ";
+#ifndef __MINGW32__
   utsname info;
   uname(&info);
-  (*this)<< "System info: ";
-  (*this)<< info.sysname << " " << info.release << " " << info.version << " ";
-  (*this)<< info.machine << ", processors online: " << _sysres.onlineProcessors();
-
-  (*this)<< "\n\nStart time: ";
-  char ts[100];
-  time_t curtime = time(nullptr);
-  tm loctime;
-  localtime_r(&curtime, &loctime);
-  asctime_r(&loctime, ts);
-  (*this)<< ts << "\n";
+  *this << info.sysname << " " << info.release << " " << info.version << " "
+        << info.machine << ", processors online: " << SystemResources::onlineProcessors();
 #else
-  (*this) << "System info: (not implemented for MINGW)\n";
-  (*this) << "Start time:  (not implemented for MINGW)\n\n";
+  *this << "(not implemented for MinGW)";
 #endif
-
-  (*this)<< "  ------ elapsed time (seconds)                     \n";
-  (*this)<< "  |       ------ record unique identifier           \n";
-  (*this)<< "  |       |     ------ load average                 \n";
-  (*this)<< "  |       |     |    ------ available memory (MB)   \n";
-  (*this)<< "  |       |     |    |     ------  major faults (MB)\n";
-  (*this)<< "  |       |     |    |     |                        \n";
-  (*this)<< "  V       V     V    V     V                        \n";
-  (*this)<< "\n";
+  *this << "\n\nStart time: ";
+  std::time_t t = std::time(nullptr);
+  *this << std::put_time(std::localtime(&t), "%c %Z")
+        << "\n\n"
+        << "  ------ elapsed time (seconds)                     \n"
+        << "  |       ------ record unique identifier           \n"
+        << "  |       |     ------ load average                 \n"
+        << "  |       |     |    ------ available memory (MB)   \n"
+        << "  |       |     |    |     ------  major faults (MB)\n"
+        << "  |       |     |    |     |                        \n"
+        << "  V       V     V    V     V                        \n"
+        << "\n";
 }
diff --git a/dynare++/kord/journal.hh b/dynare++/kord/journal.hh
index 70f3684244581f614f4c1a8405702190cf5d61bf..04a8afa9c56b559b4d1789602615e2c5b8c4debe 100644
--- a/dynare++/kord/journal.hh
+++ b/dynare++/kord/journal.hh
@@ -7,37 +7,35 @@
 
 #include "int_sequence.hh"
 
-#include <sys/time.h>
-#include <cstdio>
-#include <cstring>
 #include <iostream>
+#include <sstream>
 #include <fstream>
+#include <string>
+#include <chrono>
 
-class SystemResources
+/* Implement static methods for accessing some system resources. An instance of
+   this class is a photograph of these resources at the time of instantiation. */
+struct SystemResources
 {
-  timeval start;
-public:
-  SystemResources();
-  static long int pageSize();
-  static long int physicalPages();
-  static long int onlineProcessors();
-  static long int availableMemory();
-  void getRUS(double &load_avg, long int &pg_avail, double &utime,
-              double &stime, double &elapsed, long int &idrss,
-              long int &majflt);
-};
+  // The starting time of the executable
+  static const std::chrono::time_point<std::chrono::high_resolution_clock> start;
+
+  static long pageSize();
+  static long physicalPages();
+  static long availablePhysicalPages();
+  static long onlineProcessors();
+  static long availableMemory();
 
-struct SystemResourcesFlash
-{
   double load_avg;
-  long int pg_avail;
+  long pg_avail;
   double utime;
   double stime;
   double elapsed;
-  long int idrss;
-  long int majflt;
-  SystemResourcesFlash();
-  void diff(const SystemResourcesFlash &pre);
+  long idrss;
+  long majflt;
+
+  SystemResources();
+  void diff(const SystemResources &pre);
 };
 
 class Journal : public std::ofstream
@@ -45,7 +43,7 @@ class Journal : public std::ofstream
   int ord;
   int depth;
 public:
-  Journal(const char *fname)
+  explicit Journal(const std::string &fname)
     : std::ofstream(fname), ord(0), depth(0)
   {
     printHeader();
@@ -82,10 +80,8 @@ public:
   }
 };
 
-#define MAXLEN 1000
-
 class JournalRecord;
-JournalRecord&endrec(JournalRecord &);
+JournalRecord &endrec(JournalRecord &);
 
 class JournalRecord
 {
@@ -94,55 +90,74 @@ protected:
   int ord;
 public:
   Journal &journal;
-  char prefix[MAXLEN];
-  char mes[MAXLEN];
-  SystemResourcesFlash flash;
+  std::string prefix;
+  std::string mes;
+  SystemResources flash;
   using _Tfunc = JournalRecord &(*)(JournalRecord &);
 
-  JournalRecord(Journal &jr, char rc = 'M')
+  explicit JournalRecord(Journal &jr, char rc = 'M')
     : recChar(rc), ord(jr.getOrd()), journal(jr)
   {
-    prefix[0] = '\0'; mes[0] = '\0'; writePrefix(flash);
+    writePrefix(flash);
   }
-  virtual ~JournalRecord()
-  = default;
+  virtual ~JournalRecord() = default;
   JournalRecord &operator<<(const IntSequence &s);
   JournalRecord &
   operator<<(_Tfunc f)
   {
-    (*f)(*this); return *this;
+    (*f)(*this);
+    return *this;
+  }
+  JournalRecord &
+  operator<<(char c)
+  {
+    mes += c;
+    return *this;
   }
   JournalRecord &
-  operator<<(const char *s)
+  operator<<(const std::string &s)
   {
-    strcat(mes, s); return *this;
+    mes += s;
+    return *this;
   }
   JournalRecord &
   operator<<(int i)
   {
-    sprintf(mes+strlen(mes), "%d", i); return *this;
+    mes += std::to_string(i);
+    return *this;
   }
   JournalRecord &
   operator<<(double d)
   {
-    sprintf(mes+strlen(mes), "%f", d); return *this;
+    mes += std::to_string(d);
+    return *this;
   }
 protected:
-  void writePrefix(const SystemResourcesFlash &f);
+  void writePrefix(const SystemResources &f);
+  /* Writes a floating point number as a field of exactly "width" characters
+     large. Note that the width will not be respected if the integer part is
+     too large. */
+  static void writeFloatTabular(std::ostream &s, double d, int width);
 };
 
+/*
+  Constructs a "pair" of symmetric records with a RAII-like logic:
+   - when fed with "endrec", print the opening record
+   - subsequent records will have depth increased by 1
+   - when deleted, prints the symmetric closing record, and decrease depth
+*/
 class JournalRecordPair : public JournalRecord
 {
-  char prefix_end[MAXLEN];
+  std::string prefix_end;
 public:
-  JournalRecordPair(Journal &jr)
+  explicit JournalRecordPair(Journal &jr)
     : JournalRecord(jr, 'S')
   {
-    prefix_end[0] = '\0'; journal.incrementDepth();
+    journal.incrementDepth();
   }
   ~JournalRecordPair() override;
 private:
-  void writePrefixForEnd(const SystemResourcesFlash &f);
+  void writePrefixForEnd(const SystemResources &f);
 };
 
 #endif
diff --git a/dynare++/src/dynare_exception.hh b/dynare++/src/dynare_exception.hh
index bbaf961e93a06e48f59ba3107c37cefb4d49dd5e..6f0beb049d075f6e613744d7d0beaf4e39ab13fb 100644
--- a/dynare++/src/dynare_exception.hh
+++ b/dynare++/src/dynare_exception.hh
@@ -6,6 +6,7 @@
 #define DYNARE_EXCEPTION_H
 
 #include <string>
+#include <cstring>
 
 class DynareException
 {
diff --git a/mex/sources/k_order_perturbation/k_order_perturbation.cc b/mex/sources/k_order_perturbation/k_order_perturbation.cc
index 5df949c55e5479fb721ef673a7439a31bc6274bf..696025194934fdbd83ee60bab2c468339a51ec8d 100644
--- a/mex/sources/k_order_perturbation/k_order_perturbation.cc
+++ b/mex/sources/k_order_perturbation/k_order_perturbation.cc
@@ -63,9 +63,9 @@ DynareMxArrayToString(const mxArray *mxFldp, const int len, const int width, std
 }
 
 void
-copy_derivatives(mxArray *destin, const Symmetry &sym, const FGSContainer *derivs, const std::string &fieldname)
+copy_derivatives(mxArray *destin, const Symmetry &sym, const FGSContainer &derivs, const std::string &fieldname)
 {
-  const TwoDMatrix &x = derivs->get(sym);
+  const TwoDMatrix &x = derivs.get(sym);
   int n = x.numRows();
   int m = x.numCols();
   mxArray *tmp = mxCreateDoubleMatrix(n, m, mxREAL);
@@ -286,7 +286,7 @@ extern "C" {
               }
             if (kOrder == 3 && nlhs > 5)
               {
-                const FGSContainer *derivs = app.get_rule_ders();
+                const FGSContainer &derivs = app.get_rule_ders();
                 const std::string fieldnames[] = {"gy", "gu", "gyy", "gyu", "guu", "gss",
                                                   "gyyy", "gyyu", "gyuu", "guuu", "gyss", "guss"};
                 // creates the char** expected by mxCreateStructMatrix()