@@ -41,37 +41,30 @@ function fit!(
41
41
for k in 1 : 2
42
42
model. Σ[k] .= inv (tr (model. V[k])) .* model. storage_d_d_1
43
43
end
44
- copy! (model. storage_d_d_1, model. Σ[1 ])
45
- copy! (model. storage_d_d_2, model. Σ[2 ])
46
- Λ, Φ = eigen! (Symmetric (model. storage_d_d_1), Symmetric (model. storage_d_d_2))
47
- copy! (model. Λ, Λ)
48
- copy! (model. Φ, Φ)
49
- copyto! (model. logdetΣ2, logdet (model. Σ[2 ]))
50
- mul! (model. ỸΦ, model. Ỹ, model. Φ)
51
- mul! (model. BΦ, model. B, model. Φ)
52
- update_res! (model) # update R̃Φ
44
+ update_Φ! (model)
45
+ update_res! (model)
53
46
elseif init == :user
54
- copy! (model. storage_d_d_1, model. Σ[1 ])
55
- copy! (model. storage_d_d_2, model. Σ[2 ])
56
- Λ, Φ = eigen! (Symmetric (model. storage_d_d_1), Symmetric (model. storage_d_d_2))
57
- copy! (model. Λ, Λ)
58
- copy! (model. Φ, Φ)
59
- copyto! (model. logdetΣ2, logdet (model. Σ[2 ]))
60
- mul! (model. ỸΦ, model. Ỹ, model. Φ)
61
- mul! (model. BΦ, model. B, model. Φ)
62
- update_res! (model) # update R̃Φ
47
+ update_Φ! (model)
48
+ update_res! (model)
63
49
else
64
50
throw (" Cannot recognize initialization method $init " )
65
51
end
66
52
logl = loglikelihood! (model)
67
53
toc = time ()
54
+ verbose && println (" iter = 0, logl = $logl " )
55
+ IterativeSolvers. nextiter! (history)
56
+ push! (history, :iter , 0 )
57
+ push! (history, :logl , logl)
58
+ push! (history, :itertime , toc - tic)
68
59
# MM loop
69
60
for iter in 1 : maxiter
70
61
IterativeSolvers. nextiter! (history)
71
62
tic = time ()
72
63
# initial estiamte of Σ[i] can be lousy, so we update Σ[i] first in the 1st round
73
64
p > 0 && iter > 1 && update_B! (model)
74
65
update_Σ! (model)
66
+ update_Φ! (model)
67
+ update_res! (model)
75
68
logl_prev = logl
76
69
logl = loglikelihood! (model)
77
70
toc = time ()
@@ -157,7 +150,7 @@ function update_Σ!(
157
150
end
158
151
lmul! (Diagonal (one (T) ./ model. storage_d_1), vecs)
159
152
mul! (model. storage_d_d_1, transpose (Φinv), vecs)
160
- mul! (model. Σ[1 ], transpose ( model. storage_d_d_1), model. storage_d_d_1)
153
+ mul! (model. Σ[1 ], model. storage_d_d_1, transpose ( model. storage_d_d_1) )
161
154
# update Σ[2]
162
155
lmul! (Diagonal (model. storage_d_2), model. N2tN2)
163
156
rmul! (model. N2tN2, Diagonal (model. storage_d_2))
@@ -176,8 +169,13 @@ function update_Σ!(
176
169
end
177
170
lmul! (Diagonal (one (T) ./ model. storage_d_2), vecs)
178
171
mul! (model. storage_d_d_1, transpose (Φinv), vecs)
179
- mul! (model. Σ[2 ], transpose (model. storage_d_d_1), model. storage_d_d_1)
180
- # update parameters
172
+ mul! (model. Σ[2 ], model. storage_d_d_1, transpose (model. storage_d_d_1))
173
+ model. Σ
174
+ end
175
+
176
+ function update_Φ! (
177
+ model :: MRTVCModel{T} ;
178
+ ) where T <: BlasReal
181
179
copy! (model. storage_d_d_1, model. Σ[1 ])
182
180
copy! (model. storage_d_d_2, model. Σ[2 ])
183
181
Λ, Φ = eigen! (Symmetric (model. storage_d_d_1), Symmetric (model. storage_d_d_2))
@@ -186,8 +184,30 @@ function update_Σ!(
186
184
copyto! (model. logdetΣ2, logdet (model. Σ[2 ]))
187
185
mul! (model. ỸΦ, model. Ỹ, model. Φ)
188
186
mul! (model. BΦ, model. B, model. Φ)
189
- update_res! (model) # update R̃Φ
190
- model. Σ
187
+ end
188
+
189
+ function update_res! (
190
+ model :: MRTVCModel{T}
191
+ ) where T <: BlasReal
192
+ # update R̃Φ = (Ỹ - X̃B)Φ
193
+ BLAS. gemm! (' N' , ' N' , - one (T), model. X̃, model. BΦ, one (T), copyto! (model. R̃Φ, model. ỸΦ))
194
+ model. R̃Φ
195
+ end
196
+
197
+ function loglikelihood! (
198
+ model :: MRTVCModel{T}
199
+ ) where T <: BlasReal
200
+ n, d = size (model. Ỹ, 1 ), size (model. Ỹ, 2 )
201
+ # assemble pieces for log-likelihood
202
+ logl = n * d * log (2 π) + n * model. logdetΣ2[1 ] + d * model. logdetV2[1 ]
203
+ @inbounds for j in 1 : d
204
+ λj = model. Λ[j]
205
+ @simd for i in 1 : n
206
+ tmp = model. D[i] * λj + one (T)
207
+ logl += log (tmp) + inv (tmp) * model. R̃Φ[i, j]^ 2
208
+ end
209
+ end
210
+ logl /= - 2
191
211
end
192
212
193
213
function update_B! (
@@ -216,30 +236,6 @@ function update_B!(
216
236
model. B
217
237
end
218
238
219
- function loglikelihood! (
220
- model :: MRTVCModel{T}
221
- ) where T <: BlasReal
222
- n, d = size (model. Ỹ, 1 ), size (model. Ỹ, 2 )
223
- # assemble pieces for log-likelihood
224
- logl = n * d * log (2 π) + n * model. logdetΣ2[1 ] + d * model. logdetV2[1 ]
225
- @inbounds for j in 1 : d
226
- λj = model. Λ[j]
227
- @simd for i in 1 : n
228
- tmp = model. D[i] * λj + one (T)
229
- logl += log (tmp) + inv (tmp) * model. R̃Φ[i, j]^ 2
230
- end
231
- end
232
- logl /= - 2
233
- end
234
-
235
- function update_res! (
236
- model :: MRTVCModel{T}
237
- ) where T <: BlasReal
238
- # update R̃Φ = (Ỹ - X̃B)Φ
239
- BLAS. gemm! (' N' , ' N' , - one (T), model. X̃, model. BΦ, one (T), copyto! (model. R̃Φ, model. ỸΦ))
240
- model. R̃Φ
241
- end
242
-
243
239
function fisher_B! (
244
240
model :: MRTVCModel{T}
245
241
) where T <: BlasReal
@@ -252,7 +248,7 @@ function fisher_B!(
252
248
end
253
249
lmul! (Diagonal (model. storage_nd_1), model. storage_nd_pd)
254
250
mul! (model. storage_pd_pd, transpose (model. storage_nd_pd), model. storage_nd_pd)
255
- copyto! (model. Bcov, pinv (storage_pd_pd))
251
+ copyto! (model. Bcov, pinv (model . storage_pd_pd))
256
252
end
257
253
258
254
function fisher_Σ! (
@@ -301,7 +297,7 @@ function fisher_Σ!(
301
297
idx1 = Int (d * (d + 1 ) / 2 * (i - 1 ) + 1 )
302
298
idx2 = Int (d * (d + 1 ) / 2 * i)
303
299
idx5, idx6 = d^ 2 * (i - 1 ) + 1 , d^ 2 * i
304
- for j in i: m
300
+ for j in i: 2
305
301
idx3 = Int (d * (d + 1 ) / 2 * (j - 1 ) + 1 )
306
302
idx4 = Int (d * (d + 1 ) / 2 * j)
307
303
idx7, idx8 = d^ 2 * (j - 1 ) + 1 , d^ 2 * j
0 commit comments