private static void AssignFromSeq(IEnumerable <Object> seq, ndarray result, int dim, long offset) { if (dim >= result.ndim) { throw new RuntimeException(String.Format("Source dimensions ({0}) exceeded target array dimensions ({1}).", dim, result.ndim)); } if (seq is ndarray && seq.GetType() != typeof(ndarray)) { // Convert to an array to ensure the dimensionality reduction // assumption works. ndarray array = NpyCoreApi.FromArray((ndarray)seq, null, NPYARRAYFLAGS.NPY_ENSUREARRAY); seq = (IEnumerable <object>)array; } if (seq.Count() != result.Dim(dim)) { throw new RuntimeException("AssignFromSeq: sequence/array shape mismatch."); } long stride = result.Stride(dim); if (dim < result.ndim - 1) { // Sequence elements should be additional sequences seq.Iteri((o, i) => AssignFromSeq((IEnumerable <Object>)o, result, dim + 1, offset + stride * i)); } else { seq.Iteri((o, i) => result.Dtype.f.setitem(offset + i * stride, o, result.Array)); } }
/// <summary> /// Finds the offset for a single item assignment to the array. /// </summary> /// <param name="arr">The array we are assigning to.</param> /// <returns>The offset or -1 if this is not a single assignment.</returns> internal npy_intp SingleAssignOffset(ndarray arr) { // Check to see that there are just newaxis, ellipsis, intp or bool indexes for (int i = 0; i < num_indexes; i++) { switch (IndexType(i)) { case NpyIndexType.NPY_INDEX_NEWAXIS: case NpyIndexType.NPY_INDEX_ELLIPSIS: case NpyIndexType.NPY_INDEX_INTP: case NpyIndexType.NPY_INDEX_BOOL: break; default: return(-1); } } // Bind to the array and calculate the offset. NpyIndexes bound = Bind(arr); { npy_intp offset = 0; int nd = 0; for (int i = 0; i < bound.num_indexes; i++) { switch (bound.IndexType(i)) { case NpyIndexType.NPY_INDEX_NEWAXIS: break; case NpyIndexType.NPY_INDEX_INTP: offset += arr.Stride(nd++) * bound.GetIntP(i); break; case NpyIndexType.NPY_INDEX_SLICE: // An ellipsis became a slice on binding. // This is not a single item assignment. return(-1); default: // This should never happen return(-1); } } if (nd != arr.ndim) { // Not enough indexes. This is not a single item. return(-1); } return(offset); } }
internal static ndarray PrependOnes(ndarray arr, int nd, int ndmin) { npy_intp[] newdims = new npy_intp[ndmin]; npy_intp[] newstrides = new npy_intp[ndmin]; int num = ndmin - nd; // Set the first num dims and strides for the 1's for (int i = 0; i < num; i++) { newdims[i] = (npy_intp)1; newstrides[i] = (npy_intp)arr.ItemSize; } // Copy in the rest of dims and strides for (int i = num; i < ndmin; i++) { int k = i - num; newdims[i] = (npy_intp)arr.Dim(k); newstrides[i] = (npy_intp)arr.Stride(k); } return(NpyCoreApi.NewView(arr.Dtype, ndmin, newdims, newstrides, arr, 0, false)); }