Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ARTWORK_DIR=$(DOC_SOURCE_DIR)/artwork
MIR_PACKAGES = mir mir/ndslice

PACKAGE_mir = conv functional primitives utility
PACKAGE_mir_ndslice = package algorithm allocation dynamic field iterator package slice sorting concatenation topology
PACKAGE_mir_ndslice = package algorithm allocation dynamic field ndfield iterator package slice sorting concatenation topology

MOD_EXCLUDES=$(addprefix --ex=, mir.ndslice.internal)

Expand Down
4 changes: 4 additions & 0 deletions index.d
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ $(BOOKTABLE ,
$(TDNW $(MREF mir,ndslice,field))
$(TD Field declarations)
)
$(TR
$(TDNW $(MREF mir,ndslice,ndfield))
$(TD NdField declarations)
)
$(LEADINGROW Accessories)
$(TR
$(TDNW $(MREF mir,conv))
Expand Down
Binary file modified ndslice.graffle
Binary file not shown.
1,300 changes: 762 additions & 538 deletions ndslice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion source/mir/ndslice/algorithm.d
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ template reduce(alias fun)
}
else
alias reduce = .reduce!(naryFun!fun);

}

/// Single slice
Expand Down
58 changes: 57 additions & 1 deletion source/mir/ndslice/field.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $(T2 BitwiseField, $(SUBREF topology, bitwise))
$(T2 MapField, $(SUBREF topology, map))
$(T2 ndIotaField, $(SUBREF topology, ndiota))
$(T2 RepeatField, $(SUBREF topology, repeat))
$(T2 LinspaceField, $(SUBREF topology, linspace))
)


Expand Down Expand Up @@ -52,10 +53,25 @@ struct MapField(Field, alias fun)
+/
static alias __map(alias fun1) = MapField__map!(Field, fun, fun1);

auto ref opIndex()(ptrdiff_t index)
auto ref opIndex(T...)(T index)
{
return fun(_field[index]);
}

auto length()() @property
{
return _field.length;
}

auto shape()() @property
{
return _field.shape;
}

auto elemenstCount()() @property
{
return _field.elemenstCount;
}
}

/++
Expand Down Expand Up @@ -250,3 +266,43 @@ struct ndIotaField(size_t N)
return indexes;
}
}

/++
`LinspaceField` is used by $(SUBREF topology, linspace).
+/
struct LinspaceField(T)
{
///
size_t _length;

///
T start, stop;

// no fastmath
///
T opIndex()(size_t index)
{
auto d = _length - 1;
auto v = typeof(T.init.re)(d - index);
auto w = typeof(T.init.re)(index);
v /= d;
w /= d;
auto a = v * start;
auto b = w * stop;
return a + b;
}

@fastmath:

size_t length()() @property
{
return _length;
}

size_t[1] shape()() @property
{
size_t[1] ret = void;
ret[0] = _length;
return ret;
}
}
18 changes: 18 additions & 0 deletions source/mir/ndslice/internal.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ import mir.internal.utility;

@fastmath:

private template _prod(size_t len)
if (len)
{
static if (len == 1)
enum _prod = "elems[0]";
else
{
enum i = len - 1;
enum _prod = ._prod!i ~ " * elems[" ~ i.stringof ~ "]";
}
}

auto product(Elems...)(auto ref Elems elems)
{
return mixin(_prod!(Elems.length));
}


