@@ -330,7 +330,7 @@ function StatsAPI.fit(::Type{FixedEffectModel},
330330 notcollinear_fe_z = collinear_fe[find_cols_z (n_exo, n_endo, n_z)] .== false
331331 notcollinear_fe_endo_small = notcollinear_fe_endo[basis_endo]
332332
333- basis_all = basis (eachcol ( Xexo) ... , eachcol (Z) ... , eachcol (Xendo)... ; has_intercept = has_intercept)
333+ basis_all = basis (Xexo, Z , eachcol (Xendo)... ; has_intercept = has_intercept)
334334 basis_Xexo = basis_all[1 : size (Xexo, 2 )] .* notcollinear_fe_exo
335335 basis_Z = basis_all[(size (Xexo, 2 ) + 1 ): (size (Xexo, 2 ) + size (Z, 2 ))] .* notcollinear_fe_z
336336 basis_endo_small = basis_all[(size (Xexo, 2 ) + size (Z, 2 ) + 1 ): end ] .* notcollinear_fe_endo_small
@@ -354,7 +354,7 @@ function StatsAPI.fit(::Type{FixedEffectModel},
354354 @info " Endogenous vars collinear with ivs. Recategorized as exogenous: $(out) "
355355
356356 # third pass
357- basis_all = basis (eachcol ( Xexo) ... , eachcol (Z) ... , eachcol ( Xendo) ... ; has_intercept = has_intercept)
357+ basis_all = basis (Xexo, Z, Xendo; has_intercept = has_intercept)
358358 basis_Xexo = basis_all[1 : size (Xexo, 2 )]
359359 basis_Z = basis_all[(size (Xexo, 2 ) + 1 ): (size (Xexo, 2 ) + size (Z, 2 ))]
360360 end
@@ -366,22 +366,22 @@ function StatsAPI.fit(::Type{FixedEffectModel},
366366
367367 # Build
368368 newZ = hcat (Xexo, Z)
369- Pi = ldiv! ( cholesky! ( Symmetric ( newZ' newZ)), newZ ' Xendo)
369+ Pi = ls_solve ( newZ, Xendo)
370370 Xhat = hcat (Xexo, newZ * Pi)
371371 X = hcat (Xexo, Xendo)
372372
373373 # prepare residuals used for first stage F statistic
374374 # # partial out Xendo in place wrt (Xexo, Z)
375375 Xendo_res = BLAS. gemm! (' N' , ' N' , - 1.0 , newZ, Pi, 1.0 , Xendo)
376376 # # partial out Z in place wrt Xexo
377- Pi2 = ldiv! ( cholesky! ( Symmetric ( Xexo' Xexo)), Xexo ' Z)
377+ Pi2 = ls_solve ( Xexo, Z)
378378 Z_res = BLAS. gemm! (' N' , ' N' , - 1.0 , Xexo, Pi2, 1.0 , Z)
379379 else
380380 # get linearly independent columns
381381 n_exo = size (Xexo, 2 )
382382 perm = 1 : n_exo
383383 notcollinear_fe_exo = collinear_fe[find_cols_exo (n_exo)] .== false
384- basis_Xexo = basis (eachcol ( Xexo) ... ; has_intercept = has_intercept) .* notcollinear_fe_exo
384+ basis_Xexo = basis (Xexo; has_intercept = has_intercept) .* notcollinear_fe_exo
385385 Xexo = getcols (Xexo, basis_Xexo)
386386 Xhat = Xexo
387387 X = Xexo
@@ -393,9 +393,11 @@ function StatsAPI.fit(::Type{FixedEffectModel},
393393 # # Do the regression
394394 # #
395395 # #############################################################################
396-
397- crossx = cholesky! (Symmetric (Xhat' Xhat))
398- coef = ldiv! (crossx, Xhat' y)
396+ crossx = Xhat' * Xhat
397+ Xy = Symmetric (hvcat (2 , crossx, Xhat' y, zeros (size (Xhat, 2 ))' , [0.0 ]))
398+ invsym! (Xy; diagonal = 1 : size (Xhat, 2 ))
399+ invcrossx = Symmetric (.- Xy[1 : (end - 1 ),1 : (end - 1 )])
400+ coef = Xy[1 : (end - 1 ),end ]
399401
400402 # #############################################################################
401403 # #
@@ -453,9 +455,8 @@ function StatsAPI.fit(::Type{FixedEffectModel},
453455 end
454456
455457 # Compute standard error
456- vcov_data = Vcov. VcovData (Xhat, crossx, residuals, nobs - size (X, 2 ) - dof_fes)
458+ vcov_data = Vcov. VcovData (Xhat, crossx, invcrossx, residuals, nobs - size (X, 2 ) - dof_fes)
457459 matrix_vcov = StatsAPI. vcov (vcov_data, vcov_method)
458-
459460 # Compute Fstat
460461 F = Fstat (coef, matrix_vcov, has_intercept)
461462 # dof_ is the number of estimated coefficients beyond the intercept.
@@ -465,15 +466,15 @@ function StatsAPI.fit(::Type{FixedEffectModel},
465466 # Compute Fstat of First Stage
466467 if has_iv && first_stage
467468 Pip = Pi[(size (Pi, 1 ) - size (Z_res, 2 ) + 1 ): end , :]
468- try
469+ # try
469470 r_kp = Vcov. ranktest! (Xendo_res, Z_res, Pip,
470471 vcov_method, size (X, 2 ), dof_fes)
471472 p_kp = chisqccdf (size (Z_res, 2 ) - size (Xendo_res, 2 ) + 1 , r_kp)
472473 F_kp = r_kp / size (Z_res, 2 )
473- catch
474- @info " ranktest failed ; first-stage statistics not estimated"
475- p_kp, F_kp = NaN , NaN
476- end
474+ # catch
475+ # @info "ranktest failed ; first-stage statistics not estimated"
476+ # p_kp, F_kp = NaN, NaN
477+ # end
477478 end
478479
479480 # Compute rss, tss
0 commit comments