Nothing
mixcirc.mle <- function(u, type = "vm", rads = TRUE, g = 2, tol = 1e-4, maxiters = 500) {
if ( type == "vm" ) {
res <- .mixvm.mle(u, rads, g, tol, maxiters)
mu <- res$param[, 3:4]
mu <- ( atan(mu[, 2]/mu[, 1]) + pi * I(mu[, 1] < 0) ) %% (2 * pi)
res$param <- cbind( res$param[, 1], mu, res$param[, 2] )
colnames(res$param) <- c("probs", "mu", "kappa")
} else if ( type == "cp" ) {
res <- .mixpurka.mle(u, rads, g, tol, maxiters)
mu <- res$param[, 2:3]
mu <- ( atan(mu[, 2]/mu[, 1]) + pi * I(mu[, 1] < 0) ) %% (2 * pi)
res$param <- cbind( res$param[, 1], mu, res$param[, 4] )
colnames(res$param) <- c("probs", "theta", "alpha")
} else if ( type == "pn" ) {
res <- .mixpn.mle(u, rads, g, tol, maxiters)
mu <- res$param[, 2:3]
mu <- ( atan(mu[, 2]/mu[, 1]) + pi * I(mu[, 1] < 0) ) %% (2 * pi)
res$param <- cbind( res$param[, 1], mu, res$param[, 4] )
colnames(res$param) <- c("probs", "mu", "gamma")
} else if ( type == "gcpc" ) {
res <- .mixgcpc.mle(u, rads, g, tol, maxiters)
} else if ( type == "cipc" ) {
res <- .mixcipc.mle(u, rads, g, tol, maxiters)
mu <- res$param[, 3:4]
mu <- ( atan(mu[, 2]/mu[, 1]) + pi * I(mu[, 1] < 0) ) %% (2 * pi)
res$param <- cbind( res$param[, 1], mu, res$param[, 2] )
colnames(res$param) <- c( "probs", "omega", "gamma")
}
res
}
.mixvm.mle <- function(u, rads = TRUE, g = 2, tol = 1e-4, maxiters = 100) {
if ( ! rads ) u <- u * pi / 180
x <- cbind( cos(u), sin(u) )
res <- Directional::mixvmf.mle(x, g, n.start = 10, tol = tol, maxiters = maxiters)
names(res)[[ 4 ]] <- "probs"
res
}
.mixcipc.mle <- function(u, rads = TRUE, g = 2, tol = 1e-4, maxiters = 100) {
if ( ! rads ) u <- u * pi / 180
x <- cbind( cos(u), sin(u) )
res <- Directional::mixspcauchy.mle(x, g, n.start = 10, tol = tol, maxiters = maxiters)
names(res)[[ 5 ]] <- "probs"
res
}
.mixpurka.mle <- function(u, rads = TRUE, g = 2, tol = 1e-4, maxiters = 100) {
fun2 <- function(wlika, rswlika, x, g, param, lika) {
wij <- wlika / rswlika ## weights
pj <- Rfast::colmeans(wij) # PANOS
for ( j in 1:g ) {
mod <- .wpurka.mle(x, w = wij[, j])
theta <- mod$theta
a <- mod$alpha
param[j, ] <- c(theta, a)
v <- drop(x %*% theta)
v <- pmin(pmax(v, -1), 1)
lika[, j] <- log(a) - log( 1 - exp(-a * pi) ) - a * acos(v) + log( pj[j] )
}
wlika <- exp(lika) #PANOS
rswlika <- Rfast::rowsums(wlika) #PANOS
lik <- sum( log( rswlika ) ) #PANOS
wij <- wlika / rswlika
list(wij = wij, param = param, wlika = wlika, rswlika = rswlika, lika = lika, lik = lik)
}
if ( !rads ) u <- u * pi / 180
x <- cbind( cos(u), sin(u) )
n <- dim(x)[1]
lik <- NULL
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
runtime <- proc.time()
## Step 1
if ( g > 1 ) {
cl <- kmeans(x, g, nstart = 10)$cl
} else cl <- rep(1, n)
wij <- tabulate(cl)
while ( min(wij) <= 6 ) {
g <- g - 1
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
cl <- kmeans(x, g, nstart = 10)$cl
wij <- tabulate(cl)
}
for ( j in 1:g ) {
mod <- Directional::purka.mle(x[cl == j, ])
theta <- mod$theta
a <- mod$alpha
param[j, ] <- c(theta, a)
v <- drop(x %*% theta)
v <- pmin(pmax(v, -1), 1)
lika[, j] <- log(a) - log(1 - exp(-a * pi)) - a * acos(v)
}
wlika <- exp(lika)
rswlika <- Rfast::rowsums(wlika)
ep <- fun2(wlika, rswlika, x, g, param, lika)
lik[1] <- ep$lik
ep2 <- fun2(ep$wlika, ep$rswlika, x, g, ep$param, ep$lika)
lik[2] <- ep2$lik
i <- 2
while ( abs(lik[i] - lik[i - 1] ) > tol & i < maxiters ) {
i <- i + 1
ep <- ep2
ep2 <- fun2(ep$wlika, ep$rswlika, x, g, ep$param, ep$lika)
lik[i] <- ep2$lik
}
res <- ep2
if ( ep$lik > ep2$lik ) res <- ep
pj <- Rfast::colmeans(res$wij)
probs <- res$wij
loglik <- res$lik
ta <- Rfast::rowMaxs(res$wij) ## estimated cluster of each observation
param <- cbind(pj, res$param)
colnames(param) <- c( "probs", paste("theta", 1:2, sep = ""), "alpha" )
rownames(param) <- paste("Cluster", 1:g, sep = " ")
runtime <- proc.time() - runtime
list( param = param, loglik = loglik - n * log(2),
pred = ta, probs = probs, iters = i, runtime = runtime )
}
.wpurka.mle <- function(x, w = NULL, tol = 1e-07) {
n <- dim(x)[1]
sw <- sum(w)
eps <- 1e-6
theta <- Rfast::mediandir(x) # unweighted start
for ( iter in 1:500 ) {
ct <- drop(x %*% theta)
ct <- pmin(pmax(ct, -1 + eps), 1 - eps) # keep away from +/-1
d <- pmax(acos(ct), eps)
wts <- w / d
g <- Rfast::eachcol.apply(x, wts)
g_norm <- sqrt( sum(g^2) )
if ( g_norm < eps ) break # already at a Weiszfeld fixed point
theta_new <- g / g_norm
if ( sqrt( sum( (theta_new - theta)^2 ) ) < tol ) {
theta <- theta_new
break
}
theta <- theta_new
}
a <- drop(x %*% theta)
a[ is.na(a) ] <- 0
a <- pmin(pmax(a, -1), 1)
A <- sum( w * acos(a) ) # WEIGHTED sum of geodesic distances
circle <- function(a, A, sw) sw * log(a) - sw * log( 1 - exp(-a * pi) ) - a * A
lika <- optimize(circle, c(0.001, 1000), maximum = TRUE, A = A, sw = sw, tol = tol)
list(theta = theta, alpha = lika$maximum, loglik = lika$objective - sw * log(2) )
}
.mixpn.mle <- function(u, rads = TRUE, g = 2, tol = 1e-4, maxiters = 100) {
fun2 <- function(wlika, rswlika, x, g, param, lika) {
wij <- wlika / rswlika ## weights
pj <- Rfast::colmeans(wij) # PANOS
f <- - 0.5 ; con <- sqrt(2 * pi)
for ( j in 1:g ) {
mod <- .wpn.mle(u, w = wij[, j])
mu <- drop(mod$mu)
gam <- sum(mu^2)
tau <- drop( x %*% mu )
ptau <- pnorm(tau)
param[j, ] <- c(mu, sqrt(gam) )
lika[, j] <- - 0.5 * gam + log1p( tau * ptau * con / exp(f * tau^2) ) + log( pj[j] )
}
wlika <- exp(lika) #PANOS
rswlika <- Rfast::rowsums(wlika) #PANOS
lik <- sum( log( rswlika ) ) #PANOS
wij <- wlika / rswlika
list(wij = wij, param = param, wlika = wlika, rswlika = rswlika, lika = lika, lik = lik)
}
if ( ! rads ) u <- u * pi / 180
x <- cbind( cos(u), sin(u) )
n <- dim(x)[1]
lik <- NULL
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
runtime <- proc.time()
## Step 1
if ( g > 1 ) {
cl <- kmeans(x, g, nstart = 10)$cl
} else cl <- rep(1, n)
wij <- tabulate(cl)
while ( min(wij) <= 6 ) {
g <- g - 1
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
cl <- kmeans(x, g, nstart = 10)$cl
wij <- tabulate(cl)
}
f <- - 0.5 ; con <- sqrt(2 * pi)
for ( j in 1:g ) {
mod <- Directional::spml.mle(u[cl == j], rads = TRUE)
mu <- drop(mod$mu)
gam <- sum(mu^2)
tau <- drop( x %*% mu )
ptau <- pnorm(tau)
param[j, ] <- c( mu, sqrt(gam) )
lika[, j] <- - 0.5 * gam + log1p( tau * ptau * con / exp(f * tau^2) )
}
wlika <- exp(lika)
rswlika <- Rfast::rowsums(wlika)
RES <- try({
ep <- fun2(wlika, rswlika, x, g, param, lika)
lik[1] <- ep$lik
ep2 <- fun2(ep$wlika, ep$rswlika, x, g, ep$param, ep$lika)
lik[2] <- ep2$lik
i <- 2
while ( lik[i] - lik[i - 1] > tol & i < maxiters ) {
i <- i + 1
ep <- ep2
ep2 <- fun2(ep$wlika, ep$rswlika, x, g, ep$param, ep$lika)
lik[i] <- ep2$lik
}
res <- ep2
if ( ep$lik > ep2$lik ) res <- ep
}, silent = TRUE)
if ( !identical(class(RES), "try-error") ) {
probs <- res$wij
pj <- Rfast::colmeans(probs)
loglik <- res$lik
ta <- Rfast::rowMaxs(res$wij) ## estimated cluster of each observation
param <- cbind(pj, res$param)
colnames(param) <- c( "probs", paste("mu", 1:2, sep = ""), "gamma" )
rownames(param) <- paste("Cluster", 1:g, sep = " ")
} else pj <- loglik <- ta <- param <- probs <- iters <- NA
runtime <- proc.time() - runtime
list( param = param, loglik = loglik - n * log(2 * pi),
pred = ta, probs = probs, iters = i, runtime = runtime )
}
#### Projected multivariate normal MLE (weighted version)
#### Presnell, Morrison and Littell (1998), JASA
################################
.wpn.mle <- function(u, w = NULL, tol = 1e-09) {
ci <- cos(u) ; si <- sin(u)
x <- cbind(ci, si) ## bring the data onto the circle
n <- dim(x)[1]
if ( is.null(w) ) w <- rep(1, n)
sw <- sum(w)
ini <- Rfast::vmf.mle(x) ## weighted vMF starting values
mu1 <- ini$mu * ini$kappa
f <- - 0.5 ; con <- sqrt(2 * pi)
tau <- drop( x %*% mu1 )
ptau <- pnorm(tau)
rat <- ptau / ( exp(f * tau^2)/con + tau * ptau )
psit <- tau + rat
psit2 <- 2 - tau * rat - rat^2
der <- Rfast::eachcol.apply(x, w * psit) - sw * mu1
dera <- der[1] ; derb <- der[2]
dera2 <- sum( w * (psit2 * ci^2 - 1) )
derab <- sum( w * psit2 * ci * si )
derb2 <- sum( w * (psit2 * si^2 - 1) )
mu2 <- mu1 - c( derb2 * dera - derab * derb, - derab * dera + dera2 * derb ) / ( dera2 * derb2 - derab^2 )
i <- 2
while ( sum( abs(mu2 - mu1) ) > tol ) {
i <- i + 1
mu1 <- mu2
tau <- drop( x %*% mu1 )
ptau <- pnorm(tau)
rat <- ptau / ( exp(f * tau^2)/con + tau * ptau )
psit <- tau + rat
psit2 <- 2 - tau * rat - rat^2
der <- Rfast::eachcol.apply(x, w * psit) - sw * mu1
dera <- der[1] ; derb <- der[2]
dera2 <- sum( w * (psit2 * ci^2 - 1) )
derab <- sum( w * psit2 * ci * si )
derb2 <- sum( w * (psit2 * si^2 - 1) )
mu2 <- mu1 - c( derb2 * dera - derab * derb, - derab * dera + dera2 * derb ) / ( dera2 * derb2 - derab^2 )
}
gam <- sum(mu2^2)
loglik <- - 0.5 * sw * gam + sum( w * log1p( tau * ptau * con / exp(f * tau^2) ) ) - sw * log(2 * pi)
list(iters = i, loglik = loglik, gamma = gam, mu = mu2)
}
.mixgcpc.mle <- function(u, rads = TRUE, g = 2, tol = 1e-4, maxiters = 100) {
fun2 <- function(wlika, rswlika, u, g, param, lika) {
wij <- wlika / rswlika ## weights
pj <- Rfast::colmeans(wij) # PANOS
for ( j in 1:g ) {
mod <- .wgcpc.mle2(u, w = wij[, j])
mod1 <- .wgcpc.mle(u, w = wij[, j])
if ( mod1$loglik > mod$loglik ) mod <- mod1
omega <- mod$circmu
gam <- mod$gamma
rho <- mod$rho
param[j, ] <- c(omega, gam, rho)
phi <- u - omega
a <- gam * cos(phi)
b <- cos(phi)^2 + sin(phi)^2/rho
lika[, j] <- 0.5 * log(rho) + log( b * sqrt(gam^2 + 1) - a * sqrt(b) ) + log( pj[j] )
}
wlika <- exp(lika) #PANOS
rswlika <- Rfast::rowsums(wlika) #PANOS
lik <- sum( log( rswlika ) ) #PANOS
wij <- wlika / rswlika
list(wij = wij, param = param, wlika = wlika, rswlika = rswlika, lika = lika, lik = lik)
}
if ( !rads ) u <- u * pi / 180
n <- length(u)
lik <- NULL
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
runtime <- proc.time()
## Step 1
if ( g > 1 ) {
x <- cbind( cos(u), sin(u) )
cl <- kmeans(x, g, nstart = 10)$cl
} else cl <- rep(1, n)
wij <- tabulate(cl)
while ( min(wij) <= 6 ) {
g <- g - 1
lika <- matrix(nrow = n, ncol = g)
param <- matrix(nrow = g, ncol = 3)
cl <- kmeans(x, g, nstart = 10)$cl
wij <- tabulate(cl)
}
for ( j in 1:g ) {
mod <- Directional::gcpc.mle2(u[cl == j], rads = TRUE)
mod1 <- Directional::gcpc.mle(u[cl == j], rads = TRUE)
if ( mod1$loglik > mod$loglik ) mod <- mod1
omega <- mod$circmu
gam <- mod$gamma
rho <- mod$rho
param[j, ] <- c(omega, gam, rho)
phi <- u - omega
a <- gam * cos(phi)
b <- cos(phi)^2 + sin(phi)^2/rho
lika[, j] <- 0.5 * log(rho) + log( b * sqrt(gam^2 + 1) - a * sqrt(b) )
}
wlika <- exp(lika)
rswlika <- Rfast::rowsums(wlika)
ep <- fun2(wlika, rswlika, u, g, param, lika)
lik[1] <- ep$lik
ep2 <- fun2(ep$wlika, ep$rswlika, u, g, ep$param, ep$lika)
lik[2] <- ep2$lik
i <- 2
while ( lik[i] - lik[i - 1] > tol & i < maxiters ) {
i <- i + 1
ep <- ep2
ep2 <- fun2(ep$wlika, ep$rswlika, u, g, ep$param, ep$lika)
lik[i] <- ep2$lik
}
res <- ep2
if ( ep$lik > ep2$lik ) res <- ep
pj <- Rfast::colmeans(res$wij)
loglik <- res$lik
ta <- Rfast::rowMaxs(res$wij) ## estimated cluster of each observation
param <- cbind(pj, res$param)
runtime <- proc.time() - runtime
colnames(param) <- c( "probs", "omega", "gamma", "rho" )
rownames(param) <- paste("Cluster", 1:g, sep = " ")
list( param = param, loglik = loglik - n * log(2 * pi),
pred = ta, probs = res$wij, iters = i, runtime = runtime )
}
.wgcpc.mle2 <- function(u, w) {
lik <- function(para, u, w, sw) {
omega <- para[1]
r <- max(exp(para[2]), 1000) ; g <- max(exp(para[3]), 1000)
phi <- u - omega
a <- g * cos(phi)
b <- cos(phi)^2 + sin(phi)^2/r
0.5 * sw * log(r) + sum( w * log( b * sqrt(g^2 + 1) - a * sqrt(b) ) )
}
n <- length(u)
sw <- sum(w)
mod <- Directional::cipc.mle(u, TRUE)
suppressWarnings({
ini <- c(mod$mu, log( mod$gamma^2), rnorm(1) )
mod <- optim(ini, lik, u = u, w = w, sw = sw, control = list(maxit = 5000))
mod <- optim(mod$par, lik, u = u, w = w, sw = sw, control = list(maxit = 5000))
mod <- optim(mod$par, lik, u = u, w = w, sw = sw, control = list(maxit = 5000))
})
circmu <- mod$par[1] %% (2 *pi)
rho <- exp(mod$par[2]) ; gama <- exp(mod$par[3])
mu <- c( cos(circmu), sin(circmu) ) * gama
list(mu = mu, circmu = circmu, gamma = gama, rho = rho, loglik = -mod$value - n * log(2 * pi) )
}
.wgcpc.mle <- function(x, w = NULL) {
likint <- function(mu, rho, x, w, sw) {
g2 <- sum(mu^2)
ksi <- mu / sqrt(g2)
sinv <- matrix( c( ksi[1]^2 + ksi[2]^2/rho, ksi[1] * ksi[2] * (1 - 1/rho),
ksi[1] * ksi[2] * (1 - 1/rho), ksi[2]^2 + ksi[1]^2/rho ), ncol = 2 )
a <- as.vector(x %*% mu)
b <- Rfast::rowsums( x %*% sinv * x )
sw * 0.5 * log(rho) + sum( w * log( b * sqrt(g2 + 1) - a * sqrt(b) ) )
}
lik0 <- function(rho, x, w, sw, ma) {
m1 <- optim(ma, likint, rho = rho, x = x, w = w, sw = sw, control = list(maxit = 1000) )
- optim( m1$par, likint, rho = rho, x = x, w = w, sw = sw, control = list(maxit = 1000) )$value
}
lik <- function(param, x, w, sw) {
mu <- param[1:2]
rho <- param[3]
g2 <- sum(mu^2)
ksi <- mu / sqrt(g2)
sinv <- matrix( c( ksi[1]^2 + ksi[2]^2/rho, ksi[1] * ksi[2] * (1 - 1/rho),
ksi[1] * ksi[2] * (1 - 1/rho), ksi[2]^2 + ksi[1]^2/rho ), ncol = 2 )
a <- drop(x %*% mu)
b <- Rfast::rowsums( x %*% sinv * x )
sw * 0.5 * log(rho) + sum( w * log( b * sqrt(g2 + 1) - a * sqrt(b) ) )
}
x <- cbind( cos(x), sin(x) )
n <- dim(x)[1]
sw <- sum(w)
ma <- Rfast::eachcol.apply(x, w) / sw # weighted resultant vector as starting mu
rho <- optimize(lik0, c(0.001, 1000), x = x, w = w, sw = sw, ma = ma, maximum = TRUE)$maximum
mod <- optim(ma, likint, rho = rho, x = x, w = w, sw = sw, control = list(maxit = 5000) )
suppressWarnings({
mod <- optim( c(mod$par, rho), lik, x = x, w = w, sw = sw, control = list(maxit = 5000) )
})
mu <- mod$par[1:2] ; rho = mod$par[3]
gama <- sqrt( sum(mu^2) )
circmu <- ( atan(mu[2]/mu[1]) + pi * I(mu[1] < 0) ) %% (2 * pi)
list(mu = mu, circmu = circmu, gamma = gama, rho = rho,
loglik = -mod$value - sw * log(2 * pi) )
}
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.