Home > OS >  How do I draw a plot for my function in R with error ` Recycling array of length 1 in array-vector a
How do I draw a plot for my function in R with error ` Recycling array of length 1 in array-vector a

Time:11-29

Following this question: ![![enter image description here

where v_i are eigenvectors of GOE and x_0 is the initial vector generated in the above code.

Based on the answer, my code is as follows:


h1t <- function(t) {
  h10 <- c(x_0 %*% v[, n])
  numer <- abs(h10) * exp(-2*l[n] * t)
  denom <- vapply(t, function(.t) {
    sum((x_0 %*% v)^2 * exp(-4*l * .t))
  }, numeric(1L))
  numer/sqrt(denom)
}


plot(h1t, from = 0, to = 100)

However, after t=80, there would be NaN in the function.

> h1t(90)
[1] 0.9997982
> h1t(100)
[1] 0
> h1t(400)
[1] NaN

The plot:

enter image description here

How to fix this problem?

CodePudding user response:

h_10 in your function is a 1x1 matrix, and this is the source of the warning. You can coerce it to a single number with c, or by extracting its [1, 1]-entry.

The more serious problem is here:

sum((x_0 %*% v)^2 * exp(-4*l * t))

If t is a single number, there's no problem. But if it is a vector, this expression is mixing some vectors having different length. You have to map the vector t, with sapply or vapply for example:

h1t_modefied <- function(t) {
  h10 <- c(x_0 %*% v[, n])
  numer <- abs(h10) * exp(-2*l[n] * t)
  denom <- vapply(t, function(.t) {
    sum((x_0 %*% v)^2 * exp(-4*l * .t))
  }, numeric(1L))
  numer/sqrt(denom)
}

By the way I don't see the ^2 in your formula in the picture.

> h1t_modefied(1:2)
[1] 0.5734668 0.7033437
> h1t_modefied(1)
[1] 0.5734668

If you want to use curve you have to use x for the variable, not t:

curve(h1t_modefied(x), from = 0, to = 20)

EDIT

You updated your question, asking why the function is vanishing for large t. This is because the exponentials in the sum at the denominator are huge numbers and this sum becomes infinite.

You can improve your function to avoid these huge numbers:

# original function

h1t_A <- function(t) {
  h10 <- c(x_0 %*% v[, n])
  numer <- abs(h10) * exp(-2*l[n] * t)
  denom <- vapply(t, function(.t) {
    sum((x_0 %*% v)^2 * exp(-4*l * .t))
  }, numeric(1L))
  numer/sqrt(denom)
}

# improved function
h1t_B <- function(t) {
  h10 <- c(x_0 %*% v[, n])
  denom <- vapply(t, function(.t) {
    sum((x_0 %*% v)^2 * exp(-4*(l - l[n]) * .t))
  }, numeric(1L))
  abs(h10) / sqrt(denom)
}

# > h1t_A(10)
# [1] 0.8847206
# > h1t_B(10)
# [1] 0.8847206
# > h1t_A(100)
# [1] 0
# > h1t_B(100)
# [1] 0.9949121
# > h1t_B(400)
# [1] 0.9999991

The idea is to divide the numerator and the denominator by the exponential term of the numerator.

  •  Tags:  
  • r
  • Related