def fede_voltage_update(v_cur, v_rest, v_in, alpha_v, tau_v, dt,
    refrac_counts, pre_trace):
    """Calculate change in cell's voltage based on current voltage and input trace.

    Defined in "Unsupervised Learning of a Hierarchical Spiking Neural Network for Optical Flow Estimation: From Events to Global Motion Perception" - F. Paredes-Valles, et al.

    Voltage updates are performed according to the following formula:
    
    .. math::

        voltage_{t+1} = voltage_{t} + \\frac{(-(voltage_{t} - rest_{t}) + alpha * (incoming_{t} - pretrace_{t})) * dt}{tau}

    :param v_cur: Current voltages
    :param v_rest: Resting voltages
    :param v_in: Incoming voltages
    :param alpha_v: Incoming voltage scaling factor
    :param tau_v: Voltage decay time constant
    :param dt: Duration of single timestep
    :param refrac_counts: Number of timesteps left in refractory state for each :class:`Neuron`
    :param pre_trace: Incoming trace

    :return: New voltages
    """
    forcing = alpha_v * (v_in - pre_trace).sum(-1)
    v_delta = dt / tau_v * (-(v_cur - v_rest) + forcing)
    non_refrac = refrac_counts == 0
    v_cur += v_delta * non_refrac.to(v_delta.dtype)
    return v_cur
