The toolkit evaluates intermediate equations and general equilibrium conditions in HeteroAgentStationaryEqm_Case1_subfn, around lines 54-73
intermediateEqnsVec(gg)=real(GeneralEqmConditions_Case1_v3g(heteroagentoptions.intermediateEqnsCell{gg}, heteroagentoptions.intermediateEqnParamNames(gg).Names, Parameters));
GeneralEqmConditionsVec(gg)=real(GeneralEqmConditions_Case1_v3(GeneralEqmEqnsCell{gg}, GeneralEqmEqnParamNames(gg).Names, Parameters));
I am concerned that the trick real() can hide some mistakes or inconsistencies. It happened to me in a model where I have these intermediate equations:
heteroagentoptions.intermediateEqns.N_corp=@(L,N_noncorp) L-N_noncorp;
heteroagentoptions.intermediateEqns.K_corp=@(A,K_noncorp) A-K_noncorp;
heteroagentoptions.intermediateEqns.Y_corp=@(K_corp,N_corp,alpha,Z) Z*(K_corp^alpha)*(N_corp^(1-alpha));
In equilibrium it cannot happen that N_corp or K_corp are negative, but during the GE iterations, these two variables might be negative. This is a problem because there is a fractional power in Y_corp and the negative numbers would give complex results in matlab.
The toolkit prevents this from happening by taking real(), but wouldn’t it be better to remove this trick? This would force the user to become aware of the problem, otherwise the code might go on without converging…
In my case I fixed the problem by putting a zero floor to K_corp and N_corp:
heteroagentoptions.intermediateEqns.N_corp=@(L,N_noncorp) max(L-N_noncorp,1e-12);
heteroagentoptions.intermediateEqns.K_corp=@(A,K_noncorp) max(A-K_noncorp,1e-12);
Even better to modify the GE conditions for capital and labor as follows:
GeneralEqmEqns.CapitalMarket = @(r,K_corp,N_corp,alpha,delta,Z) ...
CorpCapitalMarketResidual(r,K_corp,N_corp,alpha,delta,Z);
and then
function resid = CorpCapitalMarketResidual(r,K_corp,N_corp,alpha,delta,Z)
if ~isfinite(K_corp) || ~isfinite(N_corp) || K_corp <= 0 || N_corp <= 0
resid = 1e6;
return
end
resid = r - (alpha*Z*(K_corp/N_corp)^(alpha-1) - delta);
end %end function
The idea is that if either K_corp or N_corp are “bad” (i.e. negative or NaN etc) we do NOT evaluate the condition r - (alpha*Z*(K_corp/N_corp)^(alpha-1) - delta) since it would be pointless and maybe would break the code, but we return a large penalty, so hopefully the GE solver changes the GE variables to avoid these bad values. This second approach has a small downside: it is more verbose, since you have to write the GE conditions as separate m-files. But of course the toolkit does not care whether you pass a GE condition as a one-liner or as a separate function like you would do for ReturnFn.
It would be nice to get some feedback on this problem from other users: what would you do in this case? Do you think the real() shim is a good idea?