Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add at/numStride/indexStride
  • Loading branch information
jmh530 committed Jun 18, 2020
commit 2705ac6a13ebfefd4cddbcc4dabfc4dc57e24c6f
218 changes: 218 additions & 0 deletions source/mir/ndslice/slice.d
Original file line number Diff line number Diff line change
Expand Up @@ -2544,6 +2544,51 @@ public:
assert(imm == x);
assert(mut == x);
}

size_t[N] numIndex(size_t n) @safe scope const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused, can be removed though

{
assert(n < elementCount, "numIndex: n must be less than elementCount");

size_t[N] output;
static if (N == 1) {
output[N - 1] = n;
} else {
output[0 .. (N - 1)] = _lengths[1 .. N];
static if (N > 2) {
foreach_reverse (i; Iota!(N - 2)) {
output[i] *= output[i + 1];
}
}
size_t mul;
foreach (i; Iota!(N - 1)) {
mul = n / output[i];
n -= mul * output[i];
output[i] = mul;
}
output[N - 1] = n;
}

return output;
}

size_t valStride(size_t n) @safe scope const
{
assert(n < elementCount, "valStride: n must be less than elementCount");

static if (kind == Contiguous || (kind == Canonical && N == 1)) {
return n;
} else static if (kind == Universal && N == 1) {
return n * _strides[0];
} else {
return indexStride(numIndex(n));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this compiles, but the code is almost the same that was used in FlattenedIterator.

 ptrdiff_t valStride()(ptrdiff_t n) @safe scope const { ptrdiff_t _shift; foreach_reverse (i; Iota!(1, N)) { immutable v = n / ptrdiff_t(_lengths[i]); n %= ptrdiff_t(_lengths[i]); static if (i == S) _shift += n; else _shift += n * _strides[i]; n = v; } _shift += n * _strides[0]; return _shift; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, any reason to make it public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@9il Not really. indexStride was public and I tried to take the same approach. I can make changes private.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is ok to make it public, but I am not sure about naming, and we need docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as below. Happy to add more docs later today. Flexible on naming.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, this code is for Canonical and Universal slices. Contiguous should just return the n

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

}

///
auto ref at(size_t n) scope return @trusted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needs more docs and more verbose name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to add more docs later today. Any suggestion on name? Maybe access or accessFlat? I am flexible.

Along the same lines, should gmean/hmean be renamed geometricMean/harmonicMean? Might need deprecation given that there have been releases...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accessFlag looks good. Existing names in stat are good as well.

{
return _iterator[valStride(n)];
}

static if (isMutable!DeepElement)
{
Expand Down Expand Up @@ -3840,3 +3885,176 @@ version(mir_test) @safe unittest
b[] = a;
assert(a == b);
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(6);
auto mFlat = m.flattened;

size_t num;
for (size_t i = 0; i < m.length!0; i++) {
assert([i] == m.numIndex(i));
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(2, 3);
auto mFlat = m.flattened;

size_t num;
for (size_t i = 0; i < m.length!0; i++) {
for (size_t j = 0; j < m.length!1; j++) {
num = j + i * (m.length!1);
assert([i, j] == m.numIndex(num));
}
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(2, 3, 4);
auto mFlat = m.flattened;

size_t num;
for (size_t i = 0; i < m.length!0; i++) {
for (size_t j = 0; j < m.length!1; j++) {
for (size_t k = 0; k < m.length!2; k++) {
num = k + j * (m.length!2) + i * (m.length!1) * (m.length!2);
assert([i, j, k] == m.numIndex(num));
}
}
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(2, 3, 4); // Contiguous Matrix
auto mFlat = m.flattened;

for (size_t i = 0; i < m.elementCount; i++) {
assert(m.at(i) == mFlat[i]);
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(3, 4); // Contiguous Matrix
auto x = m.front; // Contiguous Vector

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == m[0, i]);
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(3, 4); // Contiguous Matrix
auto x = m[0 .. $, 0 .. $ - 1]; // Canonical Matrix
auto xFlat = x.flattened;

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == xFlat[i]);
}
}


version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(2, 3, 4); // Contiguous Matrix
auto x = m[0 .. $, 0 .. $, 0 .. $ - 1]; // Canonical Matrix
auto xFlat = x.flattened;

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == xFlat[i]);
}
}


version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;
import mir.ndslice.dynamic: transposed;

auto m = iota(2, 3, 4); // Contiguous Matrix
auto x = m.transposed!(2, 1, 0); // Universal Matrix
auto xFlat = x.flattened;

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == xFlat[i]);
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;
import mir.ndslice.dynamic: transposed;

auto m = iota(3, 4); // Contiguous Matrix
auto x = m.transposed; // Universal Matrix
auto xFlat = x.flattened;

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == xFlat[i]);
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened, diagonal;

auto m = iota(3, 4); // Contiguous Matrix
auto x = m.diagonal; // Universal Vector

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == m[i, i]);
}
}

version(mir_test)
@safe pure @nogc nothrow
unittest
{
import mir.ndslice.topology: iota, flattened;

auto m = iota(3, 4); // Contiguous Matrix
auto x = m.front!1; // Universal Vector

for (size_t i = 0; i < x.elementCount; i++) {
assert(x.at(i) == m[i, 0]);
}
}