Skip to content

Commit 71f3a89

Browse files
Merge pull request #198 from alyst/fixes_2
Misc.Fixes 2
2 parents 78fa37a + d9884ae commit 71f3a89

File tree

18 files changed

+333
-506
lines changed

18 files changed

+333
-506
lines changed

src/StructuralEquationModels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export AbstractSem,
142142
update_partable!,
143143
update_estimate!,
144144
update_start!,
145+
update_se_hessian!,
145146
Fixed,
146147
fixed,
147148
Start,

src/additional_functions/helper.jl

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
function neumann_series(mat::SparseMatrixCSC)
1+
# Neumann series representation of (I - mat)⁻¹
2+
function neumann_series(mat::SparseMatrixCSC; maxiter::Integer = size(mat, 1))
23
inverse = I + mat
34
next_term = mat^2
45

6+
n = 1
57
while nnz(next_term) != 0
8+
(n <= maxiter) || error("Neumann series did not converge in $maxiter steps")
69
inverse += next_term
710
next_term *= mat
11+
n += 1
812
end
913

1014
return inverse
@@ -37,13 +41,8 @@ function get_observed(rowind, data, semobserved; args = (), kwargs = NamedTuple(
3741
return observed_vec
3842
end
3943

40-
function skipmissing_mean(mat)
41-
means = Vector{Float64}(undef, size(mat, 2))
42-
for i in 1:size(mat, 2)
43-
@views means[i] = mean(skipmissing(mat[:, i]))
44-
end
45-
return means
46-
end
44+
skipmissing_mean(mat::AbstractMatrix) =
45+
[mean(skipmissing(coldata)) for coldata in eachcol(mat)]
4746

4847
function F_one_person(imp_mean, meandiff, inverse, data, logdet)
4948
F = logdet
@@ -52,10 +51,10 @@ function F_one_person(imp_mean, meandiff, inverse, data, logdet)
5251
return F
5352
end
5453

55-
function remove_all_missing(data)
54+
function remove_all_missing(data::AbstractMatrix)
5655
keep = Vector{Int64}()
57-
for i in 1:size(data, 1)
58-
if any(.!ismissing.(data[i, :]))
56+
for (i, coldata) in zip(axes(data, 1), eachrow(data))
57+
if any(!ismissing, coldata)
5958
push!(keep, i)
6059
end
6160
end

src/additional_functions/parameters.jl

Lines changed: 29 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,19 @@ function check_constants(M)
8686
return false
8787
end
8888

89-
function get_matrix_derivative(M_indices, parameters, n_long)
90-
∇M = [
91-
sparsevec(M_indices[i], ones(length(M_indices[i])), n_long) for
92-
i in 1:length(parameters)
93-
]
94-
95-
∇M = reduce(hcat, ∇M)
96-
97-
return ∇M
89+
# construct length(M)×length(parameters) sparse matrix of 1s at the positions,
90+
# where the corresponding parameter occurs in the M matrix
91+
function matrix_gradient(M_indices::ArrayParamsMap, M_length::Integer)
92+
rowval = reduce(vcat, M_indices)
93+
colptr =
94+
pushfirst!(accumulate((ptr, M_ind) -> ptr + length(M_ind), M_indices, init = 1), 1)
95+
return SparseMatrixCSC(
96+
M_length,
97+
length(M_indices),
98+
colptr,
99+
rowval,
100+
ones(length(rowval)),
101+
)
98102
end
99103

100104
# fill M with parameters
@@ -111,97 +115,23 @@ function fill_matrix!(
111115
return M
112116
end
113117

114-
function get_partition(A_indices, S_indices)
115-
n_par = length(A_indices)
116-
117-
first_A = "a"
118-
first_S = "a"
119-
last_A = "a"
120-
last_S = "a"
121-
122-
for i in 1:n_par
123-
if length(A_indices[i]) != 0
124-
first_A = i
125-
break
126-
end
127-
end
128-
129-
for i in 1:n_par
130-
if length(S_indices[i]) != 0
131-
first_S = i
132-
break
133-
end
134-
end
135-
136-
for i in n_par + 1 .- (1:n_par)
137-
if length(A_indices[i]) != 0
138-
last_A = i
139-
break
140-
end
141-
end
142-
143-
for i in n_par + 1 .- (1:n_par)
144-
if length(S_indices[i]) != 0
145-
last_S = i
146-
break
147-
end
148-
end
149-
150-
for i in first_A:last_A
151-
if length(A_indices[i]) == 0
152-
throw(
153-
ErrorException(
154-
"Your parameter vector is not partitioned into directed and undirected effects",
155-
),
156-
)
157-
return nothing
158-
end
159-
end
160-
161-
for i in first_S:last_S
162-
if length(S_indices[i]) == 0
163-
throw(
164-
ErrorException(
165-
"Your parameter vector is not partitioned into directed and undirected effects",
166-
),
167-
)
168-
return nothing
169-
end
170-
end
171-
172-
return first_A:last_A, first_S:last_S
173-
end
174-
175-
function get_partition(M_indices)
176-
n_par = length(M_indices)
177-
178-
first_M = "a"
179-
last_M = "a"
180-
181-
for i in 1:n_par
182-
if length(M_indices[i]) != 0
183-
first_M = i
184-
break
185-
end
186-
end
187-
188-
for i in n_par + 1 .- (1:n_par)
189-
if length(M_indices[i]) != 0
190-
last_M = i
191-
break
192-
end
193-
end
194-
195-
for i in first_M:last_M
196-
if length(M_indices[i]) == 0
197-
throw(
198-
ErrorException(
199-
"Your parameter vector is not partitioned into directed, undirected and mean effects",
200-
),
201-
)
202-
return nothing
118+
# range of parameters that are referenced in the matrix
119+
function param_range(mtx_indices::AbstractArrayParamsMap)
120+
first_i = findfirst(!isempty, mtx_indices)
121+
last_i = findlast(!isempty, mtx_indices)
122+
123+
if !isnothing(first_i) && !isnothing(last_i)
124+
for i in first_i:last_i
125+
if isempty(mtx_indices[i])
126+
# TODO show which parameter is missing in which matrix
127+
throw(
128+
ErrorException(
129+
"Your parameter vector is not partitioned into directed and undirected effects",
130+
),
131+
)
132+
end
203133
end
204134
end
205135

206-
return first_M:last_M
136+
return first_i:last_i
207137
end

0 commit comments

Comments
 (0)