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

805
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)
=============================================
@ -988,7 +1785,7 @@ Here is a list of the main bugfixes since version 4.2.0:
* Option `conditional_variance_decomposition' of `stoch_simul' and
`estimation' has been fixed
* Automatic detrending now works in conjunction with the `EXPECTATION'
operator
@ -1029,7 +1826,7 @@ This release is compatible with MATLAB versions ranging from 6.5 (R13) to 7.11
Here is the list of major user-visible changes:
* New solution algorithms:
* New solution algorithms:
- Pruning for second order simulations has been added, as described in Kim,
Kim, Schaumburg and Sims (2008) [1,2]
@ -1066,7 +1863,7 @@ Here is the list of major user-visible changes:
- Syntax of deterministic shocks has changed: after the values keyword,
arbitrary expressions must be enclosed within parentheses (but numeric
constants are still accepted as is)
constants are still accepted as is)
* Various improvements:
@ -1095,7 +1892,7 @@ Here is the list of major user-visible changes:
from the console, it will replace graphical waitbars by text waitbars for
long computations
- Steady option "solve_algo=0" (uses fsolve()) now works under Octave
- Steady option "solve_algo=0" (uses fsolve()) now works under Octave
* For Emacs users:

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:
git clone --recursive http://github.com/DynareTeam/dynare.git
git clone --recursive https://github.com/DynareTeam/dynare.git
cd dynare
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**: 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**: 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
- 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```

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/>.
AC_PREREQ([2.62])
AC_INIT([dynare], [4.5-unstable])
AC_INIT([dynare], [4.6-unstable])
AC_CONFIG_SRCDIR([preprocessor/DynareMain.cc])
AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax])
@ -172,6 +172,7 @@ esac
AX_PTHREAD
AC_CONFIG_FILES([Makefile
VERSION
preprocessor/macro/Makefile
preprocessor/Makefile
doc/Makefile

View File

@ -12,7 +12,7 @@
\begin{document}
\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
this document under the terms of the GNU Free Documentation
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
CEPREMAP.} \and Johannes Pfeifer\thanks{University of Mannheim. E-mail: \href{mailto:pfeifer@uni-mannheim.de}{\texttt{pfeifer@uni-mannheim.de}}.}}
\date{First version: September 2007 \hspace{1cm} This version: October 2016}
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: May 2017}
\maketitle
@ -545,7 +545,7 @@ Most results are stored for future use:
The syntax for computing impulse response functions is:
\medskip
\texttt{bvar\_irf(}\textit{number\_of\_periods},\textit{identification\_scheme}\texttt{);}
\texttt{bvar\_irf(}\textit{number\_of\_lags},\textit{identification\_scheme}\texttt{);}
\medskip
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
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}

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;
#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);
#else
load_avg = -1.0;

View File

@ -12,114 +12,126 @@
#include <vector>
#include <map>
namespace ogp {
namespace ogp
{
class AtomAsgnEvaluator;
class AtomAsgnEvaluator;
/** This class represents atom assignments used in parameters
* settings and initval initialization. It maintains atoms of the
* all expressions on the right hand side, the parsed formulas of
* the right hand sides, and the information about the left hand
* sides. See documentation to the order member below. */
class AtomAssignings {
friend class AtomAsgnEvaluator;
protected:
typedef std::map<const char*, int, ltstr> Tvarintmap;
/** All atoms which should be sufficient for formulas at the
* right hand sides. The atoms should be filled with names
* (preregistered). This is a responsibility of the caller. */
StaticAtoms& atoms;
/** The formulas of right hand sides. */
FormulaParser expr;
/** Name storage of the names from left hand sides. */
NameStorage left_names;
/** Information on left hand sides. This maps a name to the
* index of its assigned expression in expr. More than one
* name may reference to the same expression. */
Tvarintmap lname2expr;
/** Information on left hand sides. If order[i] >= 0, then it
* says that i-th expression in expr is assigned to atom with
* order[i] tree index. */
std::vector<int> order;
public:
/** 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);
virtual ~AtomAssignings()
{}
/** Parse the assignments from the given string. */
void parse(int length, const char* stream);
/** Process a syntax error from bison. */
void error(const char* mes);
/** Add an assignment of the given name to the given
* double. Can be called by a user, anytime. */
void add_assignment_to_double(const char* name, double val);
/** Add an assignment. Called from assign.y. */
void add_assignment(int asgn_off, const char* str, int name_len,
int right_off, int right_len);
/** This applies old2new map (possibly from atom
* substitutions) to this object. It registers new variables
* in the atoms, and adds the expressions to expr, and left
* names to lname2expr. The information about dynamical part
* of substitutions is ignored, since we are now in the static
* world. */
void apply_subst(const AtomSubstitutions::Toldnamemap& mm);
/** Debug print. */
void print() const;
};
/** This class represents atom assignments used in parameters
* settings and initval initialization. It maintains atoms of the
* all expressions on the right hand side, the parsed formulas of
* the right hand sides, and the information about the left hand
* sides. See documentation to the order member below. */
class AtomAssignings
{
friend class AtomAsgnEvaluator;
protected:
typedef std::map<const char *, int, ltstr> Tvarintmap;
/** All atoms which should be sufficient for formulas at the
* right hand sides. The atoms should be filled with names
* (preregistered). This is a responsibility of the caller. */
StaticAtoms &atoms;
/** The formulas of right hand sides. */
FormulaParser expr;
/** Name storage of the names from left hand sides. */
NameStorage left_names;
/** Information on left hand sides. This maps a name to the
* index of its assigned expression in expr. More than one
* name may reference to the same expression. */
Tvarintmap lname2expr;
/** Information on left hand sides. If order[i] >= 0, then it
* says that i-th expression in expr is assigned to atom with
* order[i] tree index. */
std::vector<int> order;
public:
/** 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);
virtual ~AtomAssignings()
{
}
/** Parse the assignments from the given string. */
void parse(int length, const char *stream);
/** Process a syntax error from bison. */
void error(const char *mes);
/** Add an assignment of the given name to the given
* double. Can be called by a user, anytime. */
void add_assignment_to_double(const char *name, double val);
/** Add an assignment. Called from assign.y. */
void add_assignment(int asgn_off, const char *str, int name_len,
int right_off, int right_len);
/** This applies old2new map (possibly from atom
* substitutions) to this object. It registers new variables
* in the atoms, and adds the expressions to expr, and left
* names to lname2expr. The information about dynamical part
* of substitutions is ignored, since we are now in the static
* world. */
void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
/** Debug print. */
void print() const;
};
/** This class basically evaluates the atom assignments
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
* is also a storage for the results of the evaluation stored as a
* vector, so the class inherits from std::vector<double> and
* ogp::FormulaEvalLoader. As the expressions for atoms are
* evaluated, the results are values for atoms which will be
* used in subsequent evaluations. For this reason, the class
* inherits also from AtomValues. */
class AtomAsgnEvaluator : public FormulaEvalLoader,
public AtomValues,
protected FormulaEvaluator,
public std::vector<double> {
protected:
typedef std::map<int, double> Tusrvalmap;
Tusrvalmap user_values;
const AtomAssignings& aa;
public:
AtomAsgnEvaluator(const AtomAssignings& a)
: FormulaEvaluator(a.expr),
std::vector<double>(a.expr.nformulas()), aa(a) {}
virtual ~AtomAsgnEvaluator() {}
/** 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()
* method passing this argument as AtomValues. So the
* ogp::EvalTree will be always this->etree. */
void setValues(EvalTree& et) const;
/** User setting of the values. For example in initval,
* parameters are known and should be set to their values. In
* constrast endogenous variables are set initially to NaNs by
* AtomValues::setValues. */
void set_user_value(const char* name, double val);
/** This sets the result of i-th expression in aa to res, and
* also checks whether the i-th expression is an atom. If so,
* it sets the value of the atom in ogp::EvalTree
* this->etree. */
void load(int i, double res);
/** After the user values have been set, the assignments can
* be evaluated. For this purpose we have eval() method. The
* result is that this object as std::vector<double> will
* contain the values. It is ordered given by formulas in
* expr. */
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;
};
/** This class basically evaluates the atom assignments
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
* is also a storage for the results of the evaluation stored as a
* vector, so the class inherits from std::vector<double> and
* ogp::FormulaEvalLoader. As the expressions for atoms are
* evaluated, the results are values for atoms which will be
* used in subsequent evaluations. For this reason, the class
* inherits also from AtomValues. */
class AtomAsgnEvaluator : public FormulaEvalLoader,
public AtomValues,
protected FormulaEvaluator,
public std::vector<double>
{
protected:
typedef std::map<int, double> Tusrvalmap;
Tusrvalmap user_values;
const AtomAssignings &aa;
public:
AtomAsgnEvaluator(const AtomAssignings &a)
: FormulaEvaluator(a.expr),
std::vector<double>(a.expr.nformulas()), aa(a)
{
}
virtual ~AtomAsgnEvaluator()
{
}
/** 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()
* method passing this argument as AtomValues. So the
* ogp::EvalTree will be always this->etree. */
void setValues(EvalTree &et) const;
/** User setting of the values. For example in initval,
* parameters are known and should be set to their values. In
* constrast endogenous variables are set initially to NaNs by
* AtomValues::setValues. */
void set_user_value(const char *name, double val);
/** This sets the result of i-th expression in aa to res, and
* also checks whether the i-th expression is an atom. If so,
* it sets the value of the atom in ogp::EvalTree
* this->etree. */
void load(int i, double res);
/** After the user values have been set, the assignments can
* be evaluated. For this purpose we have eval() method. The
* result is that this object as std::vector<double> will
* contain the values. It is ordered given by formulas in
* expr. */
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>
namespace ogp {
namespace ogp
{
using std::string;
using std::map;
using std::pair;
using std::string;
using std::map;
using std::pair;
/** This class tracts an information about the performed
* substitutions. In fact, there is only one number to keep track
* about, this is a number of substitutions. */
struct SubstInfo {
int num_substs;
SubstInfo() : num_substs(0) {}
};
/** This class tracts an information about the performed
* substitutions. In fact, there is only one number to keep track
* about, this is a number of substitutions. */
struct SubstInfo
{
int num_substs;
SubstInfo() : num_substs(0)
{
}
};
/** This class tracks all atom substitutions during the job and
* then builds structures when all substitutions are finished. */
class AtomSubstitutions {
public:
typedef pair<const char*, int> Tshiftname;
typedef map<const char*, Tshiftname, ltstr> Tshiftmap;
typedef set<Tshiftname> Tshiftnameset;
typedef map<const char*, Tshiftnameset, ltstr> Toldnamemap;
protected:
/** This maps a new name to a shifted old name. This is, one
* entry looks as "a_m3 ==> a(-3)", saying that a variable
* "a_m3" corresponds to a variable "a" lagged by 3. */
Tshiftmap new2old;
/** This is inverse to new2old, which is not unique. For old
* name, say "a", it says what new names are derived with what
* shifts from the "a". For example, it can map "a" to a two
* element set {["a_m3", +3], ["a_p2", -2]}. This says that
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
* 2 one gets also old "a". */
Toldnamemap old2new;
/** This is a reference to old atoms with multiple leads and
* lags. They are supposed to be used with parsing finished
* being had called, so that the external ordering is
* available. */
const FineAtoms& old_atoms;
/** This is a reference to new atoms. All name pointers point
* to storage of these atoms. */
FineAtoms& new_atoms;
/** Substitutions information. */
SubstInfo info;
public:
/** Create the object with reference to the old and new
* atoms. In the beginning, old atoms are supposed to be with
* parsing_finished() called, and new atoms a simple copy of
* old atoms. The new atoms will be an instance of SAtoms. All
* substitution job is done by a substitution method of the
* new atoms. */
AtomSubstitutions(const FineAtoms& oa, FineAtoms& na)
: old_atoms(oa), new_atoms(na) {}
/** Construct a copy of the object using a different instances
* 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);
virtual ~AtomSubstitutions() {}
/** This is called during the substitution job from the
* substitution method of the new atoms. This says that the
* new name, say "a_m3" is a substitution of old name "a"
* shifted by -3. */
void add_substitution(const char* newname, const char* oldname, int tshift);
/** This is called when all substitutions are finished. This
* forms the new external ordering of the new atoms and calls
* parsing_finished() for the new atoms with the given ordering type. */
void substitutions_finished(VarOrdering::ord_type ot);
/** Returns a new name for old name and given tshift. For "a"
* and tshift=-3, it returns "a_m3". If there is no such
* substitution, it returns NULL. */
const char* get_new4old(const char* oldname, int tshift) const;
/** Return new2old. */
const Tshiftmap& get_new2old() const
{return new2old;}
/** Return old2new. */
const Toldnamemap& get_old2new() const
{return old2new;}
/** 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;
};
/** This class tracks all atom substitutions during the job and
* then builds structures when all substitutions are finished. */
class AtomSubstitutions
{
public:
typedef pair<const char *, int> Tshiftname;
typedef map<const char *, Tshiftname, ltstr> Tshiftmap;
typedef set<Tshiftname> Tshiftnameset;
typedef map<const char *, Tshiftnameset, ltstr> Toldnamemap;
protected:
/** This maps a new name to a shifted old name. This is, one
* entry looks as "a_m3 ==> a(-3)", saying that a variable
* "a_m3" corresponds to a variable "a" lagged by 3. */
Tshiftmap new2old;
/** This is inverse to new2old, which is not unique. For old
* name, say "a", it says what new names are derived with what
* shifts from the "a". For example, it can map "a" to a two
* element set {["a_m3", +3], ["a_p2", -2]}. This says that
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
* 2 one gets also old "a". */
Toldnamemap old2new;
/** This is a reference to old atoms with multiple leads and
* lags. They are supposed to be used with parsing finished
* being had called, so that the external ordering is
* available. */
const FineAtoms &old_atoms;
/** This is a reference to new atoms. All name pointers point
* to storage of these atoms. */
FineAtoms &new_atoms;
/** Substitutions information. */
SubstInfo info;
public:
/** Create the object with reference to the old and new
* atoms. In the beginning, old atoms are supposed to be with
* parsing_finished() called, and new atoms a simple copy of
* old atoms. The new atoms will be an instance of SAtoms. All
* substitution job is done by a substitution method of the
* new atoms. */
AtomSubstitutions(const FineAtoms &oa, FineAtoms &na)
: old_atoms(oa), new_atoms(na)
{
}
/** Construct a copy of the object using a different instances
* 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);
virtual ~AtomSubstitutions()
{
}
/** This is called during the substitution job from the
* substitution method of the new atoms. This says that the
* new name, say "a_m3" is a substitution of old name "a"
* shifted by -3. */
void add_substitution(const char *newname, const char *oldname, int tshift);
/** This is called when all substitutions are finished. This
* forms the new external ordering of the new atoms and calls
* parsing_finished() for the new atoms with the given ordering type. */
void substitutions_finished(VarOrdering::ord_type ot);
/** Returns a new name for old name and given tshift. For "a"
* and tshift=-3, it returns "a_m3". If there is no such
* substitution, it returns NULL. */
const char *get_new4old(const char *oldname, int tshift) const;
/** Return new2old. */
const Tshiftmap &
get_new2old() const
{
return new2old;
}
/** Return old2new. */
const Toldnamemap &
get_old2new() const
{
return old2new;
}
/** 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 {
public:
SAtoms()
: FineAtoms() {}
SAtoms(const SAtoms& sa)
: FineAtoms(sa) {}
virtual ~SAtoms() {}
/** This substitutes all lags and leads for all exogenous and
* all lags and leads greater than 1 for all endogenous
* variables. This is useful for perfect foresight problems
* where we can do that. */
void substituteAllLagsAndLeads(FormulaParser& fp, AtomSubstitutions& as);
/** 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. */
void substituteAllLagsAndExo1Leads(FormulaParser& fp, AtomSubstitutions& as);
protected:
/** 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);}
class SAtoms : public FineAtoms
{
public:
SAtoms()
: FineAtoms()
{
}
SAtoms(const SAtoms &sa)
: FineAtoms(sa)
{
}
virtual ~SAtoms()
{
}
/** This substitutes all lags and leads for all exogenous and
* all lags and leads greater than 1 for all endogenous
* variables. This is useful for perfect foresight problems
* where we can do that. */
void substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as);
/** 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. */
void substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as);
protected:
/** 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
* <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
* such form is already registered, one more character (either
* 'p' or 'm') is added and the test is performed again. The
* resulting name is returned in a string out. */
void attemptAuxName(const char* str, int ll, string& out) const;
/** This attempts to find a non registered name of the form
* <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
* such form is already registered, one more character (either
* 'p' or 'm') is added and the test is performed again. The
* resulting name is returned in a string out. */
void attemptAuxName(const char *str, int ll, string &out) const;
/** This makes auxiliary variables to eliminate all leads/lags
* greater/less than or equal to start up to the limit_lead
* for a variable with the given name. If the limit_lead is
* greater/less than the maxlead/minlag of the variable, than
* maxlead/minlag is used. This process is recorded in
* AtomSubstitutions. The new auxiliary variables and their
* atoms are created in this object. The auxiliary equations
* are created in the given FormulaParser. The value of step
* is allowed to be either -1 (lags) or +1 (leads). */
void makeAuxVariables(const char* name, int step, int start, int limit_lead,
FormulaParser& fp, AtomSubstitutions& as);
private:
/** This is a worker routine for findEndoWithLeadInInterval
* and findExoWithLeadInInterval. */
const char* findNameWithLeadInInterval(const vector<const char*>& names,
int ll1, int ll2) const;
/** This makes auxiliary variables to eliminate all leads/lags
* greater/less than or equal to start up to the limit_lead
* for a variable with the given name. If the limit_lead is
* greater/less than the maxlead/minlag of the variable, than
* maxlead/minlag is used. This process is recorded in
* AtomSubstitutions. The new auxiliary variables and their
* atoms are created in this object. The auxiliary equations
* are created in the given FormulaParser. The value of step
* is allowed to be either -1 (lags) or +1 (leads). */
void makeAuxVariables(const char *name, int step, int start, int limit_lead,
FormulaParser &fp, AtomSubstitutions &as);
private:
/** This is a worker routine for findEndoWithLeadInInterval
* and findExoWithLeadInInterval. */
const char *findNameWithLeadInInterval(const vector<const char *> &names,
int ll1, int ll2) const;
};
};
};

View File

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

View File

@ -13,389 +13,462 @@
#include <string>
#include <cstring>
namespace ogp {
using std::vector;
using std::map;
using std::set;
using std::string;
namespace ogp
{
using std::vector;
using std::map;
using std::set;
using std::string;
struct ltstr {
bool operator()(const char* a1, const char* a2) const
{ return strcmp(a1, a2) < 0; }
};
struct ltstr
{
bool
operator()(const char *a1, const char *a2) const
{
return strcmp(a1, a2) < 0;
}
};
/** Class storing names. We will keep names of variables in
* various places, and all these pointers will point to one
* storage, which will be responsible for allocation and
* deallocation. The main function of the class is to allocate
* space for names, and return a pointer of the stored name if
* required. */
class NameStorage {
protected:
/** Vector of names allocated, this is the storage. */
vector<char*> name_store;
/** Map useful to quickly decide if the name is already
* allocated or not. */
set<const char*, ltstr> name_set;
public:
NameStorage() {}
NameStorage(const NameStorage& stor);
virtual ~NameStorage();
/** Query for the name. If the name has been stored, it
* returns its address, otherwise 0. */
const char* query(const char* name) const;
/** Insert the name if it has not been inserted yet, and
* return its new or old allocation. */
const char* insert(const char* name);
int num() const
{return (int)name_store.size();}
const char* get_name(int i) const
{return name_store[i];}
/** Debug print. */
void print() const;
};
/** Class storing names. We will keep names of variables in
* various places, and all these pointers will point to one
* storage, which will be responsible for allocation and
* deallocation. The main function of the class is to allocate
* space for names, and return a pointer of the stored name if
* required. */
class NameStorage
{
protected:
/** Vector of names allocated, this is the storage. */
vector<char *> name_store;
/** Map useful to quickly decide if the name is already
* allocated or not. */
set<const char *, ltstr> name_set;
public:
NameStorage()
{
}
NameStorage(const NameStorage &stor);
virtual
~NameStorage();
/** Query for the name. If the name has been stored, it
* returns its address, otherwise 0. */
const char *query(const char *name) const;
/** Insert the name if it has not been inserted yet, and
* return its new or old allocation. */
const char *insert(const char *name);
int
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 {
public:
/** Type for a map mapping tree indices to double values. */
typedef map<int,double> Tconstantmap;
typedef map<int,int> Tintintmap;
protected:
/** Map mapping a tree index of a constant to its double value. */
Tconstantmap cmap;
public:
Constants() {}
/** Copy constructor. */
Constants(const Constants& c)
: cmap(c.cmap), cinvmap(c.cinvmap) {}
/** Copy constructor registering the constants in the given
* tree. The mapping from old tree indices to new ones is
* traced in tmap. */
Constants(const Constants& c, OperationTree& otree, Tintintmap& tmap)
{import_constants(c, otree, tmap);}
/** Import constants registering their tree indices in the
* given tree. The mapping form old tree indices to new ones
* is traced in tmap. */
void import_constants(const Constants& c, OperationTree& otree, Tintintmap& tmap);
/** Implements AtomValues interface. This sets the values to
* the evaluation tree EvalTree. */
void setValues(EvalTree& et) const;
/** This adds a constant with the given tree index. The
* constant must be checked previously and asserted that it
* does not exist. */
void add_constant(int t, double val);
/** Returns true if the tree index is either an hardwired
* constant (initial number OperationTree:num_constants in
* OperationTree) or the tree index is a registered constant
* by add_constant method. */
bool is_constant(int t) const;
double get_constant_value(int t) const;
/** Return -1 if the given string representation of a constant
* is not among the constants (double represenations). If it
* is, its tree index is returned. */
int check(const char* str) const;
/** Debug print. */
void print() const;
const Tconstantmap& 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;
};
class Constants : public AtomValues
{
public:
/** Type for a map mapping tree indices to double values. */
typedef map<int, double> Tconstantmap;
typedef map<int, int> Tintintmap;
protected:
/** Map mapping a tree index of a constant to its double value. */
Tconstantmap cmap;
public:
Constants()
{
}
/** Copy constructor. */
Constants(const Constants &c)
: cmap(c.cmap), cinvmap(c.cinvmap)
{
}
/** Copy constructor registering the constants in the given
* tree. The mapping from old tree indices to new ones is
* traced in tmap. */
Constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
{
import_constants(c, otree, tmap);
}
/** Import constants registering their tree indices in the
* given tree. The mapping form old tree indices to new ones
* is traced in tmap. */
void import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap);
/** Implements AtomValues interface. This sets the values to
* the evaluation tree EvalTree. */
void setValues(EvalTree &et) const;
/** This adds a constant with the given tree index. The
* constant must be checked previously and asserted that it
* does not exist. */
void add_constant(int t, double val);
/** Returns true if the tree index is either an hardwired
* constant (initial number OperationTree:num_constants in
* OperationTree) or the tree index is a registered constant
* by add_constant method. */
bool is_constant(int t) const;
double get_constant_value(int t) const;
/** Return -1 if the given string representation of a constant
* is not among the constants (double represenations). If it
* is, its tree index is returned. */
int check(const char *str) const;
/** Debug print. */
void print() const;
const Tconstantmap &
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
* constants (numerical literals), and variables with lags and
* leads. This abstraction does not distinguish between a parameter
* and a variable without lag or lead. In this sense, everything is a
* variable.*/
class DynamicAtoms : public Atoms, public Constants {
public:
/** Definition of a type mapping lags to the indices of the variables. */
typedef map<int,int> Tlagmap;
protected:
/** Definition of a type mapping names of the atoms to Tlagmap. */
typedef map<const char*, Tlagmap, ltstr> Tvarmap;
/** Definition of a type mapping indices of variables to the variable names. */
typedef map<int, const char*> Tindexmap;
/** This is just a storage for variable names, since all other
* instances of a variable name just point to the memory
* allocated by this object. */
NameStorage varnames;
/** This is the map for variables. Each variable name is
* mapped to the Tlagmap, which maps lags/leads to the nulary
* term indices in the tree. */
Tvarmap vars;
/** This is almost inverse map to the vars. It maps variable
* indices to the names. A returned name can be in turn used
* as a key in vars. */
Tindexmap indices;
/** This class is a parent to Atoms classes which distinguish between
* constants (numerical literals), and variables with lags and
* leads. This abstraction does not distinguish between a parameter
* and a variable without lag or lead. In this sense, everything is a
* variable.*/
class DynamicAtoms : public Atoms, public Constants
{
public:
/** Definition of a type mapping lags to the indices of the variables. */
typedef map<int, int> Tlagmap;
protected:
/** Definition of a type mapping names of the atoms to Tlagmap. */
typedef map<const char *, Tlagmap, ltstr> Tvarmap;
/** Definition of a type mapping indices of variables to the variable names. */
typedef map<int, const char *> Tindexmap;
/** This is just a storage for variable names, since all other
* instances of a variable name just point to the memory
* allocated by this object. */
NameStorage varnames;
/** This is the map for variables. Each variable name is
* mapped to the Tlagmap, which maps lags/leads to the nulary
* term indices in the tree. */
Tvarmap vars;
/** This is almost inverse map to the vars. It maps variable
* indices to the names. A returned name can be in turn used
* as a key in vars. */
Tindexmap indices;
/** Number of variables. */
int nv;
/** Minimum lag, if there is at least one lag, than this is a negative number. */
int minlag;
/** Maximum lead, if there is at least one lead, than this is a positive number. */
int maxlead;
public:
/** Construct empty DynamicAtoms. */
DynamicAtoms();
DynamicAtoms(const DynamicAtoms& da);
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
* assigned regardless if the same constant has already
* appeared or not. If variable, then -1 is returned only if
* the variable has not been assigned an index, otherwise the
* assigned index is returned. */
int check(const char* name) const;
/** Assign the nulary term identified by its string
* representation. This method should be called when check()
* returns -1. */
void assign(const char* name, int t);
/** Return a number of all variables. */
int nvar() const
{ return nv; }
/** Return the vector of variable indices. */
vector<int> variables() const;
/** Return max lead and min lag for a variable given by the
* index. If a variable cannot be found, the method retursn
* the smallest integer as maxlead and the largest integer as
* minlag. */
void varspan(int t, int& mlead, int& mlag) const;
/** Return max lead and min lag for a variable given by the
* name (without lead, lag). The same is valid if the variable
* name cannot be found. */
void varspan(const char* name, int& mlead, int& mlag) const;
/** Return max lead and min lag for a vector of variables given by the names. */
void varspan(const vector<const char*>& names, int& mlead, int& mlag) const;
/** Return true for all tree indices corresponding to a
* variable in the sense of this class. (This is parameters,
* exo and endo). Since the semantics of 'variable' will be
* changed in subclasses, we use name 'named atom'. These are
* all atoms but constants. */
bool is_named_atom(int t) const;
/** Return index of the variable described by the variable
* name and lag/lead. If it doesn't exist, return -1. */
int index(const char* name, int ll) const;
/** Return true if a variable is referenced, i.e. it has lag
* map. */
bool is_referenced(const char* name) const;
/** Return the lag map for the variable name. */
const Tlagmap& lagmap(const char* name) const;
/** Return the variable name for the tree index. It throws an
* exception if the tree index t is not a named atom. */
const char* name(int t) const;
/** Return the lead/lag for the tree index. It throws an
* exception if the tree index t is not a named atom. */
int lead(int t) const;
/** Return maximum lead. */
int get_maxlead() const
{return maxlead;}
/** Return minimum lag. */
int get_minlag() const
{return minlag;}
/** Return the name storage to allow querying to other
* classes. */
const NameStorage& get_name_storage() const
{return varnames;}
/** Assign the variable with a given lead. The varname must be
* from the varnames storage. The method checks if the
* variable iwht the given lead/lag is not assigned. If so, an
* exception is thrown. */
void assign_variable(const char* varname, int ll, int t);
/** Unassign the variable with a given lead and given tree
* index. The tree index is only provided as a check. An
* exception is thrown if the name, ll, and the tree index t
* are not consistent. The method also updates nv, indices,
* maxlead and minlag. The varname must be from the varnames
* storage. */
void unassign_variable(const char* varname, int ll, int t);
/** Debug print. */
void print() const;
protected:
/** Do the check for the variable. A subclass may need to
* reimplement this so that it could raise an error if the
* variable is not among a given list. */
virtual int check_variable(const char* name) const;
/** 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);
};
/** Number of variables. */
int nv;
/** Minimum lag, if there is at least one lag, than this is a negative number. */
int minlag;
/** Maximum lead, if there is at least one lead, than this is a positive number. */
int maxlead;
public:
/** Construct empty DynamicAtoms. */
DynamicAtoms();
DynamicAtoms(const DynamicAtoms &da);
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
* assigned regardless if the same constant has already
* appeared or not. If variable, then -1 is returned only if
* the variable has not been assigned an index, otherwise the
* assigned index is returned. */
int check(const char *name) const;
/** Assign the nulary term identified by its string
* representation. This method should be called when check()
* returns -1. */
void assign(const char *name, int t);
/** Return a number of all variables. */
int
nvar() const
{
return nv;
}
/** Return the vector of variable indices. */
vector<int> variables() const;
/** Return max lead and min lag for a variable given by the
* index. If a variable cannot be found, the method retursn
* the smallest integer as maxlead and the largest integer as
* minlag. */
void varspan(int t, int &mlead, int &mlag) const;
/** Return max lead and min lag for a variable given by the
* name (without lead, lag). The same is valid if the variable
* name cannot be found. */
void varspan(const char *name, int &mlead, int &mlag) const;
/** Return max lead and min lag for a vector of variables given by the names. */
void varspan(const vector<const char *> &names, int &mlead, int &mlag) const;
/** Return true for all tree indices corresponding to a
* variable in the sense of this class. (This is parameters,
* exo and endo). Since the semantics of 'variable' will be
* changed in subclasses, we use name 'named atom'. These are
* all atoms but constants. */
bool is_named_atom(int t) const;
/** Return index of the variable described by the variable
* name and lag/lead. If it doesn't exist, return -1. */
int index(const char *name, int ll) const;
/** Return true if a variable is referenced, i.e. it has lag
* map. */
bool is_referenced(const char *name) const;
/** Return the lag map for the variable name. */
const Tlagmap&lagmap(const char *name) const;
/** Return the variable name for the tree index. It throws an
* exception if the tree index t is not a named atom. */
const char *name(int t) const;
/** Return the lead/lag for the tree index. It throws an
* exception if the tree index t is not a named atom. */
int lead(int t) const;
/** Return maximum lead. */
int
get_maxlead() const
{
return maxlead;
}
/** Return minimum lag. */
int
get_minlag() const
{
return minlag;
}
/** Return the name storage to allow querying to other
* classes. */
const NameStorage &
get_name_storage() const
{
return varnames;
}
/** Assign the variable with a given lead. The varname must be
* from the varnames storage. The method checks if the
* variable iwht the given lead/lag is not assigned. If so, an
* exception is thrown. */
void assign_variable(const char *varname, int ll, int t);
/** Unassign the variable with a given lead and given tree
* index. The tree index is only provided as a check. An
* exception is thrown if the name, ll, and the tree index t
* are not consistent. The method also updates nv, indices,
* maxlead and minlag. The varname must be from the varnames
* storage. */
void unassign_variable(const char *varname, int ll, int t);
/** Debug print. */
void print() const;
protected:
/** Do the check for the variable. A subclass may need to
* reimplement this so that it could raise an error if the
* variable is not among a given list. */
virtual int check_variable(const char *name) const;
/** 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
* of variables which can appear before t, at t, or after t. It
* encapsulates the ordering, and the information about the number
* of static (appearing only at time t) predetermined (appearing
* before t and possibly at t), both (appearing before t and after
* t and possibly at t) and forward looking (appearing after t and
* possibly at t).
*
* The constructor takes a list of variable names. The class also
* provides mapping from the ordering of the variables in the list
* (outer) to the new ordering (at time t) and back.
*
* The user of the subclass must call do_ordering() after
* initialization.
*
* The class contains a few preimplemented methods for
* ordering. The class is used in this way: Make a subclass, and
* implement pure virtual do_ordering() by just plugging a
* preimplemented method, or plugging your own implementation. The
* method do_ordering() is called by the user after the constructor.
*/
class VarOrdering {
protected:
/** Number of static variables. */
int n_stat;
/** Number of predetermined variables. */
int n_pred;
/** Number of both variables. */
int n_both;
/** Number of forward looking variables. */
int n_forw;
/** This is a set of tree indices corresponding to the
* variables at all times as they occur in the formulas. In
* fact, since this is used only for derivatives, the ordering
* of this vector is only important for ordering of the
* derivatives, in other contexts the ordering is not
* important, so it is rather a set of indices.*/
vector<int> der_atoms;
/** This maps tree index of the variable to the position in
* the row of the ordering. One should be careful with making
* space in the positions for variables not appearing at time
* 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,
* 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
* 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
* 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
* to positions 3 and 4. */
map<int,int> positions;
/** This maps an ordering of the list of variables in
* constructor to the new ordering (at time t). The length is
* the number of variables. */
vector<int> outer2y;
/** This maps a new ordering to the ordering of the list of
* variables in constructor (at time t). The length is the
* number of variables. */
vector<int> y2outer;
/** This is just a reference for variable names to keep it
* from constructor to do_ordering() implementations. */
const vector<const char*>& varnames;
/** This is just a reference to atoms to keep it from
* constructor to do_ordering() implementations. */
const DynamicAtoms& atoms;
public:
/** This is an enum type for an ordering type implemented by
* do_general. */
enum ord_type {pbspbfbf, bfspbfpb};
/** Construct the ordering of the variables given by the names
* with their dynamic occurrences defined by the atoms. It
* calls the virtual method do_ordering which can be
* reimplemented. */
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)
{}
VarOrdering(const VarOrdering& vo, const vector<const char*>& vnames,
const DynamicAtoms& a);
virtual VarOrdering* clone(const vector<const char*>& vnames,
const DynamicAtoms& a) const = 0;
/** Destructor does nothing here. */
virtual ~VarOrdering() {}
/** This is the method setting the ordering and the map. A
* subclass must reimplement it, possibly using a
* preimplemented ordering. This method must be called by the
* user after the class has been created. */
virtual void do_ordering() = 0;
/** Return number of static. */
int nstat() const
{return n_stat;}
/** Return number of predetermined. */
int npred() const
{return n_pred;}
/** Return number of both. */
int nboth() const
{return n_both;}
/** Return number of forward looking. */
int nforw() const
{return n_forw;}
/** Return the set of tree indices for derivatives. */
const vector<int>& get_der_atoms() const
{return der_atoms;}
/** Return the y2outer. */
const vector<int>& get_y2outer() const
{return y2outer;}
/** Return the outer2y. */
const vector<int>& get_outer2y() const
{return outer2y;}
/** Query the atom given by the tree index. True is returned
* if the atom is one of the variables in the object. */
bool check(int t) 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
* be found, the exception is raised. */
int get_pos_of(int t) const;
/** This returns a length of ordered row of atoms. In all
* cases so far, it does not depend on the ordering and it is
* as follows. */
int length() const
{return n_stat+2*n_pred+3*n_both+2*n_forw;}
/** Debug print. */
void print() const;
protected:
/** This is a general ordering method which orders the
* variables by the given ordering ord_type. See documentation
* for respective do_ methods. */
void do_general(ord_type ordering);
/** 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);
};
/** 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
* encapsulates the ordering, and the information about the number
* of static (appearing only at time t) predetermined (appearing
* before t and possibly at t), both (appearing before t and after
* t and possibly at t) and forward looking (appearing after t and
* possibly at t).
*
* The constructor takes a list of variable names. The class also
* provides mapping from the ordering of the variables in the list
* (outer) to the new ordering (at time t) and back.
*
* The user of the subclass must call do_ordering() after
* initialization.
*
* The class contains a few preimplemented methods for
* ordering. The class is used in this way: Make a subclass, and
* implement pure virtual do_ordering() by just plugging a
* preimplemented method, or plugging your own implementation. The
* method do_ordering() is called by the user after the constructor.
*/
class VarOrdering
{
protected:
/** Number of static variables. */
int n_stat;
/** Number of predetermined variables. */
int n_pred;
/** Number of both variables. */
int n_both;
/** Number of forward looking variables. */
int n_forw;
/** This is a set of tree indices corresponding to the
* variables at all times as they occur in the formulas. In
* fact, since this is used only for derivatives, the ordering
* of this vector is only important for ordering of the
* derivatives, in other contexts the ordering is not
* important, so it is rather a set of indices.*/
vector<int> der_atoms;
/** This maps tree index of the variable to the position in
* the row of the ordering. One should be careful with making
* space in the positions for variables not appearing at time
* 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,
* 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
* 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
* 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
* to positions 3 and 4. */
map<int, int> positions;
/** This maps an ordering of the list of variables in
* constructor to the new ordering (at time t). The length is
* the number of variables. */
vector<int> outer2y;
/** This maps a new ordering to the ordering of the list of
* variables in constructor (at time t). The length is the
* number of variables. */
vector<int> y2outer;
/** This is just a reference for variable names to keep it
* from constructor to do_ordering() implementations. */
const vector<const char *> &varnames;
/** This is just a reference to atoms to keep it from
* constructor to do_ordering() implementations. */
const DynamicAtoms &atoms;
public:
/** This is an enum type for an ordering type implemented by
* do_general. */
enum ord_type {pbspbfbf, bfspbfpb};
/** Construct the ordering of the variables given by the names
* with their dynamic occurrences defined by the atoms. It
* calls the virtual method do_ordering which can be
* reimplemented. */
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)
{
}
VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
const DynamicAtoms &a);
virtual VarOrdering *clone(const vector<const char *> &vnames,
const DynamicAtoms &a) const = 0;
/** Destructor does nothing here. */
virtual ~VarOrdering()
{
}
/** This is the method setting the ordering and the map. A
* subclass must reimplement it, possibly using a
* preimplemented ordering. This method must be called by the
* user after the class has been created. */
virtual void do_ordering() = 0;
/** Return number of static. */
int
nstat() const
{
return n_stat;
}
/** Return number of predetermined. */
int
npred() const
{
return n_pred;
}
/** Return number of both. */
int
nboth() const
{
return n_both;
}
/** Return number of forward looking. */
int
nforw() const
{
return n_forw;
}
/** Return the set of tree indices for derivatives. */
const vector<int> &
get_der_atoms() const
{
return der_atoms;
}
/** Return the y2outer. */
const vector<int> &
get_y2outer() const
{
return y2outer;
}
/** Return the outer2y. */
const vector<int> &
get_outer2y() const
{
return outer2y;
}
/** Query the atom given by the tree index. True is returned
* if the atom is one of the variables in the object. */
bool check(int t) 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
* be found, the exception is raised. */
int get_pos_of(int t) const;
/** This returns a length of ordered row of atoms. In all
* cases so far, it does not depend on the ordering and it is
* as follows. */
int
length() const
{
return n_stat+2*n_pred+3*n_both+2*n_forw;
}
/** Debug print. */
void print() const;
protected:
/** This is a general ordering method which orders the
* variables by the given ordering ord_type. See documentation
* for respective do_ methods. */
void do_general(ord_type ordering);
/** 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 <string>
namespace ogp {
namespace ogp
{
using std::vector;
using std::string;
using std::vector;
using std::string;
/** This is just ordering used for endogenous variables. It
* 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),
* both(t+1), forw(t+1). */
class EndoVarOrdering1 : public VarOrdering {
public:
EndoVarOrdering1(const vector<const char*>& vnames, const DynamicAtoms& a)
: VarOrdering(vnames, a) {}
EndoVarOrdering1(const EndoVarOrdering1& vo, const vector<const char*>& vnames,
const DynamicAtoms& a)
: VarOrdering(vo, vnames, a) {}
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 ordering used for endogenous variables. It
* 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),
* both(t+1), forw(t+1). */
class EndoVarOrdering1 : public VarOrdering
{
public:
EndoVarOrdering1(const vector<const char *> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<const char *> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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
* 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),
* stat(t), pred(t), both(t), forw(t). */
class EndoVarOrdering2 : public VarOrdering {
public:
EndoVarOrdering2(const vector<const char*>& vnames, const DynamicAtoms& a)
: VarOrdering(vnames, a) {}
EndoVarOrdering2(const EndoVarOrdering2& vo, const vector<const char*>& vnames,
const DynamicAtoms& a)
: VarOrdering(vo, vnames, a) {}
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 another ordering used for endogenous
* 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),
* stat(t), pred(t), both(t), forw(t). */
class EndoVarOrdering2 : public VarOrdering
{
public:
EndoVarOrdering2(const vector<const char *> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<const char *> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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
* no assumptions about their timing. It orders them from the
* least time to the latest time. */
class ExoVarOrdering : public VarOrdering {
public:
ExoVarOrdering(const vector<const char*>& vnames, const DynamicAtoms& a)
: VarOrdering(vnames, a) {}
ExoVarOrdering(const ExoVarOrdering& vo, const vector<const char*>& vnames,
const DynamicAtoms& a)
: VarOrdering(vo, vnames, a) {}
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const
{return new ExoVarOrdering(*this, vnames, a);}
void do_ordering()
{do_increasing_time();}
};
/** This is just ordering used for exogenous variables. It makes
* no assumptions about their timing. It orders them from the
* least time to the latest time. */
class ExoVarOrdering : public VarOrdering
{
public:
ExoVarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
ExoVarOrdering(const ExoVarOrdering &vo, const vector<const char *> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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
* and exo). It maps the ordering to the particular outer
* orderings of endo and exo. It works tightly with the FineAtoms
* class. */
class AllvarOuterOrdering {
protected:
/** Type for a map mapping a variable name to an integer. */
typedef map<const char*, int, ltstr> Tvarintmap;
/** Reference to atoms. */
const FineAtoms& atoms;
/** The vector of all endo and exo variables in outer
* ordering. The pointers point to storage in atoms. */
vector<const char*> allvar;
/** The mapping from outer endogenous to outer all. For
* example endo2all[0] is the order of the first outer
* endogenous variable in the allvar ordering. */
vector<int> endo2all;
/** The mapping from outer exogenous to outer all. For example
* exo2all[0] is the order of the first outer exogenous
* variables in the allvar ordering. */
vector<int> exo2all;
public:
/** Construct the allvar outer ordering from the provided
* sequence of endo and exo names. The names can have an
* arbitrary storage, the storage is transformed to the atoms
* storage. An exception is thrown if either the list is not
* exhaustive, or some string is not a variable. */
AllvarOuterOrdering(const vector<const char*>& allvar_outer, const FineAtoms& a);
/** Copy constructor using the storage of provided atoms. */
AllvarOuterOrdering(const AllvarOuterOrdering& allvar_outer, const FineAtoms& a);
/** Return endo2all mapping. */
const vector<int>& get_endo2all() const
{return endo2all;}
/** Return exo2all mapping. */
const vector<int>& get_exo2all() const
{return exo2all;}
/** Return the allvar ordering. */
const vector<const char*>& get_allvar() const
{return allvar;}
};
/** This class provides an outer ordering of all variables (endo
* and exo). It maps the ordering to the particular outer
* orderings of endo and exo. It works tightly with the FineAtoms
* class. */
class AllvarOuterOrdering
{
protected:
/** Type for a map mapping a variable name to an integer. */
typedef map<const char *, int, ltstr> Tvarintmap;
/** Reference to atoms. */
const FineAtoms &atoms;
/** The vector of all endo and exo variables in outer
* ordering. The pointers point to storage in atoms. */
vector<const char *> allvar;
/** The mapping from outer endogenous to outer all. For
* example endo2all[0] is the order of the first outer
* endogenous variable in the allvar ordering. */
vector<int> endo2all;
/** The mapping from outer exogenous to outer all. For example
* exo2all[0] is the order of the first outer exogenous
* variables in the allvar ordering. */
vector<int> exo2all;
public:
/** Construct the allvar outer ordering from the provided
* sequence of endo and exo names. The names can have an
* arbitrary storage, the storage is transformed to the atoms
* storage. An exception is thrown if either the list is not
* exhaustive, or some string is not a variable. */
AllvarOuterOrdering(const vector<const char *> &allvar_outer, const FineAtoms &a);
/** Copy constructor using the storage of provided atoms. */
AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a);
/** Return endo2all mapping. */
const vector<int> &
get_endo2all() const
{
return endo2all;
}
/** Return exo2all mapping. */
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
* parameters (no lag and leads) and endogenous and exogenous
* variables (with lags and leads). For parameters, endogenous and
* exogenous, it defines outer orderings and internal
* orderings. The internal orderings are created by
* parsing_finished() method when it is sure that no new variables
* would be registered. The outer orderings are given by the order
* of calls of registering methods.
*
* In addition, the class also defines outer ordering of
* endogenous and exogenous variables. This is input as a
* parameter to parsing_finished(). By default, this whole outer
* ordering is just a concatenation of outer ordering of
* endogenous and exogenous variables.
*
* The internal ordering of all endo and exo variables is just a
* concatenation of endo and exo variables in their internal
* orderings. This is the ordering with respect to which all
* derivatives are taken. */
class FineAtoms : public DynamicAtoms {
friend class AllvarOuterOrdering;
protected:
typedef map<const char*, int, ltstr> Tvarintmap;
private:
/** The vector of parameters names. The order gives the order
* the data is communicated with outside world. */
vector<const char*> params;
/** A map mapping a name of a parameter to an index in the outer
* ordering. */
Tvarintmap param_outer_map;
/** The vector of endogenous variables. This defines the order
* like parameters. */
vector<const char*> endovars;
/** A map mapping a name of an endogenous variable to an index
* in the outer ordering. */
Tvarintmap endo_outer_map;
/** The vector of exogenous variables. Also defines the order
* like parameters and endovars. */
vector<const char*> exovars;
/** A map mapping a name of an exogenous variable to an index
* in the outer ordering. */
Tvarintmap exo_outer_map;
/** This class refines the DynamicAtoms by distinguishing among
* parameters (no lag and leads) and endogenous and exogenous
* variables (with lags and leads). For parameters, endogenous and
* exogenous, it defines outer orderings and internal
* orderings. The internal orderings are created by
* parsing_finished() method when it is sure that no new variables
* would be registered. The outer orderings are given by the order
* of calls of registering methods.
*
* In addition, the class also defines outer ordering of
* endogenous and exogenous variables. This is input as a
* parameter to parsing_finished(). By default, this whole outer
* ordering is just a concatenation of outer ordering of
* endogenous and exogenous variables.
*
* The internal ordering of all endo and exo variables is just a
* concatenation of endo and exo variables in their internal
* orderings. This is the ordering with respect to which all
* derivatives are taken. */
class FineAtoms : public DynamicAtoms
{
friend class AllvarOuterOrdering;
protected:
typedef map<const char *, int, ltstr> Tvarintmap;
private:
/** The vector of parameters names. The order gives the order
* the data is communicated with outside world. */
vector<const char *> params;
/** A map mapping a name of a parameter to an index in the outer
* ordering. */
Tvarintmap param_outer_map;
/** The vector of endogenous variables. This defines the order
* like parameters. */
vector<const char *> endovars;
/** A map mapping a name of an endogenous variable to an index
* in the outer ordering. */
Tvarintmap endo_outer_map;
/** The vector of exogenous variables. Also defines the order
* like parameters and endovars. */
vector<const char *> exovars;
/** A map mapping a name of an exogenous variable to an index
* in the outer ordering. */
Tvarintmap exo_outer_map;
protected:
/** This is the internal ordering of all atoms corresponding
* to endogenous variables. It is constructed by
* parsing_finished() method, which should be called after all
* parsing jobs have been finished. */
VarOrdering* endo_order;
/** This is the internal ordering of all atoms corresponding
* to exogenous variables. It has the same handling as
* endo_order. */
VarOrdering* exo_order;
/** This is the all variables outer ordering. It is
* constructed by parsing finished. */
AllvarOuterOrdering* allvar_order;
/** This vector defines a set of atoms as tree indices used
* for differentiation. The order of the atoms in this vector
* defines ordering of the derivative tensors. The ordering is
* a concatenation of atoms from endo_order and then
* exo_order. This vector is setup by parsing_finished() and
* is returned by variables(). */
vector<int> der_atoms;
/** This is a mapping from endogenous atoms to all atoms in
* der_atoms member. The mapping maps index in endogenous atom
* ordering to index (not value) in der_atoms. It is useful if
* one wants to evaluate derivatives wrt only endogenous
* variables. It is set by parsing_finished(). By definition,
* it is monotone. */
vector<int> endo_atoms_map;
/** This is a mapping from exogenous atoms to all atoms in
* der_atoms member. It is the same as endo_atoms_map for
* atoms of exogenous variables. */
vector<int> exo_atoms_map;
public:
FineAtoms()
: endo_order(NULL), exo_order(NULL), allvar_order(NULL) {}
FineAtoms(const FineAtoms& fa);
/** Deletes endo_order and exo_order. */
virtual ~FineAtoms()
{
if (endo_order) delete endo_order;
if (exo_order) delete exo_order;
if (allvar_order) delete allvar_order;
}
/** Overrides DynamicAtoms::check_variable so that the error
* would be raised if the variable name is not declared. A
* variable is declared by inserting it to
* DynamicAtoms::varnames. This is a responsibility of a
* subclass. */
int check_variable(const char* name) const;
/** This calculates min lag and max lead of endogenous variables. */
void endovarspan(int& mlead, int& mlag) const
{varspan(endovars, mlead, mlag);}
/** This calculates mim lag and max lead of exogenous variables. */
void exovarspan(int& mlead, int& mlag) const
{varspan(exovars, mlead, mlag);}
/** This calculates the number of periods in which at least
* one exogenous variable occurs. */
int num_exo_periods() const;
/** Return an (external) ordering of parameters. */
const vector<const char*>& get_params() const
{return params;}
/** Return an external ordering of endogenous variables. */
const vector<const char*>& get_endovars() const
{return endovars;}
/** Return an external ordering of exogenous variables. */
const vector<const char*>& get_exovars() const
{return exovars;}
/** This constructs internal orderings and makes the indices
* returned by variables method available. Further it
* constructs outer ordering of all variables by a simple
* concatenation of outer endogenous and outer exogenous. In
* addition, it makes nstat, npred, nboth, nforw available. */
void parsing_finished(VarOrdering::ord_type ot);
/** This does the same thing as
* parsing_finished(VarOrdering::ord_type) plus it allows for
* inputing a different outer ordering of all variables. The
* ordering is input as a list of strings, their storage can
* be arbitrary. */
void parsing_finished(VarOrdering::ord_type ot, const vector<const char*> avo);
/** Return the external ordering of all variables (endo and
* exo). This is either the second argument to
* parsing_finished or the default external ordering. This
* must be called only after parsing_finished. */
const vector<const char*>& get_allvar() const;
/** Return the map from outer ordering of endo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>& outer_endo2all() const;
/** Return the map from outer ordering of exo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>& outer_exo2all() const;
/** Return the atoms with respect to which we are going to
* differentiate. This must be called after
* parsing_finished. */
vector<int> variables() const;
/** Return the number of static. */
int nstat() const;
/** Return the number of predetermined. */
int npred() const;
/** Return the number of both. */
int nboth() const;
/** Return the number of forward looking. */
int nforw() const;
/** Return the index of an endogenous atom given by tree index in
* the endo ordering. This must be also called only after
* parsing_finished(). */
int get_pos_of_endo(int t) const;
/** Return the index of an exogenous atom given by tree index in
* the exo ordering. This must be also called only after
* parsing_finished(). */
int get_pos_of_exo(int t) const;
/** Return the index of either endogenous or exogenous atom
* given by tree index in the concatenated ordering of
* endogenous and exogenous atoms. This must be also called
* only after parsing_finished(). */
int get_pos_of_all(int t) const;
/** Return the mapping from endogenous at time t to outer
* ordering of endogenous. */
const vector<int>& y2outer_endo() const;
/** Return the mapping from the outer ordering of endogenous to endogenous
* at time t. */
const vector<int>& outer2y_endo() const;
/** Return the mapping from exogenous at time t to outer
* ordering of exogenous. */
const vector<int>& y2outer_exo() const;
/** Return the mapping from the outer ordering of exogenous to exogenous
* at time t. */
const vector<int>& outer2y_exo() const;
/** Return the endo_atoms_map. */
const vector<int>& get_endo_atoms_map() const;
/** Return the exo_atoms_map. */
const vector<int>& get_exo_atoms_map() const;
/** Return an index in the outer ordering of a given
* parameter. An exception is thrown if the name is not a
* parameter. */
int name2outer_param(const char* name) const;
/** Return an index in the outer ordering of a given
* endogenous variable. An exception is thrown if the name is not a
* and endogenous variable. */
int name2outer_endo(const char* name) const;
/** Return an index in the outer ordering of a given
* exogenous variable. An exception is thrown if the name is not a
* and exogenous variable. */
int name2outer_exo(const char* name) const;
/** Return an index in the outer ordering of all variables
* (endo and exo) for a given name. An exception is thrown if
* the name is not a variable. This must be called only after
* parsing_finished(). */
int name2outer_allvar(const char* name) const;
/** Return the number of endogenous variables at time t-1, these are state
* variables. */
int nys() const
{return npred()+nboth();}
/** Return the number of endogenous variables at time t+1. */
int nyss() const
{return nboth()+nforw();}
/** Return the number of endogenous variables. */
int ny() const
{return endovars.size();}
/** 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;
};
protected:
/** This is the internal ordering of all atoms corresponding
* to endogenous variables. It is constructed by
* parsing_finished() method, which should be called after all
* parsing jobs have been finished. */
VarOrdering *endo_order;
/** This is the internal ordering of all atoms corresponding
* to exogenous variables. It has the same handling as
* endo_order. */
VarOrdering *exo_order;
/** This is the all variables outer ordering. It is
* constructed by parsing finished. */
AllvarOuterOrdering *allvar_order;
/** This vector defines a set of atoms as tree indices used
* for differentiation. The order of the atoms in this vector
* defines ordering of the derivative tensors. The ordering is
* a concatenation of atoms from endo_order and then
* exo_order. This vector is setup by parsing_finished() and
* is returned by variables(). */
vector<int> der_atoms;
/** This is a mapping from endogenous atoms to all atoms in
* der_atoms member. The mapping maps index in endogenous atom
* ordering to index (not value) in der_atoms. It is useful if
* one wants to evaluate derivatives wrt only endogenous
* variables. It is set by parsing_finished(). By definition,
* it is monotone. */
vector<int> endo_atoms_map;
/** This is a mapping from exogenous atoms to all atoms in
* der_atoms member. It is the same as endo_atoms_map for
* atoms of exogenous variables. */
vector<int> exo_atoms_map;
public:
FineAtoms()
: endo_order(NULL), exo_order(NULL), allvar_order(NULL)
{
}
FineAtoms(const FineAtoms &fa);
/** Deletes endo_order and exo_order. */
virtual ~FineAtoms()
{
if (endo_order)
delete endo_order;
if (exo_order)
delete exo_order;
if (allvar_order)
delete allvar_order;
}
/** Overrides DynamicAtoms::check_variable so that the error
* would be raised if the variable name is not declared. A
* variable is declared by inserting it to
* DynamicAtoms::varnames. This is a responsibility of a
* subclass. */
int check_variable(const char *name) const;
/** This calculates min lag and max lead of endogenous variables. */
void
endovarspan(int &mlead, int &mlag) const
{
varspan(endovars, mlead, mlag);
}
/** This calculates mim lag and max lead of exogenous variables. */
void
exovarspan(int &mlead, int &mlag) const
{
varspan(exovars, mlead, mlag);
}
/** This calculates the number of periods in which at least
* one exogenous variable occurs. */
int num_exo_periods() const;
/** Return an (external) ordering of parameters. */
const vector<const char *> &
get_params() const
{
return params;
}
/** Return an external ordering of endogenous variables. */
const vector<const char *> &
get_endovars() const
{
return endovars;
}
/** Return an external ordering of exogenous variables. */
const vector<const char *> &
get_exovars() const
{
return exovars;
}
/** This constructs internal orderings and makes the indices
* returned by variables method available. Further it
* constructs outer ordering of all variables by a simple
* concatenation of outer endogenous and outer exogenous. In
* addition, it makes nstat, npred, nboth, nforw available. */
void parsing_finished(VarOrdering::ord_type ot);
/** This does the same thing as
* parsing_finished(VarOrdering::ord_type) plus it allows for
* inputing a different outer ordering of all variables. The
* ordering is input as a list of strings, their storage can
* be arbitrary. */
void parsing_finished(VarOrdering::ord_type ot, const vector<const char *> avo);
/** Return the external ordering of all variables (endo and
* exo). This is either the second argument to
* parsing_finished or the default external ordering. This
* must be called only after parsing_finished. */
const vector<const char *>&get_allvar() const;
/** Return the map from outer ordering of endo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>&outer_endo2all() const;
/** Return the map from outer ordering of exo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>&outer_exo2all() const;
/** Return the atoms with respect to which we are going to
* differentiate. This must be called after
* parsing_finished. */
vector<int> variables() const;
/** Return the number of static. */
int nstat() const;
/** Return the number of predetermined. */
int npred() const;
/** Return the number of both. */
int nboth() const;
/** Return the number of forward looking. */
int nforw() const;
/** Return the index of an endogenous atom given by tree index in
* the endo ordering. This must be also called only after
* parsing_finished(). */
int get_pos_of_endo(int t) const;
/** Return the index of an exogenous atom given by tree index in
* the exo ordering. This must be also called only after
* parsing_finished(). */
int get_pos_of_exo(int t) const;
/** Return the index of either endogenous or exogenous atom
* given by tree index in the concatenated ordering of
* endogenous and exogenous atoms. This must be also called
* only after parsing_finished(). */
int get_pos_of_all(int t) const;
/** Return the mapping from endogenous at time t to outer
* ordering of endogenous. */
const vector<int>&y2outer_endo() const;
/** Return the mapping from the outer ordering of endogenous to endogenous
* at time t. */
const vector<int>&outer2y_endo() const;
/** Return the mapping from exogenous at time t to outer
* ordering of exogenous. */
const vector<int>&y2outer_exo() const;
/** Return the mapping from the outer ordering of exogenous to exogenous
* at time t. */
const vector<int>&outer2y_exo() const;
/** Return the endo_atoms_map. */
const vector<int>&get_endo_atoms_map() const;
/** Return the exo_atoms_map. */
const vector<int>&get_exo_atoms_map() const;
/** Return an index in the outer ordering of a given
* parameter. An exception is thrown if the name is not a
* parameter. */
int name2outer_param(const char *name) const;
/** Return an index in the outer ordering of a given
* endogenous variable. An exception is thrown if the name is not a
* and endogenous variable. */
int name2outer_endo(const char *name) const;
/** Return an index in the outer ordering of a given
* exogenous variable. An exception is thrown if the name is not a
* and exogenous variable. */
int name2outer_exo(const char *name) const;
/** Return an index in the outer ordering of all variables
* (endo and exo) for a given name. An exception is thrown if
* the name is not a variable. This must be called only after
* parsing_finished(). */
int name2outer_allvar(const char *name) const;
/** Return the number of endogenous variables at time t-1, these are state
* variables. */
int
nys() const
{
return npred()+nboth();
}
/** Return the number of endogenous variables at time t+1. */
int
nyss() const
{
return nboth()+nforw();
}
/** Return the number of endogenous variables. */
int
ny() const
{
return endovars.size();
}
/** 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

View File

@ -5,408 +5,492 @@
#include "tree.h"
namespace ogp {
using std::vector;
namespace ogp
{
using std::vector;
/** Pure virtual class defining a minimal interface for
* representation of nulary terms within FormulaParser. */
class Atoms {
public:
Atoms() {}
virtual ~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
* implementation is strict and the name is not among
* prescribed possible values. */
virtual int check(const char* name) const = 0;
/** This method assigns an internal index to the nulary term
* described by the name. The internal index is allocated by
* OperationTree class. */
virtual void assign(const char* name, int t) = 0;
/** Returns a number of variables which will be used for
* differentiations. */
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 a minimal interface for
* representation of nulary terms within FormulaParser. */
class Atoms
{
public:
Atoms()
{
}
virtual ~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
* implementation is strict and the name is not among
* prescribed possible values. */
virtual int check(const char *name) const = 0;
/** This method assigns an internal index to the nulary term
* described by the name. The internal index is allocated by
* OperationTree class. */
virtual void assign(const char *name, int t) = 0;
/** Returns a number of variables which will be used for
* differentiations. */
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
* set nulary terms to evaluation tree EvalTree. The
* implementations of this class will have to be connected with
* Atoms to have knowledge about the atoms and their indices in
* the tree, and will call EvalTree::set_nulary. */
class AtomValues {
public:
virtual ~AtomValues() {}
virtual void setValues(EvalTree& et) const = 0;
};
/** Pure virtual class defining interface for all classes able to
* set nulary terms to evaluation tree EvalTree. The
* implementations of this class will have to be connected with
* Atoms to have knowledge about the atoms and their indices in
* the tree, and will call EvalTree::set_nulary. */
class AtomValues
{
public:
virtual ~AtomValues()
{
}
virtual void setValues(EvalTree &et) const = 0;
};
class FormulaDerEvaluator;
class FoldMultiIndex;
/** For ordering FoldMultiIndex in the std::map. */
struct ltfmi {
bool operator()(const FoldMultiIndex& i1, const FoldMultiIndex& i2) const;
};
class FormulaDerEvaluator;
class FoldMultiIndex;
/** For ordering FoldMultiIndex in the std::map. */
struct ltfmi
{
bool operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const;
};
/** This class stores derivatives (tree indices) of one formula
* for all orders upto a given one. It stores the derivatives as a
* sequence (vector) of these tree indices and sequence of the
* multidimensional indices of variables wrt which the derivatives
* were taken. In order to speed up querying for a derivative
* given the variables, we have a map mapping the multidimensional
* index to the order of the derivative in the sequence.
*
* 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,
* and implementation of the constructor has to be very difficult.
*/
class FormulaDerivatives {
friend class FormulaDerEvaluator;
protected:
/** Vector of derivatives. This is a list of derivatives (tree
* indices), the ordering is given by the algorithm used to
* create it. Currently, it starts with zero-th derivative,
* the formula itself and carries with first order, second,
* etc. */
vector<int> tder;
/** Vector of multiindices corresponding to the vector of
* derivatives. */
vector<FoldMultiIndex> indices;
/** For retrieving derivatives via a multiindex, we have a map
* mapping a multiindex to a derivative in the tder
* ordering. This means that indices[ind2der[index]] == index. */
typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap;
Tfmiintmap ind2der;
/** The number of variables. */
int nvar;
/** The maximum order of derivatives. */
int order;
public:
/** The constructor allocates and fills the sequence of the
* indices of derivatives for a formula.
* @param otree the OperationTree for which all work is done
* and to which the derivatives are added.
* @param vars the vector of nulary terms in the tree; the
* derivatives are taken with respect to these variables in
* the ordering given by the vector.
* @param f the index of the formula being differentiated. The
* 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(const FormulaDerivatives& fd);
virtual ~FormulaDerivatives(){}
/** Random access to the derivatives via multiindex. */
int derivative(const FoldMultiIndex& mi) const;
/** Return the order. */
int get_order() const
{return order;}
/** Debug print. */
void print(const OperationTree& otree) const;
};
/** This class stores derivatives (tree indices) of one formula
* for all orders upto a given one. It stores the derivatives as a
* sequence (vector) of these tree indices and sequence of the
* multidimensional indices of variables wrt which the derivatives
* were taken. In order to speed up querying for a derivative
* given the variables, we have a map mapping the multidimensional
* index to the order of the derivative in the sequence.
*
* 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,
* and implementation of the constructor has to be very difficult.
*/
class FormulaDerivatives
{
friend class FormulaDerEvaluator;
protected:
/** Vector of derivatives. This is a list of derivatives (tree
* indices), the ordering is given by the algorithm used to
* create it. Currently, it starts with zero-th derivative,
* the formula itself and carries with first order, second,
* etc. */
vector<int> tder;
/** Vector of multiindices corresponding to the vector of
* derivatives. */
vector<FoldMultiIndex> indices;
/** For retrieving derivatives via a multiindex, we have a map
* mapping a multiindex to a derivative in the tder
* ordering. This means that indices[ind2der[index]] == index. */
typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap;
Tfmiintmap ind2der;
/** The number of variables. */
int nvar;
/** The maximum order of derivatives. */
int order;
public:
/** The constructor allocates and fills the sequence of the
* indices of derivatives for a formula.
* @param otree the OperationTree for which all work is done
* and to which the derivatives are added.
* @param vars the vector of nulary terms in the tree; the
* derivatives are taken with respect to these variables in
* the ordering given by the vector.
* @param f the index of the formula being differentiated. The
* 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(const FormulaDerivatives &fd);
virtual ~FormulaDerivatives()
{
}
/** Random access to the derivatives via multiindex. */
int derivative(const FoldMultiIndex &mi) const;
/** Return the order. */
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
* differentiate them. The life cycle of the object is as follows:
* After it is created, a few calls to parse will add formulas
* (zero derivatives) to the object. Then a method differentiate()
* can be called and a vector of pointers to derivatives for each
* formula is created. After this, no one should call other
* parse() or differentiate(). A const reference of the object can
* be used in constructors of FormulaEvaluator and
* FormulaDerEvaluator in order to evaluate formulas (zero
* derivatives) and higher derivatives resp. */
class FormulaParser {
friend class FormulaCustomEvaluator;
friend class FormulaDerEvaluator;
protected:
/** The OperationTree of all formulas, including derivatives. */
OperationTree otree;
/** Reference to Atoms. The Atoms are filled with nulary terms
* during execution of parse(). */
Atoms& atoms;
/** Vector of formulas (zero derivatives) in the order as they
* have been parsed. */
vector<int> formulas;
/** The vector to derivatives, each vector corresponds to a
* formula in the vector formulas. */
vector<FormulaDerivatives*> ders;
public:
/** Construct an empty formula parser. */
FormulaParser(Atoms& a)
: atoms(a) {}
/** Copy constructor using a different instance of Atoms. */
FormulaParser(const FormulaParser& fp, Atoms& a);
virtual ~FormulaParser();
/** This class is able to parse a number of formulas and
* differentiate them. The life cycle of the object is as follows:
* After it is created, a few calls to parse will add formulas
* (zero derivatives) to the object. Then a method differentiate()
* can be called and a vector of pointers to derivatives for each
* formula is created. After this, no one should call other
* parse() or differentiate(). A const reference of the object can
* be used in constructors of FormulaEvaluator and
* FormulaDerEvaluator in order to evaluate formulas (zero
* derivatives) and higher derivatives resp. */
class FormulaParser
{
friend class FormulaCustomEvaluator;
friend class FormulaDerEvaluator;
protected:
/** The OperationTree of all formulas, including derivatives. */
OperationTree otree;
/** Reference to Atoms. The Atoms are filled with nulary terms
* during execution of parse(). */
Atoms &atoms;
/** Vector of formulas (zero derivatives) in the order as they
* have been parsed. */
vector<int> formulas;
/** The vector to derivatives, each vector corresponds to a
* formula in the vector formulas. */
vector<FormulaDerivatives *> ders;
public:
/** Construct an empty formula parser. */
FormulaParser(Atoms &a)
: atoms(a)
{
}
/** 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
* parser. */
void add_formula(int t);
/** Requires an addition of the binary operation; called from
* the parser. */
int add_binary(code_t code, int t1, int t2);
/** Requires an addition of the unary operation; called from
* the parser. */
int add_unary(code_t code, int t);
/** Requires an addition of the nulary operation given by the
* string. The Atoms are consulted for uniquness and are given
* an internal index generated by the OperationTree. This is
* the channel through which the Atoms are filled. */
int add_nulary(const char* str);
/** Requires an addition of the formula; called from the
* parser. */
void add_formula(int t);
/** Requires an addition of the binary operation; called from
* the parser. */
int add_binary(code_t code, int t1, int t2);
/** Requires an addition of the unary operation; called from
* the parser. */
int add_unary(code_t code, int t);
/** Requires an addition of the nulary operation given by the
* string. The Atoms are consulted for uniquness and are given
* an internal index generated by the OperationTree. This is
* the channel through which the Atoms are filled. */
int add_nulary(const char *str);
/** Adds a derivative to the tree. This just calls
* OperationTree::add_derivative. */
int add_derivative(int t, int v)
{return otree.add_derivative(t, v);}
/** Adds a substitution. This just calls
* OperationTree::add_substitution. */
int add_substitution(int t, const map<int,int>& subst)
{return otree.add_substitution(t, subst);}
/** Add the substitution given by the map where left sides of
* substitutions come from another parser. The right sides are
* from this object. The given t is from the given parser fp. */
int add_substitution(int t, const map<int,int>& subst,
const FormulaParser& fp)
{return otree.add_substitution(t, subst, fp.otree);}
/** This adds formulas from the given parser with (possibly)
* different atoms applying substitutions from the given map
* mapping atoms from fp to atoms of the object. */
void add_subst_formulas(const map<int,int>& subst, const FormulaParser& fp);
/** Substitute formulas. For each i from 1 through all
* formulas, it adds a substitution of the i-th formula and
* make it to be i-th formula.*/
void substitute_formulas(const std::map<int,int>& subst);
/** This method turns the given term to nulary operation. It
* 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);}
/** Adds a derivative to the tree. This just calls
* OperationTree::add_derivative. */
int
add_derivative(int t, int v)
{
return otree.add_derivative(t, v);
}
/** Adds a substitution. This just calls
* OperationTree::add_substitution. */
int
add_substitution(int t, const map<int, int> &subst)
{
return otree.add_substitution(t, subst);
}
/** Add the substitution given by the map where left sides of
* substitutions come from another parser. The right sides are
* from this object. The given t is from the given parser fp. */
int
add_substitution(int t, const map<int, int> &subst,
const FormulaParser &fp)
{
return otree.add_substitution(t, subst, fp.otree);
}
/** This adds formulas from the given parser with (possibly)
* different atoms applying substitutions from the given map
* mapping atoms from fp to atoms of the object. */
void add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp);
/** Substitute formulas. For each i from 1 through all
* formulas, it adds a substitution of the i-th formula and
* make it to be i-th formula.*/
void substitute_formulas(const std::map<int, int> &subst);
/** This method turns the given term to nulary operation. It
* 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
* formulas are parsed and added to the OperationTree and to
* the formulas vector. */
void parse(int length, const char* stream);
/** Processes a syntax error from bison. */
void error(const char* mes) const;
/** Differentiate all the formulas up to the given order. The
* variables with respect to which the derivatives are taken
* are obtained by Atoms::variables(). If the derivates exist,
* they are destroyed and created again (with possibly
* different order). */
void differentiate(int max_order);
/** Return i-th formula derivatives. */
const FormulaDerivatives& derivatives(int i) const;
/** Parse a given string containing one or more formulas. The
* formulas are parsed and added to the OperationTree and to
* the formulas vector. */
void parse(int length, const char *stream);
/** Processes a syntax error from bison. */
void error(const char *mes) const;
/** Differentiate all the formulas up to the given order. The
* variables with respect to which the derivatives are taken
* are obtained by Atoms::variables(). If the derivates exist,
* they are destroyed and created again (with possibly
* different order). */
void differentiate(int max_order);
/** Return i-th formula derivatives. */
const FormulaDerivatives&derivatives(int i) const;
/** This returns a maximum index of zero derivative formulas
* including all nulary terms. This is a mimumum length of the
* tree for which it is safe to evaluate zero derivatives of
* the formulas. */
int last_formula() const;
/** This returns a tree index of the i-th formula in the
* vector. */
int formula(int i) const
{return formulas[i];}
/** This returns a maximum index of zero derivative formulas
* including all nulary terms. This is a mimumum length of the
* tree for which it is safe to evaluate zero derivatives of
* the formulas. */
int last_formula() const;
/** This returns a tree index of the i-th formula in the
* vector. */
int
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
* 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 number of formulas. */
int
nformulas() const
{
return (int) (formulas.size());
}
/** This returns a number of formulas. */
int nformulas() const
{return (int)(formulas.size());}
/** This returns a reference to atoms. */
const Atoms &
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. */
const Atoms& getAtoms() const
{return atoms;}
Atoms& getAtoms()
{return atoms;}
/** This returns the tree. */
const OperationTree& getTree() const
{return otree;}
OperationTree& getTree()
{return otree;}
/** Debug print. */
void print() const;
private:
/** Hide this copy constructor declaration by declaring it as
* private. */
FormulaParser(const FormulaParser &fp);
/** Destroy all derivatives. */
void destroy_derivatives();
};
/** Debug print. */
void print() const;
private:
/** Hide this copy constructor declaration by declaring it as
* private. */
FormulaParser(const FormulaParser& fp);
/** Destroy all derivatives. */
void destroy_derivatives();
};
/** This is a pure virtual class defining an interface for all
* classes which will load the results of formula (zero
* derivative) evaluations. A primitive implementation of this
* class can be a vector of doubles. */
class FormulaEvalLoader
{
public:
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
* classes which will load the results of formula (zero
* derivative) evaluations. A primitive implementation of this
* class can be a vector of doubles. */
class FormulaEvalLoader {
public:
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 class evaluates a selected subset of terms of the
* tree. In the protected constructor, one can constraint the
* initialization of the evaluation tree to a given number of
* terms in the beginning. Using this constructor, one has to make
* sure, that the terms in the beginning do not refer to terms
* behind the initial part. */
class FormulaCustomEvaluator
{
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 a selected subset of terms of the
* tree. In the protected constructor, one can constraint the
* initialization of the evaluation tree to a given number of
* terms in the beginning. Using this constructor, one has to make
* sure, that the terms in the beginning do not refer to terms
* behind the initial part. */
class FormulaCustomEvaluator {
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. */
class FormulaEvaluator : public FormulaCustomEvaluator
{
public:
/** Construct from FormulaParser. */
FormulaEvaluator(const FormulaParser &fp)
: FormulaCustomEvaluator(fp)
{
}
};
/** This class evaluates zero derivatives of the FormulaParser. */
class FormulaEvaluator : public FormulaCustomEvaluator {
public:
/** Construct from FormulaParser. */
FormulaEvaluator(const FormulaParser& fp)
: FormulaCustomEvaluator(fp) {}
};
/** This is a pure virtual class defining an interface for all
* classes which will load the results of formula derivative
* evaluations. */
class FormulaDerEvalLoader
{
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
* classes which will load the results of formula derivative
* evaluations. */
class FormulaDerEvalLoader {
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 class is a utility class representing the tensor
* multindex. It can basically increment itself, and calculate
* its offset in the folded tensor. */
class FoldMultiIndex
{
/** Number of variables. */
int nvar;
/** Dimension. */
int ord;
/** The multiindex. */
int *data;
public:
/** 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
* multindex. It can basically increment itself, and calculate
* its offset in the folded tensor. */
class FoldMultiIndex {
/** Number of variables. */
int nvar;
/** Dimension. */
int ord;
/** The multiindex. */
int* data;
public:
/** 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 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);
};
/** 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

View File

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

View File

@ -8,110 +8,143 @@
#include <cstdlib> // For NULL
#include <vector>
namespace ogp {
using std::vector;
namespace ogp
{
using std::vector;
/** This class reads the given string and parses it as a
* matrix. The matrix is read row by row. The row delimiter is
* either a newline character or semicolon (first newline
* character after the semicolon is ignored), the column delimiter
* is either blank character or comma. A different number of items
* in the row is not reconciliated, we do not construct a matrix
* here. The class provides only an iterator to go through all
* read items, the iterator provides information on row number and
* column number of the item. */
class MPIterator;
class MatrixParser {
friend class MPIterator;
protected:
/** Raw data as they were read. */
vector<double> data;
/** Number of items in each row. */
vector<int> row_lengths;
/** Maximum number of row lengths. */
int nc;
public:
MatrixParser()
: nc(0) {}
MatrixParser(const MatrixParser& mp)
: data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc) {}
virtual ~MatrixParser() {}
/** Return a number of read rows. */
int nrows() const
{return (int) row_lengths.size();}
/** Return a maximum number of items in the rows. */
int ncols() const
{return nc;}
/** Parses a given data. This initializes the object data. */
void parse(int length, const char* stream);
/** Adds newly read item. This should be called from bison
* parser. */
void add_item(double v);
/** Starts a new row. This should be called from bison
* 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 class reads the given string and parses it as a
* matrix. The matrix is read row by row. The row delimiter is
* either a newline character or semicolon (first newline
* character after the semicolon is ignored), the column delimiter
* is either blank character or comma. A different number of items
* in the row is not reconciliated, we do not construct a matrix
* here. The class provides only an iterator to go through all
* read items, the iterator provides information on row number and
* column number of the item. */
class MPIterator;
class MatrixParser
{
friend class MPIterator;
protected:
/** Raw data as they were read. */
vector<double> data;
/** Number of items in each row. */
vector<int> row_lengths;
/** Maximum number of row lengths. */
int nc;
public:
MatrixParser()
: nc(0)
{
}
MatrixParser(const MatrixParser &mp)
: data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc)
{
}
virtual ~MatrixParser()
{
}
/** Return a number of read rows. */
int
nrows() const
{
return (int) row_lengths.size();
}
/** Return a maximum number of items in the rows. */
int
ncols() const
{
return nc;
}
/** Parses a given data. This initializes the object data. */
void parse(int length, const char *stream);
/** Adds newly read item. This should be called from bison
* parser. */
void add_item(double v);
/** Starts a new row. This should be called from bison
* 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
* by MatrixParser. The iterator provides only read-only access. */
class MPIterator {
friend class MatrixParser;
protected:
/** Reference to the matrix parser. */
const MatrixParser* p;
/** The index of the pointed item in the matrix parser. */
unsigned int i;
/** The column number of the pointed item starting from zero. */
int c;
/** The row number of the pointed item starting from zero. */
int r;
/** This is an iterator intended to iterate through a matrix parsed
* by MatrixParser. The iterator provides only read-only access. */
class MPIterator
{
friend class MatrixParser;
protected:
/** Reference to the matrix parser. */
const MatrixParser *p;
/** The index of the pointed item in the matrix parser. */
unsigned int i;
/** The column number of the pointed item starting from zero. */
int c;
/** The row number of the pointed item starting from zero. */
int r;
public:
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 past-the-end of the
* parsed matrix. */
MPIterator(const MatrixParser& mp, const char* dummy);
/** Return read-only reference to the pointed item. */
const double& operator*() const
{return p->data[i];}
/** Return a row index of the pointed item. */
int row() const
{return r;}
/** Return a column index of the pointed item. */
int col() const
{return c;}
/** 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++();
};
public:
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 past-the-end of the
* parsed matrix. */
MPIterator(const MatrixParser &mp, const char *dummy);
/** Return read-only reference to the pointed item. */
const double &
operator*() const
{
return p->data[i];
}
/** Return a row index of the pointed item. */
int
row() const
{
return r;
}
/** Return a column index of the pointed item. */
int
col() const
{
return c;
}
/** 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
// Local Variables:

View File

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

View File

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

View File

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

View File

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

View File

@ -18,175 +18,286 @@
class Dynare;
class DynareNameList : public NameList {
vector<const char*> names;
class DynareNameList : public NameList
{
vector<const char *> names;
public:
DynareNameList(const Dynare& dynare);
int getNum() const
{return (int)names.size();}
const char* getName(int i) 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;
DynareNameList(const Dynare &dynare);
int
getNum() const
{
return (int) names.size();
}
const char *
getName(int i) 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 {
vector<const char*> names;
class DynareExogNameList : public NameList
{
vector<const char *> names;
public:
DynareExogNameList(const Dynare& dynare);
int getNum() const
{return (int)names.size();}
const char* getName(int i) const
{return names[i];}
DynareExogNameList(const Dynare &dynare);
int
getNum() const
{
return (int) names.size();
}
const char *
getName(int i) const
{
return names[i];
}
};
class DynareStateNameList : public NameList {
vector<const char*> names;
class DynareStateNameList : public NameList
{
vector<const char *> names;
public:
DynareStateNameList(const Dynare& dynare, const DynareNameList& dnl,
const DynareExogNameList& denl);
int getNum() const
{return (int)names.size();}
const char* getName(int i) const
{return names[i];}
DynareStateNameList(const Dynare &dynare, const DynareNameList &dnl,
const DynareExogNameList &denl);
int
getNum() const
{
return (int) names.size();
}
const char *
getName(int i) const
{
return names[i];
}
};
// The following only implements DynamicModel with help of ogdyn::DynareModel
class DynareJacobian;
class Dynare : public DynamicModel {
friend class DynareNameList;
friend class DynareExogNameList;
friend class DynareStateNameList;
friend class DynareJacobian;
Journal& journal;
ogdyn::DynareModel* model;
Vector* ysteady;
TensorContainer<FSSparseTensor> md;
DynareNameList* dnl;
DynareExogNameList* denl;
DynareStateNameList* dsnl;
ogp::FormulaEvaluator* fe;
ogp::FormulaDerEvaluator* fde;
const double ss_tol;
class Dynare : public DynamicModel
{
friend class DynareNameList;
friend class DynareExogNameList;
friend class DynareStateNameList;
friend class DynareJacobian;
Journal &journal;
ogdyn::DynareModel *model;
Vector *ysteady;
TensorContainer<FSSparseTensor> md;
DynareNameList *dnl;
DynareExogNameList *denl;
DynareStateNameList *dsnl;
ogp::FormulaEvaluator *fe;
ogp::FormulaDerEvaluator *fde;
const double ss_tol;
public:
/** Parses the given model file and uses the given order to
* override order from the model file (if it is != -1). */
Dynare(const char* modname, int ord, double sstol, Journal& jr);
/** Parses the given equations with explicitly given names. */
Dynare(const char** endo, int num_endo,
const char** exo, int num_exo,
const char** par, int num_par,
const char* equations, int len, int ord,
double sstol, Journal& jr);
/** Makes a deep copy of the object. */
Dynare(const Dynare& dyn);
DynamicModel* clone() const
{return new Dynare(*this);}
virtual ~Dynare();
int nstat() const
{return model->getAtoms().nstat();}
int nboth() const
{return model->getAtoms().nboth();}
int npred() const
{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();}
/** Parses the given model file and uses the given order to
* override order from the model file (if it is != -1). */
Dynare(const char *modname, int ord, double sstol, Journal &jr);
/** Parses the given equations with explicitly given names. */
Dynare(const char **endo, int num_endo,
const char **exo, int num_exo,
const char **par, int num_par,
const char *equations, int len, int ord,
double sstol, Journal &jr);
/** Makes a deep copy of the object. */
Dynare(const Dynare &dyn);
DynamicModel *
clone() const
{
return new Dynare(*this);
}
virtual
~Dynare();
int
nstat() const
{
return model->getAtoms().nstat();
}
int
nboth() const
{
return model->getAtoms().nboth();
}
int
npred() const
{
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
{return *dnl;}
const NameList& getStateNames() const
{return *dsnl;}
const NameList& getExogNames() const
{return *denl;}
const NameList &
getAllEndoNames() const
{
return *dnl;
}
const NameList &
getStateNames() const
{
return *dsnl;
}
const NameList &
getExogNames() const
{
return *denl;
}
TwoDMatrix& getVcov()
{return model->getVcov();}
const TwoDMatrix& getVcov() const
{return model->getVcov();}
Vector& getParams()
{return model->getParams();}
const Vector& getParams() const
{return model->getParams();}
void setInitOuter(const Vector& x)
{model->setInitOuter(x);}
TwoDMatrix &
getVcov()
{
return model->getVcov();
}
const TwoDMatrix &
getVcov() const
{
return model->getVcov();
}
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
{return md;}
const Vector& getSteady() const
{return *ysteady;}
Vector& getSteady()
{return *ysteady;}
const ogdyn::DynareModel& getModel() const
{return *model;}
const TensorContainer<FSSparseTensor> &
getModelDerivatives() const
{
return md;
}
const Vector &
getSteady() const
{
return *ysteady;
}
Vector &
getSteady()
{
return *ysteady;
}
const ogdyn::DynareModel &
getModel() const
{
return *model;
}
// here is true public interface
void solveDeterministicSteady(Vector& steady);
void solveDeterministicSteady()
{solveDeterministicSteady(*ysteady);}
void evaluateSystem(Vector& out, const Vector& yy, const Vector& xx);
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();
// here is true public interface
void solveDeterministicSteady(Vector &steady);
void
solveDeterministicSteady()
{
solveDeterministicSteady(*ysteady);
}
void evaluateSystem(Vector &out, const Vector &yy, const Vector &xx);
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 writeDump(const std::string& basename) const;
void writeMat(mat_t *fd, const char *prefix) const;
void writeDump(const std::string &basename) const;
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:
DynareEvalLoader(const ogp::FineAtoms& a, Vector& out);
void load(int i, double res)
{operator[](i) = res;}
DynareEvalLoader(const ogp::FineAtoms &a, Vector &out);
void
load(int i, double res)
{
operator[](i) = res;
}
};
class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader {
class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader
{
protected:
const ogp::FineAtoms& atoms;
TensorContainer<FSSparseTensor>& md;
const ogp::FineAtoms &atoms;
TensorContainer<FSSparseTensor> &md;
public:
DynareDerEvalLoader(const ogp::FineAtoms& a, TensorContainer<FSSparseTensor>& mod_ders,
int order);
void load(int i, int iord, const int* vars, double res);
DynareDerEvalLoader(const ogp::FineAtoms &a, TensorContainer<FSSparseTensor> &mod_ders,
int order);
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:
Dynare& d;
Dynare &d;
public:
DynareJacobian(Dynare& dyn);
virtual ~DynareJacobian() {}
void load(int i, int iord, const int* vars, double res);
void eval(const Vector& in);
DynareJacobian(Dynare &dyn);
virtual ~DynareJacobian()
{
}
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:
Dynare& d;
Dynare &d;
public:
DynareVectorFunction(Dynare& dyn)
: d(dyn) {}
virtual ~DynareVectorFunction() {}
int inDim() const
{return d.ny();}
int outDim() const
{return d.ny();}
void eval(const ConstVector& in, Vector& out);
DynareVectorFunction(Dynare &dyn)
: d(dyn)
{
}
virtual ~DynareVectorFunction()
{
}
int
inDim() const
{
return d.ny();
}
int
outDim() const
{
return d.ny();
}
void eval(const ConstVector &in, Vector &out);
};
#endif

View File

@ -15,196 +15,222 @@
#include <map>
#include <vector>
namespace ogdyn {
namespace ogdyn
{
using std::map;
using std::vector;
using std::map;
using std::vector;
/** A definition of a type mapping a string to an integer. Used as
* a substitution map, saying what names are substituted for what
* expressions represented by tree indices. */
typedef map<const char*, int, ogp::ltstr> Tsubstmap;
/** A definition of a type mapping a string to an integer. Used as
* a substitution map, saying what names are substituted for what
* expressions represented by tree indices. */
typedef map<const char *, int, ogp::ltstr> Tsubstmap;
class DynareStaticAtoms : public ogp::StaticAtoms {
public:
DynareStaticAtoms()
: StaticAtoms() {}
DynareStaticAtoms(const DynareStaticAtoms& a)
: StaticAtoms(a) {}
virtual ~DynareStaticAtoms() {}
/** This registers a unique varname identifier. It throws an
* 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 DynareStaticAtoms : public ogp::StaticAtoms
{
public:
DynareStaticAtoms()
: StaticAtoms()
{
}
DynareStaticAtoms(const DynareStaticAtoms &a)
: StaticAtoms(a)
{
}
virtual ~DynareStaticAtoms()
{
}
/** This registers a unique varname identifier. It throws an
* 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 {
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;
};
/** This class represents the atom values for dynare, where
* exogenous variables can occur only at time t, and endogenous at
* times t-1, t, and t+1. */
class DynareAtomValues : public ogp::AtomValues
{
protected:
/** Reference to the atoms (we suppose that they are only at
* t-1,t,t+1. */
const ogp::FineAtoms &atoms;
/** De facto reference to the values of parameters. */
const ConstVector paramvals;
/** De facto reference to the values of endogenous at time t-1. Only
* predetermined and both part. */
const ConstVector yym;
/** De facto reference to the values of endogenous at time t. Ordering
* given by the atoms. */
const ConstVector yy;
/** De facto reference to the values of endogenous at time t+1. Only
* both and forward looking part. */
const ConstVector yyp;
/** De facto reference to the values of exogenous at time t. */
const ConstVector xx;
public:
DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &ym,
const Vector &y, const Vector &yp, const Vector &x)
: 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)
: 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
* exogenous variables can occur only at time t, and endogenous at
* times t-1, t, and t+1. */
class DynareAtomValues : public ogp::AtomValues {
protected:
/** Reference to the atoms (we suppose that they are only at
* t-1,t,t+1. */
const ogp::FineAtoms& atoms;
/** De facto reference to the values of parameters. */
const ConstVector paramvals;
/** De facto reference to the values of endogenous at time t-1. Only
* predetermined and both part. */
const ConstVector yym;
/** De facto reference to the values of endogenous at time t. Ordering
* given by the atoms. */
const ConstVector yy;
/** De facto reference to the values of endogenous at time t+1. Only
* both and forward looking part. */
const ConstVector yyp;
/** De facto reference to the values of exogenous at time t. */
const ConstVector xx;
public:
DynareAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const Vector& ym,
const Vector& y, const Vector& yp, const Vector& x)
: 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)
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x) {}
void setValues(ogp::EvalTree& et) const;
};
class DynareStaticSteadyAtomValues : public ogp::AtomValues
{
protected:
/** Reference to static atoms over which the tree, where the
* values go, is defined. */
const ogp::StaticFineAtoms &atoms_static;
/** Reference to dynamic atoms for which the class gets input
* data. */
const ogp::FineAtoms &atoms;
/** De facto reference to input data, this is a vector of
* endogenous variables in internal ordering of the dynamic
* atoms. */
ConstVector yy;
/** De facto reference to input parameters corresponding to
* ordering defined by the dynamic atoms. */
ConstVector paramvals;
public:
/** Construct the object. */
DynareStaticSteadyAtomValues(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
const Vector &pvals, const Vector &yyy)
: atoms_static(sa),
atoms(a),
yy(yyy),
paramvals(pvals)
{
}
/** Set the values to the tree defined over the static atoms. */
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 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;
};
class DynareStaticSteadyAtomValues : public ogp::AtomValues {
protected:
/** Reference to static atoms over which the tree, where the
* values go, is defined. */
const ogp::StaticFineAtoms& atoms_static;
/** Reference to dynamic atoms for which the class gets input
* data. */
const ogp::FineAtoms& atoms;
/** De facto reference to input data, this is a vector of
* endogenous variables in internal ordering of the dynamic
* atoms. */
ConstVector yy;
/** De facto reference to input parameters corresponding to
* ordering defined by the dynamic atoms. */
ConstVector paramvals;
public:
/** Construct the object. */
DynareStaticSteadyAtomValues(const ogp::FineAtoms& a, const ogp::StaticFineAtoms& sa,
const Vector& pvals, const Vector& yyy)
: atoms_static(sa),
atoms(a),
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;
};
/** 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
// Local Variables:

View File

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

View File

@ -15,377 +15,463 @@
#include <map>
#include <boost/unordered_set.hpp>
namespace ogdyn {
using boost::unordered_set;
using std::map;
namespace ogdyn
{
using boost::unordered_set;
using std::map;
/** This represents an interval in a string by the pair of
* positions (including the first, excluding the second). A
* position is given by the line and the column within the line
* (both starting from 1). */
struct PosInterval {
int fl;
int fc;
int ll;
int lc;
PosInterval() {}
PosInterval(int ifl, int ifc, int ill, int ilc)
: 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;}
/** 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 represents an interval in a string by the pair of
* positions (including the first, excluding the second). A
* position is given by the line and the column within the line
* (both starting from 1). */
struct PosInterval
{
int fl;
int fc;
int ll;
int lc;
PosInterval()
{
}
PosInterval(int ifl, int ifc, int ill, int ilc)
: 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;
}
/** 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
* parsed matrix data. */
class ParsedMatrix : public TwoDMatrix {
public:
/** Construct the object from the parsed data of ogp::MatrixParser. */
ParsedMatrix(const ogp::MatrixParser& mp);
};
/** This class is basically a GeneralMatrix but is created from
* parsed matrix data. */
class ParsedMatrix : public TwoDMatrix
{
public:
/** 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;
class PlannerInfo;
class ForwSubstBuilder;
class ForwSubstInfo;
class MultInitSS;
class ModelSSWriter;
/** A subclass is responsible for creating param_vals, init_vals,
* and vcov_mat. */
class DynareModel
{
friend class PlannerBuilder;
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,
* and vcov_mat. */
class DynareModel {
friend class PlannerBuilder;
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();
};
/** This class constructs DynareModel from dynare++ model file. It
* parses variable declarations, model equations, parameter
* assignments, initval assignments, vcov matrix and order of
* approximation. */
class DynareParser : public DynareModel
{
protected:
/** Static atoms for parameter assignments. */
DynareStaticAtoms pa_atoms;
/** Assignments for the parameters. */
ogp::AtomAssignings paramset;
/** Static atoms for initval assignments. */
DynareStaticAtoms ia_atoms;
/** Assignments for the initval. */
ogp::AtomAssignings initval;
/** Matrix parser for vcov. */
ogp::MatrixParser vcov;
public:
/** This, in fact, creates DynareModel from the given string
* 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. */
DynareParser(const char *str, int len, int ord);
DynareParser(const DynareParser &p);
virtual
~DynareParser();
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;
};
/** This class constructs DynareModel from dynare++ model file. It
* parses variable declarations, model equations, parameter
* assignments, initval assignments, vcov matrix and order of
* approximation. */
class DynareParser : public DynareModel {
protected:
/** Static atoms for parameter assignments. */
DynareStaticAtoms pa_atoms;
/** Assignments for the parameters. */
ogp::AtomAssignings paramset;
/** Static atoms for initval assignments. */
DynareStaticAtoms ia_atoms;
/** Assignments for the initval. */
ogp::AtomAssignings initval;
/** Matrix parser for vcov. */
ogp::MatrixParser vcov;
public:
/** This, in fact, creates DynareModel from the given string
* 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. */
DynareParser(const char* str, int len, int ord);
DynareParser(const DynareParser& p);
virtual ~DynareParser();
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,
* everything other by C/C++ objects. The initial values are set
* manually after the creation of this object. This implies that
* no automatic substitutions cannot be done here, which in turn
* implies that we cannot do here a social planner nor substitutions
* of multiple lags. */
class DynareSPModel : public DynareModel
{
public:
DynareSPModel(const char **endo, int num_endo,
const char **exo, int num_exo,
const char **par, int num_par,
const char *equations, int len, int ord);
DynareSPModel(const DynareSPModel &dm)
: DynareModel(dm)
{
}
~DynareSPModel()
{
}
virtual DynareModel *
clone() const
{
return new DynareSPModel(*this);
}
};
/** Semiparsed model. The equations are given by a string,
* everything other by C/C++ objects. The initial values are set
* manually after the creation of this object. This implies that
* no automatic substitutions cannot be done here, which in turn
* implies that we cannot do here a social planner nor substitutions
* of multiple lags. */
class DynareSPModel : public DynareModel {
public:
DynareSPModel(const char** endo, int num_endo,
const char** exo, int num_exo,
const char** par, int num_par,
const char* equations, int len, int ord);
DynareSPModel(const DynareSPModel& dm)
: DynareModel(dm) {}
~DynareSPModel() {}
virtual DynareModel* clone() const
{return new DynareSPModel(*this);}
};
/** This class implements a selector of operations which correspond
* to non-linear functions. This inherits from ogp::opselector and
* is used to calculate non-linear subterms in
* DynareModel::get_nonlinear_subterms(). */
class NLSelector : public ogp::opselector
{
private:
const DynareModel &model;
public:
NLSelector(const DynareModel &m) : model(m)
{
}
bool operator()(int t) const;
};
/** This class implements a selector of operations which correspond
* to non-linear functions. This inherits from ogp::opselector and
* is used to calculate non-linear subterms in
* DynareModel::get_nonlinear_subterms(). */
class NLSelector : public ogp::opselector {
private:
const DynareModel& model;
public:
NLSelector(const DynareModel& m) : model(m) {}
bool operator()(int t) const;
};
/** This class writes a mathematical code evaluating the system of
* equations and the first derivatives at zero shocks and at the
* given (static) state. Static means that lags and leads are
* ignored. */
class ModelSSWriter : public ogp::DefaultOperationFormatter
{
protected:
const DynareModel &model;
public:
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
* equations and the first derivatives at zero shocks and at the
* given (static) state. Static means that lags and leads are
* ignored. */
class ModelSSWriter : public ogp::DefaultOperationFormatter {
protected:
const DynareModel& model;
public:
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;
};
class MatlabSSWriter : public ModelSSWriter
{
protected:
/** Identifier used in function names. */
char *id;
public:
MatlabSSWriter(const DynareModel &dm, const char *idd);
virtual ~MatlabSSWriter()
{
delete [] id;
}
protected:
// from ModelSSWriter
void write_der0_preamble(FILE *fd) const;
void write_der1_preamble(FILE *fd) const;
/** This writes atom assignments. We have four kinds of atoms
* 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;
};
class MatlabSSWriter : public ModelSSWriter {
protected:
/** Identifier used in function names. */
char* id;
public:
MatlabSSWriter(const DynareModel& dm, const char* idd);
virtual ~MatlabSSWriter()
{delete [] id;}
protected:
// from ModelSSWriter
void write_der0_preamble(FILE* fd) const;
void write_der1_preamble(FILE* fd) const;
/** This writes atom assignments. We have four kinds of atoms
* 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;
};
/** 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,21 +8,22 @@
#include "KronVector.h"
#include "QuasiTriangular.h"
class KronUtils {
class KronUtils
{
public:
/* 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
\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
\I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */
static void multAtLevel(int level, const QuasiTriangular& t,
KronVector& x);
static void multAtLevelTrans(int level, const QuasiTriangular& t,
KronVector& x);
/* 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
\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
\I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */
static void multAtLevel(int level, const QuasiTriangular &t,
KronVector &x);
static void multAtLevelTrans(int level, const QuasiTriangular &t,
KronVector &x);
/* multiplies x=(F'\otimes F'\otimes..\otimes K)x */
static void multKron(const QuasiTriangular& f, const QuasiTriangular& k,
KronVector& x);
/* multiplies x=(F'\otimes F'\otimes..\otimes K)x */
static void multKron(const QuasiTriangular &f, const QuasiTriangular &k,
KronVector &x);
};
#endif /* KRON_UTILS_H */

View File

@ -9,44 +9,77 @@
class ConstKronVector;
class KronVector : public Vector {
class KronVector : public Vector
{
protected:
int m;
int n;
int depth;
int m;
int n;
int depth;
public:
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(const ConstKronVector& v); // new instance and copy
const KronVector& operator=(KronVector& v)
{Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;}
const KronVector& 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;}
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(const ConstKronVector &v); // new instance and copy
const KronVector &
operator=(KronVector &v)
{
Vector::operator=(v); m = v.m; n = v.n; depth = v.depth; return *this;
}
const KronVector &
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
{
protected:
int m;
int n;
int depth;
int m;
int n;
int depth;
public:
ConstKronVector(const KronVector& v);
ConstKronVector(const ConstKronVector& v);
ConstKronVector(const Vector& 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 ConstKronVector& v, int i);
int getM() const {return m;}
int getN() const {return n;}
int getDepth() const {return depth;}
ConstKronVector(const KronVector &v);
ConstKronVector(const ConstKronVector &v);
ConstKronVector(const Vector &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 ConstKronVector &v, int i);
int
getM() const
{
return m;
}
int
getN() const
{
return n;
}
int
getDepth() const
{
return depth;
}
};
int power(int m, int depth);

View File

@ -15,325 +15,521 @@ using namespace std;
class DiagonalBlock;
class Diagonal;
class DiagPair {
class DiagPair
{
private:
double* a1;
double* a2;
double *a1;
double *a2;
public:
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;}
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;
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;
}
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:
int jbar;
bool real;
DiagPair alpha;
double* beta1;
double* beta2;
int jbar;
bool real;
DiagPair alpha;
double *beta1;
double *beta2;
void copy(const DiagonalBlock& b) {
jbar = b.jbar;
real = b.real;
alpha = b.alpha;
beta1 = b.beta1;
beta2 = b.beta2;
}
void
copy(const DiagonalBlock &b)
{
jbar = b.jbar;
real = b.real;
alpha = b.alpha;
beta1 = b.beta1;
beta2 = b.beta2;
}
public:
DiagonalBlock() {}
DiagonalBlock(int jb, bool r, double* a1, double* a2,
double* b1, double* b2)
: alpha(a1, a2)
{
jbar = jb;
real = r;
beta1 = b1;
beta2 = b2;
}
// construct complex block
DiagonalBlock(int jb, double* a1, double* a2)
: alpha(a1, a2)
{
jbar = jb;
real = false;
beta1 = a2 - 1;
beta2 = a1 + 1;
}
// construct real block
DiagonalBlock(int jb, double* a1)
: alpha(a1, a1)
{
jbar = jb;
real = true;
beta1 = 0;
beta2 = 0;
}
DiagonalBlock(const DiagonalBlock& b)
{copy(b);}
const DiagonalBlock& operator=(const DiagonalBlock& b)
{copy(b); return *this;}
int getIndex() const
{return jbar;}
bool isReal() const
{return real;}
const DiagPair& 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;
DiagonalBlock()
{
}
DiagonalBlock(int jb, bool r, double *a1, double *a2,
double *b1, double *b2)
: alpha(a1, a2)
{
jbar = jb;
real = r;
beta1 = b1;
beta2 = b2;
}
// construct complex block
DiagonalBlock(int jb, double *a1, double *a2)
: alpha(a1, a2)
{
jbar = jb;
real = false;
beta1 = a2 - 1;
beta2 = a1 + 1;
}
// construct real block
DiagonalBlock(int jb, double *a1)
: alpha(a1, a1)
{
jbar = jb;
real = true;
beta1 = 0;
beta2 = 0;
}
DiagonalBlock(const DiagonalBlock &b)
{
copy(b);
}
const DiagonalBlock &
operator=(const DiagonalBlock &b)
{
copy(b); return *this;
}
int
getIndex() const
{
return jbar;
}
bool
isReal() const
{
return real;
}
const DiagPair &
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>
struct _diag_iter {
typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self;
_Tdiag diag;
_Titer it;
struct _diag_iter
{
typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self;
_Tdiag diag;
_Titer it;
public:
_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;}
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;}
_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;
}
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:
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<const Diagonal &, const DiagonalBlock &, list<DiagonalBlock>::const_iterator> const_diag_iter;
typedef _diag_iter<Diagonal &, DiagonalBlock &, list<DiagonalBlock>::iterator> diag_iter;
private:
int num_all;
list<DiagonalBlock> blocks;
int num_real;
void copy(const Diagonal&);
int num_all;
list<DiagonalBlock> blocks;
int num_real;
void copy(const Diagonal &);
public:
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);}
const Diagonal& operator =(const Diagonal& d) {copy(d); return *this;}
virtual ~Diagonal() {}
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);
}
const Diagonal &
operator=(const Diagonal &d)
{
copy(d); return *this;
}
virtual ~Diagonal()
{
}
int getNumComplex() const {return num_all - num_real;}
int getNumReal() const {return num_real;}
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;
int
getNumComplex() const
{
return num_all - num_real;
}
int
getNumReal() const
{
return num_real;
}
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()
{return diag_iter(*this, blocks.begin());}
const_diag_iter begin() const
{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());}
diag_iter
begin()
{
return diag_iter(*this, blocks.begin());
}
const_diag_iter
begin() const
{
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 */
void changeBase(double* p);
/* redefine pointers as data start at p */
void changeBase(double *p);
private:
static double EPS;
static int getNumComplex(const double* data, int d_size);
static bool isZero(double p);
static double EPS;
static int getNumComplex(const double *data, int d_size);
static bool isZero(double p);
};
template <class _TRef, class _TPtr>
struct _matrix_iter {
typedef _matrix_iter<_TRef, _TPtr> _Self;
int d_size;
bool real;
_TPtr ptr;
struct _matrix_iter
{
typedef _matrix_iter<_TRef, _TPtr> _Self;
int d_size;
bool real;
_TPtr ptr;
public:
_matrix_iter(_TPtr base, int ds, bool r)
{ptr = base; d_size = ds; real = r;}
virtual ~_matrix_iter() {}
const _Self& operator=(const _Self& it)
{ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;}
bool 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;
_matrix_iter(_TPtr base, int ds, bool r)
{
ptr = base; d_size = ds; real = r;
}
virtual ~_matrix_iter()
{
}
const _Self &
operator=(const _Self &it)
{
ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;
}
bool
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>
class _column_iter : public _matrix_iter<_TRef, _TPtr> {
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
typedef _column_iter<_TRef, _TPtr> _Self;
int row;
class _column_iter : public _matrix_iter<_TRef, _TPtr>
{
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
typedef _column_iter<_TRef, _TPtr> _Self;
int row;
public:
_column_iter(_TPtr base, int ds, bool r, int rw)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw) {};
_Self& operator++()
{_Tparent::ptr++; row++; return *this;}
_TRef b() const
{
if (_Tparent::real) {
return *(_Tparent::ptr);
} else {
return *(_Tparent::ptr+_Tparent::d_size);
}
}
int getRow() const {return row;}
_column_iter(_TPtr base, int ds, bool r, int rw)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw)
{
};
_Self &
operator++()
{
_Tparent::ptr++; row++; return *this;
}
_TRef
b() const
{
if (_Tparent::real)
{
return *(_Tparent::ptr);
}
else
{
return *(_Tparent::ptr+_Tparent::d_size);
}
}
int
getRow() const
{
return row;
}
};
template <class _TRef, class _TPtr>
class _row_iter : public _matrix_iter<_TRef, _TPtr> {
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
typedef _row_iter<_TRef, _TPtr> _Self;
int col;
class _row_iter : public _matrix_iter<_TRef, _TPtr>
{
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
typedef _row_iter<_TRef, _TPtr> _Self;
int col;
public:
_row_iter(_TPtr base, int ds, bool r, int cl)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl) {};
_Self& operator++()
{_Tparent::ptr += _Tparent::d_size; col++; return *this;}
virtual _TRef b() const
{
if (_Tparent::real) {
return *(_Tparent::ptr);
}else {
return *(_Tparent::ptr+1);
}
}
int getCol() const {return col;}
_row_iter(_TPtr base, int ds, bool r, int cl)
: _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl)
{
};
_Self &
operator++()
{
_Tparent::ptr += _Tparent::d_size; col++; return *this;
}
virtual _TRef
b() const
{
if (_Tparent::real)
{
return *(_Tparent::ptr);
}
else
{
return *(_Tparent::ptr+1);
}
}
int
getCol() const
{
return col;
}
};
class SchurDecomp;
class SchurDecompZero;
class QuasiTriangular : public SqSylvMatrix {
class QuasiTriangular : public SqSylvMatrix
{
public:
typedef _column_iter<const double&, const double*> const_col_iter;
typedef _column_iter<double&, double*> col_iter;
typedef _row_iter<const double&, const double*> const_row_iter;
typedef _row_iter<double&, double*> row_iter;
typedef Diagonal::const_diag_iter const_diag_iter;
typedef Diagonal::diag_iter diag_iter;
typedef _column_iter<const double &, const double *> const_col_iter;
typedef _column_iter<double &, double *> col_iter;
typedef _row_iter<const double &, const double *> const_row_iter;
typedef _row_iter<double &, double *> row_iter;
typedef Diagonal::const_diag_iter const_diag_iter;
typedef Diagonal::diag_iter diag_iter;
protected:
Diagonal diagonal;
Diagonal diagonal;
public:
QuasiTriangular(const double* d, int d_size);
QuasiTriangular(double r, const QuasiTriangular& t);
QuasiTriangular(double r, const QuasiTriangular& t,
double rr, const QuasiTriangular& tt);
QuasiTriangular(int p, const QuasiTriangular& t);
QuasiTriangular(const SchurDecomp& decomp);
QuasiTriangular(const SchurDecompZero& decomp);
QuasiTriangular(const QuasiTriangular& t);
virtual ~QuasiTriangular();
const Diagonal& getDiagonal() const {return diagonal;}
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);
QuasiTriangular(const double *d, int d_size);
QuasiTriangular(double r, const QuasiTriangular &t);
QuasiTriangular(double r, const QuasiTriangular &t,
double rr, const QuasiTriangular &tt);
QuasiTriangular(int p, const QuasiTriangular &t);
QuasiTriangular(const SchurDecomp &decomp);
QuasiTriangular(const SchurDecompZero &decomp);
QuasiTriangular(const QuasiTriangular &t);
virtual
~QuasiTriangular();
const Diagonal &
getDiagonal() const
{
return diagonal;
}
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 */
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;
const_diag_iter
diag_begin() const
{
return diagonal.begin();
}
diag_iter
diag_begin()
{
return diagonal.begin();
}
const_diag_iter
diag_end() const
{
return diagonal.end();
}
diag_iter
diag_end()
{
return diagonal.end();
}
const_diag_iter diag_begin() const
{return diagonal.begin();}
diag_iter diag_begin()
{return diagonal.begin();}
const_diag_iter diag_end() const
{return diagonal.end();}
diag_iter diag_end()
{return diagonal.end();}
/* iterators for off diagonal elements */
virtual const_col_iter col_begin(const DiagonalBlock &b) const;
virtual col_iter col_begin(const DiagonalBlock &b);
virtual const_row_iter row_begin(const DiagonalBlock &b) const;
virtual row_iter row_begin(const DiagonalBlock &b);
virtual const_col_iter col_end(const DiagonalBlock &b) const;
virtual col_iter col_end(const DiagonalBlock &b);
virtual const_row_iter row_end(const DiagonalBlock &b) const;
virtual row_iter row_end(const DiagonalBlock &b);
/* iterators for off diagonal elements */
virtual const_col_iter col_begin(const DiagonalBlock& b) const;
virtual col_iter col_begin(const DiagonalBlock& b);
virtual const_row_iter row_begin(const DiagonalBlock& b) const;
virtual row_iter row_begin(const DiagonalBlock& b);
virtual const_col_iter col_end(const DiagonalBlock& b) const;
virtual col_iter col_end(const DiagonalBlock& b);
virtual const_row_iter row_end(const DiagonalBlock& b) const;
virtual row_iter row_end(const DiagonalBlock& b);
/* clone */
virtual QuasiTriangular* clone() const
{return new QuasiTriangular(*this);}
virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const
{return new QuasiTriangular(p, t);}
virtual QuasiTriangular* clone(double r) const
{return new QuasiTriangular(r, *this);}
virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const
{return new QuasiTriangular(r, *this, rr, tt);}
/* clone */
virtual QuasiTriangular *
clone() const
{
return new QuasiTriangular(*this);
}
virtual QuasiTriangular *
clone(int p, const QuasiTriangular &t) const
{
return new QuasiTriangular(p, t);
}
virtual QuasiTriangular *
clone(double r) const
{
return new QuasiTriangular(r, *this);
}
virtual QuasiTriangular *
clone(double r, double rr, const QuasiTriangular &tt) const
{
return new QuasiTriangular(r, *this, rr, tt);
}
protected:
void setMatrix(double r, const QuasiTriangular& t);
void addMatrix(double r, const QuasiTriangular& t);
void setMatrix(double r, const QuasiTriangular &t);
void addMatrix(double r, const QuasiTriangular &t);
private:
void addUnit();
/* x = x + (T\otimes I)b */
void multaKron(KronVector& x, const ConstKronVector& b) const;
/* x = x + (T'\otimes I)b */
void multaKronTrans(KronVector& x, const ConstKronVector& b) const;
/* implementation via iterators, useful for large matrices */
void setMatrixViaIter(double r, const QuasiTriangular& t);
void addMatrixViaIter(double r, const QuasiTriangular& t);
/* hide noneffective implementations of parents */
void multsVec(Vector& x, const ConstVector& d) const;
void multsVecTrans(Vector& x, const ConstVector& d) const;
void addUnit();
/* x = x + (T\otimes I)b */
void multaKron(KronVector &x, const ConstKronVector &b) const;
/* x = x + (T'\otimes I)b */
void multaKronTrans(KronVector &x, const ConstKronVector &b) const;
/* implementation via iterators, useful for large matrices */
void setMatrixViaIter(double r, const QuasiTriangular &t);
void addMatrixViaIter(double r, const QuasiTriangular &t);
/* hide noneffective implementations of parents */
void multsVec(Vector &x, const ConstVector &d) const;
void multsVecTrans(Vector &x, const ConstVector &d) const;
};
#endif /* QUASI_TRIANGULAR_H */
// Local Variables:
// mode:C++
// End:

View File

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

View File

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

View File

@ -10,22 +10,27 @@
#include "SchurDecomp.h"
#include "QuasiTriangular.h"
class SchurDecompEig : public SchurDecomp {
class SchurDecompEig : public SchurDecomp
{
public:
typedef QuasiTriangular::diag_iter diag_iter;
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);
void orderEigen();
typedef QuasiTriangular::diag_iter diag_iter;
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);
void orderEigen();
protected:
bool tryToSwap(diag_iter& it, diag_iter& itadd);
bool tryToSwap(diag_iter &it, diag_iter &itadd);
};
#endif /* SCHUR_DECOMP_EIG_H */
// Local Variables:
// mode:C++
// End:

View File

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

View File

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

View File

@ -10,72 +10,100 @@
class SqSylvMatrix;
class SylvMatrix : public GeneralMatrix {
class SylvMatrix : public GeneralMatrix
{
public:
SylvMatrix(int m, int n)
: GeneralMatrix(m,n) {}
SylvMatrix(const double* d, int m, int n)
: GeneralMatrix(d, m, n) {}
SylvMatrix(double* d, int m, int n)
: GeneralMatrix(d, m, n) {}
SylvMatrix(const GeneralMatrix& m)
: 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) {}
SylvMatrix(int m, int n)
: GeneralMatrix(m, n)
{
}
SylvMatrix(const double *d, int m, int n)
: GeneralMatrix(d, m, n)
{
}
SylvMatrix(double *d, int m, int n)
: GeneralMatrix(d, m, n)
{
}
SylvMatrix(const GeneralMatrix &m)
: 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
|0 m| */
void multLeftI(const SqSylvMatrix& m);
/* this = |I 0|* this
|0 m'| */
void multLeftITrans(const SqSylvMatrix& m);
/* this = |0 a|*b, so that |0 a| is square */
void multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b);
/* this = this * (m\otimes m..\otimes m) */
void multRightKron(const SqSylvMatrix& m, int order);
/* this = this * (m'\otimes m'..\otimes m') */
void multRightKronTrans(const SqSylvMatrix& m, int order);
/* this = P*this, x = P*x, where P is gauss transformation setting
* a given element to zero */
void eliminateLeft(int row, int col, Vector& x);
/* this = this*P, x = P'*x, where P is gauss transformation setting
* a given element to zero */
void eliminateRight(int row, int col, Vector& x);
/* this = |I 0|* this
|0 m| */
void multLeftI(const SqSylvMatrix &m);
/* this = |I 0|* this
|0 m'| */
void multLeftITrans(const SqSylvMatrix &m);
/* this = |0 a|*b, so that |0 a| is square */
void multLeft(int zero_cols, const GeneralMatrix &a, const GeneralMatrix &b);
/* this = this * (m\otimes m..\otimes m) */
void multRightKron(const SqSylvMatrix &m, int order);
/* this = this * (m'\otimes m'..\otimes m') */
void multRightKronTrans(const SqSylvMatrix &m, int order);
/* this = P*this, x = P*x, where P is gauss transformation setting
* a given element to zero */
void eliminateLeft(int row, int col, Vector &x);
/* this = this*P, x = P'*x, where P is gauss transformation setting
* a given element to zero */
void eliminateRight(int row, int col, Vector &x);
};
class SqSylvMatrix : public SylvMatrix {
class SqSylvMatrix : public SylvMatrix
{
public:
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 GeneralMatrix& m, int i, int j, int nrows)
: SylvMatrix(m, i, j, nrows, nrows) {}
SqSylvMatrix(GeneralMatrix& m, int i, int j, int nrows)
: SylvMatrix(m, i, j, nrows, nrows) {}
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();
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 GeneralMatrix &m, int i, int j, int nrows)
: SylvMatrix(m, i, j, nrows, nrows)
{
}
SqSylvMatrix(GeneralMatrix &m, int i, int j, int nrows)
: SylvMatrix(m, i, j, nrows, nrows)
{
}
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 */
// Local Variables:
// mode:C++
// End:

View File

@ -9,55 +9,57 @@
#include <new>
class MallocAllocator {
class MallocAllocator
{
#ifdef USE_MEMORY_POOL
public:
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* p);
void operator delete[](void* p);
void *operator new(size_t size);
void *operator new[](size_t size);
void operator delete(void *p);
void operator delete[](void *p);
#endif
};
#ifdef USE_MEMORY_POOL
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* p);
void operator delete[](void* p);
void *operator new(size_t size);
void *operator new[](size_t size);
void operator delete(void *p);
void operator delete[](void *p);
#endif
class SylvMemoryPool {
char* base;
size_t length;
size_t allocated;
bool stack_mode;
SylvMemoryPool(const SylvMemoryPool&);
const SylvMemoryPool& operator=(const SylvMemoryPool&);
class SylvMemoryPool
{
char *base;
size_t length;
size_t allocated;
bool stack_mode;
SylvMemoryPool(const SylvMemoryPool &);
const SylvMemoryPool &operator=(const SylvMemoryPool &);
public:
SylvMemoryPool();
~SylvMemoryPool();
void init(size_t size);
void* allocate(size_t size);
void free(void* p);
void reset();
void setStackMode(bool);
SylvMemoryPool();
~SylvMemoryPool();
void init(size_t size);
void *allocate(size_t size);
void free(void *p);
void reset();
void setStackMode(bool);
};
class SylvMemoryDriver {
SylvMemoryDriver(const SylvMemoryDriver&);
const SylvMemoryDriver& operator=(const SylvMemoryDriver&);
class SylvMemoryDriver
{
SylvMemoryDriver(const SylvMemoryDriver &);
const SylvMemoryDriver &operator=(const SylvMemoryDriver &);
public:
SylvMemoryDriver(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);
~SylvMemoryDriver();
SylvMemoryDriver(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);
~SylvMemoryDriver();
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 */
// Local Variables:
// mode:C++
// End:

View File

@ -15,148 +15,217 @@
typedef enum {def, changed, undef} status;
template <class _Type>
struct ParamItem {
struct ParamItem
{
protected:
typedef ParamItem<_Type> _Self;
status s;
_Type value;
typedef ParamItem<_Type> _Self;
status s;
_Type value;
public:
ParamItem()
{s = undef;}
ParamItem(_Type val)
{value = val; s = def;}
ParamItem(const _Self& item)
{value = item.value; s = item.s;}
const _Self& operator=(const _Self& item)
{value = item.value; s = item.s; return *this;}
const _Self& operator=(const _Type& val)
{value = val; s = changed; return *this;}
_Type operator*() const
{return 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);
}
ParamItem()
{
s = undef;
}
ParamItem(_Type val)
{
value = val; s = def;
}
ParamItem(const _Self &item)
{
value = item.value; s = item.s;
}
const _Self &
operator=(const _Self &item)
{
value = item.value; s = item.s; return *this;
}
const _Self &
operator=(const _Type &val)
{
value = val; s = changed; return *this;
}
_Type
operator*() const
{
return 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:
typedef enum {iter, recurse} solve_method;
typedef enum {iter, recurse} solve_method;
protected:
class DoubleParamItem : public ParamItem<double> {
public:
DoubleParamItem() : ParamItem<double>() {}
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;}
class DoubleParamItem : public ParamItem<double>
{
public:
DoubleParamItem() : ParamItem<double>()
{
}
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)
mxArray* createMatlabArray() const;
mxArray *createMatlabArray() const;
#endif
};
};
class IntParamItem : public ParamItem<int> {
public:
IntParamItem() : ParamItem<int>() {}
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;}
class IntParamItem : public ParamItem<int>
{
public:
IntParamItem() : ParamItem<int>()
{
}
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)
mxArray* createMatlabArray() const;
mxArray *createMatlabArray() const;
#endif
};
};
class BoolParamItem : public ParamItem<bool> {
public:
BoolParamItem() : ParamItem<bool>() {}
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;}
class BoolParamItem : public ParamItem<bool>
{
public:
BoolParamItem() : ParamItem<bool>()
{
}
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)
mxArray* createMatlabArray() const;
mxArray *createMatlabArray() const;
#endif
};
};
class MethodParamItem : public ParamItem<solve_method> {
public:
MethodParamItem() : ParamItem<solve_method>() {}
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;}
class MethodParamItem : public ParamItem<solve_method>
{
public:
MethodParamItem() : ParamItem<solve_method>()
{
}
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)
mxArray* createMatlabArray() const;
mxArray *createMatlabArray() const;
#endif
};
};
public:
// input parameters
MethodParamItem method; // method of solution: iter/recurse
DoubleParamItem convergence_tol; // norm for what we consider converged
IntParamItem max_num_iter; // max number of iterations
DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization
BoolParamItem want_check; // true => allocate extra space for checks
// output parameters
BoolParamItem converged; // true if converged
DoubleParamItem iter_last_norm; // norm of the last iteration
IntParamItem num_iter; // number of iterations
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 viv_err1; // norm 1 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_errI; // norm Inf of error I-inv(V)*V
IntParamItem f_blocks; // number of diagonal blocks of F
IntParamItem f_largest; // size of largest diagonal block in F
IntParamItem f_zeros; // number of off diagonal zeros in F
IntParamItem f_offdiag; // number of all off diagonal elements in F
DoubleParamItem rcondA1; // reciprocal cond 1 number of A
DoubleParamItem rcondAI; // reciprocal cond Inf number of A
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_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 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 cpu_time; // time of the job in CPU seconds
// note: remember to change copy() if adding/removing member
// input parameters
MethodParamItem method; // method of solution: iter/recurse
DoubleParamItem convergence_tol; // norm for what we consider converged
IntParamItem max_num_iter; // max number of iterations
DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization
BoolParamItem want_check; // true => allocate extra space for checks
// output parameters
BoolParamItem converged; // true if converged
DoubleParamItem iter_last_norm; // norm of the last iteration
IntParamItem num_iter; // number of iterations
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 viv_err1; // norm 1 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_errI; // norm Inf of error I-inv(V)*V
IntParamItem f_blocks; // number of diagonal blocks of F
IntParamItem f_largest; // size of largest diagonal block in F
IntParamItem f_zeros; // number of off diagonal zeros in F
IntParamItem f_offdiag; // number of all off diagonal elements in F
DoubleParamItem rcondA1; // reciprocal cond 1 number of A
DoubleParamItem rcondAI; // reciprocal cond Inf number of A
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_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 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 cpu_time; // time of the job in CPU seconds
// note: remember to change copy() if adding/removing member
SylvParams(bool wc = false)
: method(recurse), convergence_tol(1.e-30), max_num_iter(15),
bs_norm(1.3), want_check(wc) {}
SylvParams(const SylvParams& p)
{copy(p);}
const SylvParams& 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;
SylvParams(bool wc = false)
: method(recurse), convergence_tol(1.e-30), max_num_iter(15),
bs_norm(1.3), want_check(wc)
{
}
SylvParams(const SylvParams &p)
{
copy(p);
}
const SylvParams &
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)
mxArray* createStructArray() const;
mxArray *createStructArray() const;
#endif
private:
void copy(const SylvParams& p);
void copy(const SylvParams &p);
};
#endif /* SYLV_PARAMS_H */
// Local Variables:
// mode:C++
// End:

View File

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

View File

@ -7,35 +7,45 @@
#include "SylvMatrix.h"
class SymSchurDecomp {
class SymSchurDecomp
{
protected:
Vector lambda;
SqSylvMatrix q;
Vector lambda;
SqSylvMatrix q;
public:
/** Calculates A = Q*Lambda*Q^T, where A is assummed to be
* symmetric and Lambda real diagonal, hence a vector. */
SymSchurDecomp(const GeneralMatrix& a);
SymSchurDecomp(const SymSchurDecomp& ssd)
: lambda(ssd.lambda), q(ssd.q) {}
virtual ~SymSchurDecomp() {}
const Vector& getLambda() const
{return lambda;}
const SqSylvMatrix& getQ() const
{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);
/** Calculates A = Q*Lambda*Q^T, where A is assummed to be
* symmetric and Lambda real diagonal, hence a vector. */
SymSchurDecomp(const GeneralMatrix &a);
SymSchurDecomp(const SymSchurDecomp &ssd)
: lambda(ssd.lambda), q(ssd.q)
{
}
virtual ~SymSchurDecomp()
{
}
const Vector &
getLambda() const
{
return lambda;
}
const SqSylvMatrix &
getQ() const
{
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
// Local Variables:
// mode:C++
// End:

View File

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

View File

@ -7,169 +7,252 @@
/* NOTE! Vector and ConstVector have not common super class in order
* to avoid running virtual method invokation mechanism. Some
* members, and methods are thus duplicated */
* members, and methods are thus duplicated */
#include <cstdio>
class GeneralMatrix;
class ConstVector;
class Vector {
class Vector
{
protected:
int len;
int s;
double* data;
bool destroy;
int len;
int s;
double *data;
bool destroy;
public:
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(const ConstVector& v);
Vector(const double* d, int l)
: len(l), s(1), data(new double[len]), destroy(true)
{copy(d, 1);}
Vector(double* d, int l)
: len(l), s(1), data(d), destroy(false) {}
Vector(double* d, int skip, int l)
: len(l), s(skip), data(d), destroy(false) {}
Vector(Vector& v, int off, int l);
Vector(const Vector& v, int off, int l);
Vector(GeneralMatrix& m, int col);
Vector(int row, GeneralMatrix& m);
const Vector& operator=(const Vector& v);
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;}
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(const ConstVector &v);
Vector(const double *d, int l)
: len(l), s(1), data(new double[len]), destroy(true)
{
copy(d, 1);
}
Vector(double *d, int l)
: len(l), s(1), data(d), destroy(false)
{
}
Vector(double *d, int skip, int l)
: len(l), s(skip), data(d), destroy(false)
{
}
Vector(Vector &v, int off, int l);
Vector(const Vector &v, int off, int l);
Vector(GeneralMatrix &m, int col);
Vector(int row, GeneralMatrix &m);
const Vector &operator=(const Vector &v);
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. */
bool operator==(const Vector& y) const;
bool operator!=(const Vector& y) const;
/** 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;
/** Exact equality. */
bool operator==(const Vector &y) const;
bool operator!=(const Vector &y) const;
/** 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;
virtual ~Vector();
void zeros();
void nans();
void infs();
bool toBeDestroyed() const {return destroy;}
void rotatePair(double alpha, double beta1, double beta2, int i);
void add(double r, const Vector& v);
void add(double r, const ConstVector& v);
void add(const double* z, const Vector& v);
void add(const double* z, const ConstVector& v);
void mult(double r);
double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const Vector& y) const;
bool isFinite() const;
void print() const;
virtual
~Vector();
void zeros();
void nans();
void infs();
bool
toBeDestroyed() const
{
return destroy;
}
void rotatePair(double alpha, double beta1, double beta2, int i);
void add(double r, const Vector &v);
void add(double r, const ConstVector &v);
void add(const double *z, const Vector &v);
void add(const double *z, const ConstVector &v);
void mult(double r);
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|
| |\otimes I .| | = | |
| -beta2 alpha| |b2| |x2|
*/
static void mult2(double alpha, double beta1, double beta2,
Vector& x1, Vector& x2,
const Vector& b1, const Vector& b2);
/* same, but adds instead of set */
static void mult2a(double alpha, double beta1, double beta2,
Vector& x1, Vector& x2,
const Vector& b1, const Vector& b2);
/* same, but subtracts instead of add */
static void mult2s(double alpha, double beta1, double beta2,
Vector& x1, Vector& x2,
const Vector& b1, const Vector& b2)
{mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);}
/* multiplies | alpha -beta1| |b1| |x1|
| |\otimes I .| | = | |
| -beta2 alpha| |b2| |x2|
*/
static void mult2(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2);
/* same, but adds instead of set */
static void mult2a(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2);
/* same, but subtracts instead of add */
static void
mult2s(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2)
{
mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);
}
private:
void copy(const double* d, int inc);
const Vector& operator=(int); // must not be used (not implemented)
const Vector& operator=(double); // must not be used (not implemented)
void copy(const double *d, int inc);
const Vector &operator=(int); // must not be used (not implemented)
const Vector &operator=(double); // must not be used (not implemented)
};
class BaseConstVector {
class BaseConstVector
{
protected:
int len;
int s;
const double* data;
int len;
int s;
const double *data;
public:
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;}
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;}
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;
}
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 ConstVector : public BaseConstVector {
class ConstVector : public BaseConstVector
{
public:
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, 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() {}
/** Exact equality. */
bool operator==(const ConstVector& y) const;
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) || operator==(y);}
bool operator>(const ConstVector& y) const
{return ! operator<=(y);}
bool operator>=(const ConstVector& y) const
{return ! operator<(y);}
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, int off, int l);
ConstVector(const double *d, int skip, int l);
ConstVector(const ConstGeneralMatrix &m, int col);
ConstVector(int row, const ConstGeneralMatrix &m);
double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const ConstVector& y) const;
bool isFinite() const;
void print() const;
virtual ~ConstVector()
{
}
/** Exact equality. */
bool operator==(const ConstVector &y) const;
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) || operator==(y);
}
bool
operator>(const ConstVector &y) const
{
return !operator<=(y);
}
bool
operator>=(const ConstVector &y) const
{
return !operator<(y);
}
double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const ConstVector &y) const;
bool isFinite() const;
void print() const;
};
class ZeroPad {
class ZeroPad
{
public:
static const int length = 16;
static const int length = 16;
private:
double pad[16];
double pad[16];
public:
ZeroPad();
const double* getBase() const {return pad;}
ZeroPad();
const double *
getBase() const
{
return pad;
}
};
#endif /* VECTOR_H */
// Local Variables:
// mode:C++
// End:

View File

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

View File

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

View File

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

View File

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

View File

@ -5,51 +5,69 @@
#ifndef OGU_MEMORY_FILE
#define OGU_MEMORY_FILE
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
* the offset in the line (both starting from 1). */
int calc_pos_offset(int length, const char* str, int line, int col);
/** This function calculates a line number and column number of a
* character given by the offset in the string. It is inverse to
* calc_pos_offset. */
void calc_pos_line_and_col(int length, const char* str, int offset,
int& line, int& col);
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
* the offset in the line (both starting from 1). */
int calc_pos_offset(int length, const char *str, int line, int col);
/** This function calculates a line number and column number of a
* character given by the offset in the string. It is inverse to
* calc_pos_offset. */
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
// Local Variables:

View File

@ -7,43 +7,54 @@
#include <vector>
namespace ogu {
namespace ogu
{
using std::vector;
using std::vector;
class PascalRow : public vector<int> {
int k;
public:
PascalRow()
: vector<int>(), k(1)
{ push_back(2); }
void setFromPrevious(const PascalRow& prev);
void prolong(const PascalRow& prev);
void prolongFirst(int n);
void print() const;
};
class PascalRow : public vector<int>
{
int k;
public:
PascalRow()
: vector<int>(), k(1)
{
push_back(2);
}
void setFromPrevious(const PascalRow &prev);
void prolong(const PascalRow &prev);
void prolongFirst(int n);
void print() const;
};
class PascalTriangle {
vector<PascalRow> tr;
public:
PascalTriangle()
{tr.push_back(PascalRow());}
PascalTriangle(const PascalTriangle& triang)
: tr(triang.tr) {}
const PascalTriangle& operator=(const PascalTriangle& triang)
{ 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;
};
class PascalTriangle
{
vector<PascalRow> tr;
public:
PascalTriangle()
{
tr.push_back(PascalRow());
}
PascalTriangle(const PascalTriangle &triang)
: tr(triang.tr)
{
}
const PascalTriangle &
operator=(const PascalTriangle &triang)
{
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;
#endif
// Local Variables:

View File

@ -155,18 +155,18 @@ sigma_m =-5.85;
Lambdamu=3.4e-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
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
algorithm, while the parameters initialized here are only set once for the initial
values of the parameters they depend on:
gammma1 as it depends on LambdaA, alppha, Lambdamu, betta, and delta
Rbar =0 as it depends on PI, LambdaA, alppha, Lambdamu, and betta
Lambdax
gammma1=mu_z*mu_I/betta-(1-delta);
R=1+(PIbar*mu_z/betta-1);
Lambdax=exp(LambdaYd);
LambdaYd= (LambdaA+alppha*Lambdamu)/(1-alppha);
*/

View File

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

View File

@ -6,22 +6,26 @@
* The data are in file "fsdat_simul.m", and have been artificially generated.
* They are therefore different from the original dataset used by Schorfheide.
*
* The prior distribution follows the one originally specified in Schorfheide's paper.
* Note that the beta prior for rho implies an asymptote and corresponding prior mode
* for rho at 0. It is generally recommended to avoid this extreme type of prior.
* The prior distribution follows the one originally specified in Schorfheide's
* paper, except for parameter rho. In the paper, the elicited beta prior for rho
* 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
* implications of long-run neutrality for monetary business cycle models",
* Journal of Applied Econometrics, 9, S37-S70.
* 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
* model.
*/
/*
* Copyright (C) 2004-2015 Dynare Team
* Copyright (C) 2004-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -109,7 +113,7 @@ alp, beta_pdf, 0.356, 0.02;
bet, beta_pdf, 0.993, 0.002;
gam, normal_pdf, 0.0085, 0.003;
mst, normal_pdf, 1.0002, 0.007;
rho, beta_pdf, 0.129, 0.223;
rho, beta_pdf, 0.129, 0.100;
psi, beta_pdf, 0.65, 0.05;
del, beta_pdf, 0.01, 0.005;
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-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>
Houtan Bastani <houtan@dynare.org>
Michel Juillard <michel.juillard@mjui.fr>
Frédéric Karamé <frederic.karame@univ-lemans.fr>
Junior Maih <junior.maih@gmail.com>
Ferhat Mihoubi <fmihoubi@univ-evry.fr>
George Perendia <george@perendia.orangehome.co.uk>
Johannes Pfeifer <jpfeifer@gmx.de>
Marco Ratto <marco.ratto@jrc.ec.europa.eu>
Sébastien Villemot <sebastien@dynare.org>
Marco Ratto <marco.ratto@ec.europa.eu>
Sébastien Villemot <sebastien.villemot@sciencespo.fr>
Source: http://www.dynare.org
Files: *
@ -18,8 +17,8 @@ Copyright: 1996-2017 Dynare Team
License: GPL-3+
Files: matlab/AIM/SP*
Copyright: public-domain
License: public-domain
Copyright: none
License: public-domain-aim
This code is in the public domain and may be used freely.
However the authors would appreciate acknowledgement of the source by
citation of any of the following papers:
@ -86,6 +85,57 @@ Copyright: 2016 Benjamin Born and Johannes Pfeifer
2016 Dynare Team
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
Copyright: 2005 Henning Schmidt, FCC, henning@fcc.chalmers.se
2006 Brecht Donckels, BIOMATH, brecht.donckels@ugent.be
@ -127,37 +177,24 @@ Copyright: 2005 Jos van der Geest <jos@jasen.nl>
2013 Christophe Gouel
2016 Dynare Team
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
Copyright: 2005 Christian Kanzow and Stefania Petra
2013 Christophe Gouel
2014 Dynare Team
License: permissive
License: permissive-lmmcp
Unlimited permission is granted to everyone to use, copy, modify or
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
License: GFDL-NIV-1.3+
@ -206,7 +243,7 @@ Files: m4/ax_compare_version.m4
Copyright: 2008 Tim Toolan <toolan@ele.uri.edu>
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>
2009 Dynare Team
License: LGPL-2.1+
@ -235,7 +272,7 @@ Copyright: 1996-2011 Daniel Waggoner and Tao Zha
License: GPL-3+
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
2003 Karibzhanov, Waggoner and Zha
License: GPL-3+
@ -316,7 +353,7 @@ License: GPL-3+
Files: contrib/dmm/randlib/*
Copyright: none
License: public-domain
License: public-domain-dmm
We place the Randlib code that we have written in the public domain.
.
NO WARRANTY
@ -336,6 +373,29 @@ License: public-domain
ITS ANALYSIS BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD
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+
Permission is granted to copy, distribute and/or modify this document
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>
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
This program is free software; you can redistribute it and/or
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])
if test "x$MATLAB_VERSION" != "x"; then
case $MATLAB_VERSION in
*2017a | *2017A)
MATLAB_VERSION="9.2"
;;
*2016b | *2016B)
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
% 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.
%
@ -26,123 +26,123 @@ 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/>.
k = size(DT,3); % number of structural parameters
smpl = size(Y,2); % Sample size.
pp = size(Y,1); % Maximum number of observed variables.
mm = size(T,2); % Number of state variables.
a = zeros(mm,1); % State vector.
Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
t = 0; % Initialization of the time index.
oldK = 0;
notsteady = 1; % Steady state flag.
F_singular = 1;
k = size(DT,3); % number of structural parameters
smpl = size(Y,2); % Sample size.
pp = size(Y,1); % Maximum number of observed variables.
mm = size(T,2); % Number of state variables.
a = zeros(mm,1); % State vector.
Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
t = 0; % Initialization of the time index.
oldK = 0;
notsteady = 1; % Steady state flag.
F_singular = 1;
lik = zeros(smpl,1); % Initialization of the vector gathering the densities.
LIK = Inf; % Default value of the log likelihood.
if nargout > 1,
if nargout > 1
DLIK = zeros(k,1); % Initialization of the score.
end
AHess = zeros(k,k); % Initialization of the Hessian
Da = zeros(mm,k); % State vector.
Dv = zeros(length(mf),k);
AHess = zeros(k,k); % Initialization of the Hessian
Da = zeros(mm,k); % State vector.
Dv = zeros(length(mf),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
while notsteady && t<smpl
t = t+1;
v = Y(:,t)-a(mf);
F = P(mf,mf) + H;
if rcond(F) < kalman_tol
if ~all(abs(F(:))<kalman_tol)
return
else
a = T*a;
P = T*P*transpose(T)+Om;
end
while notsteady && t<smpl
t = t+1;
v = Y(:,t)-a(mf);
F = P(mf,mf) + H;
if rcond(F) < kalman_tol
if ~all(abs(F(:))<kalman_tol)
return
else
F_singular = 0;
iF = inv(F);
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;
a = T*a;
P = T*P*transpose(T)+Om;
end
notsteady = max(max(abs(K-oldK))) > riccati_tol;
oldK = K;
end
else
F_singular = 0;
iF = inv(F);
K = P(:,mf)*iF;
lik(t) = log(det(F))+transpose(v)*iF*v;
if F_singular
error('The variance of the forecast error remains singular until the end of the sample')
end
[DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K);
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) );
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
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;
if nargout > 1,
a = T*(a+K*v);
P = T*(P-K*P(mf,:))*transpose(T)+Om;
DP = DP1;
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;
if nargout > 1
DLIK = DLIK/2;
end
% adding log-likelihhod constants
lik = (lik + pp*log(2*pi))/2;
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)
k = size(DT,3);
tmp = P-K*P(mf,:);
k = size(DT,3);
tmp = P-K*P(mf,:);
for ii = 1:k
DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii);
DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii);
DiF(:,:,ii) = -iF*DF(:,:,ii)*iF;
DK(:,:,ii) = DP(:,mf,ii)*iF + P(:,mf)*DiF(:,:,ii);
Dtmp = DP(:,:,ii) - DK(:,:,ii)*P(mf,:) - K*DP(mf,:,ii);
@ -150,6 +150,3 @@ for ii = 1:k
end
% end of computeDKalman

View File

@ -1,4 +1,4 @@
function e = SPAimerr(c);
function e = SPAimerr(c)
% e = aimerr(c);
%
% 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,
% 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==3) e='Aim: too many big roots.';
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] = ...
SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
% [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
% SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
%
@ -8,9 +8,9 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
% roots. This procedure will fail if the companion matrix is
% defective and does not have a linearly independent set of
% eigenvectors associated with the big roots.
%
%
% Input arguments:
%
%
% h Structural coefficient matrix (neq,neq*(nlag+1+nlead)).
% neq Number of equations.
% nlag Number of lags.
@ -19,9 +19,9 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
% by numeric_shift and reduced_form.
% uprbnd Inclusive upper bound for the modulus of roots
% allowed in the reduced form.
%
%
% Output arguments:
%
%
% b Reduced form coefficient matrix (neq,neq*nlag).
% rts Roots returned by eig.
% ia Dimension of companion matrix (number of non-trivial
@ -57,7 +57,7 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
% pages 472-489
b=[];rts=[];ia=[];nexact=[];nnumeric=[];lgroots=[];aimcode=[];
if(nlag<1 || nlead<1)
if(nlag<1 || nlead<1)
error('Aim_eig: model must have at least one lag and one lead');
end
% Initialization.
@ -66,26 +66,26 @@ bcols=neq*nlag;q=zeros(qrows,qcols);rts=zeros(qcols,1);
[h,q,iq,nexact]=SPExact_shift(h,q,iq,qrows,qcols,neq);
if (iq>qrows)
aimcode = 61;
return;
return
end
[h,q,iq,nnumeric]=SPNumeric_shift(h,q,iq,qrows,qcols,neq,condn);
if (iq>qrows)
aimcode = 62;
return;
return
end
[a,ia,js] = SPBuild_a(h,qcols,neq);
if (ia ~= 0)
if any(any(isnan(a))) || any(any(isinf(a)))
if any(any(isnan(a))) || any(any(isinf(a)))
disp('A is NAN or INF')
aimcode=63;
return
end
aimcode=63;
return
end
[w,rts,lgroots,flag_trouble]=SPEigensystem(a,uprbnd,min(length(js),qrows-iq+1));
if flag_trouble==1;
disp('Problem in SPEIG');
if flag_trouble==1
disp('Problem in SPEIG');
aimcode=64;
return
end
end
q = SPCopy_w(q,w,js,iq,qrows);
end
test=nexact+nnumeric+lgroots;

View File

@ -41,9 +41,9 @@ hs(:,left) = -hs(:,right)\hs(:,left);
a = zeros(qcols,qcols);
if(qcols > neq)
eyerows = 1:qcols-neq;
eyecols = neq+1:qcols;
a(eyerows,eyecols) = eye(qcols-neq);
eyerows = 1:qcols-neq;
eyecols = neq+1:qcols;
a(eyerows,eyecols) = eye(qcols-neq);
end
hrows = qcols-neq+1:qcols;
a(hrows,:) = hs(:,left);
@ -51,14 +51,14 @@ a(hrows,:) = hs(:,left);
% Delete inessential lags and build index array js. js indexes the
% columns in the big transition matrix that correspond to the
% essential lags in the model. They are the columns of q that will
% get the unstable left eigenvectors.
% get the unstable left eigenvectors.
js = 1:qcols;
zerocols = sum(abs(a)) == 0;
while( any(zerocols) )
a(:,zerocols) = [];
a(zerocols,:) = [];
js(zerocols) = [];
zerocols = sum(abs(a)) == 0;
a(:,zerocols) = [];
a(zerocols,:) = [];
js(zerocols) = [];
zerocols = sum(abs(a)) == 0;
end
ia = length(js);

View File

@ -2,7 +2,7 @@ function q = SPCopy_w(q,w,js,iq,qrows)
% q = SPCopy_w(q,w,js,iq,qrows)
%
% Copy the eigenvectors corresponding to the largest roots into the
% remaining empty rows and columns js of q
% remaining empty rows and columns js of q
% Author: Gary Anderson
% Original file downloaded from:
@ -30,7 +30,7 @@ function q = SPCopy_w(q,w,js,iq,qrows)
if(iq < qrows)
lastrows = iq+1:qrows;
wrows = 1:length(lastrows);
q(lastrows,js) = w(:,wrows)';
lastrows = iq+1:qrows;
wrows = 1:length(lastrows);
q(lastrows,js) = w(:,wrows)';
end

View File

@ -30,7 +30,7 @@ function [w,rts,lgroots,flag_trouble] = SPEigensystem(a,uprbnd,rowsLeft)
% Journal of Economic Dynamics and Control, 2010, vol. 34, issue 3,
% pages 472-489
opts.disp=0;
opts.disp=0;
% next block is commented out because eigs() intermitently returns different rts
%try
% [w,d] = eigs(a',rowsLeft,'LM',opts);
@ -39,24 +39,24 @@ opts.disp=0;
% [mag,k] = sort(-mag);
% rts = rts(k);
%catch
%disp('Catch in SPE');
%pause(0.5);
%aStr=datestr(clock);
%eval(['save ' regexprep(aStr,' ','') ' a']);
try
[w,d]=eig(a');
catch
lasterr
w=[];rts=[];lgroots=[];
flag_trouble=1;
return
end
rts = diag(d);
mag = abs(rts);
[mag,k] = sort(-mag);
rts = rts(k);
%disp('Catch in SPE');
%pause(0.5);
%aStr=datestr(clock);
%eval(['save ' regexprep(aStr,' ','') ' a']);
try
[w,d]=eig(a');
catch
lasterr
w=[];rts=[];lgroots=[];
flag_trouble=1;
return
end
rts = diag(d);
mag = abs(rts);
[mag,k] = sort(-mag);
rts = rts(k);
%end
flag_trouble=0;
flag_trouble=0;
%ws=SPSparse(w);
ws=sparse(w);
@ -65,7 +65,7 @@ ws = ws(:,k);
% Given a complex conjugate pair of vectors W = [w1,w2], there is a
% nonsingular matrix D such that W*D = real(W) + imag(W). That is to
% say, W and real(W)+imag(W) span the same subspace, which is all
% that aim cares about.
% that aim cares about.
ws = real(ws) + imag(ws);

View File

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

View File

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

View File

@ -2,7 +2,7 @@ function scof = SPObstruct(cof,cofb,neq,nlag,nlead)
% scof = SPObstruct(cof,cofb,neq,nlag,nlead)
%
% Construct the coefficients in the observable structure.
%
%
% Input arguments:
%
% cof structural coefficients
@ -51,17 +51,17 @@ qs=sparse(q);
qs(1:rc,1:cc) = sparse(cofb);
qcols = neq*(nlag+nlead);
if( nlead > 1 )
for i = 1:nlead-1
rows = i*neq + (1:neq);
qs(rows,:) = SPShiftright( qs((rows-neq),:), neq );
end
if( nlead > 1 )
for i = 1:nlead-1
rows = i*neq + (1:neq);
qs(rows,:) = SPShiftright( qs((rows-neq),:), neq );
end
end
l = (1: neq*nlag);
r = (neq*nlag+1: neq*(nlag+nlead));
qs(:,l) = - qs(:,r) \ qs(:,l);
qs(:,l) = - qs(:,r) \ qs(:,l);
minus = 1: neq*(nlag+1);
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);
%
% Compute reduced-form coefficient matrix, b.
@ -38,7 +38,7 @@ if(nonsing)
b = qs(1:neq,1:bcols);
b = full(b);
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);
oneover = diag(1 ./ themax);
nonsing = rcond(full(oneover *qs(:,right))) > condn;
@ -48,4 +48,3 @@ else %rescale by dividing row by maximal qr element
b = full(b);
end
end

View File

@ -3,7 +3,7 @@ function [y] = SPShiftright(x,n)
% [y] = shiftright(x,n)
%
% Shift the rows of x to the right by n columns, leaving zeros in the
% first n columns.
% first n columns.
% Original author: Gary Anderson
% Original file downloaded from:

View File

@ -1,20 +1,20 @@
function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% function [dr,aimcode]=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
% AIM System is given as a sum:
% i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,?
% AIM System is given as a sum:
% i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,?
% and its input as single array of matrices: [H-$... Hi ... H+&]
% 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)
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £
% 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)
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £
%
% INPUTS
% jacobia_ [matrix] 1st order derivative of the model
% jacobia_ [matrix] 1st order derivative of the model
% dr [matlab structure] Decision rules for stochastic simulations.
% M_ [matlab structure] Definition of the model.
%
% M_ [matlab structure] Definition of the model.
%
% OUTPUTS
% dr [matlab structure] Decision rules for stochastic simulations.
% aimcode [integer] 1: the model defines variables uniquely
@ -31,22 +31,22 @@ function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% (c==63) e='Aim: A is NAN or INF.';
% (c==64) e='Aim: Problem in SPEIG.';
% else e='Aimerr: return code not properly specified';
%
%
% SPECIAL REQUIREMENTS
% Dynare use:
% Dynare use:
% 1) the lognormal block in DR1 is being invoked for some models and changing
% values of ghx and ghy. We need to return the AIM output
% values before that block and run the block with the current returned values
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
% (it does not depend on mjdgges output).
%
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
% results to the Dynare solutiion then when if plain jacobia_ is passed,
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
%
% GP July 2008
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
% results to the Dynare solutiion then when if plain jacobia_ is passed,
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
%
% GP July 2008
% Copyright (C) 2008-2012 Dynare Team
% Copyright (C) 2008-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -69,8 +69,8 @@ lags=M_.maximum_endo_lag; % no of lags and leads
leads=M_.maximum_endo_lead;
klen=(leads+lags+1); % total lenght
theAIM_H=zeros(neq, neq*klen); % alloc space
lli=M_.lead_lag_incidence';
% "sparse" the compact jacobia into AIM H aray of matrices
lli=M_.lead_lag_incidence';
% "sparse" the compact jacobia into AIM H aray of matrices
% without exogenous shoc
theAIM_H(:,find(lli(:)))=jacobia_(:,nonzeros(lli(:)));
condn = 1.e-10;%SPAmalg uses this in zero tests
@ -102,7 +102,7 @@ if aimcode==1 %if OK
col_order=[((i-1)*neq)+dr.order_var' col_order];
end
bb_ord= bb(dr.order_var,col_order); % derive ordered gy
% variables are present in the state space at the lag at which they
% appear and at all smaller lags. The are ordered from smaller to
% higher lag (reversed order of M_.lead_lag_incidence rows for lagged
@ -117,7 +117,7 @@ if aimcode==1 %if OK
%theH0= theAIM_H (:,lags*neq+1: (lags+1)*neq);
% theHP= theAIM_H (:,(M_.maximum_endo_lag+1)*neq+1: (M_.maximum_endo_lag+2)*neq);
%theHP= theAIM_H (:,(lags+1)*neq+1: (lags+2)*neq);
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
%? = inv(H0 + H1B1)
%phi= (theH0+theHP*sparse(bb(:,(lags-1)*neq+1:end)))\eye( neq);
%AIM_ghu=phi*theAIM_Psi;
@ -137,8 +137,8 @@ else
if aimcode < 1 || aimcode > 5 % too big exception, use mjdgges
error('Error in AIM: aimcode=%d ; %s', aimcode, err);
end
% if aimcode > 5
% if aimcode > 5
% disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
% aimcode=5;
% end
% end
end

View File

@ -51,7 +51,7 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
%! @end deftypefn
%@eod:
% Copyright (C) 2001-2016 Dynare Team
% Copyright (C) 2001-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -67,35 +67,34 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
info = 0;
[dr,aimcode]=dynAIMsolver1(jacobia,M,dr);
if aimcode ~=1
info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range
info(2) = 1.0e+8;
return
info = 0;
[dr,aimcode]=dynAIMsolver1(jacobia,M,dr);
if aimcode ~=1
info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range
info(2) = 1.0e+8;
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
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
info(2) = temp'*temp;
return
end
info(2) = temp'*temp;
return
end

View File

@ -2,7 +2,7 @@ function [DirectoryName, info] = CheckPath(type,dname)
% Creates the subfolder "./M_.dname/type" if it does not exist yet.
%
% INPUTS
% type [string] Name of the subfolder.
% type [string] Name of the subfolder.
% dname [string] Name of the directory
%
% OUTPUTS
@ -12,7 +12,7 @@ function [DirectoryName, info] = CheckPath(type,dname)
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2005-2013 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%

View File

@ -16,7 +16,7 @@ function CutSample(M_, options_, estim_params_)
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2005-2015 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -66,7 +66,7 @@ if (TotalNumberOfMhFiles-1)-(FirstMhFile+1)+1 > 0
elseif TotalNumberOfMhFiles == 1
record.KeepedDraws.Distribution = [];
elseif TotalNumberOfMhFiles == 2 && FirstMhFile > 1
record.KeepedDraws.Distribution = [MAX_nruns-FirstLine+1 ; record.MhDraws(end,3)];
record.KeepedDraws.Distribution = [MAX_nruns-FirstLine+1 ; record.MhDraws(end,3)];
end
% Save updated mh-history file.

View File

@ -1,8 +1,8 @@
function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,decomp,trend_addition,state_uncertainty,M_,oo_,options_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_)
% Estimation of the smoothed variables and innovations.
%
% INPUTS
% o xparam1 [double] (p*1) vector of (estimated) parameters.
% Estimation of the smoothed variables and innovations.
%
% INPUTS
% o xparam1 [double] (p*1) vector of (estimated) parameters.
% o gend [integer] scalar specifying the number of observations ==> varargin{1}.
% o data [double] (n*T) matrix of data.
% o data_index [cell] 1*smpl cell of column vectors of indices.
@ -12,7 +12,7 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de
% o options_ [structure] describing the options
% o bayestopt_ [structure] describing the priors
% o estim_params_ [structure] characterizing parameters to be estimated
%
%
% OUTPUTS
% o alphahat [double] (m*T) matrix, smoothed endogenous variables (a_{t|T}) (decision-rule order)
% o etahat [double] (r*T) matrix, smoothed structural shocks (r>=n is the number of shocks).
@ -29,36 +29,36 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de
% matrices (meaningless for periods 1:d) (decision-rule order)
% o decomp (K*m*r*(T+K)) 4D array of shock decomposition of k-step ahead
% filtered variables (decision-rule order)
% o trend_addition [double] (n*T) pure trend component; stored in options_.varobs order
% o trend_addition [double] (n*T) pure trend component; stored in options_.varobs order
% o state_uncertainty [double] (K,K,T) array, storing the uncertainty
% about the smoothed state (decision-rule order)
% o M_ [structure] decribing the model
% o oo_ [structure] storing the results
% o options_ [structure] describing the options
% o bayestopt_ [structure] describing the priors
%
%
% Notes:
% m: number of endogenous variables (M_.endo_nbr)
% T: number of Time periods (options_.nobs)
% r: number of strucural shocks (M_.exo_nbr)
% n: number of observables (length(options_.varobs))
% K: maximum forecast horizon (max(options_.nk))
%
%
% To get variables that are stored in decision rule order in order of declaration
% as in M_.endo_names, ones needs code along the lines of:
% variables_declaration_order(dr.order_var,:) = alphahat
%
% Defines bayestopt_.mf = bayestopt_.smoother_mf (positions of observed variables
% and requested smoothed variables in decision rules (decision rule order)) and
%
% Defines bayestopt_.mf = bayestopt_.smoother_mf (positions of observed variables
% and requested smoothed variables in decision rules (decision rule order)) and
% passes it back via global variable
%
% ALGORITHM
% Diffuse Kalman filter (Durbin and Koopman)
%
% ALGORITHM
% Diffuse Kalman filter (Durbin and Koopman)
%
% SPECIAL REQUIREMENTS
% None
% Copyright (C) 2006-2016 Dynare Team
% Copyright (C) 2006-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -97,7 +97,7 @@ end
%------------------------------------------------------------------------------
% 2. call model setup & reduction program
%------------------------------------------------------------------------------
oldoo.restrict_var_list = oo_.dr.restrict_var_list;
oldoo.restrict_var_list = oo_.dr.restrict_var_list;
oldoo.restrict_columns = oo_.dr.restrict_columns;
oo_.dr.restrict_var_list = bayestopt_.smoother_var_list;
oo_.dr.restrict_columns = bayestopt_.smoother_restrict_columns;
@ -133,8 +133,8 @@ mf = bayestopt_.mf;
% ------------------------------------------------------------------------------
% 3. Initial condition of the Kalman filter
% ------------------------------------------------------------------------------
%
% Here, Pinf and Pstar are determined. If the model is stationary, determine
%
% Here, Pinf and Pstar are determined. If the model is stationary, determine
% Pstar as the solution of the Lyapunov equation and set Pinf=[] (Notation follows
% Koopman/Durbin (2003), Journal of Time Series Analysis 24(1))
%
@ -169,7 +169,7 @@ elseif options_.lik_init == 3 % Diffuse Kalman filter
kalman_algo = 3;
else
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;
T = blkdiag(T,zeros(vobs));
np = size(T,1);
@ -240,30 +240,32 @@ if kalman_algo == 1 || kalman_algo == 3
end
if kalman_algo == 2 || kalman_algo == 4
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
if ~expanded_state_vector_for_univariate_filter
%Augment state vector (follows Section 6.4.3 of DK (2012))
expanded_state_vector_for_univariate_filter=1;
Z = [Z, eye(vobs)];
ST = blkdiag(ST,zeros(vobs));
np = size(ST,1);
Q = blkdiag(Q,H);
R1 = blkdiag(R,eye(vobs));
if kalman_algo == 4
%recompute Schur state space transformation with
%expanded state space
[Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
else
Pstar = blkdiag(Pstar,H);
Pinf = blkdiag(Pinf,zeros(vobs));
end
%now reset H to 0
H = zeros(vobs,vobs);
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
if ~expanded_state_vector_for_univariate_filter
%Augment state vector (follows Section 6.4.3 of DK (2012))
expanded_state_vector_for_univariate_filter=1;
Z = [Z, eye(vobs)];
ST = blkdiag(ST,zeros(vobs));
np = size(ST,1);
Q = blkdiag(Q,H);
R1 = blkdiag(R,eye(vobs));
if kalman_algo == 4
%recompute Schur state space transformation with
%expanded state space
[Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
else
%do nothing, state vector was already expanded
Pstar = blkdiag(Pstar,H);
if ~isempty(Pinf)
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
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH3_Z(ST, ...
Z,R1,Q,diag(H), ...
Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
@ -280,7 +282,7 @@ if expanded_state_vector_for_univariate_filter && (kalman_algo == 2 || kalman_al
ahat = ahat(k,:);
aK = aK(:,k,:,:);
epsilonhat=etahat(end-vobs+1:end,:);
etahat=etahat(1:end-vobs,:);
etahat=etahat(1:end-vobs,:);
if ~isempty(PK)
PK = PK(:,k,k,:);
end

View File

@ -5,18 +5,18 @@ function Draws = GetAllPosteriorDraws(column, FirstMhFile, FirstLine, TotalNumbe
%
% INPUTS
% column: column
% FirstMhFile: first mh file
% FirstMhFile: first mh file
% FirstLine: first line
% TotalNumberOfMhFile: total number of mh file
% TotalNumberOfMhFile: total number of mh file
% NumberOfDraws: number of draws
% OUTPUTS
% Draws: draws from posterior distribution
%
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2005-2011 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -55,7 +55,7 @@ if nblck>1 && nargin<6
iline = 1;
end
end
else
else
for blck = 1:nblck
iline=iline0;
for file = FirstMhFile:TotalNumberOfMhFile

View File

@ -5,15 +5,15 @@ function [xparams, logpost] = GetOneDraw(type)
% INPUTS
% type: [string] 'posterior': draw from MCMC draws
% 'prior': draw from prior
%
%
% OUTPUTS
% xparams: vector of estimated parameters (drawn from posterior or prior distribution)
% logpost: log of the posterior density of this parameter vector
%
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2005-2015 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%

View File

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

View File

@ -1,22 +1,22 @@
function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, pnames)
% This function prints and saves posterior estimates after the mcmc
% (+updates of oo_ & TeX output).
%
% INPUTS
% estim_params_ [structure]
% (+updates of oo_ & TeX output).
%
% INPUTS
% estim_params_ [structure]
% M_ [structure]
% options_ [structure]
% bayestopt_ [structure]
% oo_ [structure]
% pnames [char] Array of char, names of the prior shapes available
%
% OUTPUTS
% oo_ [structure]
%
% OUTPUTS
% oo_ [structure]
%
% SPECIAL REQUIREMENTS
% None.
% Copyright (C) 2006-2016 Dynare Team
% Copyright (C) 2006-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -34,7 +34,7 @@ function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bay
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
%if ~options_.mh_replic && options_.load_mh_file
% load([M_.fname '_results.mat'],'oo_');
% load([M_.fname '_results.mat'],'oo_');
%end
TeX = options_.TeX;
@ -48,7 +48,7 @@ nx = nvx+nvn+ncx+ncn+np;
MetropolisFolder = CheckPath('metropolis',M_.dname);
OutputFolder = CheckPath('Output',M_.dname);
FileName = M_.fname;
FileName = M_.fname;
load_last_mh_history_file(MetropolisFolder,FileName);
@ -108,14 +108,14 @@ if np
[post_mean, post_median, post_var, hpd_interval, post_deciles, ...
density] = posterior_moments(Draws,1,options_.mh_conf_sig);
name = bayestopt_.name{ip};
oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density);
oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density);
end
end
disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),...
post_mean, ...
hpd_interval, ...
pnames(bayestopt_.pshape(ip)+1,:), ...
bayestopt_.p2(ip)));
bayestopt_.p2(ip)));
if TeX
k = estim_params_.param_vals(i,1);
name = deblank(M_.param_names_tex(k,:));
@ -163,7 +163,7 @@ if nvx
end
disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval,...
pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip)));
if TeX,
if TeX
name = deblank(M_.exo_names_tex(k,:));
TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),...
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);
@ -171,7 +171,7 @@ if nvx
ip = ip+1;
end
if TeX
TeXEnd(fid,2,'standard deviation of structural shocks');
TeXEnd(fid,2,'standard deviation of structural shocks');
end
end
if nvn
@ -213,7 +213,7 @@ if nvn
ip = ip+1;
end
if TeX
TeXEnd(fid,3,'standard deviation of measurement errors');
TeXEnd(fid,3,'standard deviation of measurement errors');
end
end
if ncx
@ -311,15 +311,15 @@ if ncn
end
disp(sprintf(pformat, header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval, ...
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,:)),')'];
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);
end
ip = ip+1;
end
if TeX
TeXEnd(fid,5,'correlation of measurement errors');
TeXEnd(fid,5,'correlation of measurement errors');
end
end
@ -359,7 +359,7 @@ fid = fidTeX;
function TeXCore(fid,name,shape,priormean,priorstd,postmean,poststd,hpd)
fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n'],...
fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n'],...
name,...
shape,...
priormean,...
@ -371,7 +371,7 @@ fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n']
function TeXEnd(fid,fnum,title)
fprintf(fid,'\\end{longtable}\n ');
fprintf(fid,'\\end{longtable}\n ');
fprintf(fid,'\\end{center}\n');
fprintf(fid,'%% End of TeX file.\n');
fclose(fid);

View File

@ -1,6 +1,6 @@
function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info)
% Copyright (C) 2005-2009 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -19,11 +19,11 @@ function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info)
global M_ options_
FigHandle = figure('Name',FigureProperties.Name);
FigHandle = figure('Name',FigureProperties.Name);
NAMES = cell(NumberOfPlots,1);
if options_.TeX
TeXNAMES = cell(NumberOfPlots,1);
TeXNAMES = cell(NumberOfPlots,1);
end
if NumberOfPlots == 9
@ -53,7 +53,7 @@ elseif NumberOfPlots == 2
elseif NumberOfPlots == 1
nr = 1;
nc = 1;
end
end
for plt = 1:NumberOfPlots
eval(['NumberOfCurves = Info.Box' int2str(plt) '.Number;'])
@ -138,7 +138,7 @@ for plt = 1:NumberOfPlots
set(hh,'Color','r','LineStyle','-','LineWidth',2)
%
%
end
end
end
axis([xmin xmax ymin ymax])
title(NAMES{plt})
@ -150,14 +150,14 @@ if Info.SaveFormat.Eps
if isempty(Info.SaveFormat.Name)
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName int2str(Info.SaveFormat.Number) '.eps']);
else
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name '.eps']);
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name '.eps']);
end
end
if Info.SaveFormat.Pdf && ~isoctave
if isempty(Info.SaveFormat.Name)
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName int2str(Info.SaveFormat.Number)]);
else
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name]);
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name]);
end
end
if Info.SaveFormat.Fig && ~isoctave

View File

@ -4,19 +4,19 @@ function oo_ = PlotPosteriorDistributions(estim_params_, M_, options_, bayestopt
% plots posterior distributions
%
% INPUTS
% estim_params_ [structure]
% estim_params_ [structure]
% M_ [structure]
% options_ [structure]
% options_ [structure]
% bayestopt_ [structure]
% oo_ [structure]
%
%
% OUTPUTS
% oo_ [structure]
%
% oo_ [structure]
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2005-2016 Dynare Team
% Copyright (C) 2005-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -49,7 +49,7 @@ nn = sqrt(MaxNumberOfPlotPerFigure);
figurename = 'Priors and posteriors';
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fidTeX = fopen([OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors.tex'],'w');
fprintf(fidTeX,'%% TeX eps-loader file generated by PlotPosteriorDistributions.m (Dynare).\n');
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
@ -63,7 +63,7 @@ for i=1:npar
subplotnum = subplotnum+1;
if subplotnum == 1
figunumber = figunumber+1;
hfig=dyn_figure(options_,'Name',figurename);
hfig=dyn_figure(options_.nodisplay,'Name',figurename);
end
[nam,texnam] = get_the_name(i,TeX,M_,estim_params_,options_);
if subplotnum == 1
@ -78,9 +78,9 @@ for i=1:npar
end
end
[x2,f2,abscissa,dens,binf2,bsup2] = draw_prior_density(i,bayestopt_);
top2 = max(f2);
top2 = max(f2);
if i <= nvx
name = deblank(M_.exo_names(estim_params_.var_exo(i,1),:));
name = deblank(M_.exo_names(estim_params_.var_exo(i,1),:));
x1 = oo_.posterior_density.shocks_std.(name)(:,1);
f1 = oo_.posterior_density.shocks_std.(name)(:,2);
oo_.prior_density.shocks_std.(name)(:,1) = x2;
@ -96,18 +96,18 @@ for i=1:npar
oo_.prior_density.measurement_errors_std.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.measurement_errors_std.(name);
end
end
elseif i <= nvx+nvn+ncx
j = i - (nvx+nvn);
k1 = estim_params_.corrx(j,1);
k2 = estim_params_.corrx(j,2);
name = [deblank(M_.exo_names(k1,:)) '_' deblank(M_.exo_names(k2,:))];
name = [deblank(M_.exo_names(k1,:)) '_' deblank(M_.exo_names(k2,:))];
x1 = oo_.posterior_density.shocks_corr.(name)(:,1);
f1 = oo_.posterior_density.shocks_corr.(name)(:,2);
oo_.prior_density.shocks_corr.(name)(:,1) = x2;
oo_.prior_density.shocks_corr.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.shocks_corr.(name);
pmod = oo_.posterior_mode.shocks_corr.(name);
end
elseif i <= nvx+nvn+ncx+ncn
j = i - (nvx+nvn+ncx);
@ -151,13 +151,13 @@ for i=1:npar
title(nam,'Interpreter','none');
hold off;
drawnow
if subplotnum == MaxNumberOfPlotPerFigure || i == npar;
dyn_saveas(hfig,[OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors' int2str(figunumber)],options_);
if subplotnum == MaxNumberOfPlotPerFigure || i == npar
dyn_saveas(hfig,[OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors' int2str(figunumber)],options_.nodisplay,options_.graph_format);
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fprintf(fidTeX,'\\begin{figure}[H]\n');
for j = 1:size(NAMES,1)
fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(j,:)),deblank(TeXNAMES(j,:)));
end
end
fprintf(fidTeX,'\\centering\n');
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_PriorsAndPosteriors%s}\n',options_.figures.textwidth*min(subplotnum/nn,1),OutputDirectoryName,M_.fname,int2str(figunumber));
fprintf(fidTeX,'\\caption{Priors and posteriors.}');

View File

@ -16,7 +16,7 @@ function PosteriorIRF(type)
% functions associated with it(the _core1 and _core2).
% 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.
%
@ -178,7 +178,7 @@ if strcmpi(type,'posterior')
end
end
if ~strcmpi(type,'prior'),
if ~strcmpi(type,'prior')
localVars.x=x;
end
@ -202,16 +202,16 @@ localVars.ifil2=ifil2;
localVars.MhDirectoryName=MhDirectoryName;
% Like sequential execution!
if isnumeric(options_.parallel),
if isnumeric(options_.parallel)
[fout] = PosteriorIRF_core1(localVars,1,B,0);
nosaddle = fout.nosaddle;
else
% Parallel execution!
[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);
NumberOfIRFfiles_dsge(j+1) =NumberOfIRFfiles_dsge(j)+nfiles;
if MAX_nirfs_dsgevar,
if MAX_nirfs_dsgevar
nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsgevar);
else
nfiles=0;
@ -235,12 +235,17 @@ else
% which files have to be copied to run remotely
NamFileInput(1,:) = {'',[M_.fname '_static.m']};
NamFileInput(2,:) = {'',[M_.fname '_dynamic.m']};
if options_.steadystate_flag,
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate.m']};
NamFileInput(3,:) = {'',[M_.fname '_set_auxiliary_variables.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
[fout] = masterParallel(options_.parallel, 1, B,NamFileInput,'PosteriorIRF_core1', localVars, globalVars, options_.parallel_info);
nosaddle=0;
for j=1:length(fout),
for j=1:length(fout)
nosaddle = nosaddle + fout(j).nosaddle;
end
@ -363,101 +368,101 @@ end
% PosteriorIRF_core2.m function.
if ~options_.nograph && ~options_.no_graph.posterior
% Save the local variables.
localVars=[];
% Save the local variables.
localVars=[];
Check=options_.TeX;
if (Check)
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
Check=options_.TeX;
if (Check)
localVars.varlist_TeX=varlist_TeX;
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!
if ~isoctave
if isnumeric(options_.parallel) || (M_.exo_nbr*ceil(size(varlist,1)/MaxNumberOfPlotPerFigure))<8,
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
else
isRemoteOctave = 0;
for indPC=1:length(options_.parallel),
isRemoteOctave = isRemoteOctave + (findstr(options_.parallel(indPC).MatlabOctavePath, 'octave'));
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
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);
else
globalVars = struct('M_',M_, ...
'options_', options_);
isRemoteOctave = 0;
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
else
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
end
else
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
end
% END parallel code!
% END parallel code!
end

View File

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

View File

@ -2,10 +2,10 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
% function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam, ThisMatlab)
% Generates the Posterior IRFs plot from the IRFs generated in
% PosteriorIRF_core1
%
%
% PARALLEL CONTEXT
% Performs in parallel execution a portion of the PosteriorIRF.m code.
% For more information, see the comment in posterior_sampler_core.m
% For more information, see the comment in posterior_sampler_core.m
% function.
%
% INPUTS
@ -30,7 +30,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
% SPECIAL REQUIREMENTS.
% None.
%
% Copyright (C) 2006-2016 Dynare Team
% Copyright (C) 2006-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -49,7 +49,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
global options_ M_
if nargin<4,
if nargin<4
whoiam=0;
end
@ -85,8 +85,8 @@ end
DirectoryName = CheckPath('Output',M_.dname);
RemoteFlag = 0;
if whoiam,
if Parallel(ThisMatlab).Local==0,
if whoiam
if Parallel(ThisMatlab).Local==0
RemoteFlag =1;
end
prct0={0,whoiam,Parallel(ThisMatlab)};
@ -96,16 +96,16 @@ end
OutputFileName={};
subplotnum = 0;
for i=fpar:npar,
for i=fpar:npar
figunumber = 0;
for j=1:nvar
if max(abs(MeanIRF(:,j,i))) >= options_.impulse_responses.plot_threshold
subplotnum = subplotnum+1;
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
hh = dyn_figure(options_,'Name',['Orthogonalized shock to ' tit(i,:)]);
hh = dyn_figure(options_.nodisplay,'Name',['Orthogonalized shock to ' tit(i,:)]);
end
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(:,2,j,i),'--k','linewidth',1)
end
% plot([1 options_.irf],[0 0],'-r','linewidth',0.5);
% plot([1 options_.irf],[0 0],'-r','linewidth',0.5);
box on
axis tight
xlim([1 options_.irf]);
@ -152,17 +152,17 @@ for i=fpar:npar,
if subplotnum == MaxNumberOfPlotPerFigure || (j == nvar && subplotnum> 0)
figunumber = figunumber+1;
dyn_saveas(hh,[DirectoryName '/' M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber)],options_);
if RemoteFlag==1,
dyn_saveas(hh,[DirectoryName '/' M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber)],options_.nodisplay,options_.graph_format);
if RemoteFlag==1
OutputFileName = [OutputFileName; {[DirectoryName,filesep], [M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber) '.*']}];
end
subplotnum = 0;
end
end% loop over selected endo_var
if whoiam,
if whoiam
fprintf('Done! \n');
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);
end
end% loop over exo_var

View File

@ -18,14 +18,14 @@ function ReshapeMatFiles(type, type2)
% posterior
% gsa
% prior
%
%
% OUTPUTS:
% none
% none
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2003-2011 Dynare Team
% Copyright (C) 2003-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -44,15 +44,15 @@ function ReshapeMatFiles(type, type2)
global M_ options_
if nargin==1,
if nargin==1
MhDirectoryName = [ CheckPath('metropolis',M_.dname) filesep ];
else
if strcmpi(type2,'posterior')
MhDirectoryName = [CheckPath('metropolis',M_.dname) filesep ];
elseif strcmpi(type2,'gsa')
if options_.opt_gsa.morris==1,
if options_.opt_gsa.morris==1
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 ];
elseif options_.opt_gsa.pprior
MhDirectoryName = [CheckPath(['gsa' filesep 'prior'],M_.dname) filesep ];
@ -61,17 +61,17 @@ else
end
else
MhDirectoryName = [CheckPath('prior',M_.dname) filesep ];
end
end
end
switch type
case 'irf_dsge'
CAPtype = 'IRF_DSGE';
TYPEsize = [ options_.irf , size(options_.varlist,1) , M_.exo_nbr ];
TYPEarray = 4;
TYPEarray = 4;
case 'irf_bvardsge'
CAPtype = 'IRF_BVARDSGE';
TYPEsize = [ options_.irf , length(options_.varobs) , M_.exo_nbr ];
TYPEarray = 4;
TYPEarray = 4;
case 'smooth'
CAPtype = 'SMOOTH';
TYPEsize = [ M_.endo_nbr , options_.nobs ];
@ -134,7 +134,7 @@ switch TYPEarray
eval(['idx = idx + size(stock_' type ',4);'])
end
%eval(['STOCK_' CAPtype ' = sort(STOCK_' CAPtype ',4);'])
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(NumberOfTYPEfiles-foffset+1) '.mat'],['STOCK_' CAPtype]);
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(NumberOfTYPEfiles-foffset+1) '.mat'],['STOCK_' CAPtype]);
end
else
load([MhDirectoryName M_.fname '_' type '1.mat']);
@ -176,7 +176,7 @@ switch TYPEarray
load([MhDirectoryName M_.fname '_' type '1.mat']);
%eval(['STOCK_' CAPtype ' = sort(stock_' type ',3);'])
eval(['STOCK_' CAPtype ' = stock_' type ';'])
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(1) '.mat'],['STOCK_' CAPtype ]);
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(1) '.mat'],['STOCK_' CAPtype ]);
end
% Original file format may be useful in some cases...
% for file = 1:NumberOfTYPEfiles

View File

@ -3,15 +3,15 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
% Wrapper function for target function used in TaRB algorithm; reassembles
% full parameter vector before calling target function
%
% INPUTS
% o optpar [double] (p_opt*1) vector of subset of parameters to be considered
% o par_vector [double] (p*1) full vector of parameters
% INPUTS
% o optpar [double] (p_opt*1) vector of subset of parameters to be considered
% o par_vector [double] (p*1) full vector of parameters
% o parameterindices [double] (p_opt*1) index of optpar entries in
% par_vector
% o TargetFun [char] string specifying the name of the objective
% function (posterior kernel).
% o varargin [structure] other inputs of target function
%
%
% OUTPUTS
% o fval [scalar] value of (minus) the likelihood.
% o info [double] (p*2) error code vector
@ -20,8 +20,9 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
% o Hess [double] (p*p) asymptotic Hessian matrix.
% 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
%
% Copyright (C) 2015-16 Dynare Team
%
% Copyright (C) 2015-2017 Dynare Team
%
% 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
[fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = feval(TargetFun,par_vector,varargin{:}); %call target function

View File

@ -2,19 +2,19 @@ function [] = Tracing()
% DESCRIPTION
% This function is used to test the correct execution of a matlab section
% on remote machine.
%
%
% If no error happen the function simply create a file.
%
% INPUTS
% ...
%
%
% OUTPUTS
% ...
%
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2010 Dynare Team
% Copyright (C) 2010-2017 Dynare Team
%
% This file is part of Dynare.
%

View File

@ -1,15 +1,15 @@
function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
% This function computes the theoretical spectral density of each
% endogenous variable declared in var_list. Results are stored in
% oo_.SpectralDensity and may be plotted. Plots are saved into the
% graphs-folder.
%
% endogenous variable declared in var_list. Results are stored in
% oo_.SpectralDensity and may be plotted. Plots are saved into the
% graphs-folder.
%
% INPUTS
% M_ [structure] Dynare's model structure
% oo_ [structure] Dynare's results structure
% options_ [structure] Dynare's options structure
% var_list [integer] Vector of indices for a subset of variables.
%
%
% OUTPUTS
% oo_ [structure] Dynare's results structure,
% containing the subfield
@ -17,9 +17,9 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
% and density, which are of size nvar*ngrid.
%
% 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.
%
@ -38,7 +38,7 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
if options_.order > 1
disp('UnivariateSpectralDensity :: I Cannot compute the theoretical spectral density')
disp('UnivariateSpectralDensity :: I Cannot compute the theoretical spectral density')
disp('with a second order approximation of the DSGE model!')
disp('Please set order = 1. I abort')
return
@ -102,7 +102,7 @@ if ~isempty(u)
ivar = oo_.dr.order_var(iky);
end
iky = iv(ivar);
iky = iv(ivar);
aa = ghx(iky,:);
bb = ghu(iky,:);
ngrid = options_.hp_ngrid; %number of grid points
@ -112,7 +112,7 @@ tneg = exp(-sqrt(-1)*freqs); %negative frequencies
if options_.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
filter_gain=ones(ngrid,1);
filter_gain=ones(ngrid,1);
elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.bandpass.indicator %filter with bandpass
filter_gain = zeros(1,ngrid);
lowest_periodicity=options_.bandpass.passband(2);
@ -122,7 +122,7 @@ elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.ba
filter_gain(freqs<=-2*pi/lowest_periodicity+2*pi & freqs>=-2*pi/highest_periodicity+2*pi)=1;
elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && ~options_.bandpass.indicator %filter with HP-filter
lambda = options_.hp_filter;
filter_gain = 4*lambda*(1 - cos(freqs)).^2 ./ (1 + 4*lambda*(1 - cos(freqs)).^2);
filter_gain = 4*lambda*(1 - cos(freqs)).^2 ./ (1 + 4*lambda*(1 - cos(freqs)).^2);
end
mathp_col = NaN(ngrid,length(ivar)^2);
@ -134,12 +134,12 @@ for ig = 1:ngrid
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
mathp_col(ig,:) = (f_hp(:))'; % store as matrix row
end;
end
f = zeros(nvar,ngrid);
for i=1:nvar
f(i,:) = real(mathp_col(:,(i-1)*nvar+i)); %read out spectral density
end
end
oo_.SpectralDensity.freqs=freqs;
oo_.SpectralDensity.density=f;
@ -159,12 +159,12 @@ if options_.nograph == 0
end
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)
xlabel('0 \leq \omega \leq \pi')
ylabel('f(\omega)')
box on
axis tight
dyn_saveas(hh,[M_.fname ,filesep,'graphs', filesep, 'SpectralDensity_' deblank(M_.endo_names(ivar(i),:))],options_)
axis tight
dyn_saveas(hh,[M_.fname ,filesep,'graphs', filesep, 'SpectralDensity_' deblank(M_.endo_names(ivar(i),:))],options_.nodisplay,options_.graph_format)
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_)
% 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
%nothing to add here
%nothing to add here
elseif ~options_.hp_filter && ~options_.one_sided_hp_filter && options_.bandpass.indicator
title = [title ' (Bandpass filter, (' ...
num2str(options_.bandpass.passband(1)),' ',num2str(options_.bandpass.passband(2)), '))'];
@ -10,6 +27,6 @@ elseif options_.hp_filter && ~options_.one_sided_hp_filter && ~options_.bandpas
num2str(options_.hp_filter) ')'];
elseif ~options_.hp_filter && options_.one_sided_hp_filter && ~options_.bandpass.indicator
title = [title ' (One-sided HP filter, lambda = ' ...
num2str(options_.one_sided_hp_filter) ')'];
num2str(options_.one_sided_hp_filter) ')'];
end
end

View File

@ -1,6 +1,6 @@
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.
%
@ -20,9 +20,13 @@ function mexpath = add_path_to_mex_files(dynareroot, modifypath)
if nargin<2
modifypath = true;
end
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
addpath(mexpath{1});
end
@ -48,7 +52,7 @@ else
end
end
else
tmp = [dynareroot '../mex/matlab/win64-7.8-9.1/'];
tmp = [dynareroot '../mex/matlab/win64-7.8-9.2/'];
if exist(tmp, 'dir')
mexpath = tmp;
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

@ -2,48 +2,48 @@ function [InnovationVariance,AutoregressiveParameters] = autoregressive_process_
% This function computes the parameters of an AR(p) process from the variance and the autocorrelation function
% (the first p terms) of this process.
%
% INPUTS
% INPUTS
% [1] Variance [double] scalar, variance of the variable.
% [2] Rho [double] p*1 vector, the autocorelation function: \rho(1), \rho(2), ..., \rho(p).
% [3] p [double] scalar, the number of lags in the AR process.
%
% OUTPUTS
% OUTPUTS
% [1] InnovationVariance [double] scalar, the variance of the innovation.
% [2] AutoregressiveParameters [double] p*1 vector of autoregressive parameters.
%
% NOTES
% NOTES
%
% The AR(p) model for {y_t} is:
%
% y_t = \phi_1 * y_{t-1} + \phi_2 * y_{t-2} + ... + \phi_p * y_{t-p} + e_t
%
% y_t = \phi_1 * y_{t-1} + \phi_2 * y_{t-2} + ... + \phi_p * y_{t-p} + e_t
%
% Let \gamma(0) and \rho(1), ..., \rho(2) be the variance and the autocorrelation function of {y_t}. This function
% compute the variance of {e_t} and the \phi_i (i=1,...,p) from the variance and the autocorrelation function of {y_t}.
% compute the variance of {e_t} and the \phi_i (i=1,...,p) from the variance and the autocorrelation function of {y_t}.
% We know that:
%
%
% \gamma(0) = \phi_1 \gamma(1) + ... + \phi_p \gamma(p) + \sigma^2
%
% where \sigma^2 is the variance of {e_t}. Equivalently we have:
%
% \sigma^2 = \gamma(0) (1-\rho(1)\phi_1 - ... - \rho(p)\phi_p)
% \sigma^2 = \gamma(0) (1-\rho(1)\phi_1 - ... - \rho(p)\phi_p)
%
% We also have for any integer h>0:
%
%
% \rho(h) = \phi_1 \rho(h-1) + ... + \phi_p \rho(h-p)
%
% We can write the equations for \rho(1), ..., \rho(p) using matrices. Let R be the p*p autocorelation
% matrix and v be the p*1 vector gathering the first p terms of the autocorrelation function. We have:
% matrix and v be the p*1 vector gathering the first p terms of the autocorrelation function. We have:
%
% v = R*PHI
%
%
% where PHI is a p*1 vector with the autoregressive parameters of the AR(p) process. We can recover the autoregressive
% parameters by inverting the autocorrelation matrix: PHI = inv(R)*v.
%
%
% This function first computes the vector PHI by inverting R and computes the variance of the innovation by evaluating
%
% \sigma^2 = \gamma(0)*(1-PHI'*v)
% Copyright (C) 2009 Dynare Team
% Copyright (C) 2009-2017 Dynare Team
%
% 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

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