Using mosaicCalc::D() to differentiate expression giving unexpected result - r

I am attempting to differentiate the expression -1+3*x^2/1+x^2 with respect to x, but the output is incorrect. The correct output should be:
8x/(1+x^2)^2
#> library(mosaicCalc)
#>
#> l=D(-1+3*x^2/1+x^2 ~x)
#> l
function (x)
8 * x
Edit:
I have used parenthesis, but the output is still incorrect
#> t=D((-1+3*x^2)/1+x^2 ~x)
#> t
function (x)
8 * x
Furthermore, I have used parenthesis for both the numerator and the denominator, and the output for the second derivative is incorrect.
> b = D((-1+3*x^2)/(1+x^2) ~x)
> b
function (x)
{
.e1 <- x^2
.e2 <- 1 + .e1
x * (6 - 2 * ((3 * .e1 - 1)/.e2))/.e2
}
> k = D(b~ x)
> k
function (x, t)
0
The correct answer for the second derivative is 8(-3x^2+1)/(1+x^2)^3
https://www.symbolab.com/solver/step-by-step/%5Cfrac%7Bd%7D%7Bdx%7D%5Cfrac%7B8x%7D%7B%5Cleft(1%2Bx%5E%7B2%7D%5Cright)%5E%7B2%7D%7D?or=input

I think you need b(x) ~ x to get your second derivative. That will give you an expression in x that can be differentiated. As is, you are differentiating an expression that doesn’t depend on x, so the derivative is 0.
I might create an issue on GitHub to see if it is possible to emit a useful message in this case.

Related

Sum of function values in R

I am trying to calculate the following ( the image says f(n) = n \sum_{i=1}^{\infty} (c(i)*(1-c(i))^n)):
where c(i) is
c <- function(i){1/i^3}
In other words, f(2) is 2*{1^(-3)(1-1^(-3))^2+2^(-3)(1-2^(-3))^2+3^(-3)(1-3^(-3))^2+4^(-3)(1-4^(-3))^2+...}.
How to write such an f function in R?
My initial attempt is:
f <- function(n){n*sum(c*(1-c)^n)}
but this is obviously wrong with error
Error in 1 - c : non-numeric argument to binary operator
Please let me know if further clarification is needed. Thanks.
Clearly, you can't get an infinite sum unless you tackle it analytically, but since we can see that it's a convergent sum, we could look at, say, the first million like this:
f <- function(n) {
C <- 1 / seq(1e6)^3
n * sum(C * (1 - C)^n)
}
Which allows:
f(1)
#> [1] 0.1847138
f(2)
#> [1] 0.3387583
f(3)
#> [1] 0.4674204
In case you are worried that this is not accurate enough, we get the same result out to 7 digits by summing only the first 10,000 terms, so 1 million should be very close to the converged value.

R loop to approximate square root of a positive real number with Newton's method

I am new to R and I'm working on a homework question which asks me to use a repeat loop using Newton's method for square root approximation. Here is what I have so far:
x = 2
a = 10
tol = 1e-04
repeat {
(abs(x^2 - a) > tol)
(x = 0.5 * (a/x + x))
if (all.equal(x^2, a)) {
break
}
}
But I am getting some error message plus a wrong answer. In the end, a should nearly equal x ^ 2 but it doesn't yet. I know there is something wrong with the all.equal portion, but I'm trying to figure out how to break the loop once they are close enough.
Thank you for any suggestions.
Don't use all.equal at all.
## trying to find `sqrt(10)`
x <- 2
a <- 10
tol <- 1e-10
repeat{
x <- 0.5 * (a / x + x)
if (abs(x * x - a) < tol) break
}
x
#[1] 3.162278

Solving a system of nonlinear equations in R

Suppose I have the following system of equations:
a * b = 5
sqrt(a * b^2) = 10
How can I solve these equations for a and b in R ?
I guess this problem can be stated as an optimisation problem, with the following function... ?
fn <- function(a, b) {
rate <- a * b
shape <- sqrt(a * b^2)
return(c(rate, shape) )
}
In a comment the poster specifically asks about using solve and optim so we show how to solve this (1) by hand, (2) using solve, (3) using optim and (4) a fixed point iteration.
1) by hand First note that if we write a = 5/b based on the first equation and substitute that into the second equation we get sqrt(5/b * b^2) = sqrt(5 * b) = 10 so b = 20 and a = 0.25.
2) solve Regarding the use of solve these equations can be transformed into linear form by taking the log of both sides giving:
log(a) + log(b) = log(5)
0.5 * (loga + 2 * log(b)) = log(10)
which can be expressed as:
m <- matrix(c(1, .5, 1, 1), 2)
exp(solve(m, log(c(5, 10))))
## [1] 0.25 20.00
3) optim Using optim we can write this where fn is from the question. fn2 is formed by subtracting off the RHS of the equations and using crossprod to form the sum of squares.
fn2 <- function(x) crossprod( fn(x[1], x[2]) - c(5, 10))
optim(c(1, 1), fn2)
giving:
$par
[1] 0.2500805 19.9958117
$value
[1] 5.51508e-07
$counts
function gradient
97 NA
$convergence
[1] 0
$message
NULL
4) fixed point For this one rewrite the equations in a fixed point form, i.e. in the form c(a, b) = f(c(a, b)) and then iterate. In general, there will be several ways to do this and not all of them will converge but in this case this seems to work. We use starting values of 1 for both a and b and divide both side of the first equation by b to get the first equation in fixed point form and we divide both sides of the second equation by sqrt(a) to get the second equation in fixed point form:
a <- b <- 1 # starting values
for(i in 1:100) {
a = 5 / b
b = 10 / sqrt(a)
}
data.frame(a, b)
## a b
## 1 0.25 20
Use this library.
library("nleqslv")
You need to define the multivariate function you want to solve for.
fn <- function(x) {
rate <- x[1] * x[2] - 5
shape <- sqrt(x[1] * x[2]^2) - 10
return(c(rate, shape))
}
Then you're good to go.
nleqslv(c(1,5), fn)
Always look at the detailed results. Numerical calculations can be tricky. In this case I got this:
Warning message:
In sqrt(x[1] * x[2]^2) : NaNs produced
That just means the procedure searched a region that included x[1] < 0 and then presumably noped the heck back to the right hand side of the plane.

