Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modern D array indexing/slicing #24

Open
John-Colvin opened this issue Mar 2, 2015 · 7 comments

Comments

Projects
None yet
3 participants
@John-Colvin
Copy link
Member

commented Mar 2, 2015

A couple of notes:

MatrixView has opIndex return by ref in order to allow array[i,j] op= v;. The should be done with opIndexOpAssign instead.

With the new extended semantics of opIndex and opSlice, a proper NDArray type can be implemented, with multi-dimensional slicing.

http://dlang.org/operatoroverloading.html

@kyllingstad

This comment has been minimized.

Copy link
Member

commented Mar 3, 2015

MatrixView has opIndex return by ref in order to allow array[i,j] op= v;. The should be done with opIndexOpAssign instead.

Good point! opIndexOpAssign didn't exist when this code was written. That would take care of the issue with the zero elements in a triangular matrix being modifiable. I'll fix it.

With the new extended semantics of opIndex and opSlice, a proper NDArray type can be implemented, with multi-dimensional slicing.

I know, and agree that would be nice to have. However, if I were to dedicate some time to doing something with the new slicing features, I think I would prioritise implementing submatrix slicing first, before going all out and creating a full-fledged N-dimensional array type. (Also, that seems general enough to be in Phobos, if you ask me.)

@9il

This comment has been minimized.

Copy link
Member

commented Mar 3, 2015

@9il

This comment has been minimized.

Copy link
Member

commented Jun 9, 2015

Code example from corresponding discussion:

size_t anyNumber;
auto ar = new int[3 * 8 * 9 + anyNumber];
auto slice = Slice[0..3, 4..8, 1..9];
assert(ar.canBeSlicedWith(slice)); //checks that ar.length <= 3 * 8 * 9

auto tensor = ar.sliced(slice);
tensor[0, 1, 2] = 4;

auto matrix = tensor[0..$, 1, 0..$];
assert(matrix[0, 2] == 4);
assert(&matrix[0, 2] is &tensor[0, 1, 2]);
@9il

This comment has been minimized.

Copy link
Member

commented Jun 9, 2015

Slice implementation is very simple:

struct Slice
{
static @safe pure nothrow @nogc:

    size_t[2][Args.length] opIndex(Args...)(Args args)
        if (allSatisfy!(isSize_t2, Args))
    body {
        return [args];
    }

    size_t[2] opSlice(size_t p)(size_t a, size_t b)
    in {
        assert(a <= b);
    }
    body {
        return [a, b];
    }

    @disable this();

private:

    enum isSize_t2(T) = is(T == size_t[2]);

}

///
unittest {
    auto slice = Slice[0..1, 3..4, 2..3];
    static assert(is(typeof(slice) == size_t[2][3]));
    assert(slice == [[0, 1], [3, 4], [2, 3]]);
}
@9il

This comment has been minimized.

Copy link
Member

commented Jun 9, 2015

Phobos PR dlang/phobos#3397

@kyllingstad

This comment has been minimized.

Copy link
Member

commented Jun 9, 2015

Nice! If this goes through in Phobos, I guess MatrixView can be removed from SciD altogether? Your Slice seems to do the same job.

@9il

This comment has been minimized.

Copy link
Member

commented Jun 9, 2015

Yes. Current (example in Phobos PR) concept is simplified, but logic is the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.