I would like to add matched_irfs and matched_irfs_weights blocks to Dynare's preprocessor, the blocks should be similar to irf_calibration. I tried for several hours to implement this but I failed miserably, so I would appreciate any help (@sebastien).
What I have in mind is the following:
matched_irfs;y(2), eR, 0.03;c(4), eA, 0.01;i(1), eA, (empIrfs(3,1));end;
This should produce a cell array in MATLAB M_.matched_irfs with the following structure:
where empIrfs is a matrix that has the empirical IRF values.
So I want to be able to either manually provide the values or access them from a matrix in the workspace.
Similarly, I would like to have a matched_irfs_weights block to specify the weighting matrix:
matched_irfs_weights;y(2), eR, y(2), eR, 20;c(4), eA, c(4), eA, (1/empIrfsCov(3,3));i(1), eA, y(2), eR, 10;end;
where empIrfsCov is the covariance matrix of the empirical IRFs. This should produce a cell array in MATLAB M_.matched_irfs_weights with the following structure:
I will then manipulate the structure in the MATLAB code.
Again, I'm very sorry, I thought this would be very easy to implement; but even with the help of ChatGPT I was not able to get this running as I don't know any C++.
Of course, this is just a proposal for an interface, but I think we should stay close to what we already have (irf_calibration) and not do some fancy other interface like y(2,eR)=20 or similar.
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
I find that too cumbersome. Most of the time, people will specify full IRFs for a shock with a diagonal weighting. I would propose to allow for just one block following the perfect foresight shocks block syntax:
matched_irfs;shock eR; var y;periods 1:10;values 1,2,3,4,5,5,4,3,2,1;weights 20; shock eA; var c;periods 4;values 0.01;weights (1/empIrfsCov(3,3))shock eA; var i;periods 1;values (empIrfs(3,1));weights 10;end;
I see your point and do like the intuitiveness of your proposal. We can very well go for this one; I don't really have a better idea here and was just aiming for something simple and clearly structured (without flexibility). Anyways, I do see the following difficulties:
Implementation in preprocessor: This might be quite hard to implement in the preprocessor due to its flexibility.
MATLAB code complexity: The MATLAB code would need to catch all cases as periods, values, and weights might have different lengths (integers, vectors) or elements might be missing (weights). Values would then need to be duplicated or initialized. In principle, this can all be done, but I wonder if having too much flexibility in the interface might actually confuse users and is more error-prone? But you have more insight into this.
Existing irf_calibration: We already have irf_calibration which is very similar to this blocks, so we would have a discrepancy here.
Cumbersome process: Regarding my proposal being cumbersome: the same applies to irf_calibration. That's why in the manual, we provide examples of how to use the preprocessor (particularly @#for) to make this less cumbersome.
Personal Preference on Syntax: Personally, I don't like the way we specify the shocks block by using semicolons all the time and only via the keywords the preprocessor knows when an entry is actually finished. I prefer having everything just separated by commas, with a semicolon being the end of this entry/line (e.g., as in estimated_params or irf_calibration). But this is just my preference.
Maybe @rattoma or @MichelJuillard can also provide a suggestion on what they find more intuitive and less cumbersome for such blocks given their experience in designing interfaces.
I don't see the high degree of complexity. It's deliberately similar to the shocks block. But here the respective entries should be passed directly to a structure without further processing or consistency checks.
That type of consistency checking would need to be done in any case and is easier to do and maintain in Matlab than in the preprocessor. In the original proposal, weights can also be missing. The only different part relative to shocks is the implicit expansion from a scalar to a vector or matrix if the length of values or weights does not coincide with the one in periods. But these are straightforward dimension checks in Matlab: error out whenever matrix dimensions are not conformable unless we are filling a vector/matrix with a scalar.
I have rarely seen people use irf_calibration and would not consider it a meaningful precedent.
irf_calibration usually does not involve a large number of matched IRFs. I understand the point about macroprocessing, but it's still very offputting for average users.
That's true. The tradeoff is between the simplicity of specifying everything just with commas separating the entries and necessarily requiring two blocks.
Alternatively, we may require a semicolon before the weights keyword. However, that new proposal may be harder to implement as it deviates more from existing code and would probably put more burden on @sebastien.
I came to prefer functional expressions with keyword names. Keywords may have default values. It is more verbose but I find it easier to read. Something like
matched_irfs(shock = eR, var = y, periods = 1:10, values = [1,2,3,4,5,5,4,3,2,1], weights = 20); matched_irfs(shock = eA, var = c, periods = 4, values = 0.01, weights = (1/empIrfsCov(3,3)));matched_irfs(shock = eA, var = i, periods = 1, values = (empIrfs(3,1)), weights = 10);
The weight keyword could have a default value of 1.
First, I don’t think the complexity of the implementation should be the deciding factor in this discussion (and in any case, all the proposals have more or less the same complexity).
I think I tend to prefer @JohannesPfeifer’s proposal, which is the most Dynare-ish syntax (I would just replace shock by varexo, to avoid introducing a new keyword).
However @wmutschl’s proposal seems also acceptable to me.
If I understand correctly, the choice between the two depends essentially on whether off-diagonal weighting elements will be frequently specified or not. If the weighting matrix is diagonal in most cases, @JohannesPfeifer’s syntax is more readable and more compact, since it has everything in the same place (the weight being just next to the value). On the other hand, that syntax is a bit cumbersome for off-diagonal elements (which are specified differently than diagonal elements).
Lastly, I find @MichelJuillard’s syntax interesting but too far from the existing Dynare syntax, which is not functional for declarative elements.
I forgot to mention that I’m referring to @JohannesPfeifer’s initial proposal, not the amended one (which is not very Dynare-ish, and which I don’t like much).
An additional issue I see with @MichelJuillard's proposal is that it's not clear which commands belong together and need to be concatenated. If there is only one experiment in the mod-file, that may be fine. But what about overwriting or clearing previous commands?
Yes, the default should be 1, but I would rather implement that on the Matlab end by initializing the weighting matrix with eye. The preprocessor should simply leave the fourth column entry of M_.matched_irfs.values empty.
This is already the current implementation in the MATLAB code: the weighting matrix is the identity and only if the user specified anything then we'll adjust that entry in the MATLAB code. Ideally, the keyword ´weight´ is optional. And yes, let's use ´weight´ and not ´weights´.
Also, I would rather have the preprocessor put all the weights in the same matrix for consumption by the MATLAB side. Mixing values and weights make sense at the interface level, but not so much at the MATLAB level.
I would suggest only the specific blocks and we will take care of conflicts between matched_irfs and matched_irfs_weights in the MATLAB code. Actually, the code already does that; that is, the idea being that matched_irfs is the more important block. So say if a user first specified both blocks using three observables and then overwrites only the matched_irfs block and uses 2 observables, then we will disregard any entries in matched_irfs_weights corresponding to the third observable.