import torch


def boost_activations(x, duty_cycles, boost_strength):
    """
    Boosting as documented in :meth:`kwinners` would compute
      x * torch.exp((target_density - duty_cycles) * boost_strength)
    but instead we compute
      x * torch.exp(-boost_strength * duty_cycles)
    which is equal to the former value times a positive constant, so it will
    have the same ranked order.

    :param x:
      Current activity of each unit.

    :param duty_cycles:
      The averaged duty cycle of each unit.

    :param boost_strength:
      A boost strength of 0.0 has no effect on x.

    :return:
         A tensor representing the boosted activity
    """
    if boost_strength > 0.0:
        return x.detach() * torch.exp(-boost_strength * duty_cycles)
    else:
        return x.detach()