Ejemplo n.º 1
0
    def test_moveaxis1(self):
        x_np = np.random.randn(2, 3, 4, 5, 7)
        expected = np.moveaxis(x_np, [0, 4, 3, 2], [1, 3, 2, 0])
        paddle.enable_static()
        with paddle.static.program_guard(fluid.Program()):
            x = paddle.static.data("x", shape=[2, 3, 4, 5, 7], dtype='float64')
            out = paddle.moveaxis(x, [0, 4, 3, 2], [1, 3, 2, 0])

            exe = paddle.static.Executor()
            out_np = exe.run(feed={"x": x_np}, fetch_list=[out])[0]

        self.assertEqual(np.array_equal(out_np, expected), True)

        paddle.disable_static()
        x = paddle.to_tensor(x_np)
        out = paddle.moveaxis(x, [0, 4, 3, 2], [1, 3, 2, 0])
        self.assertEqual(out.shape, [4, 2, 5, 7, 3])
        self.assertEqual(np.array_equal(out.numpy(), expected), True)
        paddle.enable_static()
Ejemplo n.º 2
0
    def test_error(self):
        x = paddle.randn([2, 3, 4, 5])
        # src must have the same number with dst
        with self.assertRaises(AssertionError):
            paddle.moveaxis(x, [1, 0], [2])

        # each element of src must be unique
        with self.assertRaises(ValueError):
            paddle.moveaxis(x, [1, 1], [0, 2])

        # each element of dst must be unique
        with self.assertRaises(ValueError):
            paddle.moveaxis(x, [0, 1], [2, 2])

        # each element of src must be integer
        with self.assertRaises(AssertionError):
            paddle.moveaxis(x, [0.5], [1])

        # each element of dst must be integer
        with self.assertRaises(AssertionError):
            paddle.moveaxis(x, [0], [1.5])

        # each element of src must be in the range of [-4, 3)
        with self.assertRaises(AssertionError):
            paddle.moveaxis(x, [-10, 1], [2, 3])

        # each element of dst must be in the range of [-4, 3)
        with self.assertRaises(AssertionError):
            paddle.moveaxis(x, [2, 1], [10, 3])
Ejemplo n.º 3
0
def _compute_quantile(x, q, axis=None, keepdim=False, ignore_nan=False):
    """
    Compute the quantile of the input along the specified axis.

    Args:
    Args:
        x (Tensor): The input Tensor, it's data type can be float32, float64.
        q (int|float|list): The q for calculate quantile, which should be in range [0, 1]. If q is a list,
            each q will be calculated and the first dimension of output is same to the number of ``q`` .
        axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is a list, quantile is calculated over all elements of given axises.
            If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        ignore_nan: (bool, optional): Whether to ignore NaN of input Tensor.
            If ``ignore_nan`` is True, it will calculate nanquantile.
            Otherwise it will calculate quantile. Default is False.

    Returns:
        Tensor, results of quantile along ``axis`` of ``x``.
        In order to obtain higher precision, data type of results will be float64.
    """
    # Validate x
    if not isinstance(x, Variable):
        raise TypeError("input x should be a Tensor.")

    # Validate q
    if isinstance(q, (int, float)):
        q = [q]
    elif isinstance(q, (list, tuple)):
        if len(q) <= 0:
            raise ValueError("q should not be empty")
    else:
        raise TypeError("Type of q should be int, float, list or tuple.")

    # Validate axis
    dims = len(x.shape)
    out_shape = list(x.shape)
    if axis is None:
        x = paddle.flatten(x)
        axis = 0
        out_shape = [1] * dims
    else:
        if isinstance(axis, list):
            if len(axis) <= 0:
                raise ValueError("axis should not be empty")
            axis_src, axis_dst = [], []
            for axis_single in axis:
                if not isinstance(axis_single, int) or not (
                        axis_single < dims and axis_single >= -dims):
                    raise ValueError(
                        "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))."
                    )
                if axis_single < 0:
                    axis_single = axis_single + dims
                axis_src.append(axis_single)
                out_shape[axis_single] = 1
            axis_dst = list(range(-len(axis), 0))
            x = paddle.moveaxis(x, axis_src, axis_dst)
            x = paddle.flatten(x, axis_dst[0], axis_dst[-1])
            axis = axis_dst[0]
        else:
            if not isinstance(axis, int) or not (axis < dims and axis >= -dims):
                raise ValueError(
                    "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))."
                )
            if axis < 0:
                axis += dims
            out_shape[axis] = 1

    mask = x.isnan()
    valid_counts = mask.logical_not().sum(axis=axis,
                                          keepdim=True,
                                          dtype='float64')

    indices = []

    for q_num in q:
        if q_num < 0 or q_num > 1:
            raise ValueError("q should be in range [0, 1]")
        if paddle.in_dynamic_mode():
            q_num = paddle.to_tensor(q_num, dtype='float64')
        if ignore_nan:
            indices.append(q_num * (valid_counts - 1))
        else:
            # TODO(Asthestarsfalll): Use paddle.index_fill instead of where
            index = q_num * (valid_counts - 1)
            last_index = x.shape[axis] - 1
            nums = paddle.full_like(index, fill_value=last_index)
            index = paddle.where(mask.any(axis=axis, keepdim=True), nums, index)
            indices.append(index)

    sorted_tensor = paddle.sort(x, axis)

    outputs = []

    # TODO(chenjianye): replace the for-loop to directly take elements.
    for index in indices:
        indices_below = paddle.floor(index).astype(paddle.int32)
        indices_upper = paddle.ceil(index).astype(paddle.int32)
        tensor_upper = paddle.take_along_axis(
            sorted_tensor, indices_upper, axis=axis)
        tensor_below = paddle.take_along_axis(
            sorted_tensor, indices_below, axis=axis)
        weights = (index - indices_below.astype('float64'))
        out = paddle.lerp(
            tensor_below.astype('float64'),
            tensor_upper.astype('float64'), weights)
        if not keepdim:
            out = paddle.squeeze(out, axis=axis)
        else:
            out = out.reshape(out_shape)
        outputs.append(out)

    if len(q) > 1:
        outputs = paddle.stack(outputs, 0)
    else:
        outputs = outputs[0]

    return outputs
