def pinv(x, rcond=1e-15, hermitian=False, name=None):
    "\n    Calculate pseudo inverse via SVD(singular value decomposition)\n    of one matrix or batches of regular matrix.\n\n    .. math::\n\n        if hermitian == False:\n            x = u * s * vt  (SVD)\n            out = v * 1/s * ut\n        else:\n            x = u * s * ut  (eigh)\n            out = u * 1/s * u.conj().transpose(-2,-1)\n\n    If x is hermitian or symmetric matrix, svd will be replaced with eigh.\n\n    Args:\n        x(Tensor): The input tensor. Its shape should be (*, m, n)\n            where * is zero or more batch dimensions. m and n can be\n            arbitraty positive number. The data type of x should be\n            float32 or float64 or complex64 or complex128. When data\n            type is complex64 or cpmplex128, hermitian should be set\n            True.\n\n        rcond(Tensor, optional): the tolerance value to determine\n            when is a singular value zero. Defalut:1e-15.\n\n        hermitian(bool, optional): indicates whether x is Hermitian\n            if complex or symmetric if real. Default: False.\n\n        name(str|None): A name for this layer(optional). If set None,\n            the layer will be named automatically.\n\n    Returns:\n        Tensor: The tensor with same data type with x. it represents\n        pseudo inverse of x. Its shape should be (*, n, m).\n\n    Examples:\n        .. code-block:: python\n\n            import paddle\n\n            x = paddle.arange(15).reshape((3, 5)).astype('float64')\n            input = paddle.to_tensor(x)\n            out = paddle.linalg.pinv(input)\n            print(input)\n            print(out)\n\n            # input:\n            # [[0. , 1. , 2. , 3. , 4. ],\n            # [5. , 6. , 7. , 8. , 9. ],\n            # [10., 11., 12., 13., 14.]]\n\n            # out:\n            # [[-0.22666667, -0.06666667,  0.09333333],\n            # [-0.12333333, -0.03333333,  0.05666667],\n            # [-0.02000000,  0.00000000,  0.02000000],\n            # [ 0.08333333,  0.03333333, -0.01666667],\n            # [ 0.18666667,  0.06666667, -0.05333333]]\n\n            # one can verify : x * out * x = x ;\n            # or              out * x * out = x ;\n    "
    if paddle.in_dynamic_mode():
        if (not hermitian):
            (u, s, vt) = _C_ops.svd(x, 'full_matrices', False)
            max_singular_val = _C_ops.reduce_max(s, 'dim', [(- 1)], 'keep_dim', True, 'reduce_all', False)
            rcond = paddle.to_tensor(rcond, dtype=x.dtype)
            cutoff = (rcond * max_singular_val)
            y = float('inf')
            y = paddle.to_tensor(y, dtype=x.dtype)
            condition = (s > cutoff)
            cond_int = layers.cast(condition, s.dtype)
            cond_not_int = layers.cast(layers.logical_not(condition), s.dtype)
            out1 = layers.elementwise_mul((1 / s), cond_int)
            out2 = layers.elementwise_mul((1 / y), cond_not_int)
            singular = layers.elementwise_add(out1, out2)
            (st, _) = _C_ops.unsqueeze2(singular, 'axes', [(- 2)])
            dims = list(range(len(vt.shape)))
            perm = ((dims[:(- 2)] + [dims[(- 1)]]) + [dims[(- 2)]])
            (v, _) = _C_ops.transpose2(vt, 'axis', perm)
            out_1 = (v * st)
            out_2 = _C_ops.matmul_v2(out_1, u, 'trans_x', False, 'trans_y', True)
            return out_2
        else:
            (s, u) = _C_ops.eigh(x, 'UPLO', 'L')
            s_abs = paddle.abs(s)
            max_singular_val = _C_ops.reduce_max(s_abs, 'dim', [(- 1)], 'keep_dim', True, 'reduce_all', False)
            rcond = paddle.to_tensor(rcond, dtype=s.dtype)
            cutoff = (rcond * max_singular_val)
            y = float('inf')
            y = paddle.to_tensor(y, dtype=s.dtype)
            condition = (s_abs > cutoff)
            cond_int = layers.cast(condition, s.dtype)
            cond_not_int = layers.cast(layers.logical_not(condition), s.dtype)
            out1 = layers.elementwise_mul((1 / s), cond_int)
            out2 = layers.elementwise_mul((1 / y), cond_not_int)
            singular = layers.elementwise_add(out1, out2)
            (st, _) = _C_ops.unsqueeze2(singular, 'axes', [(- 2)])
            out_1 = (u * st)
            u_conj = _C_ops.conj(u)
            out_2 = _C_ops.matmul_v2(out_1, u_conj, 'trans_x', False, 'trans_y', True)
            return out_2
    elif (not hermitian):
        helper = LayerHelper('pinv', **locals())
        dtype = x.dtype
        check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pinv')
        u = helper.create_variable_for_type_inference(dtype)
        s = helper.create_variable_for_type_inference(dtype)
        vt = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='svd', inputs={'X': [x]}, outputs={'U': u, 'VH': vt, 'S': s}, attrs={'full_matrices': False})
        max_singular_val = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='reduce_max', inputs={'X': s}, outputs={'Out': max_singular_val}, attrs={'dim': [(- 1)], 'keep_dim': True, 'reduce_all': False})
        rcond = layers.fill_constant(shape=[1], value=rcond, dtype=dtype)
        cutoff = (rcond * max_singular_val)
        y = float('inf')
        y = layers.fill_constant(shape=[1], value=y, dtype=dtype)
        condition = (s > cutoff)
        cond_int = layers.cast(condition, dtype)
        cond_not_int = layers.cast(layers.logical_not(condition), dtype)
        out1 = layers.elementwise_mul((1 / s), cond_int)
        out2 = layers.elementwise_mul((1 / y), cond_not_int)
        singular = layers.elementwise_add(out1, out2)
        st = helper.create_variable_for_type_inference(dtype=dtype)
        st_shape = helper.create_variable_for_type_inference(dtype=dtype)
        helper.append_op(type='unsqueeze2', inputs={'X': singular}, attrs={'axes': [(- 2)]}, outputs={'Out': st, 'XShape': st_shape})
        dims = list(range(len(vt.shape)))
        perm = ((dims[:(- 2)] + [dims[(- 1)]]) + [dims[(- 2)]])
        v = helper.create_variable_for_type_inference(dtype)
        v_shape = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='transpose2', inputs={'X': [vt]}, outputs={'Out': [v], 'XShape': [v_shape]}, attrs={'axis': perm})
        out_1 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='elementwise_mul', inputs={'X': v, 'Y': st}, outputs={'Out': out_1}, attrs={'axis': (- 1), 'use_mkldnn': False})
        out_1 = helper.append_activation(out_1)
        out_2 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='matmul_v2', inputs={'X': out_1, 'Y': u}, outputs={'Out': out_2}, attrs={'trans_x': False, 'trans_y': True})
        return out_2
    else:
        helper = LayerHelper('pinv', **locals())
        dtype = x.dtype
        check_variable_and_dtype(x, 'dtype', ['float32', 'float64', 'complex64', 'complex128'], 'pinv')
        if (dtype == paddle.complex128):
            s_type = 'float64'
        elif (dtype == paddle.complex64):
            s_type = 'float32'
        else:
            s_type = dtype
        u = helper.create_variable_for_type_inference(dtype)
        s = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='eigh', inputs={'X': x}, outputs={'Eigenvalues': s, 'Eigenvectors': u}, attrs={'UPLO': 'L'})
        s_abs = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='abs', inputs={'X': s}, outputs={'Out': s_abs})
        max_singular_val = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='reduce_max', inputs={'X': s_abs}, outputs={'Out': max_singular_val}, attrs={'dim': [(- 1)], 'keep_dim': True, 'reduce_all': False})
        rcond = layers.fill_constant(shape=[1], value=rcond, dtype=s_type)
        cutoff = (rcond * max_singular_val)
        y = float('inf')
        y = layers.fill_constant(shape=[1], value=y, dtype=s_type)
        condition = (s_abs > cutoff)
        cond_int = layers.cast(condition, s_type)
        cond_not_int = layers.cast(layers.logical_not(condition), s_type)
        out1 = layers.elementwise_mul((1 / s), cond_int)
        out2 = layers.elementwise_mul((1 / y), cond_not_int)
        singular = layers.elementwise_add(out1, out2)
        st = helper.create_variable_for_type_inference(dtype=s_type)
        st_shape = helper.create_variable_for_type_inference(dtype=s_type)
        helper.append_op(type='unsqueeze2', inputs={'X': singular}, attrs={'axes': [(- 2)]}, outputs={'Out': st, 'XShape': st_shape})
        out_1 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='elementwise_mul', inputs={'X': u, 'Y': st}, outputs={'Out': out_1}, attrs={'axis': (- 1), 'use_mkldnn': False})
        out_1 = helper.append_activation(out_1)
        u_conj = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='conj', inputs={'X': u}, outputs={'Out': [u_conj]})
        out_2 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='matmul_v2', inputs={'X': out_1, 'Y': u_conj}, outputs={'Out': out_2}, attrs={'trans_x': False, 'trans_y': True})
        return out_2
