/// <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); } }
public Object this[params object[] args] { get { ndarray result; NpyIndexes indexes = new NpyIndexes(); { NpyUtil_IndexProcessing.IndexConverter(this.arr.ravel(), args, indexes); result = NpyCoreApi.IterSubscript(this, indexes); } if (result.ndim == 0) { return(result.GetItem(0)); } else { return(result); } } set { NpyIndexes indexes = new NpyIndexes(); { NpyUtil_IndexProcessing.IndexConverter(this.arr.ravel(), args, indexes); if (indexes.NumIndexes == 1) { // Special cases for single assigment. switch (indexes.IndexType(0)) { case NpyIndexType.NPY_INDEX_INTP: SingleAssign(indexes.GetIntP(0), value); return; case NpyIndexType.NPY_INDEX_BOOL: if (indexes.GetBool(0)) { SingleAssign(0, value); } return; default: break; } } ndarray array_val = np.FromAny(value, arr.Dtype, 0, 0, 0, null); NpyCoreApi.IterSubscriptAssign(this, indexes, array_val); } } }
internal NpyIndexes Bind(ndarray arr) { NpyIndexes result = new NpyIndexes(); int n = NpyCoreApi.BindIndex(arr, this, result); if (n < 0) { NpyCoreApi.CheckError(); } else { result.num_indexes = n; } return(result); }
public static void IndexConverter(ndarray arr, Object[] indexArgs, NpyIndexes indexes) { int index = 0; if (indexArgs.Length != 1) { // This is the simple case. Just convert each arg. if (indexArgs.Length > NpyDefs.NPY_MAXDIMS) { throw new IndexOutOfRangeException("Too many indices"); } foreach (object arg in indexArgs) { ConvertSingleIndex(arr, arg, indexes, index++); } } else { // Single index. object arg = indexArgs[0]; if (arg is ndarray) { ConvertSingleIndex(arr, arg, indexes, index++); } else if (arg is string) { ConvertSingleIndex(arr, arg, indexes, index++); } else if (arg is IEnumerable <object> && SequenceTuple((IEnumerable <object>)arg)) { foreach (object sub in (IEnumerable <object>)arg) { ConvertSingleIndex(arr, sub, indexes, index++); } } else { ConvertSingleIndex(arr, arg, indexes, index++); } } }
private static void ConvertSingleIndex(ndarray arr, Object arg, NpyIndexes indexes, int index) { if (arg == null) { indexes.AddNewAxis(); } else if (arg is string && (string)arg == "...") { indexes.AddEllipsis(); } else if (arg is Ellipsis) { indexes.AddEllipsis(); } else if (arg is CSharpTuple) { indexes.AddCSharpTuple((CSharpTuple)arg); } else if (arg is bool) { indexes.AddIndex((bool)arg); } else if (arg is int) { indexes.AddIndex((int)arg); } else if (arg is BigInteger) { BigInteger bi = (BigInteger)arg; npy_intp lval = (npy_intp)bi; indexes.AddIndex(lval); } else if (arg is ISlice) { indexes.AddIndex((ISlice)arg); } else if (arg is string) { indexes.AddIndex(arr, (string)arg, index); } else { ndarray array_arg = null; if (arg.GetType().IsArray) { dynamic arr1 = arg; if (arr1[0] is ndarray) { } else { array_arg = np.array(new VoidPtr(arr1), null); } } else { array_arg = arg as ndarray; } if (array_arg == null && arg is IEnumerable <object> ) { array_arg = np.FromIEnumerable((IEnumerable <object>)arg, null, false, 0, 0); } if (array_arg == null && arg is IEnumerable <npy_intp> ) { var arr1 = arg as IEnumerable <npy_intp>; array_arg = np.array(arr1.ToArray(), null); } // Boolean scalars if (array_arg != null && array_arg.ndim == 0 && NpyDefs.IsBool(array_arg.TypeNum)) { indexes.AddIndex(Convert.ToBoolean(array_arg[0])); } // Integer scalars else if (array_arg != null && array_arg.ndim == 0 && NpyDefs.IsInteger(array_arg.TypeNum)) { try { indexes.AddIndex((npy_intp)Convert.ToInt64(array_arg[0])); } catch (Exception e) { throw new IndexOutOfRangeException(e.Message); } } else if (array_arg != null) { // Arrays must be either boolean or integer. if (NpyDefs.IsInteger(array_arg.TypeNum)) { indexes.AddIntpArray(array_arg); } else if (NpyDefs.IsBool(array_arg.TypeNum)) { indexes.AddBoolArray(array_arg); } else { throw new IndexOutOfRangeException("arrays used as indices must be of integer (or boolean) type."); } } else if (arg is IEnumerable <Object> ) { // Other sequences we convert to an intp array indexes.AddIntpArray(arg); } else if (arg is IConvertible) { #if NPY_INTP_64 indexes.AddIndex((npy_intp)Convert.ToInt64(arg)); #else indexes.AddIndex((npy_intp)Convert.ToInt32(arg)); #endif } else { throw new ArgumentException(String.Format("Argument '{0}' is not a valid index.", arg)); } } }