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

Better support for using Operator Aliases #35

Closed
jpfairbanks opened this issue Jul 26, 2023 · 7 comments · Fixed by #37
Closed

Better support for using Operator Aliases #35

jpfairbanks opened this issue Jul 26, 2023 · 7 comments · Fixed by #37
Assignees

Comments

@jpfairbanks
Copy link
Member

The goal here is to use familiar Div, Grad, Curl, Lapl operators in their familiar role in vector calculus. What support do we need in the Decapodes language for that? Probably and alias operator like :=

oscillator = @decapode begin
  X::Form0
  V::Form0
  div := ⋆⋅d
  
  ∂ₜ(X) == V
  ∂ₜ(V) == -k(X) + div(V)
end

Then we can update all the docs examples to use these operators when appropriate. We can't uniformly introduce a exterior calculus definitions of div, grad, curl because of things like how gradient of Pressure should be dP but gradient of concentration should be ⋆dC. Unless we can dispatch on expected return type in the type inference code, I think that we can just introduce a manual aliasing operator into the decapode macro, and then have local aliases in each example.

@lukem12345
Copy link
Member

lukem12345 commented Jul 26, 2023

Unless we can dispatch on expected return type in the type inference code,

The way I would do this without additional parsing code would be to deduce the definition of vector calculus operators using infer_types! and resolve_overloads! like we do for and d now.

e.g.

oscillator = @decapode begin
  X::Form0
  V::Form0
  
  ∂ₜ(X) == V
  ∂ₜ(V) == -k(X) + div(V)
end

osc2D = infer_types!(resolve_overloads!(oscillator))

@test osc2D == @decapode begin
  X::Form0
  V::Form0
  
  ∂ₜ(X) == V
  ∂ₜ(V) == -k(X) + div_0(V)
end |> infer_types! |> resolve_overloads!

, where div_0 is defined like ⋆⋅d internally.

I suppose that this would not work if in one 2D Decapode, the result of div of a 0Form should be a ⋆⋅d, while it should be d in another. Not sure of a pair of examples of this at the moment.

@jpfairbanks
Copy link
Member Author

I think it is probably fine to both update the parser code to allow definitions of new operators as composites of operators and to add a vector_expand!(d) which will use this table for Vector to Exterior Calculus
image
from the wikipedia page for exterior derivative. https://en.wikipedia.org/wiki/Exterior_derivative

We could then use a cancel_isos!(d) to aggressively eliminate combinations like sharp of flat, flat of sharp, star of inv(star) and inv(star) of star.

@lukem12345
Copy link
Member

lukem12345 commented Sep 1, 2023

Although PR AlgebraicJulia/Decapodes.jl#142 addresses some of these concerns, it does not One can consider that PR as providing reasonable defaults for div, grad, and curl. So I am going to work on this PR next. Changes to the Decapode macro will let users change those defaults. For now, I will only consider single-input-single-output aliases. Aliases for e.g. the advection operator will require rewrites that are more in-depth than single op1 renaming.

Further, carrying around these operators throughout the lifetime of a Decapode object will best be handled via nested Decapodes. This will likely require Decapodes which contain DecaExprs as certain attributes.

Probably and alias operator like :=

Going off of the selection provided by the "Punctuation" section of the manual, I think that -> is the best fit for this feature. These operator aliases are like anonymous functions. Hopefully this is familiar to people used to Julia syntax. (Parsing \lambda like in Python would also work and be easy, but would be extremely confusing adjacent to other Greek letters being used as physical quantities, like wavelength.) The single = is also worth consideration.

@jpfairbanks
Copy link
Member Author

I like single equal sign for operator aliases like Δ = ∘(d,⋆,d,⋆) and then for multivariable operator aliases, you could write lambdas like f = (x,y) -> div((ℒ(y,x) + y) which could create a new binary operator. For unary operations like laplacian, people are fine with point-free syntax. It kind of scales to binary operators f = (ℒ⊗id(Y)) ⋅ + is manageable, but the people love infix operators and they love variable names for specifying multi-variate functions.

@lukem12345 lukem12345 transferred this issue from AlgebraicJulia/Decapodes.jl Jun 7, 2024
@lukem12345
Copy link
Member

lukem12345 commented Jun 7, 2024

It sounds like this issue is about specifying a DSL for what is done when we “open operators” in Decapodes https://github.com/AlgebraicJulia/Decapodes.jl/blob/55ff02b26497ddc0122a9fbd8b6f0e89a7047ebc/src/operators.jl#L160

Is there anything in the AlgebraicJulia ecosystem that already has a DSL that parses little functions into a data structure that is easy to iterate over? This sounds like a directed wiring diagram.

@lukem12345
Copy link
Member

lukem12345 commented Jun 7, 2024

An attempt at this feature was made a long time ago with AlgebraicRewriting, but that failed due to reasons specified here.

But since these sorts of operations apparently only require editing the inner parts of an operator, then an AR approach may be feasible.

We can implement this feature by calling @decapode on the LHS for the “L” of a rule, @decapode on the RHS for the “R” of a rule, and specify “I” to be the variables of the same name (I.e. the outer parts)

@lukem12345
Copy link
Member

Or, we could go the oapply route instead, and implement this feature by way of issue #36 , which ought to be speedier.

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 a pull request may close this issue.

2 participants