Repository: Qiskit/qiskit

Issue:
Instruction comparison fails when parameters are arrays
### Information

- **Qiskit Terra version**: 0.8.2
- **Python version**: 3.6
- **Operating system**: Linux

### What is the current behavior?
Comparing two instructions that have matrix parameters fails ungracefully with
`ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`

Matrix parameters for instructions are currently generated when converting Aer's errors to instructions. 

### Steps to reproduce the problem
The following code raises this error:

```
from qiskit import QuantumRegister, QuantumCircuit
from qiskit.providers.aer.noise.errors.standard_errors import pauli_error
qr = QuantumRegister(1, 'qr')
circuit = QuantumCircuit(qr)
error = pauli_error([('X', 0.25), ('I', 0.75)])
circuit.append(error.to_instruction(), [qr[0]])
circuit == circuit
```


### What is the expected behavior?
Correct element-by-element comparison of the matrices, using `numpy.isclose` for almost-identical matrices.


### Suggested solutions
[Line 99](https://github.com/Qiskit/qiskit-terra/blob/fae93bc413e5f62b756d58e81d215f1c342bc848/qiskit/circuit/instruction.py#L99
) in instruction.py needs to be modified; it seems type-checking the parameter is needed (maybe `isinstance(self_param, numpy.ndarray?). For Numpy arrays `numpy.equal` and `numpy.isclose` works and returns a boolean array of results, on which `all()` can be used.



Discussion:
This is currently blocking a PR in Aer: https://github.com/Qiskit/qiskit-aer/pull/239

Resolving patch:
diff --git a/qiskit/circuit/instruction.py b/qiskit/circuit/instruction.py
--- a/qiskit/circuit/instruction.py
+++ b/qiskit/circuit/instruction.py
@@ -96,8 +96,19 @@ def __eq__(self, other):
             return False
 
         for self_param, other_param in zip_longest(self.params, other.params):
-            if self_param == other_param:
-                continue
+            try:
+                if self_param == other_param:
+                    continue
+            except ValueError:
+                pass
+
+            try:
+                if numpy.shape(self_param) == numpy.shape(other_param) \
+                   and numpy.allclose(self_param, other_param,
+                                      atol=_CUTOFF_PRECISION):
+                    continue
+            except TypeError:
+                pass
 
             try:
                 if numpy.isclose(float(self_param), float(other_param),


Test patch:
diff --git a/test/python/circuit/test_instructions.py b/test/python/circuit/test_instructions.py
--- a/test/python/circuit/test_instructions.py
+++ b/test/python/circuit/test_instructions.py
@@ -16,6 +16,8 @@
 
 import unittest
 
+import numpy as np
+
 from qiskit.circuit import Gate
 from qiskit.circuit import Parameter
 from qiskit.circuit import Instruction
@@ -36,19 +38,31 @@ def test_instructions_equal(self):
         hop2 = Instruction('s', 1, 0, [])
         hop3 = Instruction('h', 1, 0, [])
 
+        self.assertFalse(hop1 == hop2)
+        self.assertTrue(hop1 == hop3)
+
         uop1 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
         uop2 = Instruction('u', 1, 0, [0.4, 0.6, 0.5])
         uop3 = Instruction('v', 1, 0, [0.4, 0.5, 0.5])
         uop4 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
-        self.assertFalse(hop1 == hop2)
-        self.assertTrue(hop1 == hop3)
+
         self.assertFalse(uop1 == uop2)
         self.assertTrue(uop1 == uop4)
         self.assertFalse(uop1 == uop3)
+
         self.assertTrue(HGate() == HGate())
         self.assertFalse(HGate() == CnotGate())
         self.assertFalse(hop1 == HGate())
 
+        eop1 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
+        eop2 = Instruction('kraus', 1, 0, [np.array([[0, 1], [1, 0]])])
+        eop3 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
+        eop4 = Instruction('kraus', 1, 0, [np.eye(4)])
+
+        self.assertTrue(eop1 == eop3)
+        self.assertFalse(eop1 == eop2)
+        self.assertFalse(eop1 == eop4)
+
     def test_instructions_equal_with_parameters(self):
         """Test equality of instructions for cases with Parameters."""
         theta = Parameter('theta')