Sorry for opening this thread again, I’ve just been thinkning so much about this lately, because it has been so exciting for me. Therefore I made a little script to test some different things out:
# https://discourse.julialang.org/t/is-it-possible-to-multiply-with-a-derivative-operator/28914/10
# julia> DirectSum.printindices(stdout,DirectSum.indices(UInt(2^62-1)))
#v₁₂₃₄₅₆₇₈₉₀abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
using Leibniz, DirectSum, SymEngine, LinearAlgebra
import Leibniz: Monomial
printindices(V,D) = (io=IOBuffer();DirectSum.printindices(io,V,D,true);String(take!(io)))
Base.:*(d::Monomial{V,G,D,0} where G,r::Basic) where {V,D} = diff(r,symbols(Symbol(printindices(V,D))))
Base.:*(d::Monomial{V,1,D,1},r::Basic) where {V,D} = diff(r,symbols(Symbol((printindices(V,D)))))
# x and y, becomes reexpressed as v1 and v2 symbolically - this doesn't really
# matter, since in the end the expression gives a number. Shape function can
# look a bit annoying though.
# ℕ(symbols(:x),symbols(:y)), to make it easy to see, so now it is fine
x,y = symbols(:v1),symbols(:v2)
a=symbols(:a); b=symbols(:b);
∂ₓ = ∂(ℝ,1)
∂ᵧ = ∂(ℝ,2) #\_gamma
#x = v1
#y = v2
expr = 2*x^2*y*a*b
# 1st derivatives work
println("Derivative with respect to x: ",∂ₓ*(expr))
# Double derivatives also work, but multiplication order matters
println("This x-x derivative does not work: ",(∂ₓ*∂ₓ)*(expr))
println("This x-x derivative works: ",∂ₓ*(∂ₓ*expr))
# Same is true for mixed derivatives
println("This x-y derivative does not work: ",(∂ₓ*∂ᵧ)*(expr))
println("This x-y derivative works: ",∂ₓ*(∂ᵧ*expr))
# This is fine with me, because this ensures that "sloppy code" is avoided, and
# that the order of differentiation is always visible
# Imagine having a vector as:
vec = [2*x^3;4*b*y;3*a*b]
nabla = [∂ₓ;∂ᵧ;0]
# Taking the dot product these two approaches, give the same result
approach1 = nabla .* vec #Couldn't get dot product function to work..
approach2 = vec .* nabla
println()
println(transpose(approach1))
println(transpose(approach2))
# But in theory approach 2, should be [2^x^3*∂ₓ,4*b*y*∂ᵧ,0]
The first parts of the script is pretty basic, but what I wanted to talk about is the last part showing approach 1 and 2. This is in theory wrong, since an operator should not be applied on the expr to the left, but only to the right, so in approach 2, the result should have been [2^x^3*∂ₓ,4*b*y*∂ᵧ,0]
- I know that matrix multiplication in Julia is able to handle such cases, so I just wondered, whether you would think that there is an easy way to get this behaviour in Julia? This could be quite neat in writing for an example the friction term in the Navier-Stokes equation. So for an example one would have:
2^x^3*∂ₓ*(another expression) = 2^x^3*(derivative of another expression)
I don’t want you to deviate from you developing Grassmann.jl, so if this is very difficult to even implement then don’t bother please - and thanks regarding the Leibniz package - it is a nice feature being able to write something very “math like” in Julia, even if it costs a little in performance - makes it very easy for engineering processes to verify an algorithm based on some physical laws, so I really do hope you keep Leibniz in a way, in which this feature is not lost.
Kind regards