Skip to content

Commit 5af026d

Browse files
Merge pull request #12 from Bumblebee00/rule_based_repo_branch
Add rule based integration method
2 parents 64a02e9 + 8344d68 commit 5af026d

File tree

354 files changed

+168451
-525
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

354 files changed

+168451
-525
lines changed

.github/badges/rules-count.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"schemaVersion": 1,
3+
"label": "Total rules",
4+
"message": "3399",
5+
"color": "blue"
6+
}

.github/dependabot.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2+
version: 2
3+
updates:
4+
- package-ecosystem: "github-actions"
5+
directory: "/" # Location of package manifests
6+
schedule:
7+
interval: "weekly"

.github/workflows/ci.yml

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
version:
2424
- '1.10'
2525
- '1'
26+
- 'pre'
2627
os:
2728
- ubuntu-latest
2829
- macos-latest
@@ -37,7 +38,53 @@ jobs:
3738
arch: ${{ matrix.arch }}
3839
- uses: julia-actions/cache@v2
3940
- uses: julia-actions/julia-buildpkg@v1
40-
- uses: julia-actions/julia-runtest@v1
41+
- name: Run tests julia 1.11 ubuntu-latest and count rules
42+
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
43+
run: |
44+
julia --project=. -e "
45+
using SymbolicIntegration
46+
using Pkg
47+
48+
rules_count = length(SymbolicIntegration.RULES)
49+
println(\"Total rules: \$rules_count\")
50+
51+
# Create directory if it doesn't exist
52+
mkpath(\".github/badges\")
53+
54+
# Write the JSON file manually
55+
open(\".github/badges/rules-count.json\", \"w\") do f
56+
println(f, \"{\")
57+
println(f, \" \\\"schemaVersion\\\": 1,\")
58+
println(f, \" \\\"label\\\": \\\"Total rules\\\",\")
59+
println(f, \" \\\"message\\\": \\\"\$rules_count\\\",\")
60+
println(f, \" \\\"color\\\": \\\"blue\\\"\")
61+
println(f, \"}\")
62+
end
63+
64+
println(\"Badge data written to .github/badges/rules-count.json\")
65+
66+
Pkg.test()
67+
"
68+
id: count_rules
69+
70+
- name: Commit badge data
71+
if: matrix.version == '1' && matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main'
72+
env:
73+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
run: |
75+
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
76+
git config --local user.name "github-actions[bot]"
77+
git add .github/badges/rules-count.json
78+
if git diff --staged --quiet; then
79+
echo "No changes to commit"
80+
else
81+
git commit -m "Update rules count badge [skip ci]"
82+
git push
83+
fi
84+
85+
- name: Run tests (other configurations)
86+
if: ${{ !(matrix.version == '1' && matrix.os == 'ubuntu-latest') }}
87+
uses: julia-actions/julia-runtest@v1
4188
- uses: julia-actions/julia-processcoverage@v1
4289
- uses: codecov/codecov-action@v5
4390
with:

.github/workflows/spellcheck.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Spell Check
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
typos-check:
7+
name: Spell Check with Typos
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout Actions Repository
11+
uses: actions/checkout@v4
12+
- name: Check spelling
13+
uses: crate-ci/[email protected]

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
SymbolicIntegration.jl is licensed under the MIT License:
22

3-
Copyright (c) 2022 Harald Hofstätter
3+
Copyright (c) 2022 Harald Hofstätter, Mattia Micheletta Merlin, Chris Rackauckas, and other contributors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Project.toml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
name = "SymbolicIntegration"
22
uuid = "315ce56f-eed0-411d-ab8a-2fbdf9327b51"
3-
authors = ["HaraldHofstaetter <[email protected]>", "Chris Rackauckas <[email protected]>", "JuliaSymbolics contributors"]
4-
version = "2.0.0"
3+
keywords = ["symbolic", "integration", "mathematics", "computer-algebra"]
4+
license = "MIT"
5+
authors = ["HaraldHofstaetter <[email protected]>", "Mattia Micheletta Merlin <[email protected]>", "Chris Rackauckas <[email protected]>", "JuliaSymbolics contributors"]
56
description = "Symbolic integration algorithms for Julia"
67
repository = "https://github.com/JuliaSymbolics/SymbolicIntegration.jl"
7-
license = "MIT"
8-
keywords = ["symbolic", "integration", "mathematics", "computer-algebra"]
8+
version = "2.0.0"
99

1010
[deps]
1111
AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
12+
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
13+
Elliptic = "b305315f-e792-5b7a-8f41-49f472929428"
14+
FresnelIntegrals = "88497964-e39a-11e9-0fb5-b1bf0ffe80fe"
15+
HypergeometricFunctions = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
1216
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
1317
Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a"
18+
PolyLog = "85e3b03c-9856-11eb-0374-4dc1f8670e7f"
1419
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
1520
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
1621

1722
[compat]
1823
AbstractAlgebra = "0.46"
24+
Combinatorics = "1.0.2"
25+
Elliptic = "1.0.1"
26+
FresnelIntegrals = "0.2.0"
27+
HypergeometricFunctions = "0.3.28"
1928
Nemo = "0.51"
29+
PolyLog = "2.6.0"
2030
SymbolicUtils = "3"
2131
Symbolics = "6"
2232
julia = "1.10"
2333

2434
[extras]
35+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
36+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
2537
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2638

2739
[targets]
28-
test = ["Test"]
40+
test = ["Test", "Pkg", "Dates"]

README.md

Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,105 @@
11
# SymbolicIntegration.jl
22

3-
*A unified interface for symbolic integration methods in Julia*
3+
[![Build Status](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/actions/workflows/CI.yml?query=branch%3Amain)
4+
[![Spell Check](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/actions/workflows/spellcheck.yml/badge.svg?branch=main)](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/actions/workflows/spellcheck.yml)
5+
[![Rules](https://img.shields.io/badge/dynamic/json?url=https://raw.githubusercontent.com/JuliaSymbolics/SymbolicIntegration.jl/main/.github/badges/rules-count.json&query=$.message&label=Total%20rules&color=blue)](https://github.com/JuliaSymbolics/SymbolicIntegration.jl)
46

5-
SymbolicIntegration.jl provides a flexible, extensible framework for symbolic integration with multiple algorithm choices. The package uses method dispatch to allow users to select the most appropriate integration algorithm for their specific needs.
67

7-
## Key Features
8+
SymbolicIntegration.jl solves indefinite integrals using one of the implemented algorithms: Risch method and Rule based method
89

9-
- 🎯 **Multiple Integration Methods**: Extensible method dispatch system
10-
-**Exact Symbolic Results**: Guaranteed correct symbolic integration
11-
- 🔢 **Complex Root Handling**: Produces exact arctangent terms
12-
- ⚙️ **Configurable Algorithms**: Method-specific options and behavior
13-
- 🏗️ **Professional Interface**: SciML-style method selection
1410

15-
## Integration Methods
16-
17-
### RischMethod (Default)
18-
Complete symbolic integration using the Risch algorithm from Manuel Bronstein's "Symbolic Integration I: Transcendental Functions".
19-
20-
**Capabilities:**
21-
-**Rational functions**: Complete integration with Rothstein-Trager method
22-
-**Transcendental functions**: Exponential, logarithmic using differential field towers
23-
-**Complex roots**: Exact arctangent terms for complex polynomial roots
24-
-**Integration by parts**: Logarithmic function integration
25-
-**Trigonometric functions**: Via transformation to exponential form
26-
27-
**Function Classes:**
28-
- Polynomial functions: `∫x^n dx`, `∫(ax^2 + bx + c) dx`
29-
- Rational functions: `∫P(x)/Q(x) dx` → logarithmic and arctangent terms
30-
- Exponential functions: `∫exp(f(x)) dx`, `∫x*exp(x) dx`
31-
- Logarithmic functions: `∫log(x) dx`, `∫1/(x*log(x)) dx`
32-
- Trigonometric functions: `∫sin(x) dx`, `∫cos(x) dx`, `∫tan(x) dx`
33-
34-
The framework is designed to support additional integration methods as they are developed.
35-
36-
37-
38-
## Installation
11+
# Usage
3912
```julia
40-
julia> using Pkg; Pkg.add("SymbolicIntegration")
41-
```
13+
julia> using Pkg; Pkg.add("SymbolicIntegration") # installation
4214

43-
## Usage
15+
julia> using SymbolicIntegration, Symbolics
4416

45-
### Basic Integration
17+
julia> @variables x
18+
1-element Vector{Num}:
19+
x
4620

47-
```julia
48-
using SymbolicIntegration, Symbolics
49-
@variables x
50-
51-
# Default method (RischMethod) - most cases
52-
integrate(x^2, x) # (1//3)*(x^3)
53-
integrate(1/x, x) # log(x)
54-
integrate(exp(x), x) # exp(x)
55-
integrate(1/(x^2 + 1), x) # atan(x)
21+
julia> integrate(exp(2x) + 2x^2 + sin(x))
22+
(1//2)*exp(2x) + (2//3)*(x^3) - cos(x)
5623
```
24+
The first argument is the expression to integrate, second argument is the variable of integration. If the variable is not specified, it will be guessed from the expression. The +c is omitted :)
5725

5826
### Method Selection
5927

28+
You can explicitly choose a integration method like this:
6029
```julia
61-
# Explicit method choice
62-
integrate(f, x, RischMethod())
63-
64-
# Method with configuration
6530
risch = RischMethod(use_algebraic_closure=true, catch_errors=false)
6631
integrate(f, x, risch)
6732
```
33+
or like this:
34+
```julia
35+
rbm = RuleBasedMethod(verbose=true, use_gamma=false)
36+
integrate(f, x, rbm)
37+
```
38+
39+
If no method is specified, first RischMethod will be tried, then RuleBasedMethod:
40+
```julia
41+
julia> integrate(sqrt(x))
42+
┌ Warning: NotImplementedError: integrand contains unsupported expression sqrt(x)
43+
└ @ SymbolicIntegration ~/.julia/dev/SymbolicIntegration.jl_official/src/methods/risch/frontend.jl:826
6844

69-
### Complex Examples
45+
> RischMethod failed returning (sqrt(x), x)
46+
> Trying with RuleBasedMethod...
7047

48+
(2//3)*(x^(3//2))
49+
```
7150
```julia
72-
# Rational function with complex roots
73-
f = (x^3 + x^2 + x + 2)/(x^4 + 3*x^2 + 2)
74-
integrate(f, x) # (1//2)*log(2 + x^2) + atan(x)
51+
julia> integrate(abs(x))
52+
┌ Warning: NotImplementedError: integrand contains unsupported expression abs(x)
53+
└ @ SymbolicIntegration ~/.julia/dev/SymbolicIntegration.jl_official/src/methods/risch/frontend.jl:826
54+
55+
> RischMethod failed returning (abs(x), x)
56+
> Trying with RuleBasedMethod...
7557

76-
# Integration by parts
77-
integrate(log(x), x) # -x + x*log(x)
58+
No rule found for (abs(x), x)
59+
60+
> RuleBasedMethod failed returning (abs(x), x)
61+
> Sorry we cannot integrate this expression :(
7862

79-
# Nested transcendental functions
80-
integrate(1/(x*log(x)), x) # log(log(x))
8163
```
8264
83-
## Method Framework
8465
85-
SymbolicIntegration.jl uses a modern method dispatch system similar to other SciML packages:
66+
# Integration Methods
67+
Currently two algorithms are implemented: **Risch algorithm** and **Rule based integration**.
8668
87-
### Current Methods
88-
- **RischMethod**: Complete symbolic integration (default)
69+
feature | Risch | Rule based
70+
--------|-------|-----------
71+
rational functions | ✅ | ✅
72+
non integers powers | ❌ | ✅
73+
exponential functions | ✅ | ✅
74+
logarithms | ✅ | ✅
75+
trigonometric functions | ? | sometimes
76+
hyperbolic functions | ✅ | sometimes
77+
Nonelementary integrals | ❌ | most of them
78+
Special functions | ❌ | ❌
79+
more than one symbolic<br> variable in the expression | ❌ | ✅
8980
90-
### Method Configuration
91-
```julia
92-
# Research configuration (strict, complete)
93-
RischMethod(use_algebraic_closure=true, catch_errors=false)
81+
More info about them in the [methods documentation](methods/overview.md)
9482
95-
# Production configuration (robust, graceful)
96-
RischMethod(use_algebraic_closure=true, catch_errors=true)
83+
### Risch Method
84+
Complete symbolic integration using the Risch algorithm from Manuel Bronstein's "Symbolic Integration I: Transcendental Functions".
9785
98-
# Performance configuration (faster, simpler)
99-
RischMethod(use_algebraic_closure=false, catch_errors=true)
100-
```
86+
### RuleBasedMethod
10187
102-
### Extensibility
103-
The framework is designed for easy extension with additional integration methods. The abstract type `AbstractIntegrationMethod` provides the foundation for implementing new algorithms.
88+
This method uses a large number of integration rules that specify how to integrate various mathematical expressions. There are now more than 3400 rules impelmented.
10489
105-
## Documentation
90+
# Documentation
10691
10792
Complete documentation with method selection guidance, algorithm details, and examples is available at:
10893
**[https://symbolicintegration.juliasymbolics.org](https://symbolicintegration.juliasymbolics.org)**
10994
110-
## Citation
95+
96+
# Citation
11197
11298
If you use SymbolicIntegration.jl in your research, please cite:
11399
114100
```bibtex
115101
@software{SymbolicIntegration.jl,
116-
author = {Harald Hofstätter and contributors},
102+
author = {Harald Hofstätter and Mattia Micheletta Merlin and Chris Rackauckas},
117103
title = {SymbolicIntegration.jl: Symbolic Integration for Julia},
118104
url = {https://github.com/JuliaSymbolics/SymbolicIntegration.jl},
119105
year = {2023-2025}

0 commit comments

Comments
 (0)