Пример #1
0
 public NpyArrayMapIterObject()
 {
     for (int i = 0; i < npy_defs.NPY_MAXDIMS; i++)
     {
         indexes[i] = new NpyIndex();
     }
 }
Пример #2
0
        private static NpyIndex[] AllocateNpyIndexes(int NumIndices)
        {
            NpyIndex[] new_indexes = new NpyIndex[NumIndices];

            for (int i = 0; i < NumIndices; i++)
            {
                new_indexes[i] = new NpyIndex();
            }

            return(new_indexes);
        }
Пример #3
0
        internal static NpyArrayMapIterObject NpyArray_MapIterNew(NpyIndex [] indexes, int n)
        {
            NpyArrayMapIterObject mit;
            int i, j;

            /* Allocates the Python object wrapper around the map iterator. */
            mit = new NpyArrayMapIterObject();

            NpyObject_Init(mit, NpyArrayMapIter_Type);
            if (mit == null)
            {
                return(null);
            }
            for (i = 0; i < npy_defs.NPY_MAXDIMS; i++)
            {
                mit.iters[i] = null;
            }
            mit.index         = 0;
            mit.ait           = null;
            mit.subspace      = null;
            mit.numiter       = 0;
            mit.consec        = 1;
            mit.n_indexes     = 0;
            mit.nob_interface = null;

            /* Expand the boolean arrays in indexes. */
            mit.n_indexes = NpyArray_IndexExpandBool(indexes, n, mit.indexes);
            if (mit.n_indexes < 0)
            {
                Npy_DECREF(mit);
                return(null);
            }

            /* Make iterators from any intp arrays and intp in the index. */
            j = 0;
            for (i = 0; i < mit.n_indexes; i++)
            {
                NpyIndex index = mit.indexes[i];

                if (index.type == NpyIndexType.NPY_INDEX_INTP_ARRAY)
                {
                    mit.iters[j] = NpyArray_IterNew(index.intp_array);
                    if (mit.iters[j] == null)
                    {
                        mit.numiter = j - 1;
                        Npy_DECREF(mit);
                        return(null);
                    }
                    j++;
                }
                else if (index.type == NpyIndexType.NPY_INDEX_INTP)
                {
                    NpyArray_Descr indtype;
                    NpyArray       indarray;

                    /* Make a 0-d array for the index. */
                    indtype  = NpyArray_DescrFromType(NPY_TYPES.NPY_INTP);
                    indarray = NpyArray_Alloc(indtype, 0, null, false, null);
                    if (indarray == null)
                    {
                        mit.numiter = j - 1;
                        Npy_DECREF(mit);
                        return(null);
                    }

                    byte[] src = BitConverter.GetBytes(index.intp);
                    memcpy(indarray.data, new VoidPtr(src), sizeof(npy_intp));
                    mit.iters[j] = NpyArray_IterNew(indarray);
                    Npy_DECREF(indarray);
                    if (mit.iters[j] == null)
                    {
                        mit.numiter = j - 1;
                        Npy_DECREF(mit);
                        return(null);
                    }
                    j++;
                }
            }
            mit.numiter = j;

            /* Broadcast the index iterators. */
            if (NpyArray_Broadcast(mit) < 0)
            {
                Npy_DECREF(mit);
                return(null);
            }

            return(mit);
        }
