# Chain Rule in R

Hi there, I just wanted to check if there is any way of having an R code that implicitly executes the chain rule during differentiation.

For example:

Given m=x^3

and b=x^2+m^2

How can I get b'=2x+6x*m?

When I use, Deriv(b) I keep getting 2x + 2m

Thanks

Hi, and welcome!

It's hard to be definite without a `reprex` : FAQ: What's a reproducible example (`reprex`) and how do I do one?. But this is exactly what, according to its documentation the `Deriv` package and its eponymous function `Deriv()` are supposed to do. How does your problem differ from the example?

``````suppressPackageStartupMessages(library(Deriv))
f <- function(x, y) sin(x) * cos(y)
f_ <- Deriv(f)
f_(3, 4)
#>         x         y
#> 0.6471023 0.1068000
``````

Created on 2020-02-02 by the reprex package (v0.3.0)

Sorry about that, I appreciate the link--although I should have probably done my own research on how to ask a question appropriately.

``````m <- function(x){x^3
}

b <- function(x,m){x^2+m^2
}

Deriv(b)

# c(x = 2 * x, m = 2 * m)
``````

My issue is that this does not take into account that m is a function of x, and so it seems like it is not using the chain rule. I am not sure how to make it so that what I am calling m in b is implicitly a function of x. I hope this clarifies.

`Deriv` does apply the chain rule, but we need a couple of tweaks to your code in order to get what you intended. In R, a function runs in its it own environment, so the `m` inside the function `b` is an argument that gets passed into `b` when you run `b`. It is not the function `m` that you defined outside of the function `b`.

First let's redefine our functions:

``````library(Deriv)

m <- function(x){
x^3
}

b <- function(x, f){
x^2 + f(x)^2
}
``````

Notice that `b` has two arguments. `x` is a number and `f` is a function. For example, `b(3, m)` will pass the function `m` into `b`, giving 738 (3^2 + m(3)^2 = 3^2 + 3^6=738). `b(3, cos)` will pass the cosine function into `b`, giving 9.98 (3^2 + cos(3)^2 = 9.98).

Now, to run `Deriv`, we need to pass `b(x, m)` into `Deriv` as an unevaluated expression, which we can do in at least two ways (see code below). We also add the `x="x"` argument to let `Deriv` know we want only the derivative with respect to `"x"`:

``````Deriv(~b(x, m), x="x")
Deriv(quote(b(x, m)), x="x")
``````

Either way, we get:

``````x * (2 + 6 * (x * m(x)))
``````

which is 2x + 6x^2m(x)=2x+6x^5.

2 Likes

Hey! It's a learning process for everyone. Why do old doctors and lawyers still practice? Because that's exactly what it is!

I've found that a great way to figure out a problem is to get a really bonehead answer, like from an #OKBoomer whose last experience with differential equations was in the Johnson Administration, so I offer, without knowing what the result should be

``````suppressPackageStartupMessages(library(Deriv))
m <- function(x){x^3}
b <- function(x){x^2+m(x)^2}
b_ <- Deriv(b)
b_(4)
#>  6152
``````

Created on 2020-02-02 by the reprex package (v0.3.0)

1 Like

Thank you very much for this!

May I ask what the difference is between ~ and quote? If it is too laborious to explain, no worries. I just want to clarify.

This might be a bit above my pay grade but I'll give it a shot. Hopefully others can jump in and expand on or, if necessary, correct my answer.

`quote` captures an R statement without evaluating it.
`~` turns an R statement into a formula, which is also a way of delaying evaluation.

This would also work: `Deriv(expression(b(x, m)), x="x")`, because `expression` also delays evaluation. If you look at the help for `Deriv` (run `?Deriv` in the console), it describes these and other ways to pass an expression to `Deriv`. It doesn't matter here which approach you use.

If we run `Deriv(b(x,m), x="x")`, R will try to immediately evaluate `b(x,m)`. This will cause an error, because we didn't provide a value for the `x` argument. Delaying evaluation of `b(x,m)` allows `Deriv` to do whatever it's doing to symbolically evaluate the derivative.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.