# Implementation Details

This section describes important functions and implementation features in greater detail. Additional documentation can also be found in function documentation or in-line.

This section focuses on what the code does and why. Docstrings and the code itself (including comments) provide detailed information regarding *how* these basic procedures are implemented.

## The `AbstractModel`

Type

The `AbstractModel`

type provides a common interface for all model objects, which greatly facilitates the implementation of new model specifications. Any concrete subtype of `AbstractModel`

can be passed to any function defined for `AbstractModel`

, provided that the concrete type has the fields that the function expects to be available.

If a user wants to define a new subclass of models, say regression models, then the user could create a new `AbstractRegressionModel`

type as a subtype of `AbstractModel`

. Functions defined for `AbstractRegressionModel`

would only apply to concrete subtypes of `AbstractRegressionModel`

, but functions defined for `AbstractModel`

will still work on these concrete subtypes.

## The `AbstractParameter`

Type

The `AbstractParameter`

type implements our notion of a model parameter: a time-invariant, unobserved value that has significance in the model, e.g. for likelihood computation and estimation.

Though all parameters are time-invariant, they can have different features. Some parameters are scaled for use when solving the model^{[1]} and constructing the model's measurement equations^{[2]}.

During optimization, parameters may be transformed from model space to the real line via one of three different transformations: `Untransformed`

, `SquareRoot`

, and `Exponential`

. These transformations are also defined as types, and require additional information for each parameter. Typically, we have two "hyperparameters" for these transformations, `a`

, and `b`

.

`Untransformed`

:`a`

and`b`

do nothing`SquareRoot`

:`a`

and`b`

specify the bounds the parameter takes, i.e. $x\in (a, b)$`Exponential`

:`a`

and`b`

are the parameters in the transformation $a + exp(x - b)$

In some models, steady state values might be relevant parameters. They are typically functions of other parameters, so they do not need to be estimated directly.

While parameters are "time-invariant", we do allow regime switching. As an example, suppose that we have a linear regression with data from time periods $t = 1,\dots, T$, where $T > 4$, and in $t = 3$, the intercept of the regression is assumed to change values because of a structural break in the time series. We can model the intercept as a parameter with regime-switching. The parameter has one value in periods $t = 1, 2$ and a different value in periods $t = 3,\dots, T$. Currently, only regime-switching in the values of the parameter has been tested, but we have implemented regime switching in all the features. For example, you may want a different prior in each regime. See Regime-Switching Interface for documentation on the interface for regime-switching parameters.

The various requirements on parameters are nicely addressed using a parameterized type hierarchy.

`AbstractParameter{T<:Number}`

: The common abstract supertype for all parameters.`Parameter{T<:Number, U<:Transform}`

: The abstract supertype for parameters that are directly estimated.`UnscaledParameter{T<:Number, U:<Transform}`

: Concrete type for parameters that do not need to be scaled for equilibrium conditions.`ScaledParameter{T<:Number, U:<Transform}`

: Concrete type for parameters that are scaled for equilibrium conditions.

`SteadyStateParameter{T<:Number}`

: Concrete type for steady-state parameters.

All `Parameter`

s have the fields defined in `UnscaledParameter`

:

Missing docstring for `UnscaledParameter`

. Check Documenter's build log for details.

`ScaledParameters`

also have the following fields:

`scaledvalue::T`

: Parameter value scaled for use in`eqcond.jl`

`scaling::Function`

: Function used to scale parameter value for use in equilibrium conditions.

*Note:* Though not strictly necessary, defining a scaling with the parameter object allows for much a much cleaner definition of the equilibrium conditions.

Because the values of `SteadyStateParameter`

s are directly computed as a function of `ScaledParameter`

s and `UnscaledParameter`

s, they only require 4 fields:

`ModelConstructors.SteadyStateParameter`

— Type`SteadyStateParameter{T} <: AbstractParameter{T}`

Steady-state model parameter whose value depends upon the value of other (non-steady-state) `Parameter`

s. `SteadyStateParameter`

s must be constructed and added to an instance of a model object `m`

after all other model `Parameter`

s have been defined. Once added to `m`

, `SteadyStateParameter`

s are stored in `m.steady_state`

. Their values are calculated and set by `steadystate!(m)`

, rather than being estimated directly. `SteadyStateParameter`

