Victor Nielsen
Victor Nielsen

Reputation: 493

Find the x that gives a specific value of a function

I have this function:

a <- 1
b <- 2 
get_y <- function (x,a,b) {
   a * b * x
}

And I want to create a function that takes in get_y and returns the x that makes y = 4 for example. How would I do that?

Upvotes: 3

Views: 128

Answers (2)

Rui Barradas
Rui Barradas

Reputation: 76555

You can solve

get_y(x,a,b) - 4 == 0

with uniroot. You don't have to create a new function, an anonymous one will do it.

a <- 1
b <- 2 
get_y <- function (x,a,b) {
  a * b * x
}

uniroot(\(x) get_y(x,a,b) - 4, c(0, 10))
#> $root
#> [1] 2
#> 
#> $f.root
#> [1] 0
#> 
#> $iter
#> [1] 1
#> 
#> $init.it
#> [1] NA
#> 
#> $estim.prec
#> [1] 8

Created on 2023-08-15 with reprex v2.0.2


Edit

Following ThomasIsCoding's comment, here is a heuristic I many times use to find the search limits.

When the functions are (relatively) simple, use curve to plot the function. If I get it wrong at the first try, expand the limits until I no longer do. In this case, it was at the 2nd try.

# doesn't display the horizontal line,
# the intersection between the function and the line y = 4
# must be outside the plot's y axis range
# curve(get_y(x, a = a, b = b), from = 0, to = 1)

# now yes, there's an intersection, the uniroot 
# search limits can be set to the interval [0, 10]
curve(get_y(x, a = a, b = b), from = 0, to = 10)
abline(h = 4)

Created on 2023-08-15 with reprex v2.0.2

Upvotes: 3

ThomasIsCoding
ThomasIsCoding

Reputation: 102241

You can try Ryacas like below

library(Ryacas)
y <- 4
f <- sprintf("%s-%s", gsub("\\{|\\}", "", deparse1(body(get_y))), y)
x <- solve(ysym(f), "x")

and you will obtain

> x
{x==4/(a*b)} 

If you want numeric solution of x, you can try the code below with a few more lines

get_x <- function(get_y, y, a, b) {
    f <- sprintf("%s-%s", gsub("\\{|\\}", "", deparse1(body(get_y))), y)
    s <- gsub("x==", "", solve(ysym(f), "x"))
    y_eval(yac_expr(s), a = a, b = b, as.r = TRUE)
}

such that

> get_x(get_y, 4, a, b)
[1] 2

> get_x(get_y, 4, a, 5)
[1] 0.8

Upvotes: 1

Related Questions