def _compute_array_shapes(a, s, axes, inverse, real):
    """Given a passed in array ``a``, and the rest of the arguments
    (that have been fleshed out with
    :func:`~pyfftw.builders._utils._cook_nd_args`), compute
    the shape the input and output arrays need to be in order
    to satisfy all the requirements for the transform. The input
    shape *may* be different to the shape of a.

    returns:
    ``(input_shape, output_shape)``
    """
    orig_domain_shape = list(a.shape)
    fft_domain_shape = list(a.shape)
    try:
        for n, axis in enumerate(axes):
            orig_domain_shape[axis] = s[n]
            fft_domain_shape[axis] = s[n]
        if real:
            fft_domain_shape[axes[-1]] = s[-1] // 2 + 1
    except IndexError:
        raise IndexError(
            'Invalid axes: At least one of the passed axes is invalid.')
    if inverse:
        input_shape = fft_domain_shape
        output_shape = orig_domain_shape
    else:
        input_shape = orig_domain_shape
        output_shape = fft_domain_shape
    return tuple(input_shape), tuple(output_shape)