Пример #4
0
        internal static int NpyArray_MapIterBind(NpyArrayMapIterObject mit, NpyArray arr, NpyArray true_array)
        {
            NpyArrayIterObject it;
            int      subnd;
            npy_intp i, j;
            int      n;
            npy_intp dimsize;

            NpyIndex [] bound_indexes = AllocateNpyIndexes(npy_defs.NPY_MAXDIMS);
            int         nbound        = 0;

            subnd = arr.nd - mit.numiter;
            if (subnd < 0)
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "too many indices for array");
                return(-1);
            }

            mit.ait = NpyArray_IterNew(arr);
            if (mit.ait == null)
            {
                return(-1);
            }
            /* no subspace iteration needed.  Finish up and Return */
            if (subnd == 0)
            {
                n = arr.nd;
                for (i = 0; i < n; i++)
                {
                    mit.iteraxes[i] = i;
                }
                goto finish;
            }


            /* Bind the indexes to the array. */
            nbound = NpyArray_IndexBind(mit.indexes, mit.n_indexes,
                                        arr.dimensions, arr.nd,
                                        bound_indexes);
            if (nbound < 0)
            {
                nbound = 0;
                goto fail;
            }

            /* Fill in iteraxes and bscoord from the bound indexes. */
            j = 0;
            for (i = 0; i < nbound; i++)
            {
                NpyIndex index = bound_indexes[i];

                switch (index.type)
                {
                case NpyIndexType.NPY_INDEX_INTP_ARRAY:
                    mit.iteraxes[j++] = i;
                    mit.bscoord[i]    = 0;
                    break;

                case NpyIndexType.NPY_INDEX_INTP:
                    mit.bscoord[i] = index.intp;
                    break;

                case NpyIndexType.NPY_INDEX_SLICE:
                    mit.bscoord[i] = index.slice.start;
                    break;

                default:
                    mit.bscoord[i] = 0;
                    break;
                }
            }

            /* Check for non-consecutive axes. */
            mit.consec = 1;
            j          = mit.iteraxes[0];
            for (i = 1; i < mit.numiter; i++)
            {
                if (mit.iteraxes[i] != j + i)
                {
                    mit.consec = 0;
                    break;
                }
            }

            /*
             * Make the subspace iterator.
             */
            {
                npy_intp [] dimensions = new npy_intp[npy_defs.NPY_MAXDIMS];
                npy_intp [] strides    = new npy_intp[npy_defs.NPY_MAXDIMS];
                npy_intp    offset     = 0;
                int         n2;
                NpyArray    view;

                /* Convert to dimensions and strides. */
                n2 = NpyArray_IndexToDimsEtc(arr, bound_indexes, nbound,
                                             dimensions, strides, ref offset,
                                             true);
                if (n2 < 0)
                {
                    goto fail;
                }

                Npy_INCREF(arr.descr);
                view = NpyArray_NewView(arr.descr, n2,
                                        dimensions, strides,
                                        arr, offset, true);
                if (view == null)
                {
                    goto fail;
                }
                mit.subspace = NpyArray_IterNew(view);
                Npy_DECREF(view);
                if (mit.subspace == null)
                {
                    goto fail;
                }
            }

            /* Expand dimensions of result */
            n = mit.subspace.ao.nd;
            for (i = 0; i < n; i++)
            {
                mit.dimensions[mit.nd + i] = mit.subspace.ao.dimensions[i];
                mit.bscoord[mit.nd + i]    = 0;
            }
            mit.nd += n;

            /* Free the indexes. */
            NpyArray_IndexDealloc(bound_indexes, nbound);
            nbound = 0;

finish:
            /* Here check the indexes (now that we have iteraxes) */
            mit.size = NpyArray_OverflowMultiplyList(mit.dimensions, mit.nd);
            if (mit.size < 0)
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "dimensions too large in fancy indexing");
                goto fail;
            }
            if (mit.ait.size == 0 && mit.size != 0)
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "invalid index into a 0-size array");
                goto fail;
            }


            for (i = 0; i < mit.numiter; i++)
            {
                npy_intp indval;
                it = mit.iters[i];
                NpyArray_ITER_RESET(it);
                dimsize = NpyArray_DIM(arr, mit.iteraxes[i]);
                npy_intp[] dataptr = it.dataptr.datap as npy_intp[];
                while (it.index < it.size)
                {
                    indval = dataptr[it.dataptr.data_offset / sizeof(npy_intp)];
                    if (indval < 0)
                    {
                        indval += dimsize;
                    }
                    if (indval < 0 || indval >= dimsize)
                    {
                        string msg = string.Format("index ({0}) out of range (0<=index<{1}) in dimension {2}", indval, (dimsize - 1), mit.iteraxes[i]);
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError, msg);
                        goto fail;
                    }
                    NpyArray_ITER_NEXT(it);
                }
                NpyArray_ITER_RESET(it);
            }
            return(0);

