def test_two_mode(self): q = QuadOperator('p2 q0') b = get_boson_operator(q, hbar=self.hbar) expected = -1j*self.hbar/2 \ * (BosonOperator('0') + BosonOperator('0^')) \ * (BosonOperator('2') - BosonOperator('2^')) self.assertTrue(b == expected)
def test_two_term(self): q = QuadOperator('p0 q0') + QuadOperator('q0 p0') b = get_boson_operator(q, hbar=self.hbar) expected = -1j*self.hbar/2 \ * ((BosonOperator('0') + BosonOperator('0^')) * (BosonOperator('0') - BosonOperator('0^')) + (BosonOperator('0') - BosonOperator('0^')) * (BosonOperator('0') + BosonOperator('0^'))) self.assertTrue(b == expected)
def test_p(self): q = QuadOperator('p2') b = get_boson_operator(q, hbar=self.hbar) expected = BosonOperator('2') - BosonOperator('2^') expected *= -1j * numpy.sqrt(self.hbar / 2) self.assertTrue(b == expected)
def test_x(self): q = QuadOperator('q0') b = get_boson_operator(q, hbar=self.hbar) expected = BosonOperator('0') + BosonOperator('0^') expected *= numpy.sqrt(self.hbar / 2) self.assertTrue(b == expected)
def test_identity(self): q = QuadOperator('') b = get_boson_operator(q) self.assertTrue(b == BosonOperator.identity())
def test_zero(self): q = QuadOperator() b = get_boson_operator(q) self.assertTrue(b == BosonOperator.zero())
def test_invalid_op(self): op = BosonOperator() with self.assertRaises(TypeError): _ = get_boson_operator(op)
def boson_operator_sparse(operator, trunc, hbar=1.): r"""Initialize a Scipy sparse matrix in the Fock space from a bosonic operator. Since the bosonic operators lie in an infinite Fock space, a truncation value needs to be provide so that a sparse matrix of finite size can be returned. Args: operator: One of either BosonOperator or QuadOperator. trunc (int): The size at which the Fock space should be truncated when returning the matrix representing the ladder operator. hbar (float): the value of hbar to use in the definition of the canonical commutation relation [q_i, p_j] = \delta_{ij} i hbar. This only applies if calcualating the sparse representation of a quadrature operator. Returns: The corresponding Scipy sparse matrix of size [trunc, trunc]. """ if isinstance(operator, QuadOperator): from openfermion.transforms._conversion import get_boson_operator boson_operator = get_boson_operator(operator, hbar) elif isinstance(operator, BosonOperator): boson_operator = operator else: raise ValueError("Only BosonOperator and QuadOperator are supported.") if trunc < 1 or not isinstance(trunc, int): raise ValueError("Fock space truncation must be a positive integer.") # count the number of modes n_modes = 0 for term in boson_operator.terms: for ladder_operator in term: if ladder_operator[0] + 1 > n_modes: n_modes = ladder_operator[0] + 1 # Construct the Scipy sparse matrix. n_hilbert = trunc**n_modes values_list = [[]] row_list = [[]] column_list = [[]] # Loop through the terms. for term in boson_operator.terms: coefficient = boson_operator.terms[term] term_operator = coefficient * scipy.sparse.identity( n_hilbert, dtype=complex, format='csc') for ladder_op in term: # Add actual operator to the list. b = boson_ladder_sparse(n_modes, ladder_op[0], ladder_op[1], trunc) term_operator = term_operator.dot(b) # Extract triplets from sparse_term. values_list.append(term_operator.tocoo(copy=False).data) (row, column) = term_operator.nonzero() column_list.append(column) row_list.append(row) # Create sparse operator. values_list = numpy.concatenate(values_list) row_list = numpy.concatenate(row_list) column_list = numpy.concatenate(column_list) sparse_operator = scipy.sparse.coo_matrix( (values_list, (row_list, column_list)), shape=(n_hilbert, n_hilbert)).tocsc(copy=False) sparse_operator.eliminate_zeros() return sparse_operator