Skip to content

Conversation

@ashutosh-b-b
Copy link
Contributor

  1. How do I add support for closure inside the get_numeric_integral? get_numeric_integral cannot be a fixed function since the number of dependent variables may vary.

@KirillZubov
Copy link
Member

why can't? , probably better name parse_integral(or something like this) then get_numeric_integral . You need to call this function for every symbol form of integral in the model and pass dependent variables for every integral.

@KirillZubov
Copy link
Member

my pseudo code for this :)

eqs = integral1(depvars1,...) + integral2(depvars2,...)+ somthing ->
inner_representation_integral1(depvars1) + inner_representation_integral2(depvars2)+ somthing

parser(integral1(depvars1, ...),...) -> inner_representation_integral1

break
elseif e isa Symbolics.Integral
integrating_variable = toexpr(_args[1].x)
integrand = transform_expression(_args[2],dict_indvars,dict_depvars,chain,eltypeθ,strategy)
Copy link
Member

Choose a reason for hiding this comment

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

_transform_expression

integral =
(u, cord, phi, θ, integrating_variable, integrand, lb, ub, strategy=strategy, indvars=indvars, depvars=depvars)->
begin
integrand_ = NeuralPDE.build_symbolic_loss_function(nothing, indvars, depvars, phi, derivative, nothing, chain, θ, strategy, integrand = integrand)
Copy link
Member

Choose a reason for hiding this comment

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

all actions with the parser must be performed before starting training. To call the build_symbolic_loss in integral function means that it will be called every time during training, so it will take a very long time.

phi = discretization.phi
derivative = discretization.derivative
strategy = discretization.strategy
global integral = get_numeric_integral(strategy, pde_system.indvars, pde_system.depvars, dict_indvars, chain, derivative)
Copy link
Member

Choose a reason for hiding this comment

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

global is bad. it will always lead to trouble. Avoid it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in this case I needed to use integral outside the symbolic_discretize and discretize. And hence global declaration. What are other ways to do it?

@ashutosh-b-b ashutosh-b-b requested a review from KirillZubov July 18, 2021 17:20
eq = Di(i(t)) + 2*i(t) + 5*Ii(i(t)) ~ 1
bcs = [i(0.) ~ 0.0]
domains = [t Interval(0.0,2.0)]
chain = FastChain(FastDense(1,15,Flux.σ),FastDense(15,1))
Copy link
Member

Choose a reason for hiding this comment

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

it's some trouble with FastChain after the new release of Flux, just use Chain for a test while FastChain won't have been fixed.

Copy link
Member

Choose a reason for hiding this comment

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

what's up?

Copy link
Member

Choose a reason for hiding this comment

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

initial_params change behavior after the update in Flux and now it works incorrectly.

chain = FastChain(FastDense(1,12,Flux.σ),FastDense(12,1))
julia> initθ = DiffEqFlux.initial_params(chain)
26-element Vector{Union{Nothing, Float32}}:
  0.44163412f0
  0.3313627f0
 -0.24543865f0
  0.16519924f0
  0.18937507f0
 -0.047894925f0
  
 -0.50703824f0
 -0.13543157f0
  0.036089323f0
  0.0010503983f0
   nothing

Copy link
Member

Choose a reason for hiding this comment

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

Can you try and narrow that down?

Copy link
Member

Choose a reason for hiding this comment

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

ok, I will open the issue in DiffEqFlux as soon as I figure out what exactly is the problem with DiffEqFlux.initial_params.

derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[t],[i])
prob = NeuralPDE.discretize(pde_system,discretization)
Copy link
Member

Choose a reason for hiding this comment

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

it work in forward but

prob.f.f.loss_function(initθ)
1.1225828958232524

donesn't work in backward

julia> Zygote.gradient(prob.f.f.loss_function,initθ)
ERROR: MethodError: no method matching get(::Tuple{Int64, Int64}, ::Int64, ::Int64)

I suppose it is related to integral function.
So you need that work in both way:
integral = get_numeric_integral(strategy, _indvars, _depvars, dict_indvars, chain, derivative)

integral(initθ,... )
integral_ = (θ) -> integral(θ, ...)
Zygote.gradient(integral_,initθ)

All symbolic things should do before calculation because Zygote.gradient probably can't handle all of it.

@ChrisRackauckas
Copy link
Member

Is it still WIP?

## Simple Integral Test
@parameters x
@variables u(..)
Ix = Integral(x, DomainSets.ClosedInterval(0, x))
Copy link
Member

Choose a reason for hiding this comment

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