s do not require transformations from the model space to the real line or scalings for use in equilibrium conditions.

**Fields**

`key::Symbol`

: Parameter name. Should conform to the guidelines established in the DSGE Style Guide.`value::T`

: The parameter's steady-state value.`description::String`

: Short description of the parameter's economic significance.`tex_label::String`

: String for printing parameter name to LaTeX.

## The `Observable`

and `PseudoObservable`

Types

We similarly encapsulate information about observables and pseudo-observables (unobserved linear combinations of states, e.g. the output gap) into the `Observable`

and `PseudoObservable`

types. Each type has identifier fields `key`

, `name`

, and `longname`

.

Most importantly, both `Observable`

s and `PseudoObservable`

s include the information needed for transformations to and from model units. For `Observable`

s, these are the `input_series`

, `fwd_transform`

, and `rev_transform`

fields. "Forward transformations" are applied to transform the raw input data series specified in `input_series`

to model units. The model is estimated and forecasted in model units, and then we apply "reverse transformations" to get human-readable units before computing means and bands or plotting. Pseudo-observables are not observed, so they do not have `input_series`

or `fwd_transform`

s, but they may however have `rev_transform`

s.

As an example, the `:obs_gdp`

`Observable`

uses as `input_series`

aggregate nominal GDP in levels, the GDP price index, and population in levels, all from FRED.^{[3]} These series are `fwd_transform`

ed to get quarter-over-quarter log growth rates of per-capita real GDP, which are the `Observable`

's model units. The reverse transformation then converts `:obs_gdp`

into annualized quarter-over-quarter percent changes of *aggregate* real GDP.

`ModelConstructors.Observable`

— Type`mutable struct Observable`

**Fields**

`key::Symbol`

`input_series::Vector{Symbol}`

: vector of mnemonics, each in the form`:MNEMONIC__SOURCE`

(e.g.`:GDP__FRED`

). This vector is parsed to determine source (e.g. per-capita consumption gets population and consumption).`fwd_transform::Function`

: Extracts appropriate`input_series`

from a DataFrame of levels, and transforms data to model units (for example, computes per-capita growth rates from levels).`rev_transform::Function`

: Transforms a series from model units into observable units. May take kwargs.`name::String`

: e.g. "Real GDP growth"`longname::String`

: e.g. "Real GDP growth per capita"

`ModelConstructors.PseudoObservable`

— Type`mutable struct PseudoObservable`

**Fields**

`key::Symbol`

`name::String`

: e.g. "Flexible Output Growth"`longname::String`

: e.g. "Output that would prevail in a flexible-price economy"`rev_transform::Function`

: Transforms a series from model units into observable units. May take kwargs.

## Model Settings

The `Setting`

type implements computational settings that affect how the code runs without affecting the mathematical definition of the model. Depending on the model, these may include flags (e.g. whether or not to recompute the Hessian), parameterization for the Metropolis-Hastings algorithm (e.g. number of times to draw from the posterior distribution), and the vintage of data being used (`Setting`

is a parametric type - a `Setting{T<:Any}`

, so Booleans, Numbers, and Strings can all be turned into `Setting`

s). If settings exist for a model type, then they should be stored centrally in the `settings`

dictionary within the model object.

Why implement a `Setting`

type when we could put their values directly into the source code or dictionary? The most obvious answer is that the parametric type allows us to implement a single interface for all `Setting`

s (Booleans, Strings, etc.), so that when we access a particular setting during the estimation and forecast steps, we don't have to think about the setting's type.

`Setting`

s play an important role in addition to providing useful abstraction. Estimating and forecasting the New York Fed DSGE model takes many hours of computation time and creates a lot of output files. It is useful to be able to compare model output from two different models whose settings differ slightly (for example, consider two identical models that use different vintages of data as input). A central feature of the `Setting`

