Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
14a54fb
Merge pull request #40 from vfitoolkit/main
robertdkirkby Jan 9, 2026
439f4b4
p_grid
robertdkirkby Jan 9, 2026
9b819a1
clean
robertdkirkby Jan 11, 2026
8b34bbb
clean
robertdkirkby Jan 11, 2026
1be62c0
clean p_grid
robertdkirkby Jan 11, 2026
79c3e29
redo https://github.com/vfitoolkit/VFIToolkit-matlab/pull/42/commits/…
robertdkirkby Jan 11, 2026
88d85b8
reoorg
robertdkirkby Jan 11, 2026
ed3daef
minor
robertdkirkby Jan 12, 2026
b7030dc
preEV to prepare for matched expectations path
robertdkirkby Jan 12, 2026
c669596
mostly reorg
robertdkirkby Jan 12, 2026
39e7ce3
clean
robertdkirkby Jan 12, 2026
aaa99c7
big overhaul of FHorz TPath and also UnKron
robertdkirkby Jan 16, 2026
2d722d5
Added function ValueFnIter_postGI_sparse_nod_raw
aledinola Jan 16, 2026
f2023d7
Fix bug if more than one z variable
aledinola Jan 16, 2026
46907c4
GE condn reported to 6 decimal places
robertdkirkby Jan 17, 2026
49b5b92
Merge pull request #44 from aledinola/Add-sparse-matrix-for-postGI
robertdkirkby Jan 17, 2026
e71fc83
reorg
robertdkirkby Jan 17, 2026
8109677
Enable LifeCycleModel35semi to run
MichaelTiemann Jan 17, 2026
7f9a025
Added two new functions
aledinola Jan 17, 2026
013d192
Merge remote-tracking branch 'upstream/master' into Add-sparse-matrix…
aledinola Jan 17, 2026
e80afd6
Small fix
aledinola Jan 17, 2026
90e2af9
Minor changes
aledinola Jan 17, 2026
7d356d6
Merge pull request #46 from aledinola/Add-sparse-matrix-for-postGI
robertdkirkby Jan 17, 2026
a768447
minor
robertdkirkby Jan 20, 2026
6f28a14
GEnewprice3 setup moved to a subfunction
robertdkirkby Jan 20, 2026
d1919e7
clean
robertdkirkby Jan 20, 2026
ff41d91
minor fixes
robertdkirkby Jan 21, 2026
08462f1
minor
robertdkirkby Jan 21, 2026
c63bbf9
clean
robertdkirkby Jan 21, 2026
6cae6d4
minor
robertdkirkby Jan 22, 2026
c387dba
fix FHorz TPath PType
robertdkirkby Jan 22, 2026
70f3590
fix FHorz TPath with PType
robertdkirkby Jan 22, 2026
d8d8de5
minor
robertdkirkby Jan 22, 2026
aa69f40
minor
robertdkirkby Jan 25, 2026
806a10a
default never uses Howards greedy
robertdkirkby Jan 25, 2026
d85a981
minor
robertdkirkby Jan 25, 2026
5999850
mostly around maxiter, and howards-greedy, giving warnings
robertdkirkby Jan 27, 2026
10204b9
clean
robertdkirkby Jan 27, 2026
284c36d
adapt sparse howards code to look like toolkit
robertdkirkby Jan 27, 2026
1005b3f
Merge pull request #45 from MichaelTiemann/SemiExo-fixes
robertdkirkby Jan 27, 2026
e352425
Eliminate `for` loop
MichaelTiemann Jan 27, 2026
8d1ed08
clean
robertdkirkby Jan 27, 2026
1f9c92b
Merge pull request #55 from MichaelTiemann/num2cell-optimization
robertdkirkby Jan 27, 2026
743e250
lots of cleaning
robertdkirkby Jan 27, 2026
243bad9
CPU/GPU balancing
MichaelTiemann Jan 28, 2026
d9c767f
separate out the CPU version
robertdkirkby Jan 29, 2026
9294e5c
fix
robertdkirkby Jan 31, 2026
d9a445e
verboseaccuracy
robertdkirkby Feb 1, 2026
043d7cb
Merge pull request #56 from MichaelTiemann/SemiExo-gather-optimizations
robertdkirkby Feb 1, 2026
177263d
clean
robertdkirkby Feb 1, 2026
c82f9d8
verbose=2
robertdkirkby Feb 2, 2026
abb1a64
minor
robertdkirkby Feb 3, 2026
ac9e327
minor
robertdkirkby Feb 4, 2026
6dd9713
minor
robertdkirkby Feb 5, 2026
00c5380
Support ExpAsset with length(n_a)==4
MichaelTiemann Feb 11, 2026
07c6f45
fix
robertdkirkby Feb 23, 2026
e792c8d
minor fix
robertdkirkby Feb 23, 2026
5584246
Support an addition case
MichaelTiemann Feb 25, 2026
0d44f61
small improvement
robertdkirkby Mar 3, 2026
0338916
minor fix and improve
robertdkirkby Mar 3, 2026
3ea6698
Merge branch 'vfitoolkit:master' into exp-asset-length-n_a-eq-4
MichaelTiemann Mar 4, 2026
26b2408
Merge pull request #60 from MichaelTiemann/exp-asset-length-n_a-eq-4
robertdkirkby Mar 4, 2026
bed644c
AggShocks plus some minor improvements
robertdkirkby Mar 8, 2026
2b8f6ec
minor fix
robertdkirkby Mar 9, 2026
85b26a0
various minor
robertdkirkby Mar 9, 2026
f4ee524
various minor
robertdkirkby Mar 9, 2026
935ddf4
minor
robertdkirkby Mar 9, 2026
cde13dc
Tan improvement on cpu
robertdkirkby Mar 9, 2026
a4054fc
add AllStats for AggShocks
robertdkirkby Mar 10, 2026
7156c55
experienceasset with mutilple d vars
robertdkirkby Mar 10, 2026
ff9c0f3
correct comment on fminalgo
robertdkirkby Mar 11, 2026
5bc73bd
value fn from policy
robertdkirkby Mar 11, 2026
5e144fd
Ignored PTypes now listed with proper ordinal suffixes
MichaelTiemann Mar 12, 2026
447e326
Relocate error message concerning non-finite return values
MichaelTiemann Mar 12, 2026
bd66cb4
Merge pull request #62 from MichaelTiemann/earlier_error_detection_fo…
robertdkirkby Mar 12, 2026
34bab48
Merge pull request #61 from MichaelTiemann/LifeCycleProfiles_PType_im…
robertdkirkby Mar 12, 2026
d858db7
Incrementally push AggVars into PType parameter lists
MichaelTiemann Mar 12, 2026
281b314
Incrementally push AggVars into PType parameter lists
MichaelTiemann Mar 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
%%%%%%%%%%%%%%%
% Original paper:
% Farmer & Toda (2017) - Discretizing Nonlinear, Non-Gaussian Markov Processes with Exact Conditional Moments
% They how that this method outperforms both Tauchen and Rouwenhorst for almost all discretization of Gaussian AR(1).
% They show that this method outperforms both Tauchen and Rouwenhorst for almost all discretization of Gaussian AR(1).

