From 5f861cb0d8eb1218bc91c7cafae23f33c34f2247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien.villemot@ens.fr> Date: Thu, 23 Aug 2012 18:30:27 +0200 Subject: [PATCH] Use MatIO in Dynare++ instead of the home-made engine --- Makefile.am | 2 + configure.ac | 10 ++++- dynare++/kord/decision_rule.cweb | 72 +++++++++++++++---------------- dynare++/kord/decision_rule.hweb | 32 +++++++------- dynare++/kord/dynamic_model.cweb | 34 +++++++++------ dynare++/kord/dynamic_model.hweb | 4 +- dynare++/kord/global_check.cweb | 16 +++---- dynare++/kord/global_check.hweb | 10 +++-- dynare++/src/Makefile.am | 2 +- dynare++/src/dynare3.cpp | 22 +++++----- dynare++/src/dynare3.h | 4 +- dynare++/src/main.cpp | 20 ++++----- dynare++/tl/cc/t_container.hweb | 12 +++--- dynare++/tl/cc/twod_matrix.cweb | 56 ++++++++---------------- dynare++/tl/cc/twod_matrix.hweb | 27 +++--------- mex/build/dynare_simul_.am | 2 +- mex/build/k_order_perturbation.am | 2 +- mex/build/matlab/Makefile.am | 7 ++- mex/build/matlab/configure.ac | 15 ++++++- mex/build/octave/Makefile.am | 6 ++- mex/build/octave/configure.ac | 8 ++-- 21 files changed, 185 insertions(+), 178 deletions(-) diff --git a/Makefile.am b/Makefile.am index eea42e168..f010b9183 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,9 +2,11 @@ SUBDIRS = preprocessor doc tests mex/sources if HAVE_BLAS if HAVE_LAPACK +if HAVE_MATIO SUBDIRS += dynare++ endif endif +endif # MEX must be built after dynare++ (because of kordepert) if ENABLE_MATLAB diff --git a/configure.ac b/configure.ac index 533df7061..4e643b5ce 100644 --- a/configure.ac +++ b/configure.ac @@ -86,6 +86,12 @@ AC_DEFINE([BOOST_NO_HASH], [], [Don't use deprecated STL hash structures]) AC_CHECK_LIB([dl], [dlopen], [LIBADD_DLOPEN="-ldl"], []) AC_SUBST([LIBADD_DLOPEN]) +# Check for libmatio, needed by Dynare++ +AC_CHECK_HEADER([matio.h]) +AC_CHECK_LIB([matio], [Mat_Open], [LIBADD_MATIO="-lmatio"]) +AC_SUBST([LIBADD_MATIO]) +AM_CONDITIONAL([HAVE_MATIO], [test "x$ac_cv_header_matio_h" = "xyes" -a "x$ac_cv_lib_matio_Mat_Open" = "xyes"]) + AC_CHECK_PROG([MAKEINFO], [makeinfo], [makeinfo]) AC_CHECK_PROG([PDFTEX], [pdftex], [pdftex]) @@ -232,14 +238,14 @@ AM_CONDITIONAL([ENABLE_ORG_EXPORT], [test "x$enable_org_export" != "x"]) BUILD_PREPROCESSOR="yes" -if test "x$ax_blas_ok" = "xyes" -a "x$ax_lapack_ok" = "xyes"; then +if test "x$ax_blas_ok" = "xyes" -a "x$ax_lapack_ok" = "xyes" -a "x$ac_cv_header_matio_h" = "xyes" -a "x$ac_cv_lib_matio_Mat_Open" = "xyes"; then if test x"$ax_pthread_ok" = "xyes"; then BUILD_DYNAREPLUSPLUS="yes" else BUILD_DYNAREPLUSPLUS="yes (without POSIX threads)" fi else - BUILD_DYNAREPLUSPLUS="no (missing one of: BLAS, LAPACK)" + BUILD_DYNAREPLUSPLUS="no (missing one of: BLAS, LAPACK, MatIO)" fi if test "x$CWEAVE" != "x" -a x"$PDFTEX" != "x" -a "x$ax_tex_have_eplain" = "xyes"; then diff --git a/dynare++/kord/decision_rule.cweb b/dynare++/kord/decision_rule.cweb index 99536d3de..c5ab3e580 100644 --- a/dynare++/kord/decision_rule.cweb +++ b/dynare++/kord/decision_rule.cweb @@ -37,27 +37,27 @@ int DRFixPoint<KOrder::unfold>::newton_pause = 100; @<|SimResults::simulate| code1@>; @<|SimResults::simulate| code2@>; @<|SimResults::addDataSet| code@>; -@<|SimResults::writeMat4| code1@>; -@<|SimResults::writeMat4| code2@>; +@<|SimResults::writeMat| code1@>; +@<|SimResults::writeMat| code2@>; @<|SimResultsStats::simulate| code@>; -@<|SimResultsStats::writeMat4| code@>; +@<|SimResultsStats::writeMat| code@>; @<|SimResultsStats::calcMean| code@>; @<|SimResultsStats::calcVcov| code@>; @<|SimResultsDynamicStats::simulate| code@>; -@<|SimResultsDynamicStats::writeMat4| code@>; +@<|SimResultsDynamicStats::writeMat| code@>; @<|SimResultsDynamicStats::calcMean| code@>; @<|SimResultsDynamicStats::calcVariance| code@>; @<|SimResultsIRF::simulate| code1@>; @<|SimResultsIRF::simulate| code2@>; @<|SimResultsIRF::calcMeans| code@>; @<|SimResultsIRF::calcVariances| code@>; -@<|SimResultsIRF::writeMat4| code@>; +@<|SimResultsIRF::writeMat| code@>; @<|RTSimResultsStats::simulate| code1@>; @<|RTSimResultsStats::simulate| code2@>; -@<|RTSimResultsStats::writeMat4| code@>; +@<|RTSimResultsStats::writeMat| code@>; @<|IRFResults| constructor@>; @<|IRFResults| destructor@>; -@<|IRFResults::writeMat4| code@>; +@<|IRFResults::writeMat| code@>; @<|SimulationWorker::operator()()| code@>; @<|SimulationIRFWorker::operator()()| code@>; @<|RTSimulationWorker::operator()()| code@>; @@ -169,23 +169,23 @@ bool SimResults::addDataSet(TwoDMatrix* d, ExplicitShockRealization* sr) } @ -@<|SimResults::writeMat4| code1@>= -void SimResults::writeMat4(const char* base, const char* lname) const +@<|SimResults::writeMat| code1@>= +void SimResults::writeMat(const char* base, const char* lname) const { char matfile_name[100]; sprintf(matfile_name, "%s.mat", base); - FILE* out; - if (NULL != (out=fopen(matfile_name, "wb"))) { - writeMat4(out, lname); - fclose(out); + mat_t* matfd = Mat_Create(matfile_name, NULL); + if (matfd != NULL) { + writeMat(matfd, lname); + Mat_Close(matfd); } } @ This save the results as matrices with given prefix and with index appended. If there is only one matrix, the index is not appended. -@<|SimResults::writeMat4| code2@>= -void SimResults::writeMat4(FILE* fd, const char* lname) const +@<|SimResults::writeMat| code2@>= +void SimResults::writeMat(mat_t* fd, const char* lname) const { char tmp[100]; for (int i = 0; i < getNumSets(); i++) { @@ -194,7 +194,7 @@ void SimResults::writeMat4(FILE* fd, const char* lname) const else sprintf(tmp, "%s_data", lname); ConstTwoDMatrix m(*(data[i])); - m.writeMat4(fd, tmp); + m.writeMat(fd, tmp); } } @@ -219,15 +219,15 @@ void SimResultsStats::simulate(int num_sim, const DecisionRule& dr, @ Here we do not save the data itself, we save only mean and vcov. -@<|SimResultsStats::writeMat4| code@>= -void SimResultsStats::writeMat4(FILE* fd, const char* lname) const +@<|SimResultsStats::writeMat| code@>= +void SimResultsStats::writeMat(mat_t* fd, const char* lname) const { char tmp[100]; sprintf(tmp, "%s_mean", lname); ConstTwoDMatrix m(num_y, 1, mean.base()); - m.writeMat4(fd, tmp); + m.writeMat(fd, tmp); sprintf(tmp, "%s_vcov", lname); - ConstTwoDMatrix(vcov).writeMat4(fd, tmp); + ConstTwoDMatrix(vcov).writeMat(fd, tmp); } @ @@ -291,14 +291,14 @@ void SimResultsDynamicStats::simulate(int num_sim, const DecisionRule& dr, } @ -@<|SimResultsDynamicStats::writeMat4| code@>= -void SimResultsDynamicStats::writeMat4(FILE* fd, const char* lname) const +@<|SimResultsDynamicStats::writeMat| code@>= +void SimResultsDynamicStats::writeMat(mat_t* fd, const char* lname) const { char tmp[100]; sprintf(tmp, "%s_cond_mean", lname); - ConstTwoDMatrix(mean).writeMat4(fd, tmp); + ConstTwoDMatrix(mean).writeMat(fd, tmp); sprintf(tmp, "%s_cond_variance", lname); - ConstTwoDMatrix(variance).writeMat4(fd, tmp); + ConstTwoDMatrix(variance).writeMat(fd, tmp); } @ @@ -406,14 +406,14 @@ void SimResultsIRF::calcVariances() } @ -@<|SimResultsIRF::writeMat4| code@>= -void SimResultsIRF::writeMat4(FILE* fd, const char* lname) const +@<|SimResultsIRF::writeMat| code@>= +void SimResultsIRF::writeMat(mat_t* fd, const char* lname) const { char tmp[100]; sprintf(tmp, "%s_mean", lname); - means.writeMat4(fd, tmp); + means.writeMat(fd, tmp); sprintf(tmp, "%s_var", lname); - variances.writeMat4(fd, tmp); + variances.writeMat(fd, tmp); } @ @@ -458,15 +458,15 @@ void RTSimResultsStats::simulate(int num_sim, const DecisionRule& dr, const Vect } @ -@<|RTSimResultsStats::writeMat4| code@>= -void RTSimResultsStats::writeMat4(FILE* fd, const char* lname) +@<|RTSimResultsStats::writeMat| code@>= +void RTSimResultsStats::writeMat(mat_t* fd, const char* lname) { char tmp[100]; sprintf(tmp, "%s_rt_mean", lname); ConstTwoDMatrix m(nc.getDim(), 1, mean.base()); - m.writeMat4(fd, tmp); + m.writeMat(fd, tmp); sprintf(tmp, "%s_rt_vcov", lname); - ConstTwoDMatrix(vcov).writeMat4(fd, tmp); + ConstTwoDMatrix(vcov).writeMat(fd, tmp); } @ @@ -505,17 +505,17 @@ IRFResults::~IRFResults() } @ -@<|IRFResults::writeMat4| code@>= -void IRFResults::writeMat4(FILE* fd, const char* prefix) const +@<|IRFResults::writeMat| code@>= +void IRFResults::writeMat(mat_t* fd, const char* 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]->writeMat4(fd, tmp); + irf_res[2*i]->writeMat(fd, tmp); sprintf(tmp, "%s_irfm_%s", prefix, shockname); - irf_res[2*i+1]->writeMat4(fd, tmp); + irf_res[2*i+1]->writeMat(fd, tmp); } } diff --git a/dynare++/kord/decision_rule.hweb b/dynare++/kord/decision_rule.hweb index bad14cc1f..c32a1323a 100644 --- a/dynare++/kord/decision_rule.hweb +++ b/dynare++/kord/decision_rule.hweb @@ -39,6 +39,8 @@ decision rule. #ifndef DECISION_RULE_H #define DECISION_RULE_H +#include <matio.h> + #include "kord_exception.h" #include "korder.h" #include "normal_conjugate.h" @@ -89,7 +91,7 @@ deviations from the rule's steady. |evaluate| method makes only one step of simulation (in terms of absolute values, not deviations). |centralizedClone| returns a new copy of the decision rule, which is centralized about provided fix-point. And finally -|writeMat4| writes the decision rule to the Matlab MAT-4 file. +|writeMat| writes the decision rule to the MAT file. @<|DecisionRule| class declaration@>= class DecisionRule { @@ -101,7 +103,7 @@ public:@; 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 writeMat4(FILE* fd, const char* prefix) 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 int nexog() const =0; @@ -160,7 +162,7 @@ public:@; @<|DecisionRuleImpl::simulate| code@>; @<|DecisionRuleImpl::evaluate| code@>; @<|DecisionRuleImpl::centralizedClone| code@>; - @<|DecisionRuleImpl::writeMat4| code@>; + @<|DecisionRuleImpl::writeMat| code@>; int nexog() const {@+ return nu;@+} const PartitionY& getYPart() const @@ -402,16 +404,16 @@ void eval(emethod em, Vector& out, const ConstVector& v) const _Tparent::evalTrad(out, v); } -@ Write the decision rule and steady state to the MAT--4 file. -@<|DecisionRuleImpl::writeMat4| code@>= -void writeMat4(FILE* fd, const char* prefix) const +@ Write the decision rule and steady state to the MAT file. +@<|DecisionRuleImpl::writeMat| code@>= +void writeMat(mat_t* fd, const char* prefix) const { - ctraits<t>::Tpol::writeMat4(fd, prefix); + ctraits<t>::Tpol::writeMat(fd, prefix); TwoDMatrix dum(ysteady.length(), 1); dum.getData() = ysteady; char tmp[100]; sprintf(tmp, "%s_ss", prefix); - ConstTwoDMatrix(dum).writeMat4(fd, tmp); + ConstTwoDMatrix(dum).writeMat(fd, tmp); } @ This is exactly the same as |DecisionRuleImpl<KOrder::fold>|. The @@ -721,8 +723,8 @@ public:@; const ExplicitShockRealization& getShocks(int i) const { @+ return *(shocks[i]);@+} bool addDataSet(TwoDMatrix* d, ExplicitShockRealization* sr); - void writeMat4(const char* base, const char* lname) const; - void writeMat4(FILE* fd, const char* lname) const; + void writeMat(const char* base, const char* lname) const; + void writeMat(mat_t* fd, const char* lname) const; }; @ This does the same as |SimResults| plus it calculates means and @@ -738,7 +740,7 @@ public:@; : SimResults(ny, nper, nburn), mean(ny), vcov(ny,ny)@+ {} void simulate(int num_sim, const DecisionRule& dr, const Vector& start, const TwoDMatrix& vcov, Journal& journal); - void writeMat4(FILE* fd, const char* lname) const; + void writeMat(mat_t* fd, const char* lname) const; protected:@; void calcMean(); void calcVcov(); @@ -758,7 +760,7 @@ public:@; : SimResults(ny, nper, nburn), mean(ny,nper), variance(ny,nper)@+ {} void simulate(int num_sim, const DecisionRule& dr, const Vector& start, const TwoDMatrix& vcov, Journal& journal); - void writeMat4(FILE* fd, const char* lname) const; + void writeMat(mat_t* fd, const char* lname) const; protected:@; void calcMean(); void calcVariance(); @@ -789,7 +791,7 @@ public:@; means(ny, nper), variances(ny, nper)@+ {} void simulate(const DecisionRule& dr, Journal& journal); void simulate(const DecisionRule& dr); - void writeMat4(FILE* fd, const char* lname) const; + void writeMat(mat_t* fd, const char* lname) const; protected:@; void calcMeans(); void calcVariances(); @@ -822,7 +824,7 @@ public:@; const TwoDMatrix& vcov, Journal& journal); void simulate(int num_sim, const DecisionRule& dr, const Vector& start, const TwoDMatrix& vcov); - void writeMat4(FILE* fd, const char* lname); + void writeMat(mat_t* fd, const char* lname); }; @ For each shock, this simulates plus and minus impulse. The class @@ -850,7 +852,7 @@ public:@; const SimResults& control, const vector<int>& ili, Journal& journal); ~IRFResults(); - void writeMat4(FILE* fd, const char* prefix) const; + void writeMat(mat_t* fd, const char* prefix) const; }; @ This worker simulates the given decision rule and inserts the result diff --git a/dynare++/kord/dynamic_model.cweb b/dynare++/kord/dynamic_model.cweb index d8dd17159..77847164c 100644 --- a/dynare++/kord/dynamic_model.cweb +++ b/dynare++/kord/dynamic_model.cweb @@ -7,8 +7,8 @@ #include "dynamic_model.h" @<|NameList::print| code@>; -@<|NameList::writeMat4| code@>; -@<|NameList::writeMat4Indices| code@>; +@<|NameList::writeMat| code@>; +@<|NameList::writeMatIndices| code@>; @ @<|NameList::print| code@>= @@ -19,8 +19,8 @@ void NameList::print() const } @ -@<|NameList::writeMat4| code@>= -void NameList::writeMat4(FILE* fd, const char* vname) const +@<|NameList::writeMat| code@>= +void NameList::writeMat(mat_t* fd, const char* vname) const { int maxlen = 0; for (int i = 0; i < getNum(); i++) @@ -30,29 +30,37 @@ void NameList::writeMat4(FILE* fd, const char* vname) const if (maxlen == 0) return; - TwoDMatrix m(getNum(), maxlen); + char *m = new char[getNum()*maxlen]; + for (int i = 0; i < getNum(); i++) for (int j = 0; j < maxlen; j++) if (j < (int)strlen(getName(i))) - m.get(i,j) = (double)(getName(i)[j]); + m[j*getNum()+i] = getName(i)[j]; else - m.get(i,j) = (double)(' '); + m[j*getNum()+i] = ' '; + + int dims[2]; + dims[0] = getNum(); + dims[1] = maxlen; + + matvar_t *v = Mat_VarCreate(vname, MAT_C_CHAR, MAT_T_UINT8, 2, dims, m, 0); + + Mat_VarWrite(fd, v, COMPRESSION_NONE); - Mat4Header header(m, vname, "text matrix"); - header.write(fd); - fwrite(m.getData().base(), sizeof(double), m.nrows()*m.ncols(), fd); + Mat_VarFree(v); + delete[] m; } @ -@<|NameList::writeMat4Indices| code@>= -void NameList::writeMat4Indices(FILE* fd, const char* prefix) const +@<|NameList::writeMatIndices| code@>= +void NameList::writeMatIndices(mat_t* fd, const char* prefix) const { char tmp[100]; TwoDMatrix aux(1,1); for (int i = 0; i < getNum(); i++) { sprintf(tmp, "%s_i_%s", prefix, getName(i)); aux.get(0,0) = i+1; - aux.writeMat4(fd, tmp); + aux.writeMat(fd, tmp); } } diff --git a/dynare++/kord/dynamic_model.hweb b/dynare++/kord/dynamic_model.hweb index 9a0a7ae5e..aef6de7e3 100644 --- a/dynare++/kord/dynamic_model.hweb +++ b/dynare++/kord/dynamic_model.hweb @@ -33,8 +33,8 @@ public:@; virtual int getNum() const =0; virtual const char* getName(int i) const=0; void print() const; - void writeMat4(FILE* fd, const char* vname) const; - void writeMat4Indices(FILE* fd, const char* prefix) const; + void writeMat(mat_t* fd, const char* vname) const; + void writeMatIndices(mat_t* fd, const char* prefix) const; }; @ This is the interface to an information on a generic SDGE diff --git a/dynare++/kord/global_check.cweb b/dynare++/kord/global_check.cweb index 51fabed87..ea7782153 100644 --- a/dynare++/kord/global_check.cweb +++ b/dynare++/kord/global_check.cweb @@ -229,7 +229,7 @@ changing $u$. We go through all elements of $u$ and vary them from $-mult\cdot\sigma$ to $mult\cdot\sigma$ in |m| steps. @<|GlobalChecker::checkAlongShocksAndSave| code@>= -void GlobalChecker::checkAlongShocksAndSave(FILE* fd, const char* prefix, +void GlobalChecker::checkAlongShocksAndSave(mat_t* fd, const char* prefix, int m, double mult, int max_evals) { JournalRecordPair pa(journal); @@ -297,7 +297,7 @@ void GlobalChecker::checkAlongShocksAndSave(FILE* fd, const char* prefix, } char tmp[100]; sprintf(tmp, "%s_shock_%s_errors", prefix, model.getExogNames().getName(ishock)); - err_out.writeMat4(fd, tmp); + err_out.writeMat(fd, tmp); } @@ -316,7 +316,7 @@ matrix of $u_t$ to zeros. Fourth we run the |check| method and save the results. @<|GlobalChecker::checkOnEllipseAndSave| code@>= -void GlobalChecker::checkOnEllipseAndSave(FILE* fd, const char* prefix, +void GlobalChecker::checkOnEllipseAndSave(mat_t* fd, const char* prefix, int m, double mult, int max_evals) { JournalRecordPair pa(journal); @@ -406,15 +406,15 @@ and initialize matrix of shocks |umat| to zero. char tmp[100]; sprintf(tmp, "%s_ellipse_points", prefix); - ymat.writeMat4(fd, tmp); + ymat.writeMat(fd, tmp); sprintf(tmp, "%s_ellipse_errors", prefix); - out.writeMat4(fd, tmp); + out.writeMat(fd, tmp); @ Here we check the errors along a simulation. We simulate, then set |x| to zeros, check and save results. @<|GlobalChecker::checkAlongSimulationAndSave| code@>= -void GlobalChecker::checkAlongSimulationAndSave(FILE* fd, const char* prefix, +void GlobalChecker::checkAlongSimulationAndSave(mat_t* fd, const char* prefix, int m, int max_evals) { JournalRecordPair pa(journal); @@ -430,9 +430,9 @@ void GlobalChecker::checkAlongSimulationAndSave(FILE* fd, const char* prefix, char tmp[100]; sprintf(tmp, "%s_simul_points", prefix); - y->writeMat4(fd, tmp); + y->writeMat(fd, tmp); sprintf(tmp, "%s_simul_errors", prefix); - out.writeMat4(fd, tmp); + out.writeMat(fd, tmp); delete y; } diff --git a/dynare++/kord/global_check.hweb b/dynare++/kord/global_check.hweb index c54b57a73..8ba9fd30e 100644 --- a/dynare++/kord/global_check.hweb +++ b/dynare++/kord/global_check.hweb @@ -50,6 +50,8 @@ method and polar transformation. The shock $u$ are zeros. #ifndef GLOBAL_CHECK_H #define GLOBAL_CHECK_H +#include <matio.h> + #include "vector_function.h" #include "quadrature.h" @@ -143,13 +145,13 @@ public:@; rf(approx), vfs(rf, n)@+ {} void check(int max_evals, const ConstTwoDMatrix& y, const ConstTwoDMatrix& x, TwoDMatrix& out); - void checkAlongShocksAndSave(FILE* fd, const char* prefix, + void checkAlongShocksAndSave(mat_t* fd, const char* prefix, int m, double mult, int max_evals); - void checkOnEllipseAndSave(FILE* fd, const char* prefix, + void checkOnEllipseAndSave(mat_t* fd, const char* prefix, int m, double mult, int max_evals); - void checkAlongSimulationAndSave(FILE* fd, const char* prefix, + void checkAlongSimulationAndSave(mat_t* fd, const char* prefix, int m, int max_evals); - void checkUnconditionalAndSave(FILE* fd, const char* prefix, + void checkUnconditionalAndSave(mat_t* fd, const char* prefix, int m, int max_evals); protected:@; void check(const Quadrature& quad, int level, diff --git a/dynare++/src/Makefile.am b/dynare++/src/Makefile.am index 95f7c0387..f5429ff84 100644 --- a/dynare++/src/Makefile.am +++ b/dynare++/src/Makefile.am @@ -23,7 +23,7 @@ dynare___SOURCES = \ dynare___CPPFLAGS = -I../sylv/cc -I../tl/cc -I../kord -I../integ/cc -I.. -I$(top_srcdir)/mex/sources -DDYNVERSION=\"$(PACKAGE_VERSION)\" $(BOOST_CPPFLAGS) dynare___LDFLAGS = $(BOOST_LDFLAGS) -dynare___LDADD = ../kord/libkord.a ../integ/cc/libinteg.a ../tl/cc/libtl.a ../parser/cc/libparser.a ../utils/cc/libutils.a ../sylv/cc/libsylv.a $(noinst_LIBRARIES) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(PTHREAD_LIBS) +dynare___LDADD = ../kord/libkord.a ../integ/cc/libinteg.a ../tl/cc/libtl.a ../parser/cc/libparser.a ../utils/cc/libutils.a ../sylv/cc/libsylv.a $(noinst_LIBRARIES) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(PTHREAD_LIBS) $(LIBADD_MATIO) dynare___CXXFLAGS = $(PTHREAD_CFLAGS) BUILT_SOURCES = $(GENERATED_FILES) diff --git a/dynare++/src/dynare3.cpp b/dynare++/src/dynare3.cpp index 3eea8ae3f..545b5442a 100644 --- a/dynare++/src/dynare3.cpp +++ b/dynare++/src/dynare3.cpp @@ -122,32 +122,32 @@ Dynare::~Dynare() delete fde; } -void Dynare::writeMat4(FILE* fd, const char* prefix) const +void Dynare::writeMat(mat_t* fd, const char* prefix) const { char tmp[100]; sprintf(tmp, "%s_vars", prefix); - getAllEndoNames().writeMat4(fd, tmp); - getAllEndoNames().writeMat4Indices(fd, prefix); + getAllEndoNames().writeMat(fd, tmp); + getAllEndoNames().writeMatIndices(fd, prefix); sprintf(tmp, "%s_state_vars", prefix); - getStateNames().writeMat4(fd, tmp); + getStateNames().writeMat(fd, tmp); sprintf(tmp, "%s_shocks", prefix); - getExogNames().writeMat4(fd, tmp); - getExogNames().writeMat4Indices(fd, prefix); + getExogNames().writeMat(fd, tmp); + getExogNames().writeMatIndices(fd, prefix); sprintf(tmp, "%s_vcov_exo", prefix); - model->getVcov().writeMat4(fd, tmp); + model->getVcov().writeMat(fd, tmp); TwoDMatrix aux(1,1); sprintf(tmp, "%s_nstat", prefix); aux.get(0,0) = nstat(); - aux.writeMat4(fd, tmp); + aux.writeMat(fd, tmp); sprintf(tmp, "%s_npred", prefix); aux.get(0,0) = npred(); - aux.writeMat4(fd, tmp); + aux.writeMat(fd, tmp); sprintf(tmp, "%s_nboth", prefix); aux.get(0,0) = nboth(); - aux.writeMat4(fd, tmp); + aux.writeMat(fd, tmp); sprintf(tmp, "%s_nforw", prefix); aux.get(0,0) = nforw(); - aux.writeMat4(fd, tmp); + aux.writeMat(fd, tmp); } void Dynare::writeDump(const std::string& basename) const diff --git a/dynare++/src/dynare3.h b/dynare++/src/dynare3.h index fbb836ec1..a106f52aa 100644 --- a/dynare++/src/dynare3.h +++ b/dynare++/src/dynare3.h @@ -14,6 +14,8 @@ #include <vector> +#include <matio.h> + class Dynare; class DynareNameList : public NameList { @@ -140,7 +142,7 @@ public: void calcDerivatives(const Vector& yy, const Vector& xx); void calcDerivativesAtSteady(); - void writeMat4(FILE* fd, const char* prefix) const; + void writeMat(mat_t *fd, const char* prefix) const; void writeDump(const std::string& basename) const; private: void writeModelInfo(Journal& jr) const; diff --git a/dynare++/src/main.cpp b/dynare++/src/main.cpp index 5ac5d15d1..c883bf319 100644 --- a/dynare++/src/main.cpp +++ b/dynare++/src/main.cpp @@ -71,14 +71,14 @@ int main(int argc, char** argv) // open mat file std::string matfile(params.basename); matfile += ".mat"; - FILE* matfd = NULL; - if (NULL == (matfd=fopen(matfile.c_str(), "wb"))) { + mat_t* matfd = Mat_Create(matfile.c_str(), NULL); + if (matfd == NULL) { fprintf(stderr, "Couldn't open %s for writing.\n", matfile.c_str()); exit(1); } // write info about the model (dimensions and variables) - dynare.writeMat4(matfd, params.prefix); + dynare.writeMat(matfd, params.prefix); // write the dump file corresponding to the input dynare.writeDump(params.basename); @@ -103,7 +103,7 @@ int main(int argc, char** argv) std::string ss_matrix_name(params.prefix); ss_matrix_name += "_steady_states"; - ConstTwoDMatrix(app.getSS()).writeMat4(matfd, ss_matrix_name.c_str()); + ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name.c_str()); // check the approximation if (params.check_along_path || params.check_along_shocks @@ -126,14 +126,14 @@ int main(int argc, char** argv) } // write the folded decision rule to the Mat-4 file - app.getFoldDecisionRule().writeMat4(matfd, params.prefix); + app.getFoldDecisionRule().writeMat(matfd, params.prefix); // simulate conditional if (params.num_condper > 0 && params.num_condsim > 0) { SimResultsDynamicStats rescond(dynare.numeq(), params.num_condper, 0); ConstVector det_ss(app.getSS(),0); rescond.simulate(params.num_condsim, app.getFoldDecisionRule(), det_ss, dynare.getVcov(), journal); - rescond.writeMat4(matfd, params.prefix); + rescond.writeMat(matfd, params.prefix); } // simulate unconditional @@ -142,12 +142,12 @@ int main(int argc, char** argv) if (params.num_per > 0 && params.num_sim > 0) { SimResultsStats res(dynare.numeq(), params.num_per, params.num_burn); res.simulate(params.num_sim, dr, dynare.getSteady(), dynare.getVcov(), journal); - res.writeMat4(matfd, params.prefix); + res.writeMat(matfd, params.prefix); // impulse response functions if (! irf_list_ind.empty()) { IRFResults irf(dynare, dr, res, irf_list_ind, journal); - irf.writeMat4(matfd, params.prefix); + irf.writeMat(matfd, params.prefix); } } @@ -155,10 +155,10 @@ int main(int argc, char** argv) if (params.num_rtper > 0 && params.num_rtsim > 0) { RTSimResultsStats rtres(dynare.numeq(), params.num_rtper, params.num_burn); rtres.simulate(params.num_rtsim, dr, dynare.getSteady(), dynare.getVcov(), journal); - rtres.writeMat4(matfd, params.prefix); + rtres.writeMat(matfd, params.prefix); } - fclose(matfd); + Mat_Close(matfd); } catch (const KordException& e) { printf("Caugth Kord exception: "); diff --git a/dynare++/tl/cc/t_container.hweb b/dynare++/tl/cc/t_container.hweb index 00f7c6807..5aa46b461 100644 --- a/dynare++/tl/cc/t_container.hweb +++ b/dynare++/tl/cc/t_container.hweb @@ -62,6 +62,8 @@ is multiplied by unfolded tensors $g$ yielding unfolded tensor $B$. #include <string> #include <sstream> +#include <matio.h> + @<|ltsym| predicate@>; @<|TensorContainer| class definition@>; @<|UGSContainer| class declaration@>; @@ -124,7 +126,7 @@ public:@; @<|TensorContainer::fetchTensors| code@>; @<|TensorContainer::getMaxDim| code@>; @<|TensorContainer::print| code@>; - @<|TensorContainer::writeMat4| code@>; + @<|TensorContainer::writeMat| code@>; @<|TensorContainer::writeMMap| code@>; virtual ~TensorContainer() @@ -276,9 +278,9 @@ void print() const } } -@ Output to the MAT--4 file. -@<|TensorContainer::writeMat4| code@>= -void writeMat4(FILE* fd, const char* prefix) const +@ Output to the MAT file. +@<|TensorContainer::writeMat| code@>= +void writeMat(mat_t* fd, const char* prefix) const { for (const_iterator it = begin(); it != end(); ++it) { char lname[100]; @@ -290,7 +292,7 @@ void writeMat4(FILE* fd, const char* prefix) const strcat(lname, tmp); } ConstTwoDMatrix m(*((*it).second)); - m.writeMat4(fd, lname); + m.writeMat(fd, lname); } } diff --git a/dynare++/tl/cc/twod_matrix.cweb b/dynare++/tl/cc/twod_matrix.cweb index f7e1eb3c8..713229995 100644 --- a/dynare++/tl/cc/twod_matrix.cweb +++ b/dynare++/tl/cc/twod_matrix.cweb @@ -8,13 +8,10 @@ @<|ConstTwoDMatrix| constructors@>; -@<|ConstTwoDMatrix::writeMat4| code@>; +@<|ConstTwoDMatrix::writeMat| code@>; @<|TwoDMatrix| row methods code@>; @<|TwoDMatrix| column methods code@>; @<|TwoDMatrix::save| code@>; -@<|Mat4Header| constructor 1 code@>; -@<|Mat4Header| constructor 2 code@>; -@<|Mat4Header::write| code@>; @ @<|ConstTwoDMatrix| constructors@>= @@ -34,14 +31,24 @@ ConstTwoDMatrix::ConstTwoDMatrix(int first_row, int num, const ConstTwoDMatrix& : ConstGeneralMatrix(m, first_row, 0, num, m.ncols())@+ {} @ -@<|ConstTwoDMatrix::writeMat4| code@>= -void ConstTwoDMatrix::writeMat4(FILE* fd, const char* vname) const +@<|ConstTwoDMatrix::writeMat| code@>= +void ConstTwoDMatrix::writeMat(mat_t* fd, const char* vname) const { - Mat4Header header(*this, vname); - header.write(fd); + int dims[2]; + dims[0] = nrows(); + dims[1] = ncols(); + double *data = new double[nrows()*ncols()]; + for (int j = 0; j < ncols(); j++) for (int i = 0; i < nrows(); i++) - fwrite(&(get(i,j)), sizeof(double), 1, fd); + data[j*nrows()+i] = get(i,j); + + matvar_t *v = Mat_VarCreate(vname, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, data, 0); + + Mat_VarWrite(fd, v, COMPRESSION_NONE); + + Mat_VarFree(v); + delete[] data; } @ @@ -105,33 +112,4 @@ void TwoDMatrix::save(const char* fname) const fclose(fd); } -@ This constructs a MAT-4 header for Little Endian dense real double matrix. -@<|Mat4Header| constructor 1 code@>= -Mat4Header::Mat4Header(const ConstTwoDMatrix& m, const char* vn) - : type(0), rows(m.nrows()), cols(m.ncols()), imagf(0), namelen(strlen(vn)+1), - vname(vn) -{} - - -@ This constructs a MAT-4 header for text matrix. -@<|Mat4Header| constructor 2 code@>= -Mat4Header::Mat4Header(const ConstTwoDMatrix& m, const char* vn, const char* dummy) - : type(1), rows(m.nrows()), cols(m.ncols()), imagf(0), namelen(strlen(vn)+1), - vname(vn) -{} - - -@ -@<|Mat4Header::write| code@>= -void Mat4Header::write(FILE* fd) const -{ - fwrite(&type, sizeof(int), 1, fd); - fwrite(&rows, sizeof(int), 1, fd); - fwrite(&cols, sizeof(int), 1, fd); - fwrite(&imagf, sizeof(int), 1, fd); - fwrite(&namelen, sizeof(int), 1, fd); - fwrite(vname, 1, namelen, fd); -} - - -@ End of {\tt twod\_matrix.cpp} file. \ No newline at end of file +@ End of {\tt twod\_matrix.cpp} file. diff --git a/dynare++/tl/cc/twod_matrix.hweb b/dynare++/tl/cc/twod_matrix.hweb index 228474d8c..9e622189d 100644 --- a/dynare++/tl/cc/twod_matrix.hweb +++ b/dynare++/tl/cc/twod_matrix.hweb @@ -26,11 +26,11 @@ to allow submatrix construction from const reference arguments. #include "GeneralMatrix.h" #include <cstdio> +#include <matio.h> class TwoDMatrix; @<|ConstTwoDMatrix| class declaration@>; @<|TwoDMatrix| class declaration@>; -@<|Mat4Header| class declaration@>; #endif @@ -57,7 +57,7 @@ public:@/ {@+ return numRows();@+} int ncols() const {@+ return numCols();@+} - void writeMat4(FILE* fd, const char* vname) const; + void writeMat(mat_t* fd, const char* vname) const; }; @ Here we do the same as for |ConstTwoDMatrix| plus define @@ -103,8 +103,8 @@ public:@/ @<|TwoDMatrix| row methods declarations@>; @<|TwoDMatrix| column methods declarations@>; void save(const char* fname) const; - void writeMat4(FILE* fd, const char* vname) const - {@+ ConstTwoDMatrix(*this).writeMat4(fd, vname);@+} + void writeMat(mat_t* fd, const char* vname) const + {@+ ConstTwoDMatrix(*this).writeMat(fd, vname);@+} }; @ @@ -136,21 +136,4 @@ public:@/ void addColumn(double d, const TwoDMatrix& m, int from, int to) {@+ addColumn(d, ConstTwoDMatrix(m), from, to);@+} -@ -@<|Mat4Header| class declaration@>= -class Mat4Header { - int type; - int rows; - int cols; - int imagf; - int namelen; - const char* vname; -public:@; - Mat4Header(const ConstTwoDMatrix& m, const char* vname); - Mat4Header(const ConstTwoDMatrix& m, const char* vname, const char* dummy); - void write(FILE* fd) const; -}; - - - -@ End of {\tt twod\_matrix.h} file. \ No newline at end of file +@ End of {\tt twod\_matrix.h} file. diff --git a/mex/build/dynare_simul_.am b/mex/build/dynare_simul_.am index 65fc789cc..f9c504c0b 100644 --- a/mex/build/dynare_simul_.am +++ b/mex/build/dynare_simul_.am @@ -5,6 +5,6 @@ dynare_simul__CPPFLAGS = -I$(top_srcdir)/../../../dynare++/sylv/cc -I$(top_srcdi dynare_simul__CXXFLAGS = $(PTHREAD_CFLAGS) # libdynare++ must come before pthread -dynare_simul__LDADD = ../libdynare++/libdynare++.a $(PTHREAD_LIBS) +dynare_simul__LDADD = ../libdynare++/libdynare++.a $(PTHREAD_LIBS) $(LIBADD_MATIO) nodist_dynare_simul__SOURCES = $(top_srcdir)/../../../dynare++/extern/matlab/dynare_simul.cpp diff --git a/mex/build/k_order_perturbation.am b/mex/build/k_order_perturbation.am index bc604cb09..8175e4dac 100644 --- a/mex/build/k_order_perturbation.am +++ b/mex/build/k_order_perturbation.am @@ -5,7 +5,7 @@ k_order_perturbation_CPPFLAGS = -I$(top_srcdir)/../../../dynare++/src -I$(top_sr k_order_perturbation_CXXFLAGS = $(PTHREAD_CFLAGS) # libdynare++ must come before pthread -k_order_perturbation_LDADD = ../libdynare++/libdynare++.a $(PTHREAD_LIBS) $(LIBADD_DLOPEN) +k_order_perturbation_LDADD = ../libdynare++/libdynare++.a $(PTHREAD_LIBS) $(LIBADD_DLOPEN) $(LIBADD_MATIO) TOPDIR = $(top_srcdir)/../../sources/k_order_perturbation diff --git a/mex/build/matlab/Makefile.am b/mex/build/matlab/Makefile.am index 82904454f..06d5227c1 100644 --- a/mex/build/matlab/Makefile.am +++ b/mex/build/matlab/Makefile.am @@ -1,8 +1,13 @@ ACLOCAL_AMFLAGS = -I ../../../m4 # libdynare++ must come before gensylv, k_order_perturbation, dynare_simul_ + if DO_SOMETHING -SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv k_order_perturbation dynare_simul_ estimation block_kalman_filter sobol local_state_space_iterations +SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv estimation block_kalman_filter sobol local_state_space_iterations + +if HAVE_MATIO +SUBDIRS += k_order_perturbation dynare_simul_ +endif if HAVE_GSL SUBDIRS += ms_sbvar diff --git a/mex/build/matlab/configure.ac b/mex/build/matlab/configure.ac index ca948b4db..7fbfc03cb 100644 --- a/mex/build/matlab/configure.ac +++ b/mex/build/matlab/configure.ac @@ -77,6 +77,12 @@ AC_SUBST([LIBADD_DLOPEN]) AX_GSL AM_CONDITIONAL([HAVE_GSL], [test "x$has_gsl" = "xyes"]) +# Check for libmatio, needed by MEX files using Dynare++ code +AC_CHECK_HEADER([matio.h]) +AC_CHECK_LIB([matio], [Mat_Open], [LIBADD_MATIO="-lmatio"]) +AC_SUBST([LIBADD_MATIO]) +AM_CONDITIONAL([HAVE_MATIO], [test "x$ac_cv_header_matio_h" = "xyes" -a "x$ac_cv_lib_matio_Mat_Open" = "xyes"]) + AM_CONDITIONAL([DO_SOMETHING], [test "x$ax_enable_matlab" = "xyes" -a "x$ax_matlab_version_ok" = "xyes" -a "x$ax_mexopts_ok" = "xyes"]) if test "x$ax_enable_matlab" = "xyes" -a "x$ax_matlab_version_ok" = "xyes" -a "x$ax_mexopts_ok" = "xyes"; then @@ -89,6 +95,12 @@ else BUILD_MEX_MATLAB="no (missing MATLAB, or unknown version, or unknown architecture)" fi +if test "x$ac_cv_header_matio_h" = "xyes" -a "x$ac_cv_lib_matio_Mat_Open" = "xyes"; then + BUILD_KORDER_DYNSIMUL_MEX_MATLAB="yes" +else + BUILD_KORDER_DYNSIMUL_MEX_MATLAB="no (missing MatIO library)" +fi + if test "x$ax_enable_matlab" = "xyes" -a "x$ax_matlab_version_ok" = "xyes" -a "x$ax_mexopts_ok" = "xyes" -a "x$F77" != "x"; then BUILD_KALMAN_STEADY_STATE_MATLAB="yes" else @@ -124,7 +136,8 @@ AC_MSG_NOTICE([ Dynare is now configured for building the following components... Binaries (with "make"): - MEX files for MATLAB (except MS-SBVAR and Kalman Steady State): $BUILD_MEX_MATLAB + MEX files for MATLAB (except those listed below): $BUILD_MEX_MATLAB + k-order and dynare_simul MEX files for MATLAB: $BUILD_KORDER_DYNSIMUL_MEX_MATLAB MS-SBVAR MEX files for MATLAB: $BUILD_MS_SBVAR_MEX_MATLAB Kalman Steady State MEX file for MATLAB: $BUILD_KALMAN_STEADY_STATE_MATLAB M2HTML documentation: $BUILD_M2HTML diff --git a/mex/build/octave/Makefile.am b/mex/build/octave/Makefile.am index 2689afab4..eac7983ed 100644 --- a/mex/build/octave/Makefile.am +++ b/mex/build/octave/Makefile.am @@ -2,7 +2,11 @@ ACLOCAL_AMFLAGS = -I ../../../m4 # libdynare++ must come before gensylv, k_order_perturbation, dynare_simul_ if DO_SOMETHING -SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv k_order_perturbation dynare_simul_ qzcomplex ordschur block_kalman_filter sobol local_state_space_iterations linsolve +SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv qzcomplex ordschur block_kalman_filter sobol local_state_space_iterations linsolve + +if HAVE_MATIO +SUBDIRS += k_order_perturbation dynare_simul_ +endif if HAVE_GSL if HAVE_MATIO diff --git a/mex/build/octave/configure.ac b/mex/build/octave/configure.ac index 0a1362799..44119e877 100644 --- a/mex/build/octave/configure.ac +++ b/mex/build/octave/configure.ac @@ -79,9 +79,9 @@ else fi if test "x$MKOCTFILE" != "x" -a "x$ac_cv_header_matio_h" = "xyes" -a "x$ac_cv_lib_matio_Mat_Open" = "xyes"; then - BUILD_ESTIMATION_MEX_OCTAVE="yes" + BUILD_ESTIMATION_KORDER_DYNSIMUL_MEX_OCTAVE="yes" else - BUILD_ESTIMATION_MEX_OCTAVE="no (missing MatIO library)" + BUILD_ESTIMATION_KORDER_DYNSIMUL_MEX_OCTAVE="no (missing MatIO library)" fi if test "x$MKOCTFILE" != "x" -a "x$F77" != "x"; then @@ -109,10 +109,10 @@ AC_MSG_NOTICE([ Dynare is now configured for building the following components... Binaries (with "make"): - MEX files for Octave (except MS-SBVAR and Kalman Steady State): $BUILD_MEX_OCTAVE + MEX files for Octave (except those listed below): $BUILD_MEX_OCTAVE MS-SBVAR MEX files for Octave: $BUILD_MS_SBVAR_MEX_OCTAVE Kalman Steady State MEX file for Octave: $BUILD_KALMAN_STEADY_STATE_OCTAVE - Estimation MEX for Octave: $BUILD_ESTIMATION_MEX_OCTAVE + Estimation, k-order and dynare_simul MEX for Octave: $BUILD_ESTIMATION_KORDER_DYNSIMUL_MEX_OCTAVE ]) -- GitLab