This is an experiment to provide a R interface to the SymEngine library. It is still in progress, but if you are interested, please contact Jialin Ma [email protected] and Isuru Fernando [email protected].
This project is expected to be a GSoC 2018 project under the organization of The R Project for Statistical Computing.
Note: It is not supported on Windows yet.
First, ensure you have some prerequisites installed, for example on Debian-based system:
sudo apt-get install cmake libgmp-dev libmpfr-dev libmpc-dev
Then in R
devtools::install_github("Marlin-Na/symengine.R")
This package has a build-time dependency of the Rlibsymengine package, which should be automatically installed using devtools above.
Please report any problem installing the package on your system.
library(symengine)
#> SymEngine Version: 0.3.0
#> _____ _____ _
#> | __|_ _ _____| __|___ ___|_|___ ___
#> |__ | | | | __| | . | | | -_|
#> |_____|_ |_|_|_|_____|_|_|_ |_|_|_|___|
#> |___| |___|
#>
#> Attaching package: 'symengine'
#> The following object is masked from 'package:base':
#>
#> diff
A symbol or variable can be constructed from character.
(x <- Symbol("x"))
#> (Symbol) x
(y <- Symbol("y"))
#> (Symbol) y
x ^ y
#> (Pow) x^y
There are explicit constructors for such types:
Integer(42L)
#> (Integer) 42
RealDouble(base::pi)
#> (RealDouble) 3.14159265358979
For large integer and high-precision floating number that R can not hold, you can construct "Integer" or "RealMPFR" from character. For example:
8615937169318
#> [1] 8.615937e+12
as.integer(8615937169318)
#> Warning: NAs introduced by coercion to integer range
#> [1] NA
Integer("8615937169318")
#> (Integer) 8615937169318
Integer("8615937169318") ^ 9L
#> (Integer) 261651187038033556722865852191251735369739650060120439731902444918211391981554448221540729228593041137656153397421568
# TODO, currently not available
RealMPFR("3.1415926535897932384626433832795028841971693993751058209", bits = 70)
Comparing with the mpfr
function in Rmpfr
package:
Rmpfr::mpfr("3.1415926535897932384626433832795028841971693993751058209", precbits = 70)
#> 1 'mpfr' number of precision 187 bits
#> [1] 3.141592653589793238462643383279502884197169399375105820901
Or simply use the SymEngine parser instead of the explicit constructors:
S("8615937169318")
#> (Integer) 8615937169318
S("3.1415926535897932384626433832795028841971693993751058209")
#> (RealMPFR) 3.1415926535897932384626433832795028841971693993751058209
There will be explicit constructors (TODO):
Or use the parser:
S("6 + 9I")
#> (Complex) 6 + 9*I
Or use:
6L + 9L * Constant("I")
#> (Add) 6 + 9*i
The mpc
library is used for holding complex number with arbitrary precision, similar to mpfr
library for floating number.
S("2.3 + 23.9999999999999999999I")
#> (ComplexMPC) 2.29999999999999982236 + 23.9999999999999999999*I
For example:
Constant("pi")
#> (Constant) pi
sin(Constant("pi") / 2L)
#> (Integer) 1
As already showed in the above examples, S
converts a R object to SymEngine object. When the input is a character, it will parse the expression to produce appropriate object.
S(6L)
#> (Integer) 6
S(4.2)
#> (RealDouble) 4.2
(x <- S("x"))
#> (Symbol) x
(k <- S(~ k)) # Currently only work with "symbol"
#> (Symbol) k
(b <- Constant("b"))
#> (Constant) b
S("k * x + b")
#> (Add) b + k*x
k * x + b
#> (Add) k*x + b
S("pi")
#> (Constant) pi
S("sin(pi)")
#> (Integer) 0
S("(tan(x) + sin(x))^2")
#> (Pow) (sin(x) + tan(x))^2
S("a + 2 >= a")
#> (LessThan) a <= 2 + a
Substitute a variable with another one:
x <- S("x")
a <- S("a")
(expr <- (tan(x) + sin(x) + a) ^ 2L)
#> (Pow) (a + sin(x) + tan(x))^2
subs(expr, "x", "a")
#> (Pow) (a + sin(a) + tan(a))^2
subs(expr, "x", 3.1415926)
#> (Pow) (-7.94093388050907e-23 + a)^2
subs(expr, "x", Constant("pi"))
#> (Pow) a^2
subs(expr, "x", Constant("pi") * 2L/3L)
#> (Pow) (a + (-1/2)*sqrt(3))^2
expr
#> (Pow) (a + sin(x) + tan(x))^2
expand(expr)
#> (Add) 2*a*sin(x) + 2*a*tan(x) + 2*sin(x)*tan(x) + a^2 + sin(x)^2 + tan(x)^2
expr
#> (Pow) (a + sin(x) + tan(x))^2
diff(expr, "x")
#> (Mul) 2*(a + sin(x) + tan(x))*(1 + tan(x)^2 + cos(x))
diff(expr, "a")
#> (Mul) 2*(a + sin(x) + tan(x))
evalf(Constant("pi"), bits = 999)
#> (RealMPFR) 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127
Eq(x + y, S("x + y"))
#> [1] TRUE
Neq(x + y, S("x + y"))
#> [1] FALSE
tan(x)
#> (Tan) tan(x)
sin(x)/cos(x)
#> (Mul) sin(x)/cos(x)
Eq(tan(x), sin(x)/cos(x)) # Different internal representation
#> [1] FALSE
Hash(tan(x))
#> [1] "5308874006"
Hash(sin(x)/cos(x))
#> [1] "46369110327826722"
TODO
TODO
S("f(x, y)")
#> (FunctionSymbol) f(x, y)
TODO
TODO
TODO
The SymEngine objects are implemented with "externalptr":
x <- Symbol(~ x)
str(x)
#> Formal class 'Basic' [package "symengine"] with 1 slot
#> ..@ .xData:<externalptr>
See "src/interface.c" for the C code that wraps the symengine api.
-
There are several functions in base R for defferentiation, integration, solving system of equations, etc. E.g.
solve
,stats::D
,stats::deriv
,stats::integrate
,stats::numericDeriv
. -
R package
Deriv
for symbolic differentiation, it allows user to supply custom rules for differentiation. -
R package
numDeriv
for calculating numerical approximations to derivatives. -
R package
gmp
andRmpfr
provide multiple precision arithmetic and floating point operations. They also include some special functions, e.g.Rmpfr::integrateR
for numerical integration. -
R package
mpc
available at R forge. It provides multiple precision arithmetic for complex numbers. -
R package
rSymPy
provides an interface to 'SymPy' library in python via rJava. -
R package
Ryacas
provides an interface to the 'Yacas' computer algebra system. It is easier to install compared torSymPy
.
The SymEngine library can optionally depend on some external libraries, which is configured by CMake, see the list of CMake options in README of SymEngine and the configure script of Rlibsymengine.
A few notes:
-
GMP
(GNU Multiple Precision Arithmetic Library) is a C library that can be used to store and do arithmetic calculation with big integers and rationals. It has an R interface (gmp package). -
mpfr
(Multiple Precision Floating-Point Reliable) is a C library that depends on theGMP
library and is used for arbitrary precision floating number arithmetic calculations. It has an R interface (Rmpfr package). This is an optional dependency for SymEngine. -
mpc
() is a C library that extends thempfr
library for the arithmetic of complex numbers with arbitrarily precision. There is a R packagempc
which is not on CRAN, but available at R forge.