1- function fill_A_S_M (A, S, M, A_indices, S_indices, M_indices, parameters)
2- for (iA, iS, par) in zip (A_indices, S_indices, parameters)
1+ # fill A, S, and M matrices with the parameter values according to the parameters map
2+ function fill_A_S_M! (
3+ A:: AbstractMatrix ,
4+ S:: AbstractMatrix ,
5+ M:: Union{AbstractVector, Nothing} ,
6+ A_indices:: AbstractArrayParamsMap ,
7+ S_indices:: AbstractArrayParamsMap ,
8+ M_indices:: Union{AbstractArrayParamsMap, Nothing} ,
9+ parameters:: AbstractVector ,
10+ )
11+ @inbounds for (iA, iS, par) in zip (A_indices, S_indices, parameters)
312 for index_A in iA
413 A[index_A] = par
514 end
@@ -10,22 +19,28 @@ function fill_A_S_M(A, S, M, A_indices, S_indices, M_indices, parameters)
1019 end
1120
1221 if ! isnothing (M)
13- for (iM, par) in zip (M_indices, parameters)
22+ @inbounds for (iM, par) in zip (M_indices, parameters)
1423 for index_M in iM
1524 M[index_M] = par
1625 end
1726 end
1827 end
1928end
2029
21- function get_parameter_indices (parameters, M; linear = true , kwargs... )
22- M_indices = [findall (x -> (x == par), M) for par in parameters]
23-
24- if linear
25- M_indices = cartesian2linear .(M_indices, [M])
30+ # build the map from the index of the parameter to the linear indices
31+ # of this parameter occurences in M
32+ # returns ArrayParamsMap object
33+ function array_parameters_map (parameters:: AbstractVector , M:: AbstractArray )
34+ params_index = Dict (param => i for (i, param) in enumerate (parameters))
35+ T = Base. eltype (eachindex (M))
36+ res = [Vector {T} () for _ in eachindex (parameters)]
37+ for (i, val) in enumerate (M)
38+ par_ind = get (params_index, val, nothing )
39+ if ! isnothing (par_ind)
40+ push! (res[par_ind], i)
41+ end
2642 end
27-
28- return M_indices
43+ return res
2944end
3045
3146function eachindex_lower (M; linear_indices = false , kwargs... )
@@ -49,9 +64,6 @@ function linear2cartesian(ind_lin, dims)
4964 return ind_cart
5065end
5166
52- cartesian2linear (ind_cart, A:: AbstractArray ) = cartesian2linear (ind_cart, size (A))
53- linear2cartesian (ind_linear, A:: AbstractArray ) = linear2cartesian (ind_linear, size (A))
54-
5567function set_constants! (M, M_pre)
5668 for index in eachindex (M)
5769 δ = tryparse (Float64, string (M[index]))
@@ -74,116 +86,52 @@ function check_constants(M)
7486 return false
7587end
7688
77- function get_matrix_derivative (M_indices, parameters, n_long)
78- ∇M = [
79- sparsevec (M_indices[i], ones (length (M_indices[i])), n_long) for
80- i in 1 : length (parameters)
81- ]
82-
83- ∇M = reduce (hcat, ∇M)
84-
85- 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+ )
86102end
87103
88- function fill_matrix (M, M_indices, parameters)
104+ # fill M with parameters
105+ function fill_matrix! (
106+ M:: AbstractMatrix ,
107+ M_indices:: AbstractArrayParamsMap ,
108+ parameters:: AbstractVector ,
109+ )
89110 for (iM, par) in zip (M_indices, parameters)
90111 for index_M in iM
91112 M[index_M] = par
92113 end
93114 end
115+ return M
94116end
95117
96- function get_partition (A_indices, S_indices)
97- n_par = length (A_indices)
98-
99- first_A = " a"
100- first_S = " a"
101- last_A = " a"
102- last_S = " a"
103-
104- for i in 1 : n_par
105- if length (A_indices[i]) != 0
106- first_A = i
107- break
108- end
109- end
110-
111- for i in 1 : n_par
112- if length (S_indices[i]) != 0
113- first_S = i
114- break
115- end
116- end
117-
118- for i in n_par + 1 .- (1 : n_par)
119- if length (A_indices[i]) != 0
120- last_A = i
121- break
122- end
123- end
124-
125- for i in n_par + 1 .- (1 : n_par)
126- if length (S_indices[i]) != 0
127- last_S = i
128- break
129- end
130- end
131-
132- for i in first_A: last_A
133- if length (A_indices[i]) == 0
134- throw (
135- ErrorException (
136- " Your parameter vector is not partitioned into directed and undirected effects" ,
137- ),
138- )
139- return nothing
140- end
141- end
142-
143- for i in first_S: last_S
144- if length (S_indices[i]) == 0
145- throw (
146- ErrorException (
147- " Your parameter vector is not partitioned into directed and undirected effects" ,
148- ),
149- )
150- return nothing
151- end
152- end
153-
154- return first_A: last_A, first_S: last_S
155- end
156-
157- function get_partition (M_indices)
158- n_par = length (M_indices)
159-
160- first_M = " a"
161- last_M = " a"
162-
163- for i in 1 : n_par
164- if length (M_indices[i]) != 0
165- first_M = i
166- break
167- end
168- end
169-
170- for i in n_par + 1 .- (1 : n_par)
171- if length (M_indices[i]) != 0
172- last_M = i
173- break
174- end
175- end
176-
177- for i in first_M: last_M
178- if length (M_indices[i]) == 0
179- throw (
180- ErrorException (
181- " Your parameter vector is not partitioned into directed, undirected and mean effects" ,
182- ),
183- )
184- 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
185133 end
186134 end
187135
188- return first_M : last_M
136+ return first_i : last_i
189137end
0 commit comments