Reputation: 425
I want to stop the counting process for y
after it first time meet the condition of y < 0
for each i
in the for loop
. Which means, the counting process for x
will still continue as long as x > 0
(condition stated in the while loop
).
I had tried to do something which is if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2)
, it make sense for me but the result doesn't make sense because after I run the code, count_x
is around 100 (make sense) but count_y
is more than 1000 which doesn't make sense since the for loop
is only from 1:1000
.
count_x <- 0
count_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
if (x < 0){
count_x <- count_x + 1
}
if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2){
count_y <- count_y + 1
}
}
}
For example, during the 1st iteration i=1
, the while loop
will start and run the code inside the loop. So what I want to do is:
When y
first time reach negative value in the first iteration, it will update the count_y
by one, then the whole if loop
for the counting process of y
will stop doing any thing even though the while loop
is still continue to run since the if loop
for counting process of x
might not reach it first negative value yet (the condition for the while loop
still satisfied if t
is still smaller than 100), so the while loop
need to be continue without touching last inner if loop
until either t>100
first or x
first time reach its negative value. Once, the conditions for while loop
do not satisfied, then only go for the 2nd iteration i=2
.
Same thing goes to x
, the counting process for x
will stop doing anything once x
first time become a negative value but the while loop
will continue working as long as the condition for the while loop
still satisfied.
So, there will only be one time update for either x
or y
for each iteration (so maximum for y
should be 1000 since we have 1000 iteration, although unlikely to reach 1000) since the counting process for both x
and y
will stop once it reaches the first negative value.
I'm thinking to add break
function into it but not sure where should I add.
Upvotes: 3
Views: 874
Reputation: 2623
We will create variables for both x and y that will store and track when both cross zero on each i iteration. First we will check if x or y is zero and if neg
is of class NULL
. If so, then this is the first negative. We store x_0
or y_0
as 1. Then when counting, we check if x_0
or y_0
is equal to one and if neg
is NULL
. Then we will add to the counter and record the first negative. Thereafter, the condition evaluates to FALSE
.
count_x <- 0
count_y <- 0
while_x <- 0
while_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
x_0 <- 0
y_0 <- 0
neg <- NULL
neg_x <- NULL
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
if (x < 0 & is.null(neg_x)){
x_0 <- 1
}
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
if (x < 0 & is.null(neg_x)){
x_0 <- 1
}
if (y < 0 & is.null(neg)) {
y_0 <- 1
}
}
t <- t + time
if (x_0 == 1 & is.null(neg_x)){
count_x <- count_x + 1
neg_x <- "First Negative"
x_0 <- x_0 + 1
}
if (y_0 == 1 & is.null(neg)){
count_y <- count_y + 1
neg <- "first negative"
y_0 <- y_0 + 1
}
}
}
You can also place a counter outside the while loop. If x or y is less than 0, add to the counter. This is probably a better solution. The condition will evaluate regardless of when x or y cross below zero, as long as it went below zero, it will evaluate to TRUE
count_x <- 0
count_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
}
if(x < 0) {
count_x <- count_x + 1
}
if(y < 0){
count_y <- count_y + 1
}
}
For me, count_y
comes out at a 1000 in both cases. This confirms what I said previously, y goes below zero at each while
iteration.
Upvotes: 0
Reputation: 2623
I don't think there's anything wrong with the code. The y counter, to me at least, seems like it is correct. The reason why y is larger is two-fold. Firstly, even though the outer for
loop is only 1000, the inner while
loop could potentially run for more than a 100 at each i iteration. Secondly, it appears that y goes below 0 before x does, hence why the x counter is smaller.
I've modified your code to include a counter that counts how many while
iterations occur, and two variables that store the values of x
and y
respectively, the first time that y
goes below zero.
count_x <- 0
count_y <- 0
while_count <- 0
store_x <- 0
store_y <- 0
a <- 1
b <- 1
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
count_while <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
if (x < 0){
count_x <- count_x + 1
}
if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2){
count_y <- count_y + 1
store_y[a] <- y
store_x[a] <- x
a <- a + 1
}
if (y > 0){
count_while <- count_while + 1
}
}
while_count[b] <- count_while
b <- b + 1
}
Checking the averages shows that x is almost exclusively greater than zero the first time y goes below zero. The while loop averages 163 iterations.
mean(store_x)
[1] 38.90333
mean(store_y)
[1] -2.035492
mean(while_count)
[1] 163.052
which(store_x < 0)
[1] 656
So, your counter seems correct to me, x is low simply because it rarely goes below zero. In fact, run the loop for just one iteration by setting for (i in 1:1)
and run it several time, you'll find that your count_x
rarely goes above zero, despite the while
loop iterating over a 100 times. On the other hand, y
goes below zero at least once on each i
iteration.
I hope this helps!
Upvotes: 1