Skip to content

Commit 79a372b

Browse files
Qr (#253)
* remove cholesky * speed up * update * rmv find_cols * patched version * Update Project.toml * Update fit.jl
1 parent 9e5d020 commit 79a372b

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

src/fit.jl

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,17 @@ function StatsAPI.fit(::Type{FixedEffectModel},
321321
perm = 1:(n_exo + n_endo)
322322

323323
# first pass: remove colinear variables in Xendo
324-
notcollinear_fe_endo = collinear_fe[find_cols_endo(n_exo, n_endo)] .== false
325-
basis_endo = basis(eachcol(Xendo)...; has_intercept = false) .* notcollinear_fe_endo
324+
notcollinear_fe_endo = collinear_fe[(n_exo+2):(n_exo+n_endo+1)] .== false
325+
basis_endo = basis(Xendo; has_intercept = false) .* notcollinear_fe_endo
326326
Xendo = getcols(Xendo, basis_endo)
327327

328328
# second pass: remove colinear variable in Xexo, Z, and Xendo
329-
notcollinear_fe_exo = collinear_fe[find_cols_exo(n_exo)] .== false
330-
notcollinear_fe_z = collinear_fe[find_cols_z(n_exo, n_endo, n_z)] .== false
329+
notcollinear_fe_exo = collinear_fe[2:(n_exo+1)] .== false
330+
notcollinear_fe_z = collinear_fe[(n_exo+n_endo+2):(n_exo+n_endo+n_z+1)] .== false
331331
notcollinear_fe_endo_small = notcollinear_fe_endo[basis_endo]
332332

333-
basis_all = basis(Xexo, Z, eachcol(Xendo)...; has_intercept = has_intercept)
333+
334+
basis_all = basis(Xexo, Z, Xendo; has_intercept = has_intercept)
334335
basis_Xexo = basis_all[1:size(Xexo, 2)] .* notcollinear_fe_exo
335336
basis_Z = basis_all[(size(Xexo, 2) +1):(size(Xexo, 2) + size(Z, 2))] .* notcollinear_fe_z
336337
basis_endo_small = basis_all[(size(Xexo, 2) + size(Z, 2) + 1):end] .* notcollinear_fe_endo_small
@@ -380,7 +381,7 @@ function StatsAPI.fit(::Type{FixedEffectModel},
380381
# get linearly independent columns
381382
n_exo = size(Xexo, 2)
382383
perm = 1:n_exo
383-
notcollinear_fe_exo = collinear_fe[find_cols_exo(n_exo)] .== false
384+
notcollinear_fe_exo = collinear_fe[2:(n_exo+1)] .== false
384385
basis_Xexo = basis(Xexo; has_intercept = has_intercept) .* notcollinear_fe_exo
385386
Xexo = getcols(Xexo, basis_Xexo)
386387
Xhat = Xexo
@@ -393,6 +394,7 @@ function StatsAPI.fit(::Type{FixedEffectModel},
393394
## Do the regression
394395
##
395396
##############################################################################
397+
396398
crossx = Xhat' * Xhat
397399
Xy = Symmetric(hvcat(2, crossx, Xhat'y, zeros(size(Xhat, 2))', [0.0]))
398400
invsym!(Xy; diagonal = 1:size(Xhat, 2))
@@ -466,15 +468,15 @@ function StatsAPI.fit(::Type{FixedEffectModel},
466468
# Compute Fstat of First Stage
467469
if has_iv && first_stage
468470
Pip = Pi[(size(Pi, 1) - size(Z_res, 2) + 1):end, :]
469-
#try
471+
try
470472
r_kp = Vcov.ranktest!(Xendo_res, Z_res, Pip,
471473
vcov_method, size(X, 2), dof_fes)
472474
p_kp = chisqccdf(size(Z_res, 2) - size(Xendo_res, 2) + 1, r_kp)
473475
F_kp = r_kp / size(Z_res, 2)
474-
# catch
475-
# @info "ranktest failed ; first-stage statistics not estimated"
476-
# p_kp, F_kp = NaN, NaN
477-
# end
476+
catch
477+
@info "ranktest failed ; first-stage statistics not estimated"
478+
p_kp, F_kp = NaN, NaN
479+
end
478480
end
479481

480482
# Compute rss, tss

src/utils/basecol.jl

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# create the matrix X'X
2-
function crossprod(xs...)
3-
idx = vcat(0, cumsum(size(x, 2) for x in xs))
4-
XX = zeros(idx[end], idx[end])
5-
for i in 1:length(xs)
6-
for j in i:length(xs)
7-
XX[(idx[i]+1):idx[i+1], (idx[j]+1):idx[j+1]] .= xs[i]' * xs[j]
8-
end
9-
end
10-
return Symmetric(XX, :U)
2+
crossprod(x1) = Symmetric(x1'x1)
3+
4+
function crossprod(x1, x2)
5+
Symmetric(hvcat(2, x1'x1, x1'x2,
6+
zeros(size(x2, 2), size(x1, 2)), x2'x2))
7+
end
8+
9+
function crossprod(x1, x2, x3)
10+
Symmetric(hvcat(3, x1'x1, x1'x2, x1'x3,
11+
zeros(size(x2, 2), size(x1, 2)), x2'x2, x2'x3,
12+
zeros(size(x3, 2), size(x1, 2)), zeros(size(x3, 2), size(x2, 2)), x3'x3))
1113
end
1214

1315
# generalized 2inverse
@@ -47,7 +49,6 @@ function getcols(X::AbstractMatrix, basecolX::AbstractVector)
4749
sum(basecolX) == size(X, 2) ? X : X[:, basecolX]
4850
end
4951

50-
5152
function ls_solve(X, y::AbstractVector)
5253
Xy = crossprod(X, y)
5354
invsym!(Xy, diagonal = 1:size(X, 2))
@@ -59,17 +60,3 @@ function ls_solve(X, Y::AbstractMatrix)
5960
invsym!(XY, diagonal = 1:size(X, 2))
6061
return XY[1:size(X, 2),(end-size(Y, 2)+1):end]
6162
end
62-
63-
##############################################################################
64-
# Auxiliary functions to find columns of exogeneous, endogenous and IV variables
65-
##############################################################################
66-
67-
function find_cols_exo(n_exo)
68-
2:n_exo+1
69-
end
70-
function find_cols_endo(n_exo, n_endo)
71-
n_exo+2:n_exo+n_endo+1
72-
end
73-
function find_cols_z(n_exo, n_endo, n_z)
74-
n_exo+n_endo+2:n_exo+n_endo+n_z+1
75-
end

0 commit comments

Comments
 (0)