my question is "Find the maximum of the function myfun = - (sin(x)-3)^2 + 1 ,on the interval (0,5), and please answer x=? and f(x)= ?"
there is my code in R:
f <- function(x) { return((-1*sin(x)-3)^2+1 }
result <- uniroot(f,c(0,5),extendInt = "yes"
result$root
result$f.root
but the console is :
Error in uniroot(f, c(0, 5), extendInt = "yes") :
no sign change found in 1000 iterations
what's wrong with my code
Thanks a lot
optimize is the standard function for finding a max or min of a 1-dimensional function. uniroot is used for finding a root (0) of the function, not max or min values.
optimize(f, interval = c(0, 5), maximum = TRUE)
$maximum
[1] 1.570796
$objective
[1] 17
See ?optimize for examples and details.
(Note: I added a ) to the f in your question to avoid syntax errors.)
The base R function being used in the question is wrong. From the documentation:
uniroot
The function uniroot searches the interval from lower to upper for a
root (i.e., zero) of the function f with respect to its first
argument.
optimize
The function optimize searches the interval from lower to upper for
a minimum or maximum of the function f with respect to its first
argument.
Code
f <- function(x) { (-1*sin(x) - 3)^2 + 1 }
m <- optimize(f, c(0, 5), maximum = TRUE)
m
#$maximum
#[1] 1.570796
#
#$objective
#[1] 17
curve(f, 0, 5)
points(m$maximum, m$objective, pch = 16, col = "red")
Also, the function f is identical to
g <- function(x) { (sin(x) + 3)^2 + 1 }
For you purpose, you should use optim() or optimize(), instead of uniroot(), i.e.:
Given f <- function(x) -(sin(x)-3)^2+1 (the objective function in you code is not the one as you described at the beginning of your post), you will get the result via
optim(0,f,method = "L-BFGS-B",lower = 0,upper = 5,control = list(fnscale = -1))
> optim(0,f,method = "L-BFGS-B",lower = 0,upper = 5,control = list(fnscale = -1))
$par
[1] 1.570796
$value
[1] -3
$counts
function gradient
7 7
$convergence
[1] 0
$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"
or
optimize(f, interval = c(0, 5), maximum = TRUE)
> optimize(f, interval = c(0, 5), maximum = TRUE)
$maximum
[1] 1.570796
$objective
[1] -3
Related
I use RStudio for university. And I got this task where I need help:
Response times of people were measured. The following density function was found:
f (x) = 0.62 * (1 / x)
only positive reaction times between 1 and 5 seconds were measured.
In which interval [c, 5] do the top 30 percent of the response times fall? Calculate c!
Normally I would integrate in this way:
integrand_2 <- function(x) {0.62 * (1/x)}
integrate(integrand, lower = , upper = 5)
But as you can see, I have the problem that the lower limit is unknown. How can I find this unknown lower limit (c)?
Are you looking for this?
f <- function(z) integrate(function(x) 0.62 / x, z, 5)$value - 0.3
res <- uniroot(f, c(1, 5))$root
then we have
> res
[1] 3.081973
> integrate(function(x) 0.62 / x, res, 5)$value
[1] 0.2999982
Here is a way, but not with the result in ThomasIsCoding's answer.
pdf <- function(x) {
0.62/x
}
cdf <- function(x){
integrate(pdf, lower = 1, upper = x)$value
}
u <- uniroot(function(x) cdf(x) - 0.7, c(1, 5))
u$root
#[1] 3.092671
1 - cdf(u$root)
#[1] 0.2999982
But if the correct normalizing constant 1/log(5) is used instead of the rounded value 0.62, the result becomes closer.
pdf <- function(x) {
1/log(5)/x
}
# Same cdf
u <- uniroot(function(x) cdf(x) - 0.7, c(1, 5))
u$root
#[1] 3.085178
1 - cdf(u$root)
#[1] 0.2999982
I am trying to build a double optimization in R. By double optimization, I mean that there is going to be an inner call, in which I optimize a function called inner_function(), and then an outer call, in which I optimize an outer_function() whose output is computed using the optimization of inner_function().
I can make this work when inner_function() is optimized through optim() and outer_function() takes only one argument and is optimized through optimize():
constructor_function <- function(data, fixed = c(FALSE, FALSE)) {
params <- fixed
function(p) {
params[!fixed] <- p
a <- data[1]
b <- data[2]
c <- data[3]
d <- data[4]
e <- params[1]
f <- params[2]
## Calculate something
tot <- abs(a + b + c + d + e + f)
return(tot)
}
}
inner_function <- constructor_function(c(1, 2, 3, 4))
inner_function(c(5, 6))
#> [1] 21
optim(c(0, 0), inner_function)$par
#> [1] -3.454274 -6.545726
sum(optim(c(0, 0), inner_function)$par)
#> [1] -10
outer_function <- function(first_factor) {
inner_function <- constructor_function(c(first_factor, 2, 3, 4))
values <- optim(c(0, 0), inner_function)$par
tot <- sum(values)
return(tot)
}
# check
outer_function(1)
#> [1] -10
optimize(outer_function, lower = 0, upper = 4)
#> $minimum
#> [1] 3.99994
#>
#> $objective
#> [1] -12.99994
# check
outer_function(3.99994)
#> [1] -12.99994
But I can't make the double optimization work when the outer function (now called outer_function_args) takes more than one argument, so that it can be optimized only with optim():
outer_function_args <- function(first_factor, second_factor) {
inner_function <- constructor_function(c(first_factor, second_factor, 3, 4))
values <- optim(c(0, 0), inner_function)$par
tot <- sum(values)
return(tot)
}
outer_function_args(1,2)
#> [1] -10
optim(par=c(0,2), outer_function_args)
#> Error in fn(par, ...): argument "second_factor" is missing, with no default
The error mentions that argument "second_factor" is missing, but outer_function_args is running correctly.
Created on 2021-04-15 by the reprex package (v0.3.0)
You need to modify your function to take in the parameters as a vector, like so:
outer_function_args <- function(par) {
inner_function <- constructor_function(c(par[1], par[2], 3, 4))
values <- optim(c(0, 0), inner_function)$par
tot <- sum(values)
return(tot)
}
outer_function_args(par = c(1, 2))
#> [1] -10
optim(par=c(0,2), outer_function_args)
#$par
#[1] 3355434 3355445
#
#$value
#[1] -6710886
#
#$counts
#function gradient
# 253 NA
#
#$convergence
#[1] 0
#
#$message
#NULL
From the documentation of optim(par, fn) in help("optim"):
fn A function to be minimized (or maximized), with first argument the vector of parameters over which minimization is to take place. It should return a scalar result.
How can I find out the minimum value that can be returned by a function with infinite domain in R?
f <- function(x) { x^2-1 }
print(minVal(f)) # -1
f <- function(x) { x^2+1 }
print(minVal(f)) # 1
So far I've tried optimize, but it requires a finite interval:
minVal <- function(f) {
optimize(f, c(-100, 100))
}
Have you tried the nlm function?
nlm(function(x) x^2 -1, p = 1E3)
$minimum
[1] -1
$estimate
[1] -2.499974e-10
$gradient
[1] 9.995338e-07
$code
[1] 1
$iterations
[1] 1
p is a starting value for minimization that is required.
As well as nlm, you could try
optim(fn=function(x) x^2 -1, par = 1, method="BFGS")
This happens to work with a starting value of 1 or 1000 (although numerical accuracy can almost never be guaranteed for general nonlinear minimization).
This will work even better if you specify the gradient explicitly:
optim(fn=function(x) x^2 -1, gr=function(x) 2*x, par = 1, method="BFGS")
Based on some quick experiment, this seems to give the correct answer for starting values between -10^7 and 10^7.
I have the following function and want find $x$ satisfying this requirement.
$$\frac{X^{2}(1.5)^{2}\exp{1.5X^{2}}}{2} < 1$$
I wrote the following r function.
f <- function(X) 0.5*X^2 * 1.5^2 * exp(X*1.5) < 1
optimize(f, c(0, 1))
But it is giving me an error. I want to find the value of X satisfying the requirement. Thank you for the help.
If we define ff as
ff <- function(X) 0.5*X^2 * 1.5^2 * exp(X*1.5)
then graphing it
curve(ff)
we see that ff(0) = 0 and ff(x) is monotonically increasing in x. The largest value of x for which ff(x) <= 1 can be calculated as the solution to ff(x) = 1 which occurs at the minimum of g:
g <- function(x) (ff(x) - 1)^2
optimize(g, c(0, 1))
giving:
$minimum
[1] 0.6008074
$objective
[1] 1.058761e-09
Thus any value of x between 0 and 0.6008074 gives a value of ff in the closed interval [0, 1].
# create graph
curve(ff)
opt <- optimize(g, c(0, 1))
abline(h = 0:1)
abline(v = c(0, opt$minimum))
As the title suggests, I would like to solve the following problem. Let f denote a a certain function and let f0 denote a given constant. Is there an economical way of finding max{x:f(x) <= f0}?
Here is what an example would look like:
f = function(x) (x-2)^2
f0 = 0.4
and in that case the correct answer would be about 2.5. Thank you in advance.
One possibility to optimize with constraints would be to define a version of your function f which returns Inf if the constraint is not met:
f <- function(x) (x-2)^2
f0 <- 0.4
f_optim <- function(x, a = f0) ifelse(f(x) <= a, f(x), Inf)
optimize(f_optim, c(-10, 10), a = f0, maximum = T, tol = .Machine$double.eps)
$maximum
[1] 2.632456
$objective
[1] 0.4
f0 = 0.04
f = function(x) (x - 2)^2
g = function(x, f0) {
delta = f0 - f(x)
abs(delta)
}
optimize(g, c(0, 10), f0 = f0, maximum=F, tol= .Machine$double.eps)