def math(data, operator=None, operator_name=None, axis=None):
    if operator is not None and operator_name is not None:
        raise TypeError('Parameters "operator" and "operator_name" are '
                        'mutually exclusive')
    if operator_name is not None:
        if isinstance(operator_name, str):
            operator_name = (operator_name, )
        operators = []
        for one_operator_name in operator_name:
            operators.append(eval(one_operator_name))
        operator = tuple(operators)
    if callable(operator):
        operator = (operator, )
    operations = []
    for one_operator in operator:
        on_axis = False
        keepdims = True
        try:
            args = getfullargspec(one_operator).args
        except TypeError:
            lg.debug('func ' + str(one_operator) + ' is not a Python '
                     'function')
        else:
            if 'axis' in args:
                on_axis = True
                if axis is None:
                    raise TypeError('You need to specify an axis if you '
                                    'use ' + one_operator.__name__ +
                                    ' (which applies to an axis)')
            if 'keepdims' in args or one_operator in NOKEEPDIM:
                keepdims = False
        operations.append({'name': one_operator.__name__,
                           'func': one_operator,
                           'on_axis': on_axis,
                           'keepdims': keepdims,
                           })
    output = data._copy()
    if axis is not None:
        idx_axis = data.index_of(axis)
    first_op = True
    for op in operations:
        func = op['func']
        if func == mode:
            func = lambda x, axis: mode(x, axis=axis)[0]
        for i in range(output.number_of('trial')):
            if first_op:
                x = data(trial=i)
            else:
                x = output(trial=i)
            if op['on_axis']:
                lg.debug('running ' + op['name'] + ' on ' + str(idx_axis))
                try:
                    if func == diff:
                        lg.debug('Diff has one-point of zero padding')
                        x = _pad_one_axis_one_value(x, idx_axis)
                    output.data[i] = func(x, axis=idx_axis)
                except IndexError:
                    raise ValueError('The axis ' + axis + ' does not '
                                     'exist in [' +
                                     ', '.join(list(data.axis.keys())) + ']')
            else:
                lg.debug('running ' + op['name'] + ' on each datapoint')
                output.data[i] = func(x)
        first_op = False
        if op['on_axis'] and not op['keepdims']:
            del output.axis[axis]
    return output