'This subroutine checks that all parameter arrays can be broadcast
against each other, and determines the shapes parameters must have in
order to broadcast correctly.
If model_set_axis is None this merely checks that the parameters
broadcast and returns an empty dict if so.  This mode is only used for
single model sets.'

def _check_param_broadcast(self, params, max_ndim):

    all_shapes = []
    param_names = []
    model_set_axis = self._model_set_axis
    for name in self.param_names:
        if (name not in params):
            continue
        value = params[name]
        param_names.append(name)
        param_shape = np.shape(value)
        param_ndim = len(param_shape)
        if ((max_ndim is not None) and (param_ndim < max_ndim)):
            new_axes = ((1,) * (max_ndim - param_ndim))
            if (model_set_axis < 0):
                broadcast_shape = (new_axes + param_shape)
            else:
                broadcast_shape = ((param_shape[:(model_set_axis + 1)] + new_axes) + param_shape[(model_set_axis + 1):])
            self._param_metrics[name][u'broadcast_shape'] = broadcast_shape
            all_shapes.append(broadcast_shape)
        else:
            all_shapes.append(param_shape)
    try:
        check_broadcast(*all_shapes)
    except IncompatibleShapeError as exc:
        (shape_a, shape_a_idx, shape_b, shape_b_idx) = exc.args
        param_a = param_names[shape_a_idx]
        param_b = param_names[shape_b_idx]
        raise InputParameterError(u'Parameter    {0!r}    of    shape    {1!r}    cannot    be    broadcast    with    parameter    {2!r}    of    shape    {3!r}.        All    parameter    arrays    must    have    shapes    that    are    mutually    compatible    according    to    the    broadcasting    rules.'.format(param_a, shape_a, param_b, shape_b))