fail:
            NpyArray_IndexDealloc(bound_indexes, nbound);
            Npy_XDECREF(mit.subspace);
            Npy_XDECREF(mit.ait);
            mit.subspace = null;
            mit.ait      = null;
            return(-1);
        }
Пример #5
0
        /*
         * Converts indexes int out_indexes appropriate for an array by:
         *
         * 1. Expanding any ellipses.
         * 2. Setting slice start/stop/step appropriately for the array dims.
         * 3. Handling any negative indexes.
         * 4. Expanding any boolean arrays to intp arrays of non-zero indices.
         * 5. Convert any booleans to intp.
         *
         * Returns the number of indices in out_indexes, or -1 on error.
         */
        internal static int NpyArray_IndexBind(NpyIndex[] indexes, int n, npy_intp[] dimensions, int nd, NpyIndex[] out_indexes)
        {
            int i;
            int result = 0;
            int n_new  = 0;

            for (i = 0; i < n; i++)
            {
                switch (indexes[i].type)
                {
                case NpyIndexType.NPY_INDEX_STRING:
                    NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                     "String index not allowed.");
                    return(-1);

                case NpyIndexType.NPY_INDEX_ELLIPSIS:
                {
                    /* Expand the ellipsis. */
                    int j, n2;

                    int non_new_indices = count_non_new(indexes, i + 1, n);
                    n2 = nd + n_new - non_new_indices - result;
                    if (n2 < 0)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }
                    /* Fill with full slices. */
                    for (j = 0; j < n2; j++)
                    {
                        NpyIndex _out = out_indexes[result];
                        _out.type        = NpyIndexType.NPY_INDEX_SLICE;
                        _out.slice.start = 0;
                        _out.slice.stop  = dimensions[result - n_new];
                        _out.slice.step  = 1;
                        result++;
                    }
                }
                break;

                case NpyIndexType.NPY_INDEX_BOOL_ARRAY:
                {
                    /* Convert to intp array on non-zero indexes. */
                    NpyArray[] index_arrays = new NpyArray[npy_defs.NPY_MAXDIMS];
                    NpyArray   bool_array   = indexes[i].bool_array;
                    int        j;

                    if (result + bool_array.nd >= nd + n_new)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }
                    if (NpyArray_NonZero(bool_array, index_arrays, null) < 0)
                    {
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }
                    for (j = 0; j < bool_array.nd; j++)
                    {
                        out_indexes[result].type       = NpyIndexType.NPY_INDEX_INTP_ARRAY;
                        out_indexes[result].intp_array = index_arrays[j];
                        result++;
                    }
                }
                break;

                case NpyIndexType.NPY_INDEX_SLICE:
                {
                    /* Sets the slice values based on the array. */
                    npy_intp      dim;
                    NpyIndexSlice slice;

                    if (result >= nd + n_new)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }

                    dim = dimensions[result - n_new];
                    out_indexes[result].type  = NpyIndexType.NPY_INDEX_SLICE;
                    out_indexes[result].slice = indexes[i].slice;
                    slice = out_indexes[result].slice;

                    if (slice.start < 0)
                    {
                        slice.start += dim;
                    }
                    if (slice.start < 0)
                    {
                        slice.start = 0;
                        if (slice.step < 0)
                        {
                            slice.start -= 1;
                        }
                    }
                    if (slice.start >= dim)
                    {
                        slice.start = dim;
                        if (slice.step < 0)
                        {
                            slice.start -= 1;
                        }
                    }

                    if (slice.stop < 0)
                    {
                        slice.stop += dim;
                    }

                    if (slice.stop < 0)
                    {
                        slice.stop = -1;
                    }
                    if (slice.stop > dim)
                    {
                        slice.stop = dim;
                    }

                    result++;
                }
                break;

                case NpyIndexType.NPY_INDEX_SLICE_NOSTOP:
                {
                    /* Sets the slice values based on the array. */
                    npy_intp            dim;
                    NpyIndexSlice       oslice;
                    NpyIndexSliceNoStop islice;

                    if (result >= nd + n_new)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }

                    dim = dimensions[result - n_new];
                    out_indexes[result].type = NpyIndexType.NPY_INDEX_SLICE;
                    oslice = out_indexes[result].slice;
                    islice = indexes[i].slice_nostop;

                    oslice.step = islice.step;

                    if (islice.start < 0)
                    {
                        oslice.start = islice.start + dim;
                    }
                    else
                    {
                        oslice.start = islice.start;
                    }
                    if (oslice.start < 0)
                    {
                        oslice.start = 0;
                        if (oslice.step < 0)
                        {
                            oslice.start -= 1;
                        }
                    }
                    if (oslice.start >= dim)
                    {
                        oslice.start = dim;
                        if (oslice.step < 0)
                        {
                            oslice.start -= 1;
                        }
                    }

                    if (oslice.step > 0)
                    {
                        oslice.stop = dim;
                    }
                    else
                    {
                        oslice.stop = -1;
                    }

                    result++;
                }
                break;

                case NpyIndexType.NPY_INDEX_INTP:
                case NpyIndexType.NPY_INDEX_BOOL:
                {
                    npy_intp val, dim;

                    if (result >= nd + n_new)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }

                    if (indexes[i].type == NpyIndexType.NPY_INDEX_INTP)
                    {
                        val = indexes[i].intp;
                    }
                    else
                    {
                        val = (npy_intp)(indexes[i].boolean == true ? 1 : 0);
                    }
                    dim = dimensions[result - n_new];

                    if (val < 0)
                    {
                        val += dim;
                    }
                    if (val < 0 || val >= dim)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "Invalid index.");
                        return(-1);
                    }

                    out_indexes[result].type = NpyIndexType.NPY_INDEX_INTP;
                    out_indexes[result].intp = val;
                    result++;
                }
                break;


                case NpyIndexType.NPY_INDEX_INTP_ARRAY:
                    if (result >= nd + n_new)
                    {
                        NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                         "too many indices");
                        NpyArray_IndexDealloc(out_indexes, result);
                        return(-1);
                    }

                    out_indexes[result++] = indexes[i];
                    Npy_INCREF(indexes[i].intp_array);
                    break;

                case NpyIndexType.NPY_INDEX_NEWAXIS:
                    n_new++;
                    out_indexes[result++] = indexes[i];
                    break;

                default:
                    /* Copy anything else. */
                    out_indexes[result++] = indexes[i];
                    break;
                }
            }

            return(result);
        }
