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

Supertype of Symbolic expressions #16

Open
shashi opened this issue Apr 15, 2020 · 10 comments
Open

Supertype of Symbolic expressions #16

shashi opened this issue Apr 15, 2020 · 10 comments

Comments

@shashi
Copy link
Member

shashi commented Apr 15, 2020

We really want

Variable{T} <: T

But can't have it easily.

Some approaches:

  • ReflectOn in Cassette
    • (or) Write a version of this without Cassette
  • @vars a::AbstractMatrix b::Real c::Complex should generate different Variable types with the right super type. This reminds me of the NamedTuples.jl from Julia 0.6.

A resolution of this should fix #8

@ChrisRackauckas
Copy link
Member

That's for Julia to act like that when tracing. In order for symbolic analysis to handle this, you can just choose for x::Variable{T} to use the rule for T.

@shashi
Copy link
Member Author

shashi commented Apr 15, 2020

choose for x::Variable{T} to use the rule for T

Yes, we already do that....

@MasonProtter
Copy link
Member

Yeah, the issues is that it doesn’t help dispatch. Variable{T} <: Number is not good enough. Currently overrides would need to be put in all over the place.

@ChrisRackauckas
Copy link
Member

Variable{T} is definitely not good enough, but I think it's a "good enough default" for generic tracing (since you can't do Variable{T} <: T, though we're asking compiler folk to allow it if possible). That said, if there's something that allows you to take finer control of tracing , like a Cassette-y thing, then it can act like Variable{T} <: T and we could just always point people to using the right context.

@MasonProtter
Copy link
Member

MasonProtter commented Apr 23, 2020

Here's a minimal implementation of a symbolic system with custom IRTools pass that does Symbolic{T} <: T https://gist.github.com/MasonProtter/ea7588a191cf1ef388af3f26c0105c53

at the repl:

julia> using .Syms

julia> begin
           f(x::Float64)     = 1 + sin(x)^(1/2)
           g(x::Vector{Int}) = x'x + 2

           x = Sym{Float64}(:x)
           y = Sym{Vector{Int}}(:y)
       end
y::Array{Int64,1}

julia> sym() do 
           f(g(y) + x)
       end
(1 + sin((adjoint(y) * y + 2) + x) ^ 0.5) :: Float64 where {x::Float64, y::Array{Int64,1}}

This could also be implemented in Cassette if the ReflectOn branch ever merges.

@shashi
Copy link
Member Author

shashi commented Apr 23, 2020

Pretty nice! What does argument! do? I should try and play with it more. A good use case is getting qr to work on an array of symbols because it touches a lot of typeof zero(eltype(T)) kind of code, which is the tricky part of tracing.

Is anyone else feeling that we should split out just the symbolic.jl (just the type definitions) file into a SymbolicBase package, and then have the simplification + methods in this package?

This is because if we're going to make this the basis of ModelingToolkit types, then I don't want stuff to keep breaking for Chris & co.

But there's also the issue that a large part of why you'd want a base package is to avoid piracy which would mean that these methods would have to be defined in the Base package.

@shashi
Copy link
Member Author

shashi commented Apr 23, 2020

With the IRTools/Cassette approach we can say that there's a specific entrypoint

using SymbolicBase # just the types
using Symbolics: symrun # this package?
symrun() do
 ... # here + , * etc are defined
end

In other words this is saying: "run something in the symbolic context"

This would make ModelingToolkit code have a bunch of symruns everywhere.

@ChrisRackauckas
Copy link
Member

This would make ModelingToolkit code have a bunch of symruns everywhere.

No, because most usage doesn't need tracing. So it wouldn't be all that common.

@shashi
Copy link
Member Author

shashi commented Apr 23, 2020

Oh so you want both a bunch of methods and a tracing context... Yes the default methods could just be limited to Symbolic{Number} as it does now, and the tracing package can be separate.

Then I don't think we need to worry about splitting this package up right now.

@MasonProtter
Copy link
Member

Pretty nice! What does argument! do? I should try and play with it more. A good use case is getting qr to work on an array of symbols because it touches a lot of typeof zero(eltype(T)) kind of code, which is the tricky part of tracing.

Ha ha, I was never sure beyond "mike said this makes sneakyinvoke work" 😁. I think it just removes the type checking from the IR but I don't actually know.

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

No branches or pull requests

3 participants