type is a mechanism that generates unique, meaningful filenames when code is executed with different settings. Specifically, when a setting takes on a non-default value, a user-defined setting code (along with the setting's value) are appended to all output files generated during execution.

The `Setting{T<:Any}`

type is defined as follows:

`ModelConstructors.Setting`

— Type`Setting{T}`

The `Setting`

type is an interface for computational settings that affect how the code runs without affecting the mathematical definition of the model. It also provides support for non-conflicting file names for output of 2 models that differ only in the values of their computational settings.

**Fields**

`key::Symbol`

: Name of setting`value::T`

: Value of setting`print::Bool`

: Indicates whether to append this setting's code and value to output file names. If true, output file names will include a suffix of the form`_code1=val1_code2=val2`

etc. where codes are listed in alphabetical order.`code::String`

: string to print to output file suffixes when`print=true`

.`description::String`

: Short description of what the setting is used for.

We provide two functions `default_settings!`

and `default_test_settings!`

to initialize settings that most models can have. The settings are

- save root
- input data root
- vintage of data to be used
- dataset id

To update the value of an existing function, the user has two options. First, the user may use the `<=`

syntax. However, for this to work properly, it is essential that the setting's `key`

field be exactly the same as that of an existing entry in `m.settings`

. Otherwise, an additional entry will be added to `m.settings`

and the old setting will be the one accessed from other all routines. A potentially safer, though clunkier, option is to use the `update!`

method.

## Type Interfaces

`Parameter`

Interface

`Base.rand`

— Method```
Distributions.rand(p::Vector{AbstractParameter{Float64}}, n::Int;
regime_switching::Bool = false, toggle::Bool = true)
```

Generate `n`

draws from the priors of each parameter in `p`

.This returns a matrix of size `(length(p),n)`

, where each column is a sample. To sample from `p`

when it has regime-switching, set `regime_switching = true`

. The `toggle`

keyword is only relevant for regime-switching sampling. Please see `?ModelConstructors.rand_regime_switching`

.

`Base.rand`

— Method```
Distributions.rand(p::Vector{AbstractParameter{Float64}}; regime_switching::Bool = false,
toggle::Bool = true)
```

Generate a draw from the prior of each parameter in `p`

.

`ModelConstructors.differentiate_transform_to_model_space`

— Method`differentiate_transform_to_model_space{S<:Real,T<:Number, U<:Transform}(p::Parameter{S,T,U}, x::S)`

Differentiates the transform of `x`

from the real line to lie between `p.valuebounds`

The transformations are defined as follows, where (a,b) = p.transform_parameterization and c a scalar (default=1):

- Untransformed:
`x`

- SquareRoot:
`(a+b)/2 + (b-a)/2 * c * x/sqrt(1 + c^2 * x^2)`

- Exponential:
`a + exp(c*(x-b))`

Their gradients are therefore

- Untransformed:
`1`

- SquareRoot:
`(b-a)/2 * c / (1 + c^2 * x^2)^(3/2)`

- Exponential:
`c * exp(c*(x-b))`

`ModelConstructors.differentiate_transform_to_real_line`

— Method`differentiate_transform_to_real_line{S<:Real,T<:Number, U<:Transform}(p::Parameter{S,T,U}, x::S)`

Differentiates the transform of `x`

from the model space lying between `p.valuebounds`

to the real line. The transformations are defined as follows, where (a,b) = p.transform_parameterization and c a scalar (default=1):

- Untransformed: x
- SquareRoot: (1/c)*cx/sqrt(1 - cx^2), where cx = 2 * (x - (a+b)/2)/(b-a)
- Exponential: b + (1 / c) * log(x-a)

Their gradients are therefore

- Untransformed:
`1`

- SquareRoot:
`(1/c) * (1 / ( 1 - cx^2)^(-3/2)) * (2/(b-a))`

- Exponential:
`1 / (c * (x - a))`

`ModelConstructors.moments`

— Method`moments(θ::Parameter)`

If θ's prior is a `RootInverseGamma`

, τ and ν. Otherwise, returns the mean and standard deviation of the prior. If θ is fixed, returns `(θ.value, 0.0)`

.

`ModelConstructors.n_parameters_regime_switching`

— Method`function n_parameters_regime_switching(p::ParameterVector)`

calculates the total number of parameters in `p`

across all regimes.

`ModelConstructors.parameter`

— Method`parameter(p::ScaledParameter{S,T,U}, newvalue::S) where {S<:Real, T<:Number,U<:Transform}`

Returns a ScaledParameter with value field equal to `newvalue`

and scaledvalue field equal to `p.scaling(newvalue)`

. If `p`

is a fixed parameter, it is returned unchanged.

`ModelConstructors.parameter`

— Method`parameter(p::UnscaledParameter{S,T,U}, newvalue::S) where {S<:Real,T<:Number,U<:Transform}`

Returns an UnscaledParameter with value field equal to `newvalue`

. If `p`

is a fixed parameter, it is returned unchanged.

`ModelConstructors.parameter`

— Method```
parameter{S,T,U<:Transform}(key::Symbol, value::S, valuebounds = (value,value),
transform_parameterization = (value,value),
transform = Untransformed(), prior = NullablePrior();
fixed = true, scaling::Function = identity, description = "",
tex_label::String = "")
```

By default, returns a fixed `UnscaledParameter`

object with key `key`

and value `value`

. If `scaling`

is given, a `ScaledParameter`

object is returned.

`ModelConstructors.transform_to_model_space`

— Method`transform_to_model_space{S<:Real,T<:Number, U<:Transform}(p::Parameter{S,T,U}, x::S)`

Transforms `x`

from the real line to lie between `p.valuebounds`

without updating `p.value`

. The transformations are defined as follows, where (a,b) = p.transform_parameterization and c a scalar (default=1):

- Untransformed:
`x`

- SquareRoot:
`(a+b)/2 + (b-a)/2 * c * x/sqrt(1 + c^2 * x^2)`

- Exponential:
`a + exp(c*(x-b))`

`ModelConstructors.transform_to_real_line`

— Method`transform_to_real_line(p::Parameter{S,T,U}, x::S = p.value) where {S<:Real, T<:Number, U<:Transform}`

Transforms `p.value`

from model space (between `p.valuebounds`

) to the real line, without updating `p.value`

. The transformations are defined as follows, where (a,b) = p.transform_parameterization, c a scalar (default=1), and x = p.value:

- Untransformed: x
- SquareRoot: (1/c)*cx/sqrt(1 - cx^2), where cx = 2 * (x - (a+b)/2)/(b-a)
- Exponential: b + (1 / c) * log(x-a)

`ModelConstructors.update!`

— Method```
update!(pvec::ParameterVector, values::Vector{S},
indices::BitArray{1}; change_value_type::Bool = false) where S
```

Updates a subset of parameters in `pvec`

specified by indices. Assumes `values`

is sorted in the same order as the parameters in `pvec`

, ignoring parameters that are to be left unchanged.

However, `update!`

will not overwrite fixed parameters, even if `indices`

has a true in an index corresponding to a fixed parameter.

**Examples**

```
julia> pvec = ParameterVector{Float64}(undef, 3);
julia> pvec[1] = parameter(:a, 1., (0., 3.), (0., 3.), fixed = false);
julia> pvec[2] = parameter(:b, 1.);
julia> pvec[3] = parameter(:c, 1., (0., 3.), (0., 3.), fixed = false);
julia> values = [2., 2.];
julia> update!(pvec, values, [true, false, true]);
julia> map(x -> x.value, pvec)
3-element Array{Float64,1}:
2.0
1.0
2.0
```

```
julia> pvec = ParameterVector{Float64}(undef, 3);
julia> pvec[1] = parameter(:a, 1.);
julia> pvec[2] = parameter(:b, 1.);
julia> pvec[3] = parameter(:c, 1.);
julia> values = [2., 2.];
julia> update!(pvec, values, [true, false, true]);
julia> map(x -> x.value, pvec)
3-element Array{Float64,1}:
1.0
1.0
1.0
```

`ModelConstructors.update!`

— Method`update!(pvec::ParameterVector, values::Vector{S}; change_value_type::Bool = false) where S`

Update all parameters in `pvec`

that are not fixed with `values`

. Length of `values`

must equal length of `pvec`

. Function optimized for speed.

`ModelConstructors.update`

— Method`update(pvec::ParameterVector, values::Vector{S}) where S`

Returns a copy of `pvec`

where non-fixed parameter values are updated to `values`

. `pvec`

remains unchanged. Length of `values`

must equal length of `pvec`

.

We define the non-mutating version like this because we need the type stability of map!

`ModelConstructors.parameters2namedtuple`

— Method`parameters2namedtuple(m)`

returns the parameters of `m`

as a `NamedTuple`

. The input `m`

can be either an `AbstractVector{<: AbstractParameter}`

or an `AbstractModel`

.

`ModelConstructors.rand_regime_switching`

— Method`rand_regime_switching(p::Vector{AbstractParameter{Float64}}; toggle::Bool = true)`

Generate a draw from the prior of each parameter in `p`

.

### Regime-Switching Interface

To implement regime-switching, we add a field to `Parameter`

types called `regimes::Dict{Symbol, OrderedDict{Int, Any}}`

. The keys of the top level dictionary are the names of the other fields in a `Parameter`

type, e.g. `:value`

. Each key then points to an `OrderedDict`

, whose keys are the numbers of different regimes and values are the corresponding values for each regime.

The field `regimes`

functions as a "storage" of information. When a `Parameter`

type interacts with another object in Julia, e.g. `p + 1.`

, where `p`

is a `Parameter`

, what actually happens is `p.value + 1.`

. Only the current fields of `p`

will be used when interacting with other objects. To use a different value (or different fields) from another regime, the user needs to tell the parameter to switch regimes the `toggle_regime!`

function (see below).

By default, the `regimes`

field is empty (see the documentation of the `parameter`

function in `Parameter`

Interface). To add values, either pass in the dictionary as a keyword to `parameter`

or use `set_regime_val!`

. Note that the latter function is not exported.

*Note that regimes must be sorted in order* because we store the regimes as an `OrderedDict`

, and `OrderedDict`

objects are sorted by insertion order.

`ModelConstructors.regime_fixed`

— Method```
regime_fixed(p::Parameter{S}, i::Int) where S <: Real
regime_fixed(p::Parameter{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
```

returns whether `p`

is fixed in regime `i`

for the first method and whether true `p`

is fixed in regime `d[model_regime]`

for the second method.

`ModelConstructors.regime_prior`

— Method```
regime_prior(p::Parameter{S}, i::Int) where S <: Real
regime_prior(p::Parameter{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
```

returns the prior of `p`

in regime `i`

for the first method and the prior of `p`

in regime `d[model_regime]`

for the second.

`ModelConstructors.regime_val`

— Method```
regime_val(p::Parameter{S}, i::Int) where S <: Real
regime_val(p::Parameter{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
```

returns the value of `p`

in regime `i`

for the first method and the value of `p`

in regime `d[model_regime`

for the second.

`ModelConstructors.regime_valuebounds`

— Method```
regime_valuebounds(p::Parameter{S}, i::Int) where S <: Real
regime_valuebounds(p::Parameter{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
```

returns the `valuebounds`

of `p`

in regime `i`

for the first method and the `valuebounds`

of `p`

in regime `d[model_regime]`

for the second method.

`ModelConstructors.set_regime_fixed!`

— Method`set_regime_fixed!(p::Parameter{S}, i::Int, v::S; update_valuebounds::Interval = (NaN, NaN))`

sets whether `p`

is fixed in regime `i`

of `p`

. Set update_valuebounds to true to set the valuebounds to match the fixed value.

The second method allows the user to pass a dictionary to permit the case where there may be differences between the regimes of a regime-switching model and the regimes for the parameters. For example, aside from regime-switching in parameters, the model may also include other forms of regime-switching. To allow estimation of regime-switching parameters in such a model, the dictionary `d`

maps each "model" regime to a "parameter" regime. In this way, the second method specifies which "parameter" regime should be used at a given "model" regime.

`ModelConstructors.set_regime_prior!`

— Method```
set_regime_prior!(p::Parameter{S}, i::Int, v)
set_regime_prior!(p::Parameter{S}, model_regime::Int, v, d::AbstractDict{Int, Int})
```

sets the prior in regime `i`

of `p`

to be `v`

. The type of `v`

can be a `NullablePriorUnivariate`

, `NullablePriorMultivariate`

, `ContinuousUnivariateDistribution`

, or `ContinuousMultivariateDistribution'.

The second method allows the user to pass a dictionary to permit the case where there may be differences between the regimes of a regime-switching model and the regimes for the parameters. For example, aside from regime-switching in parameters, the model may also include other forms of regime-switching. To allow estimation of regime-switching parameters in such a model, the dictionary `d`

maps each "model" regime to a "parameter" regime. In this way, the second method specifies which "parameter" regime should be used at a given "model" regime.

`ModelConstructors.set_regime_val!`

— Method```
set_regime_val!(p::Parameter{S},
i::Int, v::S; override_bounds::Bool = false) where S <: Real
set_regime_val!(p::Parameter{S},
model_regime::Int, v::S, d::AbstractDict{Int, Int}; override_bounds::Bool = false) where S <: Real
```

sets the value in regime `i`

of `p`

to be `v`

. By default, we enforce the bounds that are currently in `p`

, but the bounds can be ignoerd by setting `override_bounds = true`

.

The second method allows the user to pass a dictionary to permit the case where there may be differences between the regimes of a regime-switching model and the regimes for the parameters. For example, aside from regime-switching in parameters, the model may also include other forms of regime-switching. To allow estimation of regime-switching parameters in such a model, the dictionary `d`

maps each "model" regime to a "parameter" regime. In this way, the second method specifies which "parameter" regime should be used at a given "model" regime.

`ModelConstructors.set_regime_valuebounds!`

— Method`set_regime_valuebounds!(p::Parameter{S}, i::Int, v::S)`

sets valuebounds for `p`

in regime `i`

to `v`

.

`d`

maps each "model" regime to a "parameter" regime. In this way, the second method specifies which "parameter" regime should be used at a given "model" regime.

`ModelConstructors.toggle_regime!`

— Method```
toggle_regime!(p::Parameter{S}, i::Int) where S <: Real
toggle_regime!(pvec::ParameterVector{S}, i::Int) where S <: Real
toggle_regime!(p::Parameter{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
toggle_regime!(pvec::ParameterVector{S}, model_regime::Int, d::AbstractDict{Symbol, <: AbstractDict{Int, Int}}) where S <: Real
toggle_regime!(pvec::ParameterVector{S}, model_regime::Int, d::AbstractDict{Int, Int}) where S <: Real
```

changes the fields of `p`

to regime `i`

.

For example, if

`p.regimes[:value] = OrderedDict{Int, Any}(1 => 1, 2 => 3)`

then `toggle_regime!(p, 1)`

will cause `p.value = 1`

and `toggle_regime!(p, 2)`

will cause `p.value = 3`

.

The third method allows the user to pass a dictionary to permit the case where there may be differences between the regimes of a regime-switching model and the regimes for the parameters. For example, aside from regime-switching in parameters, the model may also include other forms of regime-switching. To allow estimation of regime-switching parameters in such a model, the dictionary `d`

maps each "model" regime to a "parameter" regime. In this way, the second method specifies which "parameter" regime should be used at a given "model" regime.

The fourth method extends the third to a ParameterVector, with the possibility that each parameter may have different mappings to the model regimes. Each key of `d`

corresponds to the key of a parameter, and each value of `d`

is the mapping for model regimes to the parameter regimes of `p.key`

. The fifth method is similar to the fourth but assumes any regime-switching parameter has the same mapping from model regimes to parameter regimes, hence the use of a common dictionary.

`ModelConstructors.get_values`

— Method`get_values(pvec::ParameterVector{S}; regime_switching::Bool = true) where {S <: Real}`

constructs a vector of the underlying values in a `ParameterVector`

, including if there are regime-switching values.

`Setting`

Interface

`Base.:<=`

— Method`(<=)(m::AbstractModel, s::Setting)`

Syntax for adding a setting to a model/overwriting a setting via `m <= Setting(...)`

`ModelConstructors.get_setting`

— Method`get_setting(m::AbstractModel, setting::Symbol)`

Returns the value of the setting

`ModelConstructors.update!`

— Method`update!(a::Setting, b::Setting)`

Update `a`

with the fields of `b`

if:

- The
`key`

field is updated if`a.key == b.key`

- The
`print`

boolean and`code`

string are overwritten if`a.print`

is false and`b.print`

is true, or`a.print`

is true,`b.print`

is false, and b.code is non-empty. - The
`description`

field is updated if`b.description`

is nonempty

```
rng::MersenneTwister
testing::Bool
observable_mappings::Dict{Symbol, Observable}
pseudo_observable_mappings::Dict{Symbol, PseudoObservable}
```

- 1By solving the model, we mean a mapping from parameters to some objects of interest. In a state space model, solving the model is a mapping from parameters to a state transition function. By constructing
- 2In the context of a state space model, a measurement equation is mapping from states to observable data.
- 3In DSGE.jl, we implement a
`load_data`

function that parses`input_series`

to retrieve data from FRED. To take full advantage of the`Observable`

type, users may want to write their own`load_data`

function. For example, it may be convenient to write a`load_data`

function that parses`input_series`

to select column(s) from saved CSV files and combines them into a single data frame.