# numpy imports.
import numpy as np


def broadcast_arrays(*args):
    """ Broadcast arrays to a common shape according to the ufunc rules.

    Parameters
    ----------
    *args : arrays

    Returns
    -------
    arrays : list of arrays
        The arrays will be broadcasted versions of the corresponding input
        arrays.

    Example
    -------
    In [57]: a = array([3, 6, 7])

    In [58]: b = array([[1], [4]])

    In [60]: broadcast_arrays(a, b)
    Out[60]: 
    [array([[3, 6, 7],
           [3, 6, 7]]), array([[1, 1, 1],
           [4, 4, 4]])]
    """

    # Ensure that each argument is an array.
    args = map(np.asarray, args)

    # Get index arrays for each array.
    index_arrays = [np.arange(array.size).reshape(array.shape) 
        for array in args]

    # Get the broadcast over the index arrays.
    broadcast_iter = np.broadcast(*index_arrays)

    # Extract the broadcast indices.
    broadcasted_indices = np.transpose(list(broadcast_iter))

    arrays = []
    for indices, array in zip(broadcasted_indices, args):
        new_array = array.flat[indices]
        new_array.shape = broadcast_iter.shape
        arrays.append(new_array)

    return arrays


#### EOF #######################################################################
