JohnK
JohnK

Reputation: 1039

Problems plotting a custom function in R

I would like to program and plot this function into R:

enter image description here

The code I have been using is:

js <- sapply( seq(1,50, 1), FUN <- function(x) x^{-4})
pim <- sapply(seq(1,50, 1), FUN <- function(x) 2*pi*x)
beta <- function(x) sum(js*sqrt(2)*cos(pim*x))

but while this returns the right values for each point, I am running into trouble when I try to plot it using the curve function as what I get is:

   Error in curve(beta, 0, 1) : 
  'expr' did not evaluate to an object of length 'n'
In addition: Warning messages:
1: In pim * x :
  longer object length is not a multiple of shorter object length
2: In js * sqrt(2) * cos(pim * x) :
  longer object length is not a multiple of shorter object length

Could you please help me fix that problem and get a working plot? Thank you.

Upvotes: 3

Views: 645

Answers (2)

Joris Meys
Joris Meys

Reputation: 108523

I'm quite amazed you both use sapply inside these functions. The formula can be almost literally copied into R:

beta <- function(x, n=50){
  j <- seq_len(n)
  sum(
    j^(-4)* sqrt(2) * cos(2*j*pi*x)
  )
}

You can use any expression containing x in the function curve:

curve(sapply(x,beta),0,1)

gives the same plot.

On a sidenote: if you want beta to be vectorized, you could indeed add a sapply inside, or you could do:

beta_vect <- Vectorize(beta)
curve(beta_vect,0,1)

works as well.

Upvotes: 2

mfidino
mfidino

Reputation: 3055

The error is in your beta function. When you use sum like that is takes the sum of the entire vector for t = 1,...,T. You do not want to do this. Instead, you want to evaluate that function for each t. So, with a small change to beta you can then use the curve function.

js <- sapply( seq(1,50, 1), function(x) x^{-4})
pim <- sapply(seq(1,50, 1), function(x) 2*pi*x)
beta <- function(x) {
  sapply(x, function(y) sum(js*sqrt(2)*cos(pim*y)))
}
curve(beta, 0 ,1)

enter image description here

Upvotes: 4

Related Questions