Пример #6
0
        internal static int NpyArray_IterSubscriptAssign(NpyArrayIterObject self, NpyIndex [] indexes, int n, NpyArray value)
        {
            NpyIndex index;

            if (n > 1)
            {
                NpyErr_SetString(npyexc_type.NpyExc_IndexError, "unsupported iterator index.");
                return(-1);
            }

            if (n == 0 || (n == 1 && indexes[0].type == NpyIndexType.NPY_INDEX_ELLIPSIS))
            {
                /* Assign to the whole iter using a slice. */
                NpyIndexSlice slice = new NpyIndexSlice();

                slice.start = 0;
                slice.stop  = self.size;
                slice.step  = 1;
                return(NpyArray_IterSubscriptAssignSlice(self, slice, value));
            }

            index = indexes[0];

            switch (index.type)
            {
            case NpyIndexType.NPY_INDEX_BOOL:
                if (index.boolean)
                {
                    return(NpyArray_IterSubscriptAssignIntp(self, 0, value));
                }
                else
                {
                    return(0);
                }

            case NpyIndexType.NPY_INDEX_INTP:
                return(NpyArray_IterSubscriptAssignIntp(self, index.intp, value));

            case NpyIndexType.NPY_INDEX_SLICE:
            case NpyIndexType.NPY_INDEX_SLICE_NOSTOP:
            {
                npy_intp[] new_size = new npy_intp[1] {
                    self.size
                };
                NpyIndex [] new_index = new NpyIndex[1] {
                    new NpyIndex()
                };

                /* Bind the slice. */
                if (NpyArray_IndexBind(indexes, 1,
                                       new_size, 1,
                                       new_index) < 0)
                {
                    return(-1);
                }
                Debug.Assert(new_index[0].type == NpyIndexType.NPY_INDEX_SLICE);

                self.size = new_size[0];
                return(NpyArray_IterSubscriptAssignSlice(self, new_index[0].slice, value));
            }

            case NpyIndexType.NPY_INDEX_BOOL_ARRAY:
                return(NpyArray_IterSubscriptAssignBoolArray(self,
                                                             index.bool_array,
                                                             value));

            case NpyIndexType.NPY_INDEX_INTP_ARRAY:
                return(NpyArray_IterSubscriptAssignIntpArray(self,
                                                             index.intp_array,
                                                             value));

            case NpyIndexType.NPY_INDEX_NEWAXIS:
            case NpyIndexType.NPY_INDEX_ELLIPSIS:
                NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                 "cannot use Ellipsis or newaxes here");
                return(-1);

            default:
                NpyErr_SetString(npyexc_type.NpyExc_IndexError, "unsupported iterator index");
                return(-1);
            }
        }
