Symbolic Integrals

Symbolics.jl provides a the Integral operator for defining integrals. These can be used with various functionalities in order to represent integro-differential equations and as a representation for symbolic solving of integrals.

Note

This area is currently under heavy development. More solvers will be available in the near future.

Defining Symbolic Integrals

Note that integration domains are defined using DomainSets.jl.

Symbolics.IntegralType
Integral(domain)

Defines an Integral operator I(ex) which represents the integral of I of the expression ex over the domain. Note that the domain must be a Symbolics.VarDomainPairing where the chosen variable is the variable being integrated over, i.e. Integral(x in domain) means that I is the integral operator with respect to dx.

Examples

I1 = Integral(x in ClosedInterval(1, 5))
I2 = Integral(x in ClosedInterval(1, 5))

@variables a b
I = Integral(x in ClosedInterval(a, b))
@test isequal(I(0), 0)
@test isequal(I(2), 2*(b -a))
source

Solving Symbolic Integrals

Symbolics.jl currently has the following options for solving integrals symbolically:

PackageMethodDescriptionProsCons
SymbolicIntegration.jlRisch AlgorithmImplements theoretical Risch algorithm for elementary functionsMathematically rigorous, returns exact symbolic results, handles rational functions and transcendental functions (exp, log, trig)Still in early development, unstable, limited to specific function classes, no support for algebraic functions
SymbolicIntegration.jlRule-Based MethodApplies over 3,400 integration rules systematicallyHandles non-integer powers, supports multiple symbolic variables, more flexible than pure RischRule-dependent success, no theoretical completeness guarantee, limited by predefined rule set
SymbolicNumericIntegration.jlSymbolic-Numeric HybridUses numeric integrators with symbolic regression machine learning methodsCan solve some hard integrals very fast and easily, works differently from pure symbolic methodsCan be unreliable in easy cases, will give floats (0.5) instead of rational values (1//2), precision loss
SymPy's IntegrateHybrid MethodsUses SymPy (through SymPy.jl) to integrate the expressionReasonably robust and tested solution, mature implementationExtremely slow, Python overhead

SymbolicIntegration.jl

SymbolicIntegration.jl provides pure symbolic integration using multiple algorithmic approaches. Unlike numerical methods, it returns exact symbolic results with rational coefficients (e.g., 1//2 instead of 0.5). The package implements a flexible framework for symbolic integration that uses Julia's multiple dispatch to select appropriate algorithms for different types of integrands.

The package offers two main integration methods:

Risch Algorithm Method

The RischMethod implements the theoretical Risch algorithm for integrating:

  • Polynomial functions
  • Rational functions
  • Exponential functions
  • Logarithmic functions
  • Trigonometric functions
  • Combinations of the above

This method is mathematically rigorous and provides guaranteed results when an elementary antiderivative exists. However, it is still under development and may not handle all cases robustly.

Rule-Based Method

The rule-based approach systematically applies over 3,400 integration rules to solve integrals:

  • Handles non-integer powers and algebraic functions
  • Supports more complex integrations than pure Risch
  • Can handle multiple symbolic variables
  • More flexible but depends on the predefined rule set

The package automatically tries the Risch algorithm first, then falls back to rule-based methods if needed.

For using SymbolicIntegration.jl, see the SymbolicIntegration.jl repository for more details. Quick examples:

using Symbolics
using SymbolicIntegration

@variables x

# Basic integrations (automatic method selection)
integrate(x^2, x)           # Returns (1//3)*(x^3)
integrate(1/x, x)           # Returns log(x)
integrate(exp(x), x)        # Returns exp(x)
integrate(1/(x^2 + 1), x)   # Returns atan(x)

# Rational function with complex roots (typically uses Risch)
f = (x^3 + x^2 + x + 2)/(x^4 + 3*x^2 + 2)
integrate(f, x)  # Returns (1//2)*log(2 + x^2) + atan(x)

# Nested transcendental functions (uses Risch)
integrate(1/(x*log(x)), x)  # Returns log(log(x))

# Explicit Risch method selection
integrate(sin(x)*cos(x), x, RischMethod())

# Configurable Risch method
risch = RischMethod(use_algebraic_closure=true, catch_errors=false)
integrate(exp(x)/(1 + exp(x)), x, risch)

# Rule-based method for cases not handled by Risch
integrate(x^(1/2), x)       # Uses rule-based method for non-integer powers
integrate(sqrt(x + 1), x)   # Handles algebraic functions via rules

SymbolicNumericIntegration.jl

SymbolicNumericIntegration.jl is a package for solving symbolic integrals using numerical methods. Specifically, it mixes numerical integration with machine learning symbolic regression in order to discover the basis for the integrals solution, for which it then finds the coefficients and uses differentiation to prove the correctness of the result. While this technique is unusual and new, see the paper for details, it has the advantage of working very differently from the purely symbolic methods, and thus the problems which it finds hard can be entirely different from ones which the purely symbolic methods find hard. That is, while purely symbolic methods have difficulty depending on the complexity of the expression, this method has difficulty depending on the uniqueness of the numerical solution of the expression, and there are many complex expressions which have a very distinct solution behavior and thus can be easy to solve through this method.

One major downside to this method is that, because it works numerically, there can be precision loss in the coefficients. Thus the returned solution may have 0.5 instead of 1//2.

For using SymbolicNumericIntegration.jl, see the SymbolicNumericIntegration.jl documentation for more details. A quick example is:

using Symbolics
using SymbolicNumericIntegration

@variables x a b

integrate(3x^3 + 2x - 5)
# (x^2 + (3 // 4) * (x^4) - (5 // 1) * x, 0, 0)

integrate(exp(a * x), x; symbolic = true)
# (exp(a * x) / a, 0, 0)

integrate(sin(a * x) * cos(b * x), x; symbolic = true, detailed = false)
# (-a * cos(a * x) * cos(b * x) - b * sin(a * x) * sin(b * x)) / (a^2 - (b^2))

SymPy

The function sympy_integrate allows one to call SymPy's integration functionality. While it's generally slow, if you leave your computer on for long enough it can solve some difficult expressions.

Symbolics.sympy_integrateFunction
sympy_integrate(expr, var)

Computes indefinite integral of expr w.r.t. var using SymPy.

Arguments

  • expr: Symbolics expression.
  • var: Symbolics variable.

Returns

Symbolics integral.

Example

@variables x
expr = x^2
result = sympy_integrate(expr, x)
source