Ejemplo n.º 4
0
def quantile(x, q, axis=None, keepdim=False):
    """
    Compute the quantile of the input along the specified axis.

    Args:
        x (Tensor): The input Tensor, it's data type can be float32, float64.
        q (int|float|list): The q for calculate quantile, which should be in range [0, 1]. If q is a list, 
            each q will be calculated and the first dimension of output is same to the number of ``q`` .
        axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int.
            ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` .
            If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
            If ``axis`` is a list, quantile is calculated over all elements of given axises.
            If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None.
        keepdim (bool, optional): Whether to reserve the reduced dimension(s)
            in the output Tensor. If ``keepdim`` is True, the dimensions of
            the output Tensor is the same as ``x`` except in the reduced
            dimensions(it is of size 1 in this case). Otherwise, the shape of
            the output Tensor is squeezed in ``axis`` . Default is False.
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, results of quantile along ``axis`` of ``x``. If data type of ``x`` is float64, data type of results will be float64, otherwise data type will be float32.

    Examples:
        .. code-block:: python

            import paddle

            x = paddle.randn((2,3))
            #[[-1.28740597,  0.49533170, -1.00698614],
            # [-1.11656201, -1.01010525, -2.23457789]])

            y1 = paddle.quantile(x, q=0.5, axis=[0, 1])
            # y1 = -1.06333363

            y2 = paddle.quantile(x, q=0.5, axis=1)
            # y2 = [-1.00698614, -1.11656201]

            y3 = paddle.quantile(x, q=[0.3, 0.5], axis=1)
            # y3 =[[-1.11915410, -1.56376839],
            #      [-1.00698614, -1.11656201]]

            y4 = paddle.quantile(x, q=0.8, axis=1, keepdim=True)
            # y4 = [[-0.10559537],
            #       [-1.05268800]])
    """
    if not isinstance(x, Variable):
        raise TypeError("input x should be a Tensor.")
    dims = len(x.shape)
    out_shape = x.shape
    if axis is None:
        x = paddle.flatten(x)
        axis = 0
        out_shape = [1] * dims
    else:
        if isinstance(axis, list):
            if (len(axis) <= 0):
                raise ValueError("axis should not be empty")
            axis_src, axis_dst = [], []
            for axis_single in axis:
                if not isinstance(axis_single, int) or not (
                        axis_single < dims and axis_single >= -dims):
                    raise ValueError(
                        "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))."
                    )
                if axis_single < 0:
                    axis_single = axis_single + dims
                axis_src.append(axis_single)
                out_shape[axis_single] = 1
            axis_dst = list(range(-len(axis), 0))
            x = paddle.moveaxis(x, axis_src, axis_dst)
            x = paddle.flatten(x, axis_dst[0], axis_dst[-1])
            axis = axis_dst[0]
        else:
            if not isinstance(axis, int) or not (axis < dims and axis >= -dims):
                raise ValueError(
                    "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))."
                )
            if axis < 0:
                axis += dims
            out_shape[axis] = 1
    indices = []
    if isinstance(q, (int, float)):
        if q < 0 or q > 1:
            raise ValueError("q should be in range [0, 1]")
        indices.append(q * (x.shape[axis] - 1))
    elif isinstance(q, (list, tuple)):
        if len(q) <= 0:
            raise ValueError("q should not be empty")
        for q_num in q:
            if q_num < 0 or q_num > 1:
                raise ValueError("q should be in range [0, 1]")
            indices.append(q_num * (x.shape[axis] - 1))
    else:
        raise TypeError("Type of q should be int, float, list or tuple.")
    indices = paddle.to_tensor(indices).astype(paddle.float32)
    sorted_tensor = paddle.sort(x, axis)
    indices_below = paddle.floor(indices).astype(paddle.int32)
    indices_upper = paddle.ceil(indices).astype(paddle.int32)
    outputs = []

    # TODO(chenjianye): replace the for-loop to directly take elements.
    for i in range(len(indices)):
        if (indices_upper[i] != indices_below[i]):
            tensor_below = paddle.take_along_axis(sorted_tensor,
                                                  indices_below[i], axis)
            tensor_upper = paddle.take_along_axis(sorted_tensor,
                                                  indices_upper[i], axis)
            weights = (indices[i] - indices_below[i]).astype(x.dtype)
            out = paddle.lerp(tensor_below, tensor_upper, weights)
        else:
            out = paddle.take_along_axis(sorted_tensor, indices_below[i], axis)
        if not keepdim:
            out = paddle.squeeze(out, axis=axis)
        else:
            out = out.reshape(out_shape)
        outputs.append(out)
    if isinstance(q, (list, tuple)):
        return paddle.stack(outputs, 0)
    else:
        return outputs[0]