The package TransmissionChannelAnalysis.jl provides functionns for TCA in Julia. It is to date the most advanced of the packages, allowing for all kinds of transmission channels. However, implementing more advanced trasnmission channels requires the use of more advanced methods within the package. For most users and for most applications, the basic funcionality is sufficient. This basic functionality will be documented first, with some more advanced features discussed later.
Contributer Information
For interested contributers or others interested in the internals of TransmissionChannelAnalysis.jl please have a look at the explanation of the internals.
Defining Simple Transmission Channels
Two helper functions are provided that allow for the definition of transmission channels without having to use the more advanced methods. These are through and not_throug. As the names hint at, through is used to define a channel that must go through certain variables in certain periods, while not_through is used to define a transmission channel that cannot go through certain variables in all defined periods.
through
through(idx, horizons, order) --> Q
All paths must go through variables in idx in periods horizons. Note, this uses the dynamic system notation y such that idx refers to the index of the variable in the original dynamic system, i.e. in the SVARMA.
Arguments
For the single variable version:
idx::Int: Index of variable through which the paths should go. This is the original index in the dynamic system, e.g. the SVAR, before applying the transmission matrix.
horizons::AbstractVector{<:Int}: Horizons for which the paths must go through the variable.
order::AbstractVector{<:Int}: Variable ordering determined by the transmission matrix
For the multiple variable version:
idx::AbstractVector{<:Int}: Indices of variables through which the paths should go. These are the original indices in the dynamic system, e.g. the SVAR, before applying the transmission matrix.
horizons::Union{AbstractVector{<:Int},Vector{AbstractVector{<:Int}}}: Horizons for which the paths must go through the variable. Must either be a vector for each variable in idx or a single vector. If it is a single vector, then the horizons will be applied to each variable in idx.
order::AbstractVector{<:Int}: Variable ordering determined by the transmission matrix
Returns
Returns a transmission condition Q.
Notes
The transmission effect can be calculated using transmission.
Examples
Suppose we are interested in the contemporaneous channel in Section 5.1 of Wegner et al (2024), i.e. we are interested in the effect going through the federal funds rate contemporaneously. In our estimated model, the federal funds rate is the first variable. We would thus define the contemporaneous channe```{julia}s
contemporaneous_channel =through(1, [0], 1:4) # we have four variables with ffr being first
More generally, we could define the following, which would be the effect through the federal funds rate in the first t```{julia}periods.
q =through(1, [0, 1], 1:4)
The following is also allowed which is the effect through the federal funds rate contemporaneously and one period later, and through the output gap contemporaneously and one period later, where the federal funds rate is ordered first and the ```{julia}put gap second.
q =through([1, 2], [[0, 1], [0, 1]], 1:4)
If we want to re-order the federal funds rate after the output gap, we simply change the ordering to [2, 1, 3, 4] where 2 corresponds to the output gap ```{julia}the original ordering.
Define a transmission channel through variables for horizons. Contrary to the other through methods, variables and order are defined using the variable names of the model – other through methods use indices.
not_through
not_through(idx, horizons, order) --> Q
All paths cannot go through variables in idx in periods horizons. Note, this uses the dynamic system notation y such that idx refers to the index of the variable in the original dynamic system, i.e. in the SVARMA.
Arguments
For the single variable version:
idx::Int: Index of variable through which the paths cannot go. This is the original index in the dynamic system, e.g. the SVAR, before applying the transmission matrix.
horizons::AbstractVector{<:Int}: Horizons for which the paths cannot go through the variable.
order::AbstractVector{<:Int}: Variable ordering determined by the transmission matrix
For the multiple variable version:
idx::AbstractVector{<:Int}: Indices of variables through which the paths cannot go. These are the original indices in the dynamic system, e.g. the SVAR, before applying the transmission matrix.
horizons::Union{AbstractVector{<:Int},Vector{AbstractVector{<:Int}}}: Horizons for which the paths cannot go through the variable. Must either be a vector for each variable in idx or a single vector. If it is a single vector, then the horizons will be applied to each variable in idx.
order::AbstractVector{<:Int}: Variable ordering determined by the transmission matrix
Returns
Returns a transmission condition Q.
Notes
The transmission effect can be calculated using transmission.
Examples
The non-contemporaneous channel of monetary policy is defined in Section 5.1 of Wegner et al (2024) as the effect not going through a contemporaneous adjustment of the federal funds rate, where the transmission matrix orders the federal funds rate first. Thus, if the original SVAR has the federal funds rate ordered first, the non-contemporaneous effect can be obtained in the following ```{julia}.
q =not_through(1, [0], 1:4)
Similarly, Wegner et al (2024) define the anticipation channel of government defense spending as the effect not going through government defense spending. With government defense spending ordered second in the VAR, the following can be used to obtain the anticipati```{julia}channel.
Define a transmission channel not through variables for horizons. Contrary to the other not_through methods, variables and order are defined using the variable names of the model – other not_through methods use indices.
Both through and not_through return a transmission condition Q, which is simply an internal representation of the provided transmission channel (represented as Boolean statements). To double check whether the condition represents the desired channel, simply run Q in the REPL, which will display the internal representation using the systems form and thus using the variable notation \(x\). Alternatively, show_y or @show_y can be used to display the internal representation in the dynamic form and thus using the variable notation \(y\).
Conditions created using through and not_through can be combined using AND (&), OR (|) and NOT (!). Every new combination will return a new condition that combines the previous conditions. The returned conditions can again be combined using AND, OR, and NOT. For example, if q1, q2 and q3 are conditions obtained using through or not_through, then the following works.
This functionality allows definitions of transmission channels that are not easily defined using through and not_through. For example, if we were interested in the transmission channel that goes through \(y_{1,0}\) OR through \(y_{1,1}\), then neither of the helper functions can be used, since neither can handle OR statements. However, we can use Boolean logic and the rules for the manipulation of transmission conditions to define this transmission channel using our helper functions.
In most cases, the easiest step is to negate the original condition. The above condition can be succintly be represented as \[
y_{1,0} \lor y_{1,1}.
\] The negated statement is thus \[
\neg y_{1,0} \land \neg y_{1,1}.
\] This can be defined using not_through in the following way
q =not_through(1, [0,1], 1:n)
where we assumed that the transmission matrix is the identity matrix, implying an ordering 1:n.
To obtain the original transmission channel, we can simply negate this condition.
original_condition = !q
Defining Complex Transmission Channels
Although through and not_through are sufficient for many situations, it is still sometimes more convenient to directly define the transmission channel as a Boolean condition withough having to refer back to though and not_through.
Say, for example, we are again interested in the transmission channel going through y_{1,0} OR y_{1,1}. Instead of using the approach of first negating the statement, then using not_through, just to negate this statement again, we may as well just define the condition directly using the more advanced functionality of TransmissionChannelAnalysis.jl.
The advanced functionality simply takes a String that defines the transmission channel as a Boolean condition. The string can either be defined using the variables of the dynamic form\(y\) or the variables using the systems form\(x\). In the former case, the ordering defined by the transmission matrix must also be defined. In either case, make_condition is used.
Make a transmission condition, i.e. Q(b), out of a string.
Transmission channels are described using Boolean statements involving the variables in the dynamic model. make_condition allows for specifying these Boolean conditions as a string which is then converted to an internal representation allowing the computation of transmission channels.
Two ways of specifying the Boolean conditions exist:
make_condition(s::String) takes the Boolean condition in the systems form of Wegner et al (2024), i.e. variables must start with x followed by a number. For example, given a three variable VAR(1), y_{1,t} -> x_1, y_{2, t} -> x_2, y_{3, t} -> x_3, y_{1, t+1} -> x_4, y_{2, t+1} -> x_5, … Boolean statements then involve expressions in the x variables and define which paths can be taken. Each path involved in the transmission mechanism must satisfy the Boolean statement.
make_condition(s_y::String, order::AbstractVector{<:Int}) does the same as the first method, however the Boolean condition can be specified using the variables of the dynamic systems, i.e. y. Variables must then be specified using y_{i,t} where i is the variable number and t is the period. At all times t >= 0 with 0 denoting the contemporaneous horizon.
Arguments
s::String: A Boolean statement given as a string. Variables must start with x for them to be valid variables.
s_y::String: A Boolean statement given as a string. Variabls must have the form y_{i,t} where i is the variable number and t >= 0 is the time period. t=0 corresponds to the contemporaneous horizon.
order::AbstractVector{<:Int}: The variable ordering defined by the transmission matrix.
Boolean conditions can consist of AND (&), NOT (!), OR (|), and parentheses.
The resulting transmission condition can be used in transmission to calculate the transmission effect.
So, to define the transmission channel that goes through y_{1,0} OR through \(y_{1,1}\) with an identity transmission matrix, we can do either of the following.
# Note, we assume 4 variables in the system. q =make_condition("y_{1,0} | y_{1,1}", 1:4)# With an identity transmission matrix, y_{1,0} -> x1# and y_{1,1} -> x5 if the transmission matrix# is the identity matrix.q =make_condition("x1 | x5")
Computing Transmission Effects
Transmission effects, i.e. the effect through the transmission channel, can be computed in one of two ways in TransmissionChannelAnalysis.jl. The first way is to use the systems form to compute the transmission effect. The second way exploits the sufficiency of impulse response functions (IRFs)1 and uses these to compute the effects. The following sections describe both methods.
Preparing the Systems Form
The systems form can be used whenever a SVAR(MA) was estimated and the AR and MA coefficients are available. The first step then consists of transforming the dynamic form of the SVAR(MA) into the systems form. We provide the utility function make_systems_form for this purpose.
Transform an SVARMA dynamic model into the systems representation \(x = Bx + Omega\varepsilon\).
Arguments
Phi0::AbstractMatrix: The matrix of contemporaneous structural impulse responses.
As::Vector{<:AbstractMatrix}: A vector of reduced-form autoregressive (AR). First entry corresponds to the AR matrix for the first lag, etc.
Psis::Vector{<:AbstractMatrix}: A vector of reduced-form moving average (MA) matrices. First index corresponds to the first lag, etc.
Sigma::AbstractMatrix{<:Real}: The covariance matrix of reduced-form errors.
order::AbstractVector{<:Int}: The vector indicating the order of variables, typically determined by the transmission matrix.
max_horizon::Int: The maximum time horizon to consider for the systems model, with 0 representing the contemporaneous period.
Returns
(B, Omega) with the meaning being the same as in Wegner et al (2024).
Notes
Use make_B and make_Omega to construct the two matrices seperately.
The returned systems form can then be used in transmission to compute the trasnmission effect.
Besides make_systems_form we also offer the two separate functions make_B and make_Omega which respectively create \(B\) and \(\Omega\) of the systems form. Use of these two functions should most of the time not be required. However, for users that might want to research of TCA, having access to these two methods seperately can be helpful.
make_B
Construct B of the systems representation \(x = Bx + Omega\varepsilon\).
Notes
See make_systems_form for further information.
make_Omega
Construct Omega of the systems representation \(x = Bx + Omega\varepsilon\).
Notes
See make_systems_form for further information.
Preparing the IRFs
Estimating the transmission effects using IRFs requires Cholesky / orthogonalised IRFs for all variables, as well as the structural shocks impulse response functions. In either case, TransmissionChannelAnalysis.jl works internally with a matrix representation of IRFs. Since many software solutions for SVAR(MA) return IRFs in the form of three-dimensional arrays, we provide the utility function to_transmission_irfs that transforms the three-dimensional arrays into a matrix of IRFs.
to_transmission_irfs
to_transmission_irfs(irfs::AbstractArray{T, 3})
Transform a standard three dimensional IRF array into a IRF matrix. The
Arguments
irfs::AbstractArray{T, 3}: IRF Array of dimension nvariabels × nshocks × n_horizons with the first horizons corresponding to horizon 0.
Returns
Matrix{T} of dimension (nvariables nhorizons) × (nvariables * n*horizons). This is the same as what would be obtained via \((I-B)^{-1}\mathbb{Q}\) using the notation of Wegner et al (2024).
to_transmission_irfs should be applied to both the Cholesky / orthogonalised and the structural IRFs. The resulting IRFs can then be used in transmission to compute the transmission effects.
Computing
With either the IRFs or the systems form prepared, transmission effects can be computed using any of the following versions of the transmission function. In either case, the fourth argument to transmission must be a transmission condition that can be obtained in any of the ways described above.
To compute transmission effects using the systems form, method should be set equal to :BOmega. Similarly, to use IRFs, method should be set equal to :irfs. The default is set to :BOmega and thus, if not further specified, TransmissionChannelAnalysis.jl assumes that the systems form is being used. This choice was mostly made because the computations under the systems form are faster than the computations using IRFs.
transmission
transmission(from::Int, arr1::AbstractMatrix{T}, arr2::AbstractMatrix{T}, q::Q; method = :BOmega) where {T}
Given a transmission condition q, calculate the transmission effect using the either the :BOmega method (the default), or the :irfs method.
Arguments
from::Int: Shock number.
arr1::AbstractMatrix{T}. In case of :BOmega this must be B, in case of :irfs this must be irfs. See the documentation for the specific methods for transmission(..., ::Type{Val{:BOmega}}) and transmission(...,::Type{Val{:irfs}}).
arr2::AbstractMatrix{T}: In case of :BOmega this must be Omega, in case of :irfs this must be irfs_ortho. See the documentation for the specific methods for transmission(..., ::Type{Val{:BOmega}}) and transmission(...,::Type{Val{:irfs}}).
method::Symbol: Either :BOmega in which case the transmission effect will be calculated using the second method in Wegner et al (2024), or :irfs in which case the transmission effect is calculated using the first method in Wegner et al (2024).
Returns
Returns a Vector{T} with entry i corresponding to the transmission effect on variable \(x_i\). If \(x_k\) is the variable in the transmission condition with the highest subscript, then all entries in the returned vector with index less thatn k are NaN since interpretation of those results is nonsensical.
transmission(
from::Int,
B::AbstractMatrix{T},
Omega::AbstractMatrix{T},
q::Q,
::Type{Val{:BOmega}}
) where {T}
Given a transmission condition q, calculate the transmission effect using the :BOmega method.
Arguments
from::Int: Shock number.
B::AbstractMatrix{T}: Part of the systems representation in Wegner et al (2024).
Omega::AbstractMatrix{T}: Part of the systems representation in Wegner et al (2024).
q::Q: A transmission condition. See also Q.
Returns
Returns a Vector{T} with entry i corresponding to the transmission effect on variable \(x_i\). If \(x_k\) is the variable in the transmission condition with the highest subscript, then all entries in the returned vector with index less thatn k are NaN since interpretation of those results is nonsensical.
Returns a Vector{T} with entry i corresponding to the transmission effect on variable \(x_i\). If \(x_k\) is the variable in the transmission condition with the highest subscript, then all entries in the returned vector with index less thatn k are NaN since interpretation of those results is nonsensical.
Compute the transmission effect of a transmission channel defined by the condition q. If model is a reduced-form model, method will be used to identify the required structural shock.
Arguments
model::Model: A model, such as an SVAR, VAR, or LP.
method::AbstractIdentificationMethod: An identification method to identify the from-th structural shock.
from::Int: Shock number.
q::Q: A transmission condition. See also Q and make_condition.
order::AbnstractVector{<:Int}: order of variables defined by the transmission matrix using variable indices.
order::AbnstractVector{Symbol}: order of variables defined by the transmission matrix using variable names.
max_horizon::Int: Maximum horizon for the transmission effect.
Returns
Returns a three dimensional array with the first dimension correspondin to the endogenous variables (in original order), the second to the shock, and the third to the horizon (from 0 to max_horizon).
It may occur that a transmission condition contains a contradiction, i.e. a part of the boolean conditions says \(x_i \land \neg x_i\). These are usually automatically removed internally. However, this automatic removal can sometimes lengthen the time it takes for the condition to compile. We therefore offer the utility function set_remove_contradictions that can be used to turn this off. Even if off, the resulting transmission effect will be correct, but the computation may take a bit longer. Thus, there is a trade-off between longer compile times (if contradictions are being removed) and longer computing time (if contradictions are not removed).
set_remove_contradictions
set_remove_contradictions(b::Bool)
Sets REMOVE_CONTRADICTIONS to b.
If REMOVE_CONTRADICTIONS==true, then contradicting terms are removed before the transmission effect is computed. A term is deemed contradicting if it includes some “xi & !xi”. This would result in the entire Boolean statement to be false, and thus in the effect of this terms to be zero.
References
Wegner, Enrico, Lenard Lieb, Stephan Smeekes, and Ines Wilms. 2025. “Transmission Channel Analysis in Dynamic Models.” 2025. https://doi.org/10.48550/arxiv.2405.18987.