I don’t see how this works. If you tic-toc the ValueFnIter and StationaryDist commands it is not even close. 90% of runtime for most models is the ValueFnIter, and often sub 1 or 2% is StationaryDist. Some models differ, but in my experience largely just the ones with lots of semi-exo shocks.
StationaryDist_FHorz_Iteration_nProbs_e_raw is taking its time…
Gammatranspose is a sparse double matrix with 1.2227e+12 elements (about 7.4M live entries). It takes time…
I note that sparse single has only been supported in MATLAB since 2025a. So this whole single vs. double thing is timely…
Whelp…the Gammatranspose is dominating HV2000 Model 4:
You can see here that main memory and GPU memory are both down from the above, and we get 7 iterations per 4 minutes instead of 6. I’m not surprised, given that the Gamma transpose operation was taking the time it did.
I’ll see if other models speed up…
Chen2010 sped up by 10%:
single:
Current GE prices:
r: 0.0335
Tr: 0.0802
Current aggregate variables:
A: 6.0279
N: 2.0514
H: 4.1922
Hr: 0.2086
pensiontaxrevenue: 0.1959
pensionspend: 0.1959
accidentalbeqleft: 0.0811
Current GeneralEqmEqns:
capitalmarkets: 0.000102
accidentalbequests: -0.000102
Current GE prices:
r: 0.0335
Tr: 0.0802
Current aggregate variables:
A: 6.0279
N: 2.0514
H: 4.1922
Hr: 0.2086
pensiontaxrevenue: 0.1959
pensionspend: 0.1959
accidentalbeqleft: 0.0811
Current GeneralEqmEqns:
capitalmarkets: 0.000102
accidentalbequests: -0.000102
Quantitative properties of the benchmark economy
Targeted Variables
Payroll tax rate is 0.107
r is 3.35%
K/Y is 2.134
H/Y is 1.534
Homeownership rate is 91.0%
Nontargeted Variables
Ho/(A+Ho) is 41.0%
Gini for total wealth is 0.54
Gini for financial wealth is NaN
Gini for housing is 0.32
Mean loan-to-value ratio (for borrowers) is 12.1
ans =
0.3314
ans =
gpuArray single
0.4562
ans =
0.4830
ans =
0.4306
Elapsed time is 622.457359 seconds.
double:
Current GE prices:
r: 0.0335
Tr: 0.0804
Current aggregate variables:
A: 6.0287
N: 2.0514
H: 4.1923
Hr: 0.2086
pensiontaxrevenue: 0.1959
pensionspend: 0.1959
accidentalbeqleft: 0.0812
Current GeneralEqmEqns:
capitalmarkets: 0.000121
accidentalbequests: 0.000098
Quantitative properties of the benchmark economy
Targeted Variables
Payroll tax rate is 0.107
r is 3.35%
K/Y is 2.135
H/Y is 1.534
Homeownership rate is 91.0%
Nontargeted Variables
Ho/(A+Ho) is 41.0%
Gini for total wealth is 0.54
Gini for financial wealth is NaN
Gini for housing is 0.32
Mean loan-to-value ratio (for borrowers) is 12.1
ans =
0.3314
ans =
0.4562
ans =
0.4830
ans =
0.4306
Elapsed time is 673.037687 seconds.
As for accuracy: only a few numbers differ in the 5th decimal digit.
I found this logic in LifeCycleModel35semiz:
% Either goes up one grid point, down one grid point, or stays
if abs((pbeforeprime-pbefore)-pbeforespacing)<1e-4 % if (pbeforeprime-pbefore)==pbeforespacing
probp1=probhousepricerise;
elseif pbeforeprime==pbefore
probp1=1-probhousepricerise-probhousepricefall;
elseif abs((pbefore-pbeforeprime)-pbeforespacing)<1e-4 % if (pbeforeprime-pbefore)==-pbeforespacing
probp1=probhousepricefall;
else
probp1=0;
end
I discovered that this logic was not quite complete:
% so we are between grid points
elseif abs(pbeforeprime-pnew)==0 % in case we hit grid point exactly
probp1=1;
elseif abs(pbeforeprime-pnew)<pbeforespacing % If this is one of the nearest grid points
probp1=abs(pbeforeprime-pnew)/pbeforespacing; % linear interpolation for the probability weight
else
probp1=0;
end
Specifically, abs(pbeforeprime-pnew)<pbeforespacing needed to be abs(pbeforeprime-pnew)+1e-4<pbeforespacing) to ensure we really were to the left of the point, not essentially on top of it. Don’t ask me how I found it ![]()
I also 100% acknowledge that the best approximation to discretization and moments is to let them run in full precision and then cast them to single if/when appropriate. Messing with their quality upstream leads to inconsistent downstream results.
