Looks like it’s my fault. The call stack is:
From TransitionPath_Case1_FHorz_PType:
%% Shooting algorithm
if transpathoptions.GEnewprice~=2
% For permanent types, there is just one shooting command,
% because things like z,e, and fastOLG are handled on a per-PType basis (to permit that they differ across ptype)
[PricePath,GEcondnPath]=TransitionPath_Case1_FHorz_PType_shooting(PricePath0, PricePathNames, ParamPath, ParamPathNames, T, V_final, AgentDist_init, jequalOneDist_T, AgeWeights_T, FnsToEvaluate, GeneralEqmEqns, PricePathSizeVec, ParamPathSizeVec, PricePathSizeVec_ii, ParamPathSizeVec_ii, use_tminus1price, use_tminus1params, use_tplus1price, use_tminus1AggVars, tminus1priceNames, tminus1paramNames, tplus1priceNames, tminus1AggVarsNames, transpathoptions, PTypeStructure);
At this point we are actually getting answers for an InfHorz calculation (mixed-horizon), and I’m following literally the comment that “there is just one shooting command [operating across PTypes]”. In other words, I’m delegating down to TransitionPath_Case1_FHorz_PType_shooting the handling of the InfHorz case. Thus, from TransitionPath_Case1_FHorz_PType_shooting we get to:
% For current ptype, do the backward iteration of V and Policy, then forward iterate agent dist and get the AggVarsPath
if isfinite(PTypeStructure.(iistr).N_j)
if vfoptions.experienceasset==1
AggVarsPath=TransitionPath_FHorz_PType_ExpAsset_singlepath(PricePathOld_ii, ParamPath_ii, PricePathNames,ParamPathNames,T,V_final.(iistr),AgentDist_init.(iistr),jequalOneDist_T.(iistr),AgeWeights_T.(iistr),l_d,N_d,n_d,N_a,n_a,N_z,n_z,N_e,n_e,N_j,d_grid,a_grid,d_gridvals,aprime_gridvals,a_gridvals,z_gridvals_J, pi_z_J,pi_z_J_sim,e_gridvals_J,pi_e_J,pi_e_J_sim,ze_gridvals_J_fastOLG,ReturnFn, FnsToEvaluate, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, AggVarNames, PricePathSizeVec_ii, ParamPathSizeVec_ii, use_tminus1price, use_tminus1params, use_tplus1price, use_tminus1AggVars, tminus1priceNames, tminus1paramNames, tplus1priceNames, tminus1AggVarsNames, II1orII, II2, exceptlastj,exceptfirstj,justfirstj, transpathoptions, vfoptions, simoptions);
else
AggVarsPath=TransitionPath_FHorz_PType_singlepath(PricePathOld_ii, ParamPath_ii, PricePathNames,ParamPathNames,T,V_final.(iistr),AgentDist_init.(iistr),jequalOneDist_T.(iistr),AgeWeights_T.(iistr),l_d,N_d,n_d,N_a,n_a,N_z,n_z,N_e,n_e,N_j,d_grid,a_grid,d_gridvals,aprime_gridvals,a_gridvals,z_gridvals_J, pi_z_J,pi_z_J_sim,e_gridvals_J,pi_e_J,pi_e_J_sim,ze_gridvals_J_fastOLG,ReturnFn, FnsToEvaluate, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, AggVarNames, PricePathSizeVec_ii, ParamPathSizeVec_ii, use_tminus1price, use_tminus1params, use_tplus1price, use_tminus1AggVars, tminus1priceNames, tminus1paramNames, tplus1priceNames, tminus1AggVarsNames, II1orII, II2, exceptlastj,exceptfirstj,justfirstj, transpathoptions, vfoptions, simoptions);
end
else
AggVarsPath=TransitionPath_InfHorz_PType_singlepath(PricePathOld_ii, ParamPath_ii, PricePathNames,ParamPathNames,T,V_final.(iistr),AgentDist_init.(iistr),l_d,N_d,n_d,N_a,n_a,N_z,n_z,d_grid,a_grid,d_gridvals,aprime_gridvals,a_gridvals,z_grid, pi_z,ReturnFn, FnsToEvaluate, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, AggVarNames, transpathoptions, vfoptions, simoptions);
end
% AggVarsPath=zeros(length(FnsToEvaluate),T-1);
TransitionPath_InfHorz_PType_singlepath is a function I wrote based on extracting the guts of TransitionPath_InfHorz_PType_shooting. Its purpose is to deliver the AggVarsPath result for TransitionPath_Case1_FHorz_PType to weave into the unified mixed horizon results.
This is the inner loop taken from that, with all mistakes mine (especially the pre-computation of II1 and IIones, which I inferred by reading other codes):
% Precompute for later
II1=gpuArray(1:1:N_a*N_z);
IIones=ones(N_a*N_z,1,'gpuArray');
for tt=1:T-1
%Get the current optimal policy
if N_d>0
Policy=PolicyIndexesPath(:,:,:,tt);
else
Policy=PolicyIndexesPath(:,:,tt);
end
GEprices=PricePathOld(tt,:);
% Again, since we don't do tminus1, don't dig as deep as FHorz
for nn=1:length(ParamPathNames)
Parameters.(ParamPathNames{nn})=ParamPath(tt,nn);
end
for nn=1:length(PricePathNames)
Parameters.(PricePathNames{nn})=PricePathOld(tt,nn);
end
PolicyUnKron=UnKronPolicyIndexes_Case1(Policy, n_d, n_a, n_z,vfoptions);
AggVars=EvalFnOnAgentDist_AggVars_Case1(AgentDist, PolicyUnKron, FnsToEvaluate, Parameters, FnsToEvaluateParamNames, n_d, n_a, n_z, d_grid, a_grid, z_grid, simoptions); % The 2 is for Parallel (use GPU)
AgentDist=AgentDist_InfHorz_TPath_SingleStep(AgentDist,Policy,II1,IIones,N_a,N_z,sparse(pi_z));
AggVarsPath(:,tt)=AggVars;
end
It is in that loop that we have the N_d context arises.