Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • giovanma/dynare
  • giorgiomas/dynare
  • Vermandel/dynare
  • Dynare/dynare
  • normann/dynare
  • MichelJuillard/dynare
  • wmutschl/dynare
  • FerhatMihoubi/dynare
  • sebastien/dynare
  • lnsongxf/dynare
  • rattoma/dynare
  • CIMERS/dynare
  • FredericKarame/dynare
  • SumuduK/dynare
  • MinjeJeon/dynare
  • camilomrch/dynare
  • DoraK/dynare
  • avtishin/dynare
  • selma/dynare
  • claudio_olguin/dynare
  • jeffjiang07/dynare
  • EthanSystem/dynare
  • stepan-a/dynare
  • wjgatt/dynare
  • JohannesPfeifer/dynare
  • gboehl/dynare
  • chskcau/dynare-doc-fixes
27 results
Select Git revision
Show changes
Showing
with 257 additions and 206 deletions
......@@ -57,7 +57,7 @@ OrdSequence::operator==(const OrdSequence& s) const
while (i < length() && operator[](i) == s[i])
i++;
return (i == length());
return i == length();
}
/* The first add() adds a given integer to the class, the second
......
......@@ -117,7 +117,7 @@ IntSequence::lessEq(const IntSequence& s) const
int i = 0;
while (i < size() && operator[](i) <= s[i])
i++;
return (i == size());
return i == size();
}
bool
......@@ -128,7 +128,7 @@ IntSequence::less(const IntSequence& s) const
int i = 0;
while (i < size() && operator[](i) < s[i])
i++;
return (i == size());
return i == size();
}
void
......
......@@ -208,8 +208,7 @@ public:
isZero(int i, const Symmetry& s) const override
{
TL_RAISE_IF(i < 0 || i >= numStacks(), "Wrong index to stack in StackContainer::isZero.");
return (getType(i, s) == itype::zero
|| (getType(i, s) == itype::matrix && !conts[i]->check(s)));
return getType(i, s) == itype::zero || (getType(i, s) == itype::matrix && !conts[i]->check(s));
}
[[nodiscard]] const _Ttype&
......
/*
* Copyright © 2004 Ondra Kamenik
* Copyright © 2019 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -19,39 +19,6 @@
*/
#include "t_polynomial.hh"
#include "kron_prod.hh"
// PowerProvider::getNext() unfolded code
/* This method constructs unfolded ‘ut’ of higher dimension, deleting
the previous. */
const URSingleTensor&
PowerProvider::getNext(dummy<URSingleTensor>)
{
if (ut)
{
auto ut_new = std::make_unique<URSingleTensor>(nv, ut->dimen() + 1);
KronProd::kronMult(ConstVector(origv), ConstVector(ut->getData()), ut_new->getData());
ut = std::move(ut_new);
}
else
{
ut = std::make_unique<URSingleTensor>(nv, 1);
ut->getData() = origv;
}
return *ut;
}
// PowerProvider::getNext() folded code
/* This method just constructs next unfolded ‘ut’ and creates folded ‘ft’. */
const FRSingleTensor&
PowerProvider::getNext(dummy<FRSingleTensor>)
{
getNext<URSingleTensor>();
ft = std::make_unique<FRSingleTensor>(*ut);
return *ft;
}
UTensorPolynomial::UTensorPolynomial(const FTensorPolynomial& fp) :
TensorPolynomial<UFSTensor, UGSTensor, URSingleTensor>(fp.nrows(), fp.nvars())
......
/*
* Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2023 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -55,6 +55,7 @@
#define T_POLYNOMIAL_HH
#include "fs_tensor.hh"
#include "kron_prod.hh"
#include "pascal_triangle.hh"
#include "rfs_tensor.hh"
#include "t_container.hh"
......@@ -89,33 +90,48 @@ public:
{
}
/*
We need to select getNext() implementation at compile type depending on a
type parameter.
template<class T>
const T& getNext();
Unfortunately full specialization is not possible at class scope. This may
be a bug in GCC 6. See:
https://stackoverflow.com/questions/49707184/explicit-specialization-in-non-namespace-scope-does-not-compile-in-gcc
// PowerProvider::getNext() unfolded code
/* This method constructs unfolded ‘ut’ of higher dimension, deleting
the previous.
Apply the workaround suggested in:
https://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope
*/
template<typename T>
struct dummy
Ideally we would like to use a full-specialization of the template, but this is not
possible due to a GCC bug, so we use a workaround using std::same_as concept.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 */
template<std::same_as<URSingleTensor> T>
const T&
getNext()
{
using type = T;
};
if (ut)
{
auto ut_new = std::make_unique<URSingleTensor>(nv, ut->dimen() + 1);
KronProd::kronMult(ConstVector(origv), ConstVector(ut->getData()), ut_new->getData());
ut = std::move(ut_new);
}
else
{
ut = std::make_unique<URSingleTensor>(nv, 1);
ut->getData() = origv;
}
return *ut;
}
template<class T>
// PowerProvider::getNext() folded code
/* This method just constructs next unfolded ‘ut’ and creates folded ‘ft’.
Ideally we would like to use a full-specialization of the template, but this is not
possible due to a GCC bug, so we use a workaround using std::same_as concept.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 */
template<std::same_as<FRSingleTensor> T>
const T&
getNext()
{
return getNext(dummy<T>());
getNext<URSingleTensor>();
ft = std::make_unique<FRSingleTensor>(*ut);
return *ft;
}
private:
const URSingleTensor& getNext(dummy<URSingleTensor>);
const FRSingleTensor& getNext(dummy<FRSingleTensor>);
};
/* The tensor polynomial is basically a tensor container which is more
......
......@@ -450,7 +450,7 @@ TestRunnable::folded_contraction(int r, int nv, int dim)
<< "\terror normMax: " << v.getMax() << '\n'
<< "\terror norm1: " << v.getNorm1() << '\n';
return (v.getMax() < 1.e-10);
return v.getMax() < 1.e-10;
}
bool
......@@ -485,7 +485,7 @@ TestRunnable::unfolded_contraction(int r, int nv, int dim)
<< "\terror normMax: " << v.getMax() << '\n'
<< "\terror norm1: " << v.getNorm1() << '\n';
return (v.getMax() < 1.e-10);
return v.getMax() < 1.e-10;
}
bool
......@@ -542,7 +542,7 @@ TestRunnable::poly_eval(int r, int nv, int maxdim)
<< "\tfolded horner error norm max: " << max_fh << '\n'
<< "\tunfolded horner error norm max: " << max_uh << '\n';
return (max_ft + max_fh + max_uh < 1.0e-10);
return max_ft + max_fh + max_uh < 1.0e-10;
}
/****************************************************/
......
......@@ -34,7 +34,7 @@
! warnings when the function may not be evaluated depending on the branch
! (-Wfunction-elimination)
! Copyright © 2019-2023 Dynare Team
! Copyright © 2019-2025 Dynare Team
!
! This file is part of Dynare.
!
......@@ -311,6 +311,14 @@ module matlab_mat
use iso_c_binding
type(c_ptr), intent(in), value :: array_ptr
end function mxArrayToString_internal
!! Memory management
subroutine mxFree(ptr) bind(c, name="mxFree"//API_VER)
use iso_c_binding
type(c_ptr), intent(in) :: ptr
end subroutine mxFree
end interface
contains
! Some helper functions to make the interface more Fortran-ish
......@@ -402,13 +410,16 @@ contains
type(c_ptr), intent(in) :: pm
character(kind=c_char, len=:), allocatable :: mxArrayToString
character(kind=c_char), dimension(:), pointer, contiguous :: chararray
type(c_ptr) :: ptr
integer :: i
call c_f_pointer(mxArrayToString_internal(pm), chararray, [ mxGetNumberOfElements(pm) ])
ptr = mxArrayToString_internal(pm)
call c_f_pointer(ptr, chararray, [ mxGetNumberOfElements(pm) ])
! Convert the character array into a character scalar (of length > 1)
allocate(character(kind=c_char, len=size(chararray)) :: mxArrayToString)
do i=1,size(chararray)
mxArrayToString(i:i) = chararray(i)
end do
call mxFree(ptr)
end function mxArrayToString
end module matlab_mat
......
......@@ -53,7 +53,6 @@ extern "C"
#else
_Noreturn
#endif
void
msExit(int status);
void msExit(int status);
#endif
/*
* Copyright © 2019-2024 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -26,6 +26,8 @@
using namespace std::literals::string_literals;
std::string DynamicModelCaller::error_msg;
std::string DynamicModelCaller::error_id;
std::mutex DynamicModelCaller::error_mtx;
#if !defined(_WIN32) && !defined(__CYGWIN32__)
void* DynamicModelDllCaller::resid_mex {nullptr};
......@@ -39,6 +41,44 @@ DynamicModelDllCaller::dynamic_tt_fct DynamicModelDllCaller::residual_tt_fct {nu
DynamicModelDllCaller::dynamic_fct DynamicModelDllCaller::residual_fct {nullptr},
DynamicModelDllCaller::g1_fct {nullptr};
void
DynamicModelCaller::setErrMsg(std::string msg)
{
std::lock_guard lk {error_mtx};
error_msg = move(msg);
error_id.clear();
}
void
DynamicModelCaller::setMException(const mxArray* exception)
{
const mxArray* message_mx {nullptr};
const mxArray* identifier_mx {nullptr};
if (mxIsClass(exception, "MException"))
{
message_mx = mxGetProperty(exception, 0, "message");
identifier_mx = mxGetProperty(exception, 0, "identifier");
}
else if (mxIsStruct(exception)) // For Octave
{
message_mx = mxGetField(exception, 0, "message");
identifier_mx = mxGetField(exception, 0, "identifier");
}
else
mexErrMsgTxt("Exception of incorrect type");
if (!message_mx || !mxIsChar(message_mx) || !identifier_mx || !mxIsChar(identifier_mx))
mexErrMsgTxt("Exception object malformed");
char* message = mxArrayToString(message_mx);
char* identifier = mxArrayToString(identifier_mx);
std::lock_guard lk {error_mtx};
error_msg = message;
error_id = identifier;
mxFree(message);
mxFree(identifier);
}
void
DynamicModelDllCaller::load_dll(const std::string& basename)
{
......@@ -210,13 +250,13 @@ DynamicModelMatlabCaller::eval(double* resid)
funcname.c_str())};
if (exception)
{
error_msg = "An error occurred when calling " + funcname;
setMException(exception);
return; // Avoid manipulating null pointers in plhs, see #1832
}
if (!mxIsDouble(plhs[0]) || mxIsSparse(plhs[0]))
{
error_msg = "Residuals should be a dense array of double floats";
setErrMsg("Residuals should be a dense array of double floats");
return;
}
......@@ -249,7 +289,7 @@ DynamicModelMatlabCaller::eval(double* resid)
funcname.c_str())};
if (exception)
{
error_msg = "An error occurred when calling " + funcname;
setMException(exception);
return; // Avoid manipulating null pointers in plhs, see #1832
}
......@@ -261,7 +301,7 @@ DynamicModelMatlabCaller::eval(double* resid)
if (!mxIsDouble(plhs[0]) || !mxIsSparse(plhs[0]))
{
error_msg = "Jacobian should be a sparse array of double floats";
setErrMsg("Residuals should be a dense array of double floats");
return;
}
......
/*
* Copyright © 2019-2024 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -23,6 +23,7 @@
#include <algorithm>
#include <limits>
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
#include <vector>
......@@ -47,6 +48,8 @@ public:
// Used to store error messages (as exceptions cannot cross the OpenMP boundary)
static std::string error_msg;
static std::string error_id;
static std::mutex error_mtx; // Guard for access in OpenMP context
DynamicModelCaller(bool linear_arg, bool compute_jacobian_arg) :
linear {linear_arg}, compute_jacobian {compute_jacobian_arg}
......@@ -59,6 +62,8 @@ public:
Only copies non-zero elements, according to g1_sparse_{rowval,colval,colptr}. */
virtual void copy_jacobian_column(mwIndex col, double* dest) const = 0;
virtual void eval(double* resid) = 0;
static void setErrMsg(std::string msg);
static void setMException(const mxArray* exception);
};
class DynamicModelDllCaller : public DynamicModelCaller
......
/*
* Copyright © 2019-2024 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -205,6 +205,7 @@ mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
DynamicModelDllCaller::load_dll(basename);
DynamicModelCaller::error_msg.clear();
DynamicModelCaller::error_id.clear();
/* Parallelize the main loop, if use_dll and no external function (to avoid
parallel calls to MATLAB) */
......@@ -220,7 +221,7 @@ mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
g1_sparse_rowval_mx, g1_sparse_colval_mx,
g1_sparse_colptr_mx, linear, compute_jacobian);
// Main computing loop
// Main computing loop
#pragma omp for
for (mwIndex T = 0; T < periods; T++)
{
......@@ -282,7 +283,7 @@ mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
/* Mimic a try/catch using a global string, since exceptions are not allowed
to cross OpenMP boundary */
if (!DynamicModelCaller::error_msg.empty())
mexErrMsgTxt(DynamicModelCaller::error_msg.c_str());
mexErrMsgIdAndTxt(DynamicModelCaller::error_id.c_str(), DynamicModelCaller::error_msg.c_str());
if (compute_jacobian)
{
......
! 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/>.
! Implements Ptmp = T*(P-K*Z*P)*transpose(T)+Q where
! P is the (r x r) variance-covariance matrix of the state vector
! T is the (r x r) transition matrix of the state vector
! K is the (r x n) gain matrix
! Z is the (n x r) matrix linking observable variables to state variables
! Q is the (r x r) variance-covariance matrix of innovations in the state equation
! and accounting for different properties:
! P is a (symmetric) positive semi-definite matrix
! T can be triangular
subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
use matlab_mex
use blas
implicit none (type, external)
type(c_ptr), dimension(*), intent(in), target :: prhs
type(c_ptr), dimension(*), intent(out) :: plhs
integer(c_int), intent(in), value :: nlhs, nrhs
real(real64), dimension(:,:), pointer, contiguous :: P, T, K, Z, Q, Pnew
real(real64), dimension(:,:), allocatable :: tmp1, tmp2
integer :: i, n, r
character(kind=c_char, len=2) :: num2str
! 0. Checking the consistency and validity of input arguments
if (nrhs /= 5_c_int) then
call mexErrMsgTxt("Must have 5 input arguments")
end if
if (nlhs > 1_c_int) then
call mexErrMsgTxt("Too many output arguments")
end if
do i=1,5
if (.not. (c_associated(prhs(i)) .and. mxIsDouble(prhs(i)) .and. &
(.not. mxIsComplex(prhs(i))) .and. (.not. mxIsSparse(prhs(i))))) then
write (num2str,"(i2)") i
call mexErrMsgTxt("Argument " // trim(num2str) // " should be a real dense matrix")
end if
end do
r = int(mxGetM(prhs(1))) ! Number of states
n = int(mxGetN(prhs(3))) ! Number of observables
if ((r /= mxGetN(prhs(1))) & ! Number of columns of P
&.or. (r /= mxGetM(prhs(2))) & ! Number of lines of T
&.or. (r /= mxGetN(prhs(2))) & ! Number of columns of T
&.or. (r /= mxGetM(prhs(3))) & ! Number of lines of K
&.or. (n /= mxGetM(prhs(4))) & ! Number of lines of Z
&.or. (r /= mxGetN(prhs(4))) & ! Number of columns of Z
&.or. (r /= mxGetM(prhs(5))) & ! Number of lines of Q
&.or. (r /= mxGetN(prhs(5))) & ! Number of columns of Q
) then
call mexErrMsgTxt("Input dimension mismatch")
end if
! 1. Storing the relevant information in Fortran format
P(1:r,1:r) => mxGetPr(prhs(1))
T(1:r,1:r) => mxGetPr(prhs(2))
K(1:r,1:n) => mxGetPr(prhs(3))
Z(1:n,1:r) => mxGetPr(prhs(4))
Q(1:r,1:r) => mxGetPr(prhs(5))
plhs(1) = mxCreateDoubleMatrix(int(r, mwSize), int(r, mwSize), mxREAL)
Pnew(1:r, 1:r) => mxGetPr(plhs(1))
! 2. Computing the Riccati update of the P matrix
allocate(tmp1(r,r), tmp2(r,r))
! Pnew <- Q
Pnew = Q
! tmp1 <- K*Z
call matmul_add("N", "N", 1._real64, K, Z, 0._real64, tmp1)
! tmp2 <- P
tmp2 = P
! tmp2 <- tmp2 - tmp1*P
call matmul_add("N", "N", -1._real64, tmp1, P, 1._real64, tmp2)
! tmp1 <- T*tmp2
call matmul_add("N", "N", 1._real64, T, tmp2, 0._real64, tmp1)
! Pnew <- tmp1*T' + Pnew
call matmul_add("N", "T", 1._real64, tmp1, T, 1._real64, Pnew)
end subroutine mexFunction
Subproject commit 2746a21702a1bcc89a25083d3e7b3ab3c925edd5
Subproject commit 5e84e25c89a45dff3f52cb227cf53d150575b219
;;; dynare.el --- major mode for editing Dynare mod files
;; Copyright © 2010 Yannick Kalantzis
;; Copyright © 2019-2024 Dynare Team
;; Copyright © 2019-2025 Dynare Team
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
......@@ -88,7 +88,7 @@
'("stderr" "values" "periods" "scales" "restriction" "exclusion"
"upper_cholesky" "lower_cholesky" "equation" "bind" "relax" "error_bind"
"error_relax" "add" "multiply" "target" "auxname_target_nonstationary"
"component" "growth" "auxname" "kind" "weights")
"component" "growth" "auxname" "kind" "weights" "exogenize" "endogenize")
"Dynare statements-like keywords.")
;; Those keywords that makes the lexer enter the DYNARE_BLOCK start condition
......@@ -106,7 +106,7 @@
"conditional_forecast_paths" "svar_identification" "moment_calibration"
"irf_calibration" "ramsey_constraints" "generate_irfs" "matched_moments"
"occbin_constraints" "model_replace" "pac_target_info" "matched_irfs"
"matched_irfs_weights" "verbatim")
"matched_irfs_weights" "perfect_foresight_controlled_paths" "verbatim")
"Dynare block keywords."))
;; Mathematical functions and operators used in model equations (see "hand_side" in Bison file)
......
function packageDynare(zipfile, version, logo)
function packageDynare(zipfile, version, version_sanitized, logo)
tfolder = tempname;
mkdir(tfolder)
......@@ -10,7 +10,7 @@ unzip(zipfile,dynarefld)
% create tbx options
opts = matlab.addons.toolbox.ToolboxOptions(dynarefld, "dynare", ...
ToolboxName = "Dynare", ...
ToolboxVersion = version, ...
ToolboxVersion = version_sanitized, ...
Summary = "Solves, simulates and estimates a wide class of economic models", ...
AuthorName = "Dynare Team", ...
ToolboxImageFile = logo, ...
......
#!/bin/bash
set -exo pipefail
# Creates a dynare-X.Y.mltbx in the current repository, using the settings below.
# Needs to be run from Ubuntu 22.04 LTS, with the needed packages installed.
# Creates a dynare-X.Y.mltbx in the current repository, using the settings
# below. Needs to be run from Ubuntu, with the needed packages installed.
# The required Ubuntu version can be obtained by running “!lsb_release -a” in
# MATLAB Online.
X13ASVER=1-1-b61
MATLABPATH=/opt/MATLAB/R2024b
MATLABVER=R2024b
MATLABPATH=/opt/MATLAB/${MATLABVER}
# TODO: change size and put white background for better rendering in MATLAB Add-Ons browser
DYNARE_PNG_LOGO=../../preprocessor/doc/logos/dlogo.png
......@@ -18,13 +22,23 @@ cleanup ()
trap cleanup EXIT
pushd ../..
meson setup -Dmatlab_path="$MATLABPATH" -Dbuildtype=release -Dprefer_static=true "$tmpdir"/build-matlab-online
meson setup -Dbuild_for=matlab -Dmatlab_path="$MATLABPATH" -Dbuildtype=release -Dprefer_static=true "$tmpdir"/build-matlab-online
cd "$tmpdir"/build-matlab-online
meson compile
meson compile -v
meson install --destdir "$tmpdir"
DYNAREVER=$(meson introspect --projectinfo | jq -r '.version')
# Sanitize the version number so that is corresponds to MATLAB toolbox
# requirements: the version must be a scalar string or character vector of the
# form Major.Minor.Bug.Build, where Bug and Build are optional.
# Hence remove any character which is not a number or a dot, and ensure that we
# have at least a minor version number.
DYNAREVER_SANITIZED=${DYNAREVER//[^0-9.]/}
if [[ ${DYNAREVER_SANITIZED} != *.* ]]; then
DYNAREVER_SANITIZED=${DYNAREVER_SANITIZED}.0
fi
cd ..
strip usr/local/bin/dynare-preprocessor
strip usr/local/lib/dynare/mex/matlab/*.mexa64
......@@ -45,4 +59,4 @@ zip -q -r "$tmpdir"/dynare.zip *
# make toolbox
popd
"$MATLABPATH/bin/matlab" -batch "packageDynare('$tmpdir/dynare.zip', '$DYNAREVER', '$DYNARE_PNG_LOGO')"
"$MATLABPATH/bin/matlab" -batch "packageDynare('$tmpdir/dynare.zip', '$DYNAREVER', '$DYNAREVER_SANITIZED', '$DYNARE_PNG_LOGO')"
......@@ -18,7 +18,7 @@ shift 4
# -D options are passed, presumably due to a bug in sphinx-build.
# See: https://bugs.debian.org/933347
"$sphinx_build_exe" -b latex "$@" "$source_dir" "$private_dir"
"$sphinx_build_exe" -n -b latex "$@" "$source_dir" "$private_dir"
make -C "$private_dir" all-pdf
......
// Tests the analytic_derivation option
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;
stoch_simul(order=1,periods=200, irf=0,nomoments,noprint);
send_endogenous_variables_to_workspace;
save('my_data.mat','gp_obs','gy_obs');
estimated_params;
alp, 0.356;
rho, 0.129;
psi, 0.65;
stderr e_a, 0.035449, 0, inf;
stderr e_m, 0.008862, 0, inf;
end;
varobs gp_obs gy_obs;
options_.solve_tolf = 1e-12;
estimation(order=1,mode_compute=5,analytic_derivation,kalman_algo=2,datafile=my_data,nobs=192,mh_replic=0,mh_nblocks=2,mh_jscale=0.8,plot_priors=0);
......@@ -47,20 +47,17 @@ nstbc_psi = 0;
nstbc_theta = 2.95;
@#if !block && !bytecode && !use_dll
model;
@#elseif block && !bytecode && !use_dll
model(block, cutoff=0);
@#elseif !block && bytecode
model(bytecode);
@#elseif block && bytecode
model(block, bytecode, cutoff=0);
@#elseif !block && use_dll
model(use_dll);
@#else
model(block, use_dll, cutoff=0);
@#if block
model_options(block);
@#endif
@#if bytecode
model_options(bytecode);
@#endif
@#if use_dll
model_options(use_dll);
@#endif
model;
// Block of type “Solve two boundaries complete” (linear)
y = y(+1) - (tau +alpha*(2-alpha)*(1-tau))*(R-pie(+1))-alpha*(tau +alpha*(2-alpha)*(1-tau))*dq(+1) + alpha*(2-alpha)*((1-tau)/tau)*(y_s-y_s(+1))-A(+1);
pie = exp(-rr/400)*pie(+1)+alpha*exp(-rr/400)*dq(+1)-alpha*dq+(k/(tau+alpha*(2-alpha)*(1-tau)))*y+alpha*(2-alpha)*(1-tau)/(tau*(tau+alpha*(2-alpha)*(1-tau)))*y_s;
......@@ -218,4 +215,18 @@ shocks;
end;
perfect_foresight_setup(periods=20);
perfect_foresight_solver(no_homotopy, markowitz=0, stack_solve_algo = @{stack_solve_algo});
perfect_foresight_solver(no_homotopy, stack_solve_algo = @{stack_solve_algo}
@#if length(preconditioner) > 0
, preconditioner = @{preconditioner}
@#endif
@#if preconditioner == "iterstack"
@# if !(block && stack_solve_algo == 3)
// Ensure that problem is not too small for iterstack, and also that there is a “residual” in the block diagonal matrix (since 3 does not divide 20)
, iterstack_nperiods = 3
@# else
// For some reason iterstack can’t solve this model with block decomposition + BiCGStab
// Hence do the equivalent of a full LU
, iterstack_nperiods = 20
@# endif
@#endif
);
function run_ls2003(block, storage, solve_algo, stack_solve_algo)
function run_ls2003(block, storage, solve_algo, stack_solve_algo, preconditioner)
% Copyright © 2010-2013 Dynare Team
% Copyright © 2010-2025 Dynare Team
%
% This file is part of Dynare.
%
......@@ -17,17 +17,23 @@ function run_ls2003(block, storage, solve_algo, stack_solve_algo)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
disp(['TEST: ls2003 (block=' num2str(block) ', bytecode=' ...
num2str(storage==2) ', use_dll=' num2str(storage==1) ...
', solve_algo=' num2str(solve_algo) ...
', stack_solve_algo=' num2str(stack_solve_algo) ')...']);
if nargin < 5
preconditioner = '';
end
fprintf('TEST: ls2003 (block=%d, bytecode=%d, use_dll=%d, solve_algo=%d, stack_solve_algo=%d', block, storage==2, storage==1, solve_algo, stack_solve_algo)
if ~isempty(preconditioner)
fprintf(', preconditioner=%s', preconditioner)
end
fprintf(')...\n')
fid = fopen('ls2003_tmp.mod', 'w');
assert(fid > 0);
fprintf(fid, ['@#define block = %d\n@#define bytecode = %d\n' ...
'@#define use_dll = %d\n' ...
'@#define solve_algo = %d\n@#define stack_solve_algo = %d\n' ...
'@#define preconditioner = "%s"\n' ...
'@#include \"ls2003.mod\"\n'], block, storage==2, storage==1, ...
solve_algo, stack_solve_algo);
solve_algo, stack_solve_algo, preconditioner);
fclose(fid);
dynare('ls2003_tmp.mod','console')
end