def unravel_index(x,dims): """Convert a flat index into an index tuple for an array of given shape. e.g. for a 2x2 array, unravel_index(2,(2,2)) returns (1,0). Example usage: p = x.argmax() idx = unravel_index(p,x.shape) x[idx] == x.max() Note: x.flat[p] == x.max() Thus, it may be easier to use flattened indexing than to re-map the index to a tuple. """ if x > _nx.prod(dims)-1 or x < 0: raise ValueError("Invalid index, must be 0 <= x <= number of elements.") idx = _nx.empty_like(dims) # Take dimensions # [a,b,c,d] # Reverse and drop first element # [d,c,b] # Prepend [1] # [1,d,c,b] # Calculate cumulative product # [1,d,dc,dcb] # Reverse # [dcb,dc,d,1] dim_prod = _nx.cumprod([1] + list(dims)[:0:-1])[::-1] # Indeces become [x/dcb % a, x/dc % b, x/d % c, x/1 % d] return tuple(x/dim_prod % dims)
def unravel_index(x,dims): """Convert a flat index into an index tuple for an array of given shape. e.g. for a 2x2 array, unravel_index(2,(2,2)) returns (1,0). Example usage: p = x.argmax() idx = unravel_index(p,x.shape) x[idx] == x.max() Note: x.flat[p] == x.max() Thus, it may be easier to use flattened indexing than to re-map the index to a tuple. """ if x > _nx.prod(dims)-1 or x < 0: raise ValueError("Invalid index, must be 0 <= x <= number of elements.") idx = _nx.empty_like(dims) # Take dimensions # [a,b,c,d] # Reverse and drop first element # [d,c,b] # Prepend [1] # [1,d,c,b] # Calculate cumulative product # [1,d,dc,dcb] # Reverse # [dcb,dc,d,1] dim_prod = _nx.cumprod([1] + list(dims)[:0:-1])[::-1] # Indices become [x/dcb % a, x/dc % b, x/d % c, x/1 % d] return tuple(x/dim_prod % dims)
def unravel_index(x, dims): """ Convert a flat index to an index tuple for an array of given shape. Parameters ---------- x : int Flattened index. dims : tuple of ints Input shape, the shape of an array into which indexing is required. Returns ------- idx : tuple of ints Tuple of the same shape as `dims`, containing the unraveled index. Notes ----- In the Examples section, since ``arr.flat[x] == arr.max()`` it may be easier to use flattened indexing than to re-map the index to a tuple. Examples -------- >>> arr = np.arange(20).reshape(5, 4) >>> arr array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]) >>> x = arr.argmax() >>> x 19 >>> dims = arr.shape >>> idx = np.unravel_index(x, dims) >>> idx (4, 3) >>> arr[idx] == arr.max() True """ if x > _nx.prod(dims) - 1 or x < 0: raise ValueError("Invalid index, must be 0 <= x <= number of elements.") idx = _nx.empty_like(dims) # Take dimensions # [a,b,c,d] # Reverse and drop first element # [d,c,b] # Prepend [1] # [1,d,c,b] # Calculate cumulative product # [1,d,dc,dcb] # Reverse # [dcb,dc,d,1] dim_prod = _nx.cumprod([1] + list(dims)[:0:-1])[::-1] # Indices become [x/dcb % a, x/dc % b, x/d % c, x/1 % d] return tuple(x / dim_prod % dims)
def unravel_index(x, dims): """ Convert a flat index into an index tuple for an array of given shape. Parameters ---------- x : int Flattened index. dims : shape tuple Input shape. Notes ----- In the Examples section, since ``arr.flat[x] == arr.max()`` it may be easier to use flattened indexing than to re-map the index to a tuple. Examples -------- >>> arr = np.ones((5,4)) >>> arr array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]) >>> x = arr.argmax() >>> x 19 >>> dims = arr.shape >>> idx = np.unravel_index(x, dims) >>> idx (4, 3) >>> arr[idx] == arr.max() True """ if x > _nx.prod(dims) - 1 or x < 0: raise ValueError( "Invalid index, must be 0 <= x <= number of elements.") idx = _nx.empty_like(dims) # Take dimensions # [a,b,c,d] # Reverse and drop first element # [d,c,b] # Prepend [1] # [1,d,c,b] # Calculate cumulative product # [1,d,dc,dcb] # Reverse # [dcb,dc,d,1] dim_prod = _nx.cumprod([1] + list(dims)[:0:-1])[::-1] # Indices become [x/dcb % a, x/dc % b, x/d % c, x/1 % d] return tuple(x / dim_prod % dims)
def fill_diagonal(a, val, wrap=False): """Fill the main diagonal of the given array of any dimensionality. For an array `a` with ``a.ndim >= 2``, the diagonal is the list of locations with indices ``a[i, ..., i]`` all identical. This function modifies the input array in-place, it does not return a value. Parameters ---------- a : array, at least 2-D. Array whose diagonal is to be filled, it gets modified in-place. val : scalar Value to be written on the diagonal, its type must be compatible with that of the array a. wrap : bool For tall matrices in NumPy version up to 1.6.2, the diagonal "wrapped" after N columns. You can have this behavior with this option. This affects only tall matrices. See also -------- diag_indices, diag_indices_from Notes ----- .. versionadded:: 1.4.0 This functionality can be obtained via `diag_indices`, but internally this version uses a much faster implementation that never constructs the indices and uses simple slicing. Examples -------- >>> a = np.zeros((3, 3), int) >>> np.fill_diagonal(a, 5) >>> a array([[5, 0, 0], [0, 5, 0], [0, 0, 5]]) The same function can operate on a 4-D array: >>> a = np.zeros((3, 3, 3, 3), int) >>> np.fill_diagonal(a, 4) We only show a few blocks for clarity: >>> a[0, 0] array([[4, 0, 0], [0, 0, 0], [0, 0, 0]]) >>> a[1, 1] array([[0, 0, 0], [0, 4, 0], [0, 0, 0]]) >>> a[2, 2] array([[0, 0, 0], [0, 0, 0], [0, 0, 4]]) The wrap option affects only tall matrices: >>> # tall matrices no wrap >>> a = np.zeros((5, 3),int) >>> fill_diagonal(a, 4) >>> a array([[4, 0, 0], [0, 4, 0], [0, 0, 4], [0, 0, 0], [0, 0, 0]]) >>> # tall matrices wrap >>> a = np.zeros((5, 3),int) >>> fill_diagonal(a, 4, wrap=True) >>> a array([[4, 0, 0], [0, 4, 0], [0, 0, 4], [0, 0, 0], [4, 0, 0]]) >>> # wide matrices >>> a = np.zeros((3, 5),int) >>> fill_diagonal(a, 4, wrap=True) >>> a array([[4, 0, 0, 0, 0], [0, 4, 0, 0, 0], [0, 0, 4, 0, 0]]) """ if a.ndim < 2: raise ValueError("array must be at least 2-d") end = None if a.ndim == 2: # Explicit, fast formula for the common case. For 2-d arrays, we # accept rectangular ones. step = a.shape[1] + 1 #This is needed to don't have tall matrix have the diagonal wrap. if not wrap: end = a.shape[1] * a.shape[1] else: # For more than d=2, the strided formula is only valid for arrays with # all dimensions equal, so we check first. if not alltrue(diff(a.shape) == 0): raise ValueError("All dimensions of input must be of equal length") step = 1 + (cumprod(a.shape[:-1])).sum() # Write the value out into the diagonal. a.flat[:end:step] = val
def fill_diagonal(a, val, wrap=False): """Fill the main diagonal of the given array of any dimensionality. For an array `a` with ``a.ndim > 2``, the diagonal is the list of locations with indices ``a[i, i, ..., i]`` all identical. This function modifies the input array in-place, it does not return a value. Parameters ---------- a : array, at least 2-D. Array whose diagonal is to be filled, it gets modified in-place. val : scalar Value to be written on the diagonal, its type must be compatible with that of the array a. wrap: bool For tall matrices in NumPy version up to 1.6.2, the diagonal "wrapped" after N columns. You can have this behavior with this option. This affect only tall matrices. See also -------- diag_indices, diag_indices_from Notes ----- .. versionadded:: 1.4.0 This functionality can be obtained via `diag_indices`, but internally this version uses a much faster implementation that never constructs the indices and uses simple slicing. Examples -------- >>> a = np.zeros((3, 3), int) >>> np.fill_diagonal(a, 5) >>> a array([[5, 0, 0], [0, 5, 0], [0, 0, 5]]) The same function can operate on a 4-D array: >>> a = np.zeros((3, 3, 3, 3), int) >>> np.fill_diagonal(a, 4) We only show a few blocks for clarity: >>> a[0, 0] array([[4, 0, 0], [0, 0, 0], [0, 0, 0]]) >>> a[1, 1] array([[0, 0, 0], [0, 4, 0], [0, 0, 0]]) >>> a[2, 2] array([[0, 0, 0], [0, 0, 0], [0, 0, 4]]) # tall matrices no wrap >>> a = np.zeros((5, 3),int) >>> fill_diagonal(a, 4) array([[4, 0, 0], [0, 4, 0], [0, 0, 4], [0, 0, 0], [0, 0, 0]]) # tall matrices wrap >>> a = np.zeros((5, 3),int) >>> fill_diagonal(a, 4) array([[4, 0, 0], [0, 4, 0], [0, 0, 4], [0, 0, 0], [4, 0, 0]]) # wide matrices >>> a = np.zeros((3, 5),int) >>> fill_diagonal(a, 4) array([[4, 0, 0, 0, 0], [0, 4, 0, 0, 0], [0, 0, 4, 0, 0]]) """ if a.ndim < 2: raise ValueError("array must be at least 2-d") end = None if a.ndim == 2: # Explicit, fast formula for the common case. For 2-d arrays, we # accept rectangular ones. step = a.shape[1] + 1 # This is needed to don't have tall matrix have the diagonal wrap. if not wrap: end = a.shape[1] * a.shape[1] else: # For more than d=2, the strided formula is only valid for arrays with # all dimensions equal, so we check first. if not alltrue(diff(a.shape) == 0): raise ValueError("All dimensions of input must be of equal length") step = 1 + (cumprod(a.shape[:-1])).sum() # Write the value out into the diagonal. a.flat[:end:step] = val
def fill_diagonal(a, val): """Fill the main diagonal of the given array of any dimensionality. For an array with ndim > 2, the diagonal is the list of locations with indices a[i,i,...,i], all identical. This function modifies the input array in-place, it does not return a value. This functionality can be obtained via diag_indices(), but internally this version uses a much faster implementation that never constructs the indices and uses simple slicing. Parameters ---------- a : array, at least 2-dimensional. Array whose diagonal is to be filled, it gets modified in-place. val : scalar Value to be written on the diagonal, its type must be compatible with that of the array a. See also -------- diag_indices, diag_indices_from Notes ----- .. versionadded:: 1.4.0 Examples -------- >>> a = zeros((3,3),int) >>> fill_diagonal(a,5) >>> a array([[5, 0, 0], [0, 5, 0], [0, 0, 5]]) The same function can operate on a 4-d array: >>> a = zeros((3,3,3,3),int) >>> fill_diagonal(a,4) We only show a few blocks for clarity: >>> a[0,0] array([[4, 0, 0], [0, 0, 0], [0, 0, 0]]) >>> a[1,1] array([[0, 0, 0], [0, 4, 0], [0, 0, 0]]) >>> a[2,2] array([[0, 0, 0], [0, 0, 0], [0, 0, 4]]) """ if a.ndim < 2: raise ValueError("array must be at least 2-d") if a.ndim == 2: # Explicit, fast formula for the common case. For 2-d arrays, we # accept rectangular ones. step = a.shape[1] + 1 else: # For more than d=2, the strided formula is only valid for arrays with # all dimensions equal, so we check first. if not alltrue(diff(a.shape) == 0): raise ValueError("All dimensions of input must be of equal length") step = 1 + (cumprod(a.shape[:-1])).sum() # Write the value out into the diagonal. a.flat[::step] = val