55
66Calculate the Comparative Fit Index (CFI).
77
8- The CFI ranges from 0-1 and measures how much better the model
8+ The CFI ranges from 0-1 and measures how much better the model
99fits the data compared to a baseline model.
1010If no baseline model is provided, a model with unconstrained
1111variances (and means) is compaired against.
12- For multigroup models, variances (and means) per group are free
12+ For multigroup models, variances (and means) per group are free
1313without any equality constraints between groups.
1414"""
1515function CFI end
@@ -35,34 +35,31 @@ function CFI(χ², dof, χ²₀, dof₀)
3535end
3636
3737# ##
38- function χ²_varonly (model:: AbstractSemSingle )
39- check_single_lossfun (model; throw_error = true )
40- return χ²_varonly (model. loss. functions[1 ], model)
41- end
42-
43- function χ²_varonly (model:: SemEnsemble )
44- check_single_lossfun (model; throw_error = true )
45- return sum (χ²_varonly, model. sems)
38+ function χ²_varonly (model:: AbstractSem )
39+ check_same_semterm_type (model; throw_error = true )
40+ return sum (sem_terms (model)) do semterm
41+ χ²_varonly (_unwrap (loss (semterm)))
42+ end
4643end
4744
48- function χ²_varonly (:: SemML , model :: AbstractSemSingle )
49- N⁻ = (nsamples (model ) - 1 )
50- S = obs_cov (observed (model ))
45+ function χ²_varonly (loss :: SemML )
46+ N⁻ = (nsamples (loss ) - 1 )
47+ S = obs_cov (observed (loss ))
5148 Σ₀ = Diagonal (S)
52- p = nobserved_vars (model )
49+ p = nobserved_vars (loss )
5350 return N⁻* (logdet (Σ₀) + tr (inv (Σ₀)* S) - logdet (S) - p)
5451end
5552
5653# for the optimal variance only model, we have to solve 1/2 tr((I-XS⁻¹)^2) with X diagonal
57- function χ²_varonly (:: SemWLS , model )
58- N⁻ = (nsamples (model ) - 1 )
59- S⁻¹ = inv ((obs_cov (observed (model ))))
54+ function χ²_varonly (loss :: SemWLS )
55+ N⁻ = (nsamples (loss ) - 1 )
56+ S⁻¹ = inv ((obs_cov (observed (loss ))))
6057 Σ₀ = Diagonal (inv (S⁻¹ .* S⁻¹)* diag (S⁻¹))
6158 return N⁻* 0.5 * tr ((I - Σ₀* S⁻¹)^ 2 )
6259end
6360
6461# For FIML, an explicit bl model has to be passed
65- function χ²_varonly (:: SemFIML , model )
62+ function χ²_varonly (loss :: SemFIML )
6663 """
6764 Computing the CFI with FIML requires explicitely passing a fitted baseline model as
6865 CFI(fit::SemFit, fit_baseline::SemFit)
@@ -71,12 +68,12 @@ function χ²_varonly(::SemFIML, model)
7168 throw
7269end
7370
74- function dof_varonly (model:: AbstractSemSingle )
75- nparams_varonly = nobserved_vars (model)
76- if MeanStruct (model. implied) === HasMeanStruct
77- nparams_varonly *= 2
71+ function dof_varonly (model:: AbstractSem )
72+ return sum (sem_terms (model)) do semterm
73+ nparams_varonly = nobserved_vars (semterm)
74+ if MeanStruct (implied (semterm)) === HasMeanStruct
75+ nparams_varonly *= 2
76+ end
77+ return n_dp (loss (semterm)) - nparams_varonly
7878 end
79- return n_dp (model) - nparams_varonly
8079end
81-
82- dof_varonly (model:: SemEnsemble ) = sum (dof_varonly, model. sems)
0 commit comments