Source code for cupy.padding.pad

import numpy
import six

import cupy


def _prepend_const(narray, pad_amount, value, axis=-1):
    if pad_amount == 0:
        return narray
    padshape = tuple(x if i != axis else pad_amount
                     for i, x in enumerate(narray.shape))
    return cupy.concatenate((cupy.full(padshape, value, narray.dtype),
                             narray), axis=axis)


def _append_const(narray, pad_amount, value, axis=-1):
    if pad_amount == 0:
        return narray
    padshape = tuple(x if i != axis else pad_amount
                     for i, x in enumerate(narray.shape))
    return cupy.concatenate((narray,
                             cupy.full(padshape, value, narray.dtype)),
                            axis=axis)


def _normalize_shape(ndarray, shape, cast_to_int=True):
    ndims = ndarray.ndim
    if shape is None:
        return ((None, None), ) * ndims
    ndshape = numpy.asarray(shape)
    if ndshape.size == 1:
        ndshape = numpy.repeat(ndshape, 2)
    if ndshape.ndim == 1:
        ndshape = numpy.tile(ndshape, (ndims, 1))
    if ndshape.shape != (ndims, 2):
        message = 'Unable to create correctly shaped tuple from %s' % shape
        raise ValueError(message)
    if cast_to_int:
        ndshape = numpy.rint(ndshape).astype(int)
    return tuple(tuple(axis) for axis in ndshape)


def _validate_lengths(narray, number_elements):
    shape = _normalize_shape(narray, number_elements)
    for axis_shape in shape:
        axis_shape = [1 if x is None else x for x in axis_shape]
        axis_shape = [1 if x >= 0 else -1 for x in axis_shape]
        if axis_shape[0] < 0 or axis_shape[1] < 0:
            message = '%s cannot contain negative values.' % number_elements
            raise ValueError(message)
    return shape


[docs]def pad(array, pad_width, mode, **keywords): """Returns padded array. You can specify the padded widths and values. This function currently supports only ``mode=constant`` . Args: array (array-like): Input array of rank N. pad_width (int or array-like): Number of values padded to the edges of each axis. ((before_1, after_1), ... (before_N, after_N)) uniquely pad widths for each axis. ((before, after),) yields same before and after pad for each axis. (pad,) or int is a shortcut for before = after = pad width for all axes. You cannot specify ``cupy.ndarray`` . mode (str): 'constant' Pads with a constant values. constant_values (int or array-like): Used in ``constant``. The values are padded for each axis. ((before_1, after_1), ... (before_N, after_N)) uniquely pad constants for each axis. ((before, after),) yields same before and after constants for each axis. (constant,) or int is a shortcut for before = after = constant for all axes. Default is 0. You cannot specify ``cupy.ndarray`` . Returns: cupy.ndarray: Padded array of rank equal to ``array`` with shape increased according to ``pad_width`` . .. seealso:: :func:`numpy.pad` """ if not numpy.asarray(pad_width).dtype.kind == 'i': raise TypeError('pad_width must be of integral type.') narray = cupy.array(array) pad_width = _validate_lengths(narray, pad_width) allowed_keywords = { 'constant': ['constant_values'], } keyword_defaults = { 'constant_values': 0, } if mode != 'constant': raise NotImplementedError for key in keywords: if key not in allowed_keywords[mode]: raise ValueError('%s keyword not in allowed keywords %s' % (key, allowed_keywords[mode])) for allowed_keyword in allowed_keywords[mode]: keywords.setdefault(allowed_keyword, keyword_defaults[allowed_keyword]) for key in keywords: if key == 'constant_values': keywords[key] = _normalize_shape(narray, keywords[key], cast_to_int=False) newmatrix = narray.copy() for axis, ((pad_before, pad_after), (before_value, after_value)) \ in enumerate(six.moves.zip(pad_width, keywords['constant_values'])): newmatrix = _prepend_const(newmatrix, pad_before, before_value, axis) newmatrix = _append_const(newmatrix, pad_after, after_value, axis) return newmatrix