if rho>=0.99
fprintf('COMMENT: When discretizing gaussian AR(1) process with autocorrelation (rho) greater than 0.99 (which you currently have), the Rouwenhorst method tends to outperform Farmer-Toda method. \n')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
function AllStatsPath=EvalFnOnAggShocksPath_AllStats_InfHorz(GeneralizedTransitionFn,T,n_d,n_a,n_z,n_S,d_grid,a_grid,z_grid,FnsToEvaluate,Parameters,simoptions)

if ~exist('simoptions','var')
simoptions.npoints=100;
simoptions.nquantiles=20;
simoptions.whichstats=ones(7,1); % See StatsFromWeightedGrid(), zeros skip some stats and can be used to reduce runtimes
else
if ~isfield(simoptions,'npoints')
simoptions.npoints=100;
end
if ~isfield(simoptions,'nquantiles')
simoptions.nquantiles=20;
end
if ~isfield(simoptions,'whichstats')
simoptions.whichstats=ones(7,1); % See StatsFromWeightedGrid(), zeros skip some stats and can be used to reduce runtimes
end
end

%% Setup
PricePathNames=fieldnames(GeneralizedTransitionFn.PricePath);
AggShockNames=fieldnames(GeneralizedTransitionFn.AggShocksPath);

FnsToEvalNames=fieldnames(FnsToEvaluate);
for ff=1:length(FnsToEvalNames)
AllStatsPath.(FnsToEvalNames{ff}).Mean=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).Median=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).RatioMeanToMedian=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).Variance=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).StdDeviation=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).LorenzCurve=zeros(simoptions.npoints,T);
AllStatsPath.(FnsToEvalNames{ff}).Gini=zeros(1,T);
AllStatsPath.(FnsToEvalNames{ff}).QuantileCutoffs=zeros(simoptions.nquantiles+1,T); % Includes the min and max values
AllStatsPath.(FnsToEvalNames{ff}).QuantileMeans=zeros(simoptions.nquantiles,T);
end


