def test_trotter_hamiltonian_operation_errors(): """Test errors in ``TrotterHamiltonian`` addition and subtraction.""" # test addition with different number of parts h1 = TFIM(nqubits=5, trotter=True) term = TFIM(nqubits=2, numpy=True) h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term }, { (1, 2): term, (3, 4): term }, {(4, 0): term}) with pytest.raises(ValueError): h = h1 + h2 # test subtraction with incompatible parts h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term }, { (1, 2): term, (3, 4): term }) with pytest.raises(ValueError): h = h1 - h2 # test matmul with bad type with pytest.raises(NotImplementedError): s = h1 @ "abc" # test matmul with bad shape with pytest.raises(ValueError): s = h1 @ np.zeros((2, 2))
def test_trotter_hamiltonian_initialization_errors(): """Test errors in initialization of ``TrotterHamiltonian``.""" # Wrong type of terms with pytest.raises(TypeError): ham = TrotterHamiltonian({(0, 1): "abc"}) # Wrong type of parts with pytest.raises(TypeError): ham = TrotterHamiltonian([(0, 1)]) # Wrong number of target qubits with pytest.raises(ValueError): ham = TrotterHamiltonian({(0, 1): TFIM(nqubits=3, numpy=True)}) # Same targets multiple times h = TFIM(nqubits=2, numpy=True) with pytest.raises(ValueError): ham = TrotterHamiltonian({(0, 1): h}, {(0, 1): h}) # Different term matrix types h2 = Hamiltonian(2, np.eye(4, dtype=np.float32), numpy=True) with pytest.raises(TypeError): ham = TrotterHamiltonian({(0, 1): h, (1, 2): h2}) # ``from_twoqubit_term`` initialization with nqubits < 0 with pytest.raises(ValueError): ham = TrotterHamiltonian.from_twoqubit_term(-2, h) # ``from_twoqubit_term`` initialization with more than 2 targets h = TFIM(nqubits=3, numpy=True) with pytest.raises(ValueError): ham = TrotterHamiltonian.from_twoqubit_term(4, h)
def test_hamiltonian_mul(numpy): """Test multiplication with ``np.array`` and ``tf.Tensor`` scalar.""" import tensorflow as tf h = TFIM(nqubits=3, h=1.0, numpy=numpy) h2 = h * np.array(2) np.testing.assert_allclose(h2.matrix, 2 * np.array(h.matrix)) _ = h.eigenvectors() h2 = h * tf.cast(2, dtype=tf.complex128) np.testing.assert_allclose(h2.matrix, 2 * np.array(h.matrix))
def test_trotter_hamiltonian_scalar_add(nqubits=4): """Test addition of Trotter Hamiltonian with scalar.""" local_ham = TFIM(nqubits, h=1.0, trotter=True) target_ham = 2 + TFIM(nqubits, h=1.0, numpy=True) local_dense = (2 + local_ham).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix) local_ham = TFIM(nqubits, h=1.0, trotter=True) local_dense = (local_ham + 2).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix)
def test_trotter_hamiltonian_scalar_mul(nqubits=3): """Test multiplication of Trotter Hamiltonian with scalar.""" local_ham = TFIM(nqubits, h=1.0, trotter=True) target_ham = 2 * TFIM(nqubits, h=1.0, numpy=True) local_dense = (2 * local_ham).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix) local_ham = TFIM(nqubits, h=1.0, trotter=True) local_dense = (local_ham * 2).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix)
def test_trotter_hamiltonian_scalar_sub(nqubits=3): """Test subtraction of Trotter Hamiltonian with scalar.""" local_ham = TFIM(nqubits, h=1.0, trotter=True) target_ham = 2 - TFIM(nqubits, h=1.0, numpy=True) local_dense = (2 - local_ham).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix) target_ham = TFIM(nqubits, h=1.0, numpy=True) - 2 local_ham = TFIM(nqubits, h=1.0, trotter=True) local_dense = (local_ham - 2).dense np.testing.assert_allclose(local_dense.matrix, target_ham.matrix)
def test_hamiltonian_matmul(numpy): """Test matrix multiplication between Hamiltonians and state vectors.""" H1 = TFIM(nqubits=3, h=1.0, numpy=numpy) H2 = Y(nqubits=3, numpy=numpy) if numpy: m1 = H1.matrix m2 = H2.matrix else: m1 = H1.matrix.numpy() m2 = H2.matrix.numpy() np.testing.assert_allclose((H1 @ H2).matrix, m1 @ m2) np.testing.assert_allclose((H2 @ H1).matrix, m2 @ m1) v = utils.random_numpy_complex(8, dtype=m1.dtype) m = utils.random_numpy_complex((8, 8), dtype=m1.dtype) np.testing.assert_allclose(H1 @ v, m1.dot(v)) np.testing.assert_allclose(H1 @ m, m1 @ m) from qibo.core.states import VectorState state = VectorState.from_tensor(v) np.testing.assert_allclose(H1 @ state, m1.dot(v)) with pytest.raises(ValueError): H1 @ np.zeros((8, 8, 8), dtype=m1.dtype) with pytest.raises(NotImplementedError): H1 @ 2
def test_trotter_hamiltonian_initialization_errors(): """Test errors in initialization of ``TrotterHamiltonian``.""" # Wrong type of terms with pytest.raises(TypeError): ham = TrotterHamiltonian({(0, 1): "abc"}) # Wrong type of parts with pytest.raises(TypeError): ham = TrotterHamiltonian([(0, 1)]) # Wrong number of target qubits with pytest.raises(ValueError): ham = TrotterHamiltonian({(0, 1): TFIM(nqubits=3, numpy=True)}) # Same targets multiple times h = TFIM(nqubits=2, numpy=True) with pytest.raises(ValueError): ham = TrotterHamiltonian({(0, 1): h}, {(0, 1): h}) # Different term Hamiltonian types h2 = TFIM(nqubits=2, numpy=False) with pytest.raises(TypeError): ham = TrotterHamiltonian({(0, 1): h, (1, 2): h2})
def test_different_hamiltonian_addition(numpy): """Test adding Hamiltonians of different models.""" H1 = Y(nqubits=3, numpy=numpy) H2 = TFIM(nqubits=3, h=1.0, numpy=numpy) H = H1 + H2 matrix = H1.matrix + H2.matrix np.testing.assert_allclose(H.matrix, matrix) H = H1 - 0.5 * H2 matrix = H1.matrix - 0.5 * H2.matrix np.testing.assert_allclose(H.matrix, matrix)
def test_trotter_hamiltonian_make_compatible_repeating(nqubits): """Check ``make_compatible`` when first target is repeated in parts.""" h0target = X(nqubits) h0 = X(nqubits, trotter=True) term = TFIM(2, numpy=True) parts = [{(0, i): term} for i in range(1, nqubits)] parts.extend(({(i, 0): term} for i in range(1, nqubits))) h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, h0target.matrix)
def test_trotter_hamiltonian_make_compatible_redundant(): """Test ``make_compatible`` with redudant two-qubit terms.""" h0 = X(2, trotter=True) target_matrix = h0.dense.matrix.numpy() target_matrix = np.kron(target_matrix, np.eye(2, dtype=target_matrix.dtype)) parts = [{(0, 1, 2): TFIM(3, numpy=True)}] h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, target_matrix)
def test_trotter_hamiltonian_make_compatible_simple(): """Test ``make_compatible`` on a simple 3-qubit example.""" h0target = X(3) h0 = X(3, trotter=True) term1 = Y(1, numpy=True) term2 = TFIM(2, numpy=True) parts = [{(0, 1): term2, (1, 2): term2, (0, 2): term2, (2, ): term1}] h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, h0target.matrix)
def test_matrix_state_expectation(backend, dense): from qibo.hamiltonians import TFIM ham = TFIM(nqubits=2, h=1.0, dense=dense) matrix = K.to_numpy(ham.matrix) state = np.random.random((4, 4)) + 1j * np.random.random((4, 4)) state = state + state.T.conj() norm = np.trace(state) target_ev = np.trace(matrix.dot(state)).real state = states.MatrixState.from_tensor(state) K.assert_allclose(state.expectation(ham), target_ev) K.assert_allclose(state.expectation(ham, True), target_ev / norm)
def test_matrix_state_expectation(backend, trotter): original_backend = qibo.get_backend() qibo.set_backend(backend) from qibo.hamiltonians import TFIM ham = TFIM(nqubits=2, h=1.0, trotter=trotter) matrix = np.array(ham.matrix) state = np.random.random((4, 4)) + 1j * np.random.random((4, 4)) state = state + state.T.conj() norm = np.trace(state) target_ev = np.trace(matrix.dot(state)).real state = states.MatrixState.from_tensor(state) np.testing.assert_allclose(state.expectation(ham), target_ev) np.testing.assert_allclose(state.expectation(ham, True), target_ev / norm) qibo.set_backend(original_backend)
def test_trotter_hamiltonian_matmul(nqubits, normalize): """Test Trotter Hamiltonian expectation value.""" local_ham = TFIM(nqubits, h=1.0, trotter=True) dense_ham = TFIM(nqubits, h=1.0) state = utils.random_tensorflow_complex((2**nqubits, )) trotter_ev = dense_ham.expectation(state, normalize) target_ev = dense_ham.expectation(state, normalize) np.testing.assert_allclose(trotter_ev, target_ev) state = utils.random_numpy_complex((2**nqubits, )) trotter_ev = dense_ham.expectation(state, normalize) target_ev = dense_ham.expectation(state, normalize) np.testing.assert_allclose(trotter_ev, target_ev)
def test_tfim_hamiltonian_from_symbols(nqubits, trotter): """Check creating TFIM Hamiltonian using sympy.""" import sympy h = 0.5 z_symbols = sympy.symbols(" ".join((f"Z{i}" for i in range(nqubits)))) x_symbols = sympy.symbols(" ".join((f"X{i}" for i in range(nqubits)))) symham = sum(z_symbols[i] * z_symbols[i + 1] for i in range(nqubits - 1)) symham += z_symbols[0] * z_symbols[-1] symham += h * sum(x_symbols) symmap = {z: (i, matrices.Z) for i, z in enumerate(z_symbols)} symmap.update({x: (i, matrices.X) for i, x in enumerate(x_symbols)}) target_matrix = TFIM(nqubits, h=h).matrix if trotter: trotter_ham = TrotterHamiltonian.from_symbolic(-symham, symmap) final_matrix = trotter_ham.dense.matrix else: full_ham = Hamiltonian.from_symbolic(-symham, symmap) final_matrix = full_ham.matrix np.testing.assert_allclose(final_matrix, target_matrix)
def test_trotter_hamiltonian_operator_add_and_sub(nqubits=3): """Test addition and subtraction between Trotter Hamiltonians.""" local_ham1 = TFIM(nqubits, h=1.0, trotter=True) local_ham2 = TFIM(nqubits, h=0.5, trotter=True) local_ham = local_ham1 + local_ham2 target_ham = (TFIM(nqubits, h=1.0, numpy=True) + TFIM(nqubits, h=0.5, numpy=True)) dense = local_ham.dense np.testing.assert_allclose(dense.matrix, target_ham.matrix) local_ham = local_ham1 - local_ham2 target_ham = (TFIM(nqubits, h=1.0, numpy=True) - TFIM(nqubits, h=0.5, numpy=True)) dense = local_ham.dense np.testing.assert_allclose(dense.matrix, target_ham.matrix)
def test_trotter_hamiltonian_operation_errors(): """Test errors in ``TrotterHamiltonian`` addition and subtraction.""" # test addition with different number of parts h1 = TFIM(nqubits=5, trotter=True) term = TFIM(nqubits=2, numpy=True) h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term, (4, 0): term }, { (1, 2): term, (3, 4): term }) with pytest.raises(ValueError): h = h1 + h2 # test subtraction with incompatible parts h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term }, {(1, 2): term}, {(4, 0): term}) with pytest.raises(ValueError): h = h1 - h2 # test matmul with bad type with pytest.raises(NotImplementedError): s = h1 @ "abc" # test matmul with bad shape with pytest.raises(ValueError): s = h1 @ np.zeros((2, 2)) # test ``make_compatible`` with non-Trotter Hamiltonian with pytest.raises(TypeError): h2 = h1.make_compatible("test") # test ``make_compatible`` with interacting Hamiltonian with pytest.raises(NotImplementedError): h2 = h1.make_compatible(h2) # test ``make_compatible`` with insufficient two-qubit terms h3 = X(nqubits=7, trotter=True) with pytest.raises(ValueError): h3 = h1.make_compatible(h3)