Hi guys i have been battling to get this ODE working but i keep coming across this error : Error in eval(expr, envir, enclos) : object 'j' not found
My code is below and it seems to be an issue with my if statement in the ODE
parameters <- c(
a = 0.032,
b = (9 / 140),
c = (5 / 1400),
d = (95 / 700),
k = 1 / 140,
i = 0.25,
# r = 0.2,
n = 6000000,
x = 0.3 ,
t = 1 / 180, # important in looking at the shape
u = 1 / 180, # important in looking at the shape
v = 1 / 360, # important in looking at the shape
p = 10,
s = 10000,
g = 100
# e = .4,
#h = 1000
)
state <- c(
S = 5989900,
E = 100,
I = 100,
Q = 100,
D = 100,
B = 100,
C = 100,
Y = 100,
H = 1000,
R = 1000,
J = 1000,
h = 100,
e = 0.1,
r = 0.1
)
# set up the equations
equation <- (function(t, state, parameters)
with(as.list(c(state, parameters)), {
# rate of change
dS <- (-(a * S * I) / n) - (((1 / r) * S * D) / n)
dE <- (a * S * I) / n + (((1 / r) * S * D) / n) - i * E
if (h > Q)
j = 1
else if (h < Q)
j = 0
dI <- i * (j) * E - (e) * I - c * I - d * I
dQ <- (j) * (e) * I - b * Q - k * Q
dD <- d * I - r * D
dB <- b * Q + r * D
dC <- c * I + k * Q
dY <- p * (b * Q + r * D)
dR <- (1 - x) * (p * (b * Q + r * D)) - t * (R)
de <- t * (s / R)
dJ <- (x) * (p * (b * Q + r * D)) - v * (J)
dr <- v * (s / J)
dH <- (x) * (p * (b * Q + r * D)) - u * (H)
dh <- u * (H / g)
# return the rate of change
list(c(dS, dE, dI, dQ, dD, dB, dC, dY, dR, de, dJ, dr, dH, dh))
}))
#
# solve the equations for certain starting parameters
library(deSolve)
times <- seq(0, 200, by = 1)
out <-
ode(y = state,
times = times,
func = equation,
parms = parameters
)
# , method = "vode"
head(out)
tail(out)
# graph the results
par(oma = c(0, 0, 3, 0))
plot(out, xlab = "Time", ylab = "People")
#plot(out[, "X"], out[, "Z"], pch = ".")
mtext(outer = TRUE, side = 3, "Ebola Model",cex = 1.5
)
any help would be great!
In case when h==Q variable j won't be created.
In given example h is equal Q.
You should add else statement or assign base value to j before if statements.
Like this:
j = 0
if (h > Q){
j = 1
}
else if (h < Q) {
j = 0
}
or
if (h > Q){
j = 1
}else if (h < Q) {
j = 0
}else{
j = 0
}
Related
I receive an error from nls function in R. I search some similar questions, but do not solve this problem. For example, I try to use nlsLM from library 'minpack.lm', it also fails. So I have to ask for help here. Following is the code:
tt = c(10, 30, 50, 90, 180, 360, 720, 1440, 2880, 4320, 8640, 12960)
x = c(
1.53901e-06,
1.22765e-06,
1.11200e-06,
9.25185e-07,
8.71809e-07,
8.80705e-07,
8.36225e-07,
7.82849e-07,
8.18433e-07,
6.04928e-07,
3.46944e-07,
4.44800e-07
)
y = c(
3.81639e-06,
5.00623e-06,
4.62815e-06,
5.10631e-06,
4.48359e-06,
3.30487e-06,
2.64879e-06,
2.13727e-06,
8.02865e-07,
1.91487e-06,
3.73855e-06,
2.32631e-06
)
nt = length(tt)
L0 = 0.005
y0 = 0.000267681
model = function(K, Kd, k1) {
eta = 5 / (4 * Kd + 40)
eta1 = 1 - eta
eta1_seq = eta1 ^ c(0:(nt - 1))
Lt = L0 * eta * cumsum(eta1_seq)
b = K * x - K * Lt + 1
L = (-b + sqrt(b ^ 2.0 + 4 * K * Lt)) / (2 * K)
cx = x * K * L / (K * L + 1)
qx = Kd * cx
q1 = y0 * (1 - k1 * sqrt(tt))
y = qx + q1
return(y)
}
fit <- nls(
y ~ model(K, Kd, k1),
start = list(K = 1e+15,
Kd = 10,
k1 = 1e-5),
lower = c(1e+13, 1, 1e-10),
upper = c(1e+20, 200, 1e-3),
algorithm = "port"
)
Thanks in advance for your help!
How can the following R code be vectorized to reduce computing time?
q = matrix(0,n,p)
for(u in 1 : n){
q1 <- matrix(0,p,1)
for(iprime in 1 : n){
for(i in 1 : n){
if(cause[iprime]==1 & cause[i]>1 & (time[i]<time[u]) & (time[u] <= time[iprime])){
q1 = q1 + (covs[i,] - S1byS0hat[iprime,])*G[iprime]/G[i]*expz[i]/S0hat[iprime]
}
}
}
q[u,] = q1/(m*m)
}
Following values could be used as an example:
n = 2000
m = 500
p=3
G = runif(n)
time = runif(n,0.01,5)
cause = c(rep(0,600),rep(1,1000),rep(2,400))
covs = matrix(rnorm(n*p),n,p)
S1byS0hat = matrix(rnorm(n*p),n,p)
S0hat = rnorm(n)
expz = rnorm(n)
Benchmarking your solution:
coeff <- 10
n = 20 * coeff
m = 500
p = 3
G = runif(n)
time = runif(n, 0.01, 5)
cause = c(rep(0, 6 * coeff), rep(1, 10 * coeff), rep(2, 4 * coeff))
covs = matrix(rnorm(n * p), n, p)
S1byS0hat = matrix(rnorm(n * p), n, p)
S0hat = rnorm(n)
expz = rnorm(n)
system.time({
q = matrix(0,n,p)
for(u in 1 : n){
q1 <- matrix(0,p,1)
for(iprime in 1 : n){
for(i in 1 : n){
if(cause[iprime]==1 & cause[i]>1 & (time[i]<time[u]) & (time[u] <= time[iprime])){
q1 = q1 + (covs[i,] - S1byS0hat[iprime,])*G[iprime]/G[i]*expz[i]/S0hat[iprime]
}
}
}
q[u,] = q1/(m*m)
}
})
It takes 9 sec on my computer (with coeff = 10 instead of 100, we can increase it later for other solutions).
One first solution would be to precompute some stuff:
q2 = matrix(0, n, p)
c1 <- G / S0hat
c2 <- expz / G
for (u in 1:n) {
q1 <- rep(0, p)
ind_iprime <- which(cause == 1 & time[u] <= time)
ind_i <- which(cause > 1 & time < time[u])
for (iprime in ind_iprime) {
for (i in ind_i) {
q1 = q1 + (covs[i, ] - S1byS0hat[iprime, ]) * c1[iprime] * c2[i]
}
}
q2[u, ] = q1
}
q2 <- q2 / (m * m)
This takes 0.3 sec for coeff = 10 and 6 min for coeff = 100.
Then, you can vectorize at least one loop:
q3 <- matrix(0, n, p)
c1 <- G / S0hat
c2 <- expz / G
covs_c2 <- sweep(covs, 1, c2, '*')
S1byS0hat_c1 <- sweep(S1byS0hat, 1, c1, '*')
for (u in 1:n) {
q1 <- rep(0, p)
ind_iprime <- which(cause == 1 & time[u] <= time)
ind_i <- which(cause > 1 & time < time[u])
for (iprime in ind_iprime) {
q1 <- q1 + colSums(covs_c2[ind_i, , drop = FALSE]) * c1[iprime] -
S1byS0hat_c1[iprime, ] * sum(c2[ind_i])
}
q3[u, ] <- q1
}
q3 <- q3 / (m * m)
This takes only 15 sec.
If you care about further performance, a good strategy might be to recode this in Rcpp, especially to avoid lots of memory allocations.
I am trying to implement the following formula in R where r0, t, theta0 and alpha are constants. Also, I is a Modified Bessel function of the first kind. My issue, I suppose, is from the Sum term to the end of the formula. I set n = 150 given that the function converges to zero fast so there is no need to go beyond 150. I am using the "Bessel" package.
Formula1
Formula2
Results to reproduce first row = t, second row = Defaultcorr in %
Here is what I have thus far. I can't seem to find my mistake. Defaultcorr should be 0.04 % when t = 1 (according to the image "Results to reproduce").
To obtain this result " m " should be equal to 6.234611709.
V1 = 5
V2 = 5
K1 = 1
K2 = 1
sigma1 = 0.3
sigma2 = 0.3
Z1 = log((V1/K1)/sigma1)
Z2 = log((V2/K2)/sigma2)
t = 1
rho = 0.4
#One firm default -> Firm #1 when lambda = mu
PD_asset1 = 2 * pnorm(-(Z1/sqrt(t)))
PD_asset1
PD_asset2 = 2 * pnorm(-(Z2/sqrt(t)))
PD_asset2
#Results assuming that lambda = mu
#Conditions for alpha, theta0, r0
if (rho < 0) { #alpha
alpha = atan(-(sqrt(1-rho^2)) / rho)
} else {
alpha = pi + atan(-(sqrt(1-rho^2)) / rho)
}
if (rho > 0) { #theta0
theta0 = atan((Z2 * sqrt(1 - rho^2)) / (Z1 - (rho * Z2)))
} else {
theta0 = pi + atan((Z2 * sqrt(1 - rho^2)) / (Z1 - (rho * Z2)))
}
r0 = (Z2 / sin(theta0)) #r0
#Simplified function
h = function(n) {
(sin((n * pi * theta0)/alpha)/n)
}
n = seq(1, 150, 2)
Bessel1 = (besselI(((r0^2)/(4*t)), (0.5*(((n*pi)/alpha) + 1)), FALSE))
Bessel2 = (besselI(((r0^2)/(4*t)), (0.5*(((n*pi)/alpha) - 1)), FALSE))
l = matrix(data = n, ncol = n)
m = apply((h(l)*(Bessel1 + Bessel2)), 2, FUN = sum)
PD_asset1_or_asset2 = 1 - (((2 * r0)/(sqrt(2*pi*t))) * (exp(-(r0^2)/(4*t))) * m)
PD_asset1_or_asset2
Var_asset1 = PD_asset1 * (1 - PD_asset1)
Var_asset1
Var_asset2 = PD_asset2 * (1 - PD_asset2)
Var_asset2
PD_asset1_and_asset2 = PD_asset1 + PD_asset2 - PD_asset1_or_asset2
PD_asset1_and_asset2
Defaultcorr = (PD_asset1_and_asset2 - (PD_asset1 * PD_asset2)) / (sqrt(Var_asset1 * Var_asset2))
Defaultcorr
Any help would be appreciated. Thank you
I could get the PC scores and loading using logisticPCA from the logisticPCA package(https://cran.r-project.org/web/packages/logisticPCA/logisticPCA.pdf). But I can't find a way to extract either the eigenvalues or explained variation captured by each PC.
I came across the same issue. The solution I found was to export the function that calculates logisticPCA from the package, to extract the Eigenvalues and to calculate the ratio of each component to the total sum of Eigenvalues.
The function "logisticPCA2" can then be called like in the package and the explained Variance can be extracted:
logisticPCA2 <- function(x, k = 2, m = 4, quiet = TRUE, partial_decomp = FALSE,
max_iters = 1000, conv_criteria = 1e-5, random_start = FALSE,
start_U, start_mu, main_effects = TRUE, validation, M, use_irlba) {
if (!missing(M)) {
m = M
warning("M is depricated. Use m instead. ",
"Using m = ", m)
}
if (!missing(use_irlba)) {
partial_decomp = use_irlba
warning("use_irlba is depricated. Use partial_decomp instead. ",
"Using partial_decomp = ", partial_decomp)
}
if (partial_decomp) {
if (!requireNamespace("RSpectra", quietly = TRUE)) {
message("RSpectra must be installed to use partial_decomp")
partial_decomp = FALSE
}
}
q = as.matrix(2 * x - 1)
missing_mat = is.na(q)
q[is.na(q)] <- 0 # forces Z to be equal to theta when data is missing
n = nrow(q)
d = ncol(q)
if (k >= d & partial_decomp) {
message("k >= dimension. Setting partial_decomp = FALSE")
partial_decomp = FALSE
k = d
}
if (m == 0) {
m = 4
solve_M = TRUE
if (!missing(validation)) {
if (ncol(validation) != ncol(x)) {
stop("validation does not have the same variables as x")
}
validation = as.matrix(validation)
q_val = 2 * validation - 1
q_val[is.na(q_val)] <- 0
}
} else {
solve_M = FALSE
}
if (main_effects) {
if (!missing(start_mu)) {
mu = start_mu
} else {
mu = colMeans(m * q)
}
} else {
mu = rep(0, d)
}
# Initialize #
##################
if (!missing(start_U)) {
U = sweep(start_U, 2, sqrt(colSums(start_U^2)), "/")
} else if (random_start) {
U = matrix(rnorm(d * k), d, k)
U = qr.Q(qr(U))
} else {
if (partial_decomp) {
udv = RSpectra::svds(scale(q, center = main_effects, scale = FALSE), k = k)
} else {
udv = svd(scale(q, center = main_effects, scale = FALSE))
}
U = matrix(udv$v[, 1:k], d, k)
}
# etaTeta = crossprod(eta)
qTq = crossprod(q)
loss_trace = numeric(max_iters + 1)
eta = m * q + missing_mat * outer(rep(1, n), mu)
theta = outer(rep(1, n), mu) + scale(eta, center = mu, scale = FALSE) %*% tcrossprod(U)
loglike <- log_like_Bernoulli(q = q, theta = theta)
loss_trace[1] = (-loglike) / sum(q!=0)
ptm <- proc.time()
if (!quiet) {
cat(0, " ", loss_trace[1], "")
cat("0 hours elapsed\n")
}
for (i in 1:max_iters) {
last_U = U
last_m = m
last_mu = mu
if (solve_M) {
if (missing(validation)) {
Phat = inv.logit.mat(theta)
M_slope = sum(((Phat - x) * (q %*% tcrossprod(U)))[q != 0])
M_curve = sum((Phat * (1 - Phat) * (q %*% tcrossprod(U))^2)[q != 0])
} else {
lpca_obj = structure(list(mu = mu, U = U, m = m),
class = "lpca")
Phat = predict(lpca_obj, newdata = validation, type = "response")
M_slope = sum(((Phat - validation) * (q_val %*% tcrossprod(U)))[q_val != 0])
M_curve = sum((Phat * (1 - Phat) * (q_val %*% tcrossprod(U))^2)[q_val != 0])
}
m = max(m - M_slope / M_curve, 0)
eta = m * q + missing_mat * outer(rep(1, n), mu)
theta = outer(rep(1, n), mu) + scale(eta, center = mu, scale = FALSE) %*% tcrossprod(U)
}
Z = as.matrix(theta + 4 * q * (1 - inv.logit.mat(q * theta)))
if (main_effects) {
mu = as.numeric(colMeans(Z - eta %*% tcrossprod(U)))
}
eta = m * q + missing_mat * outer(rep(1, n), mu)
mat_temp = crossprod(scale(eta, center = mu, scale = FALSE), Z)
mat_temp = mat_temp + t(mat_temp) - crossprod(eta) + n * outer(mu, mu)
# RSpectra could give poor estimates of e-vectors
# so I switch to standard eigen if it does
repeat {
if (partial_decomp) {
eig = RSpectra::eigs_sym(mat_temp, k = min(k + 2, d))
}
if (!partial_decomp || any(eig$values[1:k] < 0)) {
eig = eigen(mat_temp, symmetric = TRUE)
if (!quiet & partial_decomp) {
cat("RSpectra::eigs_sym returned negative values.\n")
}
}
#####################################################
U = matrix(eig$vectors[, 1:k], d, k)
theta = outer(rep(1, n), mu) + scale(eta, center = mu, scale = FALSE) %*% tcrossprod(U)
this_loglike <- log_like_Bernoulli(q = q, theta = theta)
if (!partial_decomp | this_loglike >= loglike) {
loglike = this_loglike
break
} else {
partial_decomp = FALSE
warning("RSpectra::eigs_sym was too inaccurate in iteration ", i , ". Switched to base::eigen")
}
}
loss_trace[i + 1] = (-loglike) / sum(q!=0)
if (!quiet) {
time_elapsed = as.numeric(proc.time() - ptm)[3]
tot_time = max_iters / i * time_elapsed
time_remain = tot_time - time_elapsed
cat(i, " ", loss_trace[i + 1], "")
cat(round(time_elapsed / 3600, 1), "hours elapsed. Max", round(time_remain / 3600, 1), "hours remain.\n")
}
if (i > 4) {
# when solving for m, the monoticity does not apply
if (solve_M) {
if (abs(loss_trace[i] - loss_trace[i + 1]) < conv_criteria) {
break
}
} else {
if ((loss_trace[i] - loss_trace[i + 1]) < conv_criteria) {
break
}
}
}
}
# test if loss function increases
if ((loss_trace[i + 1] - loss_trace[i]) > (1e-10)) {
U = last_U
mu = last_mu
m = last_m
i = i - 1
if (!solve_M) {
warning("Algorithm stopped because deviance increased.\nThis should not happen!")
}
}
# calculate the null log likelihood for % deviance explained
if (main_effects) {
null_proportions = colMeans(x, na.rm = TRUE)
} else {
null_proportions = rep(0.5, d)
}
null_loglikes <- null_proportions * log(null_proportions) +
(1 - null_proportions) * log(1 - null_proportions)
null_loglike = sum((null_loglikes * colSums(q!=0))[!(null_proportions %in% c(0, 1))])
eta = m * q + missing_mat * outer(rep(1, n), mu)
#calculate explained variance
total_eig = sum(eig$values[1:k])
eig_sorted = sort(eig$values[1:k], decreasing = TRUE)
explainedVariance = c()
for (eig in eig_sorted){
explainedVariance = append(explainedVariance, eig/total_eig)
}
object <- list(mu = mu,
U = U,
PCs = scale(eta, center = mu, scale = FALSE) %*% U,
explainedVariance = explainedVariance,
m = m,
M = m, # need to depricate after 0.1.1
iters = i,
loss_trace = loss_trace[1:(i + 1)],
prop_deviance_expl = 1 - loglike / null_loglike)
class(object) <- "lpca"
object
}
logpca_model = logisticPCA2(data, k = 9, m = 8)
logpca_model$explainedVariance
I've been running the following code which returns the correct coefficients. However, no matter where I put a plot call, I can't get any plot output.
I'm not sure if a reproducible example is needed here, as I think this can be solved by looking at my gradientDescent function below? It's my first attempt at running this algorithm in R:
gradientDescent <- function(x, y, learn_rate, conv_threshold, n, max_iter) {
m <- runif(1, 0, 1)
c <- runif(1, 0, 1)
yhat <- m * x + c
cost_error <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
converged = F
iterations = 0
while(converged == F) {
m_new <- m - learn_rate * ((1 / n) * (sum((yhat - y) * x)))
c_new <- c - learn_rate * ((1 / n) * (sum(yhat - y)))
m <- m_new
c <- c_new
yhat <- m * x + c
cost_error_new <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
if(cost_error - cost_error_new <= conv_threshold) {
converged = T
}
iterations = iterations + 1
if(iterations > max_iter) {
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
}
}
It's unclear what you have been doing that was ineffective. The base graphics functions plot and abline should be able to produce output even when used inside functions. Lattice and ggplot2 graphics are based on grid-grpahics and would therefore need a print() wrapped around the function calls to create output (as described in the R-FAQ). So try this:
gradientDescent <- function(x, y, learn_rate, conv_threshold, n, max_iter)
{ ## plot.new() perhaps not needed
plot(x,y)
m <- runif(1, 0, 1)
c <- runif(1, 0, 1)
yhat <- m * x + c
cost_error <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
converged = F
iterations = 0
while(converged == F) {
m_new <- m - learn_rate * ((1 / n) * (sum((yhat - y) * x)))
c_new <- c - learn_rate * ((1 / n) * (sum(yhat - y)))
m <- m_new
c <- c_new
yhat <- m * x + c
cost_error_new <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
if(cost_error - cost_error_new <= conv_threshold) {
converged = T
}
iterations = iterations + 1
if(iterations > max_iter) { abline( c, m) #calculated
dev.off()
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
}
}