Skip to content

Commit 133520c

Browse files
authored
Antidifferentiate (#81)
* prep PR * using Rational{Int}
1 parent 7869250 commit 133520c

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/TypedPolynomials.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export @polyvar,
2525
variables,
2626
terms,
2727
differentiate,
28+
antidifferentiate,
2829
subs
2930

3031
include("types.jl")

src/calculus.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,38 @@ function _diff(m::Monomial{Vars},
3737
end
3838
end, Val{N}()))
3939
end
40+
41+
MP.antidifferentiate(v1::V, v2::V) where {V <: Variable} = v1*v2/2
42+
MP.antidifferentiate(v1::Variable, v2::Variable) = v1 * v2
43+
44+
function MP.antidifferentiate(m::Monomial{Vars}, v::V) where {Vars, V <: Variable}
45+
if inmonomial(v, Vars...)
46+
return _antidiff(m, v)
47+
else
48+
# Insert `v` in the monomial
49+
return m * v
50+
end
51+
end
52+
53+
_antidiff(m::Monomial, v::Variable) = _antidiff(m, exponents(m), v)
54+
55+
function _antidiff(::Monomial{Vars},
56+
exponents::NTuple{N, Integer},
57+
v::Variable) where {Vars, N}
58+
vi = find_variable_index(v, Vars)
59+
new_m = Monomial{Vars,N}(
60+
ntuple(i -> begin
61+
if i == vi
62+
(exponents[i] == 0) ? 1 : exponents[i] + 1
63+
else
64+
exponents[i]
65+
end
66+
end,
67+
Val{N}()
68+
)
69+
)
70+
# Remark : as `exponents` are imposed to be `Integer` according to
71+
# the method signature, we can use the Rational{Int} type here for the
72+
# coefficient
73+
return (1 // (exponents[vi] + 1)) * new_m
74+
end

test/calculus.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,31 @@
2525

2626
@test @inferred(differentiate(1, x)) == 0
2727
end
28+
29+
@testset "antiderivatives" begin
30+
@polyvar x y z
31+
32+
@test @inferred(antidifferentiate(x, x)) == 1//2*x^2
33+
@test @inferred(antidifferentiate(x, y)) == x*y
34+
@test @inferred(antidifferentiate(y, x)) == x*y
35+
@test @inferred(antidifferentiate(x^2, x)) == 1//3*x^3
36+
@test @inferred(antidifferentiate(x^2, y)) == x^2*y
37+
@test @inferred(antidifferentiate(x^2 * y^3, y)) == x^2 * 1//4*y^4
38+
@test @inferred(antidifferentiate(x^2 * y^3, x)) == x^3 * 1//3*y^3
39+
@test @inferred(antidifferentiate(x^2 * y^3, z)) == x^2 * y^3 * z
40+
@test @inferred(antidifferentiate(3x^2, x)) == x^3
41+
@test @inferred(antidifferentiate(3x^2 * y^0, y)) == 3x^2 * y
42+
@test @inferred(antidifferentiate(3 * x^2 + 2 * x + 1, x)) == x^3 + x^2 + x
43+
44+
@test @inferred(exponents(antidifferentiate(x^0,x))==(1,))
45+
@test @inferred(exponents(antidifferentiate(x^0*y*z^2,x))==(1,1,2))
46+
47+
m = x^2
48+
@test @wrappedallocs(antidifferentiate(m, x)) == 0
49+
@test @wrappedallocs(antidifferentiate(m, y)) == 0
50+
m = x^2 * y^3
51+
@test @wrappedallocs(antidifferentiate(m, x)) == 0
52+
@test @wrappedallocs(antidifferentiate(m, y)) == 0
53+
54+
@test @inferred(antidifferentiate(1, x)) == x
55+
end

0 commit comments

Comments
 (0)