%% Loop over tt=1:T and get AllStats
% We already have GeneralizedTransitionFn.AgentDistPath so just calculate from this.
for tt=1:T
for pp=1:length(PricePathNames)
temp=GeneralizedTransitionFn.PricePath.(PricePathNames{pp});
Parameters.(PricePathNames{pp})=temp(tt);
end
for SS_c=1:length(n_S)
temp=GeneralizedTransitionFn.AggShocksPath.(AggShockNames{SS_c});
Parameters.(AggShockNames{SS_c})=temp(tt);
end

AgentDist=GeneralizedTransitionFn.AgentDistPath(:,:,tt);
Policy=GeneralizedTransitionFn.PolicyPath(:,:,:,tt);

% would be slightly faster if I pass FnsToEvaluateCell and FnsToEvaluateParamNames
AllStats_tt=EvalFnOnAgentDist_AllStats_Case1(AgentDist,Policy,FnsToEvaluate,Parameters,[],n_d,n_a,n_z,d_grid,a_grid,z_grid,simoptions);

for ff=1:length(FnsToEvalNames)
temp=AllStatsPath.(FnsToEvalNames{ff}).Mean;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).Mean;
AllStatsPath.(FnsToEvalNames{ff}).Mean=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).Median;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).Median;
AllStatsPath.(FnsToEvalNames{ff}).Median=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).RatioMeanToMedian;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).RatioMeanToMedian;
AllStatsPath.(FnsToEvalNames{ff}).RatioMeanToMedian=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).Variance;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).Variance;
AllStatsPath.(FnsToEvalNames{ff}).Variance=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).StdDeviation;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).StdDeviation;
AllStatsPath.(FnsToEvalNames{ff}).StdDeviation=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).LorenzCurve;
temp(:,tt)=AllStats_tt.(FnsToEvalNames{ff}).LorenzCurve;
AllStatsPath.(FnsToEvalNames{ff}).LorenzCurve=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).Gini;
temp(tt)=AllStats_tt.(FnsToEvalNames{ff}).Gini;
AllStatsPath.(FnsToEvalNames{ff}).Gini=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).QuantileCutoffs;
temp(:,tt)=AllStats_tt.(FnsToEvalNames{ff}).QuantileCutoffs;
AllStatsPath.(FnsToEvalNames{ff}).QuantileCutoffs=temp;

temp=AllStatsPath.(FnsToEvalNames{ff}).QuantileMeans;
temp(:,tt)=AllStats_tt.(FnsToEvalNames{ff}).QuantileMeans;
AllStatsPath.(FnsToEvalNames{ff}).QuantileMeans=temp;
end

end









end
2 changes: 1 addition & 1 deletion EvaluateFnOnAgentDist/EvalFnOnAgentDist_AggVars_Case1.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
if isfield(simoptions,'outputasstructure')
if simoptions.outputasstructure==1
FnsToEvaluateStruct=1;
FnsToEvalNames=simoptions.AggVarNames;
% FnsToEvalNames=simoptions.AggVarNames;
elseif simoptions.outputasstructure==0
FnsToEvaluateStruct=0;
end
Expand Down
2 changes: 1 addition & 1 deletion EvaluateFnOnAgentDist/EvalFnOnAgentDist_AllStats_Case1.m
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
Values=reshape(Values,[N_a*N_z,1]);

AllStats.(FnsToEvalNames{ff})=StatsFromWeightedGrid(Values,StationaryDistVec,simoptions.npoints,simoptions.nquantiles,simoptions.tolerance,0,simoptions.whichstats);

%% If there are any conditional restrictions then deal with these
% Evaluate AllStats, but conditional on the restriction being one.
if useCondlRest==1
Expand Down
17 changes: 12 additions & 5 deletions EvaluateFnOnAgentDist/EvalFnOnAgentDist_ValuesOnGrid_Case1.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@
if simoptions.gridinterplayer==1
l_daprime=l_daprime-1;
end
a_gridvals=CreateGridvals(n_a,a_grid,1);
[z_gridvals,~,simoptions]=ExogShockSetup(n_z,z_grid,[],Parameters,simoptions,1);

if Parallel==2
a_gridvals=CreateGridvals(n_a,a_grid,1);
[z_gridvals,~,simoptions]=ExogShockSetup(n_z,z_grid,[],Parameters,simoptions,1);
elseif Parallel==1
a_gridvals=CreateGridvals(n_a,a_grid,2);
z_gridvals=CreateGridvals(n_z,z_grid,2); % CPU, so must just be simple stacked column for z
end

