Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add symbolic integral #240

Merged
merged 22 commits into from Jun 15, 2021

Conversation

ashutosh-b-b
Copy link
Contributor

  1. Need to change expand_derivatives in order to handle derivative of an integral.

@ashutosh-b-b
Copy link
Contributor Author

@ChrisRackauckas @zoemcc

@ashutosh-b-b ashutosh-b-b changed the title [WIP] Addition for symbolic integral [WIP] Add symbolic integral May 21, 2021
src/integral.jl Outdated Show resolved Hide resolved
@ChrisRackauckas
Copy link
Member

This definition only works for 1-dimensional integrals. I think it instead needs to be specified by boundary domains?

@ashutosh-b-b
Copy link
Contributor Author

This definition only works for 1-dimensional integrals. I think it instead needs to be specified by boundary domains?

Right, so instead I ll go with the domains we have in MTK?

@ChrisRackauckas
Copy link
Member

Yeah, the DomainSets.jl domains.

@codecov-commenter
Copy link

codecov-commenter commented May 21, 2021

Codecov Report

Merging #240 (0dae216) into master (5d8dfeb) will decrease coverage by 0.51%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #240      +/-   ##
==========================================
- Coverage   70.78%   70.26%   -0.52%     
==========================================
  Files          12       13       +1     
  Lines        1085     1093       +8     
==========================================
  Hits          768      768              
- Misses        317      325       +8     
Impacted Files Coverage Δ
src/integral.jl 0.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5d8dfeb...0dae216. Read the comment docs.

src/integral.jl Outdated

function Base.show(io::IO, I::Integral)
print(io, "Integral(", I.x, ")")
print(io,"upper_bound: ")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use consistent indentation of a space after a comma and no space before the comma.

test/integral.jl Outdated

@variables x y

