Generate trajectories for groups

    Returns an :math:`N(g+1)`-by-:math:`k` array of `N` trajectories,
    where :math:`g` is the number of groups and :math:`k` is the number
    of factors

    Arguments
    ---------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int, default=4
        The number of grid levels

    Returns
    -------
    numpy.ndarray

def _sample_groups(problem, N, num_levels=4):
    """Generate trajectories for groups

    Returns an :math:`N(g+1)`-by-:math:`k` array of `N` trajectories,
    where :math:`g` is the number of groups and :math:`k` is the number
    of factors

    Arguments
    ---------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int, default=4
        The number of grid levels

    Returns
    -------
    numpy.ndarray
    """
    if len(problem['groups']) != problem['num_vars']:
        raise ValueError("Groups do not match to number of variables")

    group_membership, _ = compute_groups_matrix(problem['groups'])

    if group_membership is None:
        raise ValueError("Please define the 'group_membership' matrix")
    if not isinstance(group_membership, np.ndarray):
        raise TypeError("Argument 'group_membership' should be formatted \
                         as a numpy ndarray")

    num_params = group_membership.shape[0]
    num_groups = group_membership.shape[1]
    sample = np.zeros((N * (num_groups + 1), num_params))
    sample = np.array([generate_trajectory(group_membership,
                                           num_levels)
                       for n in range(N)])
    return sample.reshape((N * (num_groups + 1), num_params))