I am using D to get derivatives of a function. However, R does not simplify the expression when returning the derivative. I need to figure out if a function has a derivative that can be expressed generically. Is there some way in R to simplify the expression?
> D(expression(sqrt(1 - x^2)), 'x')
-(0.5 * (2 * x * (1 - x^2)^-0.5))
> D(D(expression(sqrt(1 - x^2)), 'x'), 'x')
-(0.5 * (2 * (1 - x^2)^-0.5 - 2 * x * (-0.5 * (2 * x * (1 - x^2)^-1.5))))
Secondly, is there a way in R to do numerical integration?
library(Ryacas)
x <- Sym("x")
Simplify(deriv(sqrt(1 - x^2),x,2)) # return the result simplified
gives
expression((x^2 - 1 - x^2)/root(1 - x^2, 2)^3)
You can also try
PrettyForm(Simplify(deriv(sqrt(1 - x^2),x,2)))
which gives
2 2
x - 1 - x
---------------
3
/ 2 \
Sqrt\ 1 - x /
As for numerical integration try giving this to see what is available
library(sos)
findFn('{numerical+integration}')
As far as I know, R will not simplify the result of D(). It sounds as though you want a proper computer algebra system, and R is definitely not a full CAS. Mathematica and Maple are the most well-known, but there are also a number of open-source alternatives (as discussed on this SO post).
R can do numerical integration - for this kind of question it is worth searching in the R help pages first (i.e. help.search('integrate')). You can use integrate() in the stats package. There is also area() in the MASS package, but that is much simpler (i.e. for demonstration purposes).
Related
Related to a previous question: I am using Julia Symbolics package and would like to represent 5*pi symbolically. I tried the following to no avail:
using Symbolics
5 * Symbolics.pi # expanded to 15.707963267948966
Num(5) * Symbolics.pi # expanded to 15.707963267948966
#variables x
Symbolics.pi * x # Gives πx, so it works with variables
Desired result, a symbolic expression using Symbolics.pi and the constant that are not numerically calculated on the spot but are kept as a product of 5 and π and show up as 5π, using Symbolics.pi.
Try:
x = Symbolics.pi * Num(5)
print(x)
Here x should be evaluated, hence pi should be promoted.
Question: Is there symbolic ODE solver in R ? (ODE = ordinary differential equation)
I am afraid there is NO... but let me confirm from experts ...
For example, solve:
> (5x-6)^2 y' = 5(5x-6) y - 2
Here: y - unknown function, y' - its derivative
(It is easy to solve by hands: y = 1/(5(5x-6)) + C* (5x-6) , but I want to get that answer from R).
What I know:
1) There are NUMERICAL (not symbolic) solvers:
I know there are numerical ODE solvers like library(deSolve),
see answer here:
Can R language find a generic solution of the first order differential equation?
2) There are symbolic packages : (but they do not seem to contain ODE solvers)
There are symbolic packages in R like
see Ryacas and rSymPy and also some basic symbolic calculation in base R, see:
https://stats.stackexchange.com/questions/4775/symbolic-computation-in-r/4778
3) Brief overview of various differential equations solvers for R:
https://cran.r-project.org/web/views/DifferentialEquations.html
However I was unable to find sumbolic ODE solvers (((
I've had a play around with Ryacas, and you can in fact get symbolic solutions to some simple ODEs without too much work. Unfortunately, YACAS fails to find a solution for your example ODE. However, depending on the ODEs you are exploring, this might still be of use. If not, I'm happy to remove this post.
As an initial simple example, let's consider the following ODE: y'' + y = 0:
Load the library
library(Ryacas);
Since Ryacas is just an interface to YACAS, we can use YACAS' OdeSolve to solve the ODE
yacas("OdeSolve( y\'\' + y == 0 )")
#expression(C70 * exp(x * complex_cartesian(0, -1)) + C74 * exp(x *
# complex_cartesian(0, 1)))
This gives the correct solution const * exp(- ix) + const * exp(+ ix).
Unfortunately when using your particular example, OdeSolve fails to find a solution:
yacas("OdeSolve( y\'\' == (5 * (5 * x - 6) * y - 2) / (5 * x - 6)^2 )")
#expression(y(2) - (5 * ((5 * x - 6) * y(0)) - 2)/(5 * x - 6)^2)
The same happens when we use the YACAS online demo.
This question already has answers here:
Real cube root of a negative number
(3 answers)
Closed 5 years ago.
I have the following code for generating random variables in R
theta<-1
n<-1000
u<-runif(n)
H<-(-theta*log(1-u)^(1/3))
My problem is that the output I'm getting for H is NaN 1000 times as the output when I know that the answer is real. Is there something wrong with the way I defined H?
In order:
u = runif(n) # between 0 and 1
1 - u # between 0 and 1
log(1 - u) # negative real
log(1 - u) ^ (1/3) # NaN because...
From help("^") "Users are sometimes surprised by the value returned, for example why (-8)^(1/3) is NaN. For double inputs, R makes use of IEC 60559 arithmetic on all platforms, together with the C system function pow for the ^ operator. The relevant standards define the result in many corner cases. In particular, the result in the example above is mandated by the C99 standard."
So whenever you raise x to a non-integer power, the answer will be NaN if x < 0. One option, to get a negative real result, is to raise the abs(x) to the non-integer power and then make the result negative. (More generally, we multiply by sign(x) so it still works for positive x.)
sign(log(1 - u)) * (abs(log(1 - u)) ^ (1/3)) # Negative real, based on your inputs
-theta * sign(log(1 - u)) * (abs(log(1 - u)) ^ (1/3)) # Maybe what you want?
I am using R to calculate a nested functions like this:
C1_B <- function(T){integrate(function(tau)f(tau),lower=0.01*T,upper=0.99*T)$value}
f <- function(tau) {integrate(function(tau1)sqrt(1/(tau-tau1)),lower=0.01*tau,upper=0.99*tau)$value}
C1_B(0.5)
However, I receive a message like
"Error in integrate(function(tau1) sqrt(1/(tau - tau1)), lower = 0.01
* : non-finite function value
In addition: Warning message:**
In sqrt(1/(tau - tau1)) : NaNs produced"
I guess the problem is about the "(tau-tau1)" in my code; but from the
integral domain I defined ("lower=0.01*tau,upper=0.99*tau"), (tau-tau1) could not be equal to zero.
Could any body please tell me how can I solve this problem?
I gave it a try - the problem is that integrate expects the handed over function to be able to deal with input vectors and output a vector of same size.
Luckily the solution is easy - just wrap your function in sapply.
The following code works:
f <- function(tau) {integrate(function(tau1)sqrt(1/(tau-tau1)),lower=0.01*tau,upper=0.99*tau)$value}
intfun <- function(x) sapply(x,f)
C1_B <- function(T){integrate(function(tau) intfun(tau),lower=0.01*T,upper=0.99*T)$value}
C1_B(0.5)
There exists an exact solution to your integral f. However the value I get does not agree with this numeric approximation. I would say the integral of
d(tau1)/sqrt(tau - tau1)
is
-2 * sqrt(tau - tau1)
With you upper bound of 0.99*tau and you lower bound of 0.01*tau you get
-2 * (sqrt(tau - 0.99 * tau) - sqrt(tau - 0.01 * tau)) =
-2 * sqrt(tau) * (sqrt(0.01) - sqrt(0.99))
The integration of that for tau can again be solved exactly. It yields
-(4/3)(sqrt(0.01) - sqrt(0.99)) * tau^(3/2)
Edit: With your given boundaries 0.01*T and 0.99*T the final resulting solution is
-(4/3)(sqrt(0.01)-sqrt(0.99)) * ((0.99 * T)^3/2 - (0.01 * T)^3/2)
You can use integrate on the first exact integration result (for f). No error are produced. The errors you report are probably due to the method of approximation. Maybe you could try another integration function that uses another approximation. The exact solution of the function f matches the integral calculated in your program.
When you use integrate to integrate the exact result for f the results are equal to the exact final solution I gave.
I need to calculate a list of very small numbers such as
(0.1)^1000, 0.2^(1200),
and then normalize them so they will sum up to one
i.e.
a1 = 0.1^1000,
a2 = 0.2^1200
And I want to calculate
a1' = a1/(a1+a2),
a2'=a2(a1+a2).
I'm running into underflow problems, as I get a1=0. How can I get around this?
Theoretically I could deal with logs, and then log(a1) = 1000*log(0.l) would be a way to represent a1 without underflow problems - But in order to normalize I would need to get
log(a1+a2) - which I can't compute since I can't represent a1 directly.
I'm programming with R - as far as I can tell there is no data type such Decimal in c# which
allows you to get better than double-precision value.
Any suggestions will be appreciated, thanks
Mathematically spoken, one of those numbers will be appx. zero, and the other one. The difference between your numbers is huge, so I'm even wondering if this makes sense.
But to do that in general, you can use the idea from the logspace_add C-function that's underneath the hood of R. One can define logxpy ( =log(x+y) ) when lx = log(x) and ly = log(y) as :
logxpy <- function(lx,ly) max(lx,ly) + log1p(exp(-abs(lx-ly)))
Which means that we can use :
> la1 <- 1000*log(0.1)
> la2 <- 1200*log(0.2)
> exp(la1 - logxpy(la1,la2))
[1] 5.807714e-162
> exp(la2 - logxpy(la1,la2))
[1] 1
This function can be called recursively as well if you have more numbers. Mind you, 1 is still 1, and not 1 minus 5.807...e-162 . If you really need more precision and your platform supports long double types, you could code everything in eg C or C++, and return the results later on. But if I'm right, R can - for the moment - only deal with normal doubles, so ultimately you'll lose the precision again when the result is shown.
EDIT :
to do the math for you :
log(x+y) = log(exp(lx)+exp(ly))
= log( exp(lx) * (1 + exp(ly-lx) )
= lx + log ( 1 + exp(ly - lx) )
Now you just take the largest as lx, and then you come at the expression in logxpy().
EDIT 2 : Why take the maximum then? Easy, to assure that you use a negative number in exp(lx-ly). If lx-ly gets too big, then exp(lx-ly) would return Inf. That's not a correct result. exp(ly-lx) would return 0, which allows for a far better result:
Say lx=1 and ly=1000, then :
> 1+log1p(exp(1000-1))
[1] Inf
> 1000+log1p(exp(1-1000))
[1] 1000
The Brobdingnag package deals with very large or small numbers, essentially wrapping Joris's answer into a convenient form.
a1 <- as.brob(0.1)^1000
a2 <- as.brob(0.2)^1200
a1_dash <- a1 / (a1 + a2)
a2_dash <- a2 / (a1 + a2)
as.numeric(a1_dash)
as.numeric(a2_dash)
Try the arbitrary precision packages:
Rmpfr "R MPFR - Multiple Precision Floating-Point Reliable"
Ryacas "R Interface to the 'Yacas' Computer Algebra System" - may also be able to do arbitrary precision.
Maybe you can treat a1 and a2 as fractions. In your example, with
a1 = (a1num/a1denom)^1000 # 1/10
a2 = (a2num/a2denom)^1200 # 1/5
you would arrive at
a1' = (a1num^1000 * a2denom^1200)/(a1num^1000 * a2denom^1200 + a1denom^1000 * a2num^1200)
a2' = (a1denom^1000 * a2num^1200)/(a1num^1000 * a2denom^1200 + a1denom^1000 * a2num^1200)
which can be computed using the gmp package:
library(gmp)
a1 <- as.double(pow.bigz(5,1200) / (pow.bigz(5,1200)+ pow.bigz(10,1000)))