Пример #7
0
        internal static NpyArray NpyArray_IterSubscript(NpyArrayIterObject self, NpyIndex [] indexes, int n)
        {
            if (n == 0 || (n == 1 && indexes[0].type == NpyIndexType.NPY_INDEX_ELLIPSIS))
            {
                Npy_INCREF(self.ao);
                return(self.ao);
            }

            if (n > 1)
            {
                NpyErr_SetString(npyexc_type.NpyExc_IndexError, "unsupported iterator index.");
                return(null);
            }

            switch (indexes[0].type)
            {
            case NpyIndexType.NPY_INDEX_BOOL:
                return(NpyArray_IterSubscriptBool(self, indexes[0].boolean));

            case NpyIndexType.NPY_INDEX_INTP:
                /* Return a 0-d array with the value at the index. */
                return(NpyArray_IterSubscriptIntp(self, indexes[0].intp));

            case NpyIndexType.NPY_INDEX_SLICE_NOSTOP:
            case NpyIndexType.NPY_INDEX_SLICE:
            {
                NpyIndex [] new_index = new NpyIndex[1] {
                    new NpyIndex()
                };

                npy_intp[] newSize = new npy_intp[1] {
                    self.size
                };

                /* Bind the slice. */
                if (NpyArray_IndexBind(indexes, 1,
                                       newSize, 1,
                                       new_index) < 0)
                {
                    return(null);
                }

                Debug.Assert(new_index[0].type == NpyIndexType.NPY_INDEX_SLICE);

                self.size = newSize[0];

                return(NpyArray_IterSubscriptSlice(self, new_index[0].slice));
            }

            case NpyIndexType.NPY_INDEX_BOOL_ARRAY:
                return(NpyArray_IterSubscriptBoolArray(self, indexes[0].bool_array));

            case NpyIndexType.NPY_INDEX_INTP_ARRAY:
                return(NpyArray_IterSubscriptIntpArray(self, indexes[0].intp_array));

            case NpyIndexType.NPY_INDEX_NEWAXIS:
            case NpyIndexType.NPY_INDEX_ELLIPSIS:
                NpyErr_SetString(npyexc_type.NpyExc_IndexError,
                                 "cannot use Ellipsis or newaxes here");
                return(null);

            default:
                NpyErr_SetString(npyexc_type.NpyExc_IndexError, "unsupported iterator index");
                return(null);
            }
        }