I1 = Integral(x , y , 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@ChrisRackauckas
Copy link
Member

Comments @tinosulzer and @zoemcc?

@ashutosh-b-b
Copy link
Contributor Author

@ChrisRackauckas @zoemcc expand_derivatives should be change to handle the derivative of an integral case right?

@ChrisRackauckas
Copy link
Member

Should it? I am not sure it should. @YingboMa

@ashutosh-b-b
Copy link
Contributor Author

It applies the chain rule over a function in Differential , so if we have D(cos(u(x))) where D is a Differential(x) what we get is -Differential(x)(u(x))*sin(u(x)), It applies the same when we have an integral inside a differential

@YingboMa
Copy link
Member

Should it?

I think it should try to expand the derivative for an integral as well, since that's how derivative, jacobian, and etc are implemented. Is the concern that it could limit expressing integro-differential equations? I am not familiar with those, but it seems to me that we don't usually have a derivative in front of the integral in those equations, right? Even so, we don't really need expand_derivative when specifying the equations.

@valentinsulzer
Copy link
Contributor

What's there looks sensible, can get updated as needed when specific use cases come up
Should we add a test along the lines of

@variables t, x
@variables u(..)

domain = ...
Ix = Integral(x, domain)
Ix(u(t,x))

@test ... 

@ChrisRackauckas
Copy link
Member

I think it should try to expand the derivative for an integral as well, since that's how derivative, jacobian, and etc are implemented. Is the concern that it could limit expressing integro-differential equations? I am not familiar with those, but it seems to me that we don't usually have a derivative in front of the integral in those equations, right? Even so, we don't really need expand_derivative when specifying the equations.

I see, I thought the question was if expand_derivative should do symbolic integration, which seemed weird. Okay yes, makes sense to limit swap.

@shashi
Copy link
Member

shashi commented May 31, 2021

I can infer from the code that we have a way to say "integral wrt x from a to b" but not "integral of something wrt x from a to b"... What gives? Is an instance of Integral supposed to become callable?

@valentinsulzer
Copy link
Contributor

That seems like the right way to do it for consistency with Differential

@ashutosh-b-b
Copy link
Contributor Author

I made some changes for Derivative of an Integral.

src/diff.jl Outdated
t2 = D(a)
c -= t1*t2
elseif isa(value(b) , Term)
t1 = replaceSym(operation(arg).x ,value(b) , inner_function )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting needs to be cleaned up, we also never use camelCase function names. Good to stick to the package's style when you're contributing to it. Where is the expand_derivatives_ function...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could use substitute here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I infact removed replaceSym

test/integral.jl Outdated
D = Differential(x)
Dxx = Differential(x)^2
I = Integral(x, ClosedInterval(1 , v(x)))
eq = D((I(u(x,t)) )) ~ 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here.

test/integral.jl Outdated
eq = D((I(u(x,t)) )) ~ 0
O = expand_derivatives(eq.lhs)
println(O)
eq = Dxx((I(u(x,t)) )) ~ 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here.

test/integral.jl Outdated
println(O)
eq = Dxx((I(u(x,t)) )) ~ 0
O = expand_derivatives(eq.lhs)
println(O)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why print?

src/integral.jl Outdated
print(io, "Integral(", I.x, ", ", I.domain, ")")
end

Base.:(==)(I1::Integral, I2::Integral) = (isequal(I1.x, I2.x) && isequal(I1.domain, I2.domain))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When comparing numbers, we should use == instead of isequal. Consider -0.0 vs 0.0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess domains could be symbolic.

src/integral.jl Outdated
end

Base.:(==)(I1::Integral, I2::Integral) = (isequal(I1.x, I2.x) && isequal(I1.domain, I2.domain))
(D::Differential)(I::Integral{X,T}) where{X,T} = I∘D
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation.

src/diff.jl Outdated
@@ -113,6 +113,26 @@ function expand_derivatives(O::Symbolic, simplify=false; occurances=nothing)
return expand_derivatives(operation(arg)(inner), simplify)
end
end
elseif isa(operation(arg) , Integral)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace.

src/diff.jl Outdated
elseif isa(operation(arg) , Integral)
if isa(operation(arg).domain , AbstractInterval)
domain = operation(arg).domain
a , b = DomainSets.endpoints(domain)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace.

src/diff.jl Outdated
t2 = D(a)
c -= t1*t2
end
if isa(value(b) , Term)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace.

src/diff.jl Outdated
a , b = DomainSets.endpoints(domain)
c = 0
inner_function = expand_derivatives(arguments(arg)[1])
if isa(value(a), Term)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isa Term? Shouldn't it be istree? Check SymbolicUtils' docs.

@YingboMa
Copy link
Member

Remember to squash when merging this PR.

@YingboMa
Copy link
Member

Need to resolve the merge conflict.

test/integral.jl Outdated
I = Integral(y, ClosedInterval(1, v(x)))
eq = D((I(u(x,y)))) ~ 0
eq_test = I(D(u(x,y))) + D(v(x))*u(x, v(x))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test)) == true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

== true is redundant

I = Integral(y, ClosedInterval(1, 5))
eq = D((I(u(x,y)))) ~ 0
eq_test = I(D(u(x,y)))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just using Symbolics.derivative could be fine.

eq_test = I(D(u(x,y))) + D(v(x))*u(x, v(x))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))

I = Integral(y, ClosedInterval(1, v(x)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you test an integral with the integrand u^2? Does it expand the derivative?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does expand. Should I add this as a test?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did, in the last commit.

@YingboMa
Copy link
Member

CI failed.

src/diff.jl Outdated
@@ -171,7 +171,7 @@ function expand_derivatives(O::Symbolic, simplify=false; occurances=nothing)
x = +((!_iszero(c) ? vcat(c, exprs) : exprs)...)
return simplify ? SymbolicUtils.simplify(x) : x
end
elseif isa(operation(O), Integral )
elseif istree(O) && isa(operation(O), Integral )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you be more careful about whitespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I m sorry, I fixed that.

@YingboMa YingboMa merged commit ed5186b into JuliaSymbolics:master Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants