# Buggy code
def _loss(self, x, x_adv, target, c):
    """
    Compute the objective function value.

    :param x: An array with the original input.
    :type x: `np.ndarray`
    :param x_adv: An array with the adversarial input.
    :type x_adv: `np.ndarray`
    :param target: An array with the target class (one-hot encoded).
    :type target: `np.ndarray`
    :param c: Weight of the loss term aiming for classification as target.
    :type c: `float`
    :return: A tuple holding the current logits, l2 distance and overall loss.
    :rtype: `(float, float, float)`
    """
    l2dist = np.sum(np.square(x - x_adv).reshape(x.shape[0], -1), axis=1)
    z = self.classifier.predict(np.array(x_adv, dtype=NUMPY_DTYPE), logits=True)
    z_target = np.sum(z * target, axis=1)
    z_other = np.max(
        z * (1 - target) + (np.min(z, axis=1) - 1)[:, np.newaxis] * target, axis=1
    )

    # The following differs from the exact definition given in Carlini and Wagner (2016). There (page 9, left
    # column, last equation), the maximum is taken over Z_other - Z_target (or Z_target - Z_other respectively)
    # and -confidence. However, it doesn't seem that that would have the desired effect (loss term is <= 0 if and
    # only if the difference between the logit of the target and any other class differs by at least confidence).
    # Hence the rearrangement here.

    if self.targeted:
        # if targeted, optimize for making the target class most likely
        loss = np.maximum(z_other - z_target + self.confidence, np.zeros(x.shape[0]))
    else:
        # if untargeted, optimize for making any other class most likely
        loss = np.maximum(z_target - z_other + self.confidence, np.zeros(x.shape[0]))

    return z, l2dist, c * loss + l2dist


# Traceback (IndexError)
Traceback (most recent call last):
File "cw_pytorch.py", line 172, in <module>
x_test_adv = cl2m.generate(inputs, **params)
File "/home/weitian/anaconda3/envs/xnor/lib/python3.6/site-packages/art/attacks/carlini.py", line 380, in generate
x_adv_batch_tanh[active_and_update_adv] = x_adv_batch_tanh[update_adv] + \
IndexError: boolean index did not match indexed array along dimension 0; dimension is 18 but corresponding boolean dimension is 17

# Fixed code
def _loss(self, x, x_adv, target, c):
    """
    Compute the objective function value.

    :param x: An array with the original input.
    :type x: `np.ndarray`
    :param x_adv: An array with the adversarial input.
    :type x_adv: `np.ndarray`
    :param target: An array with the target class (one-hot encoded).
    :type target: `np.ndarray`
    :param c: Weight of the loss term aiming for classification as target.
    :type c: `float`
    :return: A tuple holding the current logits, l2 distance and overall loss.
    :rtype: `(float, float, float)`
    """
    l2dist = np.sum(np.square(x - x_adv).reshape(x.shape[0], -1), axis=1)
    z = self._predict(np.array(x_adv, dtype=NUMPY_DTYPE), logits=True)
    z_target = np.sum(z * target, axis=1)
    z_other = np.max(
        z * (1 - target) + (np.min(z, axis=1) - 1)[:, np.newaxis] * target, axis=1
    )

    # The following differs from the exact definition given in Carlini and Wagner (2016). There (page 9, left
    # column, last equation), the maximum is taken over Z_other - Z_target (or Z_target - Z_other respectively)
    # and -confidence. However, it doesn't seem that that would have the desired effect (loss term is <= 0 if and
    # only if the difference between the logit of the target and any other class differs by at least confidence).
    # Hence the rearrangement here.

    if self.targeted:
        # if targeted, optimize for making the target class most likely
        loss = np.maximum(z_other - z_target + self.confidence, np.zeros(x.shape[0]))
    else:
        # if untargeted, optimize for making any other class most likely
        loss = np.maximum(z_target - z_other + self.confidence, np.zeros(x.shape[0]))

    return z, l2dist, c * loss + l2dist