Skip to content

Commit 1b0924d

Browse files
ver 1.3; improved integration coverage; symbolic code refactored
1 parent b8b2bb8 commit 1b0924d

File tree

15 files changed

+268
-429
lines changed

15 files changed

+268
-429
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@ the documentation, which contains the unreleased features.
2121
## Example
2222

2323
```julia
24-
julia> using SymbolicNumericIntegration
2524
julia> using Symbolics
25+
using SymbolicNumericIntegration
2626

2727
julia> @variables x a b
2828

2929
julia> integrate(3x^3 + 2x - 5)
30-
(x^2 + (3//4)*(x^4) - (5//1)*x, 0, 0)
3130

3231
julia> integrate(exp(a * x), x; symbolic = true)
33-
(exp(a*x) / a, 0, 0)
32+
(x^2 + (3//4)*(x^4) - (5//1)*x, 0, 0)
3433

3534
julia> integrate(sin(a * x) * cos(b * x), x; symbolic = true, detailed = false)
36-
(-a*cos(a*x)*cos(b*x) - b*sin(a*x)*sin(b*x)) / (a^2 - (b^2))
35+
(exp(a*x) / a, 0, 0)
3736
```
3837

3938
# Citation

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ makedocs(sitename = "SymbolicNumericIntegration.jl",
99
authors = "Shahriar Iravanian",
1010
modules = [SymbolicNumericIntegration],
1111
clean = true, doctest = false, linkcheck = true,
12-
warnonly = [:missing_docs],
12+
# warnonly = [:missing_docs],
1313
format = Documenter.HTML(assets = ["assets/favicon.ico"],
1414
canonical = "https://docs.sciml.ai/SymbolicNumericIntegration/stable/"),
1515
pages = pages)

docs/src/index.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,52 +22,52 @@ Pkg.add("SymbolicNumericIntegration")
2222
Examples:
2323

2424
```julia
25-
julia> using SymbolicNumericIntegration
26-
julia> using Symbolics
25+
using Symbolics
26+
using SymbolicNumericIntegration
2727

28-
julia> @variables x a b
28+
@variables x a b
2929

3030
# if `detailed = true` (default), the output is a tuple of (solution, unsolved portion, err)
3131

32-
julia> integrate(3x^3 + 2x - 5)
32+
integrate(3x^3 + 2x - 5)
3333
(x^2 + (3//4)*(x^4) - (5x), 0, 0)
3434

35-
julia> integrate((5 + 2x)^-1)
35+
integrate((5 + 2x)^-1)
3636
((1//2)*log((5//2) + x), 0, 0.0)
3737

3838
# `detailed = false` simplifies the output to just the resulting integral
3939

40-
julia> integrate(x^2 / (16 + x^2); detailed = false)
40+
integrate(x^2 / (16 + x^2); detailed = false)
4141
x + 4atan((-1//4)*x)
4242

43-
julia> integrate(x^2 * log(x); detailed = false)
43+
integrate(x^2 * log(x); detailed = false)
4444
(1//3)*(x^3)*log(x) - (1//9)*(x^3)
4545

46-
julia> integrate(sec(x) * tan(x); detailed = false)
46+
integrate(sec(x) * tan(x); detailed = false)
4747
sec(x)
4848

4949
# Symbolic integration. Here, a is a symbolic constant; therefore, we need
5050
# to explicitly define the independent variable (say, x). Also, we set
5151
# `symbolic = true` to force using the symbolic solver
5252

53-
julia> integrate(sin(a * x), x; detailed = false, symbolic = true)
53+
integrate(sin(a * x), x; detailed = false, symbolic = true)
5454
(-cos(a*x)) / a
5555

56-
julia> integrate(x^2 * cos(a * x), x; detailed = false, symbolic = true)
56+
integrate(x^2 * cos(a * x), x; detailed = false, symbolic = true)
5757
((a^2)*(x^2)*sin(a*x) + 2.0a*x*cos(a*x) - 2.0sin(a*x)) / (a^3)
5858

59-
julia> integrate(log(log(a * x)) / x, x; detailed = false, symbolic = true)
59+
integrate(log(log(a * x)) / x, x; detailed = false, symbolic = true)
6060
log(a*x)*log(log(a*x)) - log(a*x)
6161

6262
# multiple symbolic constants
6363

64-
julia> integrate(cosh(a * x) * exp(b * x), x; detailed = false, symbolic = true)
64+
integrate(cosh(a * x) * exp(b * x), x; detailed = false, symbolic = true)
6565
(a*sinh(a*x)*exp(b*x) - b*cosh(a*x)*exp(b*x)) / (a^2 - (b^2))
6666

6767
# definite integration, passing a tuple of (x, lower bound, higher bound) in the
6868
# second argument
6969

70-
julia> integrate(x * sin(a * x), (x, 0, 1); symbolic = true, detailed = false)
70+
integrate(x * sin(a * x), (x, 0, 1); symbolic = true, detailed = false)
7171
(sin(a) - a*cos(a)) / (a^2)
7272
```
7373

