2

My objective is to evaluate and to plot the following log-likelihood function with two parameters:

set.seed(123)
N = 100
x = 4*rnorm(N)
y = 0.8*x + 2*rnorm(N);

LogL <- function(param,x,y,N){
        beta = param[1]
        sigma2 = param[2]
        LogLikelihood =  -N/2*log(2*pi*sigma2) - sum( (y - beta*x)^2 / (2*sigma2) ) }

I've tried using 'outer' in order to use 'wireframe' as in the following thread:

How can I plot 3D function in r?

but without success:

param1 <- seq(-2, 2, length= 30)
param2 <- seq(0.1, 4, length= 30)
values1 <- matrix(c(param1,param2),30)
z <- outer(values1, x=x,y=y,N=N, LogL)

How can I use 'outer' properly in this case? Is there any other alternative to evaluate and to plot the function 'LogL'?

1 Answers1

0

The first question is that outer() needs to have the two arguments to LogL() as separate vectors, which means rewriting your function to use the two arguments instead of one length 2 argument that you unpack. In addition, (from ?outer)

Each will be extended by rep to length the products of the lengths of X and Y before FUN is called.

so the function needs to deal with ALL the possible values of X and Y in a single call. There's probably a better way to do this, but in the interest of simplicity, I used a for() loop to loop over the different values of X and Y.

set.seed(123)
N = 100
x = 4*rnorm(N)
y = 0.8*x + 2*rnorm(N);

LogL <- function(param1, param2, x, y, N){
  beta = param1
  sigma2 = param2
  LogLikelihood = vector("numeric",length(beta))
  for (i in 1:length(beta)){
    LogLikelihood[i] = -N/2*log(2*pi*sigma2[i]) - sum( (y - beta[i]*x)^2 / (2*sigma2[i]) )
  }
  return(LogLikelihood)
}

param1 <- seq(-2, 2, length= 30)
names(param1) <- param1
param2 <- seq(0.1, 4, length= 30)
names(param2) <- param2


z <- outer(X = param1, Y = param2, FUN = LogL, N = N, x = x, y = y)

require(lattice)
#> Loading required package: lattice
wireframe(z, drape=T, col.regions=rainbow(100))

# test it out
LogL(param1[3], param2[3],  x = x, y = y, N = N)
#> [1] -11768.37

z[3,3]
#> [1] -11768.37

and that works.

Created on 2018-03-13 by the reprex package (v0.2.0).

atiretoo
  • 1,812
  • 19
  • 33
  • So, the problem was in the function, interesting. Thank you. – Carlos Guevara Mar 10 '18 at 04:07
  • After analyzing the results, I realized that `outer()` does not evaluate properly the function, the results of plotting the log-likelihood look unusual in `wireframe(z, drape=T, col.regions=rainbow(100))`. How to formulate it correctly? – Carlos Guevara Mar 10 '18 at 18:05
  • Ah, I see - the function isn't properly vectorized. It is getting the parameters as vectors. – atiretoo Mar 12 '18 at 21:53