public NpyArrayMapIterObject() { for (int i = 0; i < npy_defs.NPY_MAXDIMS; i++) { indexes[i] = new NpyIndex(); } }
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); }
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); }
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); }
/* * 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); }
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); } }
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); } }