diff --git a/qiskit/pulse/configuration.py b/qiskit/pulse/configuration.py index 74d302413a77..9c4019ce19c7 100644 --- a/qiskit/pulse/configuration.py +++ b/qiskit/pulse/configuration.py @@ -39,6 +39,26 @@ def _assert_nested_dict_equal(a, b): return True +def _get_hash(obj: dict): + obj_ = obj.copy() + for k, v in obj.items(): + if isinstance(v, dict): + obj_[k] = _get_hash(v) + elif isinstance(v, np.ndarray): + obj_[k] = v.tobytes() + elif isinstance(v, list): + v_ = [] + for i in v: + if isinstance(i, dict): + v_.append(_get_hash(i)) + else: + v_.append(i) + obj_[k] = tuple(v_) + else: + obj_[k] = v + return hash(tuple(obj_.items())) + + class Kernel: """Settings for this Kernel, which is responsible for integrating time series (raw) data into IQ points. @@ -67,7 +87,7 @@ def __eq__(self, other): return False def __hash__(self): - return hash(repr(self)) + return _get_hash(self.__dict__) class Discriminator: @@ -98,7 +118,7 @@ def __eq__(self, other): return False def __hash__(self): - return hash(repr(self)) + return _get_hash(self.__dict__) class LoRange: diff --git a/test/python/pulse/test_experiment_configurations.py b/test/python/pulse/test_experiment_configurations.py index 85ed4368cfb8..fb3dd6c2c95f 100644 --- a/test/python/pulse/test_experiment_configurations.py +++ b/test/python/pulse/test_experiment_configurations.py @@ -153,6 +153,27 @@ def test_neq_nested_params(self): ) self.assertFalse(kernel_a == kernel_b) + def test_hash(self): + """Test if hash is implemented correctly.""" + kernel_a = Kernel( + "kernel_test", + kernel={"real": np.zeros(10), "imag": np.zeros(10)}, + bias=[0, 0], + ) + kernel_b = Kernel( + "kernel_test", + kernel={"real": np.zeros(10), "imag": np.zeros(10)}, + bias=[0, 0], + ) + self.assertTrue(hash(kernel_a) == hash(kernel_b)) + + kernel_c = Kernel( + "kernel_test", + bias=[0, 0], + kernel={"real": np.zeros(10), "imag": np.zeros(10)}, + ) + self.assertFalse(hash(kernel_a) == hash(kernel_c)) + class TestDiscriminator(QiskitTestCase): """Test Discriminator.""" @@ -199,6 +220,27 @@ def test_neq_params(self): ) self.assertFalse(discriminator_a == discriminator_b) + def test_hash(self): + """Test if hash is implemented correctly.""" + discriminator_a = Discriminator( + "discriminator_test", + discriminator_type="linear", + neighborhoods=[{"qubits": 1, "channels": 1}], + ) + discriminator_b = Discriminator( + "discriminator_test", + discriminator_type="linear", + neighborhoods=[{"qubits": 1, "channels": 1}], + ) + self.assertTrue(hash(discriminator_a) == hash(discriminator_b)) + + discriminator_c = Discriminator( + "discriminator_test", + discriminator_type="linear", + neighborhoods=[{"channels": 1, "qubits": 1}], + ) + self.assertFalse(hash(discriminator_a) == hash(discriminator_c)) + if __name__ == "__main__": unittest.main()