needs a multidimensional test

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, regarding that I wanted to ask this, for a multidimensional integral, I wanted to change definition of the symbolic integral to have a vector of symbols. For eg. I wanted it to be like this : I = Integral([x , y, z], UnitCube()). Should I proceed?

Copy link
Member

Choose a reason for hiding this comment

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

It should be done in the same way we're describing sets, i.e. (x , y, z) \in UnitCube()

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 am talking about the Integral.

Copy link
Member

Choose a reason for hiding this comment

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

yes. I = Integral(x^2 + y^2 + z^2,(x,y,z) in UnitCube())

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We first define the Integral as Integral(integrating_variable, domain) and then pass the function. What I meant was using vector of integrating_variables instead. Is it fine? Or do I have to change it?

@KirillZubov
Copy link
Member

I think it will need to split tests files and move tests with integral to integro_differential_test.jl

Project.toml Outdated
Distributions = "0.23, 0.24, 0.25"
DocStringExtensions = "0.8"
Flux = "0.10.1, 0.11, 0.12"
Flux = "0.10.1, 0.11, < 0.12.5"
Copy link
Member

Choose a reason for hiding this comment

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

"Resolve conflicts" to Flux = "0.12.6"

Copy link
Member

Choose a reason for hiding this comment

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

just press the button “resolve conflict” and merge it


loss_function = parse_equation(eqs,dict_indvars,dict_depvars,chain,eltypeθ,strategy)
vars = :(cord, $θ, phi, derivative,u,p)
if integrand isa Nothing
Copy link
Member

Choose a reason for hiding this comment

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

why is it 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.

So we can re use the build_symbolic_loss_function for getting the integral function in our inner representation.

Copy link
Member

Choose a reason for hiding this comment

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

got it

phi = discretization.phi
derivative = discretization.derivative
strategy = discretization.strategy
global integral = get_numeric_integral(strategy, pde_system.indvars, pde_system.depvars, chain, derivative)
Copy link
Member

@KirillZubov KirillZubov Aug 10, 2021

Choose a reason for hiding this comment

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

why isn't it removed global yet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

function get_numeric_integral(strategy, _indvars, _depvars, chain, derivative)
depvars,indvars,dict_indvars,dict_depvars = get_vars(_indvars, _depvars)
integral =
(u, cord, phi, integrating_var_id, integrand_func, lb, ub, θ ;strategy=strategy, indvars=indvars, depvars=depvars, dict_indvars=dict_indvars, dict_depvars=dict_depvars)->
Copy link
Member

Choose a reason for hiding this comment

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

these parameters can be remove as no use indvars=indvars, depvars=depvars, dict_indvars=dict_indvars, dict_depvars=dict_depvars

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are used inside the integral function, so shouldn't we pass them?

Copy link
Member

Choose a reason for hiding this comment

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

we don't use these for initializing function inside get_numeric_integral so we don't need to pass them.

integral =
(u, cord, phi, integrating_var_id, integrand_func, lb, ub, θ ;strategy=strategy, indvars=indvars, depvars=depvars, dict_indvars=dict_indvars, dict_depvars=dict_depvars)->
begin
flat_θ = if (typeof(chain) <: AbstractVector) reduce(vcat,θ) else θ end
Copy link
Member

Choose a reason for hiding this comment

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

why do you need it? θ should already be flat

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 checked it, it wasnt. I ll recheck

ub_ = repeat(ub, 1, size(cord)[2])
end
end
for i in 1:size(cord)[2]
Copy link
Member

Choose a reason for hiding this comment

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

if cord = ones(2,300)
so then
julia> size(cord)[2]
300
why we calculate it for each index? it is very slow

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in order to give the vectorise output. We have each index is a cord point in the data, so we need to calculate integral seperately for each point

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 try mapslices but it threw a Mutating arrays not supported error

Copy link
Member

Choose a reason for hiding this comment

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

it is a vector we do not need an index, we need a broadcast here for fast performance (see how it works in get_numeric_derivative).
In any case, it works fully correctly, but slow

Copy link
Member

Choose a reason for hiding this comment

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

using BenchmarkTools

f(x) =x^2

function f_index(x)
    for i in 1:size(x)[2]
        x[:,i].^2
    end
end


