-
Notifications
You must be signed in to change notification settings - Fork 3
/
elLinearIV.m
79 lines (62 loc) · 2 KB
/
elLinearIV.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function res = elLinearIV(X, Z, y, elMethod, varargin)
% Solves a linear instrumental variables problem with EL
%
% Usage:
%
% "res = elLinearIV(X, Z, y, elMethod)"
%
% Inputs:
%
% "X" is a matrix containing the structural variables
% "Z" is a matrix containing the instruments
% "y" is a vector of the dependent variable
% "elMethod" specifies the method to use ('EL','ET', or a Cressie-Read lambda
% value). You can omit this argument to use the default 'EL'
%
% The returned structure "res" is the same as that returned by elSolve. The
% field "res.theta" contains the estimates for the coefficients on X. Note that
% it contains a field "elike" with the problem setup. This may be useful to
% pass to "elEval(...)", etc.
%
if (nargin < 4)
% Default to empirical likelihood
elMethod = 'EL';
end
nMom = size(Z,2);
nObs = size(X, 1);
assert(nObs == size(Z,1), ...
'Instrument and structural vars have different nObs');
nTheta = size(X,2);
resid = [];
% Set up the empirical likelihood problem
elike = elSetup(nObs, nMom, nTheta, @livMoments, varargin{:});
% Use custom implementations of jacobian and hessian, not automatic diff
elike.userCompJac = @livGrad;
elike.userCompHessTheta = @livHess;
spZ = spones(Z);
if nnz(spZ) > 0.25 * numel(Z)
% Use dense matrices internally, since Z is fairly dense
elike.momSparsePat = [];
else
elike.momSparsePat = spones(Z);
end
% Use OLS estimate as staring guess
thetaOls = X \ y;
% Actually solve the EL problem
res = elSolve(elike, elMethod, thetaOls, [], varargin{:});
function M = livMoments(theta, elike, mnum, newTheta)
% Compute the moments, given theta
if (newTheta)
resid = (y - X*theta);
end
M = resid .* Z(:,mnum);
end;
function grads = livGrad(theta, elike, mnum, newTheta)
% Compute the gradient of moment number 'mnum' for each observation
grads = -X .* repmat(Z(:,mnum),1,nTheta);
end;
function H = livHess(theta, elike, mnum, newTheta)
% Compute the (trivially 0) Hessian for moment condition 'mnum'
H = sparse(nTheta,nTheta);
end;
end