Julia Symbolics can't simplify derivative expressions - julia

I am using the Symbolics package in Julia, and it seems to not be simplifying derivatives of expressions.
E.g.:
#variables r
Dr = Differential(r)
simplify(expand_derivatives(Dr((2/r)^2)))
results in
(-4(2 / (r^2))) / r
If I instead create the derivative expression by hand, then simplify works great
simplify((-4*(2 / (r^2))) / r)
gives
-8 / (r^3)
as expected.
Why doesn't simplify work correctly on expressions created from differentiation?

Use expand=true. Set up code:
using Symbolics
#variables r
Dr = Differential(r)
And now:
julia> simplify(expand_derivatives(Dr((2/r)^2)); expand=true)
-8 / (r^3)
Note that simplify((-4(2 / (r^2))) / r) worked because (-4(2 / (r^2))) / r was simplified before reaching that function:
julia> -4(2 / (r^2)) / r
-8 / (r^3)

Related

How to represent 5*π symbolically in Julia

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.

Is there symbolic ODE solver in R ? (ODE = ordinary differential equation)

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.

Julia ODE package example fail

I wanted to use Julia ODE package. I saw this example online:
tspan = [0 2*pi()] y_0 = [1 0]' F = (t, y) -> [0 1; -1 0]*y ode23(F, tspan, y_0)
(source: https://github.com/JuliaLang/julia/blob/84757050b26ed549b9aee77ac7c204d9963285a2/j/ode.j)
Yet when I run it I get the following error:
ERROR: DimensionMismatch("*")
in generic_matmatmul! at linalg/matmul.jl:372
in * at linalg/matmul.jl:117
in anonymous at none:1
in ode23 at /home/rm/.julia/v0.4/ODE/src/ODE.jl:67
A simple example would help.
The example you linked to is from 2011. The code has at least two errors. One, calling pi() is incorrect; pi is now a constant. The second is the code moved from base to the ODE package. A working example (using Julia 0.4) can be seen at:
https://github.com/JuliaLang/ODE.jl/blob/master/src/ODE.jl#L36-39
using ODE
tspan = [0, 2*pi]
y0 = [1, 0]
F = (t, y) -> [0 1; -1 0]*y
ode23(F, tspan, y0)
Note that I know nothing about solving these types of equations, I just know some of the history of moving things from base into separate packages.

Generic function for solving n-order polynomial roots in Julia

All,
I've just been starting to play around with the Julia language and am enjoying it quite a bit. At the end of the 3rd tutorial there's an interesting problem: genericize the quadratic formula such that it solves for the roots of any n-order polynomial equation.
This struck me as (a) an interesting programming problem and (b) an interesting Julia problem. Has anyone out there solved this one? For reference, here is the Julia code with a couple toy examples. Again, the idea is to make this generic for any n-order polynomial.
Cheers,
Aaron
function derivative(f)
return function(x)
# pick a small value for h
h = x == 0 ? sqrt(eps(Float64)) : sqrt(eps(Float64)) * x
# floating point arithmetic gymnastics
xph = x + h
dx = xph - x
# evaluate f at x + h
f1 = f(xph)
# evaluate f at x
f0 = f(x)
# divide the difference by h
return (f1 - f0) / dx
end
end
function quadratic(f)
f1 = derivative(f)
c = f(0.0)
b = f1(0.0)
a = f(1.0) - b - c
return (-b + sqrt(b^2 - 4a*c + 0im))/2a, (-b - sqrt(b^2 - 4a*c + 0im))/2a
end
quadratic((x) -> x^2 - x - 2)
quadratic((x) -> x^2 + 2)
The package PolynomialRoots.jl provides the function roots() to find all (real and complex) roots of polynomials of any order. The only mandatory argument is the array with coefficients of the polynomial in ascending order.
For example, in order to find the roots of
6x^5 + 5x^4 + 3x^2 + 2x + 1
after loading the package (using PolynomialRoots) you can use
julia> roots([1, 2, 3, 4, 5, 6])
5-element Array{Complex{Float64},1}:
0.294195-0.668367im
-0.670332+2.77556e-17im
0.294195+0.668367im
-0.375695-0.570175im
-0.375695+0.570175im
The package is a Julia implementation of the root-finding algorithm described in this paper: http://arxiv.org/abs/1203.1034
PolynomialRoots.jl has also support for arbitrary precision calculation. This is useful for solving equation that cannot be solved in double precision. For example
julia> r = roots([94906268.375, -189812534, 94906265.625]);
julia> (r[1], r[2])
(1.0000000144879793 - 0.0im,1.0000000144879788 + 0.0im)
gives the wrong result for the polynomial, instead passing the input array in arbitrary precision forces arbitrary precision calculations that provide the right answer (see https://en.wikipedia.org/wiki/Loss_of_significance):
julia> r = roots([BigFloat(94906268.375), BigFloat(-189812534), BigFloat(94906265.625)]);
julia> (Float64(r[1]), Float64(r[2]))
(1.0000000289759583,1.0)
There are no algebraic formulae for a general polynomials of degree five and above (infact there cant be see here). So theoretically, you could proceed using the same methodology for solutions to cubics and quartics, but even that would be a lot of hard work given very unwieldy formulae for roots of quartics. You could also use a CAS like SymPy to find out those formulae.

newton.method issues

Is this method broken in R? I am using it to find roots of the following function:
f(x) = 2.5*exp(-0.5*(2*0.045 - x)) + 2.5*exp(-0.045) + 2.5*exp(-1.5*x) - 100
It is giving an answer of -38.4762403 which is not even close (f(x) = 2.903809e+25 for x=-38.4762403). The answer should be around 0.01-0.1. This function should converge..
Even for a simple function like f(x) = exp(-x) * x, it gives answer as 8.89210984 for which f(x) = 0.001222392 and I set tolerance to 10^-12..
Also, is there a non graphical version of newton method? I looked at nleqslv but have no idea how to use it..
Thanks for your help.
R has a number of root finders, such as uniroot and polyroot. For more complicated problems you can use optimisation functions such as optim, optimize or nlminb. Here is an example of solving this problem with uniroot.
## define the function
f <- function(x){
2.5*exp(-0.5*(2*0.045 - x)) + 2.5*exp(-0.045) + 2.5*exp(-1.5*x) - 100
}
## plot the function
y <- seq(-20,20,0.1)
plot(y,f(y),ylim = c(-100,100),xlim=c(-20,20))
## find the roots
uniroot(f,c(-5,0))
uniroot(f,c(0,10))

Resources