Calculate pseudo inverse via SVD(singular value decomposition)
of one matrix or batches of regular matrix.

.. math::

    if hermitian == False:
        x = u * s * vt  (SVD)
        out = v * 1/s * ut
    else:
        x = u * s * ut  (eigh)
        out = u * 1/s * u.conj().transpose(-2,-1)

If x is hermitian or symmetric matrix, svd will be replaced with eigh.

Args:
    x(Tensor): The input tensor. Its shape should be (*, m, n)
        where * is zero or more batch dimensions. m and n can be
        arbitraty positive number. The data type of x should be
        float32 or float64 or complex64 or complex128. When data
        type is complex64 or cpmplex128, hermitian should be set
        True.

    rcond(Tensor, optional): the tolerance value to determine
        when is a singular value zero. Defalut:1e-15.

    hermitian(bool, optional): indicates whether x is Hermitian
        if complex or symmetric if real. Default: False.

    name(str|None): A name for this layer(optional). If set None,
        the layer will be named automatically.

Returns:
    Tensor: The tensor with same data type with x. it represents
    pseudo inverse of x. Its shape should be (*, n, m).

Examples:
    .. code-block:: python

        import paddle

        x = paddle.arange(15).reshape((3, 5)).astype('float64')
        input = paddle.to_tensor(x)
        out = paddle.linalg.pinv(input)
        print(input)
        print(out)

        # input:
        # [[0. , 1. , 2. , 3. , 4. ],
        # [5. , 6. , 7. , 8. , 9. ],
        # [10., 11., 12., 13., 14.]]

        # out:
        # [[-0.22666667, -0.06666667,  0.09333333],
        # [-0.12333333, -0.03333333,  0.05666667],
        # [-0.02000000,  0.00000000,  0.02000000],
        # [ 0.08333333,  0.03333333, -0.01666667],
        # [ 0.18666667,  0.06666667, -0.05333333]]

        # one can verify : x * out * x = x ;
        # or              out * x * out = x ;
