libmir / mir

Mir (backports): Sparse tensors, Hoffman
http://mir.libmir.org
Boost Software License 1.0
210 stars 20 forks source link

non allocating implicit slice create (generalizing iotaSlice) #334

Closed timotheecour closed 7 years ago

timotheecour commented 8 years ago

I would really like this feature, seems quite elegant:

auto lambdaSlice(alias fun, N)(size_t[N] shape){
import std.traits;
enum D=arity!fun;// number of args to fun
static if(D==0) // slice returns fun() for each element (eg zeros(shapes) but implicit)
static if(D==1) // slice returns fun(i) for each linearized index i in 0..prod(shape); 
static if(D==2)  // slice returns fun(i,j) for each 2d index i,j, when applicable
// etc
}

// can also use unaryFun, binaryFun as in std.functional to specify 1-ary and 2-ary functions via a string

unittest{
assert(lambdaSlice!(i=>i), [3,4]) ==iotaSlice(3,4));
// convenient form using unaryFun as in std.functional to specify 1-ary function
assert(lambdaSlice!"a", [3,4]) ==iotaSlice(3,4)); // so simple!
assert(lambdaSlice!"a+b", [2,2]) ==[[0+0, 0+1], [1+0, 1+1]);
assert(lambdaSlice!(()=>1.0), [2,2]) ==[[1.0, 1.0], [1.0, 1.0]);
assert(lambdaSlice!"a+b+c", [2,3,4]) ==/*...*/);
}

9il commented 8 years ago

auto lazy_slice = indexSlice(3, 4).ndMap!(index => index[0] * index[1]); http://docs.mir.dlang.io/latest/mir_ndslice_selection.html#indexSlice http://docs.mir.dlang.io/latest/mir_ndslice_algorithm.html#ndMap

Does it work for you?

9il commented 8 years ago

auto lazy_slice = indexSlice(3, 4).ndMap!(index => index[0] * index[1]); http://docs.mir.dlang.io/latest/mir_ndslice_selection.html#indexSlice http://docs.mir.dlang.io/latest/mir_ndslice_algorithm.html#ndMap

Does it work for you?

@timotheecour can I close it?

timotheecour commented 8 years ago

I still think this is a very useful shortcut, especially with the string lambda syntax. Also, the provided indexSlice only works for fully expanded index, and for eg doesn't allow lambdaSlice!"a"(3,4)

9il commented 8 years ago

lambdaSlice!"a"(3,4)

indexSlice(3, 4).ndMap!"a[0]"

9il commented 8 years ago

for me it looks weird to add [] each time

timotheecour commented 8 years ago

for me it looks weird to add [] each time

ndMap could accept tuples of indexes:

indexSlice(3, 4).ndMap!"a+b"
indexSlice(3, 4).ndMap!((a,b)=>a+b)

but ya, lambdaSlice can probably be implemented based on indexSlice and ndMap (unless it's more efficient to do it directly).

9il commented 7 years ago

Current syntaxes:

ndiota(3, 4).map!"a[0]+a[1]"
ndiota(3, 4).map!((index)=>index[0] + index[1])

See also new cartesian and linspace.