Transition Path: 'additionalfactor' to speed up shooting algorithm

When using shooting algorithm to solve a transition path you set an update ‘factor’, this is done when you create the ‘howtoupdate’ rules. For example solving a transition path in the Aiyagari model we might set something like,
transpathoptions.GEnewprice3.howtoupdate={‘capitalmarket’,‘r’,0,0.1}
which is saying that the price (r) is updated by subtracting (the 0), the value of the general eqm condition (‘capitalmarket’) times a damping factor (0.1).

The bigger the damping factor, the faster the convergence, but a big damping factor can be unstable.

One thing you might want to do is set a small damping factor for the first few iterations (so that our poor initial guess does some convergence towards the solution), but then after some iterations we start increasing the damping factor (we are close enough to solution we are stable, and now we just want speed).

This is what the new transpathoptions.additionalfactor=[3,10,20] option enables you to do. The first number, 3, is and additional factor, so in the first iteration we would use the standard 0.1 factor, but in later iterations we would use 3*0.1 as the factor. The second and third numbers in ‘additionalfactor’ control the timing of the additional factor. Prior to period 10 we just use the standard factor of 0.1. After period 20 we use the full additional factor, so 3*0.1. Between periods 10 and 20 we linearly scale up from 1*0.1 to 3*0.1. So you can control both when we start, how quickly we introduce, and how big is the additional factor.

In a model with multiple general eqm eqns and prices, you can set up additionalfactor as a matrix which applies a different additional factor and different timings to each of the prices.

The following post is written by Claude and gives a more technical explanation of how this is done.

Hopefully this should help solving transition path general eqm a little bit faster.

Here is Claude explanation with more detail:

additionalfactor: ramping the shooting update

With transpathoptions.GEnewprice=3 you give the solver a howtoupdate rule per general eqm condition:

transpathoptions.GEnewprice3.howtoupdate={'CapitalMarket','r',0,0.1; ...
                                          'LabourMarket','w',0,0.1};
% {GE condn name, price name, add, factor}

and each iteration updates new = old ± factor * residual.

factor is a damping constant, and setting it is a compromise. A value small enough to be stable in the early iterations, when the guess is poor and the residuals are large, is usually smaller than you need later, once the path is in the right region. You pay for that in iterations.

additionalfactor lets factor grow (or shrink) as the solve proceeds.

transpathoptions.GEnewprice3.additionalfactor=[f_add,t1_add,t2_add];

factor is held as given up to iteration t1_add, then ramps linearly to f_add*factor by iteration t2_add, and stays there:

rampweight  = min(max((itercounter-t1_add)/(t2_add-t1_add),0),1);
factor_iter = factor*(1+(f_add-1)*rampweight);

It is written as 1+(f_add-1)*w rather than as a min, so that f_add<1 — damping the step down over iterations — works just as well as f_add>1. itercounter is 1 during the first iteration’s update.

Example

transpathoptions.GEnewprice3.additionalfactor=[3,10,30];

With factor=0.1: the first ten iterations run at 0.1, then the step grows linearly to 0.3 by iteration 30 and holds there. In a test case here that was the difference between converging comfortably inside a 250-iteration cap and not converging at all.

If your solve oscillates rather than converging, try f_add<1 instead. Same mechanism, damping down.

Per-equation rows

One row applies to every general eqm condition. Alternatively give one row per condition, in the same order as howtoupdate:

transpathoptions.GEnewprice3.additionalfactor=[3,10,30; ...   % CapitalMarket
                                               1,1,2];        % LabourMarket, no ramp

[1,1,2] is the no-op, and the default, since f_add=1 leaves factor alone.

Rules

  • t1_add must be an integer of at least 1
  • t2_add must be an integer strictly greater than t1_add
  • all entries must be finite
  • f_add~=1 is rejected on any row where you set factor=Inf. That is the sentinel meaning “replace the price outright”, so there is no step to scale.

Where else it works

The same option exists for the stationary general eqm shooting algorithm:

heteroagentoptions.fminalgo5.additionalfactor=[f_add,t1_add,t2_add];

with identical semantics, and it is supported in the PType transition path and stationary commands too.

It is not available with fminalgo=9 (Anderson acceleration), which accelerates the fixed-point map itself; rescaling the step underneath it would fight the acceleration. That combination raises an error rather than being quietly ignored.

One thing worth knowing

Because the update factor no longer affects how convergence is measured (see the convergence post), a more aggressive ramp cannot make a path look converged when it is not. It changes how fast you reach the answer, not what counts as the answer.

That was not true before both changes went in together: the old convergence test was the price change, which is factor * residual, so a larger factor moved the measuring stick at the same time as the prices.

1 Like