R: Make sure default argument is evaluated early

When providing a default argument to an R function, this argument is evaluated when first used in the function. How is it possible to evaluate default argument earlier in an elegant way? Example:
f <- function(x, y = 2 * x)
{
if(x < 0) x = 10
y
}
f(1) ## Returns 2
f(-1) ## Returns 20 but I would like it to return -2
Thanks
The answer wasn't to hard to find. The function 'force' does the trick:
f <- function(x, y = 2 * x)
{
force(y)
if(x < 0) x = 10
y
}
f(1) ## Returns 2
f(-1) ## -2

How to chain a list of binary functions

I am interested in the following construction:
Let's suppose I have a list of n binary functions and a vector of n+1 arguments. For arguments sake lets use
flist = c(`+`,`-`)
args = 1:3
What I would like to do is create the following function call f2(f1(x1,x2),x3) i.e in this example
`-`(`+`(1,2),3)
where the return value is the vector of cumulative results
[1] 3 0
I have a solution of the form
f = function(x,op,res = NULL){
if(is.null(res)){
res = op[[1]](x[1],x[2])
x = x[-1]
} else{
res = c(res,op[[1]](res[length(res)],x[1]))
}
if(length(op) == 1) res
else f(x[-1],op[-1],res)
}
such that is gives the correct answer
f(x,flist)
[1] 3 0
but it doesn't feel particularly R like or elegant. Is there a better way to do this. I suspect that my implementation isn't the most efficient either and so anything that is more efficient would also be of interest.
Any one got any ideas?
Alternatively if relaxing the requirement to have cumulative answers, i.e just the final answer 0 returned, was imposed is there a nice R way to do this? I know I could modify my f to deal with this alternative but if there exists a way to do this already I would love to hear about either option.
Edit:
A comment suggested a for loop implementation so we could have
falt = function(x,op){
res = numeric(length(op))
res[1] = op[[1]](x[1],x[2])
for(i in 2:length(res)) res[i] = op[[i]](res[i-1],x[i+1])
res
}
which does work out more efficient. But I still feel there must be a neater way to do this.
If your functions are already in curried form, it's a lot easier
comp <- function (f) function (g) function (x) f(g(x))
comp2 <- comp (comp) (comp) # if this is confusing, details later
add <- function (x) function (y) y + x
mult <- function (x) function (y) y * x
comp2 (mult) (add) (3) (4) (5)
# 5 * (4 + 3)
# 5 * 7
# 35
Because everything is curried, you can apply as many arguments as you want, then apply the rest later
compute <- comp2 (mult) (add)
compute (5) (6) (7)
# 7 * (6 + 5)
# 7 * 30
# 210
If you have list of binary functions, you can use a left fold (or "reduce") to create an entire sequence
identity <- function(x) x
comp <- function (f) function (g) function (x) f(g(x))
comp2 <- comp (comp) (comp)
uncurry <- function (f) function (x,y) f(x)(y)
reduce <- function(f) function(y) function (xs) Reduce(uncurry(f), xs, y)
comp2All <- reduce (comp2) (identity)
# some binary functions to use in our sequence
sub <- function (x) function (y) y - x
add <- function (x) function (y) y + x
mult <- function (x) function (y) y * x
# create a sequence of N binary functions
compute <- comp2All (list(mult, sub, mult, add))
# apply the computation to N+1 args
compute (3) (4) (5) (100) (0.2)
# 0.2 * (100 - (5 * (3 + 4))
# 0.2 * (100 - (5 * 7))
# 0.2 * (100 - 35)
# 0.2 * 65
# => 13
So you probably don't like having to apply the computation one argument at a time...
# this kind sucks, right?
compute (3) (4) (5) (6) (7)
Well we can fix that by making a function that applies a curried function to a list or arguments
capply <- reduce (identity)
capply (compute) (3:7)
# 7 * (6 - (5 * (4 + 3)))
# 7 * (6 - (5 * 7))
# 7 * (6 - 35)
# 7 * -29
# => -203
If your binary functions are not yet curried:
You can easily curry a binary function using curry2
curry2 <- function(f) function(x) function(y) f(x,y)
curry2 (`+`) (3) (4)
# => 7
If you have an entire list of binary functions that are not already curried, you can transform the entire list using map
map <- function (f) function (xs) Map(f,xs)
compute <- comp2All (map (curry2) (list (`*`, `+`, `*`, `+`)))
compute (3) (4) (5) (6) (7)
# 7 * (6 + (5 * (3 + 4)))
# 7 * (6 + (5 * 7))
# 7 * (6 + 35)
# 7 * 41
# => 287
comp vs comp2
Because you want to create a sequence of binary functions, I used
comp2All <- reduce (comp2) (identity)
If you wanted a sequence of unary functions, you would use
compAll <- reduce (comp) (identity)
what is comp2?
The comp2 definition might seem baffling, but don't let it confuse you
comp2 <- comp (comp) (comp)
If we were to expand this, we'd first see
comp2 <- function (x) comp(comp(x))
Upon further expansion (this is a fun exercise for you to do), you should see
comp2 <- function (f) function (g) function (x) function (y) f(g(x)(y))
Which can be easily understand as the composition of unary function, f, with binary function, g

Resources