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
Open

modern D array indexing/slicing #24

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

Comments

@John-Colvin
Copy link
Member

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
Copy link
Member

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
Copy link
Member

9il commented Mar 3, 2015

@9il
Copy link
Member

9il 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
Copy link
Member

9il 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
Copy link
Member

9il commented Jun 9, 2015

Phobos PR dlang/phobos#3397

@kyllingstad
Copy link
Member

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
Copy link
Member

9il 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
Projects
None yet
Development

No branches or pull requests

3 participants