-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathemalg.R
More file actions
71 lines (69 loc) · 1.68 KB
/
emalg.R
File metadata and controls
71 lines (69 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# libraries --------------------------------------------------------------
library(ropenblas) #for inverting matrices
# EM algorithm ------------------------------------------------------------
estep<-function(x,L,psi){
#finding the expectation of factors (F) given the observations (X)
hat<-solve((L%*%t(L)) + psi)
beta<-t(L)%*%hat
exp<-beta%*%x
n<-dim(L)
n<-n[2]
#finding the second moment of F given X
expsq<-diag(n)-(beta%*%L)+(exp%*%t(exp))
exps<-list("exp"=exp,"expsq"=expsq)
return(exps)
}
mstep<-function(X,L,psi){
sizeL<-dim(L)
col<-rep(0,sizeL[1])
L2<-cbind(col,col,col)
sizeX<-dim(X)
exps<-estep(X[1,],L,psi)
exp<-exps$exp
A<-(X[1,]%*%t(exp))
B<-exps$expsq
#estimating L_new
for (i in (2:sizeX[1])){
exps<-estep(X[i,],L,psi)
exp<-exps$exp
A<-(X[i,]%*%t(exp))+A
B<-exps$expsq+B
}
L2<-A%*%solve(B)
exps<-estep(X[1,],L,psi)
exp<-exps$exp
C<-(X[1,]%*%t(X[1,]))-(L2%*%exp%*%t(X[1,]))
#estimating psi_new
for (i in (2:sizeX[1])){
exps<-estep(X[i,],L,psi)
exp<-exps$exp
C<-(X[i,]%*%t(X[i,]))-(L2%*%exp%*%t(X[i,]))+C
}
psi2<-diag(diag(C))/sizeX[1]
emres<-list("L2"=L2,"psi2"=psi2)
return(emres)
}
emalg<-function(tol,maxite,X,L,psi){
Z<-scale(X)
Sn<-cov(X)
R<-cov2cor(Sn)
i<-1
while (i<maxite){
if (i>1){
psi<-psi2
L<-L2
}
mres<-mstep(Z,L,psi)
L2<-mres$L2
psi2<-mres$psi2
if (max(abs(psi2-psi))>tol & max(abs(L2-L))>tol){
i<-i+1
} else{
break
}
}
scores<-t(L2)%*%solve(R)%*%t(Z)
scores<-t(scores)
res<-list("iterations"=i,"L_new"=L2,"psi_new"=psi2,"scores"=scores)
return(res)
}