def map2cube(data_map, layout):
    r"""Map to cube

    This method transforms the input data from a 2D map with given layout to
    a 3D cube

    Parameters
    ----------
    data_map : np.ndarray
        Input data map, 2D array
    layout : tuple
        2D layout of 2D images

    Returns
    -------
    np.ndarray 3D cube

    Raises
    ------
    ValueError
        For invalid layout

    Examples
    --------
    >>> from modopt.base.transform import map2cube
    >>> a = np.array([[0, 1, 4, 5], [2, 3, 6, 7], [8, 9, 12, 13],
    [10, 11, 14, 15]])
    >>> map2cube(a, (2, 2))
    array([[[ 0,  1],
            [ 2,  3]],

           [[ 4,  5],
            [ 6,  7]],

           [[ 8,  9],
            [10, 11]],

           [[12, 13],
            [14, 15]]])

    """

    if np.all(np.array(data_map.shape) % np.array(layout)):
        raise ValueError('The desired layout must be a multiple of the number '
                         'pixels in the data map.')

    d_shape = np.array(data_map.shape) // np.array(layout)

    return np.array([data_map[(slice(i * d_shape[0], (i + 1) * d_shape[0]),
                    slice(j * d_shape[1], (j + 1) * d_shape[1]))] for i in
                    range(layout[0]) for j in range(layout[1])])
r"""Map to cube

    This method transforms the input data from a 2D map with given layout to
    a 3D cube

    Parameters
    ----------
    data_map : np.ndarray
        Input data map, 2D array
    layout : tuple
        2D layout of 2D images

    Returns
    -------
    np.ndarray 3D cube

    Raises
    ------
    ValueError
        For invalid layout

    Examples
    --------
    >>> from modopt.base.transform import map2cube
    >>> a = np.array([[0, 1, 4, 5], [2, 3, 6, 7], [8, 9, 12, 13],
    [10, 11, 14, 15]])
    >>> map2cube(a, (2, 2))
    array([[[ 0,  1],
            [ 2,  3]],

           [[ 4,  5],
            [ 6,  7]],

           [[ 8,  9],
            [10, 11]],

           [[12, 13],
            [14, 15]]])