I am trying to compute this integral in R:
I found three functions which can be used for this and they are all giving me different results. Here is the code:
integrand <- function(x){
r <- 1/x
return(r)
}
First is the option from base R:
integrate(integrand,-Inf, Inf)
Giving the result:
0 with absolute error < 0
The second is from the pracma package:
quadinf(integrand, -Inf, Inf)
Giving this output:
$Q
[1] -106.227
$relerr
[1] 108.0135
$niter
[1] 7
And the last one is from the cubature package:
cubintegrate(integrand, -Inf, Inf)
Which gives the following result:
$integral
[1] Inf
$error
[1] NaN
$neval
[1] 15
$returnCode
[1] 0
So then, which one of these is correct and which should I trust? Is it 0, infinity, or -106.227? Why are they all different in the first place?
1/x isn't integrable in [-Inf,Inf] range, because not integrable in 0.
On an integrable range, results are similar:
integrate(\(x) 1/x,1,2)
#0.6931472 with absolute error < 7.7e-15
pracma::quadinf( \(x) 1/x,1,2)
#$Q
#[1] 0.6931472
#$relerr
#[1] 7.993606e-15
#$niter
#[1] 4
Note that integral of 1/x in ]0,Inf] range is log(x):
log(2)-log(1)
#[1] 0.6931472
I'm trying to set up a "Solver" function to optimize the value of "gfc" to zero varying (and finding) the variable "fc" on equation below. The parameters are given.
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = ft-((f0-fc)/k)+((f1/k)*ln((fc-f1)/(f0-f1)))
Solving this function on Excel, I found the value of fc=5.504.
You can use uniroot to find where a function equals zero:
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = function(fc) {
ft - ((f0 - fc) / k) + ((f1 / k) * log((fc - f1) / (f0 - f1)))
}
uniroot(gfc, interval = c(f0, f1))
#> $root
#> [1] 5.504386
#>
#> $f.root
#> [1] 6.72753e-09
#>
#> $iter
#> [1] 5
#>
#> $init.it
#> [1] NA
#>
#> $estim.prec
#> [1] 6.103516e-05
I assume that what you mean is that you want to solve for the value of fc for which gfc equals zero. We assume fc lies between f0 and f1. In that case using the constants in the question we have the following base R solutions. (Additionally packages with such functionality include nleqslv and rootSolve.)
1) optimize we can minimize gfc^2:
gfc <- function(fc) ft-((f0-fc)/k)+((f1/k)*log((fc-f1)/(f0-f1)))
optimize(function(x) gfc(x)^2, c(f0, f1))
giving:
$minimum
[1] 5.504383
$objective
[1] 4.777981e-12
2) uniroot or we can do it directly using uniroot:
u <- uniroot(gfc, c(f0, f1))
giving:
> u
$root
[1] 5.504386
$f.root
[1] 6.72753e-09
$iter
[1] 5
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
3) We can also solve this directly without any function like optimize or uniroot by rewriting
gfc(fc) = 0
as this where we have moved the first term of gfc to the LHS and then isolated fc in that term putting everything else on the RHS.
fc = f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
Writing this as:
fc = f(fc)
we just iterate f.
f <- function(fc) f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
fc <- (f0 + f1)/2 # starting value
for(i in 1:10) fc <- f(fc)
fc
## [1] 5.504386
4) brute force Another approach is to evaluate gfc at many points and just pick the one for which gfc^2 is least. The finer you subdivide the interval the more accurate the answer.
s <- seq(f0, f1, length = 100000)
g <- gfc(s)
s[which.min(g^2)]
## [1] 5.504395
Graphics
We can show the solution:
curve(gfc, f0, f1)
abline(h = 0, v = u$root, lty = 2)
axis(1, u$root, round(u$root, 3))
I need to solve the following function for P and K:
I would like to find all (or a handful) of P's and K's that satisfy the equation.
I have tried using R's nleqslv package, but something is going wrong.
MPK<-function(X){
Y=numeric(2)
Y[1] = 4.34783*((.3*(X[1]^.23)+.7*(X[2]^.23))^3.34783)*0.069*(X[1]^-.77)
Y[2] = 0.3*((1-X[2])/(1-X[1]))^.7
Y
}
#solve for K, P
xstart = c(.5,.5)
nleqslv(x = xstart,fn = MPK)
What I get is the following:
$x
[1] 1.214578e+10 1.006411e+00
$fvec
[1] 5.531138e-03 7.636165e-10
$termcd
[1] 5
$message
[1] "Jacobian is too ill-conditioned (1/condition=8.9e-013) (see
allowSingular option)"
$scalex
[1] 1 1
$nfcnt
[1] 142
$njcnt
[1] 7
$iter
[1] 70
How do I specify that I need solutions where Y1 is equal to Y[2]?
Reading through this documentation in R, I don't understand how to take a derivative of the function at a specific point.
They do it here in C (with gsl_deriv_central/forward/backward), but I was wondering if there is an equivalent in R?
Just install the package numDeriv and use the grad function. Here are a few simple examples that are easy to check.
library(numDeriv)
grad(sin, 1:3)
[1] 0.5403023 -0.4161468 -0.9899925
cos(1:3)
[1] 0.5403023 -0.4161468 -0.9899925
f = function(x) x^2 + 2*x +3
grad(f, 1:3)
[1] 4 6 8
2*(1:3) + 2
[1] 4 6 8
I want to find the solution of:
-x^3+6*x^2+51*x+44=0
but with R. Is it possible?
I found the package Ryacas, but nobody seems to be able to make it work.
May sound trivial, but I'm not able to find an easy way to do this...
Do you have an alternative?
Thanks guys!
You can use polynom package:
library(polynom)
p <- polynomial(c(44,51,6,-1))
# 44 + 51*x + 6*x^2 - x^3
solve(p)
# [1] -4 -1 11
But you simply can use the function polyroot from base package:
polyroot(c(44,51,6,-1))
# [1] -1+0i -4+0i 11+0i
If you keep the real part with Re:
Re(polyroot(c(44,51,6,-1)))
# [1] -1 -4 11
Here we solve for the roots using the relationship between a matrix and its characteristic polynomial.
Given the polynomial a0 + a1*x^1 + a2*x^2 + x^3, define the matrix:
0 0 -a0
1 0 -a1
0 1 -a2
The eigenvalues of this matrix are the roots of the polynomial.
Substituting y = -x in your polynomial equation gives this
y^3 + 6*y^2 - 51*y + 44=0
And gives this example
> z <- matrix(c(0,1,0,0,0,1,-44,51,-6),3,3)
> z
[,1] [,2] [,3]
[1,] 0 0 -44
[2,] 1 0 51
[3,] 0 1 -6
> eigen(z)
$values
[1] -11 4 1
$vectors
[,1] [,2] [,3]
[1,] 0.6172134 0.73827166 0.98733164
[2,] -0.7715167 -0.67115606 -0.15707549
[3,] 0.1543033 -0.06711561 -0.02243936
Or, since we've substituted -y for x:
> eigen(-z)$values
[1] 11 -4 -1
See: http://www-math.mit.edu/~edelman/publications/polynomial_roots.pdf
I just stumbled upon this question and I am not sure if anything inherently changed around the Ryacas package, but it seems to work great in 2020, here is a helpful vignette to get started: https://cran.r-project.org/web/packages/Ryacas/vignettes/getting-started.html
Following the vignette, things seem to work as expected when I run the code:
library(Ryacas)
# initialize equation:
eq <- "-x^3+6*x^2+51*x+44"
# simplify the equation:
library(glue)
yac_str(glue("Simplify({eq})"))
[1] "6*x^2-x^3+51*x+44"
# factor:
yac_str(glue("Factor({eq})"))
[1] "(-1)*(x-11)*(x+4)*(x+1)"
You can evaluate the expression like this, plugging in whatever values for x:
# evaluate
evaluate(eq,list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "-x^3+6*x^2+51*x+44"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
Here you can see the results where x=0 produced an answer of 44, x=1 produced an answer of 100, etc...
If you evaluated the new simplified or factored versions and evaluated those, you would of course end up with the same exact results:
evaluate(yac_str(glue("Simplify({eq})")),list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "6*x^2-x^3+51*x+44"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
Notice the formula changed in the $src output, but we get the same results.
Here's the factored one too:
evaluate(yac_str(glue("Factor({eq})")),list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "(-1)*(x-11)*(x+4)*(x+1)"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
The only real difference between what I outlined here and what's outlined in the vignette is the actual formula, and the fact that I used library(glue) instead of paste0, which is also a fair option.