%% Implement new way of handling FnsToEvaluate
if isstruct(FnsToEvaluate)
Expand Down Expand Up @@ -76,9 +80,12 @@
Values=reshape(Values,[N_a*N_z,1]);
ValuesOnGrid.(AggVarNames{ff})=reshape(Values,[n_a,n_z]);
end
else
elseif Parallel==1
% CPU
simoptions.experienceasset=0; % needs to be set so can use CreateGridvals_Policy()
simoptions.experienceassetu=0; % needs to be set so can use CreateGridvals_Policy()
[d_gridvals, aprime_gridvals]=CreateGridvals_Policy(Policy,n_d,n_a,n_a,n_z,d_grid,a_grid,simoptions,1, 2);

if l_d>0

for ff=1:length(FnsToEvaluate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

%% Implement new way of handling FnsToEvaluate
% Figure out l_daprime from Policy
l_daprime=size(Policy,1);
if simoptions.gridinterplayer==0
l_daprime=size(Policy,1);
else
l_daprime=size(Policy,1)-1;
end

% Note: l_z includes e and semiz (when appropriate)
if isstruct(FnsToEvaluate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
% AgeWeightParamNames is either same for all permanent types, or must be passed as a structure.
%
% The stationary distribution be a structure and will contain both the
% weights/distribution across the permenant types, as well as a pdf for the
% weights/distribution across the permanent types, as well as a pdf for the
% stationary distribution of each specific permanent type.
%
% How exactly to handle these differences between permanent (fixed) types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
% jequaloneDist can either be same for all permanent types, or must be passed as a structure.
% AgeWeightParamNames is either same for all permanent types, or must be passed as a structure.
%
% The stationary distribution be a structure and will contain both the
% The stationary distribution must be a structure and will contain both the
% weights/distribution across the permenant types, as well as a pdf for the
% stationary distribution of each specific permanent type.
%
% How exactly to handle these differences between permanent (fixed) types
% is to some extent left to the user. You can, for example, input
% parameters that differ by permanent type as a vector with different rows f
% parameters that differ by permanent type as a vector with different rows
% for each type, or as a structure with different fields for each type.
%
% Any input that does not depend on the permanent type is just passed in
Expand Down Expand Up @@ -176,7 +176,12 @@
ii=ii+1;
Names_i{ii}=Names_i2{ii2};
else % tell the user about it
fprintf(['LifeCycleProfiles_FHorz_Case1_PType: Ignoring the ', num2str(ii2), '-th PType, ',Names_i2{ii2}, ' because it is infinite horizon \n']);
suffix='th';
if ii2<4 % Good up to 20 PTypes
suffix_cells={'st', 'nd', 'rd'};
suffix=suffix_cells{ii2};
end
fprintf('LifeCycleProfiles_FHorz_Case1_PType: Ignoring the %d%s PType { %s } because it is infinite horizon \n', ii2, suffix, Names_i2{ii2});
end
end
% Eliminate any no longer relevant functions from FnsToEvaluate (those which are only used for infinite horizon)
Expand Down Expand Up @@ -228,7 +233,7 @@
end
end
end
elseif length(simoptions.agejshifter)==1 % not using agejshifter
elseif isscalar(simoptions.agejshifter) % not using agejshifter
simoptions.agejshifter=zeros(N_i,1);
N_j_max2=N_j_max;
else % have inputed as a vector
Expand Down Expand Up @@ -563,7 +568,12 @@
if FnsAndPTypeIndicator_ii(ff)==1 % If this function is relevant to this ptype

% Get parameter names for current FnsToEvaluate functions
tempnames=getAnonymousFnInputNames(FnsToEvaluate.(FnsToEvalNames{ff}));
if isstruct(FnsToEvaluate.(FnsToEvalNames{ff}))
tempfn=FnsToEvaluate.(FnsToEvalNames{ff}).(Names_i{ii});
else
tempfn=FnsToEvaluate.(FnsToEvalNames{ff});
end
tempnames=getAnonymousFnInputNames(tempfn);
if length(tempnames)>(l_daprime_temp+l_a_temp+l_z_temp)
FnsToEvaluateParamNames={tempnames{l_daprime_temp+l_a_temp+l_z_temp+1:end}}; % the first inputs will always be (d,aprime,a,z)
else
Expand All @@ -577,7 +587,7 @@

%% We have set up the current PType, now do some calculations for it.
simoptions_temp.keepoutputasmatrix=2;
ValuesOnGrid_ffii=EvalFnOnAgentDist_Grid_J(FnsToEvaluate.(FnsToEvalNames{ff}),CellOverAgeOfParamValues,PolicyValuesPermute_temp,l_daprime_temp,n_a_temp,n_z_temp,a_gridvals_temp,z_gridvals_J_temp);
ValuesOnGrid_ffii=EvalFnOnAgentDist_Grid_J(tempfn,CellOverAgeOfParamValues,PolicyValuesPermute_temp,l_daprime_temp,n_a_temp,n_z_temp,a_gridvals_temp,z_gridvals_J_temp);

ValuesOnGrid_ffii=reshape(ValuesOnGrid_ffii,[N_a_temp*N_z_temp,N_j_temp]);
% StationaryDist_ii=reshape(StationaryDist.(Names_i{ii}),[N_a_temp*N_z_temp,N_j_temp]); % Note: does not impose *StationaryDist.ptweights(ii)
Expand Down Expand Up @@ -1193,37 +1203,37 @@
% a structure is there a need to take just a specific part and send
% only that to the 'non-PType' version of the command.

if isa(n_d,'struct')
if isstruct(n_d)
n_d_temp=n_d.(Names_i{ii});
else
n_d_temp=n_d;
end
if isa(n_a,'struct')
if isstruct(n_a)
n_a_temp=n_a.(Names_i{ii});
else
n_a_temp=n_a;
end
if isa(n_z,'struct')
if isstruct(n_z)
n_z_temp=n_z.(Names_i{ii});
else
n_z_temp=n_z;
end
if isa(N_j,'struct')
if isstruct(N_j)
N_j_temp=N_j.(Names_i{ii});
else
N_j_temp=N_j;
end
if isa(d_grid,'struct')
if isstruct(d_grid)
d_grid_temp=d_grid.(Names_i{ii});
else
d_grid_temp=d_grid;
end
if isa(a_grid,'struct')
if isstruct(a_grid)
a_grid_temp=a_grid.(Names_i{ii});
else
a_grid_temp=a_grid;
end
if isa(z_grid,'struct')
if isstruct(z_grid)
z_grid_temp=z_grid.(Names_i{ii});
else
z_grid_temp=z_grid;
Expand All @@ -1236,7 +1246,7 @@
FullParamNames=fieldnames(Parameters);
nFields=length(FullParamNames);
for kField=1:nFields
if isa(Parameters.(FullParamNames{kField}), 'struct') % Check for permanent type in structure form
if isstruct(Parameters.(FullParamNames{kField})) % Check for permanent type in structure form
names=fieldnames(Parameters.(FullParamNames{kField}));
for jj=1:length(names)
if strcmp(names{jj},Names_i{ii})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,20 @@

%%
a_gridvals=CreateGridvals(n_a,a_grid,1);
z_gridvals=CreateGridvals(n_z,z_grid,1);

PolicyPath=reshape(PolicyPath,[size(PolicyPath,1),N_a,N_z,T]);
% Create PolicyValuesPath from PolicyIndexesPath for use in calculating model stats
PolicyValuesPath=PolicyInd2Val_InfHorz_TPath(PolicyPath,n_d,n_a,n_z,T,d_grid,a_grid,simoptions,1);
PolicyValuesPath=permute(reshape(PolicyValuesPath,[size(PolicyValuesPath,1),N_a,N_z,T]),[2,3,1,4]); %[N_a,N_z,l_d+l_a,T-1]

%% Switch to z_gridvals
l_z=length(n_z);
if all(size(z_grid)==[sum(n_z),1])
z_gridvals=CreateGridvals(n_z,z_grid,1); % The 1 at end indicates want output in form of matrix.
elseif all(size(z_grid)==[prod(n_z),l_z])
z_gridvals=z_grid;
end

%%
AgentDistPath=reshape(AgentDistPath,[N_a,N_z,T]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function CorrTransProbsPath=EvalFnOnTransPath_CorrTransProbs_InfHorz(FnsToEvaluate,AgentDistPath,PolicyPath,PricePath,ParamPath, Parameters, T, n_d, n_a, n_z, d_grid, a_grid,z_grid, pi_z,simoptions)
function CorrTransProbsPath=EvalFnOnTransPath_AutoCorrTransProbs_InfHorz(FnsToEvaluate,AgentDistPath,PolicyPath,PricePath,ParamPath, Parameters, T, n_d, n_a, n_z, d_grid, a_grid,z_grid, pi_z,simoptions)
% Returns stats on (auto) correlation and transition probabilities
% You must input the names for the FnsToEvaluate that you want the transition probabilities for (by default it won't do any)
% Done as simoptions.transprobs
Expand Down Expand Up @@ -291,4 +291,4 @@
end
end
end
end
end
Loading