# Buggy code
def _get_unitary_matrix(self, unitary):
    """Return the matrix representing a unitary operation.

    Args:
        unitary (~.Operation): a PennyLane unitary operation

    Returns:
        tf.Tensor[complex] or array[complex]: Returns a 2D matrix representation of
        the unitary in the computational basis, or, in the case of a diagonal unitary,
        a 1D array representing the matrix diagonal. For non-parametric unitaries,
        the return type will be a ``np.ndarray``. For parametric unitaries, a ``tf.Tensor``
        object will be returned.
    """
    if unitary.name in self.parametric_ops:
        if unitary.name == "MultiRZ":
            return self.parametric_ops[unitary.name](
                unitary.parameters, len(unitary.wires)
            )
        return self.parametric_ops[unitary.name](*unitary.parameters)

    if isinstance(unitary, DiagonalOperation):
        return unitary.eigvals

    return unitary.matrix


# Traceback (TypeError)
import pennylane as qml
dev = qml.device('default.qubit', wires=2)
@qml.qnode(dev)
... def circuit(x):
...     qml.RZ(x, wires=1).inv()
...     return qml.expval(qml.PauliZ(0))
...
circuit(0)
tensor(1., requires_grad=True)
opt = qml.GradientDescentOptimizer(0.1)
x0 = 0.5
opt.step(circuit, x0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/optimize/gradient_descent.py", line 98, in step
g, _ = self.compute_grad(objective_fn, args, kwargs, grad_fn=grad_fn)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/optimize/gradient_descent.py", line 127, in compute_grad
grad = g(*args, **kwargs)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/_grad.py", line 96, in __call__
grad_value, ans = self._get_grad_fn(args)(*args, **kwargs)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/autograd/wrap_util.py", line 20, in nary_f
return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/_grad.py", line 113, in _grad_with_forward
vjp, ans = _make_vjp(fun, x)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/autograd/core.py", line 10, in make_vjp
end_value, end_node =  trace(start_node, fun, x)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/autograd/tracer.py", line 10, in trace
end_box = fun(start_box)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/autograd/wrap_util.py", line 15, in unary_f
return fun(*subargs, **kwargs)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/tape/qnode.py", line 521, in __call__
res = self.qtape.execute(device=self.device)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/tape/tapes/tape.py", line 1070, in execute
return self._execute(params, device=device)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/tape/tapes/tape.py", line 1101, in execute_device
res = device.execute(self)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/_qubit_device.py", line 204, in execute
self.apply(circuit.operations, rotations=circuit.diagonalizing_gates, **kwargs)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit.py", line 188, in apply
self._state = self._apply_operation(self._state, operation)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit.py", line 213, in _apply_operation
matrix = self._get_unitary_matrix(operation)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit_autograd.py", line 167, in _get_unitary_matrix
return unitary.eigvals
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/operation.py", line 878, in eigvals
return super().eigvals
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/operation.py", line 753, in eigvals
op_eigvals = self._eigvals(*self.parameters)
File "/home/nathan/anaconda3/lib/python3.7/site-packages/pennylane/ops/qubit.py", line 678, in _eigvals
p = cmath.exp(-0.5j * theta)
TypeError: must be real number, not ArrayBox

# Fixed code
def _get_unitary_matrix(self, unitary):
    """Return the matrix representing a unitary operation.

    Args:
        unitary (~.Operation): a PennyLane unitary operation

    Returns:
        tf.Tensor[complex] or array[complex]: Returns a 2D matrix representation of
        the unitary in the computational basis, or, in the case of a diagonal unitary,
        a 1D array representing the matrix diagonal. For non-parametric unitaries,
        the return type will be a ``np.ndarray``. For parametric unitaries, a ``tf.Tensor``
        object will be returned.
    """
    op_name = unitary.name.split(".inv")[0]

    if op_name in self.parametric_ops:
        if op_name == "MultiRZ":
            mat = self.parametric_ops[op_name](*unitary.parameters, len(unitary.wires))
        else:
            mat = self.parametric_ops[op_name](*unitary.parameters)

        if unitary.inverse:
            mat = self._transpose(self._conj(mat))

        return mat

    if isinstance(unitary, DiagonalOperation):
        return unitary.eigvals

    return unitary.matrix