Merge branch 'master' into json

time-shift
Stéphane Adjemian (Charybdis) 2017-06-16 20:03:36 +02:00
commit 119b5a62f2
880 changed files with 38591 additions and 29405 deletions

4
.gitignore vendored
View File

@ -60,6 +60,7 @@ checksum
/doc/dynare.info /doc/dynare.info
/doc/dynare.info-1 /doc/dynare.info-1
/doc/dynare.info-2 /doc/dynare.info-2
/doc/dynare.info-3
/doc/dynare.cp /doc/dynare.cp
/doc/dynare.fn /doc/dynare.fn
/doc/dynare.fns /doc/dynare.fns
@ -212,3 +213,6 @@ tests/julia/rbc/rbc*.jl
# Octave variables saved when Octave crashes # Octave variables saved when Octave crashes
octave-workspace octave-workspace
# VERSION generated file
VERSION

797
NEWS
View File

@ -1,3 +1,800 @@
Announcement for Dynare 4.5.0 (on 2013-12-16)
=============================================
We are pleased to announce the release of Dynare 4.5.0.
This major release adds new features and fixes various bugs.
The Windows packages are already available for download at:
http://www.dynare.org/download/dynare-stable
The Mac and Debian/Ubuntu packages should follow soon.
All users are strongly encouraged to upgrade.
This release is compatible with MATLAB versions ranging from 7.3 (R2006b) to
9.2 (R2017a) and with GNU Octave version 4.2.
Here is the list of major user-visible changes:
Dynare 4.5
==========
- Ramsey policy
+ Added command `ramsey_model` that builds the expanded model with
FOC conditions for the planner's problem but doesn't perform any
computation. Usefull to compute Ramsey policy in a perfect
foresight model,
+ `ramsey_policy` accepts multipliers in its variable list and
displays results for them.
- Perfect foresight models
+ New commands `perfect_foresight_setup` (for preparing the
simulation) and `perfect_foresight_solver` (for computing it). The
old `simul` command still exist and is now an alias for
`perfect_foresight_setup` + `perfect_foresight_solver`. It is no
longer possible to manipulate by hand the contents of
`oo_.exo_simul` when using `simul`. People who want to do
it must first call `perfect_foresight_setup`, then do the
manipulations, then call `perfect_foresight_solver`,
+ By default, the perfect foresight solver will try a homotopy
method if it fails to converge at the first try. The old behavior
can be restored with the `no_homotopy` option,
+ New option `stack_solve_algo=7` that allows specifying a
`solve_algo` solver for solving the model,
+ New option `solve_algo` that allows specifying a solver for
solving the model when using `stack_solve_algo=7`,
+ New option `lmmcp` that solves the model via a Levenberg-Marquardt
mixed complementarity problem (LMMCP) solver,
+ New option `robust_lin_solve` that triggers the use of a robust
linear solver for the default `solve_algo=4`,
+ New options `tolf` and `tolx` to control termination criteria of
solvers,
+ New option `endogenous_terminal_period` to `simul`,
+ Added the possibility to set the initial condition of the
(stochastic) extended path simulations with the histval block.
- Optimal simple rules
+ Saves the optimal value of parameters to `oo_.osr.optim_params`,
+ New block `osr_params_bounds` allows specifying bounds for the
estimated parameters,
+ New option `opt_algo` allows selecting different optimizers while
the new option `optim` allows specifying the optimizer options,
+ The `osr` command now saves the names, bounds, and indices for the
estimated parameters as well as the indices and weights of the
variables entering the objective function into `M_.osr`.
- Forecasts and Smoothing
+ The smoother and forecasts take uncertainty about trends and means
into account,
+ Forecasts accounting for measurement error are now saved in fields
of the form `HPDinf_ME` and `HPDsup_ME`,
+ New fields `oo_.Smoother.Trend` and `oo_.Smoother.Constant` that
save the trend and constant parts of the smoothed variables,
+ new field `oo_.Smoother.TrendCoeffs` that stores the trend
coefficients.
+ Rolling window forecasts allowed in `estimation` command by
passing a vector to `first_obs`,
+ The `calib_smoother` command now accepts the `loglinear`,
`prefilter`, `first_obs` and `filter_decomposition` options.
- Estimation
+ New options: `logdata`, `consider_all_endogenous`,
`consider_only_observed`, `posterior_max_subsample_draws`,
`mh_conf_sig`, `diffuse_kalman_tol`, `dirname`, `nodecomposition`
+ `load_mh_file` and `mh_recover` now try to load chain's proposal density,
+ New option `load_results_after_load_mh` that allows loading some
posterior results from a previous run if no new MCMC draws are
added,
+ New option `posterior_nograph` that suppresses the generation of
graphs associated with Bayesian IRFs, posterior smoothed objects,
and posterior forecasts,
+ Saves the posterior density at the mode in
`oo_.posterior.optimization.log_density`,
+ The `filter_covariance` option now also works with posterior
sampling like Metropolis-Hastings,
+ New option `no_posterior_kernel_density` to suppress computation
of kernel density of posterior objects,
+ Recursive estimation and forecasting now provides the individual
`oo_` structures for each sample in `oo_recursive_`,
+ The `trace_plot` command can now plot the posterior density,
+ New command `generate_trace_plots` allows generating all trace
plots for one chain,
+ New commands `prior_function` and `posterior_function` that
execute a user-defined function on parameter draws from the
prior/posterior distribution,
+ New option `huge_number` for replacement of infinite bounds with
large number during `mode_compute`,
+ New option `posterior_sampling_method` allows selecting the new
posterior sampling options:
`tailored_random_block_metropolis_hastings` (Tailored randomized
block (TaRB) Metropolis-Hastings), `slice` (Slice sampler),
`independent_metropolis_hastings` (Independent
Metropolis-Hastings),
+ New option `posterior_sampler_options` that allow controlling the
options of the `posterior_sampling_method`, its `scale_file`-option
pair allows loading the `_mh_scale.mat`-file storing the tuned
scale factor from a previous run of `mode_compute=6`,
+ New option `raftery_lewis_diagnostics` that computes Raftery/Lewis
(1992) convergence diagnostics,
+ New option `fast_kalman_filter` that provides fast Kalman filter
using Chandrasekhar recursions as described in Ed Herbst (2015),
+ The `dsge_var` option now saves results at the posterior mode into
`oo_.dsge_var`,
+ New option `smoothed_state_uncertainty` to provide the uncertainty
estimate for the smoothed state estimate from the Kalman smoother,
+ New prior density: generalized Weibull distribution,
+ Option `mh_recover` now allows continuing a crashed chain at the
last save mh-file,
+ New option `nonlinear_filter_initialization` for the
`estimation` command. Controls the initial covariance matrix
of the state variables in nonlinear filters.
+ The `conditional_variance_decomposition` option now displays
output and stores it as a LaTeX-table when the `TeX` option is
invoked,
+ The `use_calibration` to `estimated_params_init` now also works
with ML,
+ Improved initial estimation checks.
- Steady state
+ The default solver for finding the steady state is now a
trust-region solver (can be triggered explicitly with option
`solve_algo=4`),
+ New options `tolf` and `tolx` to control termination criteria of
solver,
+ The debugging mode now provides the termination values in steady
state finding.
- Stochastic simulations
+ New options `nodecomposition`,
+ New option `bandpass_filter` to compute bandpass-filtered
theoretical and simulated moments,
+ New option `one_sided_hp_filter` to compute one-sided HP-filtered
simulated moments,
+ `stoch_simul` displays a simulated variance decomposition when
simulated moments are requested,
+ `stoch_simul` saves skewness and kurtosis into respective fields
of `oo_` when simulated moments have been requested,
+ `stoch_simul` saves the unconditional variance decomposition in
`oo_.variance_decomposition`,
+ New option `dr_display_tol` that governs omission of small terms
in display of decision rules,
+ The `stoch_simul` command now prints the displayed tables as LaTeX
code when the new `TeX` option is enabled,
+ The `loglinear` option now works with lagged and leaded exogenous
variables like news shocks,
+ New option `spectral_density` that allows displaying the spectral
density of (filtered) endogenous variables,
+ New option `contemporaneous_correlation` that allows saving
contemporaneous correlations in addition to the covariances.
- Identification
+ New options `diffuse_filter` and `prior_trunc`,
+ The `identification` command now supports correlations via
simulated moments,
- Sensitivity analysis
+ New blocks `irf_calibration` and `moment_calibration`,
+ Outputs LaTeX tables if the new `TeX` option is used,
+ New option `relative_irf` to `irf_calibration` block.
- Conditional forecast
+ Command `conditional_forecast` now takes into account `histval`
block if present.
- Shock decomposition
+ New option `colormap` to `shocks_decomposition` for controlling
the color map used in the shocks decomposition graphs,
+ `shocks_decomposition` now accepts the `nograph` option,
+ New command `realtime_shock_decomposition` that for each period `T= [presample,...,nobs]`
allows computing the:
* realtime historical shock decomposition `Y(t|T)`, i.e. without observing data in `[T+1,...,nobs]`
* forecast shock decomposition `Y(T+k|T)`
* realtime conditional shock decomposition `Y(T+k|T+k)-Y(T+k|T)`
+ New block `shock_groups` that allows grouping shocks for the
`shock_decomposition` and `realtime_shock_decomposition` commands,
+ New command `plot_shock_decomposition` that allows plotting the
results from `shock_decomposition` and
`realtime_shock_decomposition` for different vintages and shock
groupings.
- Macroprocessor
+ Can now pass a macro-variable to the `@#include` macro directive,
+ New preprocessor flag `-I`, macro directive `@#includepath`, and
dynare config file block `[paths]` to pass a search path to the
macroprocessor to be used for file inclusion via `@#include`.
- Command line
+ New option `onlyclearglobals` (do not clear JIT compiled functions
with recent versions of Matlab),
+ New option `minimal_workspace` to use fewer variables in the
current workspace,
+ New option `params_derivs_order` allows limiting the order of the
derivatives with respect to the parameters that are calculated by
the preprocessor,
+ New command line option `mingw` to support the MinGW-w64 C/C++
Compiler from TDM-GCC for `use_dll`.
- dates/dseries/reporting classes
+ New methods `abs`, `cumprod` and `chain`,
+ New option `tableRowIndent` to `addTable`,
+ Reporting system revamped and made more efficient, dependency on
matlab2tikz has been dropped.
- Optimization algorithms
+ `mode_compute=2` Uses the simulated annealing as described by
Corana et al. (1987),
+ `mode_compute=101` Uses SOLVEOPT as described by Kuntsevich and
Kappel (1997),
+ `mode_compute=102` Uses `simulannealbnd` from Matlab's Global
Optimization Toolbox (if available),
+ New option `silent_optimizer` to shut off output from mode
computing/optimization,
+ New options `verbosity` and `SaveFiles` to control output and
saving of files during mode computing/optimization.
- LaTeX output
+ New command `write_latex_original_model`,
+ New option `write_equation_tags` to `write_latex_dynamic_model`
that allows printing the specified equation tags to the generate
LaTeX code,
+ New command `write_latex_parameter_table` that writes the names and
values of model parameters to a LaTeX table,
+ New command `write_latex_prior_table` that writes the descriptive
statistics about the prior distribution to a LaTeX table,
+ New command `collect_latex_files` that creates one compilable LaTeX
file containing all TeX-output.
- Misc.
+ Provides 64bit preprocessor,
+ Introduces new path management to avoid conflicts with other
toolboxes,
+ Full compatibility with Matlab 2014b's new graphic interface,
+ When using `model(linear)`, Dynare automatically checks
whether the model is truly linear,
+ `usedll`, the `msvc` option now supports `normcdf`, `acosh`,
`asinh`, and `atanh`,
+ New parallel option `NumberOfThreadsPerJob` for Windows nodes that
sets the number of threads assigned to each remote MATLAB/Octave
run,
+ Improved numerical performance of
`schur_statespace_transformation` for very large models,
+ The `all_values_required` option now also works with `histval`,
+ Add missing `horizon` option to `ms_forecast`,
+ BVAR now saves the marginal data density in
`oo_.bvar.log_marginal_data_density` and stores prior and
posterior information in `oo_.bvar.prior` and
`oo_.bvar.posterior`.
* Bugs and problems identified in version 4.4.3 and that have been fixed in version 4.5.0:
- BVAR models
+ `bvar_irf` could display IRFs in an unreadable way when they moved from
negative to positive values,
+ In contrast to what is stated in the documentation, the confidence interval
size `conf_sig` was 0.6 by default instead of 0.9.
- Conditional forecasts
+ The `conditional_forecast` command produced wrong results in calibrated
models when used at initial values outside of the steady state (given with
`initval`),
+ The `plot_conditional_forecast` option could produce unreadable figures if
the areas overlap,
+ The `conditional_forecast` command after MLE crashed,
+ In contrast to what is stated in the manual, the confidence interval size
`conf_sig` was 0.6 by default instead of 0.8.
+ Conditional forecasts were wrong when the declaration of endogenous
variables was not preceeding the declaration of the exogenous
variables and parameters.
- Discretionary policy
+ Dynare allowed running models where the number of instruments did not match
the number of omitted equations,
+ Dynare could crash in some cases when trying to display the solution,
+ Parameter dependence embedded via a `steady_state` was not taken into
account, typically resulting in crashes.
- dseries class
+ When subtracting a dseries object from a number, the number was instead
subtracted from the dseries object.
- DSGE-VAR models
+ Dynare crashed when estimation encountered non-finite values in the Jacobian
at the steady state,
+ The presence of a constant was not considered for degrees of freedom
computation of the Gamma function used during the posterior computation; due
to only affecting the constant term, results should be be unaffected, except
for model_comparison when comparing models with and without.
- Estimation command
+ In contrast to what was stated in the manual, the confidence interval size
`conf_sig` for `forecast` without MCMC was 0.6 by default instead of 0.9,
+ Calling estimation after identification could lead to crashes,
+ When using recursive estimation/forecasting and setting some elements of
`nobs` to be larger than the number of observations T in the data,
`oo_recursive_` contained additional cell entries that simply repeated the
results obtained for `oo_recursive_T`,
+ Computation of Bayesian smoother could crash for larger models when
requesting `forecast` or `filtered_variables`,
+ Geweke convergence diagnostics were not computed on the full MCMC chain when
the `load_mh_file` option was used,
+ The Geweke convergence diagnostics always used the default `taper_steps` and
`geweke_interval`,
+ Bayesian IRFs (`bayesian_irfs` option) could be displayed in an unreadable
way when they move from negative to positive values,
+ If `bayesian_irfs` was requested when `mh_replic` was too low to compute
HPDIs, plotting was crashing,
+ The x-axis value in `oo_.prior_density` for the standard deviation and
correlation of measurement errors was written into a field
`mearsurement_errors_*` instead of `measurement_errors_*`,
+ Using a user-defined `mode_compute` crashed estimation,
+ Option `mode_compute=10` did not work with infinite prior bounds,
+ The posterior variances and covariances computed by `moments_varendo` were
wrong for very large models due to a matrix erroneously being filled up with
zeros,
+ Using the `forecast` option with `loglinear` erroneously added the unlogged
steady state,
+ When using the `loglinear` option the check for the presence of a constant
was erroneously based on the unlogged steady state,
+ Estimation of `observation_trends` was broken as the trends specified as a
function of deep parameters were not correctly updated during estimation,
+ When using `analytic_derivation`, the parameter values were not set before
testing whether the steady state file changes parameter values, leading to
subsequent crashes,
+ If the steady state of an initial parameterization did not solve, the
observation equation could erroneously feature no constant when the
`use_calibration` option was used,
+ When computing posterior moments, Dynare falsely displayed that moment
computations are skipped, although the computation was performed correctly,
+ If `conditional_variance_decomposition` was requested, although all
variables contain unit roots, Dynare crashed instead of providing an error
message,
+ Computation of the posterior parameter distribution was erroneously based
on more draws than specified (there was one additional draw for every Markov
chain),
+ The estimation option `lyapunov=fixed_point` was broken,
+ Computation of `filtered_vars` with only one requested step crashed Dynare,
+ Option `kalman_algo=3` was broken with non-diagonal measurement error,
+ When using the diffuse Kalman filter with missing observations, an additive
factor log(2*pi) was missing in the last iteration step,
+ Passing of the `MaxFunEvals` and `InitialSimplexSize` options to
`mode_compute=8` was broken,
+ Bayesian forecasts contained initial conditions and had the wrong length in
both plots and stored variables,
+ Filtered variables obtained with `mh_replic=0`, ML, or
`calibrated_smoother` were padded with zeros at the beginning and end and
had the wrong length in stored variables,
+ Computation of smoothed measurement errors in Bayesian estimation was broken,
+ The `selected_variables_only` option (`mh_replic=0`, ML, or
`calibrated_smoother`) returned wrong results for smoothed, updated, and
filtered variables,
+ Combining the `selected_variables_only` option with forecasts obtained
using `mh_replic=0`, ML, or `calibrated_smoother` leaded to crashes,
+ `oo_.UpdatedVariables` was only filled when the `filtered_vars` option was specified,
+ When using Bayesian estimation with `filtered_vars`, but without
`smoother`, then `oo_.FilteredVariables` erroneously also contained filtered
variables at the posterior mean as with `mh_replic=0`,
+ Running an MCMC a second time in the same folder with a different number of
iterations could result in crashes due to the loading of stale files,
+ Results displayed after Bayesian estimation when not specifying
the `smoother` option were based on the parameters at the mode
from mode finding instead of the mean parameters from the
posterior draws. This affected the smoother results displayed, but
also calls to subsequent command relying on the parameters stored
in `M_.params` like `stoch_simul`,
+ The content of `oo_.posterior_std` after Bayesian estimation was based on
the standard deviation at the posterior mode, not the one from the MCMC, this
was not consistent with the reference manual,
+ When the initialization of an MCMC run failed, the metropolis.log file was
locked, requiring a restart of Matlab to restart estimation,
+ If the posterior mode was right at the corner of the prior bounds, the
initialization of the MCMC erroneously crashed,
+ If the number of dropped draws via `mh_drop` coincided with the number of
draws in a `_mh'-file`, `oo_.posterior.metropolis.mean` and
`oo_.posterior.metropolis.Variance` were NaN.
- Estimation and calibrated smoother
+ When using `observation_trends` with the `prefilter` option, the mean shift
due to the trend was not accounted for,
+ When using `first_obs`>1, the higher trend starting point of
`observation_trends` was not taken into account, leading, among other things,
to problems in recursive forecasting,
+ The diffuse Kalman smoother was crashing if the forecast error variance
matrix becomes singular,
+ The multivariate Kalman smoother provided incorrect state estimates when
all data for one observation are missing,
+ The multivariate diffuse Kalman smoother provided incorrect state estimates
when the `Finf` matrix becomes singular,
+ The univariate diffuse Kalman filter was crashing if the initial covariance
matrix of the nonstationary state vector is singular,
- Forecats
+ In contrast to what is stated in the manual, the confidence interval size
`conf_sig` was 0.6 by default instead of 0.9.
+ Forecasting with exogenous deterministic variables provided wrong decision
rules, yielding wrong forecasts.
+ Forecasting with exogenous deterministic variables crashed when the
`periods` option was not explicitly specified,
+ Option `forecast` when used with `initval` was using the initial values in
the `initval` block and not the steady state computed from these initial
values as the starting point of forecasts.
- Global Sensitivity Analysis
+ Sensitivity with ML estimation could result in crashes,
+ Option `mc` must be forced if `neighborhood_width` is used,
+ Fixed dimension of `stock_logpo` and `stock_ys`,
+ Incomplete variable initialization could lead to crashes with `prior_range=1`.
- Indentification
+ Identification did not correctly pass the `lik_init` option,
requiring the manual setting of `options_.diffuse_filter=1` in
case of unit roots,
+ Testing identification of standard deviations as the only
parameters to be estimated with ML leaded to crashes,
+ Automatic increase of the lag number for autocovariances when the
number of parameters is bigger than the number of non-zero moments
was broken,
+ When using ML, the asymptotic Hessian was not computed,
+ Checking for singular values when the eigenvectors contained only
one column did not work correctly,
- Model comparison
+ Selection of the `modifiedharmonicmean` estimator was broken,
- Optimal Simple Rules
+ When covariances were specified, variables that only entered with
their variance and no covariance term obtained a wrong weight,
resulting in wrong results,
+ Results reported for stochastic simulations after `osr` were based
on the last parameter vector encountered during optimization,
which does not necessarily coincide with the optimal parameter
vector,
+ Using only one (co)variance in the objective function resulted in crashes,
+ For models with non-stationary variables the objective function was computed wrongly.
- Ramsey policy
+ If a Lagrange multiplier appeared in the model with a lead or a lag
of more than one period, the steady state could be wrong.
+ When using an external steady state file, incorrect steady states
could be accepted,
+ When using an external steady state file with more than one
instrument, Dynare crashed,
+ When using an external steady state file and running `stoch_simul`
after `ramsey_planner`, an incorrect steady state was used,
+ When the number of instruments was not equal to the number of
omitted equations, Dynare crashed with a cryptic message,
+ The `planner_objective` accepted `varexo`, but ignored them for computations,
- Shock decomposition
+ Did not work with the `parameter_set=calibration` option if an
`estimated_params` block is present,
+ Crashed after MLE.
- Perfect foresight models
+ The perfect foresight solver could accept a complex solution
instead of continuing to look for a real-valued one,
+ The `initval_file` command only accepted column and not row vectors,
+ The `initval_file` command did not work with Excel files,
+ Deterministic simulations with one boundary condition crashed in
`solve_one_boundary` due to a missing underscore when passing
`options_.simul.maxit`,
+ Deterministic simulation with exogenous variables lagged by more
than one period crashed,
+ Termination criterion `maxit` was hard-coded for `solve_algo=0`
and could no be changed,
+ When using `block`/`bytecode`, relational operators could not be enforced,
+ When using `block` some exceptions were not properly handled,
leading to code crashes,
+ Using `periods=1` crashed the solver (bug only partially fixed).
- Smoothing
+ The univariate Kalman smoother returned wrong results when used
with correlated measurement error,
+ The diffuse smoother sometimes returned linear combinations of the
smoothed stochastic trend estimates instead of the original trend
estimates.
- Perturbation reduced form
+ In contrast to what is stated in the manual, the results of the
unconditional variance decomposition were only stored in
`oo_.gamma_y(nar+2)`, not in `oo_.variance_decomposition`,
+ Dynare could crash when the steady state could not be computed
when using the `loglinear` option,
+ Using `bytcode` when declared exogenous variables were not
used in the model leaded to crashes in stochastic simulations,
+ Displaying decision rules involving lags of auxiliary variables of
type 0 (leads>1) crashed.
+ The `relative_irf` option resulted in wrong output at `order>1` as
it implicitly relies on linearity.
- Displaying of the MH-history with the `internals` command crashed
if parameter names did not have same length.
- Dynare crashed when the user-defined steady state file returned an
error code, but not an conformable-sized steady state vector.
- Due to a bug in `mjdgges.mex` unstable parameter draws with
eigenvalues up to 1+1e-6 could be accepted as stable for the
purpose of the Blanchard-Kahn conditions, even if `qz_criterium<1`.
- The `use_dll` option on Octave for Windows required to pass a
compiler flag at the command line, despite the manual stating this
was not necessary.
- Dynare crashed for models with `block` option if the Blanchard-Kahn
conditions were not satisfied instead of generating an error
message.
- The `verbose` option did not work with `model(block)`.
- When falsely specifying the `model(linear)` for nonlinear models,
incorrect steady states were accepted instead of aborting.
- The `STEADY_STATE` operator called on model local variables
(so-called pound variables) did not work as expected.
- The substring operator in macro-processor was broken. The
characters of the substring could be mixed with random characters
from the memory space.
- Block decomposition could sometimes cause the preprocessor to crash.
- A bug when external functions were used in model local variables
that were contained in equations that required auxiliary
variable/equations led to crashes of Matlab.
- Sampling from the prior distribution for an inverse gamma II
distribution when `prior_trunc>0` could result in incorrect
sampling.
- Sampling from the prior distribution for a uniform distribution
when `prior_trunc>0` was ignoring the prior truncation.
- Conditional forecasts were wrong when the declaration of endogenous
variables was not preceeding the declaration of the exogenous
variables and parameters.
Announcement for Dynare 4.4.3 (on 2014-07-31) Announcement for Dynare 4.4.3 (on 2014-07-31)
============================================= =============================================

View File

@ -91,7 +91,7 @@ If you have downloaded the sources from an official source archive or the source
If you want to use Git, do the following from a terminal: If you want to use Git, do the following from a terminal:
git clone --recursive http://github.com/DynareTeam/dynare.git git clone --recursive https://github.com/DynareTeam/dynare.git
cd dynare cd dynare
autoreconf -si autoreconf -si
@ -303,7 +303,7 @@ After this, prepare the source and configure the build tree as described for Lin
- **NB**: If not compiling Dynare mex files for Octave, add ```--without-octave``` to the installation command - **NB**: If not compiling Dynare mex files for Octave, add ```--without-octave``` to the installation command
- **NB**: To compile the latest stable version of dynare, follow the same instructions as above, omitting the ```--HEAD``` argument - **NB**: To compile the latest stable version of dynare, follow the same instructions as above, omitting the ```--HEAD``` argument
- **NB**: To update a ```--HEAD``` install of dynare you need to uninstall it then install it again: ```brew uninstall dynare; brew install dynare --HEAD```. - **NB**: To update a ```--HEAD``` install of dynare you need to uninstall it then install it again: ```brew uninstall dynare; brew install dynare --HEAD```.
- **NB**: If you want to maintain a separate git directory of dynare, you can do a ```--HEAD``` install of dynare, then uninstall it. This will have the effect of bringing in all the dependencies you will need to then compile dynare from your git directory. Then, change to the git directory and type: - **NB**: If you want to maintain a separate git directory of dynare, you can do a ```--HEAD``` install of dynare, then uninstall it. This will have the effect of bringing in all the dependencies you will need to then compile dynare from your git directory. (For `flex` and `bison` it may be necessary to symlink them via `brew link bison --force` and `brew link flex --force` as they are keg-only). Then, change to the git directory and type:
- ```autoreconf -si; ./configure --with-matlab=/Applications/MATLAB_R2015a.app MATLAB_VERSION=R2015a```, adjusting the Matlab path and version to accord with your version - ```autoreconf -si; ./configure --with-matlab=/Applications/MATLAB_R2015a.app MATLAB_VERSION=R2015a```, adjusting the Matlab path and version to accord with your version
- Once compilation is done, open Matlab and type the last line shown when you type ```brew info dynare``` in the Terminal window. With the typical Homebrew setup, this is: - Once compilation is done, open Matlab and type the last line shown when you type ```brew info dynare``` in the Terminal window. With the typical Homebrew setup, this is:
- ```addpath /usr/local/opt/dynare/lib/dynare/matlab``` - ```addpath /usr/local/opt/dynare/lib/dynare/matlab```

1
VERSION.in Normal file
View File

@ -0,0 +1 @@
@PACKAGE_VERSION@

View File

@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with Dynare. If not, see <http://www.gnu.org/licenses/>. dnl along with Dynare. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ([2.62]) AC_PREREQ([2.62])
AC_INIT([dynare], [4.5-unstable]) AC_INIT([dynare], [4.6-unstable])
AC_CONFIG_SRCDIR([preprocessor/DynareMain.cc]) AC_CONFIG_SRCDIR([preprocessor/DynareMain.cc])
AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax]) AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax])
@ -172,6 +172,7 @@ esac
AX_PTHREAD AX_PTHREAD
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
VERSION
preprocessor/macro/Makefile preprocessor/macro/Makefile
preprocessor/Makefile preprocessor/Makefile
doc/Makefile doc/Makefile

View File

@ -12,7 +12,7 @@
\begin{document} \begin{document}
\title{BVAR models ``\`a la Sims'' in Dynare\thanks{Copyright \copyright~2007--2015 S\'ebastien \title{BVAR models ``\`a la Sims'' in Dynare\thanks{Copyright \copyright~2007--2015 S\'ebastien
Villemot; \copyright~2016 S\'ebastien Villemot; \copyright~2016--2017 S\'ebastien
Villemot and Johannes Pfeifer. Permission is granted to copy, distribute and/or modify Villemot and Johannes Pfeifer. Permission is granted to copy, distribute and/or modify
this document under the terms of the GNU Free Documentation this document under the terms of the GNU Free Documentation
License, Version 1.3 or any later version published by the Free License, Version 1.3 or any later version published by the Free
@ -26,8 +26,8 @@
}} }}
\author{S\'ebastien Villemot\thanks{Paris School of Economics and \author{S\'ebastien Villemot\thanks{Paris School of Economics and
CEPREMAP.} \and Johannes Pfeifer\thanks{University of Mannheim. E-mail: \href{mailto:pfeifer@uni-mannheim.de}{\texttt{pfeifer@uni-mannheim.de}}.}} CEPREMAP.} \and Johannes Pfeifer\thanks{University of Cologne. E-mail: \href{mailto:jpfeifer@uni-koeln.de}{\texttt{jpfeifer@uni-koeln.de}}.}}
\date{First version: September 2007 \hspace{1cm} This version: October 2016} \date{First version: September 2007 \hspace{1cm} This version: May 2017}
\maketitle \maketitle
@ -545,7 +545,7 @@ Most results are stored for future use:
The syntax for computing impulse response functions is: The syntax for computing impulse response functions is:
\medskip \medskip
\texttt{bvar\_irf(}\textit{number\_of\_periods},\textit{identification\_scheme}\texttt{);} \texttt{bvar\_irf(}\textit{number\_of\_lags},\textit{identification\_scheme}\texttt{);}
\medskip \medskip
The \textit{identification\_scheme} option has two potential values The \textit{identification\_scheme} option has two potential values
@ -556,7 +556,25 @@ The \textit{identification\_scheme} option has two potential values
Keep in mind that the first factorization of the covariance matrix is sensible to the ordering of the variables (as declared in the mod file with \verb+var+). This is not the case of the second factorization, but its structural interpretation is, at best, unclear (the Matrix square root of a covariance matrix, $\Sigma$, is the unique symmetric matrix $A$ such that $\Sigma = AA$).\newline Keep in mind that the first factorization of the covariance matrix is sensible to the ordering of the variables (as declared in the mod file with \verb+var+). This is not the case of the second factorization, but its structural interpretation is, at best, unclear (the Matrix square root of a covariance matrix, $\Sigma$, is the unique symmetric matrix $A$ such that $\Sigma = AA$).\newline
The mean, median, variance and confidence intervals for IRFs are saved in \texttt{oo\_.bvar.irf} If you want to change the length of the IRFs plotted by the command, you can put\\
\medskip
\texttt{options\_.irf=40;}\\
\medskip
before the \texttt{bvar\_irf}-command. Similarly, to change the coverage of the highest posterior density intervals to e.g. 60\% you can put the command\\
\medskip
\texttt{options\_.bvar.conf\_sig=0.6;}\\
\medskip
there.\newline
The mean, median, variance, and confidence intervals for IRFs are saved in \texttt{oo\_.bvar.irf}
\section{Examples} \section{Examples}

File diff suppressed because it is too large Load Diff

View File

@ -101,7 +101,11 @@ void SystemResources::getRUS(double& load_avg, long int& pg_avail,
majflt = -1; majflt = -1;
#endif #endif
#if !defined(__MINGW32__) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) && !defined(__MINGW64__) && !defined(__CYGWIN64__)
#define MINGCYGTMP (!defined(__MINGW32__) && !defined(__CYGWIN32__) && !defined(__CYGWIN__))
#define MINGCYG (MINGCYGTMP && !defined(__MINGW64__) && !defined(__CYGWIN64__))
#if MINGCYG
getloadavg(&load_avg, 1); getloadavg(&load_avg, 1);
#else #else
load_avg = -1.0; load_avg = -1.0;

View File

@ -12,114 +12,126 @@
#include <vector> #include <vector>
#include <map> #include <map>
namespace ogp { namespace ogp
{
class AtomAsgnEvaluator; class AtomAsgnEvaluator;
/** This class represents atom assignments used in parameters /** This class represents atom assignments used in parameters
* settings and initval initialization. It maintains atoms of the * settings and initval initialization. It maintains atoms of the
* all expressions on the right hand side, the parsed formulas of * all expressions on the right hand side, the parsed formulas of
* the right hand sides, and the information about the left hand * the right hand sides, and the information about the left hand
* sides. See documentation to the order member below. */ * sides. See documentation to the order member below. */
class AtomAssignings { class AtomAssignings
friend class AtomAsgnEvaluator; {
protected: friend class AtomAsgnEvaluator;
typedef std::map<const char*, int, ltstr> Tvarintmap; protected:
/** All atoms which should be sufficient for formulas at the typedef std::map<const char *, int, ltstr> Tvarintmap;
* right hand sides. The atoms should be filled with names /** All atoms which should be sufficient for formulas at the
* (preregistered). This is a responsibility of the caller. */ * right hand sides. The atoms should be filled with names
StaticAtoms& atoms; * (preregistered). This is a responsibility of the caller. */
/** The formulas of right hand sides. */ StaticAtoms &atoms;
FormulaParser expr; /** The formulas of right hand sides. */
/** Name storage of the names from left hand sides. */ FormulaParser expr;
NameStorage left_names; /** Name storage of the names from left hand sides. */
/** Information on left hand sides. This maps a name to the NameStorage left_names;
* index of its assigned expression in expr. More than one /** Information on left hand sides. This maps a name to the
* name may reference to the same expression. */ * index of its assigned expression in expr. More than one
Tvarintmap lname2expr; * name may reference to the same expression. */
/** Information on left hand sides. If order[i] >= 0, then it Tvarintmap lname2expr;
* says that i-th expression in expr is assigned to atom with /** Information on left hand sides. If order[i] >= 0, then it
* order[i] tree index. */ * says that i-th expression in expr is assigned to atom with
std::vector<int> order; * order[i] tree index. */
public: std::vector<int> order;
/** Construct the object using the provided static atoms. */ public:
AtomAssignings(StaticAtoms& a) : atoms(a), expr(atoms) /** Construct the object using the provided static atoms. */
{} AtomAssignings(StaticAtoms &a) : atoms(a), expr(atoms)
/** Make a copy with provided reference to (posibly different) {
* static atoms. */ }
AtomAssignings(const AtomAssignings& aa, StaticAtoms& a); /** Make a copy with provided reference to (posibly different)
virtual ~AtomAssignings() * static atoms. */
{} AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
/** Parse the assignments from the given string. */ virtual ~AtomAssignings()
void parse(int length, const char* stream); {
/** Process a syntax error from bison. */ }
void error(const char* mes); /** Parse the assignments from the given string. */
/** Add an assignment of the given name to the given void parse(int length, const char *stream);
* double. Can be called by a user, anytime. */ /** Process a syntax error from bison. */
void add_assignment_to_double(const char* name, double val); void error(const char *mes);
/** Add an assignment. Called from assign.y. */ /** Add an assignment of the given name to the given
void add_assignment(int asgn_off, const char* str, int name_len, * double. Can be called by a user, anytime. */
int right_off, int right_len); void add_assignment_to_double(const char *name, double val);
/** This applies old2new map (possibly from atom /** Add an assignment. Called from assign.y. */
* substitutions) to this object. It registers new variables void add_assignment(int asgn_off, const char *str, int name_len,
* in the atoms, and adds the expressions to expr, and left int right_off, int right_len);
* names to lname2expr. The information about dynamical part /** This applies old2new map (possibly from atom
* of substitutions is ignored, since we are now in the static * substitutions) to this object. It registers new variables
* world. */ * in the atoms, and adds the expressions to expr, and left
void apply_subst(const AtomSubstitutions::Toldnamemap& mm); * names to lname2expr. The information about dynamical part
/** Debug print. */ * of substitutions is ignored, since we are now in the static
void print() const; * world. */
}; void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
/** Debug print. */
void print() const;
};
/** This class basically evaluates the atom assignments /** This class basically evaluates the atom assignments
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It * AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
* is also a storage for the results of the evaluation stored as a * is also a storage for the results of the evaluation stored as a
* vector, so the class inherits from std::vector<double> and * vector, so the class inherits from std::vector<double> and
* ogp::FormulaEvalLoader. As the expressions for atoms are * ogp::FormulaEvalLoader. As the expressions for atoms are
* evaluated, the results are values for atoms which will be * evaluated, the results are values for atoms which will be
* used in subsequent evaluations. For this reason, the class * used in subsequent evaluations. For this reason, the class
* inherits also from AtomValues. */ * inherits also from AtomValues. */
class AtomAsgnEvaluator : public FormulaEvalLoader, class AtomAsgnEvaluator : public FormulaEvalLoader,
public AtomValues, public AtomValues,
protected FormulaEvaluator, protected FormulaEvaluator,
public std::vector<double> { public std::vector<double>
protected: {
typedef std::map<int, double> Tusrvalmap; protected:
Tusrvalmap user_values; typedef std::map<int, double> Tusrvalmap;
const AtomAssignings& aa; Tusrvalmap user_values;
public: const AtomAssignings &aa;
AtomAsgnEvaluator(const AtomAssignings& a) public:
: FormulaEvaluator(a.expr), AtomAsgnEvaluator(const AtomAssignings &a)
std::vector<double>(a.expr.nformulas()), aa(a) {} : FormulaEvaluator(a.expr),
virtual ~AtomAsgnEvaluator() {} std::vector<double>(a.expr.nformulas()), aa(a)
/** This sets all initial values to NaNs, all constants and {
* all values set by user by call set_value. This is called by }
* FormulaEvaluator::eval() method, which is called by eval() virtual ~AtomAsgnEvaluator()
* method passing this argument as AtomValues. So the {
* ogp::EvalTree will be always this->etree. */ }
void setValues(EvalTree& et) const; /** This sets all initial values to NaNs, all constants and
/** User setting of the values. For example in initval, * all values set by user by call set_value. This is called by
* parameters are known and should be set to their values. In * FormulaEvaluator::eval() method, which is called by eval()
* constrast endogenous variables are set initially to NaNs by * method passing this argument as AtomValues. So the
* AtomValues::setValues. */ * ogp::EvalTree will be always this->etree. */
void set_user_value(const char* name, double val); void setValues(EvalTree &et) const;
/** This sets the result of i-th expression in aa to res, and /** User setting of the values. For example in initval,
* also checks whether the i-th expression is an atom. If so, * parameters are known and should be set to their values. In
* it sets the value of the atom in ogp::EvalTree * constrast endogenous variables are set initially to NaNs by
* this->etree. */ * AtomValues::setValues. */
void load(int i, double res); void set_user_value(const char *name, double val);
/** After the user values have been set, the assignments can /** This sets the result of i-th expression in aa to res, and
* be evaluated. For this purpose we have eval() method. The * also checks whether the i-th expression is an atom. If so,
* result is that this object as std::vector<double> will * it sets the value of the atom in ogp::EvalTree
* contain the values. It is ordered given by formulas in * this->etree. */
* expr. */ void load(int i, double res);
void eval() /** After the user values have been set, the assignments can
{FormulaEvaluator::eval(*this, *this);} * be evaluated. For this purpose we have eval() method. The
/** This returns a value for a given name. If the name is not * result is that this object as std::vector<double> will
* found among atoms, or there is no assignment for the atom, * contain the values. It is ordered given by formulas in
* NaN is returned. */ * expr. */
double get_value(const char* name) const; void
}; eval()
{
FormulaEvaluator::eval(*this, *this);
}
/** This returns a value for a given name. If the name is not
* found among atoms, or there is no assignment for the atom,
* NaN is returned. */
double get_value(const char *name) const;
};
}; };

View File

@ -9,148 +9,185 @@
#include <string> #include <string>
namespace ogp { namespace ogp
{
using std::string; using std::string;
using std::map; using std::map;
using std::pair; using std::pair;
/** This class tracts an information about the performed /** This class tracts an information about the performed
* substitutions. In fact, there is only one number to keep track * substitutions. In fact, there is only one number to keep track
* about, this is a number of substitutions. */ * about, this is a number of substitutions. */
struct SubstInfo { struct SubstInfo
int num_substs; {
SubstInfo() : num_substs(0) {} int num_substs;
}; SubstInfo() : num_substs(0)
{
}
};
/** This class tracks all atom substitutions during the job and /** This class tracks all atom substitutions during the job and
* then builds structures when all substitutions are finished. */ * then builds structures when all substitutions are finished. */
class AtomSubstitutions { class AtomSubstitutions
public: {
typedef pair<const char*, int> Tshiftname; public:
typedef map<const char*, Tshiftname, ltstr> Tshiftmap; typedef pair<const char *, int> Tshiftname;
typedef set<Tshiftname> Tshiftnameset; typedef map<const char *, Tshiftname, ltstr> Tshiftmap;
typedef map<const char*, Tshiftnameset, ltstr> Toldnamemap; typedef set<Tshiftname> Tshiftnameset;
protected: typedef map<const char *, Tshiftnameset, ltstr> Toldnamemap;
/** This maps a new name to a shifted old name. This is, one protected:
* entry looks as "a_m3 ==> a(-3)", saying that a variable /** This maps a new name to a shifted old name. This is, one
* "a_m3" corresponds to a variable "a" lagged by 3. */ * entry looks as "a_m3 ==> a(-3)", saying that a variable
Tshiftmap new2old; * "a_m3" corresponds to a variable "a" lagged by 3. */
/** This is inverse to new2old, which is not unique. For old Tshiftmap new2old;
* name, say "a", it says what new names are derived with what /** This is inverse to new2old, which is not unique. For old
* shifts from the "a". For example, it can map "a" to a two * name, say "a", it says what new names are derived with what
* element set {["a_m3", +3], ["a_p2", -2]}. This says that * shifts from the "a". For example, it can map "a" to a two
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by * element set {["a_m3", +3], ["a_p2", -2]}. This says that
* 2 one gets also old "a". */ * leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
Toldnamemap old2new; * 2 one gets also old "a". */
/** This is a reference to old atoms with multiple leads and Toldnamemap old2new;
* lags. They are supposed to be used with parsing finished /** This is a reference to old atoms with multiple leads and
* being had called, so that the external ordering is * lags. They are supposed to be used with parsing finished
* available. */ * being had called, so that the external ordering is
const FineAtoms& old_atoms; * available. */
/** This is a reference to new atoms. All name pointers point const FineAtoms &old_atoms;
* to storage of these atoms. */ /** This is a reference to new atoms. All name pointers point
FineAtoms& new_atoms; * to storage of these atoms. */
/** Substitutions information. */ FineAtoms &new_atoms;
SubstInfo info; /** Substitutions information. */
public: SubstInfo info;
/** Create the object with reference to the old and new public:
* atoms. In the beginning, old atoms are supposed to be with /** Create the object with reference to the old and new
* parsing_finished() called, and new atoms a simple copy of * atoms. In the beginning, old atoms are supposed to be with
* old atoms. The new atoms will be an instance of SAtoms. All * parsing_finished() called, and new atoms a simple copy of
* substitution job is done by a substitution method of the * old atoms. The new atoms will be an instance of SAtoms. All
* new atoms. */ * substitution job is done by a substitution method of the
AtomSubstitutions(const FineAtoms& oa, FineAtoms& na) * new atoms. */
: old_atoms(oa), new_atoms(na) {} AtomSubstitutions(const FineAtoms &oa, FineAtoms &na)
/** Construct a copy of the object using a different instances : old_atoms(oa), new_atoms(na)
* of old atoms and new atoms, which are supposed to be {
* semantically same as the atoms from as. */ }
AtomSubstitutions(const AtomSubstitutions& as, const FineAtoms& oa, FineAtoms& na); /** Construct a copy of the object using a different instances
virtual ~AtomSubstitutions() {} * of old atoms and new atoms, which are supposed to be
/** This is called during the substitution job from the * semantically same as the atoms from as. */
* substitution method of the new atoms. This says that the AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na);
* new name, say "a_m3" is a substitution of old name "a" virtual ~AtomSubstitutions()
* shifted by -3. */ {
void add_substitution(const char* newname, const char* oldname, int tshift); }
/** This is called when all substitutions are finished. This /** This is called during the substitution job from the
* forms the new external ordering of the new atoms and calls * substitution method of the new atoms. This says that the
* parsing_finished() for the new atoms with the given ordering type. */ * new name, say "a_m3" is a substitution of old name "a"
void substitutions_finished(VarOrdering::ord_type ot); * shifted by -3. */
/** Returns a new name for old name and given tshift. For "a" void add_substitution(const char *newname, const char *oldname, int tshift);
* and tshift=-3, it returns "a_m3". If there is no such /** This is called when all substitutions are finished. This
* substitution, it returns NULL. */ * forms the new external ordering of the new atoms and calls
const char* get_new4old(const char* oldname, int tshift) const; * parsing_finished() for the new atoms with the given ordering type. */
/** Return new2old. */ void substitutions_finished(VarOrdering::ord_type ot);
const Tshiftmap& get_new2old() const /** Returns a new name for old name and given tshift. For "a"
{return new2old;} * and tshift=-3, it returns "a_m3". If there is no such
/** Return old2new. */ * substitution, it returns NULL. */
const Toldnamemap& get_old2new() const const char *get_new4old(const char *oldname, int tshift) const;
{return old2new;} /** Return new2old. */
/** Return substitution info. */ const Tshiftmap &
const SubstInfo& get_info() const get_new2old() const
{return info;} {
/** Return old atoms. */ return new2old;
const FineAtoms& get_old_atoms() const }
{return old_atoms;} /** Return old2new. */
/** Return new atoms. */ const Toldnamemap &
const FineAtoms& get_new_atoms() const get_old2new() const
{return new_atoms;} {
/** Debug print. */ return old2new;
void print() const; }
}; /** Return substitution info. */
const SubstInfo &
get_info() const
{
return info;
}
/** Return old atoms. */
const FineAtoms &
get_old_atoms() const
{
return old_atoms;
}
/** Return new atoms. */
const FineAtoms &
get_new_atoms() const
{
return new_atoms;
}
/** Debug print. */
void print() const;
};
class SAtoms : public FineAtoms { class SAtoms : public FineAtoms
public: {
SAtoms() public:
: FineAtoms() {} SAtoms()
SAtoms(const SAtoms& sa) : FineAtoms()
: FineAtoms(sa) {} {
virtual ~SAtoms() {} }
/** This substitutes all lags and leads for all exogenous and SAtoms(const SAtoms &sa)
* all lags and leads greater than 1 for all endogenous : FineAtoms(sa)
* variables. This is useful for perfect foresight problems {
* where we can do that. */ }
void substituteAllLagsAndLeads(FormulaParser& fp, AtomSubstitutions& as); virtual ~SAtoms()
/** This substitutes all lags of all endo and exo and one step {
* leads of all exo variables. This is useful for stochastic }
* models where we cannot solve leads more than 1. */ /** This substitutes all lags and leads for all exogenous and
void substituteAllLagsAndExo1Leads(FormulaParser& fp, AtomSubstitutions& as); * all lags and leads greater than 1 for all endogenous
protected: * variables. This is useful for perfect foresight problems
/** This finds an endogenous variable name which occurs between * where we can do that. */
* ll1 and ll2 included. */ void substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as);
const char* findEndoWithLeadInInterval(int ll1, int ll2) const /** This substitutes all lags of all endo and exo and one step
{return findNameWithLeadInInterval(get_endovars(), ll1, ll2);} * leads of all exo variables. This is useful for stochastic
/** This finds an exogenous variable name which occurs between * models where we cannot solve leads more than 1. */
* ll1 and ll2 included. */ void substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as);
const char* findExoWithLeadInInterval(int ll1, int ll2) const protected:
{return findNameWithLeadInInterval(get_exovars(), ll1, ll2);} /** This finds an endogenous variable name which occurs between
* ll1 and ll2 included. */
const char *
findEndoWithLeadInInterval(int ll1, int ll2) const
{
return findNameWithLeadInInterval(get_endovars(), ll1, ll2);
}
/** This finds an exogenous variable name which occurs between
* ll1 and ll2 included. */
const char *
findExoWithLeadInInterval(int ll1, int ll2) const
{
return findNameWithLeadInInterval(get_exovars(), ll1, ll2);
}
/** This attempts to find a non registered name of the form /** This attempts to find a non registered name of the form
* <str>_m<abs(ll)> or <str>_p<abs(ll)>. A letter 'p' is * <str>_m<abs(ll)> or <str>_p<abs(ll)>. A letter 'p' is
* chosen if ll is positive, 'm' if negative. If a name of * chosen if ll is positive, 'm' if negative. If a name of
* such form is already registered, one more character (either * such form is already registered, one more character (either
* 'p' or 'm') is added and the test is performed again. The * 'p' or 'm') is added and the test is performed again. The
* resulting name is returned in a string out. */ * resulting name is returned in a string out. */
void attemptAuxName(const char* str, int ll, string& out) const; void attemptAuxName(const char *str, int ll, string &out) const;
/** This makes auxiliary variables to eliminate all leads/lags /** This makes auxiliary variables to eliminate all leads/lags
* greater/less than or equal to start up to the limit_lead * greater/less than or equal to start up to the limit_lead
* for a variable with the given name. If the limit_lead is * for a variable with the given name. If the limit_lead is
* greater/less than the maxlead/minlag of the variable, than * greater/less than the maxlead/minlag of the variable, than
* maxlead/minlag is used. This process is recorded in * maxlead/minlag is used. This process is recorded in
* AtomSubstitutions. The new auxiliary variables and their * AtomSubstitutions. The new auxiliary variables and their
* atoms are created in this object. The auxiliary equations * atoms are created in this object. The auxiliary equations
* are created in the given FormulaParser. The value of step * are created in the given FormulaParser. The value of step
* is allowed to be either -1 (lags) or +1 (leads). */ * is allowed to be either -1 (lags) or +1 (leads). */
void makeAuxVariables(const char* name, int step, int start, int limit_lead, void makeAuxVariables(const char *name, int step, int start, int limit_lead,
FormulaParser& fp, AtomSubstitutions& as); FormulaParser &fp, AtomSubstitutions &as);
private: private:
/** This is a worker routine for findEndoWithLeadInInterval /** This is a worker routine for findEndoWithLeadInInterval
* and findExoWithLeadInInterval. */ * and findExoWithLeadInInterval. */
const char* findNameWithLeadInInterval(const vector<const char*>& names, const char *findNameWithLeadInInterval(const vector<const char *> &names,
int ll1, int ll2) const; int ll1, int ll2) const;
}; };
}; };

View File

@ -5,38 +5,58 @@
#ifndef OGP_CSV_PARSER #ifndef OGP_CSV_PARSER
#define OGP_CSV_PARSER #define OGP_CSV_PARSER
namespace ogp { namespace ogp
{
class CSVParserPeer { class CSVParserPeer
public: {
virtual ~CSVParserPeer() {} public:
virtual void item(int irow, int icol, const char* str, int length) = 0; virtual ~CSVParserPeer()
}; {
}
virtual void item(int irow, int icol, const char *str, int length) = 0;
};
class CSVParser { class CSVParser
private: {
CSVParserPeer& peer; private:
int row; CSVParserPeer &peer;
int col; int row;
const char* parsed_string; int col;
public: const char *parsed_string;
CSVParser(CSVParserPeer& p) public:
: peer(p), row(0), col(0), parsed_string(0) {} CSVParser(CSVParserPeer &p)
CSVParser(const CSVParser& csvp) : peer(p), row(0), col(0), parsed_string(0)
: peer(csvp.peer), row(csvp.row), {
col(csvp.col), parsed_string(csvp.parsed_string) {} }
virtual ~CSVParser() {} CSVParser(const CSVParser &csvp)
: peer(csvp.peer), row(csvp.row),
col(csvp.col), parsed_string(csvp.parsed_string)
{
}
virtual ~CSVParser()
{
}
void csv_error(const char* mes); void csv_error(const char *mes);
void csv_parse(int length, const char* str); void csv_parse(int length, const char *str);
void nextrow() void
{row++; col = 0;} nextrow()
void nextcol() {
{col++;} row++; col = 0;
void item(int off, int length) }
{peer.item(row, col, parsed_string+off, length);} void
}; nextcol()
{
col++;
}
void
item(int off, int length)
{
peer.item(row, col, parsed_string+off, length);
}
};
}; };
#endif #endif

View File

@ -13,389 +13,462 @@
#include <string> #include <string>
#include <cstring> #include <cstring>
namespace ogp { namespace ogp
using std::vector; {
using std::map; using std::vector;
using std::set; using std::map;
using std::string; using std::set;
using std::string;
struct ltstr { struct ltstr
bool operator()(const char* a1, const char* a2) const {
{ return strcmp(a1, a2) < 0; } bool
}; operator()(const char *a1, const char *a2) const
{
return strcmp(a1, a2) < 0;
}
};
/** Class storing names. We will keep names of variables in /** Class storing names. We will keep names of variables in
* various places, and all these pointers will point to one * various places, and all these pointers will point to one
* storage, which will be responsible for allocation and * storage, which will be responsible for allocation and
* deallocation. The main function of the class is to allocate * deallocation. The main function of the class is to allocate
* space for names, and return a pointer of the stored name if * space for names, and return a pointer of the stored name if
* required. */ * required. */
class NameStorage { class NameStorage
protected: {
/** Vector of names allocated, this is the storage. */ protected:
vector<char*> name_store; /** Vector of names allocated, this is the storage. */
/** Map useful to quickly decide if the name is already vector<char *> name_store;
* allocated or not. */ /** Map useful to quickly decide if the name is already
set<const char*, ltstr> name_set; * allocated or not. */
public: set<const char *, ltstr> name_set;
NameStorage() {} public:
NameStorage(const NameStorage& stor); NameStorage()
virtual ~NameStorage(); {
/** Query for the name. If the name has been stored, it }
* returns its address, otherwise 0. */ NameStorage(const NameStorage &stor);
const char* query(const char* name) const; virtual
/** Insert the name if it has not been inserted yet, and ~NameStorage();
* return its new or old allocation. */ /** Query for the name. If the name has been stored, it
const char* insert(const char* name); * returns its address, otherwise 0. */
int num() const const char *query(const char *name) const;
{return (int)name_store.size();} /** Insert the name if it has not been inserted yet, and
const char* get_name(int i) const * return its new or old allocation. */
{return name_store[i];} const char *insert(const char *name);
/** Debug print. */ int
void print() const; num() const
}; {
return (int) name_store.size();
}
const char *
get_name(int i) const
{
return name_store[i];
}
/** Debug print. */
void print() const;
};
class Constants : public AtomValues { class Constants : public AtomValues
public: {
/** Type for a map mapping tree indices to double values. */ public:
typedef map<int,double> Tconstantmap; /** Type for a map mapping tree indices to double values. */
typedef map<int,int> Tintintmap; typedef map<int, double> Tconstantmap;
protected: typedef map<int, int> Tintintmap;
/** Map mapping a tree index of a constant to its double value. */ protected:
Tconstantmap cmap; /** Map mapping a tree index of a constant to its double value. */
public: Tconstantmap cmap;
Constants() {} public:
/** Copy constructor. */ Constants()
Constants(const Constants& c) {
: cmap(c.cmap), cinvmap(c.cinvmap) {} }
/** Copy constructor registering the constants in the given /** Copy constructor. */
* tree. The mapping from old tree indices to new ones is Constants(const Constants &c)
* traced in tmap. */ : cmap(c.cmap), cinvmap(c.cinvmap)
Constants(const Constants& c, OperationTree& otree, Tintintmap& tmap) {
{import_constants(c, otree, tmap);} }
/** Import constants registering their tree indices in the /** Copy constructor registering the constants in the given
* given tree. The mapping form old tree indices to new ones * tree. The mapping from old tree indices to new ones is
* is traced in tmap. */ * traced in tmap. */
void import_constants(const Constants& c, OperationTree& otree, Tintintmap& tmap); Constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
/** Implements AtomValues interface. This sets the values to {
* the evaluation tree EvalTree. */ import_constants(c, otree, tmap);
void setValues(EvalTree& et) const; }
/** This adds a constant with the given tree index. The /** Import constants registering their tree indices in the
* constant must be checked previously and asserted that it * given tree. The mapping form old tree indices to new ones
* does not exist. */ * is traced in tmap. */
void add_constant(int t, double val); void import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap);
/** Returns true if the tree index is either an hardwired /** Implements AtomValues interface. This sets the values to
* constant (initial number OperationTree:num_constants in * the evaluation tree EvalTree. */
* OperationTree) or the tree index is a registered constant void setValues(EvalTree &et) const;
* by add_constant method. */ /** This adds a constant with the given tree index. The
bool is_constant(int t) const; * constant must be checked previously and asserted that it
double get_constant_value(int t) const; * does not exist. */
/** Return -1 if the given string representation of a constant void add_constant(int t, double val);
* is not among the constants (double represenations). If it /** Returns true if the tree index is either an hardwired
* is, its tree index is returned. */ * constant (initial number OperationTree:num_constants in
int check(const char* str) const; * OperationTree) or the tree index is a registered constant
/** Debug print. */ * by add_constant method. */
void print() const; bool is_constant(int t) const;
const Tconstantmap& get_constantmap() const double get_constant_value(int t) const;
{return cmap;} /** Return -1 if the given string representation of a constant
private: * is not among the constants (double represenations). If it
/** Inverse map to Tconstantmap. */ * is, its tree index is returned. */
typedef map<double,int> Tconstantinvmap; int check(const char *str) const;
/** This is an inverse map to cmap. This is only used for fast /** Debug print. */
* queries for the existing double constants in check void print() const;
* method and add_constant. */ const Tconstantmap &
Tconstantinvmap cinvmap; get_constantmap() const
}; {
return cmap;
}
private:
/** Inverse map to Tconstantmap. */
typedef map<double, int> Tconstantinvmap;
/** This is an inverse map to cmap. This is only used for fast
* queries for the existing double constants in check
* method and add_constant. */
Tconstantinvmap cinvmap;
};
/** This class is a parent to Atoms classes which distinguish between /** This class is a parent to Atoms classes which distinguish between
* constants (numerical literals), and variables with lags and * constants (numerical literals), and variables with lags and
* leads. This abstraction does not distinguish between a parameter * leads. This abstraction does not distinguish between a parameter
* and a variable without lag or lead. In this sense, everything is a * and a variable without lag or lead. In this sense, everything is a
* variable.*/ * variable.*/
class DynamicAtoms : public Atoms, public Constants { class DynamicAtoms : public Atoms, public Constants
public: {
/** Definition of a type mapping lags to the indices of the variables. */ public:
typedef map<int,int> Tlagmap; /** Definition of a type mapping lags to the indices of the variables. */
protected: typedef map<int, int> Tlagmap;
/** Definition of a type mapping names of the atoms to Tlagmap. */ protected:
typedef map<const char*, Tlagmap, ltstr> Tvarmap; /** Definition of a type mapping names of the atoms to Tlagmap. */
/** Definition of a type mapping indices of variables to the variable names. */ typedef map<const char *, Tlagmap, ltstr> Tvarmap;
typedef map<int, const char*> Tindexmap; /** Definition of a type mapping indices of variables to the variable names. */
/** This is just a storage for variable names, since all other typedef map<int, const char *> Tindexmap;
* instances of a variable name just point to the memory /** This is just a storage for variable names, since all other
* allocated by this object. */ * instances of a variable name just point to the memory
NameStorage varnames; * allocated by this object. */
/** This is the map for variables. Each variable name is NameStorage varnames;
* mapped to the Tlagmap, which maps lags/leads to the nulary /** This is the map for variables. Each variable name is
* term indices in the tree. */ * mapped to the Tlagmap, which maps lags/leads to the nulary
Tvarmap vars; * term indices in the tree. */
/** This is almost inverse map to the vars. It maps variable Tvarmap vars;
* indices to the names. A returned name can be in turn used /** This is almost inverse map to the vars. It maps variable
* as a key in vars. */ * indices to the names. A returned name can be in turn used
Tindexmap indices; * as a key in vars. */
Tindexmap indices;
/** Number of variables. */ /** Number of variables. */
int nv; int nv;
/** Minimum lag, if there is at least one lag, than this is a negative number. */ /** Minimum lag, if there is at least one lag, than this is a negative number. */
int minlag; int minlag;
/** Maximum lead, if there is at least one lead, than this is a positive number. */ /** Maximum lead, if there is at least one lead, than this is a positive number. */
int maxlead; int maxlead;
public: public:
/** Construct empty DynamicAtoms. */ /** Construct empty DynamicAtoms. */
DynamicAtoms(); DynamicAtoms();
DynamicAtoms(const DynamicAtoms& da); DynamicAtoms(const DynamicAtoms &da);
virtual ~DynamicAtoms() {} virtual ~DynamicAtoms()
/** Check the nulary term identified by its string {
* representation. The nulary term can be either a constant or }
* a variable. If constant, -1 is returned so that it could be /** Check the nulary term identified by its string
* assigned regardless if the same constant has already * representation. The nulary term can be either a constant or
* appeared or not. If variable, then -1 is returned only if * a variable. If constant, -1 is returned so that it could be
* the variable has not been assigned an index, otherwise the * assigned regardless if the same constant has already
* assigned index is returned. */ * appeared or not. If variable, then -1 is returned only if
int check(const char* name) const; * the variable has not been assigned an index, otherwise the
/** Assign the nulary term identified by its string * assigned index is returned. */
* representation. This method should be called when check() int check(const char *name) const;
* returns -1. */ /** Assign the nulary term identified by its string
void assign(const char* name, int t); * representation. This method should be called when check()
/** Return a number of all variables. */ * returns -1. */
int nvar() const void assign(const char *name, int t);
{ return nv; } /** Return a number of all variables. */
/** Return the vector of variable indices. */ int
vector<int> variables() const; nvar() const
/** Return max lead and min lag for a variable given by the {
* index. If a variable cannot be found, the method retursn return nv;
* the smallest integer as maxlead and the largest integer as }
* minlag. */ /** Return the vector of variable indices. */
void varspan(int t, int& mlead, int& mlag) const; vector<int> variables() const;
/** Return max lead and min lag for a variable given by the /** Return max lead and min lag for a variable given by the
* name (without lead, lag). The same is valid if the variable * index. If a variable cannot be found, the method retursn
* name cannot be found. */ * the smallest integer as maxlead and the largest integer as
void varspan(const char* name, int& mlead, int& mlag) const; * minlag. */
/** Return max lead and min lag for a vector of variables given by the names. */ void varspan(int t, int &mlead, int &mlag) const;
void varspan(const vector<const char*>& names, int& mlead, int& mlag) const; /** Return max lead and min lag for a variable given by the
/** Return true for all tree indices corresponding to a * name (without lead, lag). The same is valid if the variable
* variable in the sense of this class. (This is parameters, * name cannot be found. */
* exo and endo). Since the semantics of 'variable' will be void varspan(const char *name, int &mlead, int &mlag) const;
* changed in subclasses, we use name 'named atom'. These are /** Return max lead and min lag for a vector of variables given by the names. */
* all atoms but constants. */ void varspan(const vector<const char *> &names, int &mlead, int &mlag) const;
bool is_named_atom(int t) const; /** Return true for all tree indices corresponding to a
/** Return index of the variable described by the variable * variable in the sense of this class. (This is parameters,
* name and lag/lead. If it doesn't exist, return -1. */ * exo and endo). Since the semantics of 'variable' will be
int index(const char* name, int ll) const; * changed in subclasses, we use name 'named atom'. These are
/** Return true if a variable is referenced, i.e. it has lag * all atoms but constants. */
* map. */ bool is_named_atom(int t) const;
bool is_referenced(const char* name) const; /** Return index of the variable described by the variable
/** Return the lag map for the variable name. */ * name and lag/lead. If it doesn't exist, return -1. */
const Tlagmap& lagmap(const char* name) const; int index(const char *name, int ll) const;
/** Return the variable name for the tree index. It throws an /** Return true if a variable is referenced, i.e. it has lag
* exception if the tree index t is not a named atom. */ * map. */
const char* name(int t) const; bool is_referenced(const char *name) const;
/** Return the lead/lag for the tree index. It throws an /** Return the lag map for the variable name. */
* exception if the tree index t is not a named atom. */ const Tlagmap&lagmap(const char *name) const;
int lead(int t) const; /** Return the variable name for the tree index. It throws an
/** Return maximum lead. */ * exception if the tree index t is not a named atom. */
int get_maxlead() const const char *name(int t) const;
{return maxlead;} /** Return the lead/lag for the tree index. It throws an
/** Return minimum lag. */ * exception if the tree index t is not a named atom. */
int get_minlag() const int lead(int t) const;
{return minlag;} /** Return maximum lead. */
/** Return the name storage to allow querying to other int
* classes. */ get_maxlead() const
const NameStorage& get_name_storage() const {
{return varnames;} return maxlead;
/** Assign the variable with a given lead. The varname must be }
* from the varnames storage. The method checks if the /** Return minimum lag. */
* variable iwht the given lead/lag is not assigned. If so, an int
* exception is thrown. */ get_minlag() const
void assign_variable(const char* varname, int ll, int t); {
/** Unassign the variable with a given lead and given tree return minlag;
* index. The tree index is only provided as a check. An }
* exception is thrown if the name, ll, and the tree index t /** Return the name storage to allow querying to other
* are not consistent. The method also updates nv, indices, * classes. */
* maxlead and minlag. The varname must be from the varnames const NameStorage &
* storage. */ get_name_storage() const
void unassign_variable(const char* varname, int ll, int t); {
/** Debug print. */ return varnames;
void print() const; }
protected: /** Assign the variable with a given lead. The varname must be
/** Do the check for the variable. A subclass may need to * from the varnames storage. The method checks if the
* reimplement this so that it could raise an error if the * variable iwht the given lead/lag is not assigned. If so, an
* variable is not among a given list. */ * exception is thrown. */
virtual int check_variable(const char* name) const; void assign_variable(const char *varname, int ll, int t);
/** Assign the constant. */ /** Unassign the variable with a given lead and given tree
void assign_constant(const char* name, int t); * index. The tree index is only provided as a check. An
/** Assign the variable. */ * exception is thrown if the name, ll, and the tree index t
void assign_variable(const char* name, int t); * are not consistent. The method also updates nv, indices,
/** The method just updates minlag or/and maxlead. Note that * maxlead and minlag. The varname must be from the varnames
* when assigning variables, the update is done when inserting * storage. */
* to the maps, however, if removing a variable, we need to void unassign_variable(const char *varname, int ll, int t);
* call this method. */ /** Debug print. */
void update_minmaxll(); void print() const;
/** The method parses the string to recover a variable name protected:
* and lag/lead ll. The variable name doesn't contain a lead/lag. */ /** Do the check for the variable. A subclass may need to
virtual void parse_variable(const char* in, string& out, int& ll) const = 0; * reimplement this so that it could raise an error if the
public: * variable is not among a given list. */
/** Return true if the str represents a double.*/ virtual int check_variable(const char *name) const;
static bool is_string_constant(const char* str); /** Assign the constant. */
}; void assign_constant(const char *name, int t);
/** Assign the variable. */
void assign_variable(const char *name, int t);
/** The method just updates minlag or/and maxlead. Note that
* when assigning variables, the update is done when inserting
* to the maps, however, if removing a variable, we need to
* call this method. */
void update_minmaxll();
/** The method parses the string to recover a variable name
* and lag/lead ll. The variable name doesn't contain a lead/lag. */
virtual void parse_variable(const char *in, string &out, int &ll) const = 0;
public:
/** Return true if the str represents a double.*/
static bool is_string_constant(const char *str);
};
/** This class is a parent of all orderings of the dynamic atoms
/** This class is a parent of all orderings of the dynamic atoms * of variables which can appear before t, at t, or after t. It
* of variables which can appear before t, at t, or after t. It * encapsulates the ordering, and the information about the number
* encapsulates the ordering, and the information about the number * of static (appearing only at time t) predetermined (appearing
* of static (appearing only at time t) predetermined (appearing * before t and possibly at t), both (appearing before t and after
* before t and possibly at t), both (appearing before t and after * t and possibly at t) and forward looking (appearing after t and
* t and possibly at t) and forward looking (appearing after t and * possibly at t).
* possibly at t). *
* * The constructor takes a list of variable names. The class also
* The constructor takes a list of variable names. The class also * provides mapping from the ordering of the variables in the list
* provides mapping from the ordering of the variables in the list * (outer) to the new ordering (at time t) and back.
* (outer) to the new ordering (at time t) and back. *
* * The user of the subclass must call do_ordering() after
* The user of the subclass must call do_ordering() after * initialization.
* initialization. *
* * The class contains a few preimplemented methods for
* The class contains a few preimplemented methods for * ordering. The class is used in this way: Make a subclass, and
* ordering. The class is used in this way: Make a subclass, and * implement pure virtual do_ordering() by just plugging a
* implement pure virtual do_ordering() by just plugging a * preimplemented method, or plugging your own implementation. The
* preimplemented method, or plugging your own implementation. The * method do_ordering() is called by the user after the constructor.
* method do_ordering() is called by the user after the constructor. */
*/ class VarOrdering
class VarOrdering { {
protected: protected:
/** Number of static variables. */ /** Number of static variables. */
int n_stat; int n_stat;
/** Number of predetermined variables. */ /** Number of predetermined variables. */
int n_pred; int n_pred;
/** Number of both variables. */ /** Number of both variables. */
int n_both; int n_both;
/** Number of forward looking variables. */ /** Number of forward looking variables. */
int n_forw; int n_forw;
/** This is a set of tree indices corresponding to the /** This is a set of tree indices corresponding to the
* variables at all times as they occur in the formulas. In * variables at all times as they occur in the formulas. In
* fact, since this is used only for derivatives, the ordering * fact, since this is used only for derivatives, the ordering
* of this vector is only important for ordering of the * of this vector is only important for ordering of the
* derivatives, in other contexts the ordering is not * derivatives, in other contexts the ordering is not
* important, so it is rather a set of indices.*/ * important, so it is rather a set of indices.*/
vector<int> der_atoms; vector<int> der_atoms;
/** This maps tree index of the variable to the position in /** This maps tree index of the variable to the position in
* the row of the ordering. One should be careful with making * the row of the ordering. One should be careful with making
* space in the positions for variables not appearing at time * space in the positions for variables not appearing at time
* t. For instance in the pred(t-1), both(t-1), stat(t), * t. For instance in the pred(t-1), both(t-1), stat(t),
* pred(t), both(t), forw(t), both(t+1), forw(t+1) ordering, * pred(t), both(t), forw(t), both(t+1), forw(t+1) ordering,
* the variables x(t-1), y(t-1), x(t+1), z(t-1), z(t), and * the variables x(t-1), y(t-1), x(t+1), z(t-1), z(t), and
* z(t+1) having tree indices 6,5,4,3,2,1 will be ordered as * z(t+1) having tree indices 6,5,4,3,2,1 will be ordered as
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t), * follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
* x(t+1), where a bracketed expresion means non-existent by * x(t+1), where a bracketed expresion means non-existent by
* occupying a space. The map thus will look as follows: * occupying a space. The map thus will look as follows:
* {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped * {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped
* to positions 3 and 4. */ * to positions 3 and 4. */
map<int,int> positions; map<int, int> positions;
/** This maps an ordering of the list of variables in /** This maps an ordering of the list of variables in
* constructor to the new ordering (at time t). The length is * constructor to the new ordering (at time t). The length is
* the number of variables. */ * the number of variables. */
vector<int> outer2y; vector<int> outer2y;
/** This maps a new ordering to the ordering of the list of /** This maps a new ordering to the ordering of the list of
* variables in constructor (at time t). The length is the * variables in constructor (at time t). The length is the
* number of variables. */ * number of variables. */
vector<int> y2outer; vector<int> y2outer;
/** This is just a reference for variable names to keep it /** This is just a reference for variable names to keep it
* from constructor to do_ordering() implementations. */ * from constructor to do_ordering() implementations. */
const vector<const char*>& varnames; const vector<const char *> &varnames;
/** This is just a reference to atoms to keep it from /** This is just a reference to atoms to keep it from
* constructor to do_ordering() implementations. */ * constructor to do_ordering() implementations. */
const DynamicAtoms& atoms; const DynamicAtoms &atoms;
public: public:
/** This is an enum type for an ordering type implemented by /** This is an enum type for an ordering type implemented by
* do_general. */ * do_general. */
enum ord_type {pbspbfbf, bfspbfpb}; enum ord_type {pbspbfbf, bfspbfpb};
/** Construct the ordering of the variables given by the names /** Construct the ordering of the variables given by the names
* with their dynamic occurrences defined by the atoms. It * with their dynamic occurrences defined by the atoms. It
* calls the virtual method do_ordering which can be * calls the virtual method do_ordering which can be
* reimplemented. */ * reimplemented. */
VarOrdering(const vector<const char*>& vnames, const DynamicAtoms& a) VarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a)
: n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a) : n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a)
{} {
VarOrdering(const VarOrdering& vo, const vector<const char*>& vnames, }
const DynamicAtoms& a); VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
virtual VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms &a);
const DynamicAtoms& a) const = 0; virtual VarOrdering *clone(const vector<const char *> &vnames,
/** Destructor does nothing here. */ const DynamicAtoms &a) const = 0;
virtual ~VarOrdering() {} /** Destructor does nothing here. */
/** This is the method setting the ordering and the map. A virtual ~VarOrdering()
* subclass must reimplement it, possibly using a {
* preimplemented ordering. This method must be called by the }
* user after the class has been created. */ /** This is the method setting the ordering and the map. A
virtual void do_ordering() = 0; * subclass must reimplement it, possibly using a
/** Return number of static. */ * preimplemented ordering. This method must be called by the
int nstat() const * user after the class has been created. */
{return n_stat;} virtual void do_ordering() = 0;
/** Return number of predetermined. */ /** Return number of static. */
int npred() const int
{return n_pred;} nstat() const
/** Return number of both. */ {
int nboth() const return n_stat;
{return n_both;} }
/** Return number of forward looking. */ /** Return number of predetermined. */
int nforw() const int
{return n_forw;} npred() const
/** Return the set of tree indices for derivatives. */ {
const vector<int>& get_der_atoms() const return n_pred;
{return der_atoms;} }
/** Return the y2outer. */ /** Return number of both. */
const vector<int>& get_y2outer() const int
{return y2outer;} nboth() const
/** Return the outer2y. */ {
const vector<int>& get_outer2y() const return n_both;
{return outer2y;} }
/** Query the atom given by the tree index. True is returned /** Return number of forward looking. */
* if the atom is one of the variables in the object. */ int
bool check(int t) const; nforw() const
/** Return the position of the atom (nulary term) given by a {
* tree index. It is a lookup to the map. If the atom cannot return n_forw;
* be found, the exception is raised. */ }
int get_pos_of(int t) const; /** Return the set of tree indices for derivatives. */
/** This returns a length of ordered row of atoms. In all const vector<int> &
* cases so far, it does not depend on the ordering and it is get_der_atoms() const
* as follows. */ {
int length() const return der_atoms;
{return n_stat+2*n_pred+3*n_both+2*n_forw;} }
/** Debug print. */ /** Return the y2outer. */
void print() const; const vector<int> &
protected: get_y2outer() const
/** This is a general ordering method which orders the {
* variables by the given ordering ord_type. See documentation return y2outer;
* for respective do_ methods. */ }
void do_general(ord_type ordering); /** Return the outer2y. */
/** This is a preimplemented ordering for do_ordering() const vector<int> &
* method. It assumes that the variables appear only at time get_outer2y() const
* t-1, t, t+1. It orders the atoms as pred(t-1), both(t-1), {
* stat(t), pred(t), both(t), forw(t), both(t+1), return outer2y;
* forw(t+1). It builds the der_atoms, the map of positions, }
* as well as y2outer and outer2y. */ /** Query the atom given by the tree index. True is returned
void do_pbspbfbf() * if the atom is one of the variables in the object. */
{do_general(pbspbfbf);} bool check(int t) const;
/** This is a preimplemented ordering for do_ordering() /** Return the position of the atom (nulary term) given by a
* method. It assumes that the variables appear only at time * tree index. It is a lookup to the map. If the atom cannot
* t-1, t, t+1. It orders the atoms as both(t+1), forw(t+1), * be found, the exception is raised. */
* stat(t), pred(t), both(t), forw(t), pred(t-1), int get_pos_of(int t) const;
* both(t-1). It builds the der_atoms, the map of positions, /** This returns a length of ordered row of atoms. In all
* as well as y2outer and outer2y. */ * cases so far, it does not depend on the ordering and it is
void do_bfspbfpb() * as follows. */
{do_general(bfspbfpb);} int
/** This is a preimplemented ordering for do_ordering() length() const
* method. It makes no assumptions about occurences of {
* variables at different times. It orders the atoms with return n_stat+2*n_pred+3*n_both+2*n_forw;
* increasing time keeping the given ordering within one }
* time. This implies that y2outer and outer2y will be /** Debug print. */
* identities. The der_atoms will be just a sequence of atoms void print() const;
* from the least to the most time preserving the order of atoms protected:
* within one time. */ /** This is a general ordering method which orders the
void do_increasing_time(); * variables by the given ordering ord_type. See documentation
private: * for respective do_ methods. */
/** Declare this copy constructor as private to hide it. */ void do_general(ord_type ordering);
VarOrdering(const VarOrdering& vo); /** This is a preimplemented ordering for do_ordering()
}; * method. It assumes that the variables appear only at time
* t-1, t, t+1. It orders the atoms as pred(t-1), both(t-1),
* stat(t), pred(t), both(t), forw(t), both(t+1),
* forw(t+1). It builds the der_atoms, the map of positions,
* as well as y2outer and outer2y. */
void
do_pbspbfbf()
{
do_general(pbspbfbf);
}
/** This is a preimplemented ordering for do_ordering()
* method. It assumes that the variables appear only at time
* t-1, t, t+1. It orders the atoms as both(t+1), forw(t+1),
* stat(t), pred(t), both(t), forw(t), pred(t-1),
* both(t-1). It builds the der_atoms, the map of positions,
* as well as y2outer and outer2y. */
void
do_bfspbfpb()
{
do_general(bfspbfpb);
}
/** This is a preimplemented ordering for do_ordering()
* method. It makes no assumptions about occurences of
* variables at different times. It orders the atoms with
* increasing time keeping the given ordering within one
* time. This implies that y2outer and outer2y will be
* identities. The der_atoms will be just a sequence of atoms
* from the least to the most time preserving the order of atoms
* within one time. */
void do_increasing_time();
private:
/** Declare this copy constructor as private to hide it. */
VarOrdering(const VarOrdering &vo);
};
}; };

View File

@ -10,337 +10,417 @@
#include <vector> #include <vector>
#include <string> #include <string>
namespace ogp { namespace ogp
{
using std::vector; using std::vector;
using std::string; using std::string;
/** This is just ordering used for endogenous variables. It /** This is just ordering used for endogenous variables. It
* assumes that we have only time t-1, t, and t+1, orders them as * assumes that we have only time t-1, t, and t+1, orders them as
* pred(t-1), both(t-1), stat(t), pred(t), both(t), forw(t), * pred(t-1), both(t-1), stat(t), pred(t), both(t), forw(t),
* both(t+1), forw(t+1). */ * both(t+1), forw(t+1). */
class EndoVarOrdering1 : public VarOrdering { class EndoVarOrdering1 : public VarOrdering
public: {
EndoVarOrdering1(const vector<const char*>& vnames, const DynamicAtoms& a) public:
: VarOrdering(vnames, a) {} EndoVarOrdering1(const vector<const char *> &vnames, const DynamicAtoms &a)
EndoVarOrdering1(const EndoVarOrdering1& vo, const vector<const char*>& vnames, : VarOrdering(vnames, a)
const DynamicAtoms& a) {
: VarOrdering(vo, vnames, a) {} }
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<const char *> &vnames,
{return new EndoVarOrdering1(*this, vnames, a);} const DynamicAtoms &a)
void do_ordering() : VarOrdering(vo, vnames, a)
{do_pbspbfbf();} {
}; }
VarOrdering *
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const
{
return new EndoVarOrdering1(*this, vnames, a);
}
void
do_ordering()
{
do_pbspbfbf();
}
};
/** This is just another ordering used for endogenous /** This is just another ordering used for endogenous
* variables. It assumes that we have only time t-1, t, and t+1, * variables. It assumes that we have only time t-1, t, and t+1,
* orders them as both(t+1), forw(t+1), pred(t-1), both(t-1), * orders them as both(t+1), forw(t+1), pred(t-1), both(t-1),
* stat(t), pred(t), both(t), forw(t). */ * stat(t), pred(t), both(t), forw(t). */
class EndoVarOrdering2 : public VarOrdering { class EndoVarOrdering2 : public VarOrdering
public: {
EndoVarOrdering2(const vector<const char*>& vnames, const DynamicAtoms& a) public:
: VarOrdering(vnames, a) {} EndoVarOrdering2(const vector<const char *> &vnames, const DynamicAtoms &a)
EndoVarOrdering2(const EndoVarOrdering2& vo, const vector<const char*>& vnames, : VarOrdering(vnames, a)
const DynamicAtoms& a) {
: VarOrdering(vo, vnames, a) {} }
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<const char *> &vnames,
{return new EndoVarOrdering2(*this, vnames, a);} const DynamicAtoms &a)
void do_ordering() : VarOrdering(vo, vnames, a)
{do_bfspbfpb();} {
}; }
VarOrdering *
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const
{
return new EndoVarOrdering2(*this, vnames, a);
}
void
do_ordering()
{
do_bfspbfpb();
}
};
/** This is just ordering used for exogenous variables. It makes /** This is just ordering used for exogenous variables. It makes
* no assumptions about their timing. It orders them from the * no assumptions about their timing. It orders them from the
* least time to the latest time. */ * least time to the latest time. */
class ExoVarOrdering : public VarOrdering { class ExoVarOrdering : public VarOrdering
public: {
ExoVarOrdering(const vector<const char*>& vnames, const DynamicAtoms& a) public:
: VarOrdering(vnames, a) {} ExoVarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a)
ExoVarOrdering(const ExoVarOrdering& vo, const vector<const char*>& vnames, : VarOrdering(vnames, a)
const DynamicAtoms& a) {
: VarOrdering(vo, vnames, a) {} }
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const ExoVarOrdering(const ExoVarOrdering &vo, const vector<const char *> &vnames,
{return new ExoVarOrdering(*this, vnames, a);} const DynamicAtoms &a)
void do_ordering() : VarOrdering(vo, vnames, a)
{do_increasing_time();} {
}; }
VarOrdering *
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const
{
return new ExoVarOrdering(*this, vnames, a);
}
void
do_ordering()
{
do_increasing_time();
}
};
class FineAtoms; class FineAtoms;
/** This class provides an outer ordering of all variables (endo /** This class provides an outer ordering of all variables (endo
* and exo). It maps the ordering to the particular outer * and exo). It maps the ordering to the particular outer
* orderings of endo and exo. It works tightly with the FineAtoms * orderings of endo and exo. It works tightly with the FineAtoms
* class. */ * class. */
class AllvarOuterOrdering { class AllvarOuterOrdering
protected: {
/** Type for a map mapping a variable name to an integer. */ protected:
typedef map<const char*, int, ltstr> Tvarintmap; /** Type for a map mapping a variable name to an integer. */
/** Reference to atoms. */ typedef map<const char *, int, ltstr> Tvarintmap;
const FineAtoms& atoms; /** Reference to atoms. */
/** The vector of all endo and exo variables in outer const FineAtoms &atoms;
* ordering. The pointers point to storage in atoms. */ /** The vector of all endo and exo variables in outer
vector<const char*> allvar; * ordering. The pointers point to storage in atoms. */
/** The mapping from outer endogenous to outer all. For vector<const char *> allvar;
* example endo2all[0] is the order of the first outer /** The mapping from outer endogenous to outer all. For
* endogenous variable in the allvar ordering. */ * example endo2all[0] is the order of the first outer
vector<int> endo2all; * endogenous variable in the allvar ordering. */
/** The mapping from outer exogenous to outer all. For example vector<int> endo2all;
* exo2all[0] is the order of the first outer exogenous /** The mapping from outer exogenous to outer all. For example
* variables in the allvar ordering. */ * exo2all[0] is the order of the first outer exogenous
vector<int> exo2all; * variables in the allvar ordering. */
public: vector<int> exo2all;
/** Construct the allvar outer ordering from the provided public:
* sequence of endo and exo names. The names can have an /** Construct the allvar outer ordering from the provided
* arbitrary storage, the storage is transformed to the atoms * sequence of endo and exo names. The names can have an
* storage. An exception is thrown if either the list is not * arbitrary storage, the storage is transformed to the atoms
* exhaustive, or some string is not a variable. */ * storage. An exception is thrown if either the list is not
AllvarOuterOrdering(const vector<const char*>& allvar_outer, const FineAtoms& a); * exhaustive, or some string is not a variable. */
/** Copy constructor using the storage of provided atoms. */ AllvarOuterOrdering(const vector<const char *> &allvar_outer, const FineAtoms &a);
AllvarOuterOrdering(const AllvarOuterOrdering& allvar_outer, const FineAtoms& a); /** Copy constructor using the storage of provided atoms. */
/** Return endo2all mapping. */ AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a);
const vector<int>& get_endo2all() const /** Return endo2all mapping. */
{return endo2all;} const vector<int> &
/** Return exo2all mapping. */ get_endo2all() const
const vector<int>& get_exo2all() const {
{return exo2all;} return endo2all;
/** Return the allvar ordering. */ }
const vector<const char*>& get_allvar() const /** Return exo2all mapping. */
{return allvar;} const vector<int> &
}; get_exo2all() const
{
return exo2all;
}
/** Return the allvar ordering. */
const vector<const char *> &
get_allvar() const
{
return allvar;
}
};
/** This class refines the DynamicAtoms by distinguishing among /** This class refines the DynamicAtoms by distinguishing among
* parameters (no lag and leads) and endogenous and exogenous * parameters (no lag and leads) and endogenous and exogenous
* variables (with lags and leads). For parameters, endogenous and * variables (with lags and leads). For parameters, endogenous and
* exogenous, it defines outer orderings and internal * exogenous, it defines outer orderings and internal
* orderings. The internal orderings are created by * orderings. The internal orderings are created by
* parsing_finished() method when it is sure that no new variables * parsing_finished() method when it is sure that no new variables
* would be registered. The outer orderings are given by the order * would be registered. The outer orderings are given by the order
* of calls of registering methods. * of calls of registering methods.
* *
* In addition, the class also defines outer ordering of * In addition, the class also defines outer ordering of
* endogenous and exogenous variables. This is input as a * endogenous and exogenous variables. This is input as a
* parameter to parsing_finished(). By default, this whole outer * parameter to parsing_finished(). By default, this whole outer
* ordering is just a concatenation of outer ordering of * ordering is just a concatenation of outer ordering of
* endogenous and exogenous variables. * endogenous and exogenous variables.
* *
* The internal ordering of all endo and exo variables is just a * The internal ordering of all endo and exo variables is just a
* concatenation of endo and exo variables in their internal * concatenation of endo and exo variables in their internal
* orderings. This is the ordering with respect to which all * orderings. This is the ordering with respect to which all
* derivatives are taken. */ * derivatives are taken. */
class FineAtoms : public DynamicAtoms { class FineAtoms : public DynamicAtoms
friend class AllvarOuterOrdering; {
protected: friend class AllvarOuterOrdering;
typedef map<const char*, int, ltstr> Tvarintmap; protected:
private: typedef map<const char *, int, ltstr> Tvarintmap;
/** The vector of parameters names. The order gives the order private:
* the data is communicated with outside world. */ /** The vector of parameters names. The order gives the order
vector<const char*> params; * the data is communicated with outside world. */
/** A map mapping a name of a parameter to an index in the outer vector<const char *> params;
* ordering. */ /** A map mapping a name of a parameter to an index in the outer
Tvarintmap param_outer_map; * ordering. */
/** The vector of endogenous variables. This defines the order Tvarintmap param_outer_map;
* like parameters. */ /** The vector of endogenous variables. This defines the order
vector<const char*> endovars; * like parameters. */
/** A map mapping a name of an endogenous variable to an index vector<const char *> endovars;
* in the outer ordering. */ /** A map mapping a name of an endogenous variable to an index
Tvarintmap endo_outer_map; * in the outer ordering. */
/** The vector of exogenous variables. Also defines the order Tvarintmap endo_outer_map;
* like parameters and endovars. */ /** The vector of exogenous variables. Also defines the order
vector<const char*> exovars; * like parameters and endovars. */
/** A map mapping a name of an exogenous variable to an index vector<const char *> exovars;
* in the outer ordering. */ /** A map mapping a name of an exogenous variable to an index
Tvarintmap exo_outer_map; * in the outer ordering. */
Tvarintmap exo_outer_map;
protected: protected:
/** This is the internal ordering of all atoms corresponding /** This is the internal ordering of all atoms corresponding
* to endogenous variables. It is constructed by * to endogenous variables. It is constructed by
* parsing_finished() method, which should be called after all * parsing_finished() method, which should be called after all
* parsing jobs have been finished. */ * parsing jobs have been finished. */
VarOrdering* endo_order; VarOrdering *endo_order;
/** This is the internal ordering of all atoms corresponding /** This is the internal ordering of all atoms corresponding
* to exogenous variables. It has the same handling as * to exogenous variables. It has the same handling as
* endo_order. */ * endo_order. */
VarOrdering* exo_order; VarOrdering *exo_order;
/** This is the all variables outer ordering. It is /** This is the all variables outer ordering. It is
* constructed by parsing finished. */ * constructed by parsing finished. */
AllvarOuterOrdering* allvar_order; AllvarOuterOrdering *allvar_order;
/** This vector defines a set of atoms as tree indices used /** This vector defines a set of atoms as tree indices used
* for differentiation. The order of the atoms in this vector * for differentiation. The order of the atoms in this vector
* defines ordering of the derivative tensors. The ordering is * defines ordering of the derivative tensors. The ordering is
* a concatenation of atoms from endo_order and then * a concatenation of atoms from endo_order and then
* exo_order. This vector is setup by parsing_finished() and * exo_order. This vector is setup by parsing_finished() and
* is returned by variables(). */ * is returned by variables(). */
vector<int> der_atoms; vector<int> der_atoms;
/** This is a mapping from endogenous atoms to all atoms in /** This is a mapping from endogenous atoms to all atoms in
* der_atoms member. The mapping maps index in endogenous atom * der_atoms member. The mapping maps index in endogenous atom
* ordering to index (not value) in der_atoms. It is useful if * ordering to index (not value) in der_atoms. It is useful if
* one wants to evaluate derivatives wrt only endogenous * one wants to evaluate derivatives wrt only endogenous
* variables. It is set by parsing_finished(). By definition, * variables. It is set by parsing_finished(). By definition,
* it is monotone. */ * it is monotone. */
vector<int> endo_atoms_map; vector<int> endo_atoms_map;
/** This is a mapping from exogenous atoms to all atoms in /** This is a mapping from exogenous atoms to all atoms in
* der_atoms member. It is the same as endo_atoms_map for * der_atoms member. It is the same as endo_atoms_map for
* atoms of exogenous variables. */ * atoms of exogenous variables. */
vector<int> exo_atoms_map; vector<int> exo_atoms_map;
public: public:
FineAtoms() FineAtoms()
: endo_order(NULL), exo_order(NULL), allvar_order(NULL) {} : endo_order(NULL), exo_order(NULL), allvar_order(NULL)
FineAtoms(const FineAtoms& fa); {
/** Deletes endo_order and exo_order. */ }
virtual ~FineAtoms() FineAtoms(const FineAtoms &fa);
{ /** Deletes endo_order and exo_order. */
if (endo_order) delete endo_order; virtual ~FineAtoms()
if (exo_order) delete exo_order; {
if (allvar_order) delete allvar_order; if (endo_order)
} delete endo_order;
/** Overrides DynamicAtoms::check_variable so that the error if (exo_order)
* would be raised if the variable name is not declared. A delete exo_order;
* variable is declared by inserting it to if (allvar_order)
* DynamicAtoms::varnames. This is a responsibility of a delete allvar_order;
* subclass. */ }
int check_variable(const char* name) const; /** Overrides DynamicAtoms::check_variable so that the error
/** This calculates min lag and max lead of endogenous variables. */ * would be raised if the variable name is not declared. A
void endovarspan(int& mlead, int& mlag) const * variable is declared by inserting it to
{varspan(endovars, mlead, mlag);} * DynamicAtoms::varnames. This is a responsibility of a
/** This calculates mim lag and max lead of exogenous variables. */ * subclass. */
void exovarspan(int& mlead, int& mlag) const int check_variable(const char *name) const;
{varspan(exovars, mlead, mlag);} /** This calculates min lag and max lead of endogenous variables. */
/** This calculates the number of periods in which at least void
* one exogenous variable occurs. */ endovarspan(int &mlead, int &mlag) const
int num_exo_periods() const; {
/** Return an (external) ordering of parameters. */ varspan(endovars, mlead, mlag);
const vector<const char*>& get_params() const }
{return params;} /** This calculates mim lag and max lead of exogenous variables. */
/** Return an external ordering of endogenous variables. */ void
const vector<const char*>& get_endovars() const exovarspan(int &mlead, int &mlag) const
{return endovars;} {
/** Return an external ordering of exogenous variables. */ varspan(exovars, mlead, mlag);
const vector<const char*>& get_exovars() const }
{return exovars;} /** This calculates the number of periods in which at least
/** This constructs internal orderings and makes the indices * one exogenous variable occurs. */
* returned by variables method available. Further it int num_exo_periods() const;
* constructs outer ordering of all variables by a simple /** Return an (external) ordering of parameters. */
* concatenation of outer endogenous and outer exogenous. In const vector<const char *> &
* addition, it makes nstat, npred, nboth, nforw available. */ get_params() const
void parsing_finished(VarOrdering::ord_type ot); {
/** This does the same thing as return params;
* parsing_finished(VarOrdering::ord_type) plus it allows for }
* inputing a different outer ordering of all variables. The /** Return an external ordering of endogenous variables. */
* ordering is input as a list of strings, their storage can const vector<const char *> &
* be arbitrary. */ get_endovars() const
void parsing_finished(VarOrdering::ord_type ot, const vector<const char*> avo); {
/** Return the external ordering of all variables (endo and return endovars;
* exo). This is either the second argument to }
* parsing_finished or the default external ordering. This /** Return an external ordering of exogenous variables. */
* must be called only after parsing_finished. */ const vector<const char *> &
const vector<const char*>& get_allvar() const; get_exovars() const
/** Return the map from outer ordering of endo variables to {
* the allvar ordering. This must be called only after return exovars;
* parsing_finished. */ }
const vector<int>& outer_endo2all() const; /** This constructs internal orderings and makes the indices
/** Return the map from outer ordering of exo variables to * returned by variables method available. Further it
* the allvar ordering. This must be called only after * constructs outer ordering of all variables by a simple
* parsing_finished. */ * concatenation of outer endogenous and outer exogenous. In
const vector<int>& outer_exo2all() const; * addition, it makes nstat, npred, nboth, nforw available. */
/** Return the atoms with respect to which we are going to void parsing_finished(VarOrdering::ord_type ot);
* differentiate. This must be called after /** This does the same thing as
* parsing_finished. */ * parsing_finished(VarOrdering::ord_type) plus it allows for
vector<int> variables() const; * inputing a different outer ordering of all variables. The
/** Return the number of static. */ * ordering is input as a list of strings, their storage can
int nstat() const; * be arbitrary. */
/** Return the number of predetermined. */ void parsing_finished(VarOrdering::ord_type ot, const vector<const char *> avo);
int npred() const; /** Return the external ordering of all variables (endo and
/** Return the number of both. */ * exo). This is either the second argument to
int nboth() const; * parsing_finished or the default external ordering. This
/** Return the number of forward looking. */ * must be called only after parsing_finished. */
int nforw() const; const vector<const char *>&get_allvar() const;
/** Return the index of an endogenous atom given by tree index in /** Return the map from outer ordering of endo variables to
* the endo ordering. This must be also called only after * the allvar ordering. This must be called only after
* parsing_finished(). */ * parsing_finished. */
int get_pos_of_endo(int t) const; const vector<int>&outer_endo2all() const;
/** Return the index of an exogenous atom given by tree index in /** Return the map from outer ordering of exo variables to
* the exo ordering. This must be also called only after * the allvar ordering. This must be called only after
* parsing_finished(). */ * parsing_finished. */
int get_pos_of_exo(int t) const; const vector<int>&outer_exo2all() const;
/** Return the index of either endogenous or exogenous atom /** Return the atoms with respect to which we are going to
* given by tree index in the concatenated ordering of * differentiate. This must be called after
* endogenous and exogenous atoms. This must be also called * parsing_finished. */
* only after parsing_finished(). */ vector<int> variables() const;
int get_pos_of_all(int t) const; /** Return the number of static. */
/** Return the mapping from endogenous at time t to outer int nstat() const;
* ordering of endogenous. */ /** Return the number of predetermined. */
const vector<int>& y2outer_endo() const; int npred() const;
/** Return the mapping from the outer ordering of endogenous to endogenous /** Return the number of both. */
* at time t. */ int nboth() const;
const vector<int>& outer2y_endo() const; /** Return the number of forward looking. */
/** Return the mapping from exogenous at time t to outer int nforw() const;
* ordering of exogenous. */ /** Return the index of an endogenous atom given by tree index in
const vector<int>& y2outer_exo() const; * the endo ordering. This must be also called only after
/** Return the mapping from the outer ordering of exogenous to exogenous * parsing_finished(). */
* at time t. */ int get_pos_of_endo(int t) const;
const vector<int>& outer2y_exo() const; /** Return the index of an exogenous atom given by tree index in
/** Return the endo_atoms_map. */ * the exo ordering. This must be also called only after
const vector<int>& get_endo_atoms_map() const; * parsing_finished(). */
/** Return the exo_atoms_map. */ int get_pos_of_exo(int t) const;
const vector<int>& get_exo_atoms_map() const; /** Return the index of either endogenous or exogenous atom
/** Return an index in the outer ordering of a given * given by tree index in the concatenated ordering of
* parameter. An exception is thrown if the name is not a * endogenous and exogenous atoms. This must be also called
* parameter. */ * only after parsing_finished(). */
int name2outer_param(const char* name) const; int get_pos_of_all(int t) const;
/** Return an index in the outer ordering of a given /** Return the mapping from endogenous at time t to outer
* endogenous variable. An exception is thrown if the name is not a * ordering of endogenous. */
* and endogenous variable. */ const vector<int>&y2outer_endo() const;
int name2outer_endo(const char* name) const; /** Return the mapping from the outer ordering of endogenous to endogenous
/** Return an index in the outer ordering of a given * at time t. */
* exogenous variable. An exception is thrown if the name is not a const vector<int>&outer2y_endo() const;
* and exogenous variable. */ /** Return the mapping from exogenous at time t to outer
int name2outer_exo(const char* name) const; * ordering of exogenous. */
/** Return an index in the outer ordering of all variables const vector<int>&y2outer_exo() const;
* (endo and exo) for a given name. An exception is thrown if /** Return the mapping from the outer ordering of exogenous to exogenous
* the name is not a variable. This must be called only after * at time t. */
* parsing_finished(). */ const vector<int>&outer2y_exo() const;
int name2outer_allvar(const char* name) const; /** Return the endo_atoms_map. */
/** Return the number of endogenous variables at time t-1, these are state const vector<int>&get_endo_atoms_map() const;
* variables. */ /** Return the exo_atoms_map. */
int nys() const const vector<int>&get_exo_atoms_map() const;
{return npred()+nboth();} /** Return an index in the outer ordering of a given
/** Return the number of endogenous variables at time t+1. */ * parameter. An exception is thrown if the name is not a
int nyss() const * parameter. */
{return nboth()+nforw();} int name2outer_param(const char *name) const;
/** Return the number of endogenous variables. */ /** Return an index in the outer ordering of a given
int ny() const * endogenous variable. An exception is thrown if the name is not a
{return endovars.size();} * and endogenous variable. */
/** Return the number of exogenous variables. */ int name2outer_endo(const char *name) const;
int nexo() const /** Return an index in the outer ordering of a given
{return (int)exovars.size();} * exogenous variable. An exception is thrown if the name is not a
/** Return the number of parameters. */ * and exogenous variable. */
int np() const int name2outer_exo(const char *name) const;
{return (int)(params.size());} /** Return an index in the outer ordering of all variables
/** Register unique endogenous variable name. The order of * (endo and exo) for a given name. An exception is thrown if
* calls defines the endo outer ordering. The method is * the name is not a variable. This must be called only after
* virtual, since a superclass may want to do some additional * parsing_finished(). */
* action. */ int name2outer_allvar(const char *name) const;
virtual void register_uniq_endo(const char* name); /** Return the number of endogenous variables at time t-1, these are state
/** Register unique exogenous variable name. The order of * variables. */
* calls defines the exo outer ordering. The method is int
* virtual, since a superclass may want to do somem additional nys() const
* action. */ {
virtual void register_uniq_exo(const char* name); return npred()+nboth();
/** Register unique parameter name. The order of calls defines }
* the param outer ordering. The method is /** Return the number of endogenous variables at time t+1. */
* virtual, since a superclass may want to do somem additional int
* action. */ nyss() const
virtual void register_uniq_param(const char* name); {
/** Debug print. */ return nboth()+nforw();
void print() const; }
private: /** Return the number of endogenous variables. */
/** This performs the common part of parsing_finished(), which int
* is a construction of internal orderings. */ ny() const
void make_internal_orderings(VarOrdering::ord_type ot); {
protected: return endovars.size();
/** This remembers the ordering type of the last call make_internal_ordering. */ }
VarOrdering::ord_type order_type; /** Return the number of exogenous variables. */
}; int
nexo() const
{
return (int) exovars.size();
}
/** Return the number of parameters. */
int
np() const
{
return (int) (params.size());
}
/** Register unique endogenous variable name. The order of
* calls defines the endo outer ordering. The method is
* virtual, since a superclass may want to do some additional
* action. */
virtual void register_uniq_endo(const char *name);
/** Register unique exogenous variable name. The order of
* calls defines the exo outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_exo(const char *name);
/** Register unique parameter name. The order of calls defines
* the param outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_param(const char *name);
/** Debug print. */
void print() const;
private:
/** This performs the common part of parsing_finished(), which
* is a construction of internal orderings. */
void make_internal_orderings(VarOrdering::ord_type ot);
protected:
/** This remembers the ordering type of the last call make_internal_ordering. */
VarOrdering::ord_type order_type;
};
}; };
#endif #endif

View File

@ -5,408 +5,492 @@
#include "tree.h" #include "tree.h"
namespace ogp { namespace ogp
using std::vector; {
using std::vector;
/** Pure virtual class defining a minimal interface for /** Pure virtual class defining a minimal interface for
* representation of nulary terms within FormulaParser. */ * representation of nulary terms within FormulaParser. */
class Atoms { class Atoms
public: {
Atoms() {} public:
virtual ~Atoms() {} Atoms()
/** This returns previously assigned internal index to the {
* given atom, or returns -1 if the atom has not been assigned }
* yet. The method can raise an exception, if the Atoms virtual ~Atoms()
* implementation is strict and the name is not among {
* prescribed possible values. */ }
virtual int check(const char* name) const = 0; /** This returns previously assigned internal index to the
/** This method assigns an internal index to the nulary term * given atom, or returns -1 if the atom has not been assigned
* described by the name. The internal index is allocated by * yet. The method can raise an exception, if the Atoms
* OperationTree class. */ * implementation is strict and the name is not among
virtual void assign(const char* name, int t) = 0; * prescribed possible values. */
/** Returns a number of variables which will be used for virtual int check(const char *name) const = 0;
* differentiations. */ /** This method assigns an internal index to the nulary term
virtual int nvar() const = 0; * described by the name. The internal index is allocated by
/** Returns a vector of variable's internal indices which will * OperationTree class. */
* be used for differentiations. */ virtual void assign(const char *name, int t) = 0;
virtual vector<int> variables() const = 0; /** Returns a number of variables which will be used for
/** Debug print. */ * differentiations. */
virtual void print() const = 0; virtual int nvar() const = 0;
}; /** Returns a vector of variable's internal indices which will
* be used for differentiations. */
virtual vector<int> variables() const = 0;
/** Debug print. */
virtual void print() const = 0;
};
/** Pure virtual class defining interface for all classes able to /** Pure virtual class defining interface for all classes able to
* set nulary terms to evaluation tree EvalTree. The * set nulary terms to evaluation tree EvalTree. The
* implementations of this class will have to be connected with * implementations of this class will have to be connected with
* Atoms to have knowledge about the atoms and their indices in * Atoms to have knowledge about the atoms and their indices in
* the tree, and will call EvalTree::set_nulary. */ * the tree, and will call EvalTree::set_nulary. */
class AtomValues { class AtomValues
public: {
virtual ~AtomValues() {} public:
virtual void setValues(EvalTree& et) const = 0; virtual ~AtomValues()
}; {
}
virtual void setValues(EvalTree &et) const = 0;
};
class FormulaDerEvaluator; class FormulaDerEvaluator;
class FoldMultiIndex; class FoldMultiIndex;
/** For ordering FoldMultiIndex in the std::map. */ /** For ordering FoldMultiIndex in the std::map. */
struct ltfmi { struct ltfmi
bool operator()(const FoldMultiIndex& i1, const FoldMultiIndex& i2) const; {
}; bool operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const;
};
/** This class stores derivatives (tree indices) of one formula /** This class stores derivatives (tree indices) of one formula
* for all orders upto a given one. It stores the derivatives as a * for all orders upto a given one. It stores the derivatives as a
* sequence (vector) of these tree indices and sequence of the * sequence (vector) of these tree indices and sequence of the
* multidimensional indices of variables wrt which the derivatives * multidimensional indices of variables wrt which the derivatives
* were taken. In order to speed up querying for a derivative * were taken. In order to speed up querying for a derivative
* given the variables, we have a map mapping the multidimensional * given the variables, we have a map mapping the multidimensional
* index to the order of the derivative in the sequence. * index to the order of the derivative in the sequence.
* *
* The only reason we do not have only this map is that the * The only reason we do not have only this map is that the
* iterators of the map do not survive the insertions to the map, * iterators of the map do not survive the insertions to the map,
* and implementation of the constructor has to be very difficult. * and implementation of the constructor has to be very difficult.
*/ */
class FormulaDerivatives { class FormulaDerivatives
friend class FormulaDerEvaluator; {
protected: friend class FormulaDerEvaluator;
/** Vector of derivatives. This is a list of derivatives (tree protected:
* indices), the ordering is given by the algorithm used to /** Vector of derivatives. This is a list of derivatives (tree
* create it. Currently, it starts with zero-th derivative, * indices), the ordering is given by the algorithm used to
* the formula itself and carries with first order, second, * create it. Currently, it starts with zero-th derivative,
* etc. */ * the formula itself and carries with first order, second,
vector<int> tder; * etc. */
/** Vector of multiindices corresponding to the vector of vector<int> tder;
* derivatives. */ /** Vector of multiindices corresponding to the vector of
vector<FoldMultiIndex> indices; * derivatives. */
/** For retrieving derivatives via a multiindex, we have a map vector<FoldMultiIndex> indices;
* mapping a multiindex to a derivative in the tder /** For retrieving derivatives via a multiindex, we have a map
* ordering. This means that indices[ind2der[index]] == index. */ * mapping a multiindex to a derivative in the tder
typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap; * ordering. This means that indices[ind2der[index]] == index. */
Tfmiintmap ind2der; typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap;
/** The number of variables. */ Tfmiintmap ind2der;
int nvar; /** The number of variables. */
/** The maximum order of derivatives. */ int nvar;
int order; /** The maximum order of derivatives. */
public: int order;
/** The constructor allocates and fills the sequence of the public:
* indices of derivatives for a formula. /** The constructor allocates and fills the sequence of the
* @param otree the OperationTree for which all work is done * indices of derivatives for a formula.
* and to which the derivatives are added. * @param otree the OperationTree for which all work is done
* @param vars the vector of nulary terms in the tree; the * and to which the derivatives are added.
* derivatives are taken with respect to these variables in * @param vars the vector of nulary terms in the tree; the
* the ordering given by the vector. * derivatives are taken with respect to these variables in
* @param f the index of the formula being differentiated. The * the ordering given by the vector.
* zero derivative is set to f. * @param f the index of the formula being differentiated. The
* @param max_order the maximum order of differentiation. * zero derivative is set to f.
*/ * @param max_order the maximum order of differentiation.
FormulaDerivatives(OperationTree& otree, const vector<int>& vars, int f, int max_order); */
/** Copy constructor. */ FormulaDerivatives(OperationTree &otree, const vector<int> &vars, int f, int max_order);
FormulaDerivatives(const FormulaDerivatives& fd); /** Copy constructor. */
virtual ~FormulaDerivatives(){} FormulaDerivatives(const FormulaDerivatives &fd);
/** Random access to the derivatives via multiindex. */ virtual ~FormulaDerivatives()
int derivative(const FoldMultiIndex& mi) const; {
/** Return the order. */ }
int get_order() const /** Random access to the derivatives via multiindex. */
{return order;} int derivative(const FoldMultiIndex &mi) const;
/** Debug print. */ /** Return the order. */
void print(const OperationTree& otree) const; int
}; get_order() const
{
return order;
}
/** Debug print. */
void print(const OperationTree &otree) const;
};
class FormulaEvaluator; class FormulaEvaluator;
/** This class is able to parse a number of formulas and /** This class is able to parse a number of formulas and
* differentiate them. The life cycle of the object is as follows: * differentiate them. The life cycle of the object is as follows:
* After it is created, a few calls to parse will add formulas * After it is created, a few calls to parse will add formulas
* (zero derivatives) to the object. Then a method differentiate() * (zero derivatives) to the object. Then a method differentiate()
* can be called and a vector of pointers to derivatives for each * can be called and a vector of pointers to derivatives for each
* formula is created. After this, no one should call other * formula is created. After this, no one should call other
* parse() or differentiate(). A const reference of the object can * parse() or differentiate(). A const reference of the object can
* be used in constructors of FormulaEvaluator and * be used in constructors of FormulaEvaluator and
* FormulaDerEvaluator in order to evaluate formulas (zero * FormulaDerEvaluator in order to evaluate formulas (zero
* derivatives) and higher derivatives resp. */ * derivatives) and higher derivatives resp. */
class FormulaParser { class FormulaParser
friend class FormulaCustomEvaluator; {
friend class FormulaDerEvaluator; friend class FormulaCustomEvaluator;
protected: friend class FormulaDerEvaluator;
/** The OperationTree of all formulas, including derivatives. */ protected:
OperationTree otree; /** The OperationTree of all formulas, including derivatives. */
/** Reference to Atoms. The Atoms are filled with nulary terms OperationTree otree;
* during execution of parse(). */ /** Reference to Atoms. The Atoms are filled with nulary terms
Atoms& atoms; * during execution of parse(). */
/** Vector of formulas (zero derivatives) in the order as they Atoms &atoms;
* have been parsed. */ /** Vector of formulas (zero derivatives) in the order as they
vector<int> formulas; * have been parsed. */
/** The vector to derivatives, each vector corresponds to a vector<int> formulas;
* formula in the vector formulas. */ /** The vector to derivatives, each vector corresponds to a
vector<FormulaDerivatives*> ders; * formula in the vector formulas. */
public: vector<FormulaDerivatives *> ders;
/** Construct an empty formula parser. */ public:
FormulaParser(Atoms& a) /** Construct an empty formula parser. */
: atoms(a) {} FormulaParser(Atoms &a)
/** Copy constructor using a different instance of Atoms. */ : atoms(a)
FormulaParser(const FormulaParser& fp, Atoms& a); {
virtual ~FormulaParser(); }
/** Copy constructor using a different instance of Atoms. */
FormulaParser(const FormulaParser &fp, Atoms &a);
virtual
~FormulaParser();
/** Requires an addition of the formula; called from the /** Requires an addition of the formula; called from the
* parser. */ * parser. */
void add_formula(int t); void add_formula(int t);
/** Requires an addition of the binary operation; called from /** Requires an addition of the binary operation; called from
* the parser. */ * the parser. */
int add_binary(code_t code, int t1, int t2); int add_binary(code_t code, int t1, int t2);
/** Requires an addition of the unary operation; called from /** Requires an addition of the unary operation; called from
* the parser. */ * the parser. */
int add_unary(code_t code, int t); int add_unary(code_t code, int t);
/** Requires an addition of the nulary operation given by the /** Requires an addition of the nulary operation given by the
* string. The Atoms are consulted for uniquness and are given * string. The Atoms are consulted for uniquness and are given
* an internal index generated by the OperationTree. This is * an internal index generated by the OperationTree. This is
* the channel through which the Atoms are filled. */ * the channel through which the Atoms are filled. */
int add_nulary(const char* str); int add_nulary(const char *str);
/** Adds a derivative to the tree. This just calls /** Adds a derivative to the tree. This just calls
* OperationTree::add_derivative. */ * OperationTree::add_derivative. */
int add_derivative(int t, int v) int
{return otree.add_derivative(t, v);} add_derivative(int t, int v)
/** Adds a substitution. This just calls {
* OperationTree::add_substitution. */ return otree.add_derivative(t, v);
int add_substitution(int t, const map<int,int>& subst) }
{return otree.add_substitution(t, subst);} /** Adds a substitution. This just calls
/** Add the substitution given by the map where left sides of * OperationTree::add_substitution. */
* substitutions come from another parser. The right sides are int
* from this object. The given t is from the given parser fp. */ add_substitution(int t, const map<int, int> &subst)
int add_substitution(int t, const map<int,int>& subst, {
const FormulaParser& fp) return otree.add_substitution(t, subst);
{return otree.add_substitution(t, subst, fp.otree);} }
/** This adds formulas from the given parser with (possibly) /** Add the substitution given by the map where left sides of
* different atoms applying substitutions from the given map * substitutions come from another parser. The right sides are
* mapping atoms from fp to atoms of the object. */ * from this object. The given t is from the given parser fp. */
void add_subst_formulas(const map<int,int>& subst, const FormulaParser& fp); int
/** Substitute formulas. For each i from 1 through all add_substitution(int t, const map<int, int> &subst,
* formulas, it adds a substitution of the i-th formula and const FormulaParser &fp)
* make it to be i-th formula.*/ {
void substitute_formulas(const std::map<int,int>& subst); return otree.add_substitution(t, subst, fp.otree);
/** This method turns the given term to nulary operation. It }
* should be used with caution, since this method does not /** This adds formulas from the given parser with (possibly)
* anything do with atoms, but usually some action is also * different atoms applying substitutions from the given map
* needed (at leat to assign the tree index t to some * mapping atoms from fp to atoms of the object. */
* atom). */ void add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp);
void nularify(int t) /** Substitute formulas. For each i from 1 through all
{otree.nularify(t);} * formulas, it adds a substitution of the i-th formula and
/** Returns a set of nulary terms of the given term. Just * make it to be i-th formula.*/
* calls OperationTree::nulary_of_term. */ void substitute_formulas(const std::map<int, int> &subst);
const unordered_set<int>& nulary_of_term(int t) const /** This method turns the given term to nulary operation. It
{return otree.nulary_of_term(t);} * should be used with caution, since this method does not
* anything do with atoms, but usually some action is also
* needed (at leat to assign the tree index t to some
* atom). */
void
nularify(int t)
{
otree.nularify(t);
}
/** Returns a set of nulary terms of the given term. Just
* calls OperationTree::nulary_of_term. */
const unordered_set<int> &
nulary_of_term(int t) const
{
return otree.nulary_of_term(t);
}
/** Parse a given string containing one or more formulas. The /** Parse a given string containing one or more formulas. The
* formulas are parsed and added to the OperationTree and to * formulas are parsed and added to the OperationTree and to
* the formulas vector. */ * the formulas vector. */
void parse(int length, const char* stream); void parse(int length, const char *stream);
/** Processes a syntax error from bison. */ /** Processes a syntax error from bison. */
void error(const char* mes) const; void error(const char *mes) const;
/** Differentiate all the formulas up to the given order. The /** Differentiate all the formulas up to the given order. The
* variables with respect to which the derivatives are taken * variables with respect to which the derivatives are taken
* are obtained by Atoms::variables(). If the derivates exist, * are obtained by Atoms::variables(). If the derivates exist,
* they are destroyed and created again (with possibly * they are destroyed and created again (with possibly
* different order). */ * different order). */
void differentiate(int max_order); void differentiate(int max_order);
/** Return i-th formula derivatives. */ /** Return i-th formula derivatives. */
const FormulaDerivatives& derivatives(int i) const; const FormulaDerivatives&derivatives(int i) const;
/** This returns a maximum index of zero derivative formulas /** This returns a maximum index of zero derivative formulas
* including all nulary terms. This is a mimumum length of the * including all nulary terms. This is a mimumum length of the
* tree for which it is safe to evaluate zero derivatives of * tree for which it is safe to evaluate zero derivatives of
* the formulas. */ * the formulas. */
int last_formula() const; int last_formula() const;
/** This returns a tree index of the i-th formula in the /** This returns a tree index of the i-th formula in the
* vector. */ * vector. */
int formula(int i) const int
{return formulas[i];} formula(int i) const
{
return formulas[i];
}
/** This returns a tree index of the last formula and pops its
* item from the formulas vector. The number of formulas is
* then less by one. Returns -1 if there is no formula. If
* there are derivatives of the last formula, they are
* destroyed and the vector ders is popped from the back. */
int pop_last_formula();
/** This returns a tree index of the last formula and pops its /** This returns a number of formulas. */
* item from the formulas vector. The number of formulas is int
* then less by one. Returns -1 if there is no formula. If nformulas() const
* there are derivatives of the last formula, they are {
* destroyed and the vector ders is popped from the back. */ return (int) (formulas.size());
int pop_last_formula(); }
/** This returns a number of formulas. */ /** This returns a reference to atoms. */
int nformulas() const const Atoms &
{return (int)(formulas.size());} getAtoms() const
{
return atoms;
}
Atoms &
getAtoms()
{
return atoms;
}
/** This returns the tree. */
const OperationTree &
getTree() const
{
return otree;
}
OperationTree &
getTree()
{
return otree;
}
/** This returns a reference to atoms. */ /** Debug print. */
const Atoms& getAtoms() const void print() const;
{return atoms;} private:
Atoms& getAtoms() /** Hide this copy constructor declaration by declaring it as
{return atoms;} * private. */
/** This returns the tree. */ FormulaParser(const FormulaParser &fp);
const OperationTree& getTree() const /** Destroy all derivatives. */
{return otree;} void destroy_derivatives();
OperationTree& getTree() };
{return otree;}
/** Debug print. */ /** This is a pure virtual class defining an interface for all
void print() const; * classes which will load the results of formula (zero
private: * derivative) evaluations. A primitive implementation of this
/** Hide this copy constructor declaration by declaring it as * class can be a vector of doubles. */
* private. */ class FormulaEvalLoader
FormulaParser(const FormulaParser& fp); {
/** Destroy all derivatives. */ public:
void destroy_derivatives(); virtual ~FormulaEvalLoader()
}; {
}
/** Set the value res for the given formula. The formula is
* identified by an index corresponding to the ordering in
* which the formulas have been parsed (starting from
* zero). */
virtual void load(int i, double res) = 0;
};
/** This is a pure virtual class defining an interface for all /** This class evaluates a selected subset of terms of the
* classes which will load the results of formula (zero * tree. In the protected constructor, one can constraint the
* derivative) evaluations. A primitive implementation of this * initialization of the evaluation tree to a given number of
* class can be a vector of doubles. */ * terms in the beginning. Using this constructor, one has to make
class FormulaEvalLoader { * sure, that the terms in the beginning do not refer to terms
public: * behind the initial part. */
virtual ~FormulaEvalLoader() {} class FormulaCustomEvaluator
/** Set the value res for the given formula. The formula is {
* identified by an index corresponding to the ordering in protected:
* which the formulas have been parsed (starting from /** The evaluation tree. */
* zero). */ EvalTree etree;
virtual void load(int i, double res) = 0; /** The custom tree indices to be evaluated. */
}; vector<int> terms;
public:
/** Construct from FormulaParser and given list of terms. */
FormulaCustomEvaluator(const FormulaParser &fp, const vector<int> &ts)
: etree(fp.otree), terms(ts)
{
}
/** Construct from OperationTree and given list of terms. */
FormulaCustomEvaluator(const OperationTree &ot, const vector<int> &ts)
: etree(ot), terms(ts)
{
}
/** Evaluate the terms using the given AtomValues and load the
* results using the given loader. The loader is called for
* each term in the order of the terms. */
void eval(const AtomValues &av, FormulaEvalLoader &loader);
protected:
FormulaCustomEvaluator(const FormulaParser &fp)
: etree(fp.otree, fp.last_formula()), terms(fp.formulas)
{
}
};
/** This class evaluates a selected subset of terms of the /** This class evaluates zero derivatives of the FormulaParser. */
* tree. In the protected constructor, one can constraint the class FormulaEvaluator : public FormulaCustomEvaluator
* initialization of the evaluation tree to a given number of {
* terms in the beginning. Using this constructor, one has to make public:
* sure, that the terms in the beginning do not refer to terms /** Construct from FormulaParser. */
* behind the initial part. */ FormulaEvaluator(const FormulaParser &fp)
class FormulaCustomEvaluator { : FormulaCustomEvaluator(fp)
protected: {
/** The evaluation tree. */ }
EvalTree etree; };
/** The custom tree indices to be evaluated. */
vector<int> terms;
public:
/** Construct from FormulaParser and given list of terms. */
FormulaCustomEvaluator(const FormulaParser& fp, const vector<int>& ts)
: etree(fp.otree), terms(ts)
{}
/** Construct from OperationTree and given list of terms. */
FormulaCustomEvaluator(const OperationTree& ot, const vector<int>& ts)
: etree(ot), terms(ts)
{}
/** Evaluate the terms using the given AtomValues and load the
* results using the given loader. The loader is called for
* each term in the order of the terms. */
void eval(const AtomValues& av, FormulaEvalLoader& loader);
protected:
FormulaCustomEvaluator(const FormulaParser& fp)
: etree(fp.otree, fp.last_formula()), terms(fp.formulas)
{}
};
/** This class evaluates zero derivatives of the FormulaParser. */ /** This is a pure virtual class defining an interface for all
class FormulaEvaluator : public FormulaCustomEvaluator { * classes which will load the results of formula derivative
public: * evaluations. */
/** Construct from FormulaParser. */ class FormulaDerEvalLoader
FormulaEvaluator(const FormulaParser& fp) {
: FormulaCustomEvaluator(fp) {} public:
}; virtual ~FormulaDerEvalLoader()
{
}
/** This loads the result of the derivative of the given
* order. The semantics of i is the same as in
* FormulaEvalLoader::load. The indices of variables with
* respect to which the derivative was taken are stored in
* memory pointed by vars. These are the tree indices of the
* variables. */
virtual void load(int i, int order, const int *vars, double res) = 0;
};
/** This is a pure virtual class defining an interface for all /** This class is a utility class representing the tensor
* classes which will load the results of formula derivative * multindex. It can basically increment itself, and calculate
* evaluations. */ * its offset in the folded tensor. */
class FormulaDerEvalLoader { class FoldMultiIndex
public: {
virtual ~FormulaDerEvalLoader() {} /** Number of variables. */
/** This loads the result of the derivative of the given int nvar;
* order. The semantics of i is the same as in /** Dimension. */
* FormulaEvalLoader::load. The indices of variables with int ord;
* respect to which the derivative was taken are stored in /** The multiindex. */
* memory pointed by vars. These are the tree indices of the int *data;
* variables. */ public:
virtual void load(int i, int order, const int* vars, double res) = 0; /** Initializes to the zero derivative. Order is 0, data is
}; * empty. */
FoldMultiIndex(int nv);
/** Initializes the multiindex to zeros or given i. */
FoldMultiIndex(int nv, int order, int i = 0);
/** Makes a new multiindex of the same order applying a given
* mapping to the indices. The mapping is supposed to be monotone. */
FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp);
/** Shifting constructor. This adds a given number of orders
* to the end, copying the last item to the newly added items,
* keeping the index ordered. If the index was empty (zero-th
* dimension), then zeros are added. */
FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders);
/** Copy constructor. */
FoldMultiIndex(const FoldMultiIndex &fmi);
/** Desctructor. */
virtual ~FoldMultiIndex()
{
delete [] data;
}
/** Assignment operator. */
const FoldMultiIndex &operator=(const FoldMultiIndex &fmi);
/** Operator < implementing lexicographic ordering within one
* order, increasing order across orders. */
bool operator<(const FoldMultiIndex &fmi) const;
bool operator==(const FoldMultiIndex &fmi) const;
/** Increment the multiindex. */
void increment();
/** Return offset of the multiindex in the folded tensor. */
int offset() const;
const int &
operator[](int i) const
{
return data[i];
}
/** Return order of the multiindex, i.e. dimension of the
* tensor. */
int
order() const
{
return ord;
}
/** Return the number of variables. */
int
nv() const
{
return nvar;
}
/** Return the data. */
const int *
ind() const
{
return data;
}
/** Return true if the end of the tensor is reached. The
* result of a subsequent increment should be considered
* unpredictable. */
bool
past_the_end() const
{
return (ord == 0) || (data[0] == nvar);
}
/** Prints the multiindex in the brackets. */
void print() const;
private:
static int offset_recurse(int *data, int len, int nv);
};
/** This class is a utility class representing the tensor /** This class evaluates derivatives of the FormulaParser. */
* multindex. It can basically increment itself, and calculate class FormulaDerEvaluator
* its offset in the folded tensor. */ {
class FoldMultiIndex { /** Its own instance of EvalTree. */
/** Number of variables. */ EvalTree etree;
int nvar; /** The indices of derivatives for each formula. This is a
/** Dimension. */ * const copy FormulaParser::ders. We do not allocate nor
int ord; * deallocate anything here. */
/** The multiindex. */ vector<const FormulaDerivatives *> ders;
int* data; /** A copy of tree indices corresponding to atoms to with
public: * respect the derivatives were taken. */
/** Initializes to the zero derivative. Order is 0, data is vector<int> der_atoms;
* empty. */ public:
FoldMultiIndex(int nv); /** Construct the object from FormulaParser. */
/** Initializes the multiindex to zeros or given i. */ FormulaDerEvaluator(const FormulaParser &fp);
FoldMultiIndex(int nv, int order, int i = 0); /** Evaluate the derivatives from the FormulaParser wrt to all
/** Makes a new multiindex of the same order applying a given * atoms in variables vector at the given AtomValues. The
* mapping to the indices. The mapping is supposed to be monotone. */ * given loader is used for output. */
FoldMultiIndex(int nv, const FoldMultiIndex& mi, const vector<int>& mp); void eval(const AtomValues &av, FormulaDerEvalLoader &loader, int order);
/** Shifting constructor. This adds a given number of orders /** Evaluate the derivatives from the FormulaParser wrt to a
* to the end, copying the last item to the newly added items, * selection of atoms of the atoms in der_atoms vector at the
* keeping the index ordered. If the index was empty (zero-th * given AtomValues. The selection is given by a monotone
* dimension), then zeros are added. */ * mapping to the indices (not values) of the der_atoms. */
FoldMultiIndex(const FoldMultiIndex& fmi, int new_orders); void eval(const vector<int> &mp, const AtomValues &av, FormulaDerEvalLoader &loader,
/** Copy constructor. */ int order);
FoldMultiIndex(const FoldMultiIndex& fmi); };
/** Desctructor. */
virtual ~FoldMultiIndex()
{delete [] data;}
/** Assignment operator. */
const FoldMultiIndex& operator=(const FoldMultiIndex& fmi);
/** Operator < implementing lexicographic ordering within one
* order, increasing order across orders. */
bool operator<(const FoldMultiIndex& fmi) const;
bool operator==(const FoldMultiIndex& fmi) const;
/** Increment the multiindex. */
void increment();
/** Return offset of the multiindex in the folded tensor. */
int offset() const;
const int& operator[](int i) const
{return data[i];}
/** Return order of the multiindex, i.e. dimension of the
* tensor. */
int order() const
{return ord;}
/** Return the number of variables. */
int nv() const
{return nvar;}
/** Return the data. */
const int* ind() const
{return data;}
/** Return true if the end of the tensor is reached. The
* result of a subsequent increment should be considered
* unpredictable. */
bool past_the_end() const
{return (ord == 0) || (data[0] == nvar);}
/** Prints the multiindex in the brackets. */
void print() const;
private:
static int offset_recurse(int* data, int len, int nv);
};
/** This class evaluates derivatives of the FormulaParser. */
class FormulaDerEvaluator {
/** Its own instance of EvalTree. */
EvalTree etree;
/** The indices of derivatives for each formula. This is a
* const copy FormulaParser::ders. We do not allocate nor
* deallocate anything here. */
vector<const FormulaDerivatives*> ders;
/** A copy of tree indices corresponding to atoms to with
* respect the derivatives were taken. */
vector<int> der_atoms;
public:
/** Construct the object from FormulaParser. */
FormulaDerEvaluator(const FormulaParser& fp);
/** Evaluate the derivatives from the FormulaParser wrt to all
* atoms in variables vector at the given AtomValues. The
* given loader is used for output. */
void eval(const AtomValues& av, FormulaDerEvalLoader& loader, int order);
/** Evaluate the derivatives from the FormulaParser wrt to a
* selection of atoms of the atoms in der_atoms vector at the
* given AtomValues. The selection is given by a monotone
* mapping to the indices (not values) of the der_atoms. */
void eval(const vector<int>& mp, const AtomValues& av, FormulaDerEvalLoader& loader,
int order);
};
}; };
#endif #endif

View File

@ -15,29 +15,32 @@
// in EVERY action consuming material (this can be done with #define // in EVERY action consuming material (this can be done with #define
// YY_USER_ACTION) and in bison you must use option %locations. // YY_USER_ACTION) and in bison you must use option %locations.
#ifndef OG_LOCATION_H #ifndef OG_LOCATION_H
#define OG_LOCATION_H #define OG_LOCATION_H
namespace ogp { namespace ogp
{
struct location_type { struct location_type
int off; // offset of the token {
int ll; // length ot the token int off; // offset of the token
location_type() : off(0), ll(0) {} int ll; // length ot the token
}; location_type() : off(0), ll(0)
{
}
};
}; };
#define YYLTYPE ogp::location_type #define YYLTYPE ogp::location_type
// set current off to the first off and add all lengths // set current off to the first off and add all lengths
#define YYLLOC_DEFAULT(Current, Rhs, N) \ #define YYLLOC_DEFAULT(Current, Rhs, N) \
{(Current).off = (Rhs)[1].off; \ {(Current).off = (Rhs)[1].off; \
(Current).ll = 0; \ (Current).ll = 0; \
for (int i = 1; i <= N; i++) (Current).ll += (Rhs)[i].ll;} for (int i = 1; i <= N; i++) (Current).ll += (Rhs)[i].ll; }
#define SET_LLOC(prefix) (prefix##lloc.off += prefix##lloc.ll, prefix##lloc.ll = prefix##leng) #define SET_LLOC(prefix) (prefix ## lloc.off += prefix ## lloc.ll, prefix ## lloc.ll = prefix ## leng)
#endif #endif

View File

@ -8,110 +8,143 @@
#include <cstdlib> // For NULL #include <cstdlib> // For NULL
#include <vector> #include <vector>
namespace ogp { namespace ogp
using std::vector; {
using std::vector;
/** This class reads the given string and parses it as a /** This class reads the given string and parses it as a
* matrix. The matrix is read row by row. The row delimiter is * matrix. The matrix is read row by row. The row delimiter is
* either a newline character or semicolon (first newline * either a newline character or semicolon (first newline
* character after the semicolon is ignored), the column delimiter * character after the semicolon is ignored), the column delimiter
* is either blank character or comma. A different number of items * is either blank character or comma. A different number of items
* in the row is not reconciliated, we do not construct a matrix * in the row is not reconciliated, we do not construct a matrix
* here. The class provides only an iterator to go through all * here. The class provides only an iterator to go through all
* read items, the iterator provides information on row number and * read items, the iterator provides information on row number and
* column number of the item. */ * column number of the item. */
class MPIterator; class MPIterator;
class MatrixParser { class MatrixParser
friend class MPIterator; {
protected: friend class MPIterator;
/** Raw data as they were read. */ protected:
vector<double> data; /** Raw data as they were read. */
/** Number of items in each row. */ vector<double> data;
vector<int> row_lengths; /** Number of items in each row. */
/** Maximum number of row lengths. */ vector<int> row_lengths;
int nc; /** Maximum number of row lengths. */
public: int nc;
MatrixParser() public:
: nc(0) {} MatrixParser()
MatrixParser(const MatrixParser& mp) : nc(0)
: data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc) {} {
virtual ~MatrixParser() {} }
/** Return a number of read rows. */ MatrixParser(const MatrixParser &mp)
int nrows() const : data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc)
{return (int) row_lengths.size();} {
/** Return a maximum number of items in the rows. */ }
int ncols() const virtual ~MatrixParser()
{return nc;} {
/** Parses a given data. This initializes the object data. */ }
void parse(int length, const char* stream); /** Return a number of read rows. */
/** Adds newly read item. This should be called from bison int
* parser. */ nrows() const
void add_item(double v); {
/** Starts a new row. This should be called from bison return (int) row_lengths.size();
* parser. */ }
void start_row(); /** Return a maximum number of items in the rows. */
/** Process a parse error from the parser. */ int
void error(const char* mes) const; ncols() const
/** Return begin iterator. */ {
MPIterator begin() const; return nc;
/** Return end iterator. */ }
MPIterator end() const; /** Parses a given data. This initializes the object data. */
protected: void parse(int length, const char *stream);
/** Returns an index of the first non-empty row starting at /** Adds newly read item. This should be called from bison
* start. If the start row is non-empty, returns the start. If * parser. */
* there is no other non-empty row, returns void add_item(double v);
* row_lengths.size(). */ /** Starts a new row. This should be called from bison
int find_first_non_empty_row(int start = 0) const; * parser. */
}; void start_row();
/** Process a parse error from the parser. */
void error(const char *mes) const;
/** Return begin iterator. */
MPIterator begin() const;
/** Return end iterator. */
MPIterator end() const;
protected:
/** Returns an index of the first non-empty row starting at
* start. If the start row is non-empty, returns the start. If
* there is no other non-empty row, returns
* row_lengths.size(). */
int find_first_non_empty_row(int start = 0) const;
};
/** This is an iterator intended to iterate through a matrix parsed /** This is an iterator intended to iterate through a matrix parsed
* by MatrixParser. The iterator provides only read-only access. */ * by MatrixParser. The iterator provides only read-only access. */
class MPIterator { class MPIterator
friend class MatrixParser; {
protected: friend class MatrixParser;
/** Reference to the matrix parser. */ protected:
const MatrixParser* p; /** Reference to the matrix parser. */
/** The index of the pointed item in the matrix parser. */ const MatrixParser *p;
unsigned int i; /** The index of the pointed item in the matrix parser. */
/** The column number of the pointed item starting from zero. */ unsigned int i;
int c; /** The column number of the pointed item starting from zero. */
/** The row number of the pointed item starting from zero. */ int c;
int r; /** The row number of the pointed item starting from zero. */
int r;
public: public:
MPIterator() : p(NULL), i(0), c(0), r(0) {} MPIterator() : p(NULL), i(0), c(0), r(0)
/** Constructs an iterator pointing to the beginning of the {
* parsed matrix. */ }
MPIterator(const MatrixParser& mp); /** Constructs an iterator pointing to the beginning of the
/** Constructs an iterator pointing to the past-the-end of the * parsed matrix. */
* parsed matrix. */ MPIterator(const MatrixParser &mp);
MPIterator(const MatrixParser& mp, const char* dummy); /** Constructs an iterator pointing to the past-the-end of the
/** Return read-only reference to the pointed item. */ * parsed matrix. */
const double& operator*() const MPIterator(const MatrixParser &mp, const char *dummy);
{return p->data[i];} /** Return read-only reference to the pointed item. */
/** Return a row index of the pointed item. */ const double &
int row() const operator*() const
{return r;} {
/** Return a column index of the pointed item. */ return p->data[i];
int col() const }
{return c;} /** Return a row index of the pointed item. */
/** Assignment operator. */ int
const MPIterator& operator=(const MPIterator& it) row() const
{p = it.p; i = it.i; c = it.c; r = it.r; return *this;} {
/** Return true if the iterators are the same, this is if they return r;
* have the same underlying object and the same item index. */ }
bool operator==(const MPIterator& it) const /** Return a column index of the pointed item. */
{return it.p == p && it.i == i;} int
/** Negative of the operator==. */ col() const
bool operator!=(const MPIterator& it) const {
{return ! (it == *this);} return c;
/** Increment operator. */ }
MPIterator& operator++(); /** Assignment operator. */
}; const MPIterator &
operator=(const MPIterator &it)
{
p = it.p; i = it.i; c = it.c; r = it.r; return *this;
}
/** Return true if the iterators are the same, this is if they
* have the same underlying object and the same item index. */
bool
operator==(const MPIterator &it) const
{
return it.p == p && it.i == i;
}
/** Negative of the operator==. */
bool
operator!=(const MPIterator &it) const
{
return !(it == *this);
}
/** Increment operator. */
MPIterator &operator++();
};
}; };
#endif #endif
// Local Variables: // Local Variables:

View File

@ -5,24 +5,28 @@
#ifndef OGP_NAMELIST #ifndef OGP_NAMELIST
#define OGP_NAMELIST #define OGP_NAMELIST
namespace ogp { namespace ogp
{
/** Parent class of all parsers parsing a namelist. They must /** Parent class of all parsers parsing a namelist. They must
* implement add_name() method and error() method, which is called * implement add_name() method and error() method, which is called
* when an parse error occurs. * when an parse error occurs.
* *
* Parsing a name list is done as follows: implement * Parsing a name list is done as follows: implement
* NameListParser interface, create the object, and call * NameListParser interface, create the object, and call
* NameListParser::namelist_parse(int lengt, const char* * NameListParser::namelist_parse(int lengt, const char*
* text). When implementing error(), one may consult global * text). When implementing error(), one may consult global
* location_type namelist_lloc. */ * location_type namelist_lloc. */
class NameListParser { class NameListParser
public: {
virtual ~NameListParser() {} public:
virtual void add_name(const char* name) = 0; virtual ~NameListParser()
virtual void namelist_error(const char* mes) = 0; {
void namelist_parse(int length, const char* text); }
}; virtual void add_name(const char *name) = 0;
virtual void namelist_error(const char *mes) = 0;
void namelist_parse(int length, const char *text);
};
}; };
#endif #endif

View File

@ -7,61 +7,88 @@
#include <string> #include <string>
namespace ogp { namespace ogp
using std::string; {
using std::string;
/** This is an easy exception, which, besides the message, stores /** This is an easy exception, which, besides the message, stores
* also an offset of the parse error. Since we might need to track * also an offset of the parse error. Since we might need to track
* the argument number and for example the filed in the argument * the argument number and for example the filed in the argument
* which caused the error, we add three integers, which have no * which caused the error, we add three integers, which have no
* semantics here. They should be documented in the function which * semantics here. They should be documented in the function which
* throws an exception and sets them. Their default value is -1, * throws an exception and sets them. Their default value is -1,
* which means they have not been set. */ * which means they have not been set. */
class ParserException { class ParserException
protected: {
char* mes; protected:
int off; char *mes;
int aux_i1; int off;
int aux_i2; int aux_i1;
int aux_i3; int aux_i2;
public: int aux_i3;
ParserException(const char* m, int offset); public:
ParserException(const string& m, int offset); ParserException(const char *m, int offset);
ParserException(const string& m, const char* dum, int i1); ParserException(const string &m, int offset);
ParserException(const string& m, const char* dum, int i1, int i2); ParserException(const string &m, const char *dum, int i1);
ParserException(const string& m, const char* dum, int i1, int i2, int i3); ParserException(const string &m, const char *dum, int i1, int i2);
ParserException(const ParserException& e, int plus_offset); ParserException(const string &m, const char *dum, int i1, int i2, int i3);
/** Makes a copy and pushes given integer to aux_i1 shuffling ParserException(const ParserException &e, int plus_offset);
* others and forgetting the last. */ /** Makes a copy and pushes given integer to aux_i1 shuffling
ParserException(const ParserException& e, const char* dum, int i); * others and forgetting the last. */
/** Makes a copy and pushes given two integers to aux_i1 and aux_i2 shuffling ParserException(const ParserException &e, const char *dum, int i);
* others and forgetting the last two. */ /** Makes a copy and pushes given two integers to aux_i1 and aux_i2 shuffling
ParserException(const ParserException& e, const char* dum, int i1, int i2); * others and forgetting the last two. */
/** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling ParserException(const ParserException &e, const char *dum, int i1, int i2);
* others and forgetting the last three. */ /** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling
ParserException(const ParserException& e, const char* dum, int i1, int i2, int i3); * others and forgetting the last three. */
ParserException(const ParserException& e); ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3);
virtual ~ParserException(); ParserException(const ParserException &e);
void print(FILE* fd) const; virtual
const char* message() const ~ParserException();
{return mes;} void print(FILE *fd) const;
int offset() const const char *
{return off;} message() const
const int& i1() const {
{return aux_i1;} return mes;
int& i1() }
{return aux_i1;} int
const int& i2() const offset() const
{return aux_i2;} {
int& i2() return off;
{return aux_i2;} }
const int& i3() const const int &
{return aux_i3;} i1() const
int& i3() {
{return aux_i3;} return aux_i1;
protected: }
void copy(const ParserException& e); int &
}; i1()
{
return aux_i1;
}
const int &
i2() const
{
return aux_i2;
}
int &
i2()
{
return aux_i2;
}
const int &
i3() const
{
return aux_i3;
}
int &
i3()
{
return aux_i3;
}
protected:
void copy(const ParserException &e);
};
}; };
#endif #endif

View File

@ -7,79 +7,95 @@
#include "dynamic_atoms.h" #include "dynamic_atoms.h"
namespace ogp { namespace ogp
{
class StaticAtoms : public Atoms, public Constants { class StaticAtoms : public Atoms, public Constants
protected: {
typedef map<const char*, int, ltstr> Tvarmap; protected:
typedef map<int, const char*> Tinvmap; typedef map<const char *, int, ltstr> Tvarmap;
/** Storage for names. */ typedef map<int, const char *> Tinvmap;
NameStorage varnames; /** Storage for names. */
/** Outer order of variables. */ NameStorage varnames;
vector<const char*> varorder; /** Outer order of variables. */
/** This is the map mapping a variable name to the tree vector<const char *> varorder;
* index. */ /** This is the map mapping a variable name to the tree
Tvarmap vars; * index. */
/** This is the inverse mapping. It maps a tree index to the Tvarmap vars;
* variable name. */ /** This is the inverse mapping. It maps a tree index to the
Tinvmap indices; * variable name. */
public: Tinvmap indices;
StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars() public:
{} StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars()
/* Copy constructor. */ {
StaticAtoms(const StaticAtoms& a); }
/** Conversion from DynamicAtoms. This takes all atoms from /* Copy constructor. */
* the DynamicAtoms and adds its static version. The new tree StaticAtoms(const StaticAtoms &a);
* indices are allocated in the passed OperationTree. Whole /** Conversion from DynamicAtoms. This takes all atoms from
* the process is traced in the map mapping old tree indices * the DynamicAtoms and adds its static version. The new tree
* to new tree indices. */ * indices are allocated in the passed OperationTree. Whole
StaticAtoms(const DynamicAtoms& da, OperationTree& otree, Tintintmap& tmap) * the process is traced in the map mapping old tree indices
: Atoms(), Constants(), varnames(), varorder(), vars() * to new tree indices. */
{import_atoms(da, otree, tmap);} StaticAtoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap)
/* Destructor. */ : Atoms(), Constants(), varnames(), varorder(), vars()
virtual ~StaticAtoms() {} {
/** This imports atoms from dynamic atoms inserting the new import_atoms(da, otree, tmap);
* tree indices to the given tree (including constants). The }
* mapping from old atoms to new atoms is traced in tmap. */ /* Destructor. */
void import_atoms(const DynamicAtoms& da, OperationTree& otree, virtual ~StaticAtoms()
Tintintmap& tmap); {
/** If the name is constant, it returns its tree index if the }
* constant is registered in Constants, it returns -1 /** This imports atoms from dynamic atoms inserting the new
* otherwise. If the name is not constant, it returns result * tree indices to the given tree (including constants). The
* from check_variable, which is implemented by a subclass. */ * mapping from old atoms to new atoms is traced in tmap. */
int check(const char* name) const; void import_atoms(const DynamicAtoms &da, OperationTree &otree,
/** This assigns a given tree index to the variable name. The Tintintmap &tmap);
* name should have been checked before the call. */ /** If the name is constant, it returns its tree index if the
void assign(const char* name, int t); * constant is registered in Constants, it returns -1
int nvar() const * otherwise. If the name is not constant, it returns result
{return varnames.num();} * from check_variable, which is implemented by a subclass. */
/** This returns a vector of all variables. */ int check(const char *name) const;
vector<int> variables() const; /** This assigns a given tree index to the variable name. The
/** This returns a tree index of the given variable. */ * name should have been checked before the call. */
int index(const char* name) const; void assign(const char *name, int t);
/** This returns a name from the given tree index. NULL is int
* returned if the tree index doesn't exist. */ nvar() const
const char* inv_index(int t) const; {
/** This returns a name in a outer ordering. (There is no other ordering.) */ return varnames.num();
const char* name(int i) const }
{return varorder[i];} /** This returns a vector of all variables. */
/** Debug print. */ vector<int> variables() const;
void print() const; /** This returns a tree index of the given variable. */
/** This registers a variable. A subclass can reimplement int index(const char *name) const;
* this, for example, to ensure uniqueness of the /** This returns a name from the given tree index. NULL is
* name. However, this method should be always called in * returned if the tree index doesn't exist. */
* overriding methods to do the registering job. */ const char *inv_index(int t) const;
virtual void register_name(const char* name); /** This returns a name in a outer ordering. (There is no other ordering.) */
/** Return the name storage to allow querying to other const char *
* classes. */ name(int i) const
const NameStorage& get_name_storage() const {
{return varnames;} return varorder[i];
protected: }
/** This checks the variable. The implementing subclass might /** Debug print. */
* want to throw an exception if the variable has not been void print() const;
* registered. */ /** This registers a variable. A subclass can reimplement
virtual int check_variable(const char* name) const = 0; * this, for example, to ensure uniqueness of the
}; * name. However, this method should be always called in
* overriding methods to do the registering job. */
virtual void register_name(const char *name);
/** Return the name storage to allow querying to other
* classes. */
const NameStorage &
get_name_storage() const
{
return varnames;
}
protected:
/** This checks the variable. The implementing subclass might
* want to throw an exception if the variable has not been
* registered. */
virtual int check_variable(const char *name) const = 0;
};
}; };
#endif #endif

View File

@ -8,165 +8,202 @@
#include "static_atoms.h" #include "static_atoms.h"
#include "fine_atoms.h" #include "fine_atoms.h"
namespace ogp { namespace ogp
{
/** This class represents static atoms distinguishing between /** This class represents static atoms distinguishing between
* parameters, endogenous and exogenous variables. The class * parameters, endogenous and exogenous variables. The class
* maintains also ordering of all three categories (referenced as * maintains also ordering of all three categories (referenced as
* outer or inner, since there is only one ordering). It can be * outer or inner, since there is only one ordering). It can be
* constructed either from scratch, or from fine dynamic atoms. In * constructed either from scratch, or from fine dynamic atoms. In
* the latter case, one can decide if the ordering of this static * the latter case, one can decide if the ordering of this static
* atoms should be internal or external ordering of the original * atoms should be internal or external ordering of the original
* dynamic fine atoms. */ * dynamic fine atoms. */
class StaticFineAtoms : public StaticAtoms { class StaticFineAtoms : public StaticAtoms
public: {
typedef map<int,int> Tintintmap; public:
protected: typedef map<int, int> Tintintmap;
typedef map<const char*, int, ltstr> Tvarintmap; protected:
private: typedef map<const char *, int, ltstr> Tvarintmap;
/** The vector of parameter names, gives the parameter private:
* ordering. */ /** The vector of parameter names, gives the parameter
vector<const char*> params; * ordering. */
/** A map mappping a parameter name to an index in the ordering. */ vector<const char *> params;
Tvarintmap param_outer_map; /** A map mappping a parameter name to an index in the ordering. */
/** The vector of endogenous variables. This defines the order Tvarintmap param_outer_map;
* like parameters. */ /** The vector of endogenous variables. This defines the order
vector<const char*> endovars; * like parameters. */
/** A map mapping a name of an endogenous variable to an index vector<const char *> endovars;
* in the ordering. */ /** A map mapping a name of an endogenous variable to an index
Tvarintmap endo_outer_map; * in the ordering. */
/** The vector of exogenous variables. Also defines the order Tvarintmap endo_outer_map;
* like parameters and endovars. */ /** The vector of exogenous variables. Also defines the order
vector<const char*> exovars; * like parameters and endovars. */
/** A map mapping a name of an exogenous variable to an index vector<const char *> exovars;
* in the outer ordering. */ /** A map mapping a name of an exogenous variable to an index
Tvarintmap exo_outer_map; * in the outer ordering. */
/** This vector defines a set of atoms as tree indices used Tvarintmap exo_outer_map;
* for differentiation. The order of the atoms in is the /** This vector defines a set of atoms as tree indices used
* concatenation of the outer ordering of endogenous and * for differentiation. The order of the atoms in is the
* exogenous. This vector is setup by parsing_finished() and * concatenation of the outer ordering of endogenous and
* is returned by variables(). */ * exogenous. This vector is setup by parsing_finished() and
vector<int> der_atoms; * is returned by variables(). */
/** This is a mapping from endogenous atoms to all atoms in vector<int> der_atoms;
* der_atoms member. The mapping maps index in endogenous atom /** This is a mapping from endogenous atoms to all atoms in
* ordering to index (not value) in der_atoms. It is useful if * der_atoms member. The mapping maps index in endogenous atom
* one wants to evaluate derivatives wrt only endogenous * ordering to index (not value) in der_atoms. It is useful if
* variables. It is set by parsing_finished(). By definition, * one wants to evaluate derivatives wrt only endogenous
* it is monotone. */ * variables. It is set by parsing_finished(). By definition,
vector<int> endo_atoms_map; * it is monotone. */
/** This is a mapping from exogenous atoms to all atoms in vector<int> endo_atoms_map;
* der_atoms member. It is the same as endo_atoms_map for /** This is a mapping from exogenous atoms to all atoms in
* atoms of exogenous variables. */ * der_atoms member. It is the same as endo_atoms_map for
vector<int> exo_atoms_map; * atoms of exogenous variables. */
public: vector<int> exo_atoms_map;
StaticFineAtoms() {} public:
/** Copy constructor making a new storage for atom names. */ StaticFineAtoms()
StaticFineAtoms(const StaticFineAtoms& sfa); {
/** Conversion from dynamic FineAtoms taking its outer }
* ordering as ordering of parameters, endogenous and /** Copy constructor making a new storage for atom names. */
* exogenous. A biproduct is an integer to integer map mapping StaticFineAtoms(const StaticFineAtoms &sfa);
* tree indices of the dynamic atoms to tree indices of the /** Conversion from dynamic FineAtoms taking its outer
* static atoms. */ * ordering as ordering of parameters, endogenous and
StaticFineAtoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap) * exogenous. A biproduct is an integer to integer map mapping
{StaticFineAtoms::import_atoms(fa, otree, tmap);} * tree indices of the dynamic atoms to tree indices of the
/** Conversion from dynamic FineAtoms taking its internal * static atoms. */
* ordering as ordering of parameters, endogenous and StaticFineAtoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap)
* exogenous. A biproduct is an integer to integer map mapping {
* tree indices of the dynamic atoms to tree indices of the StaticFineAtoms::import_atoms(fa, otree, tmap);
* static atoms. */ }
StaticFineAtoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap, /** Conversion from dynamic FineAtoms taking its internal
const char* dummy) * ordering as ordering of parameters, endogenous and
{StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);} * exogenous. A biproduct is an integer to integer map mapping
virtual ~StaticFineAtoms() {} * tree indices of the dynamic atoms to tree indices of the
/** This adds atoms from dynamic atoms inserting new tree * static atoms. */
* indices to the given tree and tracing the mapping from old StaticFineAtoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap,
* atoms to new atoms in tmap. The ordering of the static const char *dummy)
* atoms is the same as outer ordering of dynamic atoms. */ {
void import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap); StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);
/** This adds atoms from dynamic atoms inserting new tree }
* indices to the given tree and tracing the mapping from old virtual ~StaticFineAtoms()
* atoms to new atoms in tmap. The ordering of the static {
* atoms is the same as internal ordering of dynamic atoms. */ }
void import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap, /** This adds atoms from dynamic atoms inserting new tree
const char* dummy); * indices to the given tree and tracing the mapping from old
/** Overrides StaticAtoms::check_variable so that the error * atoms to new atoms in tmap. The ordering of the static
* would be raised if the variable name is not declared. A * atoms is the same as outer ordering of dynamic atoms. */
* variable is declared by inserting it to void import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap);
* StaticAtoms::varnames, which is done with registering /** This adds atoms from dynamic atoms inserting new tree
* methods. This a responsibility of a subclass. */ * indices to the given tree and tracing the mapping from old
int check_variable(const char* name) const; * atoms to new atoms in tmap. The ordering of the static
/** Return an (external) ordering of parameters. */ * atoms is the same as internal ordering of dynamic atoms. */
const vector<const char*>& get_params() const void import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap,
{return params;} const char *dummy);
/** Return an external ordering of endogenous variables. */ /** Overrides StaticAtoms::check_variable so that the error
const vector<const char*>& get_endovars() const * would be raised if the variable name is not declared. A
{return endovars;} * variable is declared by inserting it to
/** Return an external ordering of exogenous variables. */ * StaticAtoms::varnames, which is done with registering
const vector<const char*>& get_exovars() const * methods. This a responsibility of a subclass. */
{return exovars;} int check_variable(const char *name) const;
/** This constructs der_atoms, and the endo_endoms_map and /** Return an (external) ordering of parameters. */
* exo_atoms_map, which can be created only after the parsing const vector<const char *> &
* is finished. */ get_params() const
void parsing_finished(); {
/** Return the atoms with respect to which we are going to return params;
* differentiate. */ }
vector<int> variables() const /** Return an external ordering of endogenous variables. */
{return der_atoms;} const vector<const char *> &
/** Return the endo_atoms_map. */ get_endovars() const
const vector<int>& get_endo_atoms_map() const {
{return endo_atoms_map;} return endovars;
/** Return the exo_atoms_map. */ }
const vector<int>& get_exo_atoms_map() const /** Return an external ordering of exogenous variables. */
{return endo_atoms_map;} const vector<const char *> &
/** Return an index in the outer ordering of a given get_exovars() const
* parameter. An exception is thrown if the name is not a {
* parameter. */ return exovars;
int name2outer_param(const char* name) const; }
/** Return an index in the outer ordering of a given /** This constructs der_atoms, and the endo_endoms_map and
* endogenous variable. An exception is thrown if the name is not a * exo_atoms_map, which can be created only after the parsing
* and endogenous variable. */ * is finished. */
int name2outer_endo(const char* name) const; void parsing_finished();
/** Return an index in the outer ordering of a given /** Return the atoms with respect to which we are going to
* exogenous variable. An exception is thrown if the name is not a * differentiate. */
* and exogenous variable. */ vector<int>
int name2outer_exo(const char* name) const; variables() const
/** Return the number of endogenous variables. */ {
int ny() const return der_atoms;
{return endovars.size();} }
/** Return the number of exogenous variables. */ /** Return the endo_atoms_map. */
int nexo() const const vector<int> &
{return (int)exovars.size();} get_endo_atoms_map() const
/** Return the number of parameters. */ {
int np() const return endo_atoms_map;
{return (int)(params.size());} }
/** Register unique endogenous variable name. The order of /** Return the exo_atoms_map. */
* calls defines the endo outer ordering. The method is const vector<int> &
* virtual, since a superclass may want to do some additional get_exo_atoms_map() const
* action. */ {
virtual void register_uniq_endo(const char* name); return endo_atoms_map;
/** Register unique exogenous variable name. The order of }
* calls defines the exo outer ordering. The method is /** Return an index in the outer ordering of a given
* virtual, since a superclass may want to do somem additional * parameter. An exception is thrown if the name is not a
* action. */ * parameter. */
virtual void register_uniq_exo(const char* name); int name2outer_param(const char *name) const;
/** Register unique parameter name. The order of calls defines /** Return an index in the outer ordering of a given
* the param outer ordering. The method is * endogenous variable. An exception is thrown if the name is not a
* virtual, since a superclass may want to do somem additional * and endogenous variable. */
* action. */ int name2outer_endo(const char *name) const;
virtual void register_uniq_param(const char* name); /** Return an index in the outer ordering of a given
/** Debug print. */ * exogenous variable. An exception is thrown if the name is not a
void print() const; * and exogenous variable. */
private: int name2outer_exo(const char *name) const;
/** Add endogenous variable name, which is already in the name /** Return the number of endogenous variables. */
* storage. */ int
void register_endo(const char* name); ny() const
/** Add exogenous variable name, which is already in the name {
* storage. */ return endovars.size();
void register_exo(const char* name); }
/** Add parameter name, which is already in the name /** Return the number of exogenous variables. */
* storage. */ int
void register_param(const char* name); nexo() const
}; {
return (int) exovars.size();
}
/** Return the number of parameters. */
int
np() const
{
return (int) (params.size());
}
/** Register unique endogenous variable name. The order of
* calls defines the endo outer ordering. The method is
* virtual, since a superclass may want to do some additional
* action. */
virtual void register_uniq_endo(const char *name);
/** Register unique exogenous variable name. The order of
* calls defines the exo outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_exo(const char *name);
/** Register unique parameter name. The order of calls defines
* the param outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_param(const char *name);
/** Debug print. */
void print() const;
private:
/** Add endogenous variable name, which is already in the name
* storage. */
void register_endo(const char *name);
/** Add exogenous variable name, which is already in the name
* storage. */
void register_exo(const char *name);
/** Add parameter name, which is already in the name
* storage. */
void register_param(const char *name);
};
}; };

View File

@ -10,442 +10,511 @@
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <cstdio> #include <cstdio>
namespace ogp { namespace ogp
{
using boost::unordered_set; using boost::unordered_set;
using boost::unordered_map; using boost::unordered_map;
using std::vector; using std::vector;
using std::set; using std::set;
using std::map; using std::map;
/** Enumerator representing nulary, unary and binary operation /** Enumerator representing nulary, unary and binary operation
* codes. For nulary, 'none' is used. When one is adding a new * codes. For nulary, 'none' is used. When one is adding a new
* codes, he should update the code of #OperationTree::add_unary, * codes, he should update the code of #OperationTree::add_unary,
* #OperationTree::add_binary, and of course * #OperationTree::add_binary, and of course
* #OperationTree::add_derivative. */ * #OperationTree::add_derivative. */
enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER}; ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
/** Class representing a nulary, unary, or binary operation. */ /** Class representing a nulary, unary, or binary operation. */
class Operation { class Operation
protected: {
/** Code of the operation. */ protected:
code_t code; /** Code of the operation. */
/** First operand. If none, then it is -1. */ code_t code;
int op1; /** First operand. If none, then it is -1. */
/** Second operand. If none, then it is -1. */ int op1;
int op2; /** Second operand. If none, then it is -1. */
int op2;
public: public:
/** Constructs a binary operation. */ /** Constructs a binary operation. */
Operation(code_t cd, int oper1, int oper2) Operation(code_t cd, int oper1, int oper2)
: code(cd), op1(oper1), op2(oper2) {} : code(cd), op1(oper1), op2(oper2)
/** Constructs a unary operation. */ {
Operation(code_t cd, int oper1) }
: code(cd), op1(oper1), op2(-1) {} /** Constructs a unary operation. */
/** Constructs a nulary operation. */ Operation(code_t cd, int oper1)
Operation() : code(cd), op1(oper1), op2(-1)
: code(NONE), op1(-1), op2(-1) {} {
/** A copy constructor. */ }
Operation(const Operation& op) /** Constructs a nulary operation. */
: code(op.code), op1(op.op1), op2(op.op2) {} Operation()
: code(NONE), op1(-1), op2(-1)
{
}
/** A copy constructor. */
Operation(const Operation &op)
: code(op.code), op1(op.op1), op2(op.op2)
{
}
/** Operator =. */ /** Operator =. */
const Operation& operator=(const Operation& op) const Operation &
{ operator=(const Operation &op)
code = op.code; {
op1 = op.op1; code = op.code;
op2 = op.op2; op1 = op.op1;
return *this; op2 = op.op2;
} return *this;
/** Operator ==. */ }
bool operator==(const Operation& op) const /** Operator ==. */
{ bool
return code == op.code && op1 == op.op1 && op2 == op.op2; operator==(const Operation &op) const
} {
/** Operator < implementing lexicographic ordering. */ return code == op.code && op1 == op.op1 && op2 == op.op2;
bool operator<(const Operation& op) const }
{ /** Operator < implementing lexicographic ordering. */
return (code < op.code || bool
code == op.code && operator<(const Operation &op) const
(op1 < op.op1 || op1 == op.op1 && op2 < op.op2)); {
} return (code < op.code
/** Returns a number of operands. */ || code == op.code
int nary() const && (op1 < op.op1 || op1 == op.op1 && op2 < op.op2));
{ }
return (op2 == -1)? ((op1 == -1) ? 0 : 1) : 2; /** Returns a number of operands. */
} int
/** Returns a hash value of the operation. */ nary() const
size_t hashval() const {
{ return (op2 == -1) ? ((op1 == -1) ? 0 : 1) : 2;
return op2+1 + (op1+1)^15 + code^30; }
} /** Returns a hash value of the operation. */
size_t
hashval() const
{
return op2+1 + (op1+1)^15 + code^30;
}
code_t getCode() const code_t
{ return code; } getCode() const
int getOp1() const {
{ return op1; } return code;
int getOp2() const }
{ return op2; } int
getOp1() const
{
return op1;
}
int
getOp2() const
{
return op2;
}
}; };
/** This struct is a predicate for ordering of the operations in /** This struct is a predicate for ordering of the operations in
* OperationTree class. now obsolete */ * OperationTree class. now obsolete */
struct ltoper { struct ltoper
bool operator()(const Operation& oper1, const Operation& oper2) const {
{return oper1 < oper2;} bool
}; operator()(const Operation &oper1, const Operation &oper2) const
{
return oper1 < oper2;
}
};
/** Hash function object for Operation. */ /** Hash function object for Operation. */
struct ophash { struct ophash
size_t operator()(const Operation& op) const {
{ return op.hashval(); } size_t
}; operator()(const Operation &op) const
{
return op.hashval();
}
};
/** This struct is a function object selecting some /** This struct is a function object selecting some
* operations. The operation is given by a tree index. */ * operations. The operation is given by a tree index. */
struct opselector { struct opselector
virtual bool operator()(int t) const = 0; {
virtual ~opselector() {} virtual bool operator()(int t) const = 0;
}; virtual ~opselector()
{
}
};
/** Forward declaration of OperationFormatter. */ /** Forward declaration of OperationFormatter. */
class OperationFormatter; class OperationFormatter;
class DefaultOperationFormatter; class DefaultOperationFormatter;
/** Forward declaration of EvalTree to make it friend of OperationTree. */ /** Forward declaration of EvalTree to make it friend of OperationTree. */
class EvalTree; class EvalTree;
/** Class representing a set of trees for terms. Each term is /** Class representing a set of trees for terms. Each term is
* given a unique non-negative integer. The terms are basically * given a unique non-negative integer. The terms are basically
* operations whose (integer) operands point to another terms in * operations whose (integer) operands point to another terms in
* the tree. The terms are stored in the vector. Equivalent unary * the tree. The terms are stored in the vector. Equivalent unary
* and binary terms are stored only once. This class guarantees * and binary terms are stored only once. This class guarantees
* the uniqueness. The uniqueness of nulary terms is guaranteed by * the uniqueness. The uniqueness of nulary terms is guaranteed by
* the caller, since at this level of Operation abstraction, one * the caller, since at this level of Operation abstraction, one
* cannot discriminate between different nulary operations * cannot discriminate between different nulary operations
* (constants, variables). The uniqueness is enforced by the * (constants, variables). The uniqueness is enforced by the
* unordered_map whose keys are operations and values are integers * unordered_map whose keys are operations and values are integers
* (indices of the terms). * (indices of the terms).
* This class can also make derivatives of a given term with * This class can also make derivatives of a given term with
* respect to a given nulary term. I order to be able to quickly * respect to a given nulary term. I order to be able to quickly
* recognize zero derivativates, we maintain a list of nulary * recognize zero derivativates, we maintain a list of nulary
* terms contained in the term. A possible zero derivative is then quickly * terms contained in the term. A possible zero derivative is then quickly
* recognized by looking at the list. The list is implemented as a * recognized by looking at the list. The list is implemented as a
* unordered_set of integers. * unordered_set of integers.
* *
* In addition, many term can be differentiated multiple times wrt * In addition, many term can be differentiated multiple times wrt
* one variable since they can be referenced multiple times. To * one variable since they can be referenced multiple times. To
* avoid this, for each term we maintain a map mapping variables * avoid this, for each term we maintain a map mapping variables
* to the derivatives of the term. As the caller will * to the derivatives of the term. As the caller will
* differentiate wrt more and more variables, these maps will * differentiate wrt more and more variables, these maps will
* become richer and richer. * become richer and richer.
*/ */
class OperationTree { class OperationTree
friend class EvalTree; {
friend class DefaultOperationFormatter; friend class EvalTree;
protected: friend class DefaultOperationFormatter;
/** This is the vector of the terms. An index to this vector protected:
* uniquelly determines the term. */ /** This is the vector of the terms. An index to this vector
vector<Operation> terms; * uniquelly determines the term. */
vector<Operation> terms;
/** This defines a type for a map mapping the unary and binary /** This defines a type for a map mapping the unary and binary
* operations to their indices. */ * operations to their indices. */
typedef unordered_map<Operation, int, ophash> _Topmap; typedef unordered_map<Operation, int, ophash> _Topmap;
typedef _Topmap::value_type _Topval; typedef _Topmap::value_type _Topval;
/** This is the map mapping the unary and binary operations to /** This is the map mapping the unary and binary operations to
* the indices of the terms.*/ * the indices of the terms.*/
_Topmap opmap; _Topmap opmap;
/** This is a type for a set of integers. */ /** This is a type for a set of integers. */
typedef unordered_set<int> _Tintset; typedef unordered_set<int> _Tintset;
/** This is a vector of integer sets corresponding to the /** This is a vector of integer sets corresponding to the
* nulary terms contained in the term. */ * nulary terms contained in the term. */
vector<_Tintset> nul_incidence; vector<_Tintset> nul_incidence;
/** This is a type of the map from variables (nulary terms) to /** This is a type of the map from variables (nulary terms) to
* the terms. */ * the terms. */
typedef unordered_map<int, int> _Tderivmap; typedef unordered_map<int, int> _Tderivmap;
/** This is a vector of derivative mappings. For each term, it /** This is a vector of derivative mappings. For each term, it
* maps variables to the derivatives of the term with respect * maps variables to the derivatives of the term with respect
* to the variables. */ * to the variables. */
vector<_Tderivmap> derivatives; vector<_Tderivmap> derivatives;
/** The tree index of the last nulary term. */ /** The tree index of the last nulary term. */
int last_nulary; int last_nulary;
public: public:
/** This is a number of constants set in the following /** This is a number of constants set in the following
* enum. This number reserves space in a vector of terms for * enum. This number reserves space in a vector of terms for
* the constants. */ * the constants. */
static const int num_constants = 4; static const int num_constants = 4;
/** Enumeration for special terms. We need zero, one, nan and /** Enumeration for special terms. We need zero, one, nan and
* 2/pi. These will be always first four terms having indices * 2/pi. These will be always first four terms having indices
* zero, one and two, three. If adding anything to this * zero, one and two, three. If adding anything to this
* enumeration, make sure you have updated num_constants above.*/ * enumeration, make sure you have updated num_constants above.*/
enum {zero=0, one=1, nan=2, two_over_pi=3}; enum {zero = 0, one = 1, nan = 2, two_over_pi = 3};
/** The unique constructor which initializes the object to /** The unique constructor which initializes the object to
* contain only zero, one and nan and two_over_pi.*/ * contain only zero, one and nan and two_over_pi.*/
OperationTree(); OperationTree();
/** Copy constructor. */ /** Copy constructor. */
OperationTree(const OperationTree& ot) OperationTree(const OperationTree &ot)
: terms(ot.terms), opmap(ot.opmap), nul_incidence(ot.nul_incidence), : terms(ot.terms), opmap(ot.opmap), nul_incidence(ot.nul_incidence),
derivatives(ot.derivatives), derivatives(ot.derivatives),
last_nulary(ot.last_nulary) last_nulary(ot.last_nulary)
{} {
}
/** Add a nulary operation. The caller is responsible for not /** Add a nulary operation. The caller is responsible for not
* inserting two semantically equivalent nulary operations. * inserting two semantically equivalent nulary operations.
* @return newly allocated index * @return newly allocated index
*/ */
int add_nulary(); int add_nulary();
/** Add a unary operation. The uniqness is checked, if it /** Add a unary operation. The uniqness is checked, if it
* already exists, then it is not added. * already exists, then it is not added.
* @param code the code of the unary operation * @param code the code of the unary operation
* @param op the index of the operand * @param op the index of the operand
* @return the index of the operation * @return the index of the operation
*/ */
int add_unary(code_t code, int op); int add_unary(code_t code, int op);
/** Add a binary operation. The uniqueness is checked, if it /** Add a binary operation. The uniqueness is checked, if it
* already exists, then it is not added. * already exists, then it is not added.
* @param code the code of the binary operation * @param code the code of the binary operation
* @param op1 the index of the first operand * @param op1 the index of the first operand
* @param op2 the index of the second operand * @param op2 the index of the second operand
* @return the index of the operation * @return the index of the operation
*/ */
int add_binary(code_t code, int op1, int op2); int add_binary(code_t code, int op1, int op2);
/** Add the derivative of the given term with respect to the /** Add the derivative of the given term with respect to the
* given nulary operation. * given nulary operation.
* @param t the index of the operation being differentiated * @param t the index of the operation being differentiated
* @param v the index of the nulary operation * @param v the index of the nulary operation
* @return the index of the derivative * @return the index of the derivative
*/ */
int add_derivative(int t, int v); int add_derivative(int t, int v);
/** Add the substitution given by the map. This adds a new /** Add the substitution given by the map. This adds a new
* term which is equal to the given term with applied * term which is equal to the given term with applied
* substitutions given by the map replacing each term on the * substitutions given by the map replacing each term on the
* left by a term on the right. We do not check that the terms * left by a term on the right. We do not check that the terms
* on the left are not subterms of the terms on the right. If * on the left are not subterms of the terms on the right. If
* so, the substituted terms are not subject of further * so, the substituted terms are not subject of further
* substitution. */ * substitution. */
int add_substitution(int t, const map<int,int>& subst); int add_substitution(int t, const map<int, int> &subst);
/** Add the substitution given by the map where left sides of /** Add the substitution given by the map where left sides of
* substitutions come from another tree. The right sides are * substitutions come from another tree. The right sides are
* from this tree. The given t is from the given otree. */ * from this tree. The given t is from the given otree. */
int add_substitution(int t, const map<int,int>& subst, int add_substitution(int t, const map<int, int> &subst,
const OperationTree& otree); const OperationTree &otree);
/** This method turns the given term to a nulary /** This method turns the given term to a nulary
* operation. This is an only method, which changes already * operation. This is an only method, which changes already
* existing term (all other methods add something new). User * existing term (all other methods add something new). User
* should use this with caution and must make sure that * should use this with caution and must make sure that
* something similar has happened for atoms. In addition, it * something similar has happened for atoms. In addition, it
* does not do anything with derivatives, so it should not be * does not do anything with derivatives, so it should not be
* used after some derivatives were created, and derivatives * used after some derivatives were created, and derivatives
* already created and saved in derivatives mappings should be * already created and saved in derivatives mappings should be
* forgotten with forget_derivative_maps. */ * forgotten with forget_derivative_maps. */
void nularify(int t); void nularify(int t);
/** Return the set of nulary terms of the given term. */ /** Return the set of nulary terms of the given term. */
const unordered_set<int>& nulary_of_term(int t) const const unordered_set<int> &
{return nul_incidence[t];} nulary_of_term(int t) const
{
return nul_incidence[t];
}
/** Select subterms of the given term according a given /** Select subterms of the given term according a given
* operation selector and return the set of terms that * operation selector and return the set of terms that
* correspond to the compounded operations. The given term is * correspond to the compounded operations. The given term is
* a compound function of the returned subterms and the * a compound function of the returned subterms and the
* function consists only from operations which yield false in * function consists only from operations which yield false in
* the selector. */ * the selector. */
unordered_set<int> select_terms(int t, const opselector& sel) const; unordered_set<int> select_terms(int t, const opselector &sel) const;
/** Select subterms of the given term according a given /** Select subterms of the given term according a given
* operation selector and return the set of terms that * operation selector and return the set of terms that
* correspond to the compounded operations. The given term is * correspond to the compounded operations. The given term is
* a compound function of the returned subterms and the * a compound function of the returned subterms and the
* subterms are maximal subterms consisting from operations * subterms are maximal subterms consisting from operations
* yielding true in the selector. */ * yielding true in the selector. */
unordered_set<int> select_terms_inv(int t, const opselector& sel) const; unordered_set<int> select_terms_inv(int t, const opselector &sel) const;
/** This forgets all the derivative mappings. It is used after /** This forgets all the derivative mappings. It is used after
* a term has been nularified, and then the derivative * a term has been nularified, and then the derivative
* mappings carry wrong information. Note that the derivatives * mappings carry wrong information. Note that the derivatives
* mappings serve only as a tool for quick returns in * mappings serve only as a tool for quick returns in
* add_derivative. Resseting the mappings is harmless, all the * add_derivative. Resseting the mappings is harmless, all the
* information is rebuilt in add_derivative without any * information is rebuilt in add_derivative without any
* additional nodes (trees). */ * additional nodes (trees). */
void forget_derivative_maps(); void forget_derivative_maps();
/** This returns an operation of a given term. */ /** This returns an operation of a given term. */
const Operation& operation(int t) const const Operation &
{return terms[t];} operation(int t) const
{
return terms[t];
}
/** This outputs the operation to the given file descriptor /** This outputs the operation to the given file descriptor
* using the given OperationFormatter. */ * using the given OperationFormatter. */
void print_operation_tree(int t, FILE* fd, OperationFormatter& f) const; void print_operation_tree(int t, FILE *fd, OperationFormatter &f) const;
/** Debug print of a given operation: */ /** Debug print of a given operation: */
void print_operation(int t) const; void print_operation(int t) const;
/** Return the last tree index of a nulary term. */ /** Return the last tree index of a nulary term. */
int get_last_nulary() const int
{return last_nulary;} get_last_nulary() const
{
return last_nulary;
}
/** Get the number of all operations. */ /** Get the number of all operations. */
int get_num_op() const int
{return (int)(terms.size());} get_num_op() const
private: {
/** This registers a calculated derivative of the term in the return (int) (terms.size());
* #derivatives vector. }
* @param t the index of the term for which we register the derivative private:
* @param v the index of the nulary term (variable) to which /** This registers a calculated derivative of the term in the
* respect the derivative was taken * #derivatives vector.
* @param tder the index of the resulting derivative * @param t the index of the term for which we register the derivative
*/ * @param v the index of the nulary term (variable) to which
void register_derivative(int t, int v, int tder); * respect the derivative was taken
/** This does the same job as select_terms with the only * @param tder the index of the resulting derivative
* difference, that it adds the terms to the given set and */
* hence can be used recursivelly. */ void register_derivative(int t, int v, int tder);
void select_terms(int t, const opselector& sel, unordered_set<int>& subterms) const; /** This does the same job as select_terms with the only
/** This does the same job as select_terms_inv with the only * difference, that it adds the terms to the given set and
* difference, that it adds the terms to the given set and * hence can be used recursivelly. */
* hence can be used recursivelly and returns true if the term void select_terms(int t, const opselector &sel, unordered_set<int> &subterms) const;
* was selected. */ /** This does the same job as select_terms_inv with the only
bool select_terms_inv(int t, const opselector& sel, unordered_set<int>& subterms) const; * difference, that it adds the terms to the given set and
/** This updates nul_incidence information after the term t * hence can be used recursivelly and returns true if the term
* was turned to a nulary term in all terms. It goes through * was selected. */
* the tree from simplest terms to teh more complex ones and bool select_terms_inv(int t, const opselector &sel, unordered_set<int> &subterms) const;
* changes the nul_incidence information where necesary. It /** This updates nul_incidence information after the term t
* maintains a set where the changes have been made.*/ * was turned to a nulary term in all terms. It goes through
void update_nul_incidence_after_nularify(int t); * the tree from simplest terms to teh more complex ones and
}; * changes the nul_incidence information where necesary. It
* maintains a set where the changes have been made.*/
void update_nul_incidence_after_nularify(int t);
};
/** EvalTree class allows for an evaluation of the given tree for /** EvalTree class allows for an evaluation of the given tree for
* a given values of nulary terms. For each term in the * a given values of nulary terms. For each term in the
* OperationTree the class maintains a resulting value and a flag * OperationTree the class maintains a resulting value and a flag
* if the value has been calculated or set. The life cycle of the * if the value has been calculated or set. The life cycle of the
* class is the following: After it is initialized, the user must * class is the following: After it is initialized, the user must
* set values for necessary nulary terms. Then the object can be * set values for necessary nulary terms. Then the object can be
* requested to evaluate particular terms. During this process, * requested to evaluate particular terms. During this process,
* the number of evaluated terms is increasing. Then the user can * the number of evaluated terms is increasing. Then the user can
* request overall reset of evaluation flags, set the nulary terms * request overall reset of evaluation flags, set the nulary terms
* to new values and evaluate a number of terms. * to new values and evaluate a number of terms.
* *
* Note that currently the user cannot request a reset of * Note that currently the user cannot request a reset of
* evaluation flags only for those terms depending on a given * evaluation flags only for those terms depending on a given
* nulary term. This might be added in future and handeled by a * nulary term. This might be added in future and handeled by a
* subclasses of OperationTree and EvalTree, since we need a * subclasses of OperationTree and EvalTree, since we need a
* support for this in OperationTree. * support for this in OperationTree.
*/ */
class EvalTree { class EvalTree
protected: {
/** Reference to the OperationTree over which all evaluations protected:
* are done. */ /** Reference to the OperationTree over which all evaluations
const OperationTree& otree; * are done. */
/** The array of values. */ const OperationTree &otree;
double* const values; /** The array of values. */
/** The array of evaluation flags. */ double *const values;
bool* const flags; /** The array of evaluation flags. */
/** The index of last operation in the EvalTree. Length of bool *const flags;
* values and flags will be then last_operation+1. */ /** The index of last operation in the EvalTree. Length of
int last_operation; * values and flags will be then last_operation+1. */
public: int last_operation;
/** Initializes the evaluation tree for the given operation public:
* tree. If last is greater than -1, that the evaluation tree /** Initializes the evaluation tree for the given operation
* will contain only formulas up to the given last index * tree. If last is greater than -1, that the evaluation tree
* (included). */ * will contain only formulas up to the given last index
EvalTree(const OperationTree& otree, int last = -1); * (included). */
virtual ~EvalTree() EvalTree(const OperationTree &otree, int last = -1);
{ delete [] values; delete [] flags; } virtual ~EvalTree()
/** Set evaluation flag to all terms (besides the first {
* special terms) to false. */ delete [] values; delete [] flags;
void reset_all(); }
/** Set value for a given nulary term. */ /** Set evaluation flag to all terms (besides the first
void set_nulary(int t, double val); * special terms) to false. */
/** Evaluate the given term with nulary terms set so far. */ void reset_all();
double eval(int t); /** Set value for a given nulary term. */
/** Debug print. */ void set_nulary(int t, double val);
void print() const; /** Evaluate the given term with nulary terms set so far. */
/* Return the operation tree. */ double eval(int t);
const OperationTree& getOperationTree() const /** Debug print. */
{return otree;} void print() const;
private: /* Return the operation tree. */
EvalTree(const EvalTree&); const OperationTree &
}; getOperationTree() const
{
return otree;
}
private:
EvalTree(const EvalTree &);
};
/** This is an interface describing how a given operation is /** This is an interface describing how a given operation is
* formatted for output. */ * formatted for output. */
class OperationFormatter { class OperationFormatter
public: {
/** Empty virtual destructor. */ public:
virtual ~OperationFormatter() {} /** Empty virtual destructor. */
/** Print the formatted operation op with a given tree index t virtual ~OperationFormatter()
* to a given descriptor. (See class OperationTree to know {
* what is a tree index.) This prints all the tree. This }
* always writes equation, left hand side is a string /** Print the formatted operation op with a given tree index t
* represenation (a variable, temporary, whatever) of the * to a given descriptor. (See class OperationTree to know
* term, the right hand side is a string representation of the * what is a tree index.) This prints all the tree. This
* operation (which will refer to other string representation * always writes equation, left hand side is a string
* of subterms). */ * represenation (a variable, temporary, whatever) of the
virtual void format(const Operation& op, int t, FILE* fd)=0; * term, the right hand side is a string representation of the
}; * operation (which will refer to other string representation
* of subterms). */
virtual void format(const Operation &op, int t, FILE *fd) = 0;
};
/** The default formatter formats the formulas with a usual syntax /** The default formatter formats the formulas with a usual syntax
* (for example Matlab). A formatting of atoms and terms might be * (for example Matlab). A formatting of atoms and terms might be
* reimplemented by a subclass. In addition, during its life, the * reimplemented by a subclass. In addition, during its life, the
* object maintains a set of tree indices which have been output * object maintains a set of tree indices which have been output
* and they are not output any more. */ * and they are not output any more. */
class DefaultOperationFormatter : public OperationFormatter { class DefaultOperationFormatter : public OperationFormatter
protected: {
const OperationTree& otree; protected:
set<int> stop_set; const OperationTree &otree;
public: set<int> stop_set;
DefaultOperationFormatter(const OperationTree& ot) public:
: otree(ot) {} DefaultOperationFormatter(const OperationTree &ot)
/** Format the operation with the default syntax. */ : otree(ot)
void format(const Operation& op, int t, FILE* fd); {
/** This prints a string represenation of the given term, for }
* example 'tmp10' for term 10. In this implementation it /** Format the operation with the default syntax. */
* prints $10. */ void format(const Operation &op, int t, FILE *fd);
virtual void format_term(int t, FILE* fd) const; /** This prints a string represenation of the given term, for
/** Print a string representation of the nulary term. */ * example 'tmp10' for term 10. In this implementation it
virtual void format_nulary(int t, FILE* fd) const; * prints $10. */
/** Print a delimiter between two statements. By default it is virtual void format_term(int t, FILE *fd) const;
* "\n". */ /** Print a string representation of the nulary term. */
virtual void print_delim(FILE* fd) const; virtual void format_nulary(int t, FILE *fd) const;
}; /** Print a delimiter between two statements. By default it is
* "\n". */
virtual void print_delim(FILE *fd) const;
};
class NularyStringConvertor { class NularyStringConvertor
public: {
virtual ~NularyStringConvertor() {} public:
/** Return the string representation of the atom with the tree virtual ~NularyStringConvertor()
* index t. */ {
virtual std::string convert(int t) const = 0; }
}; /** Return the string representation of the atom with the tree
* index t. */
virtual std::string convert(int t) const = 0;
};
/** This class converts the given term to its mathematical string representation. */ /** This class converts the given term to its mathematical string representation. */
class OperationStringConvertor { class OperationStringConvertor
protected: {
const NularyStringConvertor& nulsc; protected:
const OperationTree& otree; const NularyStringConvertor &nulsc;
public: const OperationTree &otree;
OperationStringConvertor(const NularyStringConvertor& nsc, const OperationTree& ot) public:
: nulsc(nsc), otree(ot) {} OperationStringConvertor(const NularyStringConvertor &nsc, const OperationTree &ot)
/** Empty virtual destructor. */ : nulsc(nsc), otree(ot)
virtual ~OperationStringConvertor() {} {
/** Convert the operation to the string mathematical }
* representation. This does not write any equation, just /** Empty virtual destructor. */
* returns a string representation of the formula. */ virtual ~OperationStringConvertor()
std::string convert(const Operation& op, int t) const; {
}; }
/** Convert the operation to the string mathematical
* representation. This does not write any equation, just
* returns a string representation of the formula. */
std::string convert(const Operation &op, int t) const;
};
}; };
#endif #endif

View File

@ -18,175 +18,286 @@
class Dynare; class Dynare;
class DynareNameList : public NameList { class DynareNameList : public NameList
vector<const char*> names; {
vector<const char *> names;
public: public:
DynareNameList(const Dynare& dynare); DynareNameList(const Dynare &dynare);
int getNum() const int
{return (int)names.size();} getNum() const
const char* getName(int i) const {
{return names[i];} return (int) names.size();
/** This for each string of the input vector calculates its index }
* in the names. And returns the resulting vector of indices. If const char *
* the name cannot be found, then an exception is raised. */ getName(int i) const
vector<int> selectIndices(const vector<const char*>& ns) const; {
return names[i];
}
/** This for each string of the input vector calculates its index
* in the names. And returns the resulting vector of indices. If
* the name cannot be found, then an exception is raised. */
vector<int> selectIndices(const vector<const char *> &ns) const;
}; };
class DynareExogNameList : public NameList { class DynareExogNameList : public NameList
vector<const char*> names; {
vector<const char *> names;
public: public:
DynareExogNameList(const Dynare& dynare); DynareExogNameList(const Dynare &dynare);
int getNum() const int
{return (int)names.size();} getNum() const
const char* getName(int i) const {
{return names[i];} return (int) names.size();
}
const char *
getName(int i) const
{
return names[i];
}
}; };
class DynareStateNameList : public NameList { class DynareStateNameList : public NameList
vector<const char*> names; {
vector<const char *> names;
public: public:
DynareStateNameList(const Dynare& dynare, const DynareNameList& dnl, DynareStateNameList(const Dynare &dynare, const DynareNameList &dnl,
const DynareExogNameList& denl); const DynareExogNameList &denl);
int getNum() const int
{return (int)names.size();} getNum() const
const char* getName(int i) const {
{return names[i];} return (int) names.size();
}
const char *
getName(int i) const
{
return names[i];
}
}; };
// The following only implements DynamicModel with help of ogdyn::DynareModel // The following only implements DynamicModel with help of ogdyn::DynareModel
class DynareJacobian; class DynareJacobian;
class Dynare : public DynamicModel { class Dynare : public DynamicModel
friend class DynareNameList; {
friend class DynareExogNameList; friend class DynareNameList;
friend class DynareStateNameList; friend class DynareExogNameList;
friend class DynareJacobian; friend class DynareStateNameList;
Journal& journal; friend class DynareJacobian;
ogdyn::DynareModel* model; Journal &journal;
Vector* ysteady; ogdyn::DynareModel *model;
TensorContainer<FSSparseTensor> md; Vector *ysteady;
DynareNameList* dnl; TensorContainer<FSSparseTensor> md;
DynareExogNameList* denl; DynareNameList *dnl;
DynareStateNameList* dsnl; DynareExogNameList *denl;
ogp::FormulaEvaluator* fe; DynareStateNameList *dsnl;
ogp::FormulaDerEvaluator* fde; ogp::FormulaEvaluator *fe;
const double ss_tol; ogp::FormulaDerEvaluator *fde;
const double ss_tol;
public: public:
/** Parses the given model file and uses the given order to /** Parses the given model file and uses the given order to
* override order from the model file (if it is != -1). */ * override order from the model file (if it is != -1). */
Dynare(const char* modname, int ord, double sstol, Journal& jr); Dynare(const char *modname, int ord, double sstol, Journal &jr);
/** Parses the given equations with explicitly given names. */ /** Parses the given equations with explicitly given names. */
Dynare(const char** endo, int num_endo, Dynare(const char **endo, int num_endo,
const char** exo, int num_exo, const char **exo, int num_exo,
const char** par, int num_par, const char **par, int num_par,
const char* equations, int len, int ord, const char *equations, int len, int ord,
double sstol, Journal& jr); double sstol, Journal &jr);
/** Makes a deep copy of the object. */ /** Makes a deep copy of the object. */
Dynare(const Dynare& dyn); Dynare(const Dynare &dyn);
DynamicModel* clone() const DynamicModel *
{return new Dynare(*this);} clone() const
virtual ~Dynare(); {
int nstat() const return new Dynare(*this);
{return model->getAtoms().nstat();} }
int nboth() const virtual
{return model->getAtoms().nboth();} ~Dynare();
int npred() const int
{return model->getAtoms().npred();} nstat() const
int nforw() const {
{return model->getAtoms().nforw();} return model->getAtoms().nstat();
int nexog() const }
{return model->getAtoms().nexo();} int
int nys() const nboth() const
{return model->getAtoms().nys();} {
int nyss() const return model->getAtoms().nboth();
{return model->getAtoms().nyss();} }
int ny() const int
{return model->getAtoms().ny();} npred() const
int order() const {
{return model->getOrder();} return model->getAtoms().npred();
}
int
nforw() const
{
return model->getAtoms().nforw();
}
int
nexog() const
{
return model->getAtoms().nexo();
}
int
nys() const
{
return model->getAtoms().nys();
}
int
nyss() const
{
return model->getAtoms().nyss();
}
int
ny() const
{
return model->getAtoms().ny();
}
int
order() const
{
return model->getOrder();
}
const NameList& getAllEndoNames() const const NameList &
{return *dnl;} getAllEndoNames() const
const NameList& getStateNames() const {
{return *dsnl;} return *dnl;
const NameList& getExogNames() const }
{return *denl;} const NameList &
getStateNames() const
{
return *dsnl;
}
const NameList &
getExogNames() const
{
return *denl;
}
TwoDMatrix& getVcov() TwoDMatrix &
{return model->getVcov();} getVcov()
const TwoDMatrix& getVcov() const {
{return model->getVcov();} return model->getVcov();
Vector& getParams() }
{return model->getParams();} const TwoDMatrix &
const Vector& getParams() const getVcov() const
{return model->getParams();} {
void setInitOuter(const Vector& x) return model->getVcov();
{model->setInitOuter(x);} }
Vector &
getParams()
{
return model->getParams();
}
const Vector &
getParams() const
{
return model->getParams();
}
void
setInitOuter(const Vector &x)
{
model->setInitOuter(x);
}
const TensorContainer<FSSparseTensor>& getModelDerivatives() const const TensorContainer<FSSparseTensor> &
{return md;} getModelDerivatives() const
const Vector& getSteady() const {
{return *ysteady;} return md;
Vector& getSteady() }
{return *ysteady;} const Vector &
const ogdyn::DynareModel& getModel() const getSteady() const
{return *model;} {
return *ysteady;
}
Vector &
getSteady()
{
return *ysteady;
}
const ogdyn::DynareModel &
getModel() const
{
return *model;
}
// here is true public interface // here is true public interface
void solveDeterministicSteady(Vector& steady); void solveDeterministicSteady(Vector &steady);
void solveDeterministicSteady() void
{solveDeterministicSteady(*ysteady);} solveDeterministicSteady()
void evaluateSystem(Vector& out, const Vector& yy, const Vector& xx); {
void evaluateSystem(Vector& out, const Vector& yym, const Vector& yy, solveDeterministicSteady(*ysteady);
const Vector& yyp, const Vector& xx); }
void calcDerivatives(const Vector& yy, const Vector& xx); void evaluateSystem(Vector &out, const Vector &yy, const Vector &xx);
void calcDerivativesAtSteady(); void evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
const Vector &yyp, const Vector &xx);
void calcDerivatives(const Vector &yy, const Vector &xx);
void calcDerivativesAtSteady();
void writeMat(mat_t *fd, const char* prefix) const; void writeMat(mat_t *fd, const char *prefix) const;
void writeDump(const std::string& basename) const; void writeDump(const std::string &basename) const;
private: private:
void writeModelInfo(Journal& jr) const; void writeModelInfo(Journal &jr) const;
}; };
class DynareEvalLoader : public ogp::FormulaEvalLoader, public Vector { class DynareEvalLoader : public ogp::FormulaEvalLoader, public Vector
{
public: public:
DynareEvalLoader(const ogp::FineAtoms& a, Vector& out); DynareEvalLoader(const ogp::FineAtoms &a, Vector &out);
void load(int i, double res) void
{operator[](i) = res;} load(int i, double res)
{
operator[](i) = res;
}
}; };
class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader { class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader
{
protected: protected:
const ogp::FineAtoms& atoms; const ogp::FineAtoms &atoms;
TensorContainer<FSSparseTensor>& md; TensorContainer<FSSparseTensor> &md;
public: public:
DynareDerEvalLoader(const ogp::FineAtoms& a, TensorContainer<FSSparseTensor>& mod_ders, DynareDerEvalLoader(const ogp::FineAtoms &a, TensorContainer<FSSparseTensor> &mod_ders,
int order); int order);
void load(int i, int iord, const int* vars, double res); void load(int i, int iord, const int *vars, double res);
}; };
class DynareJacobian : public ogu::Jacobian, public ogp::FormulaDerEvalLoader { class DynareJacobian : public ogu::Jacobian, public ogp::FormulaDerEvalLoader
{
protected: protected:
Dynare& d; Dynare &d;
public: public:
DynareJacobian(Dynare& dyn); DynareJacobian(Dynare &dyn);
virtual ~DynareJacobian() {} virtual ~DynareJacobian()
void load(int i, int iord, const int* vars, double res); {
void eval(const Vector& in); }
void load(int i, int iord, const int *vars, double res);
void eval(const Vector &in);
}; };
class DynareVectorFunction : public ogu::VectorFunction { class DynareVectorFunction : public ogu::VectorFunction
{
protected: protected:
Dynare& d; Dynare &d;
public: public:
DynareVectorFunction(Dynare& dyn) DynareVectorFunction(Dynare &dyn)
: d(dyn) {} : d(dyn)
virtual ~DynareVectorFunction() {} {
int inDim() const }
{return d.ny();} virtual ~DynareVectorFunction()
int outDim() const {
{return d.ny();} }
void eval(const ConstVector& in, Vector& out); int
inDim() const
{
return d.ny();
}
int
outDim() const
{
return d.ny();
}
void eval(const ConstVector &in, Vector &out);
}; };
#endif #endif

View File

@ -15,196 +15,222 @@
#include <map> #include <map>
#include <vector> #include <vector>
namespace ogdyn { namespace ogdyn
{
using std::map; using std::map;
using std::vector; using std::vector;
/** A definition of a type mapping a string to an integer. Used as /** A definition of a type mapping a string to an integer. Used as
* a substitution map, saying what names are substituted for what * a substitution map, saying what names are substituted for what
* expressions represented by tree indices. */ * expressions represented by tree indices. */
typedef map<const char*, int, ogp::ltstr> Tsubstmap; typedef map<const char *, int, ogp::ltstr> Tsubstmap;
class DynareStaticAtoms : public ogp::StaticAtoms { class DynareStaticAtoms : public ogp::StaticAtoms
public: {
DynareStaticAtoms() public:
: StaticAtoms() {} DynareStaticAtoms()
DynareStaticAtoms(const DynareStaticAtoms& a) : StaticAtoms()
: StaticAtoms(a) {} {
virtual ~DynareStaticAtoms() {} }
/** This registers a unique varname identifier. It throws an DynareStaticAtoms(const DynareStaticAtoms &a)
* exception if the variable name is duplicate. It checks the : StaticAtoms(a)
* uniqueness and then it calls StaticAtoms::register_name. */ {
void register_name(const char* name); }
protected: virtual ~DynareStaticAtoms()
/** This returns a tree index of the given variable, and if {
* the variable has not been registered, it throws an }
* exception. */ /** This registers a unique varname identifier. It throws an
int check_variable(const char* name) const; * exception if the variable name is duplicate. It checks the
}; * uniqueness and then it calls StaticAtoms::register_name. */
void register_name(const char *name);
protected:
/** This returns a tree index of the given variable, and if
* the variable has not been registered, it throws an
* exception. */
int check_variable(const char *name) const;
};
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor
{
public:
enum atype {endovar, exovar, param};
protected:
typedef map<const char *, atype, ogp::ltstr> Tatypemap;
/** The map assigining a type to each name. */
Tatypemap atom_type;
public:
DynareDynamicAtoms()
: ogp::SAtoms()
{
}
DynareDynamicAtoms(const DynareDynamicAtoms &dda);
virtual ~DynareDynamicAtoms()
{
}
/** This parses a variable of the forms: varname(+3),
* varname(3), varname, varname(-3), varname(0), varname(+0),
* varname(-0). */
virtual void parse_variable(const char *in, std::string &out, int &ll) const;
/** Registers unique name of endogenous variable. */
void register_uniq_endo(const char *name);
/** Registers unique name of exogenous variable. */
void register_uniq_exo(const char *name);
/** Registers unique name of parameter. */
void register_uniq_param(const char *name);
/** Return true if the name is a given type. */
bool is_type(const char *name, atype tp) const;
/** Debug print. */
void print() const;
/** Implement NularyStringConvertor::convert. */
std::string convert(int t) const;
};
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor { /** This class represents the atom values for dynare, where
public: * exogenous variables can occur only at time t, and endogenous at
enum atype {endovar, exovar, param}; * times t-1, t, and t+1. */
protected: class DynareAtomValues : public ogp::AtomValues
typedef map<const char*, atype, ogp::ltstr> Tatypemap; {
/** The map assigining a type to each name. */ protected:
Tatypemap atom_type; /** Reference to the atoms (we suppose that they are only at
public: * t-1,t,t+1. */
DynareDynamicAtoms() const ogp::FineAtoms &atoms;
: ogp::SAtoms() {} /** De facto reference to the values of parameters. */
DynareDynamicAtoms(const DynareDynamicAtoms& dda); const ConstVector paramvals;
virtual ~DynareDynamicAtoms() {} /** De facto reference to the values of endogenous at time t-1. Only
/** This parses a variable of the forms: varname(+3), * predetermined and both part. */
* varname(3), varname, varname(-3), varname(0), varname(+0), const ConstVector yym;
* varname(-0). */ /** De facto reference to the values of endogenous at time t. Ordering
virtual void parse_variable(const char* in, std::string& out, int& ll) const; * given by the atoms. */
/** Registers unique name of endogenous variable. */ const ConstVector yy;
void register_uniq_endo(const char* name); /** De facto reference to the values of endogenous at time t+1. Only
/** Registers unique name of exogenous variable. */ * both and forward looking part. */
void register_uniq_exo(const char* name); const ConstVector yyp;
/** Registers unique name of parameter. */ /** De facto reference to the values of exogenous at time t. */
void register_uniq_param(const char* name); const ConstVector xx;
/** Return true if the name is a given type. */ public:
bool is_type(const char* name, atype tp) const; DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &ym,
/** Debug print. */ const Vector &y, const Vector &yp, const Vector &x)
void print() const; : atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
/** Implement NularyStringConvertor::convert. */ {
std::string convert(int t) const; }
}; DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const ConstVector &ym,
const Vector &y, const ConstVector &yp, const Vector &x)
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
{
}
void setValues(ogp::EvalTree &et) const;
};
/** This class represents the atom values at the steady state. It
* makes only appropriate subvector yym and yyp of the y vector,
* makes a vector of zero exogenous variables and uses
* DynareAtomValues with more general interface. */
class DynareSteadyAtomValues : public ogp::AtomValues
{
protected:
/** Subvector of yy. */
const ConstVector yym;
/** Subvector of yy. */
const ConstVector yyp;
/** Vector of zeros for exogenous variables. */
Vector xx;
/** Atom values using this yym, yyp and xx. */
DynareAtomValues av;
public:
DynareSteadyAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &y)
: yym(y, a.nstat(), a.nys()),
yyp(y, a.nstat()+a.npred(), a.nyss()),
xx(a.nexo()),
av(a, pvals, yym, y, yyp, xx)
{
xx.zeros();
}
void
setValues(ogp::EvalTree &et) const
{
av.setValues(et);
}
};
/** This class represents the atom values for dynare, where class DynareStaticSteadyAtomValues : public ogp::AtomValues
* exogenous variables can occur only at time t, and endogenous at {
* times t-1, t, and t+1. */ protected:
class DynareAtomValues : public ogp::AtomValues { /** Reference to static atoms over which the tree, where the
protected: * values go, is defined. */
/** Reference to the atoms (we suppose that they are only at const ogp::StaticFineAtoms &atoms_static;
* t-1,t,t+1. */ /** Reference to dynamic atoms for which the class gets input
const ogp::FineAtoms& atoms; * data. */
/** De facto reference to the values of parameters. */ const ogp::FineAtoms &atoms;
const ConstVector paramvals; /** De facto reference to input data, this is a vector of
/** De facto reference to the values of endogenous at time t-1. Only * endogenous variables in internal ordering of the dynamic
* predetermined and both part. */ * atoms. */
const ConstVector yym; ConstVector yy;
/** De facto reference to the values of endogenous at time t. Ordering /** De facto reference to input parameters corresponding to
* given by the atoms. */ * ordering defined by the dynamic atoms. */
const ConstVector yy; ConstVector paramvals;
/** De facto reference to the values of endogenous at time t+1. Only public:
* both and forward looking part. */ /** Construct the object. */
const ConstVector yyp; DynareStaticSteadyAtomValues(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
/** De facto reference to the values of exogenous at time t. */ const Vector &pvals, const Vector &yyy)
const ConstVector xx; : atoms_static(sa),
public: atoms(a),
DynareAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const Vector& ym, yy(yyy),
const Vector& y, const Vector& yp, const Vector& x) paramvals(pvals)
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x) {} {
DynareAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const ConstVector& ym, }
const Vector& y, const ConstVector& yp, const Vector& x) /** Set the values to the tree defined over the static atoms. */
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x) {} void setValues(ogp::EvalTree &et) const;
void setValues(ogp::EvalTree& et) const; };
};
/** This class represents the atom values at the steady state. It /** This class takes a vector of endogenous variables and a
* makes only appropriate subvector yym and yyp of the y vector, * substitution map. It supposes that variables at the right hand
* makes a vector of zero exogenous variables and uses * sides of the substitutions are set in the endogenous vector. It
* DynareAtomValues with more general interface. */ * evaluates the substitutions and if the variables corresponding
class DynareSteadyAtomValues : public ogp::AtomValues { * to left hand sides are not set in the endogenous vector it sets
protected: * them to calculated values. If a variable is already set, it
/** Subvector of yy. */ * does not override its value. It has no methods, everything is
const ConstVector yym; * done in the constructor. */
/** Subvector of yy. */ class DynareSteadySubstitutions : public ogp::FormulaEvalLoader
const ConstVector yyp; {
/** Vector of zeros for exogenous variables. */ protected:
Vector xx; const ogp::FineAtoms &atoms;
/** Atom values using this yym, yyp and xx. */ public:
DynareAtomValues av; DynareSteadySubstitutions(const ogp::FineAtoms &a, const ogp::OperationTree &tree,
public: const Tsubstmap &subst,
DynareSteadyAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const Vector& y) const Vector &pvals, Vector &yy);
: yym(y, a.nstat(), a.nys()), void load(int i, double res);
yyp(y, a.nstat()+a.npred(), a.nyss()), protected:
xx(a.nexo()), Vector &y;
av(a, pvals, yym, y, yyp, xx) vector<const char *> left_hand_sides;
{xx.zeros();} vector<int> right_hand_sides;
void setValues(ogp::EvalTree& et) const };
{av.setValues(et);}
};
class DynareStaticSteadyAtomValues : public ogp::AtomValues { /** This class is a static version of DynareSteadySustitutions. It
protected: * works for static atoms and static tree and substitution map
/** Reference to static atoms over which the tree, where the * over the static tree. It also needs dynamic version of the
* values go, is defined. */ * atoms, since it defines ordering of the vectors pvals, and
const ogp::StaticFineAtoms& atoms_static; * yy. */
/** Reference to dynamic atoms for which the class gets input class DynareStaticSteadySubstitutions : public ogp::FormulaEvalLoader
* data. */ {
const ogp::FineAtoms& atoms; protected:
/** De facto reference to input data, this is a vector of const ogp::FineAtoms &atoms;
* endogenous variables in internal ordering of the dynamic const ogp::StaticFineAtoms &atoms_static;
* atoms. */ public:
ConstVector yy; DynareStaticSteadySubstitutions(const ogp::FineAtoms &a,
/** De facto reference to input parameters corresponding to const ogp::StaticFineAtoms &sa,
* ordering defined by the dynamic atoms. */ const ogp::OperationTree &tree,
ConstVector paramvals; const Tsubstmap &subst,
public: const Vector &pvals, Vector &yy);
/** Construct the object. */ void load(int i, double res);
DynareStaticSteadyAtomValues(const ogp::FineAtoms& a, const ogp::StaticFineAtoms& sa, protected:
const Vector& pvals, const Vector& yyy) Vector &y;
: atoms_static(sa), vector<const char *> left_hand_sides;
atoms(a), vector<int> right_hand_sides;
yy(yyy), };
paramvals(pvals) {}
/** Set the values to the tree defined over the static atoms. */
void setValues(ogp::EvalTree& et) const;
};
/** This class takes a vector of endogenous variables and a
* substitution map. It supposes that variables at the right hand
* sides of the substitutions are set in the endogenous vector. It
* evaluates the substitutions and if the variables corresponding
* to left hand sides are not set in the endogenous vector it sets
* them to calculated values. If a variable is already set, it
* does not override its value. It has no methods, everything is
* done in the constructor. */
class DynareSteadySubstitutions : public ogp::FormulaEvalLoader {
protected:
const ogp::FineAtoms& atoms;
public:
DynareSteadySubstitutions(const ogp::FineAtoms& a, const ogp::OperationTree& tree,
const Tsubstmap& subst,
const Vector& pvals, Vector& yy);
void load(int i, double res);
protected:
Vector& y;
vector<const char*> left_hand_sides;
vector<int> right_hand_sides;
};
/** This class is a static version of DynareSteadySustitutions. It
* works for static atoms and static tree and substitution map
* over the static tree. It also needs dynamic version of the
* atoms, since it defines ordering of the vectors pvals, and
* yy. */
class DynareStaticSteadySubstitutions : public ogp::FormulaEvalLoader {
protected:
const ogp::FineAtoms& atoms;
const ogp::StaticFineAtoms& atoms_static;
public:
DynareStaticSteadySubstitutions(const ogp::FineAtoms& a,
const ogp::StaticFineAtoms& sa,
const ogp::OperationTree& tree,
const Tsubstmap& subst,
const Vector& pvals, Vector& yy);
void load(int i, double res);
protected:
Vector& y;
vector<const char*> left_hand_sides;
vector<int> right_hand_sides;
};
}; };
#endif #endif
// Local Variables: // Local Variables:

View File

@ -7,31 +7,39 @@
#include <string> #include <string>
class DynareException { class DynareException
char* mes; {
char *mes;
public: public:
DynareException(const char* m, const char* fname, int line, int col) DynareException(const char *m, const char *fname, int line, int col)
{ {
mes = new char[strlen(m) + strlen(fname) + 100]; mes = new char[strlen(m) + strlen(fname) + 100];
sprintf(mes, "Parse error at %s, line %d, column %d: %s", fname, line, col, m); sprintf(mes, "Parse error at %s, line %d, column %d: %s", fname, line, col, m);
} }
DynareException(const char* fname, int line, const std::string& m) DynareException(const char *fname, int line, const std::string &m)
{ {
mes = new char[m.size() + strlen(fname) + 50]; mes = new char[m.size() + strlen(fname) + 50];
sprintf(mes, "%s:%d: %s", fname, line, m.c_str()); sprintf(mes, "%s:%d: %s", fname, line, m.c_str());
} }
DynareException(const char* m, int offset) DynareException(const char *m, int offset)
{ {
mes = new char[strlen(m) + 100]; mes = new char[strlen(m) + 100];
sprintf(mes, "Parse error in provided string at offset %d: %s", offset, m); sprintf(mes, "Parse error in provided string at offset %d: %s", offset, m);
} }
DynareException(const DynareException& e) DynareException(const DynareException &e)
: mes(new char[strlen(e.mes)+1]) : mes(new char[strlen(e.mes)+1])
{strcpy(mes, e.mes);} {
virtual ~DynareException() strcpy(mes, e.mes);
{delete [] mes;} }
const char* message() const virtual ~DynareException()
{return mes;} {
delete [] mes;
}
const char *
message() const
{
return mes;
}
}; };
#endif #endif

View File

@ -15,377 +15,463 @@
#include <map> #include <map>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
namespace ogdyn { namespace ogdyn
using boost::unordered_set; {
using std::map; using boost::unordered_set;
using std::map;
/** This represents an interval in a string by the pair of /** This represents an interval in a string by the pair of
* positions (including the first, excluding the second). A * positions (including the first, excluding the second). A
* position is given by the line and the column within the line * position is given by the line and the column within the line
* (both starting from 1). */ * (both starting from 1). */
struct PosInterval { struct PosInterval
int fl; {
int fc; int fl;
int ll; int fc;
int lc; int ll;
PosInterval() {} int lc;
PosInterval(int ifl, int ifc, int ill, int ilc) PosInterval()
: fl(ifl), fc(ifc), ll(ill), lc(ilc) {} {
const PosInterval& operator=(const PosInterval& pi) }
{fl = pi.fl; fc = pi.fc; ll = pi.ll; lc = pi.lc; return *this;} PosInterval(int ifl, int ifc, int ill, int ilc)
/** This returns the interval beginning and interval length : fl(ifl), fc(ifc), ll(ill), lc(ilc)
* within the given string. */ {
void translate(const char* beg, int len, const char*& ibeg, int& ilen) const; }
/** Debug print. */ const PosInterval &
void print() const operator=(const PosInterval &pi)
{printf("fl=%d fc=%d ll=%d lc=%d\n",fl,fc,ll,lc);} {
}; fl = pi.fl; fc = pi.fc; ll = pi.ll; lc = pi.lc; return *this;
}
/** This returns the interval beginning and interval length
* within the given string. */
void translate(const char *beg, int len, const char * &ibeg, int &ilen) const;
/** Debug print. */
void
print() const
{
printf("fl=%d fc=%d ll=%d lc=%d\n", fl, fc, ll, lc);
}
};
/** This class is basically a GeneralMatrix but is created from /** This class is basically a GeneralMatrix but is created from
* parsed matrix data. */ * parsed matrix data. */
class ParsedMatrix : public TwoDMatrix { class ParsedMatrix : public TwoDMatrix
public: {
/** Construct the object from the parsed data of ogp::MatrixParser. */ public:
ParsedMatrix(const ogp::MatrixParser& mp); /** Construct the object from the parsed data of ogp::MatrixParser. */
}; ParsedMatrix(const ogp::MatrixParser &mp);
};
class PlannerBuilder;
class PlannerInfo;
class ForwSubstBuilder;
class ForwSubstInfo;
class MultInitSS;
class ModelSSWriter;
class PlannerBuilder; /** A subclass is responsible for creating param_vals, init_vals,
class PlannerInfo; * and vcov_mat. */
class ForwSubstBuilder; class DynareModel
class ForwSubstInfo; {
class MultInitSS; friend class PlannerBuilder;
class ModelSSWriter; friend class ForwSubstBuilder;
friend class MultInitSS;
friend class ModelSSWriter;
protected:
/** All atoms for whole model. */
DynareDynamicAtoms atoms;
/** Parsed model equations. */
ogp::FormulaParser eqs;
/** Order of approximation. */
int order;
/** A vector of parameters values created by a subclass. It
* is stored with natural ordering (outer) of the parameters
* given by atoms. */
Vector *param_vals;
/** A vector of initial values created by a subclass. It is
* stored with internal ordering given by atoms. */
Vector *init_vals;
/** A matrix for vcov. It is created by a subclass. */
TwoDMatrix *vcov_mat;
/** Tree index of the planner objective. If there was no
* planner objective keyword, the value is set to -1. */
int t_plobjective;
/** Tree index of the planner discount. If there was no
* planner discount keyword, the value is set to -1. */
int t_pldiscount;
/** Pointer to PlannerBuilder, which is created only if the
* planner's FOC are added to the model. */
PlannerBuilder *pbuilder;
/** Pointer to an object which builds auxiliary variables and
* equations to rewrite a model containing multiple leads to
* an equivalent model having only +1 leads. */
ForwSubstBuilder *fbuilder;
/** Pointer to AtomSubstitutions which are created when the
* atoms are being substituted because of multiple lags
* etc. It uses also an old copy of atoms, which is
* created. */
ogp::AtomSubstitutions *atom_substs;
/** Pointer to a copy of original atoms before substitutions
* took place. */
ogp::SAtoms *old_atoms;
public:
/** Initializes the object to an empty state. */
DynareModel();
/** Construct a new deep copy. */
DynareModel(const DynareModel &dm);
virtual
~DynareModel();
virtual DynareModel *clone() const = 0;
const DynareDynamicAtoms &
getAtoms() const
{
return atoms;
}
const ogp::FormulaParser &
getParser() const
{
return eqs;
}
int
getOrder() const
{
return order;
}
/** Return the vector of parameter values. */
const Vector &
getParams() const
{
return *param_vals;
}
Vector &
getParams()
{
return *param_vals;
}
/** Return the vector of initial values of endo variables. */
const Vector &
getInit() const
{
return *init_vals;
}
Vector &
getInit()
{
return *init_vals;
}
/** Return the vcov matrix. */
const TwoDMatrix &
getVcov() const
{
return *vcov_mat;
}
TwoDMatrix &
getVcov()
{
return *vcov_mat;
}
/** Return planner info. */
const PlannerInfo *get_planner_info() const;
/** Return forward substitutions info. */
const ForwSubstInfo *get_forw_subst_info() const;
/** Return substitutions info. */
const ogp::SubstInfo *get_subst_info() const;
/** This sets initial values given in outer ordering. */
void setInitOuter(const Vector &x);
/** This returns true if the given term is a function of
* hardwired constants, numerical constants and parameters. */
bool is_constant_term(int t) const;
/** Debug print. */
void print() const;
/** Dump the model to the output stream. This includes
* variable declarations, parameter values, model code,
* initval, vcov and order. */
void dump_model(std::ostream &os) const;
protected:
/** Adds a name of endogenous, exogenous or a parameter. The
* sort is governed by the flag. See dynglob.y for values of
* the flag. This is used by a subclass when declaring the
* names. */
void add_name(const char *name, int flag);
/** This checks the model consistency. Thus includes: number
* of endo variables and number of equations, min and max lag
* of endogenous variables and occurrrences of exogenous
* variables. It throws an exception, if there is a problem. */
void check_model() const;
/** This shifts the given variable identified by the tree
* index in time. So if the given tree index represents a(+3)
* and the tshift is -4, the method returns tree index of the
* a(-1). If a(-1) doesn't exist, it is added to the tree. If
* it exists, its tree index is returned. If the tree index
* doesn't correspond to an endogenous nor exogenous variable,
* an exception is thrown. */
int variable_shift(int t, int tshift);
/** For the given set of atoms identified by tree indices and
* given time shift, this method returns a map mapping each
* variable in the given set to its time shifted variable. The
* map is passed through the reference and is cleared in the
* beginning. */
void variable_shift_map(const unordered_set<int> &a_set, int tshift,
map<int, int> &s_map);
/** This returns maximum lead and minimum lag of an endogenous
* or exogenous variable in the given term. If there are no
* endo or exo variables, than it returns the least integer as
* max lead and the greatest integer as min lag. */
void termspan(int t, int &mlead, int &mlag) const;
/** This function returns a set of non-linear subterms of the
* given term, these are terms whose linear combination
* constitutes the given term. */
unordered_set<int> get_nonlinear_subterms(int t) const;
/** This method assigns already used tree index of some term
* to the not-yet used atom name with the given lead/lag. In
* this way, all occurrences of term t are substituted with
* the atom name(ll). The method handles also rewriting
* operation tree including derivatives of the term t. */
void substitute_atom_for_term(const char *name, int ll, int t);
/** This performs a final job after the model is parsed. It
* creates the PlannerBuilder object if the planner's FOC are
* needed, then it creates ForwSubstBuilder handling multiple
* leads and finally it creates the substitution object saving
* old atoms and performs the substitutions. */
void final_job();
};
/** A subclass is responsible for creating param_vals, init_vals, /** This class constructs DynareModel from dynare++ model file. It
* and vcov_mat. */ * parses variable declarations, model equations, parameter
class DynareModel { * assignments, initval assignments, vcov matrix and order of
friend class PlannerBuilder; * approximation. */
friend class ForwSubstBuilder; class DynareParser : public DynareModel
friend class MultInitSS; {
friend class ModelSSWriter; protected:
protected: /** Static atoms for parameter assignments. */
/** All atoms for whole model. */ DynareStaticAtoms pa_atoms;
DynareDynamicAtoms atoms; /** Assignments for the parameters. */
/** Parsed model equations. */ ogp::AtomAssignings paramset;
ogp::FormulaParser eqs; /** Static atoms for initval assignments. */
/** Order of approximation. */ DynareStaticAtoms ia_atoms;
int order; /** Assignments for the initval. */
/** A vector of parameters values created by a subclass. It ogp::AtomAssignings initval;
* is stored with natural ordering (outer) of the parameters /** Matrix parser for vcov. */
* given by atoms. */ ogp::MatrixParser vcov;
Vector* param_vals; public:
/** A vector of initial values created by a subclass. It is /** This, in fact, creates DynareModel from the given string
* stored with internal ordering given by atoms. */ * of the given length corresponding to the Dynare++ model
Vector* init_vals; * file. If the given ord is not -1, then it overrides setting
/** A matrix for vcov. It is created by a subclass. */ * in the model file. */
TwoDMatrix* vcov_mat; DynareParser(const char *str, int len, int ord);
/** Tree index of the planner objective. If there was no DynareParser(const DynareParser &p);
* planner objective keyword, the value is set to -1. */ virtual
int t_plobjective; ~DynareParser();
/** Tree index of the planner discount. If there was no DynareModel *
* planner discount keyword, the value is set to -1. */ clone() const
int t_pldiscount; {
/** Pointer to PlannerBuilder, which is created only if the return new DynareParser(*this);
* planner's FOC are added to the model. */ }
PlannerBuilder* pbuilder; /** Adds a name of endogenous, exogenous or a parameter. This
/** Pointer to an object which builds auxiliary variables and * addss the name to the parent class DynareModel and also
* equations to rewrite a model containing multiple leads to * registers the name to either paramset, or initval. */
* an equivalent model having only +1 leads. */ void add_name(const char *name, int flag);
ForwSubstBuilder* fbuilder; /** Sets position of the model section. Called from
/** Pointer to AtomSubstitutions which are created when the * dynglob.y. */
* atoms are being substituted because of multiple lags void
* etc. It uses also an old copy of atoms, which is set_model_pos(int off1, int off2)
* created. */ {
ogp::AtomSubstitutions* atom_substs; model_beg = off1; model_end = off2;
/** Pointer to a copy of original atoms before substitutions }
* took place. */ /** Sets position of the section setting parameters. Called
ogp::SAtoms* old_atoms; * from dynglob.y. */
public: void
/** Initializes the object to an empty state. */ set_paramset_pos(int off1, int off2)
DynareModel(); {
/** Construct a new deep copy. */ paramset_beg = off1; paramset_end = off2;
DynareModel(const DynareModel& dm); }
virtual ~DynareModel(); /** Sets position of the initval section. Called from
virtual DynareModel* clone() const = 0; * dynglob.y. */
const DynareDynamicAtoms& getAtoms() const void
{return atoms;} set_initval_pos(int off1, int off2)
const ogp::FormulaParser& getParser() const {
{return eqs;} initval_beg = off1; initval_end = off2;
int getOrder() const }
{return order;} /** Sets position of the vcov section. Called from
/** Return the vector of parameter values. */ * dynglob.y. */
const Vector& getParams() const void
{return *param_vals;} set_vcov_pos(int off1, int off2)
Vector& getParams() {
{return *param_vals;} vcov_beg = off1; vcov_end = off2;
/** Return the vector of initial values of endo variables. */ }
const Vector& getInit() const /** Parser the given string as integer and set to as the
{return *init_vals;} * order. */
Vector& getInit() void
{return *init_vals;} set_order_pos(int off1, int off2)
/** Return the vcov matrix. */ {
const TwoDMatrix& getVcov() const order_beg = off1; order_end = off2;
{return *vcov_mat;} }
TwoDMatrix& getVcov() /** Sets position of the planner_objective section. Called
{return *vcov_mat;} * from dynglob.y. */
/** Return planner info. */ void
const PlannerInfo* get_planner_info() const; set_pl_objective_pos(int off1, int off2)
/** Return forward substitutions info. */ {
const ForwSubstInfo* get_forw_subst_info() const; plobjective_beg = off1; plobjective_end = off2;
/** Return substitutions info. */ }
const ogp::SubstInfo* get_subst_info() const; /** Sets position of the planner_discount section. Called from
/** This sets initial values given in outer ordering. */ * dynglob.y. */
void setInitOuter(const Vector& x); void
/** This returns true if the given term is a function of set_pl_discount_pos(int off1, int off2)
* hardwired constants, numerical constants and parameters. */ {
bool is_constant_term(int t) const; pldiscount_beg = off1; pldiscount_end = off2;
/** Debug print. */ }
void print() const; /** Processes a syntax error from bison. */
/** Dump the model to the output stream. This includes void error(const char *mes);
* variable declarations, parameter values, model code, /** Debug print. */
* initval, vcov and order. */ void print() const;
void dump_model(std::ostream& os) const; protected:
protected: void parse_glob(int length, const char *stream);
/** Adds a name of endogenous, exogenous or a parameter. The int parse_order(int length, const char *stream);
* sort is governed by the flag. See dynglob.y for values of int parse_pldiscount(int length, const char *stream);
* the flag. This is used by a subclass when declaring the /** Evaluate paramset assignings and set param_vals. */
* names. */ void calc_params();
void add_name(const char* name, int flag); /** Evaluate initval assignings and set init_vals. */
/** This checks the model consistency. Thus includes: number void calc_init();
* of endo variables and number of equations, min and max lag /** Do the final job. This includes building the planner
* of endogenous variables and occurrrences of exogenous * problem (if any) and substituting for multiple lags, and
* variables. It throws an exception, if there is a problem. */ * one period leads of exogenous variables, and calculating
void check_model() const; * initial guess of lagrange multipliers in the social planner
/** This shifts the given variable identified by the tree * problem. Precondtion: everything parsed and calculated
* index in time. So if the given tree index represents a(+3) * parameters, postcondition: calculated initvals vector and
* and the tshift is -4, the method returns tree index of the * parsing_finished for expanded vectors. */
* a(-1). If a(-1) doesn't exist, it is added to the tree. If void final_job();
* it exists, its tree index is returned. If the tree index private:
* doesn't correspond to an endogenous nor exogenous variable, int model_beg, model_end;
* an exception is thrown. */ int paramset_beg, paramset_end;
int variable_shift(int t, int tshift); int initval_beg, initval_end;
/** For the given set of atoms identified by tree indices and int vcov_beg, vcov_end;
* given time shift, this method returns a map mapping each int order_beg, order_end;
* variable in the given set to its time shifted variable. The int plobjective_beg, plobjective_end;
* map is passed through the reference and is cleared in the int pldiscount_beg, pldiscount_end;
* beginning. */ };
void variable_shift_map(const unordered_set<int>& a_set, int tshift,
map<int,int>& s_map);
/** This returns maximum lead and minimum lag of an endogenous
* or exogenous variable in the given term. If there are no
* endo or exo variables, than it returns the least integer as
* max lead and the greatest integer as min lag. */
void termspan(int t, int& mlead, int& mlag) const;
/** This function returns a set of non-linear subterms of the
* given term, these are terms whose linear combination
* constitutes the given term. */
unordered_set<int> get_nonlinear_subterms(int t) const;
/** This method assigns already used tree index of some term
* to the not-yet used atom name with the given lead/lag. In
* this way, all occurrences of term t are substituted with
* the atom name(ll). The method handles also rewriting
* operation tree including derivatives of the term t. */
void substitute_atom_for_term(const char* name, int ll, int t);
/** This performs a final job after the model is parsed. It
* creates the PlannerBuilder object if the planner's FOC are
* needed, then it creates ForwSubstBuilder handling multiple
* leads and finally it creates the substitution object saving
* old atoms and performs the substitutions. */
void final_job();
};
/** This class constructs DynareModel from dynare++ model file. It /** Semiparsed model. The equations are given by a string,
* parses variable declarations, model equations, parameter * everything other by C/C++ objects. The initial values are set
* assignments, initval assignments, vcov matrix and order of * manually after the creation of this object. This implies that
* approximation. */ * no automatic substitutions cannot be done here, which in turn
class DynareParser : public DynareModel { * implies that we cannot do here a social planner nor substitutions
protected: * of multiple lags. */
/** Static atoms for parameter assignments. */ class DynareSPModel : public DynareModel
DynareStaticAtoms pa_atoms; {
/** Assignments for the parameters. */ public:
ogp::AtomAssignings paramset; DynareSPModel(const char **endo, int num_endo,
/** Static atoms for initval assignments. */ const char **exo, int num_exo,
DynareStaticAtoms ia_atoms; const char **par, int num_par,
/** Assignments for the initval. */ const char *equations, int len, int ord);
ogp::AtomAssignings initval; DynareSPModel(const DynareSPModel &dm)
/** Matrix parser for vcov. */ : DynareModel(dm)
ogp::MatrixParser vcov; {
public: }
/** This, in fact, creates DynareModel from the given string ~DynareSPModel()
* of the given length corresponding to the Dynare++ model {
* file. If the given ord is not -1, then it overrides setting }
* in the model file. */ virtual DynareModel *
DynareParser(const char* str, int len, int ord); clone() const
DynareParser(const DynareParser& p); {
virtual ~DynareParser(); return new DynareSPModel(*this);
DynareModel* clone() const }
{return new DynareParser(*this);} };
/** Adds a name of endogenous, exogenous or a parameter. This
* addss the name to the parent class DynareModel and also
* registers the name to either paramset, or initval. */
void add_name(const char* name, int flag);
/** Sets position of the model section. Called from
* dynglob.y. */
void set_model_pos(int off1, int off2)
{model_beg = off1; model_end = off2;}
/** Sets position of the section setting parameters. Called
* from dynglob.y. */
void set_paramset_pos(int off1, int off2)
{paramset_beg = off1; paramset_end = off2;}
/** Sets position of the initval section. Called from
* dynglob.y. */
void set_initval_pos(int off1, int off2)
{initval_beg = off1; initval_end = off2;}
/** Sets position of the vcov section. Called from
* dynglob.y. */
void set_vcov_pos(int off1, int off2)
{vcov_beg = off1; vcov_end = off2;}
/** Parser the given string as integer and set to as the
* order. */
void set_order_pos(int off1, int off2)
{order_beg = off1; order_end = off2;}
/** Sets position of the planner_objective section. Called
* from dynglob.y. */
void set_pl_objective_pos(int off1, int off2)
{plobjective_beg = off1; plobjective_end = off2;}
/** Sets position of the planner_discount section. Called from
* dynglob.y. */
void set_pl_discount_pos(int off1, int off2)
{pldiscount_beg = off1; pldiscount_end = off2;}
/** Processes a syntax error from bison. */
void error(const char* mes);
/** Debug print. */
void print() const;
protected:
void parse_glob(int length, const char* stream);
int parse_order(int length, const char* stream);
int parse_pldiscount(int length, const char* stream);
/** Evaluate paramset assignings and set param_vals. */
void calc_params();
/** Evaluate initval assignings and set init_vals. */
void calc_init();
/** Do the final job. This includes building the planner
* problem (if any) and substituting for multiple lags, and
* one period leads of exogenous variables, and calculating
* initial guess of lagrange multipliers in the social planner
* problem. Precondtion: everything parsed and calculated
* parameters, postcondition: calculated initvals vector and
* parsing_finished for expanded vectors. */
void final_job();
private:
int model_beg, model_end;
int paramset_beg, paramset_end;
int initval_beg, initval_end;
int vcov_beg, vcov_end;
int order_beg, order_end;
int plobjective_beg, plobjective_end;
int pldiscount_beg, pldiscount_end;
};
/** Semiparsed model. The equations are given by a string, /** This class implements a selector of operations which correspond
* everything other by C/C++ objects. The initial values are set * to non-linear functions. This inherits from ogp::opselector and
* manually after the creation of this object. This implies that * is used to calculate non-linear subterms in
* no automatic substitutions cannot be done here, which in turn * DynareModel::get_nonlinear_subterms(). */
* implies that we cannot do here a social planner nor substitutions class NLSelector : public ogp::opselector
* of multiple lags. */ {
class DynareSPModel : public DynareModel { private:
public: const DynareModel &model;
DynareSPModel(const char** endo, int num_endo, public:
const char** exo, int num_exo, NLSelector(const DynareModel &m) : model(m)
const char** par, int num_par, {
const char* equations, int len, int ord); }
DynareSPModel(const DynareSPModel& dm) bool operator()(int t) const;
: DynareModel(dm) {} };
~DynareSPModel() {}
virtual DynareModel* clone() const
{return new DynareSPModel(*this);}
};
/** This class implements a selector of operations which correspond /** This class writes a mathematical code evaluating the system of
* to non-linear functions. This inherits from ogp::opselector and * equations and the first derivatives at zero shocks and at the
* is used to calculate non-linear subterms in * given (static) state. Static means that lags and leads are
* DynareModel::get_nonlinear_subterms(). */ * ignored. */
class NLSelector : public ogp::opselector { class ModelSSWriter : public ogp::DefaultOperationFormatter
private: {
const DynareModel& model; protected:
public: const DynareModel &model;
NLSelector(const DynareModel& m) : model(m) {} public:
bool operator()(int t) const; ModelSSWriter(const DynareModel &m)
}; : DefaultOperationFormatter(m.eqs.getTree()),
model(m)
{
}
/** This writes the evaluation of the system. It calls pure
* virtual methods for writing a preamble, then assignment of
* atoms, and then assignment for resulting object. These are
* language dependent and are implemented in the subclass. */
void write_der0(FILE *fd);
/** This writes the evaluation of the first order derivative of
the system. It calls pure virtual methods for writing a
preamble, assignment, and assignemnt of the resulting
objects. */
void write_der1(FILE *fd);
protected:
virtual void write_der0_preamble(FILE *fd) const = 0;
virtual void write_der1_preamble(FILE *fd) const = 0;
virtual void write_atom_assignment(FILE *fd) const = 0;
virtual void write_der0_assignment(FILE *fd) const = 0;
virtual void write_der1_assignment(FILE *fd) const = 0;
};
/** This class writes a mathematical code evaluating the system of class MatlabSSWriter : public ModelSSWriter
* equations and the first derivatives at zero shocks and at the {
* given (static) state. Static means that lags and leads are protected:
* ignored. */ /** Identifier used in function names. */
class ModelSSWriter : public ogp::DefaultOperationFormatter { char *id;
protected: public:
const DynareModel& model; MatlabSSWriter(const DynareModel &dm, const char *idd);
public: virtual ~MatlabSSWriter()
ModelSSWriter(const DynareModel& m) {
: DefaultOperationFormatter(m.eqs.getTree()), delete [] id;
model(m) {} }
/** This writes the evaluation of the system. It calls pure protected:
* virtual methods for writing a preamble, then assignment of // from ModelSSWriter
* atoms, and then assignment for resulting object. These are void write_der0_preamble(FILE *fd) const;
* language dependent and are implemented in the subclass. */ void write_der1_preamble(FILE *fd) const;
void write_der0(FILE* fd); /** This writes atom assignments. We have four kinds of atoms
/** This writes the evaluation of the first order derivative of * set here: endogenous vars coming from one parameter,
the system. It calls pure virtual methods for writing a * parameter values given by the second parameter, constants,
preamble, assignment, and assignemnt of the resulting * and the OperationTree::num_constants hardwired constants in
objects. */ * ogp::OperationTree. */
void write_der1(FILE* fd); void write_atom_assignment(FILE *fd) const;
protected: void write_der0_assignment(FILE *fd) const;
virtual void write_der0_preamble(FILE* fd) const =0; void write_der1_assignment(FILE *fd) const;
virtual void write_der1_preamble(FILE* fd) const =0; /** This prints t10 for t=10. */
virtual void write_atom_assignment(FILE* fd) const =0; void format_term(int t, FILE *fd) const;
virtual void write_der0_assignment(FILE* fd) const =0; /** This prints a10 for t=10. The atoms a10 are supposed to be
virtual void write_der1_assignment(FILE* fd) const =0; * set by write_atom_assignments(). */
}; void format_nulary(int t, FILE *fd) const;
private:
void write_common1_preamble(FILE *fd) const;
void write_common2_preamble(FILE *fd) const;
};
/** This class implements OperationFormatter for debugging
class MatlabSSWriter : public ModelSSWriter { * purposes. It renders atoms in a more friendly way than the
protected: * ogp::DefaulOperationFormatter. */
/** Identifier used in function names. */ class DebugOperationFormatter : public ogp::DefaultOperationFormatter
char* id; {
public: protected:
MatlabSSWriter(const DynareModel& dm, const char* idd); const DynareModel &model;
virtual ~MatlabSSWriter() public:
{delete [] id;} DebugOperationFormatter(const DynareModel &m)
protected: : DefaultOperationFormatter(m.getParser().getTree()),
// from ModelSSWriter model(m)
void write_der0_preamble(FILE* fd) const; {
void write_der1_preamble(FILE* fd) const; }
/** This writes atom assignments. We have four kinds of atoms void format_nulary(int t, FILE *fd) const;
* set here: endogenous vars coming from one parameter, };
* parameter values given by the second parameter, constants,
* and the OperationTree::num_constants hardwired constants in
* ogp::OperationTree. */
void write_atom_assignment(FILE* fd) const;
void write_der0_assignment(FILE* fd) const;
void write_der1_assignment(FILE* fd) const;
/** This prints t10 for t=10. */
void format_term(int t, FILE* fd) const;
/** This prints a10 for t=10. The atoms a10 are supposed to be
* set by write_atom_assignments(). */
void format_nulary(int t, FILE* fd) const;
private:
void write_common1_preamble(FILE* fd) const;
void write_common2_preamble(FILE* fd) const;
};
/** This class implements OperationFormatter for debugging
* purposes. It renders atoms in a more friendly way than the
* ogp::DefaulOperationFormatter. */
class DebugOperationFormatter : public ogp::DefaultOperationFormatter {
protected:
const DynareModel& model;
public:
DebugOperationFormatter(const DynareModel& m)
: DefaultOperationFormatter(m.getParser().getTree()),
model(m) {}
void format_nulary(int t, FILE* fd) const;
};
}; };
#endif #endif

View File

@ -3,71 +3,87 @@
// Copyright 2004, Ondra Kamenik // Copyright 2004, Ondra Kamenik
/* /*
along shocks: m mult max_evals along shocks: m mult max_evals
ellipse: m mult max_evals (10*m) (0.5*mult) ellipse: m mult max_evals (10*m) (0.5*mult)
simul: m max_evals (10*m) simul: m max_evals (10*m)
--check-scale 2.0 --check-evals 1000 --check-num 10 --check PES --check-scale 2.0 --check-evals 1000 --check-num 10 --check PES
*/ */
#include <vector> #include <vector>
#include <string> #include <string>
struct DynareParams { struct DynareParams
const char* modname; {
std::string basename; const char *modname;
int num_per; std::string basename;
int num_burn; int num_per;
int num_sim; int num_burn;
int num_rtper; int num_sim;
int num_rtsim; int num_rtper;
int num_condper; int num_rtsim;
int num_condsim; int num_condper;
int num_threads; int num_condsim;
int num_steps; int num_threads;
const char* prefix; int num_steps;
int seed; const char *prefix;
int order; int seed;
/** Tolerance used for steady state calcs. */ int order;
double ss_tol; /** Tolerance used for steady state calcs. */
bool check_along_path; double ss_tol;
bool check_along_shocks; bool check_along_path;
bool check_on_ellipse; bool check_along_shocks;
int check_evals; bool check_on_ellipse;
int check_num; int check_evals;
double check_scale; int check_num;
/** Flag for doing IRFs even if the irf_list is empty. */ double check_scale;
bool do_irfs_all; /** Flag for doing IRFs even if the irf_list is empty. */
/** List of shocks for which IRF will be calculated. */ bool do_irfs_all;
std::vector<const char*> irf_list; /** List of shocks for which IRF will be calculated. */
bool do_centralize; std::vector<const char *> irf_list;
double qz_criterium; bool do_centralize;
bool help; double qz_criterium;
bool version; bool help;
DynareParams(int argc, char** argv); bool version;
void printHelp() const; DynareParams(int argc, char **argv);
int getCheckShockPoints() const void printHelp() const;
{return check_num;} int
double getCheckShockScale() const getCheckShockPoints() const
{return check_scale;} {
int getCheckEllipsePoints() const return check_num;
{return 10*check_num;} }
double getCheckEllipseScale() const double
{return 0.5*check_scale;} getCheckShockScale() const
int getCheckPathPoints() const {
{return 10*check_num;} return check_scale;
}
int
getCheckEllipsePoints() const
{
return 10*check_num;
}
double
getCheckEllipseScale() const
{
return 0.5*check_scale;
}
int
getCheckPathPoints() const
{
return 10*check_num;
}
private: private:
enum {opt_per, opt_burn, opt_sim, opt_rtper, opt_rtsim, opt_condper, opt_condsim, enum {opt_per, opt_burn, opt_sim, opt_rtper, opt_rtsim, opt_condper, opt_condsim,
opt_prefix, opt_threads, opt_prefix, opt_threads,
opt_steps, opt_seed, opt_order, opt_ss_tol, opt_check, opt_steps, opt_seed, opt_order, opt_ss_tol, opt_check,
opt_check_along_path, opt_check_along_shocks, opt_check_on_ellipse, opt_check_along_path, opt_check_along_shocks, opt_check_on_ellipse,
opt_check_evals, opt_check_scale, opt_check_num, opt_noirfs, opt_irfs, opt_check_evals, opt_check_scale, opt_check_num, opt_noirfs, opt_irfs,
opt_help, opt_version, opt_centralize, opt_no_centralize, opt_qz_criterium}; opt_help, opt_version, opt_centralize, opt_no_centralize, opt_qz_criterium};
void processCheckFlags(const char* flags); void processCheckFlags(const char *flags);
/** This gathers strings from argv[optind] and on not starting /** This gathers strings from argv[optind] and on not starting
* with '-' to the irf_list. It stops one item before the end, * with '-' to the irf_list. It stops one item before the end,
* since this is the model file. */ * since this is the model file. */
void processIRFList(int argc, char** argv); void processIRFList(int argc, char **argv);
}; };
// Local Variables: // Local Variables:

View File

@ -5,75 +5,85 @@
#ifndef FORW_SUBST_BUILDER_H #ifndef FORW_SUBST_BUILDER_H
#define FORW_SUBST_BUILDER_H #define FORW_SUBST_BUILDER_H
#include "dynare_model.h" #include "dynare_model.h"
namespace ogdyn { namespace ogdyn
{
/** This struct encapsulates information about the process of /** This struct encapsulates information about the process of
* forward substitutions. */ * forward substitutions. */
struct ForwSubstInfo { struct ForwSubstInfo
int num_affected_equations; {
int num_subst_terms; int num_affected_equations;
int num_aux_variables; int num_subst_terms;
int num_new_terms; int num_aux_variables;
ForwSubstInfo() int num_new_terms;
: num_affected_equations(0), ForwSubstInfo()
num_subst_terms(0), : num_affected_equations(0),
num_aux_variables(0), num_subst_terms(0),
num_new_terms(0) {} num_aux_variables(0),
}; num_new_terms(0)
{
}
};
class ForwSubstBuilder { class ForwSubstBuilder
typedef map<int, const char*> Ttermauxmap; {
protected: typedef map<int, const char *> Ttermauxmap;
/** Reference to the model, to which we will add equations and protected:
* change some equations. */ /** Reference to the model, to which we will add equations and
DynareModel& model; * change some equations. */
/** A map mapping new auxiliary variables to the terms in the DynareModel &model;
* tree in the DynareModel. */ /** A map mapping new auxiliary variables to the terms in the
Tsubstmap aux_map; * tree in the DynareModel. */
/** Information about the substitutions. */ Tsubstmap aux_map;
ForwSubstInfo info; /** Information about the substitutions. */
public: ForwSubstInfo info;
/** Do all the jobs needed. This scans all equations in the public:
* model, and for equations containing forward looking /** Do all the jobs needed. This scans all equations in the
* variables greater than 1 lead, it makes corresponding * model, and for equations containing forward looking
* substitutions. Basically, it breaks each equation to its * variables greater than 1 lead, it makes corresponding
* non-linear components and creates substitutions for these * substitutions. Basically, it breaks each equation to its
* components, not for whole equation. This is because the * non-linear components and creates substitutions for these
* expectation operator can go through the linear part of the * components, not for whole equation. This is because the
* function. This will save us many occurrences of other * expectation operator can go through the linear part of the
* variables involved in the equation. */ * function. This will save us many occurrences of other
ForwSubstBuilder(DynareModel& m); * variables involved in the equation. */
/** Copy constructor with a new instance of the model. */ ForwSubstBuilder(DynareModel &m);
ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m); /** Copy constructor with a new instance of the model. */
/** Return the auxiliary variable mapping. */ ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m);
const Tsubstmap& get_aux_map() const /** Return the auxiliary variable mapping. */
{return aux_map;} const Tsubstmap &
/** Return the information. */ get_aux_map() const
const ForwSubstInfo& get_info() const {
{return info;} return aux_map;
private: }
ForwSubstBuilder(const ForwSubstBuilder& b); /** Return the information. */
/** This method takes a nonlinear term t, and if it has leads const ForwSubstInfo &
* of greater than 1, then it substitutes the term for the new get_info() const
* variable (or string of variables). Note that the {
* substitution is done by DynamicAtoms::assign_variable. This return info;
* means that the substitution is made for all other }
* ocurrences of t in the model. So there is no need of private:
* tracking already substituted terms. The other two ForwSubstBuilder(const ForwSubstBuilder &b);
* parameters are just for identification of the new auxiliary /** This method takes a nonlinear term t, and if it has leads
* variables. When called from the constructor, i is an * of greater than 1, then it substitutes the term for the new
* equation number, j is an order of the non-linear term in * variable (or string of variables). Note that the
* the equation. */ * substitution is done by DynamicAtoms::assign_variable. This
void substitute_for_term(int t, int i, int j); * means that the substitution is made for all other
/** This is called just at the end of the job. It unassigns * ocurrences of t in the model. So there is no need of
* all nulary terms with a lead greater than 1. */ * tracking already substituted terms. The other two
void unassign_gt_1_leads(); * parameters are just for identification of the new auxiliary
/** This unassigns all leads greater than 1 of the given name. */ * variables. When called from the constructor, i is an
void unassign_gt_1_leads(const char* name); * equation number, j is an order of the non-linear term in
}; * the equation. */
void substitute_for_term(int t, int i, int j);
/** This is called just at the end of the job. It unassigns
* all nulary terms with a lead greater than 1. */
void unassign_gt_1_leads();
/** This unassigns all leads greater than 1 of the given name. */
void unassign_gt_1_leads(const char *name);
};
}; };
#endif #endif

View File

@ -8,82 +8,102 @@
#include "twod_matrix.h" #include "twod_matrix.h"
#include "journal.h" #include "journal.h"
namespace ogu { namespace ogu
{
class OneDFunction { class OneDFunction
public: {
virtual ~OneDFunction() {} public:
virtual double eval(double) = 0; virtual ~OneDFunction()
}; {
}
virtual double eval(double) = 0;
};
class GoldenSectionSearch { class GoldenSectionSearch
protected: {
static double tol; protected:
static double golden; static double tol;
public: static double golden;
static double search(OneDFunction& f, double x1, double x2); public:
protected: static double search(OneDFunction &f, double x1, double x2);
/** This initializes a bracket by moving x2 and b (as a golden protected:
* section of x1,x2) so that f(x1)>f(b) && f(b)<f(x2). The point /** This initializes a bracket by moving x2 and b (as a golden
* x1 is not moved, since it is considered as reliable and f(x1) * section of x1,x2) so that f(x1)>f(b) && f(b)<f(x2). The point
* is supposed to be finite. If initialization of a bracket * x1 is not moved, since it is considered as reliable and f(x1)
* succeeded, then [x1, b, x2] is the bracket and true is * is supposed to be finite. If initialization of a bracket
* returned. Otherwise, b is the minimum found and false is * succeeded, then [x1, b, x2] is the bracket and true is
* returned. */ * returned. Otherwise, b is the minimum found and false is
static bool init_bracket(OneDFunction& f, double x1, double& x2, double& b); * returned. */
/** This supposes that f(x1) is finite and it moves x2 toward x1 static bool init_bracket(OneDFunction &f, double x1, double &x2, double &b);
* until x2 and b (as a golden section of x1,x2) are finite. If /** This supposes that f(x1) is finite and it moves x2 toward x1
* succeeded, the routine returns true and x2, and b. Otherwise, * until x2 and b (as a golden section of x1,x2) are finite. If
* it returns false. */ * succeeded, the routine returns true and x2, and b. Otherwise,
static bool search_for_finite(OneDFunction& f, double x1, double& x2, double& b); * it returns false. */
}; static bool search_for_finite(OneDFunction &f, double x1, double &x2, double &b);
};
class VectorFunction { class VectorFunction
public: {
VectorFunction() {} public:
virtual ~VectorFunction() {} VectorFunction()
virtual int inDim() const = 0; {
virtual int outDim() const = 0; }
/** Check dimensions of eval parameters. */ virtual ~VectorFunction()
void check_for_eval(const ConstVector& in, Vector& out) const; {
/** Evaluate the vector function. */ }
virtual void eval(const ConstVector& in, Vector& out) = 0; virtual int inDim() const = 0;
}; virtual int outDim() const = 0;
/** Check dimensions of eval parameters. */
void check_for_eval(const ConstVector &in, Vector &out) const;
/** Evaluate the vector function. */
virtual void eval(const ConstVector &in, Vector &out) = 0;
};
class Jacobian : public TwoDMatrix { class Jacobian : public TwoDMatrix
public: {
Jacobian(int n) public:
: TwoDMatrix(n,n) {} Jacobian(int n)
virtual ~Jacobian() {} : TwoDMatrix(n, n)
virtual void eval(const Vector& in) = 0; {
}; }
virtual ~Jacobian()
{
}
virtual void eval(const Vector &in) = 0;
};
class NLSolver : public OneDFunction { class NLSolver : public OneDFunction
protected: {
Journal& journal; protected:
VectorFunction& func; Journal &journal;
Jacobian& jacob; VectorFunction &func;
const int max_iter; Jacobian &jacob;
const double tol; const int max_iter;
private: const double tol;
Vector xnewton; private:
Vector xcauchy; Vector xnewton;
Vector x; Vector xcauchy;
public: Vector x;
NLSolver(VectorFunction& f, Jacobian& j, int maxit, double tl, Journal& jr) public:
: journal(jr), func(f), jacob(j), max_iter(maxit), tol(tl), NLSolver(VectorFunction &f, Jacobian &j, int maxit, double tl, Journal &jr)
xnewton(f.inDim()), xcauchy(f.inDim()), x(f.inDim()) : journal(jr), func(f), jacob(j), max_iter(maxit), tol(tl),
{xnewton.zeros(); xcauchy.zeros(); x.zeros();} xnewton(f.inDim()), xcauchy(f.inDim()), x(f.inDim())
virtual ~NLSolver() {} {
/** Returns true if the problem has converged. xx as input is the xnewton.zeros(); xcauchy.zeros(); x.zeros();
* starting value, as output it is a solution. */ }
bool solve(Vector& xx, int& iter); virtual ~NLSolver()
/** To implement OneDFunction interface. It returns {
* func(xx)^T*func(xx), where }
* xx=x+lambda*xcauchy+(1-lambda)*xnewton. It is non-const only /** Returns true if the problem has converged. xx as input is the
* because it calls func, x, xnewton, xcauchy is not changed. */ * starting value, as output it is a solution. */
double eval(double lambda); bool solve(Vector &xx, int &iter);
}; /** To implement OneDFunction interface. It returns
* func(xx)^T*func(xx), where
* xx=x+lambda*xcauchy+(1-lambda)*xnewton. It is non-const only
* because it calls func, x, xnewton, xcauchy is not changed. */
double eval(double lambda);
};
}; };

View File

@ -5,273 +5,322 @@
#include "dynare_model.h" #include "dynare_model.h"
namespace ogdyn { namespace ogdyn
{
using boost::unordered_set; using boost::unordered_set;
using std::map; using std::map;
using std::vector; using std::vector;
/** This is a two dimensional array of integers. Nothing /** This is a two dimensional array of integers. Nothing
* difficult. */ * difficult. */
class IntegerMatrix { class IntegerMatrix
protected: {
/** Number of rows. */ protected:
int nr; /** Number of rows. */
/** Number of columns. */ int nr;
int nc; /** Number of columns. */
/** The pointer to the data. */ int nc;
int* data; /** The pointer to the data. */
public: int *data;
/** Construct uninitialized array. */ public:
IntegerMatrix(int nrr, int ncc) /** Construct uninitialized array. */
: nr(nrr), nc(ncc), data(new int[nr*nc]) {} IntegerMatrix(int nrr, int ncc)
/** Copy constructor. */ : nr(nrr), nc(ncc), data(new int[nr*nc])
IntegerMatrix(const IntegerMatrix& im) {
: nr(im.nr), nc(im.nc), data(new int[nr*nc]) }
{memcpy(data, im.data, nr*nc*sizeof(int));} /** Copy constructor. */
virtual ~IntegerMatrix() IntegerMatrix(const IntegerMatrix &im)
{delete [] data;} : nr(im.nr), nc(im.nc), data(new int[nr*nc])
/** Assignment operator. It can only assing array with the {
* same dimensions. */ memcpy(data, im.data, nr*nc*sizeof(int));
const IntegerMatrix& operator=(const IntegerMatrix& im); }
int& operator()(int i, int j) virtual ~IntegerMatrix()
{return data[i+j*nr];} {
const int& operator()(int i, int j) const delete [] data;
{return data[i+j*nr];} }
int nrows() const /** Assignment operator. It can only assing array with the
{return nr;} * same dimensions. */
int ncols() const const IntegerMatrix &operator=(const IntegerMatrix &im);
{return nc;} int &
}; operator()(int i, int j)
{
return data[i+j*nr];
}
const int &
operator()(int i, int j) const
{
return data[i+j*nr];
}
int
nrows() const
{
return nr;
}
int
ncols() const
{
return nc;
}
};
/** The three dimensional array of integers. Nothing difficult. */ /** The three dimensional array of integers. Nothing difficult. */
class IntegerArray3 { class IntegerArray3
protected: {
/** First dimension. */ protected:
int n1; /** First dimension. */
/** Second dimension. */ int n1;
int n2; /** Second dimension. */
/** Third dimension. */ int n2;
int n3; /** Third dimension. */
/** The data. */ int n3;
int* data; /** The data. */
public: int *data;
/** Constrcut unitialized array. */ public:
IntegerArray3(int nn1, int nn2, int nn3) /** Constrcut unitialized array. */
: n1(nn1), n2(nn2), n3(nn3), data(new int[n1*n2*n3]) {} IntegerArray3(int nn1, int nn2, int nn3)
/** Copy constructor. */ : n1(nn1), n2(nn2), n3(nn3), data(new int[n1*n2*n3])
IntegerArray3(const IntegerArray3& ia3) {
: n1(ia3.n1), n2(ia3.n2), n3(ia3.n3), data(new int[n1*n2*n3]) }
{memcpy(data, ia3.data, n1*n2*n3*sizeof(int));} /** Copy constructor. */
virtual ~IntegerArray3() IntegerArray3(const IntegerArray3 &ia3)
{delete [] data;} : n1(ia3.n1), n2(ia3.n2), n3(ia3.n3), data(new int[n1*n2*n3])
/** Assignment operator assigning the arrays with the same dimensions. */ {
const IntegerArray3& operator=(const IntegerArray3& ia3); memcpy(data, ia3.data, n1*n2*n3*sizeof(int));
int& operator()(int i, int j, int k) }
{return data[i+j*n1+k*n1*n2];} virtual ~IntegerArray3()
const int& operator()(int i, int j, int k) const {
{return data[i+j*n1+k*n1*n2];} delete [] data;
int dim1() const }
{return n1;} /** Assignment operator assigning the arrays with the same dimensions. */
int dim2() const const IntegerArray3 &operator=(const IntegerArray3 &ia3);
{return n2;} int &
int dim3() const operator()(int i, int j, int k)
{return n3;} {
}; return data[i+j*n1+k*n1*n2];
}
const int &
operator()(int i, int j, int k) const
{
return data[i+j*n1+k*n1*n2];
}
int
dim1() const
{
return n1;
}
int
dim2() const
{
return n2;
}
int
dim3() const
{
return n3;
}
};
/** This struct encapsulates information about the building of a /** This struct encapsulates information about the building of a
* planner's problem. */ * planner's problem. */
struct PlannerInfo { struct PlannerInfo
int num_lagrange_mults; {
int num_aux_variables; int num_lagrange_mults;
int num_new_terms; int num_aux_variables;
PlannerInfo() int num_new_terms;
: num_lagrange_mults(0), PlannerInfo()
num_aux_variables(0), : num_lagrange_mults(0),
num_new_terms(0) {} num_aux_variables(0),
}; num_new_terms(0)
{
}
};
class MultInitSS; class MultInitSS;
/** This class builds the first order conditions of the social /** This class builds the first order conditions of the social
* planner problem with constraints being the equations in the * planner problem with constraints being the equations in the
* model. The model is non-const parameter to the constructor * model. The model is non-const parameter to the constructor
* which adds appropriate FOCs to the system. It also allows for * which adds appropriate FOCs to the system. It also allows for
* an estimation of the lagrange multipliers given all other * an estimation of the lagrange multipliers given all other
* endogenous variables of the static system. For this purpose we * endogenous variables of the static system. For this purpose we
* need to create static atoms and static versions of all the tree * need to create static atoms and static versions of all the tree
* index matrices. The algorithm and algebra are documented in * index matrices. The algorithm and algebra are documented in
* dynare++-ramsey.pdf. */ * dynare++-ramsey.pdf. */
class PlannerBuilder { class PlannerBuilder
friend class MultInitSS; {
public: friend class MultInitSS;
/** Type for a set of variable names. */ public:
typedef unordered_set<const char*> Tvarset; /** Type for a set of variable names. */
/** Type for a set of equations. An equation is identified by typedef unordered_set<const char *> Tvarset;
* an index to an equation in the equation vector given by /** Type for a set of equations. An equation is identified by
* DynareModel::eqs. The tree index of the i-th formula is * an index to an equation in the equation vector given by
* retrieved as DynareModel::egs.formula(i). */ * DynareModel::eqs. The tree index of the i-th formula is
typedef vector<int> Teqset; * retrieved as DynareModel::egs.formula(i). */
protected: typedef vector<int> Teqset;
/** This is a set of variables wrt which the planner protected:
* optimizes. These could be all endogenous variables, but it /** This is a set of variables wrt which the planner
* is beneficial to exclude all variables which are * optimizes. These could be all endogenous variables, but it
* deterministic transformations of past exogenous variables, * is beneficial to exclude all variables which are
* since the planner cannot influence them. This could save a * deterministic transformations of past exogenous variables,
* few equations. This is not changed after it is constructed, * since the planner cannot influence them. This could save a
* but it is constructed manually, so it cannot be declared as * few equations. This is not changed after it is constructed,
* const. */ * but it is constructed manually, so it cannot be declared as
Tvarset yset; * const. */
/** These are the equation indices constituing the constraints Tvarset yset;
* for the planner. Again, it is beneficial to exclude all /** These are the equation indices constituing the constraints
* equations defining exogenous variables excluded from * for the planner. Again, it is beneficial to exclude all
* yset. */ * equations defining exogenous variables excluded from
const Teqset fset; * yset. */
/** Reference to the model. */ const Teqset fset;
ogdyn::DynareModel& model; /** Reference to the model. */
/** Tree index of the planner objective. */ ogdyn::DynareModel &model;
int tb; /** Tree index of the planner objective. */
/** Tree index of the planner discount parameter. */ int tb;
int tbeta; /** Tree index of the planner discount parameter. */
/** The maximum lead in the model including the planner's int tbeta;
* objective before building the planner's FOCs. */ /** The maximum lead in the model including the planner's
const int maxlead; * objective before building the planner's FOCs. */
/** The minimum lag in the model including the planner's objective const int maxlead;
* before building the planner's FOCs. */ /** The minimum lag in the model including the planner's objective
const int minlag; * before building the planner's FOCs. */
/** Tree indices of formulas in the planner FOCs involving const int minlag;
* derivatives of the planner's objective. Rows correspond to the /** Tree indices of formulas in the planner FOCs involving
* endogenous variables, columns correspond to lags in the * derivatives of the planner's objective. Rows correspond to the
* objective function. The contents of the matrix will evolve as * endogenous variables, columns correspond to lags in the
* the algorithm proceeds. */ * objective function. The contents of the matrix will evolve as
IntegerMatrix diff_b; * the algorithm proceeds. */
/** Tree indices of formulas in the planner FOCs involving IntegerMatrix diff_b;
* derivatives of the model equations (constraints). The first /** Tree indices of formulas in the planner FOCs involving
* dimension corresponds to endogenous variables, the second to * derivatives of the model equations (constraints). The first
* the constraints, the third to lags or leads of endogenous * dimension corresponds to endogenous variables, the second to
* variables in the constraints. The contents of the array will * the constraints, the third to lags or leads of endogenous
* evolve as the algorithm proceeds.*/ * variables in the constraints. The contents of the array will
IntegerArray3 diff_f; * evolve as the algorithm proceeds.*/
/** Static version of the model atoms. It is needed to build IntegerArray3 diff_f;
* static version of diff_b and diff_f. */ /** Static version of the model atoms. It is needed to build
ogp::StaticFineAtoms static_atoms; * static version of diff_b and diff_f. */
/** Static version of all the trees of diff_b and diff_f build ogp::StaticFineAtoms static_atoms;
* over static_atoms. */ /** Static version of all the trees of diff_b and diff_f build
ogp::OperationTree static_tree; * over static_atoms. */
/** Tree indices of static version of diff_b over static_atoms and static_tree. */ ogp::OperationTree static_tree;
IntegerMatrix diff_b_static; /** Tree indices of static version of diff_b over static_atoms and static_tree. */
/** Tree indices of static version of diff_f over static_atoms IntegerMatrix diff_b_static;
* and static_tree. This member is created before calling /** Tree indices of static version of diff_f over static_atoms
* lagrange_mult_f(), so it does not contain the * and static_tree. This member is created before calling
* multiplication with the lagrange multipliers. */ * lagrange_mult_f(), so it does not contain the
IntegerArray3 diff_f_static; * multiplication with the lagrange multipliers. */
/** Auxiliary variables mapping. During the algorithm, some IntegerArray3 diff_f_static;
* auxiliary variables for the terms might be created, so we /** Auxiliary variables mapping. During the algorithm, some
* remember their names and tree indices of the terms. This * auxiliary variables for the terms might be created, so we
* maps a name to the tree index of an expression equal to the * remember their names and tree indices of the terms. This
* auxiliary variable at time zero. The auxiliary variables * maps a name to the tree index of an expression equal to the
* names point to the dynamic atoms storage, tree inidices to * auxiliary variable at time zero. The auxiliary variables
* the dynamic model tree. */ * names point to the dynamic atoms storage, tree inidices to
Tsubstmap aux_map; * the dynamic model tree. */
/** Static version of aux_map. The names point to static_atoms Tsubstmap aux_map;
* storage, the tree indices to the static_tree. */ /** Static version of aux_map. The names point to static_atoms
Tsubstmap static_aux_map; * storage, the tree indices to the static_tree. */
/** Information about the number of various things. */ Tsubstmap static_aux_map;
PlannerInfo info; /** Information about the number of various things. */
public: PlannerInfo info;
/** Build the planner problem for the given model optimizing public:
* through the given endogenous variables with the given /** Build the planner problem for the given model optimizing
* constraints. We allow for a selection of a subset of * through the given endogenous variables with the given
* equations and variables in order to eliminate exogenous * constraints. We allow for a selection of a subset of
* predetermined process which cannot be influenced by the * equations and variables in order to eliminate exogenous
* social planner. */ * predetermined process which cannot be influenced by the
PlannerBuilder(ogdyn::DynareModel& m, const Tvarset& yyset, * social planner. */
const Teqset& ffset); PlannerBuilder(ogdyn::DynareModel &m, const Tvarset &yyset,
/** Construct a copy of the builder with provided model, which const Teqset &ffset);
* is supposed to be the copy of the model in the builder. */ /** Construct a copy of the builder with provided model, which
PlannerBuilder(const PlannerBuilder& pb, ogdyn::DynareModel& m); * is supposed to be the copy of the model in the builder. */
/** Return the information. */ PlannerBuilder(const PlannerBuilder &pb, ogdyn::DynareModel &m);
const PlannerInfo& get_info() const /** Return the information. */
{return info;} const PlannerInfo &
protected: get_info() const
/** Differentiate the planner objective wrt endogenous {
* variables with different lags. */ return info;
void add_derivatives_of_b(); }
/** Differentiate the constraints wrt endogenous variables protected:
* with different lags and leads. */ /** Differentiate the planner objective wrt endogenous
void add_derivatives_of_f(); * variables with different lags. */
/** Shift derivatives of diff_b. */ void add_derivatives_of_b();
void shift_derivatives_of_b(); /** Differentiate the constraints wrt endogenous variables
/** Shift derivatives of diff_ff. */ * with different lags and leads. */
void shift_derivatives_of_f(); void add_derivatives_of_f();
/** Multiply with the discount factor terms in diff_b. */ /** Shift derivatives of diff_b. */
void beta_multiply_b(); void shift_derivatives_of_b();
/** Multiply with the discount factor terms in diff_f. */ /** Shift derivatives of diff_ff. */
void beta_multiply_f(); void shift_derivatives_of_f();
/** Fill static_atoms and static_tree and build diff_b_static, /** Multiply with the discount factor terms in diff_b. */
* diff_f_static and aux_map_static with static versions of diff_b, void beta_multiply_b();
* diff_f and aux_map. */ /** Multiply with the discount factor terms in diff_f. */
void make_static_version(); void beta_multiply_f();
/** Multiply diff_f with Langrange multipliers. */ /** Fill static_atoms and static_tree and build diff_b_static,
void lagrange_mult_f(); * diff_f_static and aux_map_static with static versions of diff_b,
/** Add the equations to the mode, including equation for auxiliary variables. */ * diff_f and aux_map. */
void form_equations(); void make_static_version();
private: /** Multiply diff_f with Langrange multipliers. */
/** Fill yset for a given yyset and given name storage. */ void lagrange_mult_f();
void fill_yset(const ogp::NameStorage& ns, const Tvarset& yyset); /** Add the equations to the mode, including equation for auxiliary variables. */
/** Fill aux_map and aux_map_static for a given aaux_map and void form_equations();
* aaux_map_static for a given storage of dynamic atoms (used private:
* for aux_map) and static atoms storage from this object for /** Fill yset for a given yyset and given name storage. */
* aux_map_static. */ void fill_yset(const ogp::NameStorage &ns, const Tvarset &yyset);
void fill_aux_map(const ogp::NameStorage& ns, const Tsubstmap& aaux_map, /** Fill aux_map and aux_map_static for a given aaux_map and
const Tsubstmap& astatic_aux_map); * aaux_map_static for a given storage of dynamic atoms (used
/** Avoid copying from only PlannerBuilder. */ * for aux_map) and static atoms storage from this object for
PlannerBuilder(const PlannerBuilder& pb); * aux_map_static. */
}; void fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_map,
const Tsubstmap &astatic_aux_map);
/** Avoid copying from only PlannerBuilder. */
PlannerBuilder(const PlannerBuilder &pb);
};
/** This class only calculates for the given initial guess of /** This class only calculates for the given initial guess of
* endogenous variables, initial guess of the Langrange * endogenous variables, initial guess of the Langrange
* multipliers of the social planner problem yielding the least * multipliers of the social planner problem yielding the least
* square error. It is used by just calling its constructor. The * square error. It is used by just calling its constructor. The
* constructor takes non-const reference to the vector of * constructor takes non-const reference to the vector of
* endogenous variables, calculates lambdas and put the values of * endogenous variables, calculates lambdas and put the values of
* lambdas to the vector. The algbera is found in * lambdas to the vector. The algbera is found in
* dynare++-ramsey.pdf. * dynare++-ramsey.pdf.
* *
* The code can be run only after the parsing has been finished in * The code can be run only after the parsing has been finished in
* atoms. */ * atoms. */
class MultInitSS : public ogp::FormulaEvalLoader { class MultInitSS : public ogp::FormulaEvalLoader
protected: {
/** The constant reference to the builder. */ protected:
const PlannerBuilder& builder; /** The constant reference to the builder. */
/** The constant term of the problem. Its length is the number const PlannerBuilder &builder;
* of endogenous variable wrt the planner optimizes. */ /** The constant term of the problem. Its length is the number
Vector b; * of endogenous variable wrt the planner optimizes. */
/** The matrix of the overdetermined problem. The number of Vector b;
* rows is equal to the number of endogenous variables wrt /** The matrix of the overdetermined problem. The number of
* which the planner optimizes, the number of columns is equal * rows is equal to the number of endogenous variables wrt
* to the number of Langrange multipliers which is equal to * which the planner optimizes, the number of columns is equal
* the number of constraints which is smaller than the number * to the number of Langrange multipliers which is equal to
* of endogenous variables. Hence the system b+F*lambda=0 is * the number of constraints which is smaller than the number
* overdetermined. */ * of endogenous variables. Hence the system b+F*lambda=0 is
GeneralMatrix F; * overdetermined. */
public: GeneralMatrix F;
/** The constructor of the object which does everything. Its public:
* main goal is to update yy. Note that if an item of yy /** The constructor of the object which does everything. Its
* corresponding to a lagrange multiplier is already set, it * main goal is to update yy. Note that if an item of yy
* is not reset. */ * corresponding to a lagrange multiplier is already set, it
MultInitSS(const PlannerBuilder& pb, const Vector& pvals, Vector& yy); * is not reset. */
/** This loads evaluated parts of b or F and decodes i and MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy);
* advances b or F depending on the decoded i. The decoding is /** This loads evaluated parts of b or F and decodes i and
* dependent on the way how the terms of builder.diff_b and * advances b or F depending on the decoded i. The decoding is
* builder.diff_f_save have been put the the * dependent on the way how the terms of builder.diff_b and
* ogp::FormulaCustomEvaluator. This is documented in the code * builder.diff_f_save have been put the the
* of the constructor. */ * ogp::FormulaCustomEvaluator. This is documented in the code
void load(int i, double res); * of the constructor. */
}; void load(int i, double res);
};
}; };
#endif #endif
// Local Variables: // Local Variables:

View File

@ -7,47 +7,55 @@
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
class BlockDiagonal : public QuasiTriangular
class BlockDiagonal : public QuasiTriangular { {
int* const row_len; int *const row_len;
int* const col_len; int *const col_len;
public: public:
BlockDiagonal(const double* d, int d_size); BlockDiagonal(const double *d, int d_size);
BlockDiagonal(int p, const BlockDiagonal& b); BlockDiagonal(int p, const BlockDiagonal &b);
BlockDiagonal(const BlockDiagonal& b); BlockDiagonal(const BlockDiagonal &b);
BlockDiagonal(const QuasiTriangular& t); BlockDiagonal(const QuasiTriangular &t);
const BlockDiagonal& operator=(const QuasiTriangular& t) const BlockDiagonal &
{GeneralMatrix::operator=(t); return *this;} operator=(const QuasiTriangular &t)
const BlockDiagonal& operator=(const BlockDiagonal& b); {
~BlockDiagonal() {delete [] row_len; delete [] col_len;} GeneralMatrix::operator=(t); return *this;
void setZeroBlockEdge(diag_iter edge); }
int getNumZeros() const; const BlockDiagonal &operator=(const BlockDiagonal &b);
int getNumBlocks() const; ~BlockDiagonal()
int getLargestBlock() const; {
void printInfo() const; delete [] row_len; delete [] col_len;
}
void setZeroBlockEdge(diag_iter edge);
int getNumZeros() const;
int getNumBlocks() const;
int getLargestBlock() const;
void printInfo() const;
void multKron(KronVector& x) const; void multKron(KronVector &x) const;
void multKronTrans(KronVector& x) const; void multKronTrans(KronVector &x) const;
const_col_iter col_begin(const DiagonalBlock& b) const; const_col_iter col_begin(const DiagonalBlock &b) const;
col_iter col_begin(const DiagonalBlock& b); col_iter col_begin(const DiagonalBlock &b);
const_row_iter row_end(const DiagonalBlock& b) const; const_row_iter row_end(const DiagonalBlock &b) const;
row_iter row_end(const DiagonalBlock& b); row_iter row_end(const DiagonalBlock &b);
QuasiTriangular* clone() const QuasiTriangular *
{return new BlockDiagonal(*this);} clone() const
{
return new BlockDiagonal(*this);
}
private: private:
void setZerosToRU(diag_iter edge); void setZerosToRU(diag_iter edge);
const_diag_iter findBlockStart(const_diag_iter from) const; const_diag_iter findBlockStart(const_diag_iter from) const;
static void savePartOfX(int si, int ei, const KronVector& x, Vector& work); static void savePartOfX(int si, int ei, const KronVector &x, Vector &work);
void multKronBlock(const_diag_iter start, const_diag_iter end, void multKronBlock(const_diag_iter start, const_diag_iter end,
KronVector& x, Vector& work) const; KronVector &x, Vector &work) const;
void multKronBlockTrans(const_diag_iter start, const_diag_iter end, void multKronBlockTrans(const_diag_iter start, const_diag_iter end,
KronVector& x, Vector& work) const; KronVector &x, Vector &work) const;
}; };
#endif /* BLOCK_DIAGONAL_H */ #endif /* BLOCK_DIAGONAL_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -11,310 +11,484 @@
class GeneralMatrix; class GeneralMatrix;
class ConstGeneralMatrix { class ConstGeneralMatrix
friend class GeneralMatrix; {
friend class GeneralMatrix;
protected: protected:
ConstVector data; ConstVector data;
int rows; int rows;
int cols; int cols;
int ld; int ld;
public: public:
ConstGeneralMatrix(const double* d, int m, int n) ConstGeneralMatrix(const double *d, int m, int n)
: data(d, m*n), rows(m), cols(n), ld(m) {} : data(d, m*n), rows(m), cols(n), ld(m)
ConstGeneralMatrix(const GeneralMatrix& m); {
ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); }
ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols); ConstGeneralMatrix(const GeneralMatrix &m);
virtual ~ConstGeneralMatrix() {} ConstGeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols);
ConstGeneralMatrix(const ConstGeneralMatrix &m, int i, int j, int nrows, int ncols);
virtual ~ConstGeneralMatrix()
{
}
const double& get(int i, int j) const const double &
{return data[j*ld+i];} get(int i, int j) const
int numRows() const {return rows;} {
int numCols() const {return cols;} return data[j*ld+i];
int getLD() const {return ld;} }
const double* base() const {return data.base();} int
const ConstVector& getData() const {return data;} numRows() const
{
return rows;
}
int
numCols() const
{
return cols;
}
int
getLD() const
{
return ld;
}
const double *
base() const
{
return data.base();
}
const ConstVector &
getData() const
{
return data;
}
double getNormInf() const; double getNormInf() const;
double getNorm1() const; double getNorm1() const;
/* x = scalar(a)*x + scalar(b)*this*d */ /* x = scalar(a)*x + scalar(b)*this*d */
void multVec(double a, Vector& x, double b, const ConstVector& d) const; void multVec(double a, Vector &x, double b, const ConstVector &d) const;
/* x = scalar(a)*x + scalar(b)*this'*d */ /* x = scalar(a)*x + scalar(b)*this'*d */
void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const; void multVecTrans(double a, Vector &x, double b, const ConstVector &d) const;
/* x = x + this*d */ /* x = x + this*d */
void multaVec(Vector& x, const ConstVector& d) const void
{multVec(1.0, x, 1.0, d);} multaVec(Vector &x, const ConstVector &d) const
/* x = x + this'*d */ {
void multaVecTrans(Vector& x, const ConstVector& d) const multVec(1.0, x, 1.0, d);
{multVecTrans(1.0, x, 1.0, d);} }
/* x = x - this*d */ /* x = x + this'*d */
void multsVec(Vector& x, const ConstVector& d) const void
{multVec(1.0, x, -1.0, d);} multaVecTrans(Vector &x, const ConstVector &d) const
/* x = x - this'*d */ {
void multsVecTrans(Vector& x, const ConstVector& d) const multVecTrans(1.0, x, 1.0, d);
{multVecTrans(1.0, x, -1.0, d);} }
/* m = inv(this)*m */ /* x = x - this*d */
void multInvLeft(GeneralMatrix& m) const; void
/* m = inv(this')*m */ multsVec(Vector &x, const ConstVector &d) const
void multInvLeftTrans(GeneralMatrix& m) const; {
/* d = inv(this)*d */ multVec(1.0, x, -1.0, d);
void multInvLeft(Vector& d) const; }
/* d = inv(this')*d */ /* x = x - this'*d */
void multInvLeftTrans(Vector& d) const; void
multsVecTrans(Vector &x, const ConstVector &d) const
{
multVecTrans(1.0, x, -1.0, d);
}
/* m = inv(this)*m */
void multInvLeft(GeneralMatrix &m) const;
/* m = inv(this')*m */
void multInvLeftTrans(GeneralMatrix &m) const;
/* d = inv(this)*d */
void multInvLeft(Vector &d) const;
/* d = inv(this')*d */
void multInvLeftTrans(Vector &d) const;
bool isFinite() const; bool isFinite() const;
/** Returns true of the matrix is exactly zero. */ /** Returns true of the matrix is exactly zero. */
bool isZero() const; bool isZero() const;
virtual void print() const; virtual void print() const;
protected: protected:
void multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const; void multInvLeft(const char *trans, int mrows, int mcols, int mld, double *d) const;
}; };
class GeneralMatrix
class GeneralMatrix { {
friend class ConstGeneralMatrix; friend class ConstGeneralMatrix;
protected: protected:
Vector data; Vector data;
int rows; int rows;
int cols; int cols;
int ld; int ld;
public: public:
GeneralMatrix(int m, int n) GeneralMatrix(int m, int n)
: data(m*n), rows(m), cols(n), ld(m) {} : data(m*n), rows(m), cols(n), ld(m)
GeneralMatrix(const double* d, int m, int n) {
: data(d, m*n), rows(m), cols(n), ld(m) {} }
GeneralMatrix(double* d, int m, int n) GeneralMatrix(const double *d, int m, int n)
: data(d, m*n), rows(m), cols(n), ld(m) {} : data(d, m*n), rows(m), cols(n), ld(m)
GeneralMatrix(const GeneralMatrix& m); {
GeneralMatrix(const ConstGeneralMatrix& m); }
GeneralMatrix(const GeneralMatrix&m, const char* dummy); // transpose GeneralMatrix(double *d, int m, int n)
GeneralMatrix(const ConstGeneralMatrix&m, const char* dummy); // transpose : data(d, m*n), rows(m), cols(n), ld(m)
GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); {
GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols); }
/* this = a*b */ GeneralMatrix(const GeneralMatrix &m);
GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b); GeneralMatrix(const ConstGeneralMatrix &m);
/* this = a*b' */ GeneralMatrix(const GeneralMatrix &m, const char *dummy); // transpose
GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum); GeneralMatrix(const ConstGeneralMatrix &m, const char *dummy); // transpose
/* this = a'*b */ GeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols);
GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b); GeneralMatrix(GeneralMatrix &m, int i, int j, int nrows, int ncols);
/* this = a'*b */ /* this = a*b */
GeneralMatrix(const GeneralMatrix& a, const char* dum1, GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b);
const GeneralMatrix& b, const char* dum2); /* this = a*b' */
GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b, const char *dum);
/* this = a'*b */
GeneralMatrix(const GeneralMatrix &a, const char *dum, const GeneralMatrix &b);
/* this = a'*b */
GeneralMatrix(const GeneralMatrix &a, const char *dum1,
const GeneralMatrix &b, const char *dum2);
virtual ~GeneralMatrix(); virtual
const GeneralMatrix& operator=(const GeneralMatrix& m) ~GeneralMatrix();
{data=m.data; rows=m.rows; cols=m.cols; ld=m.ld; return *this;} const GeneralMatrix &
operator=(const GeneralMatrix &m)
{
data = m.data; rows = m.rows; cols = m.cols; ld = m.ld; return *this;
}
const double& get(int i, int j) const const double &
{return data[j*ld+i];} get(int i, int j) const
double& get(int i, int j) {
{return data[j*ld+i];} return data[j*ld+i];
int numRows() const {return rows;} }
int numCols() const {return cols;} double &
int getLD() const {return ld;} get(int i, int j)
double* base() {return data.base();} {
const double* base() const {return data.base();} return data[j*ld+i];
Vector& getData() {return data;} }
const Vector& getData() const {return data;} int
numRows() const
{
return rows;
}
int
numCols() const
{
return cols;
}
int
getLD() const
{
return ld;
}
double *
base()
{
return data.base();
}
const double *
base() const
{
return data.base();
}
Vector &
getData()
{
return data;
}
const Vector &
getData() const
{
return data;
}
double getNormInf() const double
{return ConstGeneralMatrix(*this).getNormInf();} getNormInf() const
double getNorm1() const {
{return ConstGeneralMatrix(*this).getNorm1();} return ConstGeneralMatrix(*this).getNormInf();
}
double
getNorm1() const
{
return ConstGeneralMatrix(*this).getNorm1();
}
/* place matrix m to the position (i,j) */ /* place matrix m to the position (i,j) */
void place(const ConstGeneralMatrix& m, int i, int j); void place(const ConstGeneralMatrix &m, int i, int j);
void place(const GeneralMatrix& m, int i, int j) void
{place(ConstGeneralMatrix(m), i, j);} place(const GeneralMatrix &m, int i, int j)
{
place(ConstGeneralMatrix(m), i, j);
}
/* this = a*b */ /* this = a*b */
void mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b); void mult(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b);
void mult(const GeneralMatrix& a, const GeneralMatrix& b) void
{mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));} mult(const GeneralMatrix &a, const GeneralMatrix &b)
{
mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));
}
/* this = this + scalar*a*b */ /* this = this + scalar*a*b */
void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, void multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
double mult=1.0); double mult = 1.0);
void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, void
double mult=1.0) multAndAdd(const GeneralMatrix &a, const GeneralMatrix &b,
{multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);} double mult = 1.0)
{
multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);
}
/* this = this + scalar*a*b' */ /* this = this + scalar*a*b' */
void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, void multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
const char* dum, double mult=1.0); const char *dum, double mult = 1.0);
void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, void
const char* dum, double mult=1.0) multAndAdd(const GeneralMatrix &a, const GeneralMatrix &b,
{multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);} const char *dum, double mult = 1.0)
{
multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);
}
/* this = this + scalar*a'*b */ /* this = this + scalar*a'*b */
void multAndAdd(const ConstGeneralMatrix& a, const char* dum, const ConstGeneralMatrix& b, void multAndAdd(const ConstGeneralMatrix &a, const char *dum, const ConstGeneralMatrix &b,
double mult=1.0); double mult = 1.0);
void multAndAdd(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b, void
double mult=1.0) multAndAdd(const GeneralMatrix &a, const char *dum, const GeneralMatrix &b,
{multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);} double mult = 1.0)
{
multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);
}
/* this = this + scalar*a'*b' */ /* this = this + scalar*a'*b' */
void multAndAdd(const ConstGeneralMatrix& a, const char* dum1, void multAndAdd(const ConstGeneralMatrix &a, const char *dum1,
const ConstGeneralMatrix& b, const char* dum2, double mult=1.0); const ConstGeneralMatrix &b, const char *dum2, double mult = 1.0);
void multAndAdd(const GeneralMatrix& a, const char* dum1, void
const GeneralMatrix& b, const char* dum2, double mult=1.0) multAndAdd(const GeneralMatrix &a, const char *dum1,
{multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b),dum2, mult);} const GeneralMatrix &b, const char *dum2, double mult = 1.0)
{
multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b), dum2, mult);
}
/* this = this + scalar*a*a' */ /* this = this + scalar*a*a' */
void addOuter(const ConstVector& a, double mult=1.0); void addOuter(const ConstVector &a, double mult = 1.0);
void addOuter(const Vector& a, double mult=1.0) void
{addOuter(ConstVector(a), mult);} addOuter(const Vector &a, double mult = 1.0)
{
addOuter(ConstVector(a), mult);
}
/* this = this * m */ /* this = this * m */
void multRight(const ConstGeneralMatrix& m); void multRight(const ConstGeneralMatrix &m);
void multRight(const GeneralMatrix& m) void
{multRight(ConstGeneralMatrix(m));} multRight(const GeneralMatrix &m)
{
multRight(ConstGeneralMatrix(m));
}
/* this = m * this */ /* this = m * this */
void multLeft(const ConstGeneralMatrix& m); void multLeft(const ConstGeneralMatrix &m);
void multLeft(const GeneralMatrix& m) void
{multLeft(ConstGeneralMatrix(m));} multLeft(const GeneralMatrix &m)
{
multLeft(ConstGeneralMatrix(m));
}
/* this = this * m' */ /* this = this * m' */
void multRightTrans(const ConstGeneralMatrix& m); void multRightTrans(const ConstGeneralMatrix &m);
void multRightTrans(const GeneralMatrix& m) void
{multRightTrans(ConstGeneralMatrix(m));} multRightTrans(const GeneralMatrix &m)
{
multRightTrans(ConstGeneralMatrix(m));
}
/* this = m' * this */ /* this = m' * this */
void multLeftTrans(const ConstGeneralMatrix& m); void multLeftTrans(const ConstGeneralMatrix &m);
void multLeftTrans(const GeneralMatrix& m) void
{multLeftTrans(ConstGeneralMatrix(m));} multLeftTrans(const GeneralMatrix &m)
{
multLeftTrans(ConstGeneralMatrix(m));
}
/* x = scalar(a)*x + scalar(b)*this*d */ /* x = scalar(a)*x + scalar(b)*this*d */
void multVec(double a, Vector& x, double b, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multVec(a, x, b, d);} multVec(double a, Vector &x, double b, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multVec(a, x, b, d);
}
/* x = scalar(a)*x + scalar(b)*this'*d */ /* x = scalar(a)*x + scalar(b)*this'*d */
void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);} multVecTrans(double a, Vector &x, double b, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);
}
/* x = x + this*d */ /* x = x + this*d */
void multaVec(Vector& x, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multaVec(x, d);} multaVec(Vector &x, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multaVec(x, d);
}
/* x = x + this'*d */ /* x = x + this'*d */
void multaVecTrans(Vector& x, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multaVecTrans(x, d);} multaVecTrans(Vector &x, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multaVecTrans(x, d);
}
/* x = x - this*d */ /* x = x - this*d */
void multsVec(Vector& x, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multsVec(x, d);} multsVec(Vector &x, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multsVec(x, d);
}
/* x = x - this'*d */ /* x = x - this'*d */
void multsVecTrans(Vector& x, const ConstVector& d) const void
{ConstGeneralMatrix(*this).multsVecTrans(x, d);} multsVecTrans(Vector &x, const ConstVector &d) const
{
ConstGeneralMatrix(*this).multsVecTrans(x, d);
}
/* this = zero */ /* this = zero */
void zeros(); void zeros();
/** this = unit (on main diagonal) */ /** this = unit (on main diagonal) */
void unit(); void unit();
/* this = NaN */ /* this = NaN */
void nans(); void nans();
/* this = Inf */ /* this = Inf */
void infs(); void infs();
/* this = scalar*this */ /* this = scalar*this */
void mult(double a); void mult(double a);
/* this = this + scalar*m */ /* this = this + scalar*m */
void add(double a, const ConstGeneralMatrix& m); void add(double a, const ConstGeneralMatrix &m);
void add(double a, const GeneralMatrix& m) void
{add(a, ConstGeneralMatrix(m));} add(double a, const GeneralMatrix &m)
{
add(a, ConstGeneralMatrix(m));
}
/* this = this + scalar*m' */ /* this = this + scalar*m' */
void add(double a, const ConstGeneralMatrix& m, const char* dum); void add(double a, const ConstGeneralMatrix &m, const char *dum);
void add(double a, const GeneralMatrix& m, const char* dum) void
{add(a, ConstGeneralMatrix(m), dum);} add(double a, const GeneralMatrix &m, const char *dum)
{
add(a, ConstGeneralMatrix(m), dum);
}
bool isFinite() const bool
{return (ConstGeneralMatrix(*this)).isFinite();} isFinite() const
{
return (ConstGeneralMatrix(*this)).isFinite();
}
bool isZero() const bool
{return (ConstGeneralMatrix(*this)).isZero();} isZero() const
{
return (ConstGeneralMatrix(*this)).isZero();
}
virtual void print() const virtual void
{ConstGeneralMatrix(*this).print();} print() const
{
ConstGeneralMatrix(*this).print();
}
private: private:
void copy(const ConstGeneralMatrix& m, int ioff = 0, int joff = 0); void copy(const ConstGeneralMatrix &m, int ioff = 0, int joff = 0);
void copy(const GeneralMatrix& m, int ioff = 0, int joff = 0) void
{copy(ConstGeneralMatrix(m), ioff, joff);} copy(const GeneralMatrix &m, int ioff = 0, int joff = 0)
{
copy(ConstGeneralMatrix(m), ioff, joff);
}
void gemm(const char* transa, const ConstGeneralMatrix& a, void gemm(const char *transa, const ConstGeneralMatrix &a,
const char* transb, const ConstGeneralMatrix& b, const char *transb, const ConstGeneralMatrix &b,
double alpha, double beta); double alpha, double beta);
void gemm(const char* transa, const GeneralMatrix& a, void
const char* transb, const GeneralMatrix& b, gemm(const char *transa, const GeneralMatrix &a,
double alpha, double beta) const char *transb, const GeneralMatrix &b,
{gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b), double alpha, double beta)
alpha, beta);} {
gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b),
alpha, beta);
}
/* this = this * op(m) (without whole copy of this) */ /* this = this * op(m) (without whole copy of this) */
void gemm_partial_right(const char* trans, const ConstGeneralMatrix& m, void gemm_partial_right(const char *trans, const ConstGeneralMatrix &m,
double alpha, double beta); double alpha, double beta);
void gemm_partial_right(const char* trans, const GeneralMatrix& m, void
double alpha, double beta) gemm_partial_right(const char *trans, const GeneralMatrix &m,
{gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);} double alpha, double beta)
{
gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);
}
/* this = op(m) *this (without whole copy of this) */ /* this = op(m) *this (without whole copy of this) */
void gemm_partial_left(const char* trans, const ConstGeneralMatrix& m, void gemm_partial_left(const char *trans, const ConstGeneralMatrix &m,
double alpha, double beta); double alpha, double beta);
void gemm_partial_left(const char* trans, const GeneralMatrix& m, void
double alpha, double beta) gemm_partial_left(const char *trans, const GeneralMatrix &m,
{gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);} double alpha, double beta)
{
gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);
}
/* number of rows/columns for copy used in gemm_partial_* */ /* number of rows/columns for copy used in gemm_partial_* */
static int md_length; static int md_length;
}; };
class SVDDecomp { class SVDDecomp
{
protected: protected:
/** Minimum of number of rows and columns of the decomposed /** Minimum of number of rows and columns of the decomposed
* matrix. */ * matrix. */
const int minmn; const int minmn;
/** Singular values. */ /** Singular values. */
Vector sigma; Vector sigma;
/** Orthogonal matrix U. */ /** Orthogonal matrix U. */
GeneralMatrix U; GeneralMatrix U;
/** Orthogonal matrix V^T. */ /** Orthogonal matrix V^T. */
GeneralMatrix VT; GeneralMatrix VT;
/** Convered flag. */ /** Convered flag. */
bool conv; bool conv;
public: public:
SVDDecomp(const GeneralMatrix& A) SVDDecomp(const GeneralMatrix &A)
: minmn(std::min<int>(A.numRows(), A.numCols())), : minmn(std::min<int>(A.numRows(), A.numCols())),
sigma(minmn), sigma(minmn),
U(A.numRows(), A.numRows()), U(A.numRows(), A.numRows()),
VT(A.numCols(), A.numCols()), VT(A.numCols(), A.numCols()),
conv(false) conv(false)
{construct(A);} {
const GeneralMatrix& getU() const construct(A);
{return U;} }
const GeneralMatrix& getVT() const const GeneralMatrix &
{return VT;} getU() const
void solve(const GeneralMatrix& B, GeneralMatrix& X) const; {
void solve(const Vector& b, Vector& x) const return U;
{ }
GeneralMatrix xmat(x.base(), x.length(), 1); const GeneralMatrix &
solve(GeneralMatrix(b.base(), b.length(), 1), xmat); getVT() const
} {
return VT;
}
void solve(const GeneralMatrix &B, GeneralMatrix &X) const;
void
solve(const Vector &b, Vector &x) const
{
GeneralMatrix xmat(x.base(), x.length(), 1);
solve(GeneralMatrix(b.base(), b.length(), 1), xmat);
}
private: private:
void construct(const GeneralMatrix& A); void construct(const GeneralMatrix &A);
}; };
#endif /* GENERAL_MATRIX_H */ #endif /* GENERAL_MATRIX_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -10,52 +10,73 @@
#include "SimilarityDecomp.h" #include "SimilarityDecomp.h"
#include "SylvesterSolver.h" #include "SylvesterSolver.h"
class GeneralSylvester { class GeneralSylvester
SylvParams pars; {
SylvMemoryDriver mem_driver; SylvParams pars;
int order; SylvMemoryDriver mem_driver;
const SqSylvMatrix a; int order;
const SylvMatrix b; const SqSylvMatrix a;
const SqSylvMatrix c; const SylvMatrix b;
SylvMatrix d; const SqSylvMatrix c;
bool solved; SylvMatrix d;
SchurDecompZero* bdecomp; bool solved;
SimilarityDecomp* cdecomp; SchurDecompZero *bdecomp;
SylvesterSolver* sylv; SimilarityDecomp *cdecomp;
SylvesterSolver *sylv;
public: public:
/* construct with my copy of d*/ /* construct with my copy of d*/
GeneralSylvester(int ord, int n, int m, int zero_cols, GeneralSylvester(int ord, int n, int m, int zero_cols,
const double* da, const double* db, const double *da, const double *db,
const double* dc, const double* dd, const double *dc, const double *dd,
const SylvParams& ps); const SylvParams &ps);
GeneralSylvester(int ord, int n, int m, int zero_cols, GeneralSylvester(int ord, int n, int m, int zero_cols,
const double* da, const double* db, const double *da, const double *db,
const double* dc, const double* dd, const double *dc, const double *dd,
bool alloc_for_check = false); bool alloc_for_check = false);
/* construct with provided storage for d */ /* construct with provided storage for d */
GeneralSylvester(int ord, int n, int m, int zero_cols, GeneralSylvester(int ord, int n, int m, int zero_cols,
const double* da, const double* db, const double *da, const double *db,
const double* dc, double* dd, const double *dc, double *dd,
bool alloc_for_check = false); bool alloc_for_check = false);
GeneralSylvester(int ord, int n, int m, int zero_cols, GeneralSylvester(int ord, int n, int m, int zero_cols,
const double* da, const double* db, const double *da, const double *db,
const double* dc, double* dd, const double *dc, double *dd,
const SylvParams& ps); const SylvParams &ps);
virtual ~GeneralSylvester(); virtual
int getM() const {return c.numRows();} ~GeneralSylvester();
int getN() const {return a.numRows();} int
const double* getResult() const {return d.base();} getM() const
const SylvParams& getParams() const {return pars;} {
SylvParams& getParams() {return pars;} return c.numRows();
void solve(); }
void check(const double* ds); int
getN() const
{
return a.numRows();
}
const double *
getResult() const
{
return d.base();
}
const SylvParams &
getParams() const
{
return pars;
}
SylvParams &
getParams()
{
return pars;
}
void solve();
void check(const double *ds);
private: private:
void init(); void init();
}; };
#endif /* GENERAL_SYLVESTER_H */ #endif /* GENERAL_SYLVESTER_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -10,24 +10,30 @@
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
#include "SimilarityDecomp.h" #include "SimilarityDecomp.h"
class IterativeSylvester : public SylvesterSolver { class IterativeSylvester : public SylvesterSolver
{
public: public:
IterativeSylvester(const QuasiTriangular& k, const QuasiTriangular& f) IterativeSylvester(const QuasiTriangular &k, const QuasiTriangular &f)
: SylvesterSolver(k, f) {} : SylvesterSolver(k, f)
IterativeSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp) {
: SylvesterSolver(kdecomp, fdecomp) {} }
IterativeSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp) IterativeSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp)
: SylvesterSolver(kdecomp, fdecomp) {} : SylvesterSolver(kdecomp, fdecomp)
void solve(SylvParams& pars, KronVector& x) const; {
}
IterativeSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp)
: SylvesterSolver(kdecomp, fdecomp)
{
}
void solve(SylvParams &pars, KronVector &x) const;
private: private:
double performFirstStep(KronVector& x) const; double performFirstStep(KronVector &x) const;
static double performStep(const QuasiTriangular& k, const QuasiTriangular& f, static double performStep(const QuasiTriangular &k, const QuasiTriangular &f,
KronVector& x); KronVector &x);
}; };
#endif /* ITERATIVE_SYLVESTER_H */ #endif /* ITERATIVE_SYLVESTER_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -8,21 +8,22 @@
#include "KronVector.h" #include "KronVector.h"
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
class KronUtils { class KronUtils
{
public: public:
/* multiplies I_m\otimes..\I_m\otimes T\otimes I_m...I_m\otimes I_n /* multiplies I_m\otimes..\I_m\otimes T\otimes I_m...I_m\otimes I_n
with given b and returns x. T must be (m,m), number of with given b and returns x. T must be (m,m), number of
\otimes is b.getDepth(), level is a number of I_m's between T \otimes is b.getDepth(), level is a number of I_m's between T
and I_n plus 1. If level=0, then we multiply and I_n plus 1. If level=0, then we multiply
\I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */ \I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */
static void multAtLevel(int level, const QuasiTriangular& t, static void multAtLevel(int level, const QuasiTriangular &t,
KronVector& x); KronVector &x);
static void multAtLevelTrans(int level, const QuasiTriangular& t, static void multAtLevelTrans(int level, const QuasiTriangular &t,
KronVector& x); KronVector &x);
/* multiplies x=(F'\otimes F'\otimes..\otimes K)x */ /* multiplies x=(F'\otimes F'\otimes..\otimes K)x */
static void multKron(const QuasiTriangular& f, const QuasiTriangular& k, static void multKron(const QuasiTriangular &f, const QuasiTriangular &k,
KronVector& x); KronVector &x);
}; };
#endif /* KRON_UTILS_H */ #endif /* KRON_UTILS_H */

View File

@ -9,44 +9,77 @@
class ConstKronVector; class ConstKronVector;
class KronVector : public Vector { class KronVector : public Vector
{
protected: protected:
int m; int m;
int n; int n;
int depth; int depth;
public: public:
KronVector() : Vector((double*)0, 0), m(0), n(0), depth(0) {} KronVector() : Vector((double *) 0, 0), m(0), n(0), depth(0)
KronVector(int mm, int nn, int dp); // new instance {
KronVector(Vector& v, int mm, int nn, int dp); // conversion }
KronVector(KronVector&, int i); // picks i-th subvector KronVector(int mm, int nn, int dp); // new instance
KronVector(const ConstKronVector& v); // new instance and copy KronVector(Vector &v, int mm, int nn, int dp); // conversion
const KronVector& operator=(KronVector& v) KronVector(KronVector &, int i); // picks i-th subvector
{Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;} KronVector(const ConstKronVector &v); // new instance and copy
const KronVector& operator=(const KronVector& v) const KronVector &
{Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;} operator=(KronVector &v)
const KronVector& operator=(const ConstKronVector& v); {
const KronVector& operator=(const Vector& v); Vector::operator=(v); m = v.m; n = v.n; depth = v.depth; return *this;
int getM() const {return m;} }
int getN() const {return n;} const KronVector &
int getDepth() const {return depth;} operator=(const KronVector &v)
{
Vector::operator=(v); m = v.m; n = v.n; depth = v.depth; return *this;
}
const KronVector &operator=(const ConstKronVector &v);
const KronVector &operator=(const Vector &v);
int
getM() const
{
return m;
}
int
getN() const
{
return n;
}
int
getDepth() const
{
return depth;
}
}; };
class ConstKronVector : public ConstVector class ConstKronVector : public ConstVector
{ {
protected: protected:
int m; int m;
int n; int n;
int depth; int depth;
public: public:
ConstKronVector(const KronVector& v); ConstKronVector(const KronVector &v);
ConstKronVector(const ConstKronVector& v); ConstKronVector(const ConstKronVector &v);
ConstKronVector(const Vector& v, int mm, int nn, int dp); ConstKronVector(const Vector &v, int mm, int nn, int dp);
ConstKronVector(const ConstVector& v, int mm, int nn, int dp); ConstKronVector(const ConstVector &v, int mm, int nn, int dp);
ConstKronVector(const KronVector& v, int i); ConstKronVector(const KronVector &v, int i);
ConstKronVector(const ConstKronVector& v, int i); ConstKronVector(const ConstKronVector &v, int i);
int getM() const {return m;} int
int getN() const {return n;} getM() const
int getDepth() const {return depth;} {
return m;
}
int
getN() const
{
return n;
}
int
getDepth() const
{
return depth;
}
}; };
int power(int m, int depth); int power(int m, int depth);

View File

@ -15,325 +15,521 @@ using namespace std;
class DiagonalBlock; class DiagonalBlock;
class Diagonal; class Diagonal;
class DiagPair { class DiagPair
{
private: private:
double* a1; double *a1;
double* a2; double *a2;
public: public:
DiagPair() {} DiagPair()
DiagPair(double* aa1, double* aa2) {a1 = aa1; a2 = aa2;} {
DiagPair(const DiagPair& p) {a1 = p.a1; a2 = p.a2;} }
const DiagPair& operator=(const DiagPair& p) {a1 = p.a1; a2 = p.a2; return *this;} DiagPair(double *aa1, double *aa2)
const DiagPair& operator=(double v) {*a1 = v; *a2 = v; return *this;} {
const double& operator*() const {return *a1;} a1 = aa1; a2 = aa2;
/** here we must not define double& operator*(), since it wouldn't }
rewrite both values, we use operator= for this */ DiagPair(const DiagPair &p)
friend class Diagonal; {
friend class DiagonalBlock; a1 = p.a1; a2 = p.a2;
}
const DiagPair &
operator=(const DiagPair &p)
{
a1 = p.a1; a2 = p.a2; return *this;
}
const DiagPair &
operator=(double v)
{
*a1 = v; *a2 = v; return *this;
}
const double &
operator*() const
{
return *a1;
}
/** here we must not define double& operator*(), since it wouldn't
rewrite both values, we use operator= for this */
friend class Diagonal;
friend class DiagonalBlock;
}; };
class DiagonalBlock { class DiagonalBlock
{
private: private:
int jbar; int jbar;
bool real; bool real;
DiagPair alpha; DiagPair alpha;
double* beta1; double *beta1;
double* beta2; double *beta2;
void copy(const DiagonalBlock& b) { void
jbar = b.jbar; copy(const DiagonalBlock &b)
real = b.real; {
alpha = b.alpha; jbar = b.jbar;
beta1 = b.beta1; real = b.real;
beta2 = b.beta2; alpha = b.alpha;
} beta1 = b.beta1;
beta2 = b.beta2;
}
public: public:
DiagonalBlock() {} DiagonalBlock()
DiagonalBlock(int jb, bool r, double* a1, double* a2, {
double* b1, double* b2) }
: alpha(a1, a2) DiagonalBlock(int jb, bool r, double *a1, double *a2,
{ double *b1, double *b2)
jbar = jb; : alpha(a1, a2)
real = r; {
beta1 = b1; jbar = jb;
beta2 = b2; real = r;
} beta1 = b1;
// construct complex block beta2 = b2;
DiagonalBlock(int jb, double* a1, double* a2) }
: alpha(a1, a2) // construct complex block
{ DiagonalBlock(int jb, double *a1, double *a2)
jbar = jb; : alpha(a1, a2)
real = false; {
beta1 = a2 - 1; jbar = jb;
beta2 = a1 + 1; real = false;
} beta1 = a2 - 1;
// construct real block beta2 = a1 + 1;
DiagonalBlock(int jb, double* a1) }
: alpha(a1, a1) // construct real block
{ DiagonalBlock(int jb, double *a1)
jbar = jb; : alpha(a1, a1)
real = true; {
beta1 = 0; jbar = jb;
beta2 = 0; real = true;
} beta1 = 0;
DiagonalBlock(const DiagonalBlock& b) beta2 = 0;
{copy(b);} }
const DiagonalBlock& operator=(const DiagonalBlock& b) DiagonalBlock(const DiagonalBlock &b)
{copy(b); return *this;} {
int getIndex() const copy(b);
{return jbar;} }
bool isReal() const const DiagonalBlock &
{return real;} operator=(const DiagonalBlock &b)
const DiagPair& getAlpha() const {
{return alpha;} copy(b); return *this;
DiagPair& getAlpha() }
{return alpha;} int
double& getBeta1() const getIndex() const
{return *beta1;} {
double& getBeta2() const return jbar;
{return *beta2;} }
double getDeterminant() const; bool
double getSBeta() const; isReal() const
double getSize() const; {
void setReal(); return real;
// for debugging }
void checkBlock(const double* d, int d_size); const DiagPair &
friend class Diagonal; getAlpha() const
{
return alpha;
}
DiagPair &
getAlpha()
{
return alpha;
}
double &
getBeta1() const
{
return *beta1;
}
double &
getBeta2() const
{
return *beta2;
}
double getDeterminant() const;
double getSBeta() const;
double getSize() const;
void setReal();
// for debugging
void checkBlock(const double *d, int d_size);
friend class Diagonal;
}; };
template <class _Tdiag, class _Tblock, class _Titer> template <class _Tdiag, class _Tblock, class _Titer>
struct _diag_iter { struct _diag_iter
typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self; {
_Tdiag diag; typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self;
_Titer it; _Tdiag diag;
_Titer it;
public: public:
_diag_iter(_Tdiag d, _Titer iter) : diag(d), it(iter) {} _diag_iter(_Tdiag d, _Titer iter) : diag(d), it(iter)
_Tblock operator*() const {return *it;} {
_Self& operator++() {++it; return *this;} }
_Self& operator--() {--it; return *this;} _Tblock
bool operator==(const _Self& x) const {return x.it == it;} operator*() const
bool operator!=(const _Self& x) const {return x.it != it;} {
const _Self& operator=(const _Self& x) {it = x.it; return *this;} return *it;
_Titer iter() const {return it;} }
_Self &
operator++()
{
++it; return *this;
}
_Self &
operator--()
{
--it; return *this;
}
bool
operator==(const _Self &x) const
{
return x.it == it;
}
bool
operator!=(const _Self &x) const
{
return x.it != it;
}
const _Self &
operator=(const _Self &x)
{
it = x.it; return *this;
}
_Titer
iter() const
{
return it;
}
}; };
class Diagonal { class Diagonal
{
public: public:
typedef _diag_iter<const Diagonal&, const DiagonalBlock&, list<DiagonalBlock>::const_iterator> const_diag_iter; typedef _diag_iter<const Diagonal &, const DiagonalBlock &, list<DiagonalBlock>::const_iterator> const_diag_iter;
typedef _diag_iter<Diagonal&, DiagonalBlock&, list<DiagonalBlock>::iterator> diag_iter; typedef _diag_iter<Diagonal &, DiagonalBlock &, list<DiagonalBlock>::iterator> diag_iter;
private: private:
int num_all; int num_all;
list<DiagonalBlock> blocks; list<DiagonalBlock> blocks;
int num_real; int num_real;
void copy(const Diagonal&); void copy(const Diagonal &);
public: public:
Diagonal() : num_all(0), num_real(0) {} Diagonal() : num_all(0), num_real(0)
Diagonal(double* data, int d_size); {
Diagonal(double* data, const Diagonal& d); }
Diagonal(const Diagonal& d) {copy(d);} Diagonal(double *data, int d_size);
const Diagonal& operator =(const Diagonal& d) {copy(d); return *this;} Diagonal(double *data, const Diagonal &d);
virtual ~Diagonal() {} Diagonal(const Diagonal &d)
{
copy(d);
}
const Diagonal &
operator=(const Diagonal &d)
{
copy(d); return *this;
}
virtual ~Diagonal()
{
}
int getNumComplex() const {return num_all - num_real;} int
int getNumReal() const {return num_real;} getNumComplex() const
int getSize() const {return getNumReal() + 2*getNumComplex();} {
int getNumBlocks() const {return num_all;} return num_all - num_real;
void getEigenValues(Vector& eig) const; }
void swapLogically(diag_iter it); int
void checkConsistency(diag_iter it); getNumReal() const
double getAverageSize(diag_iter start, diag_iter end); {
diag_iter findClosestBlock(diag_iter start, diag_iter end, double a); return num_real;
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a); }
void print() const; int
getSize() const
{
return getNumReal() + 2*getNumComplex();
}
int
getNumBlocks() const
{
return num_all;
}
void getEigenValues(Vector &eig) const;
void swapLogically(diag_iter it);
void checkConsistency(diag_iter it);
double getAverageSize(diag_iter start, diag_iter end);
diag_iter findClosestBlock(diag_iter start, diag_iter end, double a);
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
void print() const;
diag_iter begin() diag_iter
{return diag_iter(*this, blocks.begin());} begin()
const_diag_iter begin() const {
{return const_diag_iter(*this, blocks.begin());} return diag_iter(*this, blocks.begin());
diag_iter end() }
{return diag_iter(*this, blocks.end());} const_diag_iter
const_diag_iter end() const begin() const
{return const_diag_iter(*this, blocks.end());} {
return const_diag_iter(*this, blocks.begin());
}
diag_iter
end()
{
return diag_iter(*this, blocks.end());
}
const_diag_iter
end() const
{
return const_diag_iter(*this, blocks.end());
}
/* redefine pointers as data start at p */ /* redefine pointers as data start at p */
void changeBase(double* p); void changeBase(double *p);
private: private:
static double EPS; static double EPS;
static int getNumComplex(const double* data, int d_size); static int getNumComplex(const double *data, int d_size);
static bool isZero(double p); static bool isZero(double p);
}; };
template <class _TRef, class _TPtr> template <class _TRef, class _TPtr>
struct _matrix_iter { struct _matrix_iter
typedef _matrix_iter<_TRef, _TPtr> _Self; {
int d_size; typedef _matrix_iter<_TRef, _TPtr> _Self;
bool real; int d_size;
_TPtr ptr; bool real;
_TPtr ptr;
public: public:
_matrix_iter(_TPtr base, int ds, bool r) _matrix_iter(_TPtr base, int ds, bool r)
{ptr = base; d_size = ds; real = r;} {
virtual ~_matrix_iter() {} ptr = base; d_size = ds; real = r;
const _Self& operator=(const _Self& it) }
{ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;} virtual ~_matrix_iter()
bool operator==(const _Self& it) const {
{return ptr == it.ptr;} }
bool operator!=(const _Self& it) const const _Self &
{return ptr != it.ptr;} operator=(const _Self &it)
_TRef operator*() const {
{return *ptr;} ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;
_TRef a() const }
{return *ptr;} bool
virtual _Self& operator++() =0; operator==(const _Self &it) const
{
return ptr == it.ptr;
}
bool
operator!=(const _Self &it) const
{
return ptr != it.ptr;
}
_TRef
operator*() const
{
return *ptr;
}
_TRef
a() const
{
return *ptr;
}
virtual _Self &operator++() = 0;
}; };
template <class _TRef, class _TPtr> template <class _TRef, class _TPtr>
class _column_iter : public _matrix_iter<_TRef, _TPtr> { class _column_iter : public _matrix_iter<_TRef, _TPtr>
typedef _matrix_iter<_TRef, _TPtr> _Tparent; {
typedef _column_iter<_TRef, _TPtr> _Self; typedef _matrix_iter<_TRef, _TPtr> _Tparent;
int row; typedef _column_iter<_TRef, _TPtr> _Self;
int row;
public: public:
_column_iter(_TPtr base, int ds, bool r, int rw) _column_iter(_TPtr base, int ds, bool r, int rw)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw) {}; : _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw)
_Self& operator++() {
{_Tparent::ptr++; row++; return *this;} };
_TRef b() const _Self &
{ operator++()
if (_Tparent::real) { {
return *(_Tparent::ptr); _Tparent::ptr++; row++; return *this;
} else { }
return *(_Tparent::ptr+_Tparent::d_size); _TRef
} b() const
} {
int getRow() const {return row;} if (_Tparent::real)
{
return *(_Tparent::ptr);
}
else
{
return *(_Tparent::ptr+_Tparent::d_size);
}
}
int
getRow() const
{
return row;
}
}; };
template <class _TRef, class _TPtr> template <class _TRef, class _TPtr>
class _row_iter : public _matrix_iter<_TRef, _TPtr> { class _row_iter : public _matrix_iter<_TRef, _TPtr>
typedef _matrix_iter<_TRef, _TPtr> _Tparent; {
typedef _row_iter<_TRef, _TPtr> _Self; typedef _matrix_iter<_TRef, _TPtr> _Tparent;
int col; typedef _row_iter<_TRef, _TPtr> _Self;
int col;
public: public:
_row_iter(_TPtr base, int ds, bool r, int cl) _row_iter(_TPtr base, int ds, bool r, int cl)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl) {}; : _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl)
_Self& operator++() {
{_Tparent::ptr += _Tparent::d_size; col++; return *this;} };
virtual _TRef b() const _Self &
{ operator++()
if (_Tparent::real) { {
return *(_Tparent::ptr); _Tparent::ptr += _Tparent::d_size; col++; return *this;
}else { }
return *(_Tparent::ptr+1); virtual _TRef
} b() const
} {
int getCol() const {return col;} if (_Tparent::real)
{
return *(_Tparent::ptr);
}
else
{
return *(_Tparent::ptr+1);
}
}
int
getCol() const
{
return col;
}
}; };
class SchurDecomp; class SchurDecomp;
class SchurDecompZero; class SchurDecompZero;
class QuasiTriangular : public SqSylvMatrix { class QuasiTriangular : public SqSylvMatrix
{
public: public:
typedef _column_iter<const double&, const double*> const_col_iter; typedef _column_iter<const double &, const double *> const_col_iter;
typedef _column_iter<double&, double*> col_iter; typedef _column_iter<double &, double *> col_iter;
typedef _row_iter<const double&, const double*> const_row_iter; typedef _row_iter<const double &, const double *> const_row_iter;
typedef _row_iter<double&, double*> row_iter; typedef _row_iter<double &, double *> row_iter;
typedef Diagonal::const_diag_iter const_diag_iter; typedef Diagonal::const_diag_iter const_diag_iter;
typedef Diagonal::diag_iter diag_iter; typedef Diagonal::diag_iter diag_iter;
protected: protected:
Diagonal diagonal; Diagonal diagonal;
public: public:
QuasiTriangular(const double* d, int d_size); QuasiTriangular(const double *d, int d_size);
QuasiTriangular(double r, const QuasiTriangular& t); QuasiTriangular(double r, const QuasiTriangular &t);
QuasiTriangular(double r, const QuasiTriangular& t, QuasiTriangular(double r, const QuasiTriangular &t,
double rr, const QuasiTriangular& tt); double rr, const QuasiTriangular &tt);
QuasiTriangular(int p, const QuasiTriangular& t); QuasiTriangular(int p, const QuasiTriangular &t);
QuasiTriangular(const SchurDecomp& decomp); QuasiTriangular(const SchurDecomp &decomp);
QuasiTriangular(const SchurDecompZero& decomp); QuasiTriangular(const SchurDecompZero &decomp);
QuasiTriangular(const QuasiTriangular& t); QuasiTriangular(const QuasiTriangular &t);
virtual ~QuasiTriangular(); virtual
const Diagonal& getDiagonal() const {return diagonal;} ~QuasiTriangular();
int getNumOffdiagonal() const; const Diagonal &
void swapDiagLogically(diag_iter it); getDiagonal() const
void checkDiagConsistency(diag_iter it); {
double getAverageDiagSize(diag_iter start, diag_iter end); return diagonal;
diag_iter findClosestDiagBlock(diag_iter start, diag_iter end, double a); }
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a); int getNumOffdiagonal() const;
void swapDiagLogically(diag_iter it);
void checkDiagConsistency(diag_iter it);
double getAverageDiagSize(diag_iter start, diag_iter end);
diag_iter findClosestDiagBlock(diag_iter start, diag_iter end, double a);
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
/* (I+T)y = x, y-->x */
virtual void solvePre(Vector &x, double &eig_min);
/* (I+T')y = x, y-->x */
virtual void solvePreTrans(Vector &x, double &eig_min);
/* (I+T)x = b */
virtual void solve(Vector &x, const ConstVector &b, double &eig_min);
/* (I+T')x = b */
virtual void solveTrans(Vector &x, const ConstVector &b, double &eig_min);
/* x = Tb */
virtual void multVec(Vector &x, const ConstVector &b) const;
/* x = T'b */
virtual void multVecTrans(Vector &x, const ConstVector &b) const;
/* x = x + Tb */
virtual void multaVec(Vector &x, const ConstVector &b) const;
/* x = x + T'b */
virtual void multaVecTrans(Vector &x, const ConstVector &b) const;
/* x = (T\otimes I)x */
virtual void multKron(KronVector &x) const;
/* x = (T'\otimes I)x */
virtual void multKronTrans(KronVector &x) const;
/* A = T*A */
virtual void multLeftOther(GeneralMatrix &a) const;
/* A = T'*A */
virtual void multLeftOtherTrans(GeneralMatrix &a) const;
/* (I+T)y = x, y-->x */ const_diag_iter
virtual void solvePre(Vector& x, double& eig_min); diag_begin() const
/* (I+T')y = x, y-->x */ {
virtual void solvePreTrans(Vector& x, double& eig_min); return diagonal.begin();
/* (I+T)x = b */ }
virtual void solve(Vector& x, const ConstVector& b, double& eig_min); diag_iter
/* (I+T')x = b */ diag_begin()
virtual void solveTrans(Vector& x, const ConstVector& b, double& eig_min); {
/* x = Tb */ return diagonal.begin();
virtual void multVec(Vector& x, const ConstVector& b) const; }
/* x = T'b */ const_diag_iter
virtual void multVecTrans(Vector& x, const ConstVector& b) const; diag_end() const
/* x = x + Tb */ {
virtual void multaVec(Vector& x, const ConstVector& b) const; return diagonal.end();
/* x = x + T'b */ }
virtual void multaVecTrans(Vector& x, const ConstVector& b) const; diag_iter
/* x = (T\otimes I)x */ diag_end()
virtual void multKron(KronVector& x) const; {
/* x = (T'\otimes I)x */ return diagonal.end();
virtual void multKronTrans(KronVector& x) const; }
/* A = T*A */
virtual void multLeftOther(GeneralMatrix& a) const;
/* A = T'*A */
virtual void multLeftOtherTrans(GeneralMatrix& a) const;
const_diag_iter diag_begin() const /* iterators for off diagonal elements */
{return diagonal.begin();} virtual const_col_iter col_begin(const DiagonalBlock &b) const;
diag_iter diag_begin() virtual col_iter col_begin(const DiagonalBlock &b);
{return diagonal.begin();} virtual const_row_iter row_begin(const DiagonalBlock &b) const;
const_diag_iter diag_end() const virtual row_iter row_begin(const DiagonalBlock &b);
{return diagonal.end();} virtual const_col_iter col_end(const DiagonalBlock &b) const;
diag_iter diag_end() virtual col_iter col_end(const DiagonalBlock &b);
{return diagonal.end();} virtual const_row_iter row_end(const DiagonalBlock &b) const;
virtual row_iter row_end(const DiagonalBlock &b);
/* iterators for off diagonal elements */ /* clone */
virtual const_col_iter col_begin(const DiagonalBlock& b) const; virtual QuasiTriangular *
virtual col_iter col_begin(const DiagonalBlock& b); clone() const
virtual const_row_iter row_begin(const DiagonalBlock& b) const; {
virtual row_iter row_begin(const DiagonalBlock& b); return new QuasiTriangular(*this);
virtual const_col_iter col_end(const DiagonalBlock& b) const; }
virtual col_iter col_end(const DiagonalBlock& b); virtual QuasiTriangular *
virtual const_row_iter row_end(const DiagonalBlock& b) const; clone(int p, const QuasiTriangular &t) const
virtual row_iter row_end(const DiagonalBlock& b); {
return new QuasiTriangular(p, t);
/* clone */ }
virtual QuasiTriangular* clone() const virtual QuasiTriangular *
{return new QuasiTriangular(*this);} clone(double r) const
virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const {
{return new QuasiTriangular(p, t);} return new QuasiTriangular(r, *this);
virtual QuasiTriangular* clone(double r) const }
{return new QuasiTriangular(r, *this);} virtual QuasiTriangular *
virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const clone(double r, double rr, const QuasiTriangular &tt) const
{return new QuasiTriangular(r, *this, rr, tt);} {
return new QuasiTriangular(r, *this, rr, tt);
}
protected: protected:
void setMatrix(double r, const QuasiTriangular& t); void setMatrix(double r, const QuasiTriangular &t);
void addMatrix(double r, const QuasiTriangular& t); void addMatrix(double r, const QuasiTriangular &t);
private: private:
void addUnit(); void addUnit();
/* x = x + (T\otimes I)b */ /* x = x + (T\otimes I)b */
void multaKron(KronVector& x, const ConstKronVector& b) const; void multaKron(KronVector &x, const ConstKronVector &b) const;
/* x = x + (T'\otimes I)b */ /* x = x + (T'\otimes I)b */
void multaKronTrans(KronVector& x, const ConstKronVector& b) const; void multaKronTrans(KronVector &x, const ConstKronVector &b) const;
/* implementation via iterators, useful for large matrices */ /* implementation via iterators, useful for large matrices */
void setMatrixViaIter(double r, const QuasiTriangular& t); void setMatrixViaIter(double r, const QuasiTriangular &t);
void addMatrixViaIter(double r, const QuasiTriangular& t); void addMatrixViaIter(double r, const QuasiTriangular &t);
/* hide noneffective implementations of parents */ /* hide noneffective implementations of parents */
void multsVec(Vector& x, const ConstVector& d) const; void multsVec(Vector &x, const ConstVector &d) const;
void multsVecTrans(Vector& x, const ConstVector& d) const; void multsVecTrans(Vector &x, const ConstVector &d) const;
}; };
#endif /* QUASI_TRIANGULAR_H */ #endif /* QUASI_TRIANGULAR_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -8,37 +8,50 @@
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
#include "GeneralMatrix.h" #include "GeneralMatrix.h"
class QuasiTriangularZero : public QuasiTriangular { class QuasiTriangularZero : public QuasiTriangular
int nz; // number of zero columns {
GeneralMatrix ru; // data in right upper part (nz,d_size) int nz; // number of zero columns
GeneralMatrix ru; // data in right upper part (nz,d_size)
public: public:
QuasiTriangularZero(int num_zeros, const double* d, int d_size); QuasiTriangularZero(int num_zeros, const double *d, int d_size);
QuasiTriangularZero(double r, const QuasiTriangularZero& t); QuasiTriangularZero(double r, const QuasiTriangularZero &t);
QuasiTriangularZero(double r, const QuasiTriangularZero& t, QuasiTriangularZero(double r, const QuasiTriangularZero &t,
double rr, const QuasiTriangularZero& tt); double rr, const QuasiTriangularZero &tt);
QuasiTriangularZero(int p, const QuasiTriangularZero& t); QuasiTriangularZero(int p, const QuasiTriangularZero &t);
QuasiTriangularZero(const QuasiTriangular& t); QuasiTriangularZero(const QuasiTriangular &t);
QuasiTriangularZero(const SchurDecompZero& decomp); QuasiTriangularZero(const SchurDecompZero &decomp);
~QuasiTriangularZero(); ~QuasiTriangularZero();
void solvePre(Vector& x, double& eig_min); void solvePre(Vector &x, double &eig_min);
void solvePreTrans(Vector& x, double& eig_min); void solvePreTrans(Vector &x, double &eig_min);
void multVec(Vector& x, const ConstVector& b) const; void multVec(Vector &x, const ConstVector &b) const;
void multVecTrans(Vector& x, const ConstVector& b) const; void multVecTrans(Vector &x, const ConstVector &b) const;
void multaVec(Vector& x, const ConstVector& b) const; void multaVec(Vector &x, const ConstVector &b) const;
void multaVecTrans(Vector& x, const ConstVector& b) const; void multaVecTrans(Vector &x, const ConstVector &b) const;
void multKron(KronVector& x) const; void multKron(KronVector &x) const;
void multKronTrans(KronVector& x) const; void multKronTrans(KronVector &x) const;
void multLeftOther(GeneralMatrix& a) const; void multLeftOther(GeneralMatrix &a) const;
/* clone */ /* clone */
virtual QuasiTriangular* clone() const virtual QuasiTriangular *
{return new QuasiTriangularZero(*this);} clone() const
virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const {
{return new QuasiTriangularZero(p, (const QuasiTriangularZero&)t);} return new QuasiTriangularZero(*this);
virtual QuasiTriangular* clone(double r) const }
{return new QuasiTriangularZero(r, *this);} virtual QuasiTriangular *
virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const clone(int p, const QuasiTriangular &t) const
{return new QuasiTriangularZero(r, *this, rr, (const QuasiTriangularZero&)tt);} {
void print() const; return new QuasiTriangularZero(p, (const QuasiTriangularZero &) t);
}
virtual QuasiTriangular *
clone(double r) const
{
return new QuasiTriangularZero(r, *this);
}
virtual QuasiTriangular *
clone(double r, double rr, const QuasiTriangular &tt) const
{
return new QuasiTriangularZero(r, *this, rr, (const QuasiTriangularZero &) tt);
}
void print() const;
}; };
#endif /* QUASI_TRIANGULAR_ZERO_H */ #endif /* QUASI_TRIANGULAR_ZERO_H */

View File

@ -9,35 +9,61 @@
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
class QuasiTriangular; class QuasiTriangular;
class SchurDecomp { class SchurDecomp
bool q_destroy; {
SqSylvMatrix* q; bool q_destroy;
bool t_destroy; SqSylvMatrix *q;
QuasiTriangular* t; bool t_destroy;
QuasiTriangular *t;
public: public:
SchurDecomp(const SqSylvMatrix& m); SchurDecomp(const SqSylvMatrix &m);
SchurDecomp(const QuasiTriangular& tr); SchurDecomp(const QuasiTriangular &tr);
SchurDecomp(QuasiTriangular& tr); SchurDecomp(QuasiTriangular &tr);
const SqSylvMatrix& getQ() const {return *q;} const SqSylvMatrix &
const QuasiTriangular& getT() const {return *t;} getQ() const
SqSylvMatrix& getQ() {return *q;} {
QuasiTriangular& getT() {return *t;} return *q;
virtual int getDim() const; }
virtual ~SchurDecomp(); const QuasiTriangular &
getT() const
{
return *t;
}
SqSylvMatrix &
getQ()
{
return *q;
}
QuasiTriangular &
getT()
{
return *t;
}
virtual int getDim() const;
virtual
~SchurDecomp();
}; };
class SchurDecompZero : public SchurDecomp { class SchurDecompZero : public SchurDecomp
GeneralMatrix ru; /* right upper matrix */ {
GeneralMatrix ru; /* right upper matrix */
public: public:
SchurDecompZero(const GeneralMatrix& m); SchurDecompZero(const GeneralMatrix &m);
const GeneralMatrix& getRU() const {return ru;} const GeneralMatrix &
int getDim() const; getRU() const
int getZeroCols() const {return ru.numRows();} {
return ru;
}
int getDim() const;
int
getZeroCols() const
{
return ru.numRows();
}
}; };
#endif /* SCHUR_DECOMP_H */ #endif /* SCHUR_DECOMP_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -10,22 +10,27 @@
#include "SchurDecomp.h" #include "SchurDecomp.h"
#include "QuasiTriangular.h" #include "QuasiTriangular.h"
class SchurDecompEig : public SchurDecomp { class SchurDecompEig : public SchurDecomp
{
public: public:
typedef QuasiTriangular::diag_iter diag_iter; typedef QuasiTriangular::diag_iter diag_iter;
SchurDecompEig(const SqSylvMatrix& m) : SchurDecomp(m) {} SchurDecompEig(const SqSylvMatrix &m) : SchurDecomp(m)
SchurDecompEig(const QuasiTriangular& tr) : SchurDecomp(tr) {}; {
SchurDecompEig(QuasiTriangular& tr) : SchurDecomp(tr) {} }
diag_iter bubbleEigen(diag_iter from, diag_iter to); SchurDecompEig(const QuasiTriangular &tr) : SchurDecomp(tr)
void orderEigen(); {
};
SchurDecompEig(QuasiTriangular &tr) : SchurDecomp(tr)
{
}
diag_iter bubbleEigen(diag_iter from, diag_iter to);
void orderEigen();
protected: protected:
bool tryToSwap(diag_iter& it, diag_iter& itadd); bool tryToSwap(diag_iter &it, diag_iter &itadd);
}; };
#endif /* SCHUR_DECOMP_EIG_H */ #endif /* SCHUR_DECOMP_EIG_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -9,33 +9,43 @@
#include "BlockDiagonal.h" #include "BlockDiagonal.h"
#include "SylvParams.h" #include "SylvParams.h"
class SimilarityDecomp { class SimilarityDecomp
SqSylvMatrix* q; {
BlockDiagonal* b; SqSylvMatrix *q;
SqSylvMatrix* invq; BlockDiagonal *b;
typedef BlockDiagonal::diag_iter diag_iter; SqSylvMatrix *invq;
typedef BlockDiagonal::diag_iter diag_iter;
public: public:
SimilarityDecomp(const double* d, int d_size, double log10norm = 3.0); SimilarityDecomp(const double *d, int d_size, double log10norm = 3.0);
virtual ~SimilarityDecomp(); virtual
const SqSylvMatrix& getQ() const ~SimilarityDecomp();
{return *q;} const SqSylvMatrix &
const SqSylvMatrix& getInvQ() const getQ() const
{return *invq;} {
const BlockDiagonal& getB() const return *q;
{return *b;} }
void check(SylvParams& pars, const GeneralMatrix& m) const; const SqSylvMatrix &
void infoToPars(SylvParams& pars) const; getInvQ() const
{
return *invq;
}
const BlockDiagonal &
getB() const
{
return *b;
}
void check(SylvParams &pars, const GeneralMatrix &m) const;
void infoToPars(SylvParams &pars) const;
protected: protected:
void getXDim(diag_iter start, diag_iter end, int& rows, int& cols) const; void getXDim(diag_iter start, diag_iter end, int &rows, int &cols) const;
bool solveX(diag_iter start, diag_iter end, GeneralMatrix& X, double norm) const; bool solveX(diag_iter start, diag_iter end, GeneralMatrix &X, double norm) const;
void updateTransform(diag_iter start, diag_iter end, GeneralMatrix& X); void updateTransform(diag_iter start, diag_iter end, GeneralMatrix &X);
void bringGuiltyBlock(diag_iter start, diag_iter& end); void bringGuiltyBlock(diag_iter start, diag_iter &end);
void diagonalize(double norm); void diagonalize(double norm);
}; };
#endif /* SIMILARITY_DECOMP_H */ #endif /* SIMILARITY_DECOMP_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -7,24 +7,26 @@
#include "SylvMemory.h" #include "SylvMemory.h"
class SylvException : public MallocAllocator
class SylvException : public MallocAllocator { {
protected: protected:
char file[50]; char file[50];
int line; int line;
const SylvException* source; const SylvException *source;
public: public:
SylvException(const char* f, int l, const SylvException* s); SylvException(const char *f, int l, const SylvException *s);
virtual ~SylvException(); virtual
virtual int printMessage(char* str, int maxlen) const; ~SylvException();
void printMessage() const; virtual int printMessage(char *str, int maxlen) const;
void printMessage() const;
}; };
class SylvExceptionMessage : public SylvException { class SylvExceptionMessage : public SylvException
char message[500]; {
char message[500];
public: public:
SylvExceptionMessage(const char* f, int l, const char* mes); SylvExceptionMessage(const char *f, int l, const char *mes);
virtual int printMessage(char* str, int maxlen) const; virtual int printMessage(char *str, int maxlen) const;
}; };
// define macros: // define macros:
@ -33,7 +35,6 @@ public:
#endif /* SYLV_EXCEPTION_H */ #endif /* SYLV_EXCEPTION_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -10,72 +10,100 @@
class SqSylvMatrix; class SqSylvMatrix;
class SylvMatrix : public GeneralMatrix { class SylvMatrix : public GeneralMatrix
{
public: public:
SylvMatrix(int m, int n) SylvMatrix(int m, int n)
: GeneralMatrix(m,n) {} : GeneralMatrix(m, n)
SylvMatrix(const double* d, int m, int n) {
: GeneralMatrix(d, m, n) {} }
SylvMatrix(double* d, int m, int n) SylvMatrix(const double *d, int m, int n)
: GeneralMatrix(d, m, n) {} : GeneralMatrix(d, m, n)
SylvMatrix(const GeneralMatrix& m) {
: GeneralMatrix(m) {} }
SylvMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols) SylvMatrix(double *d, int m, int n)
: GeneralMatrix(m, i, j, nrows, ncols) {} : GeneralMatrix(d, m, n)
SylvMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols) {
: GeneralMatrix(m, i, j, nrows, ncols) {} }
SylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b) SylvMatrix(const GeneralMatrix &m)
: GeneralMatrix(a, b) {} : GeneralMatrix(m)
{
}
SylvMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols)
: GeneralMatrix(m, i, j, nrows, ncols)
{
}
SylvMatrix(GeneralMatrix &m, int i, int j, int nrows, int ncols)
: GeneralMatrix(m, i, j, nrows, ncols)
{
}
SylvMatrix(const GeneralMatrix &a, const GeneralMatrix &b)
: GeneralMatrix(a, b)
{
}
/* this = |I 0|* this /* this = |I 0|* this
|0 m| */ |0 m| */
void multLeftI(const SqSylvMatrix& m); void multLeftI(const SqSylvMatrix &m);
/* this = |I 0|* this /* this = |I 0|* this
|0 m'| */ |0 m'| */
void multLeftITrans(const SqSylvMatrix& m); void multLeftITrans(const SqSylvMatrix &m);
/* this = |0 a|*b, so that |0 a| is square */ /* this = |0 a|*b, so that |0 a| is square */
void multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b); void multLeft(int zero_cols, const GeneralMatrix &a, const GeneralMatrix &b);
/* this = this * (m\otimes m..\otimes m) */ /* this = this * (m\otimes m..\otimes m) */
void multRightKron(const SqSylvMatrix& m, int order); void multRightKron(const SqSylvMatrix &m, int order);
/* this = this * (m'\otimes m'..\otimes m') */ /* this = this * (m'\otimes m'..\otimes m') */
void multRightKronTrans(const SqSylvMatrix& m, int order); void multRightKronTrans(const SqSylvMatrix &m, int order);
/* this = P*this, x = P*x, where P is gauss transformation setting /* this = P*this, x = P*x, where P is gauss transformation setting
* a given element to zero */ * a given element to zero */
void eliminateLeft(int row, int col, Vector& x); void eliminateLeft(int row, int col, Vector &x);
/* this = this*P, x = P'*x, where P is gauss transformation setting /* this = this*P, x = P'*x, where P is gauss transformation setting
* a given element to zero */ * a given element to zero */
void eliminateRight(int row, int col, Vector& x); void eliminateRight(int row, int col, Vector &x);
}; };
class SqSylvMatrix : public SylvMatrix
class SqSylvMatrix : public SylvMatrix { {
public: public:
SqSylvMatrix(int m) : SylvMatrix(m, m) {} SqSylvMatrix(int m) : SylvMatrix(m, m)
SqSylvMatrix(const double* d, int m) : SylvMatrix(d, m, m) {} {
SqSylvMatrix(double* d, int m) : SylvMatrix(d, m, m) {} }
SqSylvMatrix(const SqSylvMatrix& m) : SylvMatrix(m) {} SqSylvMatrix(const double *d, int m) : SylvMatrix(d, m, m)
SqSylvMatrix(const GeneralMatrix& m, int i, int j, int nrows) {
: SylvMatrix(m, i, j, nrows, nrows) {} }
SqSylvMatrix(GeneralMatrix& m, int i, int j, int nrows) SqSylvMatrix(double *d, int m) : SylvMatrix(d, m, m)
: SylvMatrix(m, i, j, nrows, nrows) {} {
SqSylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b); }
const SqSylvMatrix& operator=(const SqSylvMatrix& m) SqSylvMatrix(const SqSylvMatrix &m) : SylvMatrix(m)
{GeneralMatrix::operator=(m); return *this;} {
/* x = (this \otimes this..\otimes this)*d */ }
void multVecKron(KronVector& x, const KronVector& d) const; SqSylvMatrix(const GeneralMatrix &m, int i, int j, int nrows)
/* x = (this' \otimes this'..\otimes this')*d */ : SylvMatrix(m, i, j, nrows, nrows)
void multVecKronTrans(KronVector& x, const KronVector& d) const; {
/* a = inv(this)*a, b=inv(this)*b */ }
void multInvLeft2(GeneralMatrix& a, GeneralMatrix& b, SqSylvMatrix(GeneralMatrix &m, int i, int j, int nrows)
double& rcond1, double& rcondinf) const; : SylvMatrix(m, i, j, nrows, nrows)
/* this = I */ {
void setUnit(); }
SqSylvMatrix(const GeneralMatrix &a, const GeneralMatrix &b);
const SqSylvMatrix &
operator=(const SqSylvMatrix &m)
{
GeneralMatrix::operator=(m); return *this;
}
/* x = (this \otimes this..\otimes this)*d */
void multVecKron(KronVector &x, const KronVector &d) const;
/* x = (this' \otimes this'..\otimes this')*d */
void multVecKronTrans(KronVector &x, const KronVector &d) const;
/* a = inv(this)*a, b=inv(this)*b */
void multInvLeft2(GeneralMatrix &a, GeneralMatrix &b,
double &rcond1, double &rcondinf) const;
/* this = I */
void setUnit();
}; };
#endif /* SYLV_MATRIX_H */ #endif /* SYLV_MATRIX_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -9,55 +9,57 @@
#include <new> #include <new>
class MallocAllocator { class MallocAllocator
{
#ifdef USE_MEMORY_POOL #ifdef USE_MEMORY_POOL
public: public:
void* operator new(size_t size); void *operator new(size_t size);
void* operator new[](size_t size); void *operator new[](size_t size);
void operator delete(void* p); void operator delete(void *p);
void operator delete[](void* p); void operator delete[](void *p);
#endif #endif
}; };
#ifdef USE_MEMORY_POOL #ifdef USE_MEMORY_POOL
void* operator new(size_t size); void *operator new(size_t size);
void* operator new[](size_t size); void *operator new[](size_t size);
void operator delete(void* p); void operator delete(void *p);
void operator delete[](void* p); void operator delete[](void *p);
#endif #endif
class SylvMemoryPool { class SylvMemoryPool
char* base; {
size_t length; char *base;
size_t allocated; size_t length;
bool stack_mode; size_t allocated;
SylvMemoryPool(const SylvMemoryPool&); bool stack_mode;
const SylvMemoryPool& operator=(const SylvMemoryPool&); SylvMemoryPool(const SylvMemoryPool &);
const SylvMemoryPool &operator=(const SylvMemoryPool &);
public: public:
SylvMemoryPool(); SylvMemoryPool();
~SylvMemoryPool(); ~SylvMemoryPool();
void init(size_t size); void init(size_t size);
void* allocate(size_t size); void *allocate(size_t size);
void free(void* p); void free(void *p);
void reset(); void reset();
void setStackMode(bool); void setStackMode(bool);
}; };
class SylvMemoryDriver { class SylvMemoryDriver
SylvMemoryDriver(const SylvMemoryDriver&); {
const SylvMemoryDriver& operator=(const SylvMemoryDriver&); SylvMemoryDriver(const SylvMemoryDriver &);
const SylvMemoryDriver &operator=(const SylvMemoryDriver &);
public: public:
SylvMemoryDriver(int num_d, int m, int n, int order); SylvMemoryDriver(int num_d, int m, int n, int order);
SylvMemoryDriver(const SylvParams& pars, int num_d, int m, int n, int order); SylvMemoryDriver(const SylvParams &pars, int num_d, int m, int n, int order);
static void setStackMode(bool); static void setStackMode(bool);
~SylvMemoryDriver(); ~SylvMemoryDriver();
protected: protected:
void allocate(int num_d, int m, int n, int order); void allocate(int num_d, int m, int n, int order);
}; };
#endif /* SYLV_MEMORY_H */ #endif /* SYLV_MEMORY_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -15,148 +15,217 @@
typedef enum {def, changed, undef} status; typedef enum {def, changed, undef} status;
template <class _Type> template <class _Type>
struct ParamItem { struct ParamItem
{
protected: protected:
typedef ParamItem<_Type> _Self; typedef ParamItem<_Type> _Self;
status s; status s;
_Type value; _Type value;
public: public:
ParamItem() ParamItem()
{s = undef;} {
ParamItem(_Type val) s = undef;
{value = val; s = def;} }
ParamItem(const _Self& item) ParamItem(_Type val)
{value = item.value; s = item.s;} {
const _Self& operator=(const _Self& item) value = val; s = def;
{value = item.value; s = item.s; return *this;} }
const _Self& operator=(const _Type& val) ParamItem(const _Self &item)
{value = val; s = changed; return *this;} {
_Type operator*() const value = item.value; s = item.s;
{return value;} }
status getStatus() const const _Self &
{return s;} operator=(const _Self &item)
void print(FILE* f, const char* prefix, const char* str, const char* fmt) const {
{ value = item.value; s = item.s; return *this;
if (s == undef) }
return; const _Self &
char out[1000]; operator=(const _Type &val)
strcpy(out, prefix); {
strcat(out, str); value = val; s = changed; return *this;
strcat(out, "= "); }
strcat(out, fmt); _Type
if (s == def) operator*() const
strcat(out, " <default>"); {
strcat(out,"\n"); return value;
fprintf(f, out, value); }
} status
getStatus() const
{
return s;
}
void
print(FILE *f, const char *prefix, const char *str, const char *fmt) const
{
if (s == undef)
return;
char out[1000];
strcpy(out, prefix);
strcat(out, str);
strcat(out, "= ");
strcat(out, fmt);
if (s == def)
strcat(out, " <default>");
strcat(out, "\n");
fprintf(f, out, value);
}
}; };
class SylvParams { class SylvParams
{
public: public:
typedef enum {iter, recurse} solve_method; typedef enum {iter, recurse} solve_method;
protected: protected:
class DoubleParamItem : public ParamItem<double> { class DoubleParamItem : public ParamItem<double>
public: {
DoubleParamItem() : ParamItem<double>() {} public:
DoubleParamItem(double val) : ParamItem<double>(val) {} DoubleParamItem() : ParamItem<double>()
DoubleParamItem(const DoubleParamItem& item) : ParamItem<double>(item) {} {
const DoubleParamItem& operator=(const double& val) }
{ParamItem<double>::operator=(val); return *this;} DoubleParamItem(double val) : ParamItem<double>(val)
{
}
DoubleParamItem(const DoubleParamItem &item) : ParamItem<double>(item)
{
}
const DoubleParamItem &
operator=(const double &val)
{
ParamItem<double>::operator=(val); return *this;
}
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
mxArray* createMatlabArray() const; mxArray *createMatlabArray() const;
#endif #endif
}; };
class IntParamItem : public ParamItem<int> { class IntParamItem : public ParamItem<int>
public: {
IntParamItem() : ParamItem<int>() {} public:
IntParamItem(int val) : ParamItem<int>(val) {} IntParamItem() : ParamItem<int>()
IntParamItem(const IntParamItem& item) : ParamItem<int>(item) {} {
const IntParamItem& operator=(const int& val) }
{ParamItem<int>::operator=(val); return *this;} IntParamItem(int val) : ParamItem<int>(val)
{
}
IntParamItem(const IntParamItem &item) : ParamItem<int>(item)
{
}
const IntParamItem &
operator=(const int &val)
{
ParamItem<int>::operator=(val); return *this;
}
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
mxArray* createMatlabArray() const; mxArray *createMatlabArray() const;
#endif #endif
}; };
class BoolParamItem : public ParamItem<bool> { class BoolParamItem : public ParamItem<bool>
public: {
BoolParamItem() : ParamItem<bool>() {} public:
BoolParamItem(bool val) : ParamItem<bool>(val) {} BoolParamItem() : ParamItem<bool>()
BoolParamItem(const BoolParamItem& item) : ParamItem<bool>(item) {} {
const BoolParamItem& operator=(const bool& val) }
{ParamItem<bool>::operator=(val); return *this;} BoolParamItem(bool val) : ParamItem<bool>(val)
{
}
BoolParamItem(const BoolParamItem &item) : ParamItem<bool>(item)
{
}
const BoolParamItem &
operator=(const bool &val)
{
ParamItem<bool>::operator=(val); return *this;
}
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
mxArray* createMatlabArray() const; mxArray *createMatlabArray() const;
#endif #endif
}; };
class MethodParamItem : public ParamItem<solve_method> { class MethodParamItem : public ParamItem<solve_method>
public: {
MethodParamItem() : ParamItem<solve_method>() {} public:
MethodParamItem(solve_method val) : ParamItem<solve_method>(val) {} MethodParamItem() : ParamItem<solve_method>()
MethodParamItem(const MethodParamItem& item) : ParamItem<solve_method>(item) {} {
const MethodParamItem operator=(const solve_method& val) }
{ParamItem<solve_method>::operator=(val); return *this;} MethodParamItem(solve_method val) : ParamItem<solve_method>(val)
{
}
MethodParamItem(const MethodParamItem &item) : ParamItem<solve_method>(item)
{
}
const MethodParamItem
operator=(const solve_method &val)
{
ParamItem<solve_method>::operator=(val); return *this;
}
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
mxArray* createMatlabArray() const; mxArray *createMatlabArray() const;
#endif #endif
}; };
public: public:
// input parameters // input parameters
MethodParamItem method; // method of solution: iter/recurse MethodParamItem method; // method of solution: iter/recurse
DoubleParamItem convergence_tol; // norm for what we consider converged DoubleParamItem convergence_tol; // norm for what we consider converged
IntParamItem max_num_iter; // max number of iterations IntParamItem max_num_iter; // max number of iterations
DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization
BoolParamItem want_check; // true => allocate extra space for checks BoolParamItem want_check; // true => allocate extra space for checks
// output parameters // output parameters
BoolParamItem converged; // true if converged BoolParamItem converged; // true if converged
DoubleParamItem iter_last_norm; // norm of the last iteration DoubleParamItem iter_last_norm; // norm of the last iteration
IntParamItem num_iter; // number of iterations IntParamItem num_iter; // number of iterations
DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C-V*F*inv(V) DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C-V*F*inv(V)
DoubleParamItem f_errI; // norm Inf of diagonalization abs. error C-V*F*inv(V) DoubleParamItem f_errI; // norm Inf of diagonalization abs. error C-V*F*inv(V)
DoubleParamItem viv_err1; // norm 1 of error I-V*inv(V) DoubleParamItem viv_err1; // norm 1 of error I-V*inv(V)
DoubleParamItem viv_errI; // norm Inf of error I-V*inv(V) DoubleParamItem viv_errI; // norm Inf of error I-V*inv(V)
DoubleParamItem ivv_err1; // norm 1 of error I-inv(V)*V DoubleParamItem ivv_err1; // norm 1 of error I-inv(V)*V
DoubleParamItem ivv_errI; // norm Inf of error I-inv(V)*V DoubleParamItem ivv_errI; // norm Inf of error I-inv(V)*V
IntParamItem f_blocks; // number of diagonal blocks of F IntParamItem f_blocks; // number of diagonal blocks of F
IntParamItem f_largest; // size of largest diagonal block in F IntParamItem f_largest; // size of largest diagonal block in F
IntParamItem f_zeros; // number of off diagonal zeros in F IntParamItem f_zeros; // number of off diagonal zeros in F
IntParamItem f_offdiag; // number of all off diagonal elements in F IntParamItem f_offdiag; // number of all off diagonal elements in F
DoubleParamItem rcondA1; // reciprocal cond 1 number of A DoubleParamItem rcondA1; // reciprocal cond 1 number of A
DoubleParamItem rcondAI; // reciprocal cond Inf number of A DoubleParamItem rcondAI; // reciprocal cond Inf number of A
DoubleParamItem eig_min; // minimum eigenvalue of the solved system DoubleParamItem eig_min; // minimum eigenvalue of the solved system
DoubleParamItem mat_err1; // rel. matrix 1 norm of A*X-B*X*kron(C,..,C)-D DoubleParamItem mat_err1; // rel. matrix 1 norm of A*X-B*X*kron(C,..,C)-D
DoubleParamItem mat_errI; // rel. matrix Inf norm of A*X-B*X*kron(C,..,C)-D DoubleParamItem mat_errI; // rel. matrix Inf norm of A*X-B*X*kron(C,..,C)-D
DoubleParamItem mat_errF; // rel. matrix Frob. norm of A*X-B*X*kron(C,..,C)-D DoubleParamItem mat_errF; // rel. matrix Frob. norm of A*X-B*X*kron(C,..,C)-D
DoubleParamItem vec_err1; // rel. vector 1 norm of A*X-B*X*kron(C,..,C)-D DoubleParamItem vec_err1; // rel. vector 1 norm of A*X-B*X*kron(C,..,C)-D
DoubleParamItem vec_errI; // rel. vector Inf norm of A*X-B*X*kron(C,..,C)-D DoubleParamItem vec_errI; // rel. vector Inf norm of A*X-B*X*kron(C,..,C)-D
DoubleParamItem cpu_time; // time of the job in CPU seconds DoubleParamItem cpu_time; // time of the job in CPU seconds
// note: remember to change copy() if adding/removing member // note: remember to change copy() if adding/removing member
SylvParams(bool wc = false) SylvParams(bool wc = false)
: method(recurse), convergence_tol(1.e-30), max_num_iter(15), : method(recurse), convergence_tol(1.e-30), max_num_iter(15),
bs_norm(1.3), want_check(wc) {} bs_norm(1.3), want_check(wc)
SylvParams(const SylvParams& p) {
{copy(p);} }
const SylvParams& operator=(const SylvParams& p) SylvParams(const SylvParams &p)
{copy(p); return *this;} {
~SylvParams() {} copy(p);
void print(const char* prefix) const; }
void print(FILE* fdesc, const char* prefix) const; const SylvParams &
void setArrayNames(int& num, const char** names) const; operator=(const SylvParams &p)
{
copy(p); return *this;
}
~SylvParams()
{
}
void print(const char *prefix) const;
void print(FILE *fdesc, const char *prefix) const;
void setArrayNames(int &num, const char **names) const;
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
mxArray* createStructArray() const; mxArray *createStructArray() const;
#endif #endif
private: private:
void copy(const SylvParams& p); void copy(const SylvParams &p);
}; };
#endif /* SYLV_PARAMS_H */ #endif /* SYLV_PARAMS_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -12,40 +12,47 @@
#include "SylvParams.h" #include "SylvParams.h"
#include "SchurDecomp.h" #include "SchurDecomp.h"
class SylvesterSolver { class SylvesterSolver
{
protected: protected:
const QuasiTriangular* const matrixK; const QuasiTriangular *const matrixK;
const QuasiTriangular* const matrixF; const QuasiTriangular *const matrixF;
private: private:
/* return true when it is more efficient to use QuasiTriangular /* return true when it is more efficient to use QuasiTriangular
* than QuasiTriangularZero */ * than QuasiTriangularZero */
static bool zeroPad(const SchurDecompZero& kdecomp) { static bool
return ((kdecomp.getZeroCols()*3 < kdecomp.getDim()*2) || zeroPad(const SchurDecompZero &kdecomp)
(kdecomp.getZeroCols() < 10)); {
} return ((kdecomp.getZeroCols()*3 < kdecomp.getDim()*2)
|| (kdecomp.getZeroCols() < 10));
}
public: public:
SylvesterSolver(const QuasiTriangular& k, const QuasiTriangular& f) SylvesterSolver(const QuasiTriangular &k, const QuasiTriangular &f)
: matrixK(new QuasiTriangular(k)), : matrixK(new QuasiTriangular(k)),
matrixF(new QuasiTriangular(f)) matrixF(new QuasiTriangular(f))
{} {
SylvesterSolver(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp) }
: matrixK((zeroPad(kdecomp)) ? SylvesterSolver(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp)
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)), : matrixK((zeroPad(kdecomp)) ?
matrixF(new QuasiTriangular(fdecomp)) new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
{} matrixF(new QuasiTriangular(fdecomp))
SylvesterSolver(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp) {
: matrixK((zeroPad(kdecomp)) ? }
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)), SylvesterSolver(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp)
matrixF(new BlockDiagonal(fdecomp.getB())) : matrixK((zeroPad(kdecomp)) ?
{} new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
virtual ~SylvesterSolver() matrixF(new BlockDiagonal(fdecomp.getB()))
{delete matrixK; delete matrixF;} {
virtual void solve(SylvParams& pars, KronVector& x) const = 0; }
virtual ~SylvesterSolver()
{
delete matrixK; delete matrixF;
}
virtual void solve(SylvParams &pars, KronVector &x) const = 0;
}; };
#endif /* SYLVESTER_SOLVER_H */ #endif /* SYLVESTER_SOLVER_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -7,35 +7,45 @@
#include "SylvMatrix.h" #include "SylvMatrix.h"
class SymSchurDecomp { class SymSchurDecomp
{
protected: protected:
Vector lambda; Vector lambda;
SqSylvMatrix q; SqSylvMatrix q;
public: public:
/** Calculates A = Q*Lambda*Q^T, where A is assummed to be /** Calculates A = Q*Lambda*Q^T, where A is assummed to be
* symmetric and Lambda real diagonal, hence a vector. */ * symmetric and Lambda real diagonal, hence a vector. */
SymSchurDecomp(const GeneralMatrix& a); SymSchurDecomp(const GeneralMatrix &a);
SymSchurDecomp(const SymSchurDecomp& ssd) SymSchurDecomp(const SymSchurDecomp &ssd)
: lambda(ssd.lambda), q(ssd.q) {} : lambda(ssd.lambda), q(ssd.q)
virtual ~SymSchurDecomp() {} {
const Vector& getLambda() const }
{return lambda;} virtual ~SymSchurDecomp()
const SqSylvMatrix& getQ() const {
{return q;} }
/** Return factor F*F^T = A, raises and exception if A is not const Vector &
* positive semidefinite, F must be square. */ getLambda() const
void getFactor(GeneralMatrix& f) const; {
/** Returns true if A is positive semidefinite. */ return lambda;
bool isPositiveSemidefinite() const; }
/** Correct definitness. This sets all eigenvalues between minus const SqSylvMatrix &
* tolerance and zero to zero. */ getQ() const
void correctDefinitness(double tol); {
return q;
}
/** Return factor F*F^T = A, raises and exception if A is not
* positive semidefinite, F must be square. */
void getFactor(GeneralMatrix &f) const;
/** Returns true if A is positive semidefinite. */
bool isPositiveSemidefinite() const;
/** Correct definitness. This sets all eigenvalues between minus
* tolerance and zero to zero. */
void correctDefinitness(double tol);
}; };
#endif #endif
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -11,105 +11,112 @@
#include "QuasiTriangularZero.h" #include "QuasiTriangularZero.h"
#include "SimilarityDecomp.h" #include "SimilarityDecomp.h"
class TriangularSylvester : public SylvesterSolver { class TriangularSylvester : public SylvesterSolver
const QuasiTriangular* const matrixKK; {
const QuasiTriangular* const matrixFF; const QuasiTriangular *const matrixKK;
const QuasiTriangular *const matrixFF;
public: public:
TriangularSylvester(const QuasiTriangular& k, const QuasiTriangular& f); TriangularSylvester(const QuasiTriangular &k, const QuasiTriangular &f);
TriangularSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp); TriangularSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp);
TriangularSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp); TriangularSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp);
virtual ~TriangularSylvester(); virtual
void print() const; ~TriangularSylvester();
void solve(SylvParams& pars, KronVector& d) const; void print() const;
void solve(SylvParams &pars, KronVector &d) const;
void solvi(double r, KronVector& d, double& eig_min) const; void solvi(double r, KronVector &d, double &eig_min) const;
void solvii(double alpha, double beta1, double beta2, void solvii(double alpha, double beta1, double beta2,
KronVector& d1, KronVector& d2, KronVector &d1, KronVector &d2,
double& eig_min) const; double &eig_min) const;
void solviip(double alpha, double betas, void solviip(double alpha, double betas,
KronVector& d, double& eig_min) const; KronVector &d, double &eig_min) const;
/* evaluates: /* evaluates:
|x1| |d1| |alpha -beta1| |d1| |x1| |d1| |alpha -beta1| |d1|
| | = | |+| |\otimes F'...\otimes K | | | | = | |+| |\otimes F'...\otimes K | |
|x2| |d2| |beta2 alpha| |d2| |x2| |d2| |beta2 alpha| |d2|
*/ */
void linEval(double alpha, double beta1, double beta2, void linEval(double alpha, double beta1, double beta2,
KronVector& x1, KronVector& x2, KronVector &x1, KronVector &x2,
const ConstKronVector& d1, const ConstKronVector& d2) const; const ConstKronVector &d1, const ConstKronVector &d2) const;
void linEval(double alpha, double beta1, double beta2, void
KronVector& x1, KronVector& x2, linEval(double alpha, double beta1, double beta2,
const KronVector& d1, const KronVector& d2) const KronVector &x1, KronVector &x2,
{linEval(alpha, beta1, beta2, x1, x2, const KronVector &d1, const KronVector &d2) const
ConstKronVector(d1), ConstKronVector(d2));} {
linEval(alpha, beta1, beta2, x1, x2,
ConstKronVector(d1), ConstKronVector(d2));
}
/* evaluates: /* evaluates:
|x1| |d1| |gamma -delta1| |d1| |x1| |d1| |gamma -delta1| |d1|
| | = | | + 2alpha*| |\otimes F'...\otimes K | | + | | = | | + 2alpha*| |\otimes F'...\otimes K | | +
|x2| |d2| |delta2 gamma| |d2| |x2| |d2| |delta2 gamma| |d2|
|gamma -delta1|^2 |d1| |gamma -delta1|^2 |d1|
+ (alpha^2+betas)*| |\otimes F'2...\otimes K2 | | + (alpha^2+betas)*| |\otimes F'2...\otimes K2 | |
|delta2 gamma| |d2| |delta2 gamma| |d2|
*/ */
void quaEval(double alpha, double betas, void quaEval(double alpha, double betas,
double gamma, double delta1, double delta2, double gamma, double delta1, double delta2,
KronVector& x1, KronVector& x2, KronVector &x1, KronVector &x2,
const ConstKronVector& d1, const ConstKronVector& d2) const; const ConstKronVector &d1, const ConstKronVector &d2) const;
void quaEval(double alpha, double betas, void
double gamma, double delta1, double delta2, quaEval(double alpha, double betas,
KronVector& x1, KronVector& x2, double gamma, double delta1, double delta2,
const KronVector& d1, const KronVector& d2) const KronVector &x1, KronVector &x2,
{quaEval(alpha, betas, gamma, delta1, delta2, x1, x2, const KronVector &d1, const KronVector &d2) const
ConstKronVector(d1), ConstKronVector(d2));} {
quaEval(alpha, betas, gamma, delta1, delta2, x1, x2,
ConstKronVector(d1), ConstKronVector(d2));
}
private: private:
/* returns square of size of minimal eigenvalue of the system solved, /* returns square of size of minimal eigenvalue of the system solved,
now obsolete */ now obsolete */
double getEigSep(int depth) const; double getEigSep(int depth) const;
/* recursivelly calculates kronecker product of complex vectors (used in getEigSep) */ /* recursivelly calculates kronecker product of complex vectors (used in getEigSep) */
static void multEigVector(KronVector& eig, const Vector& feig, const Vector& keig); static void multEigVector(KronVector &eig, const Vector &feig, const Vector &keig);
/* auxiliary typedefs */ /* auxiliary typedefs */
typedef QuasiTriangular::const_diag_iter const_diag_iter; typedef QuasiTriangular::const_diag_iter const_diag_iter;
typedef QuasiTriangular::const_row_iter const_row_iter; typedef QuasiTriangular::const_row_iter const_row_iter;
/* called from solvi */ /* called from solvi */
void solviRealAndEliminate(double r, const_diag_iter di, void solviRealAndEliminate(double r, const_diag_iter di,
KronVector& d, double& eig_min) const; KronVector &d, double &eig_min) const;
void solviComplexAndEliminate(double r, const_diag_iter di, void solviComplexAndEliminate(double r, const_diag_iter di,
KronVector& d, double& eig_min) const; KronVector &d, double &eig_min) const;
/* called from solviip */ /* called from solviip */
void solviipRealAndEliminate(double alpha, double betas, void solviipRealAndEliminate(double alpha, double betas,
const_diag_iter di, const_diag_iter dsi, const_diag_iter di, const_diag_iter dsi,
KronVector& d, double& eig_min) const; KronVector &d, double &eig_min) const;
void solviipComplexAndEliminate(double alpha, double betas, void solviipComplexAndEliminate(double alpha, double betas,
const_diag_iter di, const_diag_iter dsi, const_diag_iter di, const_diag_iter dsi,
KronVector& d, double& eig_min) const; KronVector &d, double &eig_min) const;
/* eliminations */ /* eliminations */
void solviEliminateReal(const_diag_iter di, KronVector& d, void solviEliminateReal(const_diag_iter di, KronVector &d,
const KronVector& y, double divisor) const; const KronVector &y, double divisor) const;
void solviEliminateComplex(const_diag_iter di, KronVector& d, void solviEliminateComplex(const_diag_iter di, KronVector &d,
const KronVector& y1, const KronVector& y2, const KronVector &y1, const KronVector &y2,
double divisor) const; double divisor) const;
void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi, void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
KronVector& d, KronVector &d,
const KronVector& y1, const KronVector& y2, const KronVector &y1, const KronVector &y2,
double divisor, double divisor2) const; double divisor, double divisor2) const;
void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi, void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
KronVector& d, KronVector &d,
const KronVector& y1, const KronVector& y11, const KronVector &y1, const KronVector &y11,
const KronVector& y2, const KronVector& y22, const KronVector &y2, const KronVector &y22,
double divisor) const; double divisor) const;
/* Lemma 2 */ /* Lemma 2 */
void solviipComplex(double alpha, double betas, double gamma, void solviipComplex(double alpha, double betas, double gamma,
double delta1, double delta2, double delta1, double delta2,
KronVector& d1, KronVector& d2, KronVector &d1, KronVector &d2,
double& eig_min) const; double &eig_min) const;
/* norms for what we consider zero on diagonal of F */ /* norms for what we consider zero on diagonal of F */
static double diag_zero; static double diag_zero;
static double diag_zero_sq; // square of diag_zero static double diag_zero_sq; // square of diag_zero
}; };
#endif /* TRIANGULAR_SYLVESTER_H */ #endif /* TRIANGULAR_SYLVESTER_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -14,162 +14,245 @@
class GeneralMatrix; class GeneralMatrix;
class ConstVector; class ConstVector;
class Vector { class Vector
{
protected: protected:
int len; int len;
int s; int s;
double* data; double *data;
bool destroy; bool destroy;
public: public:
Vector() : len(0), s(1), data(0), destroy(false) {} Vector() : len(0), s(1), data(0), destroy(false)
Vector(int l) : len(l), s(1), data(new double[l]), destroy(true) {} {
Vector(Vector& v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false) {} }
Vector(const Vector& v); Vector(int l) : len(l), s(1), data(new double[l]), destroy(true)
Vector(const ConstVector& v); {
Vector(const double* d, int l) }
: len(l), s(1), data(new double[len]), destroy(true) Vector(Vector &v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false)
{copy(d, 1);} {
Vector(double* d, int l) }
: len(l), s(1), data(d), destroy(false) {} Vector(const Vector &v);
Vector(double* d, int skip, int l) Vector(const ConstVector &v);
: len(l), s(skip), data(d), destroy(false) {} Vector(const double *d, int l)
Vector(Vector& v, int off, int l); : len(l), s(1), data(new double[len]), destroy(true)
Vector(const Vector& v, int off, int l); {
Vector(GeneralMatrix& m, int col); copy(d, 1);
Vector(int row, GeneralMatrix& m); }
const Vector& operator=(const Vector& v); Vector(double *d, int l)
const Vector& operator=(const ConstVector& v); : len(l), s(1), data(d), destroy(false)
double& operator[](int i) {
{return data[s*i];} }
const double& operator[](int i) const Vector(double *d, int skip, int l)
{return data[s*i];} : len(l), s(skip), data(d), destroy(false)
const double* base() const {
{return data;} }
double* base() Vector(Vector &v, int off, int l);
{return data;} Vector(const Vector &v, int off, int l);
int length() const Vector(GeneralMatrix &m, int col);
{return len;} Vector(int row, GeneralMatrix &m);
int skip() const const Vector &operator=(const Vector &v);
{return s;} const Vector &operator=(const ConstVector &v);
double &
operator[](int i)
{
return data[s*i];
}
const double &
operator[](int i) const
{
return data[s*i];
}
const double *
base() const
{
return data;
}
double *
base()
{
return data;
}
int
length() const
{
return len;
}
int
skip() const
{
return s;
}
/** Exact equality. */ /** Exact equality. */
bool operator==(const Vector& y) const; bool operator==(const Vector &y) const;
bool operator!=(const Vector& y) const; bool operator!=(const Vector &y) const;
/** Lexicographic ordering. */ /** Lexicographic ordering. */
bool operator<(const Vector& y) const; bool operator<(const Vector &y) const;
bool operator<=(const Vector& y) const; bool operator<=(const Vector &y) const;
bool operator>(const Vector& y) const; bool operator>(const Vector &y) const;
bool operator>=(const Vector& y) const; bool operator>=(const Vector &y) const;
virtual ~Vector(); virtual
void zeros(); ~Vector();
void nans(); void zeros();
void infs(); void nans();
bool toBeDestroyed() const {return destroy;} void infs();
void rotatePair(double alpha, double beta1, double beta2, int i); bool
void add(double r, const Vector& v); toBeDestroyed() const
void add(double r, const ConstVector& v); {
void add(const double* z, const Vector& v); return destroy;
void add(const double* z, const ConstVector& v); }
void mult(double r); void rotatePair(double alpha, double beta1, double beta2, int i);
double getNorm() const; void add(double r, const Vector &v);
double getMax() const; void add(double r, const ConstVector &v);
double getNorm1() const; void add(const double *z, const Vector &v);
double dot(const Vector& y) const; void add(const double *z, const ConstVector &v);
bool isFinite() const; void mult(double r);
void print() const; double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const Vector &y) const;
bool isFinite() const;
void print() const;
/* multiplies | alpha -beta1| |b1| |x1| /* multiplies | alpha -beta1| |b1| |x1|
| |\otimes I .| | = | | | |\otimes I .| | = | |
| -beta2 alpha| |b2| |x2| | -beta2 alpha| |b2| |x2|
*/ */
static void mult2(double alpha, double beta1, double beta2, static void mult2(double alpha, double beta1, double beta2,
Vector& x1, Vector& x2, Vector &x1, Vector &x2,
const Vector& b1, const Vector& b2); const Vector &b1, const Vector &b2);
/* same, but adds instead of set */ /* same, but adds instead of set */
static void mult2a(double alpha, double beta1, double beta2, static void mult2a(double alpha, double beta1, double beta2,
Vector& x1, Vector& x2, Vector &x1, Vector &x2,
const Vector& b1, const Vector& b2); const Vector &b1, const Vector &b2);
/* same, but subtracts instead of add */ /* same, but subtracts instead of add */
static void mult2s(double alpha, double beta1, double beta2, static void
Vector& x1, Vector& x2, mult2s(double alpha, double beta1, double beta2,
const Vector& b1, const Vector& b2) Vector &x1, Vector &x2,
{mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);} const Vector &b1, const Vector &b2)
{
mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);
}
private: private:
void copy(const double* d, int inc); void copy(const double *d, int inc);
const Vector& operator=(int); // must not be used (not implemented) const Vector &operator=(int); // must not be used (not implemented)
const Vector& operator=(double); // must not be used (not implemented) const Vector &operator=(double); // must not be used (not implemented)
}; };
class BaseConstVector
class BaseConstVector { {
protected: protected:
int len; int len;
int s; int s;
const double* data; const double *data;
public: public:
BaseConstVector(int l, int si, const double* d) : len(l), s(si), data(d) {} BaseConstVector(int l, int si, const double *d) : len(l), s(si), data(d)
BaseConstVector(const BaseConstVector& v) : len(v.len), s(v.s), data(v.data) {} {
const BaseConstVector& operator=(const BaseConstVector& v) }
{len = v.len; s = v.s; data = v.data; return *this;} BaseConstVector(const BaseConstVector &v) : len(v.len), s(v.s), data(v.data)
const double& operator[](int i) const {
{return data[s*i];} }
const double* base() const const BaseConstVector &
{return data;} operator=(const BaseConstVector &v)
int length() const {
{return len;} len = v.len; s = v.s; data = v.data; return *this;
int skip() const }
{return s;} const double &
operator[](int i) const
{
return data[s*i];
}
const double *
base() const
{
return data;
}
int
length() const
{
return len;
}
int
skip() const
{
return s;
}
}; };
class ConstGeneralMatrix; class ConstGeneralMatrix;
class ConstVector : public BaseConstVector { class ConstVector : public BaseConstVector
{
public: public:
ConstVector(const Vector& v) : BaseConstVector(v.length(), v.skip(), v.base()) {} ConstVector(const Vector &v) : BaseConstVector(v.length(), v.skip(), v.base())
ConstVector(const ConstVector& v) : BaseConstVector(v) {} {
ConstVector(const double* d, int l) : BaseConstVector(l, 1, d) {} }
ConstVector(const Vector& v, int off, int l); ConstVector(const ConstVector &v) : BaseConstVector(v)
ConstVector(const ConstVector& v, int off, int l); {
ConstVector(const double* d, int skip, int l); }
ConstVector(const ConstGeneralMatrix& m, int col); ConstVector(const double *d, int l) : BaseConstVector(l, 1, d)
ConstVector(int row, const ConstGeneralMatrix& m); {
}
ConstVector(const Vector &v, int off, int l);
ConstVector(const ConstVector &v, int off, int l);
ConstVector(const double *d, int skip, int l);
ConstVector(const ConstGeneralMatrix &m, int col);
ConstVector(int row, const ConstGeneralMatrix &m);
virtual ~ConstVector() {} virtual ~ConstVector()
/** Exact equality. */ {
bool operator==(const ConstVector& y) const; }
bool operator!=(const ConstVector& y) const /** Exact equality. */
{return ! operator==(y);} bool operator==(const ConstVector &y) const;
/** Lexicographic ordering. */ bool
bool operator<(const ConstVector& y) const; operator!=(const ConstVector &y) const
bool operator<=(const ConstVector& y) const {
{return operator<(y) || operator==(y);} return !operator==(y);
bool operator>(const ConstVector& y) const }
{return ! operator<=(y);} /** Lexicographic ordering. */
bool operator>=(const ConstVector& y) const bool operator<(const ConstVector &y) const;
{return ! operator<(y);} bool
operator<=(const ConstVector &y) const
{
return operator<(y) || operator==(y);
}
bool
operator>(const ConstVector &y) const
{
return !operator<=(y);
}
bool
operator>=(const ConstVector &y) const
{
return !operator<(y);
}
double getNorm() const; double getNorm() const;
double getMax() const; double getMax() const;
double getNorm1() const; double getNorm1() const;
double dot(const ConstVector& y) const; double dot(const ConstVector &y) const;
bool isFinite() const; bool isFinite() const;
void print() const; void print() const;
}; };
class ZeroPad { class ZeroPad
{
public: public:
static const int length = 16; static const int length = 16;
private: private:
double pad[16]; double pad[16];
public: public:
ZeroPad(); ZeroPad();
const double* getBase() const {return pad;} const double *
getBase() const
{
return pad;
}
}; };
#endif /* VECTOR_H */ #endif /* VECTOR_H */
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View File

@ -12,31 +12,58 @@
using namespace std; using namespace std;
class MMException : public MallocAllocator { class MMException : public MallocAllocator
string message; {
string message;
public: public:
MMException(string mes) : message(mes) {} MMException(string mes) : message(mes)
MMException(const char* mes) : message(mes) {} {
const char* getMessage() const {return message.data();} }
MMException(const char *mes) : message(mes)
{
}
const char *
getMessage() const
{
return message.data();
}
}; };
class MMMatrixIn : public MallocAllocator { class MMMatrixIn : public MallocAllocator
double* data; {
int rows; double *data;
int cols; int rows;
int cols;
public: public:
MMMatrixIn(const char* fname); MMMatrixIn(const char *fname);
~MMMatrixIn(); ~MMMatrixIn();
const double* getData() const {return data;} const double *
int size() const {return rows*cols;} getData() const
int row() const {return rows;} {
int col() const {return cols;} return data;
}
int
size() const
{
return rows*cols;
}
int
row() const
{
return rows;
}
int
col() const
{
return cols;
}
}; };
class MMMatrixOut : public MallocAllocator { class MMMatrixOut : public MallocAllocator
{
public: public:
static void write(const char* fname, int rows, int cols, const double* data); static void write(const char *fname, int rows, int cols, const double *data);
static void write(const char* fname, const GeneralMatrix& m); static void write(const char *fname, const GeneralMatrix &m);
}; };
#endif /* MM_MATRIX_H */ #endif /* MM_MATRIX_H */

View File

@ -11,67 +11,78 @@
#include "rfs_tensor.h" #include "rfs_tensor.h"
#include "t_container.h" #include "t_container.h"
class Factory { class Factory
void init(const Symmetry& s, const IntSequence& nvs); {
void init(int dim, int nv); void init(const Symmetry &s, const IntSequence &nvs);
void fillMatrix(TwoDMatrix& m) const; void init(int dim, int nv);
void fillMatrix(TwoDMatrix &m) const;
public: public:
double get() const; double get() const;
// this can be used with UGSTensor, FGSTensor // this can be used with UGSTensor, FGSTensor
template <class _Ttype> template <class _Ttype>
_Ttype* make(int r, const Symmetry& s, const IntSequence& nvs) _Ttype *
{ make(int r, const Symmetry &s, const IntSequence &nvs)
_Ttype* res = new _Ttype(r, TensorDimens(s, nvs)); {
init(s, nvs); _Ttype *res = new _Ttype(r, TensorDimens(s, nvs));
fillMatrix(*res); init(s, nvs);
return res; fillMatrix(*res);
} return res;
}
// this can be used with FFSTensor, UFSTensor, FRTensor, URTensor // this can be used with FFSTensor, UFSTensor, FRTensor, URTensor
template <class _Ttype> template <class _Ttype>
_Ttype* make(int r, int nv, int dim) _Ttype *
{ make(int r, int nv, int dim)
_Ttype* res = new _Ttype(r, nv, dim); {
init(dim, nv); _Ttype *res = new _Ttype(r, nv, dim);
fillMatrix(*res); init(dim, nv);
return res; fillMatrix(*res);
} return res;
}
template <class _Ttype, class _Ctype> template <class _Ttype, class _Ctype>
_Ctype* makeCont(int r, const IntSequence& nvs, int maxdim) _Ctype *
{ makeCont(int r, const IntSequence &nvs, int maxdim)
int symnum = nvs.size(); {
_Ctype* res = new _Ctype(symnum); int symnum = nvs.size();
for (int dim = 1; dim <= maxdim; dim++) { _Ctype *res = new _Ctype(symnum);
if (symnum == 1) { for (int dim = 1; dim <= maxdim; dim++)
// full symmetry {
Symmetry sym(dim); if (symnum == 1)
_Ttype* t = make<_Ttype>(r, sym, nvs); {
res->insert(t); // full symmetry
} else { Symmetry sym(dim);
// general symmetry _Ttype *t = make<_Ttype>(r, sym, nvs);
for (int i = 0; i <= dim; i++) { res->insert(t);
Symmetry sym(i, dim-i); }
_Ttype* t = make<_Ttype>(r, sym, nvs); else
res->insert(t); {
} // general symmetry
} for (int i = 0; i <= dim; i++)
} {
return res; Symmetry sym(i, dim-i);
} _Ttype *t = make<_Ttype>(r, sym, nvs);
res->insert(t);
}
}
}
return res;
}
template <class _Ttype, class _Ptype> template <class _Ttype, class _Ptype>
_Ptype* makePoly(int r, int nv, int maxdim) _Ptype *
{ makePoly(int r, int nv, int maxdim)
_Ptype* p = new _Ptype(r, nv); {
for (int d = 1; d <= maxdim; d++) { _Ptype *p = new _Ptype(r, nv);
_Ttype* t = make<_Ttype>(r, nv, d); for (int d = 1; d <= maxdim; d++)
p->insert(t); {
} _Ttype *t = make<_Ttype>(r, nv, d);
return p; p->insert(t);
} }
return p;
}
Vector* makeVector(int n); Vector *makeVector(int n);
}; };
#endif #endif

View File

@ -10,115 +10,121 @@
#include "sparse_tensor.h" #include "sparse_tensor.h"
#include "Vector.h" #include "Vector.h"
class IntGenerator { class IntGenerator
int maxim; {
double probab; int maxim;
double probab;
public: public:
IntGenerator() IntGenerator()
: maxim(5), probab(0.3) {} : maxim(5), probab(0.3)
void init(int nf, int ny, int nv, int nw, int nu, int mx, double prob); {
int get() const; }
void init(int nf, int ny, int nv, int nw, int nu, int mx, double prob);
int get() const;
}; };
extern IntGenerator intgen; extern IntGenerator intgen;
class Monom : public IntSequence
class Monom : public IntSequence { {
public: public:
Monom(int len); // generate a random monom Monom(int len); // generate a random monom
Monom(int len, int item); // generate monom whose items are the given item Monom(int len, int item); // generate monom whose items are the given item
double deriv(const IntSequence& vars) const; double deriv(const IntSequence &vars) const;
// this = this*m^ex (in monomial sense) // this = this*m^ex (in monomial sense)
void multiplyWith(int ex, const Monom& m); void multiplyWith(int ex, const Monom &m);
void print() const; void print() const;
}; };
class Monom2Vector; class Monom2Vector;
class Monom1Vector { class Monom1Vector
friend class Monom2Vector; {
int nx; friend class Monom2Vector;
int len; int nx;
Monom** const x; int len;
Monom **const x;
public: public:
Monom1Vector(int nxx, int l); Monom1Vector(int nxx, int l);
~Monom1Vector(); ~Monom1Vector();
void deriv(const IntSequence& c, Vector& out) const; void deriv(const IntSequence &c, Vector &out) const;
FGSTensor* deriv(int dim) const; FGSTensor *deriv(int dim) const;
void print() const; void print() const;
}; };
//class Monom3Vector; //class Monom3Vector;
class Monom2Vector { class Monom2Vector
int ny; {
int nu; int ny;
int len; int nu;
Monom** const y; int len;
Monom** const u; Monom **const y;
Monom **const u;
public: public:
// generate random vector of monom two vector // generate random vector of monom two vector
Monom2Vector(int nyy, int nuu, int l); Monom2Vector(int nyy, int nuu, int l);
// calculate g(x(y,u)) // calculate g(x(y,u))
Monom2Vector(const Monom1Vector& g, const Monom2Vector& xmon); Monom2Vector(const Monom1Vector &g, const Monom2Vector &xmon);
~Monom2Vector(); ~Monom2Vector();
void deriv(const Symmetry& s, const IntSequence& c, Vector& out) const; void deriv(const Symmetry &s, const IntSequence &c, Vector &out) const;
FGSTensor* deriv(const Symmetry& s) const; FGSTensor *deriv(const Symmetry &s) const;
FGSContainer* deriv(int maxdim) const; FGSContainer *deriv(int maxdim) const;
void print() const; void print() const;
}; };
class Monom4Vector { class Monom4Vector
int len; {
int nx1; int len;
int nx2; int nx1;
int nx3; int nx2;
int nx4; int nx3;
Monom** const x1; int nx4;
Monom** const x2; Monom **const x1;
Monom** const x3; Monom **const x2;
Monom** const x4; Monom **const x3;
Monom **const x4;
public: public:
/* random for g(y,u,sigma) */ /* random for g(y,u,sigma) */
Monom4Vector(int l, int ny, int nu); Monom4Vector(int l, int ny, int nu);
/* random for G(y,u,u',sigma) */ /* random for G(y,u,u',sigma) */
Monom4Vector(int l, int ny, int nu, int nup); Monom4Vector(int l, int ny, int nu, int nup);
/* random for f(y+,y,y-,u) */ /* random for f(y+,y,y-,u) */
Monom4Vector(int l, int nbigg, int ng, int ny, int nu); Monom4Vector(int l, int nbigg, int ng, int ny, int nu);
/* substitution f(G(y,u,u',sigma),g(y,u,sigma),y,u) */ /* substitution f(G(y,u,u',sigma),g(y,u,sigma),y,u) */
Monom4Vector(const Monom4Vector& f, const Monom4Vector& bigg, Monom4Vector(const Monom4Vector &f, const Monom4Vector &bigg,
const Monom4Vector& g); const Monom4Vector &g);
~Monom4Vector(); ~Monom4Vector();
FSSparseTensor* deriv(int dim) const; FSSparseTensor *deriv(int dim) const;
FGSTensor* deriv(const Symmetry& s) const; FGSTensor *deriv(const Symmetry &s) const;
void deriv(const Symmetry& s, const IntSequence& coor, Vector& out) const; void deriv(const Symmetry &s, const IntSequence &coor, Vector &out) const;
void print() const; void print() const;
protected: protected:
void init_random(); void init_random();
}; };
struct SparseDerivGenerator
struct SparseDerivGenerator { {
int maxdimen; int maxdimen;
FGSContainer* bigg; FGSContainer *bigg;
FGSContainer* g; FGSContainer *g;
FGSContainer* rcont; FGSContainer *rcont;
FSSparseTensor** const ts; FSSparseTensor **const ts;
SparseDerivGenerator(int nf, int ny, int nu, int nup, int nbigg, int ng, SparseDerivGenerator(int nf, int ny, int nu, int nup, int nbigg, int ng,
int mx, double prob, int maxdim); int mx, double prob, int maxdim);
~SparseDerivGenerator(); ~SparseDerivGenerator();
}; };
struct DenseDerivGenerator
struct DenseDerivGenerator { {
int maxdimen; int maxdimen;
FGSContainer* xcont; FGSContainer *xcont;
FGSContainer* rcont; FGSContainer *rcont;
FGSTensor** const ts; FGSTensor **const ts;
UGSContainer* uxcont; UGSContainer *uxcont;
UGSTensor** const uts; UGSTensor **const uts;
DenseDerivGenerator(int ng, int nx, int ny, int nu, DenseDerivGenerator(int ng, int nx, int ny, int nu,
int mx, double prob, int maxdim); int mx, double prob, int maxdim);
void unfold(); void unfold();
~DenseDerivGenerator(); ~DenseDerivGenerator();
}; };
#endif #endif

View File

@ -11,41 +11,54 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
namespace ogu { namespace ogu
{
/** A primitive exception. */ /** A primitive exception. */
class Exception { class Exception
static const int file_length = 100; {
static const int mes_length = 500; static const int file_length = 100;
protected: static const int mes_length = 500;
char file[file_length]; protected:
int line; char file[file_length];
char mes[mes_length]; int line;
public: char mes[mes_length];
Exception(const char* f, int l, const char* m) public:
{ Exception(const char *f, int l, const char *m)
strncpy(file, f, file_length-1); {
file[file_length-1] = '\0'; strncpy(file, f, file_length-1);
line = l; file[file_length-1] = '\0';
strncpy(mes, m, std::min(mes_length-1,(int)strlen(m))); line = l;
mes[mes_length-1] = '\0'; strncpy(mes, m, std::min(mes_length-1, (int) strlen(m)));
} mes[mes_length-1] = '\0';
Exception(const char* f, int l, const std::string& m) }
{ Exception(const char *f, int l, const std::string &m)
strncpy(file, f, file_length-1); {
file[file_length-1] = '\0'; strncpy(file, f, file_length-1);
line = l; file[file_length-1] = '\0';
strncpy(mes, m.c_str(), std::min(mes_length-1,(int)m.length())); line = l;
mes[mes_length-1] = '\0'; strncpy(mes, m.c_str(), std::min(mes_length-1, (int) m.length()));
} mes[mes_length-1] = '\0';
virtual ~Exception() {} }
void print(FILE* fd) const virtual ~Exception()
{ fprintf(fd, "%s:%d: %s\n", file, line, mes); } {
void print() const }
{ print(stdout); } void
const char* message() const print(FILE *fd) const
{ return mes; } {
}; fprintf(fd, "%s:%d: %s\n", file, line, mes);
}
void
print() const
{
print(stdout);
}
const char *
message() const
{
return mes;
}
};
}; };
#endif #endif

View File

@ -5,51 +5,69 @@
#ifndef OGU_MEMORY_FILE #ifndef OGU_MEMORY_FILE
#define OGU_MEMORY_FILE #define OGU_MEMORY_FILE
namespace ogu { namespace ogu
/** This function calculates an offset of a given position in a {
* given string. The position is given by the line number and by /** This function calculates an offset of a given position in a
* the offset in the line (both starting from 1). */ * given string. The position is given by the line number and by
int calc_pos_offset(int length, const char* str, int line, int col); * the offset in the line (both starting from 1). */
/** This function calculates a line number and column number of a int calc_pos_offset(int length, const char *str, int line, int col);
* character given by the offset in the string. It is inverse to /** This function calculates a line number and column number of a
* calc_pos_offset. */ * character given by the offset in the string. It is inverse to
void calc_pos_line_and_col(int length, const char* str, int offset, * calc_pos_offset. */
int& line, int& col); void calc_pos_line_and_col(int length, const char *str, int offset,
int &line, int &col);
/** This class opens a given file and makes its copy in memory and
* appends it with the '\0' character. Since the type of length is
* int, it can store files with size at most 4GB. If the file
* could be opened for reading, data is NULL and length is -1. If
* the file is empty but exists, len is zero and data points to a
* newly allocated memory containing '\0' character at the end. */
class MemoryFile {
protected:
int len;
char* data;
public:
MemoryFile(const char* fname);
virtual ~MemoryFile()
{if (data) delete [] data;}
int length() const
{return len;}
const char* base() const
{return data;}
bool exists() const
{return len != -1;}
/** Return the offset of a character in the given line
* (starting from 1) with the given offset in the line. */
int offset(int line, int lineoff) const
{return calc_pos_offset(len, data, line, lineoff);}
/** Return the line number and column number of the character
* defined by the offset. */
void line_and_col(int offset, int& line, int& col) const
{calc_pos_line_and_col(len, data, offset, line, col);}
};
/** This class opens a given file and makes its copy in memory and
* appends it with the '\0' character. Since the type of length is
* int, it can store files with size at most 4GB. If the file
* could be opened for reading, data is NULL and length is -1. If
* the file is empty but exists, len is zero and data points to a
* newly allocated memory containing '\0' character at the end. */
class MemoryFile
{
protected:
int len;
char *data;
public:
MemoryFile(const char *fname);
virtual ~MemoryFile()
{
if (data)
delete [] data;
}
int
length() const
{
return len;
}
const char *
base() const
{
return data;
}
bool
exists() const
{
return len != -1;
}
/** Return the offset of a character in the given line
* (starting from 1) with the given offset in the line. */
int
offset(int line, int lineoff) const
{
return calc_pos_offset(len, data, line, lineoff);
}
/** Return the line number and column number of the character
* defined by the offset. */
void
line_and_col(int offset, int &line, int &col) const
{
calc_pos_line_and_col(len, data, offset, line, col);
}
};
}; };
#endif #endif
// Local Variables: // Local Variables:

View File

@ -7,43 +7,54 @@
#include <vector> #include <vector>
namespace ogu { namespace ogu
{
using std::vector; using std::vector;
class PascalRow : public vector<int> { class PascalRow : public vector<int>
int k; {
public: int k;
PascalRow() public:
: vector<int>(), k(1) PascalRow()
{ push_back(2); } : vector<int>(), k(1)
void setFromPrevious(const PascalRow& prev); {
void prolong(const PascalRow& prev); push_back(2);
void prolongFirst(int n); }
void print() const; void setFromPrevious(const PascalRow &prev);
}; void prolong(const PascalRow &prev);
void prolongFirst(int n);
void print() const;
};
class PascalTriangle { class PascalTriangle
vector<PascalRow> tr; {
public: vector<PascalRow> tr;
PascalTriangle() public:
{tr.push_back(PascalRow());} PascalTriangle()
PascalTriangle(const PascalTriangle& triang) {
: tr(triang.tr) {} tr.push_back(PascalRow());
const PascalTriangle& operator=(const PascalTriangle& triang) }
{ tr = triang.tr; return *this;} PascalTriangle(const PascalTriangle &triang)
int noverk(int n, int k); : tr(triang.tr)
void print() const; {
protected: }
void ensure(int n, int k); const PascalTriangle &
int max_n() const; operator=(const PascalTriangle &triang)
int max_k() const; {
}; tr = triang.tr; return *this;
}
int noverk(int n, int k);
void print() const;
protected:
void ensure(int n, int k);
int max_n() const;
int max_k() const;
};
}; };
extern ogu::PascalTriangle ptriang; extern ogu::PascalTriangle ptriang;
#endif #endif
// Local Variables: // Local Variables:

View File

@ -155,18 +155,18 @@ sigma_m =-5.85;
Lambdamu=3.4e-3; Lambdamu=3.4e-3;
LambdaA = 2.8e-3; LambdaA = 2.8e-3;
LambdaYd= (LambdaA+alppha*Lambdamu)/(1-alppha);
/* /*
The following parameters are set in the steady state file as they depend on other The following parameters are set in the steady state file as they depend on other
deep parameters that were estimated in the original study. Setting them in the deep parameters (some were estimated in the original study). Setting them in the
steady state file means they are updated for every parameter draw in the MCMC steady state file means they are updated for every parameter draw in the MCMC
algorithm, while the parameters initialized here are only set once for the initial algorithm, while the parameters initialized here are only set once for the initial
values of the parameters they depend on: values of the parameters they depend on:
gammma1 as it depends on LambdaA, alppha, Lambdamu, betta, and delta gammma1=mu_z*mu_I/betta-(1-delta);
Rbar =0 as it depends on PI, LambdaA, alppha, Lambdamu, and betta R=1+(PIbar*mu_z/betta-1);
Lambdax Lambdax=exp(LambdaYd);
LambdaYd= (LambdaA+alppha*Lambdamu)/(1-alppha);
*/ */

View File

@ -36,6 +36,7 @@ d=1;
phi=1; phi=1;
m=0; m=0;
zeta=1; zeta=1;
LambdaYd= (LambdaA+alppha*Lambdamu)/(1-alppha);
mu_z=exp(LambdaYd); mu_z=exp(LambdaYd);
mu_I=exp(Lambdamu); mu_I=exp(Lambdamu);
mu_A=exp(LambdaA); mu_A=exp(LambdaA);

View File

@ -6,22 +6,26 @@
* The data are in file "fsdat_simul.m", and have been artificially generated. * The data are in file "fsdat_simul.m", and have been artificially generated.
* They are therefore different from the original dataset used by Schorfheide. * They are therefore different from the original dataset used by Schorfheide.
* *
* The prior distribution follows the one originally specified in Schorfheide's paper. * The prior distribution follows the one originally specified in Schorfheide's
* Note that the beta prior for rho implies an asymptote and corresponding prior mode * paper, except for parameter rho. In the paper, the elicited beta prior for rho
* for rho at 0. It is generally recommended to avoid this extreme type of prior. * implies an asymptote and corresponding prior mode at 0. It is generally
* recommended to avoid this extreme type of prior. Some optimizers, for instance
* mode_compute=12 (Mathworks' particleswarm algorithm) may find a posterior mode
* with rho equal to zero. We lowered the value of the prior standard deviation
* (changing .223 to .100) to remove the asymptote.
* *
* The equations are taken from J. Nason and T. Cogley (1994): "Testing the * The equations are taken from J. Nason and T. Cogley (1994): "Testing the
* implications of long-run neutrality for monetary business cycle models", * implications of long-run neutrality for monetary business cycle models",
* Journal of Applied Econometrics, 9, S37-S70. * Journal of Applied Econometrics, 9, S37-S70.
* Note that there is an initial minus sign missing in equation (A1), p. S63. * Note that there is an initial minus sign missing in equation (A1), p. S63.
* *
* This implementation was written by Michel Juillard. Please note that the * This implementation was originally written by Michel Juillard. Please note that the
* following copyright notice only applies to this Dynare implementation of the * following copyright notice only applies to this Dynare implementation of the
* model. * model.
*/ */
/* /*
* Copyright (C) 2004-2015 Dynare Team * Copyright (C) 2004-2017 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -109,7 +113,7 @@ alp, beta_pdf, 0.356, 0.02;
bet, beta_pdf, 0.993, 0.002; bet, beta_pdf, 0.993, 0.002;
gam, normal_pdf, 0.0085, 0.003; gam, normal_pdf, 0.0085, 0.003;
mst, normal_pdf, 1.0002, 0.007; mst, normal_pdf, 1.0002, 0.007;
rho, beta_pdf, 0.129, 0.223; rho, beta_pdf, 0.129, 0.100;
psi, beta_pdf, 0.65, 0.05; psi, beta_pdf, 0.65, 0.05;
del, beta_pdf, 0.01, 0.005; del, beta_pdf, 0.01, 0.005;
stderr e_a, inv_gamma_pdf, 0.035449, inf; stderr e_a, inv_gamma_pdf, 0.035449, inf;

View File

@ -1,16 +1,15 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Dynare Upstream-Name: Dynare
Upstream-Contact: Dynare Team, whose members in 2016 are: Upstream-Contact: Dynare Team, whose members in 2017 are:
Stéphane Adjemian <stephane.adjemian@univ-lemans.fr> Stéphane Adjemian <stephane.adjemian@univ-lemans.fr>
Houtan Bastani <houtan@dynare.org> Houtan Bastani <houtan@dynare.org>
Michel Juillard <michel.juillard@mjui.fr> Michel Juillard <michel.juillard@mjui.fr>
Frédéric Karamé <frederic.karame@univ-lemans.fr> Frédéric Karamé <frederic.karame@univ-lemans.fr>
Junior Maih <junior.maih@gmail.com> Junior Maih <junior.maih@gmail.com>
Ferhat Mihoubi <fmihoubi@univ-evry.fr> Ferhat Mihoubi <fmihoubi@univ-evry.fr>
George Perendia <george@perendia.orangehome.co.uk>
Johannes Pfeifer <jpfeifer@gmx.de> Johannes Pfeifer <jpfeifer@gmx.de>
Marco Ratto <marco.ratto@jrc.ec.europa.eu> Marco Ratto <marco.ratto@ec.europa.eu>
Sébastien Villemot <sebastien@dynare.org> Sébastien Villemot <sebastien.villemot@sciencespo.fr>
Source: http://www.dynare.org Source: http://www.dynare.org
Files: * Files: *
@ -18,8 +17,8 @@ Copyright: 1996-2017 Dynare Team
License: GPL-3+ License: GPL-3+
Files: matlab/AIM/SP* Files: matlab/AIM/SP*
Copyright: public-domain Copyright: none
License: public-domain License: public-domain-aim
This code is in the public domain and may be used freely. This code is in the public domain and may be used freely.
However the authors would appreciate acknowledgement of the source by However the authors would appreciate acknowledgement of the source by
citation of any of the following papers: citation of any of the following papers:
@ -86,6 +85,57 @@ Copyright: 2016 Benjamin Born and Johannes Pfeifer
2016 Dynare Team 2016 Dynare Team
License: GPL-3+ License: GPL-3+
Files: matlab/gsa/Morris_Measure_Groups.m
matlab/gsa/Sampling_Function_2.m
Copyright: 2005 European Commission
2012 Dynare Team
License: GPL-3+
Comment: Written by Jessica Cariboni and Francesca Campolongo
Joint Research Centre, The European Commission,
Files: matlab/gsa/cumplot.m
matlab/gsa/filt_mc_.m
matlab/gsa/gsa_plotmatrix.m
matlab/gsa/gsa_skewness.m
matlab/gsa/gsa_speed.m
matlab/gsa/log_trans_.m
matlab/gsa/map_calibration.m
matlab/gsa/map_ident_.m
matlab/gsa/mcf_analysis.m
matlab/gsa/myboxplot.m
matlab/gsa/myprctilecol.m
matlab/gsa/prior_draw_gsa.m
matlab/gsa/read_data.m
matlab/gsa/redform_map.m
matlab/gsa/redform_screen.m
matlab/gsa/scatter_mcf.m
matlab/gsa/smirnov.m
matlab/gsa/stab_map_.m
matlab/gsa/stab_map_1.m
matlab/gsa/stab_map_2.m
matlab/gsa/stand_.m
matlab/gsa/tcrit.m
matlab/gsa/teff.m
matlab/gsa/trank.m
Copyright: 2011-2017 European Commission
2011-2017 Dynare Team
License: GPL-3+
Files: matlab/gsa/pick.m
Copyright: none
License: public-domain-jrc
This software has been developed at the Joint Research Centre of European Commission
by officers in the course of their official duties. This software is not subject to copyright
protection and is in the public domain. It is an experimental system. The Joint Research Centre
of European Commission assumes no responsibility whatsoever for its use by other parties
and makes no guarantees, expressed or implied, about its quality, reliability, or any other
characteristic. We would appreciate acknowledgement if the software is used.
Comment: This file is part of GLUEWIN.
The program has been developed by M. Ratto, European Commission, Joint Research Centre,
Institute for the Protection and Security of The Citizen, Technological and Economic Risk Management,
Applied Statistics, as a deliverable of the IMPACT project
(EC Fifth Framework Programme, SCA Project, IST-1999-11313, DG-INFSO).
Files: matlab/optimization/simpsa.m matlab/optimization/simpsaget.m matlab/optimization/simpsaset.m Files: matlab/optimization/simpsa.m matlab/optimization/simpsaget.m matlab/optimization/simpsaset.m
Copyright: 2005 Henning Schmidt, FCC, henning@fcc.chalmers.se Copyright: 2005 Henning Schmidt, FCC, henning@fcc.chalmers.se
2006 Brecht Donckels, BIOMATH, brecht.donckels@ugent.be 2006 Brecht Donckels, BIOMATH, brecht.donckels@ugent.be
@ -127,37 +177,24 @@ Copyright: 2005 Jos van der Geest <jos@jasen.nl>
2013 Christophe Gouel 2013 Christophe Gouel
2016 Dynare Team 2016 Dynare Team
License: BSD-2-clause License: BSD-2-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Files: matlab/lmmcp/lmmcp.m Files: matlab/lmmcp/lmmcp.m
Copyright: 2005 Christian Kanzow and Stefania Petra Copyright: 2005 Christian Kanzow and Stefania Petra
2013 Christophe Gouel 2013 Christophe Gouel
2014 Dynare Team 2014 Dynare Team
License: permissive License: permissive-lmmcp
Unlimited permission is granted to everyone to use, copy, modify or Unlimited permission is granted to everyone to use, copy, modify or
distribute this software. distribute this software.
Files: doc/dynare.texi doc/*.tex doc/*.svg doc/*.dia doc/*.pdf doc/*.bib Files: matlab/utilities/graphics/distinguishable_colors.m
Copyright: 2010-2011 Timothy E. Holy
License: BSD-2-clause
Files: matlab/utilities/graphics/colorspace.m
Copyright: 2005-2010 Pascal Getreuer
License: BSD-2-clause
Files: doc/dynare.texi doc/*.tex doc/*.svg doc/*.pdf doc/*.bib
Copyright: 1996-2017 Dynare Team Copyright: 1996-2017 Dynare Team
License: GFDL-NIV-1.3+ License: GFDL-NIV-1.3+
@ -206,7 +243,7 @@ Files: m4/ax_compare_version.m4
Copyright: 2008 Tim Toolan <toolan@ele.uri.edu> Copyright: 2008 Tim Toolan <toolan@ele.uri.edu>
License: permissive-autoconf License: permissive-autoconf
Files: m4/ax_latex_bibtex_test.m4 m4/ax_latex_class.m4 m4/ax_tex_test.m4 Files: m4/ax_latex_class.m4 m4/ax_tex_test.m4
Copyright: 2008 Boretti Mathieu <boretti@eig.unige.ch> Copyright: 2008 Boretti Mathieu <boretti@eig.unige.ch>
2009 Dynare Team 2009 Dynare Team
License: LGPL-2.1+ License: LGPL-2.1+
@ -235,7 +272,7 @@ Copyright: 1996-2011 Daniel Waggoner and Tao Zha
License: GPL-3+ License: GPL-3+
Files: contrib/ms-sbvar/switch_dw/state_space/sbvar/dw_csminwel.c Files: contrib/ms-sbvar/switch_dw/state_space/sbvar/dw_csminwel.c
state_space/sbvar/dw_csminwel.h contrib/ms-sbvar/switch_dw/state_space/sbvar/dw_csminwel.h
Copyright: 1996 Christopher Sims Copyright: 1996 Christopher Sims
2003 Karibzhanov, Waggoner and Zha 2003 Karibzhanov, Waggoner and Zha
License: GPL-3+ License: GPL-3+
@ -316,7 +353,7 @@ License: GPL-3+
Files: contrib/dmm/randlib/* Files: contrib/dmm/randlib/*
Copyright: none Copyright: none
License: public-domain License: public-domain-dmm
We place the Randlib code that we have written in the public domain. We place the Randlib code that we have written in the public domain.
. .
NO WARRANTY NO WARRANTY
@ -336,6 +373,29 @@ License: public-domain
ITS ANALYSIS BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD ITS ANALYSIS BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD
PARTIES) THE PROGRAM. PARTIES) THE PROGRAM.
License: BSD-2-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
License: GFDL-NIV-1.3+ License: GFDL-NIV-1.3+
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or under the terms of the GNU Free Documentation License, Version 1.3 or
@ -344,21 +404,6 @@ License: GFDL-NIV-1.3+
. .
A copy of the license can be found at <http://www.gnu.org/licenses/fdl.txt> A copy of the license can be found at <http://www.gnu.org/licenses/fdl.txt>
License: GPL-2+
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 the Free Software Foundation, either version 2 of
the License, or (at your option) any later version.
.
This program 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 this program. If not, see
<http://www.gnu.org/licenses/>.
License: GPL-2+ with Autoconf exception License: GPL-2+ with Autoconf exception
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as

View File

@ -1,66 +0,0 @@
# ===========================================================================
# http://www.nongnu.org/autoconf-archive/ax_latex_test.html
# ===========================================================================
#
# OBSOLETE MACRO
#
# Deprecated because of licensing issues. The Lesser GPL imposes licensing
# restrictions on the generated configure script unless it is augmented
# with an Autoconf Exception clause.
#
# SYNOPSIS
#
# AX_LATEX_BIBTEX_TEST(FILEDATA,BIBDATA,VARIABLETOSET,[NOCLEAN])
#
# DESCRIPTION
#
# This macros creates a bib file called contest.bib with BIBDATA,
# executes the latex application with FILEDATA as input, then runs
# bibtex on the resulting aux file, and finally sets VARIABLETOSET
# to yes or no depending on the result. If NOCLEAN is set, the folder
# used for the test is not deleted after testing.
#
# The macro assumes that the variables PDFLATEX and BIBTEX are set.
#
# Adapted from the macro AX_LATEX_TEST by Sébastien Villemot.
#
# LICENSE
#
# Copyright (c) 2008 Boretti Mathieu <boretti@eig.unige.ch>
# Copyright (c) 2009 Dynare Team
#
# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# This library 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 Lesser
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
AC_DEFUN([AX_LATEX_BIBTEX_TEST],[
rm -rf conftest.dir/.acltx
AS_MKDIR_P([conftest.dir/.acltx])
cd conftest.dir/.acltx
m4_ifval([$3],[$3="no"; export $3;])
cat > conftest.tex << ACLEOF
$1
ACLEOF
cat > conftest.bib << ACLEOF
$2
ACLEOF
$PDFLATEX conftest 2>&1 1>output
$BIBTEX conftest 2>&1 1>output2 m4_ifval([$3],[&& $3=yes])
cd ..
cd ..
sed 's/^/| /' conftest.dir/.acltx/conftest.tex >&5
echo "$as_me:$LINENO: executing $PDFLATEX conftest" >&5
sed 's/^/| /' conftest.dir/.acltx/output >&5
echo "$as_me:$LINENO: executing $BIBTEX conftest" >&5
sed 's/^/| /' conftest.dir/.acltx/output2 >&5
m4_ifval([$4],,[rm -rf conftest.dir/.acltx])
])

View File

@ -22,6 +22,9 @@ AC_REQUIRE([AX_MATLAB])
AC_MSG_CHECKING([for MATLAB version]) AC_MSG_CHECKING([for MATLAB version])
if test "x$MATLAB_VERSION" != "x"; then if test "x$MATLAB_VERSION" != "x"; then
case $MATLAB_VERSION in case $MATLAB_VERSION in
*2017a | *2017A)
MATLAB_VERSION="9.2"
;;
*2016b | *2016B) *2016b | *2016B)
MATLAB_VERSION="9.1" MATLAB_VERSION="9.1"
;; ;;

View File

@ -1,61 +0,0 @@
function t = dynTimeIndex() % --*-- Unitary tests --*--
% t = dynTimeIndex()
%
% Constructor for the dynTimeIndex class.
%
% INPUTS:
% None.
%
% OUTPUTS:
% * t, dynTimeIndex object.
%
% DESCRIPTION:
% The dynTimeIndex object is used to shift backward or forward dseries objects. For instance, if ts
% is a dseries object and t is a dynTimeIndex object then the following expressions are equivalent:
%
% us = ts.lag()
% us = ts.lag(1)
% us = lag(ts,1)
% us = ts(t-1)
%
% This class has only one member: t = int8(0) when instantiated.
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
t = struct();
t.index = int8(0);
t = class(t,'dynTimeIndex');
%@test:1
%$ % Instantiate a dynTimeIndex object
%$ try
%$ u = dynTimeIndex();
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = isa(u,'dynTimeIndex');
%$ end
%$
%$ T = all(t);
%@eof:1

View File

@ -1,62 +0,0 @@
function C = minus(A,B) % --*-- Unitary tests --*--
% C = minus(A,B)
%
% Overloads binary minus operator.
%
% INPUTS:
% * A, dynTimeIndex object.
% * B, integer scalar.
%
% OUTPUTS:
% * C, dynTimeIndex object.
%
% EXAMPLE:
%
% >> t = dynTimeIndex();
% >> t.index
%
% ans =
%
% 0
%
% >> s = t-1;
% >> s.index
%
% ans =
%
% -1
%
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
if ~(isa(A,'dynTimeIndex') || isint(B))
error(['dynTimeIndex::plus: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
end
C = struct();
C.index = A.index-B;
C = class(C,'dynTimeIndex');
%@test:1
%$ a = dynTimeIndex();
%$ b = a-1;
%$ t(1) = isa(b,'dynTimeIndex');
%$ t(2) = isequal(b.index,-int8(1));
%$ T = all(t);
%@eof:1

View File

@ -1,74 +0,0 @@
function C = mpower(A,B) % --*-- Unitary tests --*--
% C = mpower(A,B)
%
% Overloads binary mpower operator (^).
%
% INPUTS :
% * A, dynTimeIndex object.
% * B, integer scalar.
%
% OUTPUTS :
% * C, dynTimeIndex object.
%
% EXAMPLE 1 :
%
% >> B = dynTimeIndex()-1;
% >> B
% B = <dynTimeIndex: -1>
% >> B^4
% ans = <dynTimeIndex: -4>
% >>
%
% EXAMPLE 2 :
% This method can be used to apply the lead and lag methods an arbitrary number of times to a dseries object. For instance, if
% ts is a dseries object, and if we define
%
% >> B = dynTimeIndex()-1;
% >> F = dynTimeIndex()+1;
%
% B and F can be used as lag and lead operators and the following syntax:
%
% >> us = ts(F^2);
%
% is equivalent to
%
% >> us = ts.lead(2)
%
% or
%
% >> us = ts.lead.lead
%
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
if ~(isa(A,'dynTimeIndex') || isint(B))
error(['dynTimeIndex::mpower: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
end
C = struct();
C.index = A.index*B;
C = class(C,'dynTimeIndex');
%@test:1
%$ a = dynTimeIndex()+1;
%$ b = a^2;
%$ t(1) = isa(b,'dynTimeIndex');
%$ t(2) = isequal(b.index,int8(2));
%$ T = all(t);
%@eof:1

View File

@ -1,62 +0,0 @@
function C = plus(A,B) % --*-- Unitary tests --*--
% C = plus(A,B)
%
% Overloads binary plus operator.
%
% INPUTS:
% * A, dynTimeIndex object.
% * B, integer scalar.
%
% OUTPUTS:
% * C, dynTimeIndex object.
%
% EXAMPLE:
%
% >> t = dynTimeIndex();
% >> t.index
%
% ans =
%
% 0
%
% >> s = t+1;
% >> s.index
%
% ans =
%
% 1
%
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
if ~(isa(A,'dynTimeIndex') || isint(B))
error(['dynTimeIndex::plus: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
end
C = struct();
C.index = A.index+B;
C = class(C,'dynTimeIndex');
%@test:1
%$ a = dynTimeIndex();
%$ b = a+1;
%$ t(1) = isa(b,'dynTimeIndex');
%$ t(2) = isequal(b.index,int8(1));
%$ T = all(t);
%@eof:1

View File

@ -1,54 +0,0 @@
function B = subsref(A,S) % --*-- Unitary tests --*--
% B = subsref(A,S)
%
% Overloads the subsref method for dynTimeIndex class. This method only allows to get
% the value of the field `index`.
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
if length(S)>1
error('dynTimeIndex::subsref: Something is wrong in your syntax!')
end
if isequal(S.type,'.')
if isequal(S.subs,'index')
B = builtin('subsref', A, S(1));
else
error(['dynTimeIndex::subsref: ' S.subs ' is not a known member!'])
end
else
error('dynTimeIndex::subsref: Something is wrong in your syntax!')
end
%@test:1
%$ % Instantiate a dynTimeIndex object
%$ u = dynTimeIndex();
%$ try
%$ v = u.index;
%$ t(1) = 1;
%$ catch
%$ t(1) = 0;
%$ end
%$
%$ if t(1)
%$ t(2) = isequal(v,int8(0));
%$ end
%$
%$ T = all(t);
%@eof:1

View File

@ -8,7 +8,7 @@ function [AHess, DLIK, LIK] = AHessian(T,R,Q,H,P,Y,DT,DYss,DOm,DH,DP,start,mf,ka
% NOTE: the derivative matrices (DT,DR ...) are 3-dim. arrays with last % NOTE: the derivative matrices (DT,DR ...) are 3-dim. arrays with last
% dimension equal to the number of structural parameters % dimension equal to the number of structural parameters
% Copyright (C) 2011-2016 Dynare Team % Copyright (C) 2011-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -26,120 +26,120 @@ function [AHess, DLIK, LIK] = AHessian(T,R,Q,H,P,Y,DT,DYss,DOm,DH,DP,start,mf,ka
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
k = size(DT,3); % number of structural parameters k = size(DT,3); % number of structural parameters
smpl = size(Y,2); % Sample size. smpl = size(Y,2); % Sample size.
pp = size(Y,1); % Maximum number of observed variables. pp = size(Y,1); % Maximum number of observed variables.
mm = size(T,2); % Number of state variables. mm = size(T,2); % Number of state variables.
a = zeros(mm,1); % State vector. a = zeros(mm,1); % State vector.
Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations. Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
t = 0; % Initialization of the time index. t = 0; % Initialization of the time index.
oldK = 0; oldK = 0;
notsteady = 1; % Steady state flag. notsteady = 1; % Steady state flag.
F_singular = 1; F_singular = 1;
lik = zeros(smpl,1); % Initialization of the vector gathering the densities. lik = zeros(smpl,1); % Initialization of the vector gathering the densities.
LIK = Inf; % Default value of the log likelihood. LIK = Inf; % Default value of the log likelihood.
if nargout > 1, if nargout > 1
DLIK = zeros(k,1); % Initialization of the score. DLIK = zeros(k,1); % Initialization of the score.
end end
AHess = zeros(k,k); % Initialization of the Hessian AHess = zeros(k,k); % Initialization of the Hessian
Da = zeros(mm,k); % State vector. Da = zeros(mm,k); % State vector.
Dv = zeros(length(mf),k); Dv = zeros(length(mf),k);
% for ii = 1:k % for ii = 1:k
% DOm = DR(:,:,ii)*Q*transpose(R) + R*DQ(:,:,ii)*transpose(R) + R*Q*transpose(DR(:,:,ii)); % DOm = DR(:,:,ii)*Q*transpose(R) + R*DQ(:,:,ii)*transpose(R) + R*Q*transpose(DR(:,:,ii));
% end % end
while notsteady && t<smpl while notsteady && t<smpl
t = t+1; t = t+1;
v = Y(:,t)-a(mf); v = Y(:,t)-a(mf);
F = P(mf,mf) + H; F = P(mf,mf) + H;
if rcond(F) < kalman_tol if rcond(F) < kalman_tol
if ~all(abs(F(:))<kalman_tol) if ~all(abs(F(:))<kalman_tol)
return return
else
a = T*a;
P = T*P*transpose(T)+Om;
end
else else
F_singular = 0; a = T*a;
iF = inv(F); P = T*P*transpose(T)+Om;
K = P(:,mf)*iF;
lik(t) = log(det(F))+transpose(v)*iF*v;
[DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K);
for ii = 1:k
Dv(:,ii) = -Da(mf,ii) - DYss(mf,ii);
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
if t>=start && nargout > 1
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
end
end
vecDPmf = reshape(DP(mf,mf,:),[],k);
% iPmf = inv(P(mf,mf));
if t>=start
AHess = AHess + Dv'*iF*Dv + .5*(vecDPmf' * kron(iF,iF) * vecDPmf);
end
a = T*(a+K*v);
P = T*(P-K*P(mf,:))*transpose(T)+Om;
DP = DP1;
end end
notsteady = max(max(abs(K-oldK))) > riccati_tol; else
oldK = K; F_singular = 0;
end iF = inv(F);
K = P(:,mf)*iF;
lik(t) = log(det(F))+transpose(v)*iF*v;
if F_singular [DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K);
error('The variance of the forecast error remains singular until the end of the sample')
end
if t < smpl
t0 = t+1;
while t < smpl
t = t+1;
v = Y(:,t)-a(mf);
for ii = 1:k
Dv(:,ii) = -Da(mf,ii)-DYss(mf,ii);
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
if t>=start && nargout >1
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
end
end
if t>=start
AHess = AHess + Dv'*iF*Dv;
end
a = T*(a+K*v);
lik(t) = transpose(v)*iF*v;
end
AHess = AHess + .5*(smpl-t0+1)*(vecDPmf' * kron(iF,iF) * vecDPmf);
if nargout > 1
for ii = 1:k for ii = 1:k
% DLIK(ii,1) = DLIK(ii,1) + (smpl-t0+1)*trace( iF*DF(:,:,ii) ); Dv(:,ii) = -Da(mf,ii) - DYss(mf,ii);
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
if t>=start && nargout > 1
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
end
end end
vecDPmf = reshape(DP(mf,mf,:),[],k);
% iPmf = inv(P(mf,mf));
if t>=start
AHess = AHess + Dv'*iF*Dv + .5*(vecDPmf' * kron(iF,iF) * vecDPmf);
end end
lik(t0:smpl) = lik(t0:smpl) + log(det(F)); a = T*(a+K*v);
% for ii = 1:k; P = T*(P-K*P(mf,:))*transpose(T)+Om;
% for jj = 1:ii DP = DP1;
% H(ii,jj) = trace(iPmf*(.5*DP(mf,mf,ii)*iPmf*DP(mf,mf,jj) + Dv(:,ii)*Dv(:,jj)'));
% end
% end
end end
notsteady = max(max(abs(K-oldK))) > riccati_tol;
oldK = K;
end
if F_singular
error('The variance of the forecast error remains singular until the end of the sample')
end
if t < smpl
t0 = t+1;
while t < smpl
t = t+1;
v = Y(:,t)-a(mf);
for ii = 1:k
Dv(:,ii) = -Da(mf,ii)-DYss(mf,ii);
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
if t>=start && nargout >1
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
end
end
if t>=start
AHess = AHess + Dv'*iF*Dv;
end
a = T*(a+K*v);
lik(t) = transpose(v)*iF*v;
end
AHess = AHess + .5*(smpl-t0+1)*(vecDPmf' * kron(iF,iF) * vecDPmf);
if nargout > 1
for ii = 1:k
% DLIK(ii,1) = DLIK(ii,1) + (smpl-t0+1)*trace( iF*DF(:,:,ii) );
end
end
lik(t0:smpl) = lik(t0:smpl) + log(det(F));
% for ii = 1:k;
% for jj = 1:ii
% H(ii,jj) = trace(iPmf*(.5*DP(mf,mf,ii)*iPmf*DP(mf,mf,jj) + Dv(:,ii)*Dv(:,jj)'));
% end
% end
end
AHess = -AHess; AHess = -AHess;
if nargout > 1, if nargout > 1
DLIK = DLIK/2; DLIK = DLIK/2;
end end
% adding log-likelihhod constants % adding log-likelihhod constants
lik = (lik + pp*log(2*pi))/2; lik = (lik + pp*log(2*pi))/2;
LIK = sum(lik(start:end)); % Minus the log-likelihood. LIK = sum(lik(start:end)); % Minus the log-likelihood.
% end of main function % end of main function
function [DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K) function [DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K)
k = size(DT,3); k = size(DT,3);
tmp = P-K*P(mf,:); tmp = P-K*P(mf,:);
for ii = 1:k for ii = 1:k
DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii); DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii);
@ -150,6 +150,3 @@ for ii = 1:k
end end
% end of computeDKalman % end of computeDKalman

View File

@ -1,4 +1,4 @@
function e = SPAimerr(c); function e = SPAimerr(c)
% e = aimerr(c); % e = aimerr(c);
% %
% Interpret the return codes generated by the aim routines. % Interpret the return codes generated by the aim routines.
@ -29,7 +29,7 @@ function e = SPAimerr(c);
% Journal of Economic Dynamics and Control, 2010, vol. 34, issue 3, % Journal of Economic Dynamics and Control, 2010, vol. 34, issue 3,
% pages 472-489 % pages 472-489
if(c==1) e='Aim: unique solution.'; if(c==1) e='Aim: unique solution.';
elseif(c==2) e='Aim: roots not correctly computed by real_schur.'; elseif(c==2) e='Aim: roots not correctly computed by real_schur.';
elseif(c==3) e='Aim: too many big roots.'; elseif(c==3) e='Aim: too many big roots.';
elseif(c==35) e='Aim: too many big roots, and q(:,right) is singular.'; elseif(c==35) e='Aim: too many big roots, and q(:,right) is singular.';

View File

@ -1,5 +1,5 @@
function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ... function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
SPAmalg(h,neq,nlag,nlead,condn,uprbnd) SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
% [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ... % [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
% SPAmalg(h,neq,nlag,nlead,condn,uprbnd) % SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
% %
@ -66,12 +66,12 @@ bcols=neq*nlag;q=zeros(qrows,qcols);rts=zeros(qcols,1);
[h,q,iq,nexact]=SPExact_shift(h,q,iq,qrows,qcols,neq); [h,q,iq,nexact]=SPExact_shift(h,q,iq,qrows,qcols,neq);
if (iq>qrows) if (iq>qrows)
aimcode = 61; aimcode = 61;
return; return
end end
[h,q,iq,nnumeric]=SPNumeric_shift(h,q,iq,qrows,qcols,neq,condn); [h,q,iq,nnumeric]=SPNumeric_shift(h,q,iq,qrows,qcols,neq,condn);
if (iq>qrows) if (iq>qrows)
aimcode = 62; aimcode = 62;
return; return
end end
[a,ia,js] = SPBuild_a(h,qcols,neq); [a,ia,js] = SPBuild_a(h,qcols,neq);
if (ia ~= 0) if (ia ~= 0)
@ -81,7 +81,7 @@ if (ia ~= 0)
return return
end end
[w,rts,lgroots,flag_trouble]=SPEigensystem(a,uprbnd,min(length(js),qrows-iq+1)); [w,rts,lgroots,flag_trouble]=SPEigensystem(a,uprbnd,min(length(js),qrows-iq+1));
if flag_trouble==1; if flag_trouble==1
disp('Problem in SPEIG'); disp('Problem in SPEIG');
aimcode=64; aimcode=64;
return return

View File

@ -41,9 +41,9 @@ hs(:,left) = -hs(:,right)\hs(:,left);
a = zeros(qcols,qcols); a = zeros(qcols,qcols);
if(qcols > neq) if(qcols > neq)
eyerows = 1:qcols-neq; eyerows = 1:qcols-neq;
eyecols = neq+1:qcols; eyecols = neq+1:qcols;
a(eyerows,eyecols) = eye(qcols-neq); a(eyerows,eyecols) = eye(qcols-neq);
end end
hrows = qcols-neq+1:qcols; hrows = qcols-neq+1:qcols;
a(hrows,:) = hs(:,left); a(hrows,:) = hs(:,left);
@ -56,9 +56,9 @@ a(hrows,:) = hs(:,left);
js = 1:qcols; js = 1:qcols;
zerocols = sum(abs(a)) == 0; zerocols = sum(abs(a)) == 0;
while( any(zerocols) ) while( any(zerocols) )
a(:,zerocols) = []; a(:,zerocols) = [];
a(zerocols,:) = []; a(zerocols,:) = [];
js(zerocols) = []; js(zerocols) = [];
zerocols = sum(abs(a)) == 0; zerocols = sum(abs(a)) == 0;
end end
ia = length(js); ia = length(js);

View File

@ -30,7 +30,7 @@ function q = SPCopy_w(q,w,js,iq,qrows)
if(iq < qrows) if(iq < qrows)
lastrows = iq+1:qrows; lastrows = iq+1:qrows;
wrows = 1:length(lastrows); wrows = 1:length(lastrows);
q(lastrows,js) = w(:,wrows)'; q(lastrows,js) = w(:,wrows)';
end end

View File

@ -39,22 +39,22 @@ opts.disp=0;
% [mag,k] = sort(-mag); % [mag,k] = sort(-mag);
% rts = rts(k); % rts = rts(k);
%catch %catch
%disp('Catch in SPE'); %disp('Catch in SPE');
%pause(0.5); %pause(0.5);
%aStr=datestr(clock); %aStr=datestr(clock);
%eval(['save ' regexprep(aStr,' ','') ' a']); %eval(['save ' regexprep(aStr,' ','') ' a']);
try try
[w,d]=eig(a'); [w,d]=eig(a');
catch catch
lasterr lasterr
w=[];rts=[];lgroots=[]; w=[];rts=[];lgroots=[];
flag_trouble=1; flag_trouble=1;
return return
end end
rts = diag(d); rts = diag(d);
mag = abs(rts); mag = abs(rts);
[mag,k] = sort(-mag); [mag,k] = sort(-mag);
rts = rts(k); rts = rts(k);
%end %end
flag_trouble=0; flag_trouble=0;

View File

@ -36,12 +36,11 @@ right = qcols+1:qcols+neq;
zerorows = find( sum(abs( hs(:,right)' ))==0 ); zerorows = find( sum(abs( hs(:,right)' ))==0 );
while( any(zerorows) && iq <= qrows ) while( any(zerorows) && iq <= qrows )
nz = length(zerorows); nz = length(zerorows);
q(iq+1:iq+nz,:) = hs(zerorows,left); q(iq+1:iq+nz,:) = hs(zerorows,left);
hs(zerorows,:) = SPShiftright(hs(zerorows,:),neq); hs(zerorows,:) = SPShiftright(hs(zerorows,:),neq);
iq = iq + nz; iq = iq + nz;
nexact = nexact + nz; nexact = nexact + nz;
zerorows = find( sum(abs( hs(:,right)' ))==0 ); zerorows = find( sum(abs( hs(:,right)' ))==0 );
end end
h=full(hs); h=full(hs);

View File

@ -37,14 +37,14 @@ right = qcols+1:qcols+neq;
zerorows = find( abs(diag(R)) <= condn ); zerorows = find( abs(diag(R)) <= condn );
while( any(zerorows) && iq <= qrows ) while( any(zerorows) && iq <= qrows )
h=sparse(h); h=sparse(h);
Q=sparse(Q); Q=sparse(Q);
h = Q'*h; h = Q'*h;
nz = length(zerorows); nz = length(zerorows);
q(iq+1:iq+nz,:) = h(zerorows,left); q(iq+1:iq+nz,:) = h(zerorows,left);
h(zerorows,:) = SPShiftright( h(zerorows,:), neq ); h(zerorows,:) = SPShiftright( h(zerorows,:), neq );
iq = iq + nz; iq = iq + nz;
nnumeric = nnumeric + nz; nnumeric = nnumeric + nz;
[Q,R,E] = qr( full(h(:,right)) ); [Q,R,E] = qr( full(h(:,right)) );
zerorows = find( abs(diag(R)) <= condn ); zerorows = find( abs(diag(R)) <= condn );
end end

View File

@ -52,16 +52,16 @@ qs(1:rc,1:cc) = sparse(cofb);
qcols = neq*(nlag+nlead); qcols = neq*(nlag+nlead);
if( nlead > 1 ) if( nlead > 1 )
for i = 1:nlead-1 for i = 1:nlead-1
rows = i*neq + (1:neq); rows = i*neq + (1:neq);
qs(rows,:) = SPShiftright( qs((rows-neq),:), neq ); qs(rows,:) = SPShiftright( qs((rows-neq),:), neq );
end end
end end
l = (1: neq*nlag); l = (1: neq*nlag);
r = (neq*nlag+1: neq*(nlag+nlead)); r = (neq*nlag+1: neq*(nlag+nlead));
qs(:,l) = - qs(:,r) \ qs(:,l); qs(:,l) = - qs(:,r) \ qs(:,l);
minus = 1: neq*(nlag+1); minus = 1: neq*(nlag+1);
plus = neq*(nlag+1)+1: neq*(nlag+1+nlead); plus = neq*(nlag+1)+1: neq*(nlag+1+nlead);

View File

@ -1,4 +1,4 @@
function [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,condn); function [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,condn)
% [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,b,condn); % [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,b,condn);
% %
% Compute reduced-form coefficient matrix, b. % Compute reduced-form coefficient matrix, b.
@ -38,7 +38,7 @@ if(nonsing)
b = qs(1:neq,1:bcols); b = qs(1:neq,1:bcols);
b = full(b); b = full(b);
else %rescale by dividing row by maximal qr element else %rescale by dividing row by maximal qr element
%'inverse condition number small, rescaling ' %'inverse condition number small, rescaling '
themax=max(abs(qs(:,right)),[],2); themax=max(abs(qs(:,right)),[],2);
oneover = diag(1 ./ themax); oneover = diag(1 ./ themax);
nonsing = rcond(full(oneover *qs(:,right))) > condn; nonsing = rcond(full(oneover *qs(:,right))) > condn;
@ -48,4 +48,3 @@ else %rescale by dividing row by maximal qr element
b = full(b); b = full(b);
end end
end end

View File

@ -3,12 +3,12 @@ function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson % Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson
% and derives the solution for gy=dr.hgx and gu=dr.hgu from the AIM outputs % and derives the solution for gy=dr.hgx and gu=dr.hgu from the AIM outputs
% AIM System is given as a sum: % AIM System is given as a sum:
% i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,? % i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,?
% and its input as single array of matrices: [H-$... Hi ... H+&] % and its input as single array of matrices: [H-$... Hi ... H+&]
% and its solution as xt=SUM( Bi*xt+i) + @*£*zt for i=-$...-1 % and its solution as xt=SUM( Bi*xt+i) + @*£*zt for i=-$...-1
% with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1) % with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1)
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu'] % Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £ % where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £
% %
% INPUTS % INPUTS
% jacobia_ [matrix] 1st order derivative of the model % jacobia_ [matrix] 1st order derivative of the model
@ -46,7 +46,7 @@ function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% %
% GP July 2008 % GP July 2008
% Copyright (C) 2008-2012 Dynare Team % Copyright (C) 2008-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -51,7 +51,7 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
%! @end deftypefn %! @end deftypefn
%@eod: %@eod:
% Copyright (C) 2001-2016 Dynare Team % Copyright (C) 2001-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -68,34 +68,33 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
info = 0; info = 0;
[dr,aimcode]=dynAIMsolver1(jacobia,M,dr); [dr,aimcode]=dynAIMsolver1(jacobia,M,dr);
if aimcode ~=1 if aimcode ~=1
info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range
info(2) = 1.0e+8; info(2) = 1.0e+8;
return return
end
A = kalman_transition_matrix(dr,M.nstatic+(1:M.nspred), 1:M.nspred,...
M.exo_nbr);
dr.eigval = eig(A);
disp(dr.eigval)
nd = size(dr.kstate,1);
nba = nd-sum( abs(dr.eigval) < qz_criterium );
nsfwrd = M.nsfwrd;
if nba ~= nsfwrd
temp = sort(abs(dr.eigval));
if nba > nsfwrd
temp = temp(nd-nba+1:nd-nsfwrd)-1-qz_criterium;
info(1) = 3;
elseif nba < nsfwrd
temp = temp(nd-nsfwrd+1:nd-nba)-1-qz_criterium;
info(1) = 4;
end end
A = kalman_transition_matrix(dr,M.nstatic+(1:M.nspred), 1:M.nspred,... info(2) = temp'*temp;
M.exo_nbr); return
dr.eigval = eig(A); end
disp(dr.eigval)
nd = size(dr.kstate,1);
nba = nd-sum( abs(dr.eigval) < qz_criterium );
nsfwrd = M.nsfwrd;
if nba ~= nsfwrd
temp = sort(abs(dr.eigval));
if nba > nsfwrd
temp = temp(nd-nba+1:nd-nsfwrd)-1-qz_criterium;
info(1) = 3;
elseif nba < nsfwrd;
temp = temp(nd-nsfwrd+1:nd-nba)-1-qz_criterium;
info(1) = 4;
end
info(2) = temp'*temp;
return
end

View File

@ -12,7 +12,7 @@ function [DirectoryName, info] = CheckPath(type,dname)
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2005-2013 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -16,7 +16,7 @@ function CutSample(M_, options_, estim_params_)
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2005-2015 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -58,7 +58,7 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% None % None
% Copyright (C) 2006-2016 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -169,7 +169,7 @@ elseif options_.lik_init == 3 % Diffuse Kalman filter
kalman_algo = 3; kalman_algo = 3;
else else
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal... if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
%Augment state vector (follows Section 6.4.3 of DK (2012)) %Augment state vector (follows Section 6.4.3 of DK (2012))
expanded_state_vector_for_univariate_filter=1; expanded_state_vector_for_univariate_filter=1;
T = blkdiag(T,zeros(vobs)); T = blkdiag(T,zeros(vobs));
np = size(T,1); np = size(T,1);
@ -240,29 +240,31 @@ if kalman_algo == 1 || kalman_algo == 3
end end
if kalman_algo == 2 || kalman_algo == 4 if kalman_algo == 2 || kalman_algo == 4
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal... if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
if ~expanded_state_vector_for_univariate_filter if ~expanded_state_vector_for_univariate_filter
%Augment state vector (follows Section 6.4.3 of DK (2012)) %Augment state vector (follows Section 6.4.3 of DK (2012))
expanded_state_vector_for_univariate_filter=1; expanded_state_vector_for_univariate_filter=1;
Z = [Z, eye(vobs)]; Z = [Z, eye(vobs)];
ST = blkdiag(ST,zeros(vobs)); ST = blkdiag(ST,zeros(vobs));
np = size(ST,1); np = size(ST,1);
Q = blkdiag(Q,H); Q = blkdiag(Q,H);
R1 = blkdiag(R,eye(vobs)); R1 = blkdiag(R,eye(vobs));
if kalman_algo == 4 if kalman_algo == 4
%recompute Schur state space transformation with %recompute Schur state space transformation with
%expanded state space %expanded state space
[Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium); [Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
else else
Pstar = blkdiag(Pstar,H); Pstar = blkdiag(Pstar,H);
if ~isempty(Pinf)
Pinf = blkdiag(Pinf,zeros(vobs)); Pinf = blkdiag(Pinf,zeros(vobs));
end end
%now reset H to 0
H = zeros(vobs,vobs);
else
%do nothing, state vector was already expanded
end end
%now reset H to 0
H = zeros(vobs,vobs);
else
%do nothing, state vector was already expanded
end end
end
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH3_Z(ST, ... [alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH3_Z(ST, ...
Z,R1,Q,diag(H), ... Z,R1,Q,diag(H), ...

View File

@ -16,7 +16,7 @@ function Draws = GetAllPosteriorDraws(column, FirstMhFile, FirstLine, TotalNumbe
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2005-2011 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -13,7 +13,7 @@ function [xparams, logpost] = GetOneDraw(type)
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2005-2015 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -1,6 +1,6 @@
function [mean,variance] = GetPosteriorMeanVariance(M,drop) function [mean,variance] = GetPosteriorMeanVariance(M,drop)
% Copyright (C) 2012-2016 Dynare Team % Copyright (C) 2012-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -17,37 +17,37 @@ function [mean,variance] = GetPosteriorMeanVariance(M,drop)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
MetropolisFolder = CheckPath('metropolis',M.dname); MetropolisFolder = CheckPath('metropolis',M.dname);
FileName = M.fname; FileName = M.fname;
BaseName = [MetropolisFolder filesep FileName]; BaseName = [MetropolisFolder filesep FileName];
load_last_mh_history_file(MetropolisFolder, FileName); load_last_mh_history_file(MetropolisFolder, FileName);
NbrDraws = sum(record.MhDraws(:,1)); NbrDraws = sum(record.MhDraws(:,1));
NbrFiles = sum(record.MhDraws(:,2)); NbrFiles = sum(record.MhDraws(:,2));
NbrBlocks = record.Nblck; NbrBlocks = record.Nblck;
mean = 0; mean = 0;
variance = 0; variance = 0;
NbrKeptDraws = 0; NbrKeptDraws = 0;
for i=1:NbrBlocks for i=1:NbrBlocks
NbrDrawsCurrentBlock = 0; NbrDrawsCurrentBlock = 0;
for j=1:NbrFiles for j=1:NbrFiles
o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']); o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']);
NbrDrawsCurrentFile = size(o.x2,1); NbrDrawsCurrentFile = size(o.x2,1);
if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= drop*NbrDraws if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= drop*NbrDraws
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
continue
elseif NbrDrawsCurrentBlock < drop*NbrDraws
FirstDraw = ceil(drop*NbrDraws - NbrDrawsCurrentBlock + 1);
x2 = o.x2(FirstDraw:end,:);
else
x2 = o.x2;
end
NbrKeptDrawsCurrentFile = size(x2,1);
%recursively compute mean and variance
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
x2Demeaned = bsxfun(@minus,x2,mean');
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile; NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile; continue
elseif NbrDrawsCurrentBlock < drop*NbrDraws
FirstDraw = ceil(drop*NbrDraws - NbrDrawsCurrentBlock + 1);
x2 = o.x2(FirstDraw:end,:);
else
x2 = o.x2;
end end
NbrKeptDrawsCurrentFile = size(x2,1);
%recursively compute mean and variance
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
x2Demeaned = bsxfun(@minus,x2,mean');
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile;
end end
end

View File

@ -16,7 +16,7 @@ function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bay
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% None. % None.
% Copyright (C) 2006-2016 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -163,7 +163,7 @@ if nvx
end end
disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval,... disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval,...
pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip))); pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip)));
if TeX, if TeX
name = deblank(M_.exo_names_tex(k,:)); name = deblank(M_.exo_names_tex(k,:));
TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),... TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),...
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval); bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);
@ -311,7 +311,7 @@ if ncn
end end
disp(sprintf(pformat, header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval, ... disp(sprintf(pformat, header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval, ...
pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip))); pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip)));
if TeX, if TeX
name = ['(',deblank(M_.endo_names_tex(k1,:)) ',' deblank(M_.endo_names_tex(k2,:)),')']; name = ['(',deblank(M_.endo_names_tex(k1,:)) ',' deblank(M_.endo_names_tex(k2,:)),')'];
TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),... TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),...
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval); bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);

View File

@ -1,6 +1,6 @@
function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info) function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info)
% Copyright (C) 2005-2009 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -16,7 +16,7 @@ function oo_ = PlotPosteriorDistributions(estim_params_, M_, options_, bayestopt
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2005-2016 Dynare Team % Copyright (C) 2005-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -63,7 +63,7 @@ for i=1:npar
subplotnum = subplotnum+1; subplotnum = subplotnum+1;
if subplotnum == 1 if subplotnum == 1
figunumber = figunumber+1; figunumber = figunumber+1;
hfig=dyn_figure(options_,'Name',figurename); hfig=dyn_figure(options_.nodisplay,'Name',figurename);
end end
[nam,texnam] = get_the_name(i,TeX,M_,estim_params_,options_); [nam,texnam] = get_the_name(i,TeX,M_,estim_params_,options_);
if subplotnum == 1 if subplotnum == 1
@ -151,8 +151,8 @@ for i=1:npar
title(nam,'Interpreter','none'); title(nam,'Interpreter','none');
hold off; hold off;
drawnow drawnow
if subplotnum == MaxNumberOfPlotPerFigure || i == npar; if subplotnum == MaxNumberOfPlotPerFigure || i == npar
dyn_saveas(hfig,[OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors' int2str(figunumber)],options_); dyn_saveas(hfig,[OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors' int2str(figunumber)],options_.nodisplay,options_.graph_format);
if TeX && any(strcmp('eps',cellstr(options_.graph_format))) if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fprintf(fidTeX,'\\begin{figure}[H]\n'); fprintf(fidTeX,'\\begin{figure}[H]\n');
for j = 1:size(NAMES,1) for j = 1:size(NAMES,1)

View File

@ -16,7 +16,7 @@ function PosteriorIRF(type)
% functions associated with it(the _core1 and _core2). % functions associated with it(the _core1 and _core2).
% See also the comments posterior_sampler.m funtion. % See also the comments posterior_sampler.m funtion.
% Copyright (C) 2006-2016 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -178,7 +178,7 @@ if strcmpi(type,'posterior')
end end
end end
if ~strcmpi(type,'prior'), if ~strcmpi(type,'prior')
localVars.x=x; localVars.x=x;
end end
@ -202,16 +202,16 @@ localVars.ifil2=ifil2;
localVars.MhDirectoryName=MhDirectoryName; localVars.MhDirectoryName=MhDirectoryName;
% Like sequential execution! % Like sequential execution!
if isnumeric(options_.parallel), if isnumeric(options_.parallel)
[fout] = PosteriorIRF_core1(localVars,1,B,0); [fout] = PosteriorIRF_core1(localVars,1,B,0);
nosaddle = fout.nosaddle; nosaddle = fout.nosaddle;
else else
% Parallel execution! % Parallel execution!
[nCPU, totCPU, nBlockPerCPU] = distributeJobs(options_.parallel, 1, B); [nCPU, totCPU, nBlockPerCPU] = distributeJobs(options_.parallel, 1, B);
for j=1:totCPU-1, for j=1:totCPU-1
nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsge); nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsge);
NumberOfIRFfiles_dsge(j+1) =NumberOfIRFfiles_dsge(j)+nfiles; NumberOfIRFfiles_dsge(j+1) =NumberOfIRFfiles_dsge(j)+nfiles;
if MAX_nirfs_dsgevar, if MAX_nirfs_dsgevar
nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsgevar); nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsgevar);
else else
nfiles=0; nfiles=0;
@ -235,12 +235,17 @@ else
% which files have to be copied to run remotely % which files have to be copied to run remotely
NamFileInput(1,:) = {'',[M_.fname '_static.m']}; NamFileInput(1,:) = {'',[M_.fname '_static.m']};
NamFileInput(2,:) = {'',[M_.fname '_dynamic.m']}; NamFileInput(2,:) = {'',[M_.fname '_dynamic.m']};
if options_.steadystate_flag, NamFileInput(3,:) = {'',[M_.fname '_set_auxiliary_variables.m']};
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate.m']}; if options_.steadystate_flag
if options_.steadystate_flag == 1
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate.m']};
else
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate2.m']};
end
end end
[fout] = masterParallel(options_.parallel, 1, B,NamFileInput,'PosteriorIRF_core1', localVars, globalVars, options_.parallel_info); [fout] = masterParallel(options_.parallel, 1, B,NamFileInput,'PosteriorIRF_core1', localVars, globalVars, options_.parallel_info);
nosaddle=0; nosaddle=0;
for j=1:length(fout), for j=1:length(fout)
nosaddle = nosaddle + fout(j).nosaddle; nosaddle = nosaddle + fout(j).nosaddle;
end end
@ -363,101 +368,101 @@ end
% PosteriorIRF_core2.m function. % PosteriorIRF_core2.m function.
if ~options_.nograph && ~options_.no_graph.posterior if ~options_.nograph && ~options_.no_graph.posterior
% Save the local variables. % Save the local variables.
localVars=[]; localVars=[];
Check=options_.TeX; Check=options_.TeX;
if (Check) if (Check)
localVars.varlist_TeX=varlist_TeX; localVars.varlist_TeX=varlist_TeX;
end
localVars.nvar=nvar;
localVars.MeanIRF=MeanIRF;
localVars.tit=tit;
localVars.nn=nn;
localVars.MAX_nirfs_dsgevar=MAX_nirfs_dsgevar;
localVars.HPDIRF=HPDIRF;
localVars.varlist=varlist;
localVars.MaxNumberOfPlotPerFigure=MaxNumberOfPlotPerFigure;
if options_.dsge_var
localVars.HPDIRFdsgevar=HPDIRFdsgevar;
localVars.MeanIRFdsgevar = MeanIRFdsgevar;
end
% The files .TeX are genereted in sequential way always!
% The files .TeX are generated in sequential way always!
subplotnum = 0;
tit_TeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fidTeX = fopen([DirectoryName filesep M_.fname '_BayesianIRF.tex'],'w');
fprintf(fidTeX,'%% TeX eps-loader file generated by PosteriorIRF.m (Dynare).\n');
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
fprintf(fidTeX,' \n');
titTeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
for ii=irf_shocks_indx
figunumber = 0;
for jj=1:nvar
if max(abs(MeanIRF(:,jj,ii))) >= options_.impulse_responses.plot_threshold
subplotnum = subplotnum+1;
if subplotnum == 1
fprintf(fidTeX,'\\begin{figure}[H]\n');
end
name = deblank(varlist(jj,:));
texname = deblank(varlist_TeX(jj,:));
fprintf(fidTeX,['\\psfrag{%s}[1][][0.5][0]{%s}\n'],name,['$' texname '$']);
end
if subplotnum == MaxNumberOfPlotPerFigure || (jj == nvar && subplotnum> 0)
figunumber = figunumber+1;
fprintf(fidTeX,'\\centering \n');
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_Bayesian_IRF_%s_%d}\n',options_.figures.textwidth*min(subplotnum/nn,1),DirectoryName,M_.fname,deblank(tit(ii,:)),figunumber);
if options_.relative_irf
fprintf(fidTeX,['\\caption{Bayesian relative IRF.}']);
else
fprintf(fidTeX,'\\caption{Bayesian IRF: Orthogonalized shock to $%s$.}\n',deblank(tit_TeX(ii,:)));
end
fprintf(fidTeX,'\\label{Fig:BayesianIRF:%s:%d}\n',deblank(tit(ii,:)),figunumber);
fprintf(fidTeX,'\\end{figure}\n');
fprintf(fidTeX,' \n');
subplotnum = 0;
end
end
end end
fprintf(fidTeX,'%% End of TeX file.\n');
fclose(fidTeX);
end
% The others file format are generated in parallel by PosteriorIRF_core2!
% Comment for testing! localVars.nvar=nvar;
if ~isoctave localVars.MeanIRF=MeanIRF;
if isnumeric(options_.parallel) || (M_.exo_nbr*ceil(size(varlist,1)/MaxNumberOfPlotPerFigure))<8, localVars.tit=tit;
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0); localVars.nn=nn;
else localVars.MAX_nirfs_dsgevar=MAX_nirfs_dsgevar;
isRemoteOctave = 0; localVars.HPDIRF=HPDIRF;
for indPC=1:length(options_.parallel), localVars.varlist=varlist;
isRemoteOctave = isRemoteOctave + (findstr(options_.parallel(indPC).MatlabOctavePath, 'octave')); localVars.MaxNumberOfPlotPerFigure=MaxNumberOfPlotPerFigure;
if options_.dsge_var
localVars.HPDIRFdsgevar=HPDIRFdsgevar;
localVars.MeanIRFdsgevar = MeanIRFdsgevar;
end
% The files .TeX are genereted in sequential way always!
% The files .TeX are generated in sequential way always!
subplotnum = 0;
tit_TeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fidTeX = fopen([DirectoryName filesep M_.fname '_BayesianIRF.tex'],'w');
fprintf(fidTeX,'%% TeX eps-loader file generated by PosteriorIRF.m (Dynare).\n');
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
fprintf(fidTeX,' \n');
titTeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
for ii=irf_shocks_indx
figunumber = 0;
for jj=1:nvar
if max(abs(MeanIRF(:,jj,ii))) >= options_.impulse_responses.plot_threshold
subplotnum = subplotnum+1;
if subplotnum == 1
fprintf(fidTeX,'\\begin{figure}[H]\n');
end
name = deblank(varlist(jj,:));
texname = deblank(varlist_TeX(jj,:));
fprintf(fidTeX,['\\psfrag{%s}[1][][0.5][0]{%s}\n'],name,['$' texname '$']);
end
if subplotnum == MaxNumberOfPlotPerFigure || (jj == nvar && subplotnum> 0)
figunumber = figunumber+1;
fprintf(fidTeX,'\\centering \n');
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_Bayesian_IRF_%s_%d}\n',options_.figures.textwidth*min(subplotnum/nn,1),DirectoryName,M_.fname,deblank(tit(ii,:)),figunumber);
if options_.relative_irf
fprintf(fidTeX,['\\caption{Bayesian relative IRF.}']);
else
fprintf(fidTeX,'\\caption{Bayesian IRF: Orthogonalized shock to $%s$.}\n',deblank(tit_TeX(ii,:)));
end
fprintf(fidTeX,'\\label{Fig:BayesianIRF:%s:%d}\n',deblank(tit(ii,:)),figunumber);
fprintf(fidTeX,'\\end{figure}\n');
fprintf(fidTeX,' \n');
subplotnum = 0;
end
end
end end
if isRemoteOctave fprintf(fidTeX,'%% End of TeX file.\n');
fclose(fidTeX);
end
% The others file format are generated in parallel by PosteriorIRF_core2!
% Comment for testing!
if ~isoctave
if isnumeric(options_.parallel) || (M_.exo_nbr*ceil(size(varlist,1)/MaxNumberOfPlotPerFigure))<8
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0); [fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
else else
globalVars = struct('M_',M_, ... isRemoteOctave = 0;
'options_', options_); for indPC=1:length(options_.parallel)
isRemoteOctave = isRemoteOctave + (findstr(options_.parallel(indPC).MatlabOctavePath, 'octave'));
end
if isRemoteOctave
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
else
globalVars = struct('M_',M_, ...
'options_', options_);
[fout] = masterParallel(options_.parallel, 1, M_.exo_nbr,NamFileInput,'PosteriorIRF_core2', localVars, globalVars, options_.parallel_info); [fout] = masterParallel(options_.parallel, 1, M_.exo_nbr,NamFileInput,'PosteriorIRF_core2', localVars, globalVars, options_.parallel_info);
end
end end
else
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
end end
else % END parallel code!
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
end
% END parallel code!
end end

View File

@ -23,7 +23,7 @@ function myoutput=PosteriorIRF_core1(myinputs,fpar,B,whoiam, ThisMatlab)
% SPECIAL REQUIREMENTS. % SPECIAL REQUIREMENTS.
% None. % None.
% %
% Copyright (C) 2006-2016 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -43,7 +43,7 @@ function myoutput=PosteriorIRF_core1(myinputs,fpar,B,whoiam, ThisMatlab)
global options_ estim_params_ oo_ M_ bayestopt_ dataset_ dataset_info global options_ estim_params_ oo_ M_ bayestopt_ dataset_ dataset_info
if nargin<4, if nargin<4
whoiam=0; whoiam=0;
end end
@ -55,7 +55,7 @@ irun =myinputs.irun;
irun2=myinputs.irun2; irun2=myinputs.irun2;
npar=myinputs.npar; npar=myinputs.npar;
type=myinputs.type; type=myinputs.type;
if ~strcmpi(type,'prior'), if ~strcmpi(type,'prior')
x=myinputs.x; x=myinputs.x;
end end
@ -102,7 +102,7 @@ end
RemoteFlag = 0; RemoteFlag = 0;
if whoiam if whoiam
if Parallel(ThisMatlab).Local==0, if Parallel(ThisMatlab).Local==0
RemoteFlag =1; RemoteFlag =1;
end end
prct0={0,whoiam,Parallel(ThisMatlab)}; prct0={0,whoiam,Parallel(ThisMatlab)};
@ -165,7 +165,7 @@ while fpar<B
elseif info(1) == 5 elseif info(1) == 5
errordef = 'Rank condition is not satisfied'; errordef = 'Rank condition is not satisfied';
end end
if strcmpi(type,'prior'), if strcmpi(type,'prior')
disp(['PosteriorIRF :: Dynare is unable to solve the model (' errordef ')']) disp(['PosteriorIRF :: Dynare is unable to solve the model (' errordef ')'])
continue continue
else else
@ -240,9 +240,9 @@ while fpar<B
else else
stock_irf_bvardsge(:,:,:,IRUN) = reshape(tmp_dsgevar,options_.irf,dataset_.vobs,M_.exo_nbr); stock_irf_bvardsge(:,:,:,IRUN) = reshape(tmp_dsgevar,options_.irf,dataset_.vobs,M_.exo_nbr);
instr = [MhDirectoryName '/' M_.fname '_irf_bvardsge' ... instr = [MhDirectoryName '/' M_.fname '_irf_bvardsge' ...
int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];, int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];
eval(['save ' instr]); eval(['save ' instr]);
if RemoteFlag==1, if RemoteFlag==1
OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}]; OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}];
end end
NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1; NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1;
@ -259,14 +259,14 @@ while fpar<B
int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;']; int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];
eval(['save ' instr]); eval(['save ' instr]);
NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1; NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1;
if RemoteFlag==1, if RemoteFlag==1
OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}]; OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}];
end end
irun = 0; irun = 0;
end end
end end
save([MhDirectoryName '/' M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat'],'stock_irf_dsge'); save([MhDirectoryName '/' M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat'],'stock_irf_dsge');
if RemoteFlag==1, if RemoteFlag==1
OutputFileName_dsge = [OutputFileName_dsge; {[MhDirectoryName filesep], [M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat']}]; OutputFileName_dsge = [OutputFileName_dsge; {[MhDirectoryName filesep], [M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat']}];
end end
NumberOfIRFfiles_dsge = NumberOfIRFfiles_dsge+1; NumberOfIRFfiles_dsge = NumberOfIRFfiles_dsge+1;
@ -278,7 +278,7 @@ while fpar<B
end end
stock = stock_param; stock = stock_param;
save([MhDirectoryName '/' M_.fname '_param_irf' int2str(ifil2) '.mat'],'stock'); save([MhDirectoryName '/' M_.fname '_param_irf' int2str(ifil2) '.mat'],'stock');
if RemoteFlag==1, if RemoteFlag==1
OutputFileName_param = [OutputFileName_param; {[MhDirectoryName filesep], [M_.fname '_param_irf' int2str(ifil2) '.mat']}]; OutputFileName_param = [OutputFileName_param; {[MhDirectoryName filesep], [M_.fname '_param_irf' int2str(ifil2) '.mat']}];
end end
ifil2 = ifil2 + 1; ifil2 = ifil2 + 1;

View File

@ -30,7 +30,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
% SPECIAL REQUIREMENTS. % SPECIAL REQUIREMENTS.
% None. % None.
% %
% Copyright (C) 2006-2016 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -49,7 +49,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
global options_ M_ global options_ M_
if nargin<4, if nargin<4
whoiam=0; whoiam=0;
end end
@ -85,8 +85,8 @@ end
DirectoryName = CheckPath('Output',M_.dname); DirectoryName = CheckPath('Output',M_.dname);
RemoteFlag = 0; RemoteFlag = 0;
if whoiam, if whoiam
if Parallel(ThisMatlab).Local==0, if Parallel(ThisMatlab).Local==0
RemoteFlag =1; RemoteFlag =1;
end end
prct0={0,whoiam,Parallel(ThisMatlab)}; prct0={0,whoiam,Parallel(ThisMatlab)};
@ -96,16 +96,16 @@ end
OutputFileName={}; OutputFileName={};
subplotnum = 0; subplotnum = 0;
for i=fpar:npar, for i=fpar:npar
figunumber = 0; figunumber = 0;
for j=1:nvar for j=1:nvar
if max(abs(MeanIRF(:,j,i))) >= options_.impulse_responses.plot_threshold if max(abs(MeanIRF(:,j,i))) >= options_.impulse_responses.plot_threshold
subplotnum = subplotnum+1; subplotnum = subplotnum+1;
if subplotnum == 1 && options_.relative_irf if subplotnum == 1 && options_.relative_irf
hh = dyn_figure(options_,'Name',['Relative response to orthogonalized shock to ' tit(i,:)]); hh = dyn_figure(options_.nodisplay,'Name',['Relative response to orthogonalized shock to ' tit(i,:)]);
elseif subplotnum == 1 && ~options_.relative_irf elseif subplotnum == 1 && ~options_.relative_irf
hh = dyn_figure(options_,'Name',['Orthogonalized shock to ' tit(i,:)]); hh = dyn_figure(options_.nodisplay,'Name',['Orthogonalized shock to ' tit(i,:)]);
end end
set(0,'CurrentFigure',hh) set(0,'CurrentFigure',hh)
@ -135,7 +135,7 @@ for i=fpar:npar,
plot(1:options_.irf,HPDIRFdsgevar(:,1,j,i),'--k','linewidth',1) plot(1:options_.irf,HPDIRFdsgevar(:,1,j,i),'--k','linewidth',1)
plot(1:options_.irf,HPDIRFdsgevar(:,2,j,i),'--k','linewidth',1) plot(1:options_.irf,HPDIRFdsgevar(:,2,j,i),'--k','linewidth',1)
end end
% plot([1 options_.irf],[0 0],'-r','linewidth',0.5); % plot([1 options_.irf],[0 0],'-r','linewidth',0.5);
box on box on
axis tight axis tight
xlim([1 options_.irf]); xlim([1 options_.irf]);
@ -152,17 +152,17 @@ for i=fpar:npar,
if subplotnum == MaxNumberOfPlotPerFigure || (j == nvar && subplotnum> 0) if subplotnum == MaxNumberOfPlotPerFigure || (j == nvar && subplotnum> 0)
figunumber = figunumber+1; figunumber = figunumber+1;
dyn_saveas(hh,[DirectoryName '/' M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber)],options_); dyn_saveas(hh,[DirectoryName '/' M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber)],options_.nodisplay,options_.graph_format);
if RemoteFlag==1, if RemoteFlag==1
OutputFileName = [OutputFileName; {[DirectoryName,filesep], [M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber) '.*']}]; OutputFileName = [OutputFileName; {[DirectoryName,filesep], [M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber) '.*']}];
end end
subplotnum = 0; subplotnum = 0;
end end
end% loop over selected endo_var end% loop over selected endo_var
if whoiam, if whoiam
fprintf('Done! \n'); fprintf('Done! \n');
waitbarString = [ 'Exog. shocks ' int2str(i) '/' int2str(npar) ' done.']; waitbarString = [ 'Exog. shocks ' int2str(i) '/' int2str(npar) ' done.'];
% fMessageStatus((i-fpar+1)/(npar-fpar+1),whoiam,waitbarString, waitbarTitle, Parallel(ThisMatlab)); % fMessageStatus((i-fpar+1)/(npar-fpar+1),whoiam,waitbarString, waitbarTitle, Parallel(ThisMatlab));
dyn_waitbar((i-fpar+1)/(npar-fpar+1),[],waitbarString); dyn_waitbar((i-fpar+1)/(npar-fpar+1),[],waitbarString);
end end
end% loop over exo_var end% loop over exo_var

View File

@ -25,7 +25,7 @@ function ReshapeMatFiles(type, type2)
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2003-2011 Dynare Team % Copyright (C) 2003-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -44,15 +44,15 @@ function ReshapeMatFiles(type, type2)
global M_ options_ global M_ options_
if nargin==1, if nargin==1
MhDirectoryName = [ CheckPath('metropolis',M_.dname) filesep ]; MhDirectoryName = [ CheckPath('metropolis',M_.dname) filesep ];
else else
if strcmpi(type2,'posterior') if strcmpi(type2,'posterior')
MhDirectoryName = [CheckPath('metropolis',M_.dname) filesep ]; MhDirectoryName = [CheckPath('metropolis',M_.dname) filesep ];
elseif strcmpi(type2,'gsa') elseif strcmpi(type2,'gsa')
if options_.opt_gsa.morris==1, if options_.opt_gsa.morris==1
MhDirectoryName = [CheckPath('gsa/screen',M_.dname) filesep ]; MhDirectoryName = [CheckPath('gsa/screen',M_.dname) filesep ];
elseif options_.opt_gsa.morris==2, elseif options_.opt_gsa.morris==2
MhDirectoryName = [CheckPath('gsa/identif',M_.dname) filesep ]; MhDirectoryName = [CheckPath('gsa/identif',M_.dname) filesep ];
elseif options_.opt_gsa.pprior elseif options_.opt_gsa.pprior
MhDirectoryName = [CheckPath(['gsa' filesep 'prior'],M_.dname) filesep ]; MhDirectoryName = [CheckPath(['gsa' filesep 'prior'],M_.dname) filesep ];

View File

@ -21,7 +21,8 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
% o SteadyState [double] Vector of doubles, steady state level for the endogenous variables. % o SteadyState [double] Vector of doubles, steady state level for the endogenous variables.
% o trend_coeff [double] Matrix of doubles, coefficients of the deterministic trend in the measurement equation % o trend_coeff [double] Matrix of doubles, coefficients of the deterministic trend in the measurement equation
% %
% Copyright (C) 2015-16 Dynare Team
% Copyright (C) 2015-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -40,4 +41,3 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
par_vector(parameterindices,:)=optpar; %reassemble parameter par_vector(parameterindices,:)=optpar; %reassemble parameter
[fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = feval(TargetFun,par_vector,varargin{:}); %call target function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = feval(TargetFun,par_vector,varargin{:}); %call target function

View File

@ -14,7 +14,7 @@ function [] = Tracing()
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright (C) 2010 Dynare Team % Copyright (C) 2010-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -19,7 +19,7 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
% Adapted from th_autocovariances.m. % Adapted from th_autocovariances.m.
% Copyright (C) 2006-2015 Dynare Team % Copyright (C) 2006-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -112,7 +112,7 @@ tneg = exp(-sqrt(-1)*freqs); %negative frequencies
if options_.one_sided_hp_filter if options_.one_sided_hp_filter
error('UnivariateSpectralDensity:: spectral density estimate not available with one-sided HP filter') error('UnivariateSpectralDensity:: spectral density estimate not available with one-sided HP filter')
elseif options_.hp_filter == 0 && ~options_.bandpass.indicator %do not filter elseif options_.hp_filter == 0 && ~options_.bandpass.indicator %do not filter
filter_gain=ones(ngrid,1); filter_gain=ones(ngrid,1);
elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.bandpass.indicator %filter with bandpass elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.bandpass.indicator %filter with bandpass
filter_gain = zeros(1,ngrid); filter_gain = zeros(1,ngrid);
lowest_periodicity=options_.bandpass.passband(2); lowest_periodicity=options_.bandpass.passband(2);
@ -134,7 +134,7 @@ for ig = 1:ngrid
g_omega = [aa*tneg(ig) bb]*f_omega*[aa'*tpos(ig); bb']; % selected variables g_omega = [aa*tneg(ig) bb]*f_omega*[aa'*tpos(ig); bb']; % selected variables
f_hp = filter_gain(ig)^2*g_omega; % spectral density of selected filtered series f_hp = filter_gain(ig)^2*g_omega; % spectral density of selected filtered series
mathp_col(ig,:) = (f_hp(:))'; % store as matrix row mathp_col(ig,:) = (f_hp(:))'; % store as matrix row
end; end
f = zeros(nvar,ngrid); f = zeros(nvar,ngrid);
for i=1:nvar for i=1:nvar
@ -159,12 +159,12 @@ if options_.nograph == 0
end end
for i= 1:nvar for i= 1:nvar
hh = dyn_figure(options_,'Name',['Spectral Density of ' deblank(M_.endo_names(ivar(i),:)) '.']); hh = dyn_figure(options_.nodisplay,'Name',['Spectral Density of ' deblank(M_.endo_names(ivar(i),:)) '.']);
plot(freqs,f(i,:),'-k','linewidth',2) plot(freqs,f(i,:),'-k','linewidth',2)
xlabel('0 \leq \omega \leq \pi') xlabel('0 \leq \omega \leq \pi')
ylabel('f(\omega)') ylabel('f(\omega)')
box on box on
axis tight axis tight
dyn_saveas(hh,[M_.fname ,filesep,'graphs', filesep, 'SpectralDensity_' deblank(M_.endo_names(ivar(i),:))],options_) dyn_saveas(hh,[M_.fname ,filesep,'graphs', filesep, 'SpectralDensity_' deblank(M_.endo_names(ivar(i),:))],options_.nodisplay,options_.graph_format)
end end
end end

View File

@ -0,0 +1,126 @@
function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions,opts_decomp)
%function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions)
% Saves the results from the shock_decomposition command to xls
%
% Inputs
% z [n_var*(nshock+2)*nperiods] shock decomposition array, see shock_decomposition.m for details
% shock_names [endo_nbr*string length] shock names from M_.exo_names
% endo_names [exo_nbr*string length] variable names from M_.endo_names
% i_var [n_var*1] vector indices of requested variables in M_.endo_names and z
% initial_date [dseries object] first period of decomposition to plot
% DynareModel [structure] Dynare model structure
% DynareOptions [structure] Dynare options structure
% Copyright (C) 2016-2017 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 <http://www.gnu.org/licenses/>.
SteadyState=[];
fig_mode='';
fig_mode1='';
fig_name='';
screen_shocks=0;
use_shock_groups = DynareOptions.plot_shock_decomp.use_shock_groups;
if use_shock_groups
shock_groups = DynareModel.shock_groups.(use_shock_groups);
shock_ind = fieldnames(shock_groups);
end
% number of components equals number of shocks + 1 (initial conditions)
comp_nbr = size(z,2)-1;
if nargin==8
if isfield(opts_decomp,'steady_state')
SteadyState = opts_decomp.steady_state;
end
if isfield(opts_decomp,'fig_mode') && ~isempty(opts_decomp.fig_mode)
fig_mode = opts_decomp.fig_mode;
fig_mode1 = ['_' fig_mode];
fig_mode = [fig_mode '_'];
end
if isfield(opts_decomp,'screen_shocks')
if use_shock_groups
screen_shocks=0;
elseif comp_nbr>18
screen_shocks = opts_decomp.screen_shocks;
end
end
if isfield(opts_decomp,'fig_name')
fig_name = opts_decomp.fig_name;
% fig_name = ['_' fig_name];
fig_name1 = [fig_name];
fig_name = [fig_name '_'];
end
if screen_shocks
fig_name1 = [fig_name1 '_screen'];
fig_name = [fig_name 'screen_'];
end
end
gend = size(z,3);
if isempty(initial_date)
x = 1:gend;
else
freq = initial_date.freq;
initial_period = initial_date.time(1) + (initial_date.time(2)-1)/freq;
x = initial_period:(1/freq):initial_period+(gend-1)/freq;
end
nvar = length(i_var);
labels = char(char(shock_names),'Initial values');
if ~(screen_shocks && comp_nbr>18)
screen_shocks=0;
end
comp_nbr0=comp_nbr;
%%plot decomposition
for j=1:nvar
d0={};
z1 = squeeze(z(i_var(j),:,:));
if screen_shocks
[junk, isort] = sort(mean(abs(z1(1:end-2,:)')), 'descend');
labels = char(char(shock_names(isort(1:16),:)),'Others', 'Initial values');
zres = sum(z1(isort(17:end),:),1);
z1 = [z1(isort(1:16),:); zres; z1(comp_nbr0:end,:)];
comp_nbr=18;
end
d0(1,:)=[{'Decomposition'} cellstr(labels(1:comp_nbr,:))' {'Smoot Var'}];
d0=[d0; num2cell([x' z1'])];
LastRow=size(d0,1);
if use_shock_groups
d0(LastRow+2,1)={'Legend.'};
d0(LastRow+2,2)={'Shocks include:'};
d0(LastRow+3:LastRow+3+comp_nbr-1,1)=cellstr(labels(1:comp_nbr,:));
for ic=1:comp_nbr
group_members = shock_groups.(shock_ind{ic}).shocks;
d0(LastRow+2+ic,2:1+length(group_members))=group_members;
end
end
warning off
if ~ismac
[STATUS,MESSAGE] = xlswrite([DynareModel.fname,'_shock_decomposition',fig_mode,fig_name1],d0,deblank(endo_names(i_var(j),:)));
else
[STATUS] = xlwrite([DynareModel.fname,'_shock_decomposition',fig_mode,fig_name1],d0,deblank(endo_names(i_var(j),:)));
end
warning on
clear d0
end

View File

@ -1,7 +1,24 @@
function title=add_filter_subtitle(title,options_) function title=add_filter_subtitle(title,options_)
% Copyright (C) 2015-2017 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 <http://www.gnu.org/licenses/>.
if ~options_.hp_filter && ~options_.one_sided_hp_filter && ~options_.bandpass.indicator %do not filter if ~options_.hp_filter && ~options_.one_sided_hp_filter && ~options_.bandpass.indicator %do not filter
%nothing to add here %nothing to add here
elseif ~options_.hp_filter && ~options_.one_sided_hp_filter && options_.bandpass.indicator elseif ~options_.hp_filter && ~options_.one_sided_hp_filter && options_.bandpass.indicator
title = [title ' (Bandpass filter, (' ... title = [title ' (Bandpass filter, (' ...
num2str(options_.bandpass.passband(1)),' ',num2str(options_.bandpass.passband(2)), '))']; num2str(options_.bandpass.passband(1)),' ',num2str(options_.bandpass.passband(2)), '))'];

View File

@ -1,6 +1,6 @@
function mexpath = add_path_to_mex_files(dynareroot, modifypath) function mexpath = add_path_to_mex_files(dynareroot, modifypath)
% Copyright (C) 2015-2016 Dynare Team % Copyright (C) 2015-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -22,7 +22,11 @@ if nargin<2
end end
if exist('OCTAVE_VERSION') if exist('OCTAVE_VERSION')
mexpath = {[dynareroot '../mex/octave/']}; if ispc() && strcmpi(computer(), 'i686-w64-mingw32')
mexpath = {[dynareroot '../mex/octave32/']};
else
mexpath = {[dynareroot '../mex/octave/']};
end
if modifypath if modifypath
addpath(mexpath{1}); addpath(mexpath{1});
end end
@ -48,7 +52,7 @@ else
end end
end end
else else
tmp = [dynareroot '../mex/matlab/win64-7.8-9.1/']; tmp = [dynareroot '../mex/matlab/win64-7.8-9.2/'];
if exist(tmp, 'dir') if exist(tmp, 'dir')
mexpath = tmp; mexpath = tmp;
if modifypath if modifypath

View File

@ -0,0 +1,333 @@
function [z, endo_names, endo_names_tex, steady_state, i_var, oo_] = annualized_shock_decomposition(oo_, M_, options_, i_var, t0, t1, realtime_, vintage_, steady_state, q2a, cumfix)
% function oo_ = annualized_shock_decomposition(oo_,t0,options_.nobs);
% Computes annualized shocks contribution to a simulated trajectory. The fields set are
% oo_.annualized_shock_decomposition, oo_.annualized_realtime_shock_decomposition,
% oo_.annualized_realtime_conditional_shock_decomposition and oo_.annualized_realtime_forecast_shock_decomposition.
% Subfields are arrays n_var by nshock+2 by nperiods. The
% first nshock columns store the respective shock contributions, column n+1
% stores the role of the initial conditions, while column n+2 stores the
% value of the smoothed variables. Both the variables and shocks are stored
% in the order of endo_names and M_.exo_names, respectively.
%
% INPUTS
% oo_: [structure] Storage of results
% M_: [structure] Storage of model
% opts: [structure] options for shock decomp
% i_var: [array] index of vars
% t0: [integer] first period
% t1: [integer] last period
% realtime_: [integer]
% vintage_: [integer]
% steady_state: [array] steady state value of quarterly (log-) level vars
% q2a: [structure] info on q2a
%
% OUTPUTS
% z: [matrix] shock decomp to plot
% endo_names: [char] updated var names
% endo_names_tex: [char] updated TeX var names
% steady_state: [array] updated stady state of vars
% i_var: [integer array] updated var indices to plot
% oo_: [structure] Storage of results
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
opts = options_.plot_shock_decomp;
nvar = length(i_var);
GYTREND0 = q2a.GYTREND0;
var_type = q2a.type;
islog = q2a.islog;
aux = q2a.aux;
aux0 = aux;
cumfix = q2a.cumfix;
% usual shock decomp
if isstruct(oo_)
% z = oo_.shock_decomposition;
myopts=options_;
myopts.plot_shock_decomp.type='qoq';
myopts.plot_shock_decomp.realtime=0;
[z, junk] = plot_shock_decomposition(M_,oo_,myopts,[]);
else
z = oo_;
end
z = z(i_var,:,:);
mytype=var_type;
if isfield(q2a,'name')
mytxt = q2a.name;
mytex = q2a.name;
if isfield(q2a,'tex_name')
mytex = q2a.tex_name;
end
if mytype==2
gtxt = ['PHI' mytxt]; % inflation rate
gtex = ['{\pi(' mytex ')}'];
elseif mytype
gtxt = ['G' mytxt]; % inflation rate
gtex = ['{g(' mytex ')}'];
end
if isfield(q2a,'gname')
gtxt = q2a.gname;
end
if isfield(q2a,'tex_gname')
gtex = q2a.tex_gname;
end
mytype=0;
end
if isstruct(aux)
if ischar(aux.y)
myopts=options_;
myopts.plot_shock_decomp.type='qoq';
myopts.plot_shock_decomp.realtime=0;
[y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,aux.y);
aux.y=y_aux;
aux.yss=steady_state_aux;
end
yaux=aux.y;
end
if mytype==2
gtxt = 'PHI'; % inflation rate
gtex = '\pi';
elseif mytype
gtxt = 'G'; % growth rate
gtex = 'g';
end
steady_state=steady_state(i_var);
% endo_names = M_.endo_names(i_var,:);
% endo_names_tex = M_.endo_names_tex(i_var,:);
nterms = size(z,2);
nfrcst = opts.forecast/4;
for j=1:nvar
if j>1
endo_names = char(endo_names,[deblank(M_.endo_names(i_var(j),:)) '_A']);
endo_names_tex = char(endo_names_tex,['{' deblank(M_.endo_names_tex(i_var(j),:)) '}^A']);
gendo_names = char(gendo_names,[gtxt endo_names(j,:)]);
gendo_names_tex = char(gendo_names_tex,[gtex '(' deblank(endo_names_tex(j,:)) ')']);
else
if nvar==1 && ~mytype
endo_names = mytxt;
endo_names_tex = mytex;
gendo_names = gtxt;
gendo_names_tex = gtex;
else
endo_names = [deblank(M_.endo_names(i_var(j),:)) '_A'];
endo_names_tex = ['{' deblank(M_.endo_names_tex(i_var(j),:)) '}^A'];
gendo_names = [gtxt endo_names(j,:)];
gendo_names_tex = [gtex '(' deblank(endo_names_tex(j,:)) ')'];
end
end
for k =1:nterms
if isstruct(aux)
aux.y = squeeze(yaux(j,k,min((t0-3):-4:1):end));
end
[za(j,k,:), steady_state_a(j,1), gza(j,k,:), steady_state_ga(j,1)] = ...
quarterly2annual(squeeze(z(j,k,min((t0-3):-4:1):end)),steady_state(j),GYTREND0,var_type,islog,aux);
end
ztmp=squeeze(za(j,:,:));
if cumfix==0
zscale = sum(ztmp(1:end-1,:))./ztmp(end,:);
ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]);
else
zres = ztmp(end,:)-sum(ztmp(1:end-1,:));
ztmp(end-1,:) = ztmp(end-1,:) + zres;
end
gztmp=squeeze(gza(j,:,:));
if cumfix==0
gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:);
gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]);
else
gres = gztmp(end,:) - sum(gztmp(1:end-1,:));
gztmp(end-1,:) = gztmp(end-1,:)+gres;
end
za(j,:,:) = ztmp;
gza(j,:,:) = gztmp;
end
if q2a.plot ==1
z=gza;
endo_names = gendo_names;
endo_names_tex = gendo_names_tex;
elseif q2a.plot == 2
z=za;
else
z=cat(1,za,gza);
endo_names = char(endo_names,gendo_names);
endo_names_tex = char(endo_names_tex,gendo_names_tex);
end
% if isstruct(oo_)
% oo_.annualized_shock_decomposition=z;
% end
% realtime
if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition')
init=1;
for i=t0:4:t1
yr=floor(i/4);
za=[];
gza=[];
myopts=options_;
myopts.plot_shock_decomp.type='qoq';
myopts.plot_shock_decomp.realtime=1;
myopts.plot_shock_decomp.vintage=i;
[z, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,[]);
z = z(i_var,:,:);
if isstruct(aux)
if ischar(aux0.y)
[y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,aux0.y);
aux.y=y_aux;
aux.yss=steady_state_aux;
end
yaux=aux.y;
end
nterms = size(z,2);
% z = oo_.realtime_shock_decomposition.(['time_' int2str(i)]);
% z = z(i_var,:,:);
for j=1:nvar
for k =nterms:-1:1
% if k<nterms
% ztmp = squeeze(sum(z(j,[1:k-1,k+1:end-1],t0-4:end)));
% else
ztmp = squeeze(z(j,k,min((t0-3):-4:1):end));
% end
if isstruct(aux)
aux.y = squeeze(yaux(j,k,min((t0-3):-4:1):end));
end
[za(j,k,:), steady_state_a(j,1), gza(j,k,:), steady_state_ga(j,1)] = ...
quarterly2annual(ztmp,steady_state(j),GYTREND0,var_type,islog,aux);
% if k<nterms
% za(j,k,:) = za(j,end,:) - za(j,k,:);
% gza(j,k,:) = gza(j,end,:) - gza(j,k,:);
% end
end
ztmp=squeeze(za(j,:,:));
if cumfix==0
zscale = sum(ztmp(1:end-1,:))./ztmp(end,:);
ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]);
else
zres = ztmp(end,:)-sum(ztmp(1:end-1,:));
ztmp(end-1,:) = ztmp(end-1,:) + zres;
end
gztmp=squeeze(gza(j,:,:));
if cumfix==0
gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:);
gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]);
else
gres = gztmp(end,:) - sum(gztmp(1:end-1,:));
gztmp(end-1,:) = gztmp(end-1,:)+gres;
end
za(j,:,:) = ztmp;
gza(j,:,:) = gztmp;
end
if q2a.plot ==1
z=gza;
elseif q2a.plot == 2
z=za;
else
z=cat(1,za,gza);
end
if init==1
oo_.annualized_realtime_shock_decomposition.pool = z;
else
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr) = z(:,:,end-nfrcst);
end
oo_.annualized_realtime_shock_decomposition.(['yr_' int2str(yr)]) = z;
if opts.forecast
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr)]) = z(:,:,end-nfrcst:end);
if init>nfrcst
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)]) = ...
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-nfrcst:end) - ...
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)]);
% fix others
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) = ...
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) + ...
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:);
% fix total
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:) = ...
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-nfrcst:end);
if i==t1
for my_forecast_=(nfrcst-1):-1:1
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)]) = ...
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-my_forecast_:yr) - ...
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,:,1:my_forecast_+1);
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end-1,:) = ...
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,1:my_forecast_+1);
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,:) = ...
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-my_forecast_:yr);
end
end
end
end
% ztmp=oo_.realtime_shock_decomposition.pool(:,:,21:29)-oo_.realtime_forecast_shock_decomposition.time_21;
init=init+1;
end
switch realtime_
case 0
z = oo_.annualized_shock_decomposition;
case 1 % realtime
if vintage_
z = oo_.annualized_realtime_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
else
z = oo_.annualized_realtime_shock_decomposition.pool;
end
case 2 % conditional
if vintage_
z = oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
else
error();
end
case 3 % forecast
if vintage_
z = oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
else
error()
end
end
end
if q2a.plot ==0
i_var=1:2*nvar;
steady_state = [steady_state_a;steady_state_ga];
else
i_var=1:nvar;
if q2a.plot ==1
steady_state = steady_state_ga;
else
steady_state = steady_state_a;
end
end

View File

@ -43,7 +43,7 @@ function [InnovationVariance,AutoregressiveParameters] = autoregressive_process_
% %
% \sigma^2 = \gamma(0)*(1-PHI'*v) % \sigma^2 = \gamma(0)*(1-PHI'*v)
% Copyright (C) 2009 Dynare Team % Copyright (C) 2009-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -0,0 +1,122 @@
function forecasts = backward_model_forecast(initialcondition, listofvariables, periods, withuncertainty)
% Returns unconditional forecasts.
%
% INPUTS
% - initialcondition [dseries] Initial conditions for the endogenous variables.
% - periods [integer] scalar, the number of (forecast) periods.
% - withuncertainty [logical] scalar, returns confidence bands if true.
%
% OUTPUTS
% - forecast [dseries]
% Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
global M_ options_ oo_
% Check that the model is actually backward
if M_.maximum_lead
error(['backward_model_irf:: The specified model is not backward looking!'])
end
% Initialize returned argument.
forecasts = struct();
% Set defaults.
if nargin<2
listofvariables = cellstr(M_.endo_names);
periods = 8;
withuncertainty = false;
end
if nargin<3
periods = 8;
withuncertainty = false;
end
if nargin<4
withuncertainty = false;
end
% Get full list of endogenous variables
endo_names = cellstr(M_.endo_names);
% Get vector of indices for the selected endogenous variables.
n = length(listofvariables);
idy = zeros(n,1);
for i=1:n
j = strmatch(listofvariables{i}, endo_names, 'exact');
if isempty(j)
error('backward_model_forecast:: Variable %s is unknown!', listofvariables{i})
else
idy(i) = j;
end
end
% Set the number of simulations (if required).
if withuncertainty
B = 1000;
end
% Get the covariance matrix of the shocks.
if withuncertainty
Sigma = M_.Sigma_e + 1e-14*eye(M_.exo_nbr);
sigma = transpose(chol(Sigma));
end
% Set initial condition.
if isdates(initialcondition)
if isempty(M_.endo_histval)
error('backward_model_irf: histval block for setting initial condition is missing!')
end
initialcondition = dseries(transpose(M_.endo_histval), initialcondition, endo_names, cellstr(M_.endo_names_tex));
end
% Put initial conditions in a vector of doubles
initialconditions = transpose(initialcondition{endo_names{:}}.data);
% Compute forecast without shock
innovations = zeros(periods+max(M_.maximum_exo_lag, 1), M_.exo_nbr);
if M_.maximum_exo_lag
if isempty(M_.exo_histval)
error('You need to set the past values for the exogenous variables!')
else
innovations(1:M_.maximum_exo_lag, :) = M_.exo_histval;
end
end
oo__0 = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
forecasts.pointforecast = dseries(transpose(oo__0.endo_simul(idy,:)), initialcondition.init, listofvariables);
if withuncertainty
% Preallocate an array gathering the simulations.
ArrayOfForectasts = zeros(n, periods+1, B);
for i=1:B
innovations(max(M_.maximum_exo_lag, 1)+1:end,:) = transpose(sigma*randn(M_.exo_nbr, periods));
oo__ = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
ArrayOfForecasts(:,:,i) = oo__.endo_simul(idy,:);
end
% Compute mean (over future uncertainty) forecast.
forecasts.meanforecast = dseries(transpose(mean(ArrayOfForecasts, 3)), initialcondition.init, listofvariables);
forecasts.medianforecast = dseries(transpose(median(ArrayOfForecasts, 3)), initialcondition.init, listofvariables);
forecasts.stdforecast = dseries(transpose(std(ArrayOfForecasts, 1,3)), initialcondition.init, listofvariables);
% Compute lower and upper 95% confidence bands
ArrayOfForecasts = sort(ArrayOfForecasts, 3);
forecasts.lb = dseries(transpose(ArrayOfForecasts(:,:,round(0.025*B))), initialcondition.init, listofvariables);
forecasts.ub = dseries(transpose(ArrayOfForecasts(:,:,round(0.975*B))), initialcondition.init, listofvariables);
end

View File

@ -0,0 +1,121 @@
function [endogenousvariables, exogenousvariables] = backward_model_inversion(constraints, exogenousvariables, initialconditions, endo_names, exo_names, freeinnovations, DynareModel, DynareOptions, DynareOutput)
% INPUTS
% - constraints [dseries] with N constrained endogenous variables from t1 to t2.
% - exogenousvariables [dseries] with Q exogenous variables.
% - initialconditions [dseries] with M endogenous variables starting before t1 (M initialcond must contain at least the state variables).
% - endo_names [cell] list of endogenous variable names.
% - exo_names [cell] list of exogenous variable names.
% - freeinstruments [cell] list of exogenous variable names used to control the constrained endogenous variables.
%
% OUTPUTS
% - endogenous [dseries]
% - exogenous [dseries]
%
% REMARKS
% Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
% Get indices for the calibrated and free innovations.
freeinnovations_id = zeros(length(freeinnovations), 1);
if length(freeinnovations)<DynareModel.exo_nbr
for i=1:length(freeinnovations)
freeinnovations_id(i) = strmatch(freeinnovations{i}, exo_names, 'exact');
end
calibratedinnovations_id = setdiff(transpose(1:length(exo_names)), freeinnovations_id);
else
freeinnovations_id = transpose(1:length(exo_names));
calibratedinnovations_id = [];
end
nxfree = length(freeinnovations_id);
nxcalb = length(calibratedinnovations_id);
% Get indices for the the controlled and free endogenous variables.
controlledendogenousvariables_id = zeros(length(freeinnovations), 1);
if length(freeinnovations)<DynareModel.endo_nbr
for i=1:length(freeinnovations)
controlledendogenousvariables_id(i) = strmatch(constraints.name{i}, endo_names, 'exact');
end
freeendogenousvariables_id = setdiff(transpose(1:length(endo_names)), controlledendogenousvariables_id);
else
controlledendogenousvariables_id = transpose(1:length(endo_names));
freeendogenousvariables_id = [];
end
nyfree = length(freeendogenousvariables_id);
nyctrl = length(controlledendogenousvariables_id);
% Get indices of variables appearing at time t-1.
iy1 = find(DynareModel.lead_lag_incidence(1,:)>0);
% Get indices of variables appearing at time t.
iy0 = find(DynareModel.lead_lag_incidence(2,:)>0);
% Set indices for trust_region algorithm.
idx = 1:DynareModel.endo_nbr;
jdx = 1:(nyfree+nxfree);
% Build structure to be passed to the objective function.
ModelInversion.nyfree = nyfree;
ModelInversion.nyctrl = nyctrl;
ModelInversion.nxfree = nxfree;
ModelInversion.nxcalb = nxcalb;
ModelInversion.y_constrained_id = vec(DynareModel.lead_lag_incidence(2,controlledendogenousvariables_id));
ModelInversion.y_free_id = vec(DynareModel.lead_lag_incidence(2,freeendogenousvariables_id));
ModelInversion.x_free_id = freeinnovations_id;
ModelInversion.J_id = [ModelInversion.y_free_id ; sum(DynareModel.lead_lag_incidence(:)>0)+ModelInversion.x_free_id];
% Get the name of the dynamic model routines.
model_dynamic = str2func([DynareModel.fname,'_dynamic']);
model_dtransf = str2func('dynamic_backward_model_for_inversion');
% Initialization of vector y (free endogenous variables and free innovations).
y = NaN(nyfree+nxfree);
% Initialization of the returned simulations (endogenous variables).
Y = NaN(DynareModel.endo_nbr, nobs(constraints)+1);
initialconditions
constraints.dates(1)
Y(:,1) = initialconditions(constraints.dates(1)-1).data(1:DynareModel.endo_nbr);
for i=1:nyctrl
Y(controlledendogenousvariables_id(i),2:end) = transpose(constraints.data(:,i));
end
% Initialization of the returned simulations (exogenous variables).
X = exogenousvariables{exo_names{:}}(constraints.dates(1)-max(1,DynareModel.maximum_exo_lag):constraints.dates(end)).data;
% Inversion of the model, solvers for the free endogenous and exogenous variables (call a Newton-like algorithm in each period).
for it = 2:nobs(constraints)+1
% Set the lagged values of the endogenous variables.
ylag = Y(iy1,it-1);
% Set the current values of the constrained endogenous variables.
ycur = Y(controlledendogenousvariables_id,it);
% Vector z gather the free endogenous variables (initialized with lagged
% values) and the free exogenous variables (initialized with 0).
z = [Y(freeendogenousvariables_id,it-1); zeros(nxfree, 1)];
% Solves for z.
z = dynare_solve(model_dtransf, z, DynareOptions, model_dynamic, ylag, ycur, X, DynareModel.params, DynareOutput.steady_state, it+DynareModel.maximum_exo_lag, ModelInversion);
% Update the matrix of exogenous variables.
X(it,freeinnovations_id) = z(nyfree+1:end);
% Update the matrix of endogenous variables.
Y(freeendogenousvariables_id,it) = z(1:nyfree);
end
endogenousvariables = dseries(Y', constraints.dates(1)-1, endo_names);
exogenousvariables = dseries(X(max(DynareModel.maximum_exo_lag,1)+1:end,:), constraints.dates(1), exo_names);

Some files were not shown because too many files have changed in this diff Show More