def broadcast_rule(shape_a, shape_b):
    'Return output shape of broadcast shape_a, shape_b.\n    e.g. broadcast_rule((3,2), (4,3,2))\n    returns output_shape = (4,3,2)\n\n    Check out explanations and more examples at\n    https://docs.scipy.org/doc/numpy-1.10.0/user/basics.broadcasting.html\n    http://eli.thegreenplace.net/2015/broadcasting-arrays-in-numpy/\n    '
    assert isinstance(shape_a, tuple)
    assert isinstance(shape_b, tuple)
    if (len(shape_a) > len(shape_b)):
        (longer_shape, shorter_shape) = (shape_a, shape_b)
    else:
        (longer_shape, shorter_shape) = (shape_b, shape_a)
    len_diff = (len(longer_shape) - len(shorter_shape))
    for i in range(len_diff):
        shorter_shape = ((1,) + shorter_shape)
    assert (len(shorter_shape) == len(longer_shape))
    output_shape = list(longer_shape)
    for i in range(len(output_shape)):
        assert ((shorter_shape[i] == longer_shape[i]) or (shorter_shape[i] == 1) or (longer_shape[i] == 1))
        output_shape[i] = max(shorter_shape[i], longer_shape[i])
    return tuple(output_shape)
Return output shape of broadcast shape_a, shape_b.
e.g. broadcast_rule((3,2), (4,3,2))
returns output_shape = (4,3,2)

Check out explanations and more examples at
https://docs.scipy.org/doc/numpy-1.10.0/user/basics.broadcasting.html
http://eli.thegreenplace.net/2015/broadcasting-arrays-in-numpy/
def broadcast_rule(shape_a, shape_b):
    'Return output shape of broadcast shape_a, shape_b.\n    e.g. broadcast_rule((3,2), (4,3,2))\n    returns output_shape = (4,3,2)\n\n    Check out explanations and more examples at\n    https://docs.scipy.org/doc/numpy-1.10.0/user/basics.broadcasting.html\n    http://eli.thegreenplace.net/2015/broadcasting-arrays-in-numpy/\n    '
    assert isinstance(shape_a, tuple)
    assert isinstance(shape_b, tuple)
    if (len(shape_a) > len(shape_b)):
        (longer_shape, shorter_shape) = (shape_a, shape_b)
    else:
        (longer_shape, shorter_shape) = (shape_b, shape_a)
    len_diff = (len(longer_shape) - len(shorter_shape))
    for i in range(len_diff):
        shorter_shape = ((1,) + shorter_shape)
    assert (len(shorter_shape) == len(longer_shape))
    output_shape = list(longer_shape)
    for i in range(len(output_shape)):
        assert ((shorter_shape[i] == longer_shape[i]) or (shorter_shape[i] == 1) or (longer_shape[i] == 1))
        output_shape[i] = max(shorter_shape[i], longer_shape[i])
    return tuple(output_shape)