SimPanelValues with grid interpolation layer

The InfHorz and FHorz commands for SimPanelValues (simulate panel data) should now both work with grid interpolation layer.

1 Like

That’s nice. In a model with entrepreneurs, sometimes one would like to compute moments such as the entry and exit rate (entry means the transition rate from e=worker into e=entrepreneur, where e is a variable that denotes occupational choice). One could then simulate a panel using this toolkit command SimPanelValues.

Another possibility is to avoid simulations and use directly the stationary distirbution. To this end, I wrote this function that computes the transition rates given policy function for the endogenous state, for occupational choice and the stationary distribution.

In the code below,

  • pol_aprime = a'(a,z) maps the state variables (a,z) into next period endogenous state a'.
  • pol_e = e(a,z) maps the state variables (a,z) into the current period occupation e \in \{ 1,2\} where 1=worker and 2=entrepreneur.
  • StationaryDist is the stationary distribution defined as a probability mass over (a,z).
% Compute T(o,o')=mass of individuals who go from occupation o in the current 
% period to occupation o' in the next period
% pol_e maps state (a,z) into {1,2} where 1=worker, 2=entre

T = zeros(2,2); 

for z_c=1:n_young
    for a_c=1:n_a
        aprime_c = pol_aprime(a_c,z_c);
        o = pol_e(a_c,z_c);
        for zprime_c = 1:n_young
            o_prime = pol_e(aprime_c,zprime_c);
            T(o,o_prime) = T(o,o_prime)+pi_z(z_c,zprime_c)*StationaryDist(a_c,z_c);
        end
    end
end

exit_E_to_W = T(2,1)/sum(T(2,:));
entry_W_to_E = T(1,2)/sum(T(1,:));

@robertdkirkby Is there a toolkit command that does something similar to my function above? Of course the simulation approach is a valid alternative.

EvalFnOnAgentDist_AutoCorrTransProb_InfHorz(), when you use simoptions to ask for the transition probabilities, is doing this. This is not yet implemented in FHorz but will be at some point.

Just set up a FnsToEvaluate that takes values =1 for entrepreneur and =0 for worker. Set simoptions.transprobs and it will then report the transition probabilities between entrepreneur and worker.

1 Like

If I have a function to evaluate called E that takes values 0 and 1 (1 for entrepreneur and 0 if not), should I set

simoptions.transprobs = {‘E’}

Is that it?
Thanks

Thanks for your answer, I will double check the result against my function to make sure all is good.

Yep. It’s that easy :wink:

It will report transition probabilities between all unique values taken by the FnsToEvaluate that you name (you can name multiple).

You can use simoptions to further specify if you wanted rank transition probabilities instead (e.g., if you want transition probabilities between quintiles of the earnings distribution).

1 Like

There is a typo in your post: the name of the command is EvalFnOnAgentDist_AutoCorrTransProbs_InfHorz

I checked and there is a non-negligible difference between the transition probs given by the toolkit command and those given by my function :frowning:

First, the command generates a warning:

Warning: Have not yet implemented simoptions.conditionalrestrictions for CorrTransProbs_InfHorz, ask on forum if you need
this 
> In EvalFnOnAgentDist_AutoCorrTransProbs_InfHorz (line 67)

This is however not relevant for this calculation since I want the exit and entry rate for entrepreneurs and I think conditional restrictions should play no role (entre = 1 if agent has e=1 .and. age=1)
So

  • exit rate = Prob(from entre=1 to entre=0), hence element (2,1) of the transition matrix
  • entry rate = Prob(from entre=0 to entre=1), hence element (1,2)
    of the transition matrix

The toolkit command is coded as

FnsToEvaluate.Entre =  @(l,e,aprime,a,eta,theta,age) (age==1)*(e==1);
simoptions.transprobs = {'Entre'};
CorrTransProbs=EvalFnOnAgentDist_AutoCorrTransProbs_InfHorz(StationaryDist,Policy,FnsToEvaluate,Params,[],n_d,n_a,n_z,d_grid,a_grid,z_grid,pi_z,simoptions);

and Mom.CorrTransProbs.Entre.TransitionProbs is:


    0.9795    0.0205
    0.2502    0.7498

My function instead gives 0.0253 and 0.2334. Not a big difference, but not negligible either.

@robertdkirkby Could you please have a look at the short function I have coded to compute the entry and exit rates (it is for the replication of Bruggeman 2021). If you spot an error we can assume the toolkit command is correct, otherwise it has a bug :smiley:
Thanks!

function [exit_E_to_W,entry_W_to_E,T] = fun_entry_exit(StationaryDist,pi_z,pol_e,pol_aprime,a_grid,n_a,n_z)
% This function computes the entry and exit rates b/w occupations. 
% We restrict the sample to young people.

% There n_young=n_eps*n_theta points for young agents and 1 point for old
% agents
n_young = n_z(1)-1;

% Check inputs
if ~isequal(size(StationaryDist),[n_a,n_young+1])
    error('Size of StationaryDist NOT correct!')
end
if ~isequal(size(pol_e),[n_a,n_young+1])
    error('Size of pol_e NOT correct!')
end
if ~isequal(size(pol_aprime),[n_a,n_young+1])
    error('Size of pol_aprime NOT correct!')
end
if ~isequal(size(pi_z),[prod(n_z),prod(n_z)])
    error('Size of pi_z NOT correct!')
end 
if n_a~=length(a_grid)
    error('n_a is NOT correct!')
end

%% Move to CPU
StationaryDist = gather(StationaryDist);
pi_z       = gather(pi_z);
pol_e      = gather(pol_e);
pol_aprime = gather(pol_aprime);

%% Consider only young people (a,z=eps*theta+1)
StationaryDist = StationaryDist(:,1:n_young)/sum(StationaryDist(:,1:n_young),"all");
pol_e          = pol_e(:,1:n_young);
pol_aprime     = pol_aprime(:,1:n_young); 

% Compute T(o,o')=mass of individuals who go from occupation o in the current 
% period to occupation o' in the next period
% pol_e maps state (a,z) into {1,2} where 1=worker, 2=entre

T = zeros(2,2); 

for z_c=1:n_young
    for a_c=1:n_a
        aprime_c = pol_aprime(a_c,z_c);
        o = pol_e(a_c,z_c);
        for zprime_c = 1:n_young
            o_prime = pol_e(aprime_c,zprime_c);
            T(o,o_prime) = T(o,o_prime)+pi_z(z_c,zprime_c)*StationaryDist(a_c,z_c);
        end
    end
end

exit_E_to_W = T(2,1)/sum(T(2,:));
entry_W_to_E = T(1,2)/sum(T(1,:));

end %end function

It only showed the warning because your simoptions contained conditionalrestrictions

if isfield(simoptions,'conditionalrestrictions')
    warning('Have not yet implemented simoptions.conditionalrestrictions for CorrTransProbs_InfHorz, ask on forum if you need this')
end

I will take a look

1 Like

Hi @robertdkirkby, I was wondering if you agree with my computation of entry and exit rate in the model with entrepreneurs.
Thanks in advance for the feedback!