libmir/numir

shapeNested -> mir.ndslice.allocation.shape

9il opened this issue · 2 comments

9il commented

Hello @ShigekiKarita
shapeNested can be replaced with mir.ndslice.allocation: shape

9il commented

Something like this

auto shapeNested(T)(T[] a)
{
   int err;
   auto ret = shape(a, err);
   if (err)
     throw new Exception("Array has bad shape");
   return ret;
}

@9il Thanks for your advice! But it doesn't suit me because I want to write like this nparray([[1,2],[3,4]]) and need it to pass this test.

import std.stdio;
import mir.ndslice.allocation: shape;

auto shapeNested(T)(T[] a)
{
   int err;
   auto ret = shape(a, err);
   if (err)
     throw new Exception("Array has bad shape");
   return ret;
}

unittest
{
    int[2][3] nested = [[1,2],[3,4],[5,6]];
    writeln(nested.shapeNested);
    assert(nested.shapeNested == [3, 2]);
}

but this results is [3]. And test fails.

$ dub test --compiler=dmd
Generating test runner configuration 'numir-test-library' for 'library' (library).
Performing "unittest" build using dmd for x86_64.
numir 0.0.1+commit.18.g1344512: building configuration "numir-test-library"...
Linking...
Running ./numir-test-library 
[3]
core.exception.AssertError@source/misc.d(17): unittest failure

I found the compiler treats the nested [[...]] arg as an array with just first order length. So I have to avoid this behavior by this recursive cast.

size_t[rank!T] shapeNested(T)(T array)
{
    static if (rank!T == 0)
    {
        return [];
    }
    else
    {
        return to!(size_t[rank!T])(array.length ~ shapeNested(array[0]));
    }
}