Nothing
.restr.none <- function (iter, pa)
{
iter$code = TRUE
return (iter)
}
## restricts the clusters' covariance matrices by averaging them
.restr.avgcov <- function (iter, pa)
{
s.all <- matrix (0, pa$p, pa$p)
for (k in 1:pa$K)
s.all <- s.all + iter$sigma[,,k] * iter$csize[k]/sum(iter$csize)
iter$sigma[,,] <- s.all ##
iter$code = sum(diag (s.all)) > pa$zero.tol
return (iter)
}
## restricts the clusters' covariance matrices by restricting it's eigenvalues or determinants without restrics directions
.restr.diffax <- function (iter, pa, f.restr.eigen = .restr2_eigenv, restr.deter, restr.fact = 12)
{
if (pa$p == 1) # one - dimensional
if (restr.fact == 1) # all variances should be equal -> use the simpler .restr.avgcov function instead
return (.restr.avgcov (iter, pa)) #
else #
restr.deter <- FALSE # else - if p == 1 always use the simpler eigen - restriction
if (!missing (restr.deter)) # evaluating the appropriate restriction function
f.restr.eigen <- if (restr.deter) .restr2_deter_ else .restr2_eigenv #n
u <- array (NA, c(pa$p, pa$p, pa$K))
d <- array (NA, c(pa$p, pa$K))
for (k in 1:pa$K)
{
ev <- eigen (iter$sigma[,,k])
u [,,k] <- ev$vectors
d [,k] <- ev$values
}
d [d < 0] <- 0 ## all eigenvalue < 0 are restricted to 0 BECAUSE: min (d) < 0 -> max (d) / min (d) < 0 which would always fit our eigenvalue - criterion!
## there is *NO* reason *AT ALL* for touching *ANY* eigenvalue > 0!! (e.g. 0 <= d < 1e-16!)
d <- f.restr.eigen (d, iter$csize, restr.fact, pa$zero.tol)
## checking for singularity in all clusters.
iter$code = max(d) > pa$zero.tol
if (!iter$code)
return (iter)
for (k in 1:pa$K) ## re-composing the sigmas
iter$sigma[,,k] <- u[,,k] %*% diag (d[,k], nrow = pa$p) %*% t(u[,,k])
return (iter)
}
.diag_matmult_y_x_yt <- function (x, y) diag (y %*% x %*% t(y)) # a simple helper function for use with "apply"
.sum_diag_matmult_y_x <- function (x, y) sum (diag (y %*% x)) # a simple helper function for use with "apply"
# Function for restricted principal components which allows restrictions type 0 and 1
.restr.dir <- function (iter, pa, restr.deter = FALSE, restr.fact = 12, n_inic = 10, n_iter1 = 10, n_iter2 = 10, ...)
{
if (pa$p == 1 || # only one dim -> use the simpler .restr.diffax function instead, as directions make no sense here.
(restr.fact == 1 && !restr.deter)) # all eigenvalues should be equal -> use the simpler .restr.diffax function instead!
return (.restr.diffax (iter, pa, restr.fact = restr.fact))
# evaluating the appropriate restriction function
f.restr.eigen <- if (restr.deter) .restr2_deter_ else .restr2_eigenv
for (inic in 1:n_inic)
{
#initial solution for u
#o ee <- matrix(runif(pa$p*pa$p, min=0, max=1),pa$p,pa$p)
ee <- matrix (rnorm (pa$p * (pa$p+1)), ncol=pa$p) #n as suggested by agustin 20110217
w <- eigen(t(ee)%*%ee)
u <- w$vectors
#iterations
for (iter1 in 1: n_iter1)
{
dd <- apply (iter$sigma, 3, .diag_matmult_y_x_yt , y = t(u))
dd <- f.restr.eigen (dd, iter$csize, restr.fact, pa$zero.tol)
u <- .optvectors (iter, pa, u, dd, n.iter = n_iter2, ...)
}
res <- 0
for (i in 1:pa$K)
res <- res + iter$csize[i] * sum (diag (u %*% diag (1 / dd[,i]) %*% t (u) %*% iter$sigma[,,i]))
## no need to store all solutions; only saving the best solution
if (inic == 1 || res < best$res) #n store the first/best solution
best <- list (u = u, dd = dd, res = res)
}
## reconstructing sgima
iter$code <- max(best$dd) > pa$zero.tol
if (!iter$code) # if function failed
return (iter)
# calculate the new sigmas
for (i in 1:pa$K) # using the best found solution
iter$sigma[,, i] <- best$u %*% diag (best$dd[, i]) %*% t (best$u)
return(iter)
}
# Function for vector optimization
.optvectors <- function (iter, pa, u, d, n.iter, ovv = 0)
{
#iterations in each pair of directions
for (iter2 in 1:n.iter)
{
#t for (j in 1:pa$p)
for (j in 1:(pa$p - 1))
{
#t for (m in 1: pa$p)
for (m in (j+1): pa$p)
{
a_mj <- matrix(0, pa$p, pa$p)
for (i in 1:pa$K)
a_mj <- a_mj + (d[j,i] - d[m,i] ) / (d[j,i] * d[m,i] ) * iter$csize[i] * iter$sigma[,,i] ## NOTE - this is actually equal for each iteration of iter2. Thus these values could be calculated in a
a2_mj <- t (u[,c(j,m)]) %*% a_mj %*% u[,c(j,m)]
v <- eigen(a2_mj)
uu <- u[,c(j,m)] %*% v$vectors
#cat ("values:\n")
#print (v$values)
#cat ("vecs:\n")
#print (v$vectors)
##browser ()
if (ovv == 0)
{
## ### NEW: new part without checking for labels and signs.
u[,j] <- uu[,1]
u[,m] <- uu[,2]
}
else if (ovv == 1)
{
## ### 2DELETE: old part which checked the labels and signs
#checking labels and signs in order to allow identifiability
up1 <- up2 <- u
up1[,j] <- up2[,m] <- uu[,1]
up1[,m] <- up2[,j] <- uu[,2]
resp1 <- resp2 <- 0
for (i in 1:pa$K)
{
resp1 <- resp1 + iter$csize[i] * sum (diag (up1 %*% diag (1 / d[,i]) %*% t (up1) %*% iter$sigma[,,i])) #n extracted iter$csize[i] out of sum (diag (...))
resp2 <- resp2 + iter$csize[i] * sum (diag (up2 %*% diag (1 / d[,i]) %*% t (up2) %*% iter$sigma[,,i])) #n
}
less <- (resp1 - resp2) <= sqrt (pa$zero.tol)
neg1 <- t (uu[, 1 + !less]) %*% u[, j] < 0 # transforming the logical variable ("less") into the appropriate index
neg2 <- t (uu[, 1 + less]) %*% u[, m] < 0 #
u <- if (less) up1 else up2 # storing the proper up1 or up2 matrix in u
if (neg1) u[, j] <- -u[, j] # changing the sign of the proper columns (if necessary)
if (neg2) u[, m] <- -u[, m]
}
# print (u)
# cat ("\n")
}
}
}
return(u)
}
# Function for proporcionality case (only restrictions type 1 are allowed )
.restr.prop <- function (iter, pa, restr.fact = 12, n_inic = 10, n_iter1 = 10, n_iter2 = 10, ...)
{
if (pa$p == 1) ## only one dim -> use the simpler .restr.diffax function instead!
return (.restr.diffax (iter, pa, restr.fact = restr.fact))
if (restr.fact == 1) ## all covmats should be exactly equal -> use the simpler .restr.avgcov function instead!
return (.restr.avgcov (iter, pa))
for (inic in 1:n_inic)
{
#initial solution
#o ee <- matrix (runif (pa$p * pa$p, min = 0, max = 1), pa$p, pa$p)
ee <- matrix (rnorm (pa$p * (pa$p+1)), ncol=pa$p) #n as suggested by agustin 20110217
w <- eigen (t (ee) %*% ee)
u <- w$vectors
sf <- w$values / (prod (w$values)^(1/pa$p))
## remark: if w$values[pa$p] is very small we might run in numerical problems here!
#iterations
for (iter1 in 1: n_iter1)
{
dd <- apply (iter$sigma, 3, .diag_matmult_y_x_yt , y = t(u))
st <- colSums (dd / sf) / pa$p
st <- .restr2_eigenv (t (st), iter$csize, restr.fact^(1 / pa$p), pa$zero.tol)
sf <- colSums (t (dd) * iter$csize / as.numeric (st))
sf <- sf / prod(sf)^(1 / pa$p)
#u estimation
dd <- sf %*% st # st is a 1 x K matrix (from .restr2_eigenv)
u <- .optvectors(iter, pa, u, dd, n.iter = n_iter2, ...)
}
tempSum <- apply (iter$sigma, 3, .sum_diag_matmult_y_x, y = u %*% diag (1/sf) %*% t (u))
res <- sum (iter$csize * (log (st^pa$p) + tempSum / st))
if (inic == 1 || res < best$res)
best <- list (u = u, sf = sf, st = st, res = res)
}
iter$code <- max(best$sf) > pa$zero.tol
if (!iter$code) # if function failed
return (iter)
# reconstruct the sigma - matrices
for (i in 1:pa$K)
iter$sigma[,,i] <- best$st[i] * best$u %*% diag (best$sf) %*% t (best$u)
#a iter$sigma <- sapply (best$st, get ("*"), sigmaBase, simplify = FALSE) - iter$sigma #a alternative: think about future representation of sigma as a list!
return(iter)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.