@@ -81,13 +81,13 @@ SymbolicNumericIntegration.jl exports some special integral functions (defined o
8181
For examples:
8282

8383
```julia
84-
julia> integrate(exp(x + 1) / (x + 1))
84+
integrate(exp(x + 1) / (x + 1))
8585
(SymbolicNumericIntegration.Ei(1 + x), 0, 0.0)
8686

87-
julia> integrate(x * cos(a*x^2 - 1) / (a*x^2 - 1), x; detailed=false, symbolic=true)
87+
integrate(x * cos(a * x^2 - 1) / (a * x^2 - 1), x; detailed = false, symbolic = true)
8888
((1//2)*SymbolicNumericIntegration.Ci(a*(x^2) - 1)) / a
8989

90-
julia> integrate(1 / (x*log(log(x))), x; detailed=false, symbolic=true)
90+
integrate(1 / (x * log(log(x))), x; detailed = false, symbolic = true)
9191
SymbolicNumericIntegration.Li(log(x))
9292
```
9393

@@ -213,4 +213,4 @@ file and the
213213
[project]($link_project)
214214
file.
215215
""")
216-
```
216+
```

src/SymbolicNumericIntegration.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ using DataDrivenDiffEq, DataDrivenSparse
1111

1212
struct NumericalPlan
1313
abstol::Float64
14-
radius::Float64
15-
complex_plane::Bool
14+
radius::Float64
15+
complex_plane::Bool
1616
opt::DataDrivenDiffEq.AbstractDataDrivenAlgorithm
1717
end
1818

@@ -36,7 +36,7 @@ include("sparse.jl")
3636
# include("optim.jl")
3737
include("integral.jl")
3838

39-
export integrate, generate_basis
39+
export integrate, generate_basis, best_hints
4040

4141
include("symbolic.jl")
4242

src/candidates.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using DataStructures
22

3-
# this is the main heurisctic used to find the test fragments
3+
# this is the old heurisctic used to find the test fragments
44
function generate_basis(eq, x, try_kernel = true)
55
if !try_kernel
66
S = sum(generate_homotopy(expr(eq), x))

src/homotopy.jl

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ end
8080

8181
guard_zero(x) = isequal(x, 0) ? one(x) : x
8282

83+
# The core of ansatz generation.
84+
# The name is not accurate and should be changed (not really homotopy,
85+
# just inspired from!)
8386
function generate_homotopy(eq, x)
8487
eq = value(eq)
8588
x = value(x)
@@ -95,7 +98,7 @@ function generate_homotopy(eq, x)
9598
for i in 1:length(ks)
9699
μ = u[i]
97100
y, dy = apply_partial_int_rules(sub[μ], x)
98-
101+
99102
y = substitute(y, sub)
100103
∂y = guard_zero(diff(dy, x))
101104

@@ -157,8 +160,9 @@ partial_int_rules = [
157160
@rule 𝛷(~x, asech(~u)) => (asech(~u), ~u)
158161
@rule 𝛷(~x, acoth(~u)) => (~u * acot(~u) + log(~u + 1), ~u)
159162
# logarithmic and exponential functions
160-
@rule 𝛷(~x, log(~u)) => (~u + ~u * log(~u) + sum(pow_minus_rule(~u, ~x, -1); init = one(~u)),
161-
~u);
163+
@rule 𝛷(~x, log(~u)) => (~u + ~u * log(~u) +
164+
sum(pow_minus_rule(~u, ~x, -1); init = one(~u)),
165+
~u)
162166
@rule 𝛷(~x, 1 / log(~u)) => (log(log(~u)) + li(~u), ~u)
163167
@rule 𝛷(~x, exp(~u)) => (exp(~u) + ei(~u) + erfi_(~x), ~u)
164168
@rule 𝛷(~x, ^(exp(~u), ~k::is_neg)) => (^(exp(-~u), -~k), ~u)
@@ -167,10 +171,13 @@ partial_int_rules = [
167171
@rule 𝛷(~x, sqrt(~u)) => (sum(sqrt_rule(~u, ~x, 0.5); init = one(~u)), ~u);
168172
@rule 𝛷(~x, 1 / sqrt(~u)) => (sum(sqrt_rule(~u, ~x, -0.5); init = one(~u)), ~u);
169173
# rational functions
170-
@rule 𝛷(~x, 1 / ^(~u::is_univar_poly, ~k::is_pos_int)) => (sum(pow_minus_rule(~u, ~x, -~k);
174+
@rule 𝛷(~x, 1 / ^(~u::is_univar_poly, ~k::is_pos_int)) => (sum(pow_minus_rule(~u,
175+
~x,
176+
-~k);
171177
init = one(~u)),
178+
~u)
179+
@rule 𝛷(~x, 1 / ~u::is_univar_poly) => (sum(pow_minus_rule(~u, ~x, -1); init = one(~u)),
172180
~u);
173-
@rule 𝛷(~x, 1 / ~u::is_univar_poly) => (sum(pow_minus_rule(~u, ~x, -1); init = one(~u)), ~u);
174181
@rule 𝛷(~x, ^(~u, -1)) => (log(~u) + ~u * log(~u), ~u)
175182
@rule 𝛷(~x, ^(~u, ~k::is_neg_int)) => (sum(^(~u, i) for i in (~k + 1):-1), ~u)
176183
@rule 𝛷(~x, 1 / ~u) => (log(~u), ~u)
@@ -187,7 +194,7 @@ end
187194

188195
function pow_minus_rule(p, x, k; abstol = 1e-8)
189196
if !is_univar_poly(p)
190-
return [p^k, p^(k + 1), log(p), p*log(p)]
197+
return [p^k, p^(k + 1), log(p), p * log(p)]
191198
end
192199

193200
# x = var(p)
@@ -203,7 +210,7 @@ function pow_minus_rule(p, x, k; abstol = 1e-8)
203210
r = nice_parameter.(r)
204211
s = nice_parameter.(s)
205212

206-
# ∫ 1 / ((x-z₁)(x-z₂)) dx = ... + c₁ * log(x-z₁) + c₂ * log(x-z₂)
213+
# applying ∫ 1 / ((x-z₁)(x-z₂)) dx = ... + c₁ * log(x-z₁) + c₂ * log(x-z₂)
207214
q = Any[log(x - u) for u in r]
208215
for i in eachindex(s)
209216
β = s[i]
@@ -225,9 +232,9 @@ end
225232

226233
function sqrt_rule(p, x, k)
227234
h = Any[p^k, p^(k + 1)]
228-
235+
229236
Δ = diff(p, x)
230-
push!(h, log/2 + sqrt(p)))
237+
push!(h, log / 2 + sqrt(p)))
231238

232239
if !is_univar_poly(p)
233240
return h
@@ -254,4 +261,3 @@ function sqrt_rule(p, x, k)
254261

255262
return h
256263
end
257-

0 commit comments

Comments
 (0)