-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Following up here on my ill-advised rreusser/ndarray-awise-prototype#1 since this is starting to seem more like a extension or fork of cwise than a use of cwise.
Was trying to figure out how to express reduce operations in a general manner but fell way short. Your response "there are probably better ways to do this but hey, more than one way to skin a cat" is way too kind. 😝
I'm currently thinking about what it'd mean to reorder dimensions within cwise. Expressing this seems the most immediately challenging part while the rest is an exercise for the implementer…
What about actually allowing index notation? For example:
contraction over one index: In other words, matrix multiplication. The k loop goes on the inside with its pre/post just outside it. The scope of this would be only over a k loop, but you could use c directly. Would have to think about a syntax that would actually allow gemm-style block-wise multiplications. Represented as:
{
args: [ 'array(i,j,k)', 'array(k,l,m)', 'array(i,j,l,m)'],
contractIndices: ['k'],
beforeContract: function(a, b, c) { c = 0 },
body: function(a, b, c) { c += a * b },
afterContract: function(a, b, c) { }
}contraction over two indices: Similar. beforeContract and afterContract go just outside the innermost contraction loops:
{
args: [ 'array(i,j,k)', 'array(j,k,l)', 'array(i,l)' ],
contractIndices: ['j','k'],
beforeContract: function(a, b, c) { c = 0 },
body: function(a, b, c) { c += a * b },
afterContract: function(a, b, c) { }
}Average over two of three dimensions: Here the notation gets unwieldy and it starts to feel like it's all falling apart.
{
args: [ 'array(j)', 'array(i,j,k)', 'size' ],
contractIndices: ['i', 'k'],
pre: function( size ) { this.factor = 1 / size.i / size.k }
beforeContract: function(a, b) { a = 0 },
body: function(a, b) { a += b },
afterContract: function(a, b) { b *= this.factor }
}I think this is logically consistent and can be optimized within reason (or at least reduces to cwise if unused). It seems possible but probably too invasive to work into cwise which seems more oriented toward image processing. Features like blockIndices and offset are great, but it might add factorial complexity to get all combinations of cases to play well together.
It sounded like you've thought about this before. I think what I've described is a thing that could exist; I just don't know if it's a thing that should exist…
Then again, I might be aiming for something more complicated than the benefit derived from it…