6. Conditioning on transforms
A forecaster’s judgment is almost never a level. It is “output grows one percent this quarter”, or “inflation runs at two percent a year”. The solver needs a level, and the level a growth rate implies depends on the level the path reaches one period earlier, which is itself part of the solution.
A conditioning value can therefore carry the form it is written in, and the plan resolves it as a fixed point.
p = simplan(m, [0, 24], 1);
p = append(p, 'Output', 1, 1.0, 1, 'Transform', 'pct');
p = append(p, 'EfficiencyInnovation', 1, NaN, 1);
sims = perfect_foresight(m, 'simul_historical_data', p);
6.1. The forms
Name |
The value is |
|---|---|
|
the level itself |
|
the log of the level |
|
the change from the previous level |
|
the log change from the previous level |
|
the gross rate of change |
|
the percent change |
|
hold at the previous level; no value needed |
The table is rise.engine.transform.catalog. It is shared on purpose:
a plan uses these rules to turn a conditioning value into the level it
implies, and a single-equation model uses the same rules to invert a
left-hand side written in a transform. Two copies would drift.
A transform the table does not list is refused by name, and the message lists the ones that exist.
6.2. Which period the rate is against
A rate is measured against some earlier period, and which one is part of
the statement. Shift says which, counted backwards, so the default is
-1.
% a year-on-year rate in a quarterly model
p = append(p, 'Output', 8, 2.0, 1, 'Transform', 'pct', 'Shift', -4);
A positive shift is refused. A transform is measured against a level the path has already reached; pointing forward would ask the plan to resolve a value against something it has not computed.
6.3. Why a fixed point
The level implied by “grow one percent” is the previous level times 1.01, and the previous level is part of the answer. Converting once against a guess gives the wrong level, and the error compounds down the path.
So the plan solves, recomputes the implied levels from the path it just produced, and solves again, until the levels stop moving. The seed only decides where the iteration starts, not where it ends.
Two consequences worth knowing.
The solver is untouched. The resolution happens outside the stacked system, so a plan carrying no transforms takes exactly the path it always took, with no extra solve and no change of any kind.
The count still has to work. A pinned value needs a freed shock, in the usual way. Four conditioned periods need four freed shocks or the system is not square, and that is reported by name rather than quietly returning something that satisfies neither.
6.4. Checking it delivered
The test that matters is not whether the solver converged, but whether the realised rates are the ones that were asked for:
asked realised
_____ ________
1 1
0.8 0.8
0.6 0.6
0.4 0.4
largest miss: 8.88e-16 percentage points
Asking for the same judgment as levels, computed by hand from the same growth rates, lands in the same place to 3e-15. If it did not, one of the two would be wrong.
Worked example:
rise-modern-tutorials/WorkingWithAModel/growth_conditioning.
See also