[R] Sometimes having problems finding a minimum using optim(), optimize(), and nlm() (while searching for noncentral F parameters)

Ken Kelley KKIII at Indiana.Edu
Tue Oct 11 06:38:09 CEST 2005


Hi everyone.

I have a problem that I have been unable to determine either the best 
way to proceed and why the methods I'm trying to use sometimes fail. I'm 
using the pf() function in an optimization function to find a 
noncentrality parameter that leads to a specific value at a specified 
quantile. My goal is to have a general function that returns the 
noncentrality parameter that leads to a given value at a defined 
quantile. For example, with 5 and 200 degrees of freedom, what 
noncentrality parameter has at its .975 quantile a value of 4 (it is 
3.0725 by the way)? The code I've written, using three different methods 
works great at times, but at other times it fails (sometimes all 
sometimes not). It isn't even that the functions I'm trying to write 
fail, but the reason they sometimes fail and sometimes do not is what is 
really bothering me; I simply don't understand why the functions at 
times stop the iterative process of minimization and return what the 
function believes to be a successful convergence value (e.g., optim() 
sometimes returns a 0 stating successful convergence when it clearly is 
not).

I'm using three function [optim(), optimize(), and nlm()] to try and 
accomplish the same goal (which was stated above). I believe that they 
should all return the same value, and at times they do just that, but at 
other times the methods return inappropriate results. I'll paste my code 
that illustrates an example where all is well and one where things fail.

Is there are easier way to do what I'm trying to accomplish? The analog 
in SAS of what I'm trying to come up with is FNONCT.

#Begin code
##################################################################
# Define necessary values.
F.value <- 4
tol <- 1e-8
df.1 <- 5
df.2 <- 200
alpha.lower <- .025
maxit<-1000

# The function to be minimized. Here we are looking for the noncentral
# value, 'Lambda', that has at its .975 quantile 'F.value'.
Low.Lim.NC.F <- function(Lambda, alpha.lower, F.value, df.1, df.2)
{
abs(pf(q=F.value, df1=df.1, df2=df.2, ncp=Lambda) - (1-alpha.lower))
# This will be near zero when an appropriate Lambda value is found.
# The Lambda value that leads to a solution of zero is the noncentrality
# value that has at its .975 quantile a value of 'F.value'.
}

# Use the quantile from a central F distribution as a minimum.
LL.0 <- qf(p=alpha.lower, df1=df.1, df2=df.2)

optim(par=LL.0, fn=Low.Lim.NC.F,
method="L-BFGS-B", # Others return the same result usually.
lower=LL.0, upper = Inf, control = list(maxit=maxit, reltol=1e-10), 
hessian = FALSE, alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, 
df.2=df.2)

# Try to accomplish the same task with a different R function.
optimize(f=Low.Lim.NC.F, lower=LL.0, upper=50, maximum=FALSE, tol=tol, 
alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, df.2=df.2)

# Try to accomplish the same task with a different R function.
nlm(f=Low.Lim.NC.F, p=LL.0, fscale=1,
print.level = 0, ndigit=12, gradtol = 1e-6,
stepmax = max(1000 * sqrt(sum((LL.0/10)^2)), 1000),
steptol = 1e-6, iterlim = 1000, check.analyticals = TRUE, 
alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, df.2=df.2)

# The answer in each case is 3.0725. Thus, a noncentral F with
# 5 and 200 df with a noncentrality parameter 3.0725 has at its .975
# quantile a value of 4 (this has been verified in another software).

# But, suppose we triple the F.value to 12 and rerun the code.

F.value <- 12

# The function to be minimized. Here we are looking for the noncentral
# value, 'Lambda', that has at its .975 quantile 'F.value'.
Low.Lim.NC.F <- function(Lambda, alpha.lower, F.value, df.1, df.2)
{
abs(pf(q=F.value, df1=df.1, df2=df.2, ncp=Lambda) - (1-alpha.lower))
}

# Use the quantile from a central F distribution as a minimum.
LL.0 <- qf(p=alpha.lower, df1=df.1, df2=df.2)

optim(par=LL.0, fn=Low.Lim.NC.F,
method="L-BFGS-B",  # Others return the same result usually. 
  lower=LL.0, upper = Inf, control = list(maxit=maxit, reltol=1e-10), 
hessian = FALSE, alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, 
df.2=df.2)

# Try to accomplish the same task with a different R function.
optimize(f=Low.Lim.NC.F, lower=LL.0, upper=500, maximum=FALSE, tol=tol, 
alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, df.2=df.2)

# Try to accomplish the same task with a different R function.
nlm(f=Low.Lim.NC.F, p=LL.0, fscale=1,
gradtol = 1e-6, stepmax = max(1000 * sqrt(sum((LL.0/10)^2)), 1000),
steptol = 1e-6, iterlim = 1000, check.analyticals = TRUE, 
alpha.lower=alpha.lower, F.value=F.value, df.1=df.1, df.2=df.2)

# Now only optimize() works and optim() and nlm() both return the
# same (wrong) answer. Why would the function stop when the
# minimized value was .025 (when it should stop when the value is
# very close to zero)?

# But, optimize() isn't always the answer either, because if the
# upper limit is too large, the function will fail.
# For example, changing the upper limit of optimize in
# this example to 1000 leads to a failure.
##################################################################
#End Code

Am I going about this the best, or even a reasonable, way? Are there 
other functions I'm missing that would be more appropriate given what 
I'm trying to do? Any help would most certainly be appreciated.

Thanks,
Ken

-- 
Ken Kelley, Ph.D.
Inquiry Methodology Program
Indiana University
201 North Rose Avenue, Room 4004
Bloomington, Indiana 47405
http://www.indiana.edu/~kenkel




More information about the R-help mailing list