template _iotaArgs(size_t length, string prefix, string suffix)
{
static if (length)
Expand Down
232 changes: 232 additions & 0 deletions source/mir/ndslice/ndfield.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/++
This is a submodule of $(MREF mir,ndslice).

NdField is a type with `opIndex(size_t[N] index...)` primitive.
An ndslice can be created on top of a ndField using $(SUBREF slice, slicedNdField).

$(BOOKTABLE $(H2 NdFields),
$(TR $(TH NdField Name) $(TH Used By))
$(T2 Cartesian, $(SUBREF topology, cartesian))
$(T2 Kronecker, $(SUBREF topology, kronecker))
)

See_also: $(SUBREF concatenation, concatenation).

License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Copyright: Copyright © 2016-, Ilya Yaroshenko
Authors: Ilya Yaroshenko

Macros:
SUBREF = $(REF_ALTTEXT $(TT $2), $2, mir, ndslice, $1)$(NBSP)
T2=$(TR $(TDNW $(LREF $1)) $(TD $+))
+/
module mir.ndslice.ndfield;

import mir.internal.utility;
import mir.ndslice.internal;
import mir.ndslice.slice;
import mir.primitives;
import std.meta;

private template _indexes(NdFields...)
{
static if (NdFields.length == 0)
enum _indexes = "";
else
{
alias Next = NdFields[0 .. $ - 1];
enum i = Next.length;
enum _indexes = ._indexes!Next ~
"_fields[" ~ i.stringof ~ "][" ~ _indexes_range!([staticMap!(DimensionCount, Next)].sum, DimensionCount!(NdFields[$ - 1])) ~ "], ";
}
}

private template _indexes_range(size_t begin, size_t count)
{
static if (count == 0)
enum _indexes_range = "";
else
{
enum next = count - 1;
enum elem = begin + next;
enum _indexes_range = ._indexes_range!(begin, next) ~ "indexes[" ~ elem.stringof ~ "], ";
}
}

///
struct Cartesian(NdFields...)
if (NdFields.length > 1)
{
///
NdFields _fields;

package enum size_t M(size_t f) = [staticMap!(DimensionCount, NdFields[0..f])].sum;
package enum size_t N = M!(NdFields.length);

///
size_t length(size_t d = 0)() @property
{
foreach(f, ref field; _fields)
static if (M!(f + 1) > d)
return field.length!(d - M!f);
}

///
size_t[N] shape()() @property
{
typeof(return) ret = void;
foreach(f, ref field; _fields)
{
static if (hasShape!(NdFields[f]))
{
auto s = field.shape;
foreach(j; Iota!(s.length))
ret[M!f + j] = s[j];
}
else
{
ret[M!f] = field.length;
}
}
return ret;
}

///
size_t elementsCount()() @property
{
size_t ret = 1;
foreach (ref field; _fields)
ret *= field.elementsCount;
ret;
}

///
auto opIndex()(size_t[N] indexes...)
{
import mir.functional : tuple;
return mixin("tuple(" ~ _indexes!(NdFields) ~ ")");
}
}

private template _kr_indexes(size_t n)
{
static if (n == 0)
enum _kr_indexes = "";
else
{
enum i = n - 1;
enum _kr_indexes = ._kr_indexes!i ~ "_fields[" ~ i.stringof ~ "][ind[" ~ i.stringof ~ "]], ";
}
}

///
struct Kronecker(alias fun, NdFields...)
if (NdFields.length > 1 && allSatisfy!(templateOr!(hasShape, hasLength), NdFields[1 .. $]))
{
///
NdFields _fields;

private enum N = DimensionCount!(NdFields[$-1]);

///
size_t length(size_t d = 0)() @property
{
static if (d == 0)
{
size_t ret = _fields[0].length;
foreach(ref field; _fields[1 .. $])
ret *= field.length;
}
else
{
size_t ret = _fields[0].length!d;
foreach(ref field; _fields[1 .. $])
ret *= field.length!d;
}
return ret;
}


///
size_t[N] shape()() @property
{
static if (N > 1)
{
size_t[N] ret = _fields[0].shape;
foreach(ref field; _fields[1 .. $])
{
auto s = field.shape;
foreach(i; Iota!N)
ret[i] *= s[i];
}
return ret;
}
else
{
size_t[1] ret = void;
ret[0] = _fields[0].length;
foreach(ref field; _fields[1 .. $])
ret[0] *= field.length;
return ret;
}
}

///
size_t elementsCount()() @property
{
size_t ret = 1;
foreach (ref field; _fields)
ret *= field.elementsCount;
ret;
}

///
auto opIndex()(size_t[N] indexes...)
{
static if (N > 1)
size_t[N][NdFields.length] ind = void;
else
size_t[NdFields.length] ind = void;
foreach_reverse (f, ref field; _fields)
{
static if (f)
{
static if (hasShape!(NdFields[f]))
{
auto s = field.shape;
}
else
{
size_t[1] s = void;
s[0] = field.length;
}
static if (N > 1)
{
foreach(i; Iota!N)
{
ind[f][i] = indexes[i] % s[i];
indexes[i] /= s[i];
}
}
else
{
ind[f] = indexes[0] % s[0];
indexes[0] /= s[0];
}
}
else
{
static if (N > 1)
{
foreach(i; Iota!N)
ind[f][i] = indexes[i];
}
else
{
ind[f] = indexes[0];
}
}
}
return mixin("fun(" ~ _kr_indexes!(ind.length) ~ ")");
}
}
11 changes: 11 additions & 0 deletions source/mir/ndslice/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@ $(TR $(TDNW $(SUBMODULE topology) $(BR)
$(SUBREF topology, bitwise)
$(SUBREF topology, blocks)
$(SUBREF topology, canonical)
$(SUBREF topology, cartesian)
$(SUBREF topology, diagonal)
$(SUBREF topology, evertPack)
$(SUBREF topology, flattened)
$(SUBREF topology, indexed)
$(SUBREF topology, iota)
$(SUBREF topology, ipack)
$(SUBREF topology, kronecker)
$(SUBREF topology, linspace)
$(SUBREF topology, map)
$(SUBREF topology, ndiota)
$(SUBREF topology, pack)
Expand Down Expand Up @@ -223,6 +226,14 @@ $(TR $(TDNW $(SUBMODULE field)
)
)

$(TR $(TDNW $(SUBMODULE ndfield)
$(BR) $(SMALL Declarations))
$(TD
$(SUBREF ndfield, Cartesian)
$(SUBREF ndfield, Kronecker)
)
)

))

$(H2 Example: Image Processing)
Expand Down
Loading