Julia Summer of Einsum
nextjournal.com
nextjournal.com
I'm excited to see what comes out of Andreas' summer work on his implementation of Einsum! There's definitely room for more cool ideas in this space. In particular, I think baking in AD functionality is a cool approach.
It seems like named columns like in SQL might be better?
The main difference between this sort of approach and the approach in an EinSum esque package is that these packages actually encode the name of the dimensions in the type signature of the array whereas an Einsum-esque approach, the names are just temporary labels for the purposes of the macro call.
Also towards adding something like, making einsum work where you just specify the left-hand side of the einsum and then it uses the encoded names. (Rather than the temporay labels)
PRs to add that feature are welcome
It's not optimal, but it's the best I know and named-indices would have their drawbacks too.
It should also be noted that the original use of Einstein notation had all the indices refer to the same thing (it refers to some basis of the underlying vector space). I'v seen some ML papers where this was very much not the case. Obviously in those situations you should be very clear about which index means what.
Pandas is somewhere halfway that and raw matrix/numpy math, automatically aligning dataframes by row and column names first before doing computations. Even though performance is usually closer to numpy than SQL, the extra overhead is sometimes large enough for people to drop down to plain numpy.
f(x) = x * x
function(x) x * x end
function f(x) x * x end
f = x -> x * x
If Julia just used curly brackets instead, we wouldn't need all of these different ways to declare functions.
It really have been nicer if I could just do:
{ x -> x * x }
or for named function:
def f(x) { x * x }
Options one and three are both good to have because sometimes you want one-line function definitions (mostly when you want your code to look like math) and sometimes you want big standard 'code looking' multi-line function definitions. If you don't want to choose in the future, just choose one now and stuck with it. Both can be used for everything if you're willing to put up with some awkward syntax.
f(x) = begin x * x end
If this is your main complaint about julia, I'd say we're doing pretty good.
Curly brackets are useful notation and it'd be a waste to use them up for something like this.
Julia's great, but the Pascal-like 'begin and 'end' delimiters strike me as incredibly ugly. There are many alternatives that I can see (such as the one I mentioned above) that would obviate this situation.
I consider myself a 'mathy' person (I work as a quant), but even so, Julia is a very odd language. All of these compromises or whatever just to please the math people who have a hard time programming. Some of these things the more I think about them are great (array indices starting at one make a lot of sense, actually) and the ability to just write '2x' instead of '2*x' is growing on me.
I guess I don't know what my point is. Maybe it's that Julia seems a little alienating for CS types, and that might hamper adoption.
All in all, Julia's pretty great, despite the minor quibbles I mentioned. I sure as hell wish I could use it for quant work instead of being stuck with the vastly inferior Python.
Would
@einsum c[i,j] = a[i,k] * b[k,j]
be slower than direct matrix multiplication?
Otherwise, you might end up lowering to a naïve for loop which would be significantly slower. TensorCast.jl and TensorOperations.jl know how to make matrix multiplication calls but currently Einsum isn't that smart.
Macros are just syntax transformations.