def pinv(x, rcond=1e-15, hermitian=False, name=None):
    "\n    Calculate pseudo inverse via SVD(singular value decomposition)\n    of one matrix or batches of regular matrix.\n\n    .. math::\n\n        if hermitian == False:\n            x = u * s * vt  (SVD)\n            out = v * 1/s * ut\n        else:\n            x = u * s * ut  (eigh)\n            out = u * 1/s * u.conj().transpose(-2,-1)\n\n    If x is hermitian or symmetric matrix, svd will be replaced with eigh.\n\n    Args:\n        x(Tensor): The input tensor. Its shape should be (*, m, n)\n            where * is zero or more batch dimensions. m and n can be\n            arbitraty positive number. The data type of x should be\n            float32 or float64 or complex64 or complex128. When data\n            type is complex64 or cpmplex128, hermitian should be set\n            True.\n\n        rcond(Tensor, optional): the tolerance value to determine\n            when is a singular value zero. Defalut:1e-15.\n\n        hermitian(bool, optional): indicates whether x is Hermitian\n            if complex or symmetric if real. Default: False.\n\n        name(str|None): A name for this layer(optional). If set None,\n            the layer will be named automatically.\n\n    Returns:\n        Tensor: The tensor with same data type with x. it represents\n        pseudo inverse of x. Its shape should be (*, n, m).\n\n    Examples:\n        .. code-block:: python\n\n            import paddle\n\n            x = paddle.arange(15).reshape((3, 5)).astype('float64')\n            input = paddle.to_tensor(x)\n            out = paddle.linalg.pinv(input)\n            print(input)\n            print(out)\n\n            # input:\n            # [[0. , 1. , 2. , 3. , 4. ],\n            # [5. , 6. , 7. , 8. , 9. ],\n            # [10., 11., 12., 13., 14.]]\n\n            # out:\n            # [[-0.22666667, -0.06666667,  0.09333333],\n            # [-0.12333333, -0.03333333,  0.05666667],\n            # [-0.02000000,  0.00000000,  0.02000000],\n            # [ 0.08333333,  0.03333333, -0.01666667],\n            # [ 0.18666667,  0.06666667, -0.05333333]]\n\n            # one can verify : x * out * x = x ;\n            # or              out * x * out = x ;\n    "
    if paddle.in_dynamic_mode():
        if (not hermitian):
            (u, s, vt) = _C_ops.svd(x, 'full_matrices', False)
            max_singular_val = _C_ops.reduce_max(s, 'dim', [(- 1)], 'keep_dim', True, 'reduce_all', False)
            rcond = paddle.to_tensor(rcond, dtype=x.dtype)
            cutoff = (rcond * max_singular_val)
            y = float('inf')
            y = paddle.to_tensor(y, dtype=x.dtype)
            condition = (s > cutoff)
            cond_int = layers.cast(condition, s.dtype)
            cond_not_int = layers.cast(layers.logical_not(condition), s.dtype)
            out1 = layers.elementwise_mul((1 / s), cond_int)
            out2 = layers.elementwise_mul((1 / y), cond_not_int)
            singular = layers.elementwise_add(out1, out2)
            (st, _) = _C_ops.unsqueeze2(singular, 'axes', [(- 2)])
            dims = list(range(len(vt.shape)))
            perm = ((dims[:(- 2)] + [dims[(- 1)]]) + [dims[(- 2)]])
            (v, _) = _C_ops.transpose2(vt, 'axis', perm)
            out_1 = (v * st)
            out_2 = _C_ops.matmul_v2(out_1, u, 'trans_x', False, 'trans_y', True)
            return out_2
        else:
            (s, u) = _C_ops.eigh(x, 'UPLO', 'L')
            s_abs = paddle.abs(s)
            max_singular_val = _C_ops.reduce_max(s_abs, 'dim', [(- 1)], 'keep_dim', True, 'reduce_all', False)
            rcond = paddle.to_tensor(rcond, dtype=s.dtype)
            cutoff = (rcond * max_singular_val)
            y = float('inf')
            y = paddle.to_tensor(y, dtype=s.dtype)
            condition = (s_abs > cutoff)
            cond_int = layers.cast(condition, s.dtype)
            cond_not_int = layers.cast(layers.logical_not(condition), s.dtype)
            out1 = layers.elementwise_mul((1 / s), cond_int)
            out2 = layers.elementwise_mul((1 / y), cond_not_int)
            singular = layers.elementwise_add(out1, out2)
            (st, _) = _C_ops.unsqueeze2(singular, 'axes', [(- 2)])
            out_1 = (u * st)
            u_conj = _C_ops.conj(u)
            out_2 = _C_ops.matmul_v2(out_1, u_conj, 'trans_x', False, 'trans_y', True)
            return out_2
    elif (not hermitian):
        helper = LayerHelper('pinv', **locals())
        dtype = x.dtype
        check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pinv')
        u = helper.create_variable_for_type_inference(dtype)
        s = helper.create_variable_for_type_inference(dtype)
        vt = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='svd', inputs={'X': [x]}, outputs={'U': u, 'VH': vt, 'S': s}, attrs={'full_matrices': False})
        max_singular_val = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='reduce_max', inputs={'X': s}, outputs={'Out': max_singular_val}, attrs={'dim': [(- 1)], 'keep_dim': True, 'reduce_all': False})
        rcond = layers.fill_constant(shape=[1], value=rcond, dtype=dtype)
        cutoff = (rcond * max_singular_val)
        y = float('inf')
        y = layers.fill_constant(shape=[1], value=y, dtype=dtype)
        condition = (s > cutoff)
        cond_int = layers.cast(condition, dtype)
        cond_not_int = layers.cast(layers.logical_not(condition), dtype)
        out1 = layers.elementwise_mul((1 / s), cond_int)
        out2 = layers.elementwise_mul((1 / y), cond_not_int)
        singular = layers.elementwise_add(out1, out2)
        st = helper.create_variable_for_type_inference(dtype=dtype)
        st_shape = helper.create_variable_for_type_inference(dtype=dtype)
        helper.append_op(type='unsqueeze2', inputs={'X': singular}, attrs={'axes': [(- 2)]}, outputs={'Out': st, 'XShape': st_shape})
        dims = list(range(len(vt.shape)))
        perm = ((dims[:(- 2)] + [dims[(- 1)]]) + [dims[(- 2)]])
        v = helper.create_variable_for_type_inference(dtype)
        v_shape = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='transpose2', inputs={'X': [vt]}, outputs={'Out': [v], 'XShape': [v_shape]}, attrs={'axis': perm})
        out_1 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='elementwise_mul', inputs={'X': v, 'Y': st}, outputs={'Out': out_1}, attrs={'axis': (- 1), 'use_mkldnn': False})
        out_1 = helper.append_activation(out_1)
        out_2 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='matmul_v2', inputs={'X': out_1, 'Y': u}, outputs={'Out': out_2}, attrs={'trans_x': False, 'trans_y': True})
        return out_2
    else:
        helper = LayerHelper('pinv', **locals())
        dtype = x.dtype
        check_variable_and_dtype(x, 'dtype', ['float32', 'float64', 'complex64', 'complex128'], 'pinv')
        if (dtype == paddle.complex128):
            s_type = 'float64'
        elif (dtype == paddle.complex64):
            s_type = 'float32'
        else:
            s_type = dtype
        u = helper.create_variable_for_type_inference(dtype)
        s = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='eigh', inputs={'X': x}, outputs={'Eigenvalues': s, 'Eigenvectors': u}, attrs={'UPLO': 'L'})
        s_abs = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='abs', inputs={'X': s}, outputs={'Out': s_abs})
        max_singular_val = helper.create_variable_for_type_inference(s_type)
        helper.append_op(type='reduce_max', inputs={'X': s_abs}, outputs={'Out': max_singular_val}, attrs={'dim': [(- 1)], 'keep_dim': True, 'reduce_all': False})
        rcond = layers.fill_constant(shape=[1], value=rcond, dtype=s_type)
        cutoff = (rcond * max_singular_val)
        y = float('inf')
        y = layers.fill_constant(shape=[1], value=y, dtype=s_type)
        condition = (s_abs > cutoff)
        cond_int = layers.cast(condition, s_type)
        cond_not_int = layers.cast(layers.logical_not(condition), s_type)
        out1 = layers.elementwise_mul((1 / s), cond_int)
        out2 = layers.elementwise_mul((1 / y), cond_not_int)
        singular = layers.elementwise_add(out1, out2)
        st = helper.create_variable_for_type_inference(dtype=s_type)
        st_shape = helper.create_variable_for_type_inference(dtype=s_type)
        helper.append_op(type='unsqueeze2', inputs={'X': singular}, attrs={'axes': [(- 2)]}, outputs={'Out': st, 'XShape': st_shape})
        out_1 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='elementwise_mul', inputs={'X': u, 'Y': st}, outputs={'Out': out_1}, attrs={'axis': (- 1), 'use_mkldnn': False})
        out_1 = helper.append_activation(out_1)
        u_conj = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='conj', inputs={'X': u}, outputs={'Out': [u_conj]})
        out_2 = helper.create_variable_for_type_inference(dtype)
        helper.append_op(type='matmul_v2', inputs={'X': out_1, 'Y': u_conj}, outputs={'Out': out_2}, attrs={'trans_x': False, 'trans_y': True})
        return out_2