julia> @benchmark f.(data) setup=(data=rand(2,1000))
BenchmarkTools.Trial: 10000 samples with 9 evaluations.
 Range (min  max):  2.525 μs   3.818 ms  ┊ GC (min  max):  0.00%  99.82%
 Time  (median):     3.732 μs              ┊ GC (median):     0.00%
 Time  (mean ± σ):   7.412 μs ± 85.571 μs  ┊ GC (mean ± σ):  28.22% ±  2.44%

  ▁ ▂ █▅▄▇▂ ▁                 ▃▄▅▄▄▄▃▃▃▃▂▂▂▁▁                ▂
  █▄█████████▆▅▄▅▄▅▆▅▅▅▃▅▆▅▅▅▇█████████████████▇▇▇▇▆▄▅▅▆▅▅▅▅ █
  2.52 μs      Histogram: log(frequency) by time     12.2 μs <

 Memory estimate: 15.75 KiB, allocs estimate: 1.

julia> @benchmark f_index(data) setup=(data=rand(2,1000))
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min  max):   56.758 μs  36.600 ms  ┊ GC (min  max):  0.00%  99.53%
 Time  (median):      78.680 μs              ┊ GC (median):     0.00%
 Time  (mean ± σ):   118.139 μs ±  1.100 ms  ┊ GC (mean ± σ):  29.35% ±  3.15%

  ▄▃ ▆█▆▆▆▄▅█▇▃▃▂▂▃▂▃▃▃▂▂▂▂▁▁▁▁▁▁▁▁▁  ▁▁                       ▂
  ████████████████████████████████████████▇▇█▇▇▇▇▇▇▆▆▆▇▆▆▄▅▄▅▅ █
  56.8 μs       Histogram: log(frequency) by time       188 μs <

 Memory estimate: 187.50 KiB, allocs estimate: 2000.

Project.toml Outdated
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Copy link
Member

Choose a reason for hiding this comment

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

why is this added?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh that got pushed by mistake. I ll remove it.

phi = nothing,
derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[x,y],[u])
Copy link
Member

@KirillZubov KirillZubov Aug 16, 2021

Choose a reason for hiding this comment

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

@named pde_system = PDESystem(eq,bcs,domains,[x,y],[u])

phi = nothing,
derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[x,y],[u])
Copy link
Member

@KirillZubov KirillZubov Aug 16, 2021

Choose a reason for hiding this comment

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

@named

phi = nothing,
derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[x],[u])
Copy link
Member

@KirillZubov KirillZubov Aug 16, 2021

Choose a reason for hiding this comment

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

@named

phi = nothing,
derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[t],[i])
Copy link
Member

Choose a reason for hiding this comment

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

@named

phi = nothing,
derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[t],[i])
Copy link
Member

Choose a reason for hiding this comment

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

and here @named

We use the grid training strategy and then use the `PhysicsInformedNN` interface to define the optimization problem.
```julia
strategy_ = NeuralPDE.GridTraining(0.05)
discretization = NeuralPDE.PhysicsInformedNN(chain,
Copy link
Member

Choose a reason for hiding this comment

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

remove all NeuralPDE. from doc

# Integro Differential Equations
Lets take an example of an integro differential equation :
```math
\frac{∂}{∂x} u(x) + 2u(x) + 5 \int_{0}{x}u(t)dt = 1 for x \geq 0
Copy link
Member

Choose a reason for hiding this comment

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

\int_{0}^{x}u(t)dt

derivative = nothing,
)
pde_system = PDESystem(eq,bcs,domains,[t],[i])
prob = NeuralPDE.discretize(pde_system,discretization)
Copy link
Member

Choose a reason for hiding this comment

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

add

cb = function (p,l)
    println("Current loss is: $l")
    return false
end

@ashutosh-b-b ashutosh-b-b changed the title [WIP] Add Integro Differential Equations Support Add Integro Differential Equations Support Aug 21, 2021
@variables u(..)
Dx = Differential(x)
Dy = Differential(y)
Ix = Integral([x,y], (x,y) in DomainSets.ProductDomain(UnitInterval(),ClosedInterval(0 ,x)))
Copy link
Member

Choose a reason for hiding this comment

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

why is this two outputs? The equations below don't have the right size.

Comment on lines 847 to 849
Ix = Integral([x,y], (x,y) in DomainSets.UnitSquare())
eq = Ix(u(x,y)) ~ 1/3
bcs = [u(0., 0.) ~ 1, Dx(u(x,y)) ~ -2*x , Dy(u(x ,y)) ~ -2*y ]
Copy link
Member

Choose a reason for hiding this comment

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

same sizing issue.

@ChrisRackauckas ChrisRackauckas merged commit 5114808 into SciML:master Aug 23, 2021
@ChrisRackauckas
Copy link
Member

@sdwfrost

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.

3 participants