mindquantum.core.operators

MindQuantum operators library. An operator is composed of a combination of one or more basic gates.

Contains classes representing: - Qubit operators - Fermion operators - TimeEvolution operator

class mindquantum.core.operators.FermionOperator(term=None, coefficient=1.0)[source]

The Fermion Operator such as FermionOperator(’ 4^ 3 9 3^ ‘) are used to represent \(a_4^\dagger a_3 a_9 a_3^\dagger\). These are the Basic Operators to describe a fermionic system, such as a Molecular system. The FermionOperator are follows the anti-commutation relationship.

Parameters
  • terms (str) – The input term of fermion operator. Default: None.

  • coefficient (Union[numbers.Number, str, ParameterResolver]) – The coefficient for the corresponding single operators Default: 1.0.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> a_p_dagger = FermionOperator('1^')
>>> a_p_dagger
1.0 [1^]
>>> a_q = FermionOperator('0')
>>> a_q
1.0 [0]
>>> zero = FermionOperator()
>>> zero
0
>>> identity= FermionOperator('')
>>> identity
1.0 []
>>> para_op = FermionOperator('0 1^', 'x')
>>> para_op
x [0 1^]
>>> para_dt = {'x':2}
>>> op = para_op.subs(para_dt)
>>> op
2 [0 1^]
property imag

Convert the coeff to its imag part.

Returns

FermionOperator, the imag part of this fermion operator.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> f = FermionOperator('0', 1 + 2j) + FermionOperator('0^', 'a')
>>> f.imag.compress()
2.0 [0]
normal_ordered()[source]

Return the normal ordered form of the Fermion Operator.

Returns

FermionOperator, the normal ordered FermionOperator.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> origin = FermionOperator('0 1^')
>>> origin
1.0 [0 1^]
>>> origin.normal_ordered()
-1.0 [1^ 0]
property real

Convert the coeff to its real part.

Returns

FermionOperator, the real part of this fermion operator.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> f = FermionOperator('0', 1 + 2j) + FermionOperator('0^', 'a')
>>> f.real.compress()
1.0 [0] +
a [0^]
class mindquantum.core.operators.Hamiltonian(hamiltonian)[source]

A QubitOperator hamiltonian wrapper.

Parameters

hamiltonian (QubitOperator) – The pauli word qubit operator.

Examples

>>> from mindquantum.core.operators import QubitOperator
>>> from mindquantum import Hamiltonian
>>> ham = Hamiltonian(QubitOperator('Z0 Y1', 0.3))
get_cpp_obj(hermitian=False)[source]
Parameters

hermitian (bool) – Whether to get the cpp object of this hamiltonian in hermitian version.

sparse(n_qubits=1)[source]

Calculate the sparse matrix of this hamiltonian in pqc operator

Parameters

n_qubits (int) – The total qubit of this hamiltonian, only need when mode is ‘frontend’. Default: 1.

class mindquantum.core.operators.InteractionOperator(constant, one_body_tensor, two_body_tensor)[source]

Class to store ‘interaction opeartors’ which are used to configure a ferinonic molecular Hamiltonian.

The Hamiltonian including one-body and two-body terms which conserve spin and parity. In this module, the stored coefficient could be represented the molecular Hamiltonians through the FermionOperator class.

Note

The operators stored in this class has the form:

\[C + \sum_{p, q} h_{[p, q]} a^\dagger_p a_q + \sum_{p, q, r, s} h_{[p, q, r, s]} a^\dagger_p a^\dagger_q a_r a_s.\]

Where \(C\) is a constant.

Parameters
  • constant (numbers.Number) – A constant term in the operator given as a float. For instance, the nuclear repulsion energy.

  • one_body_tensor (numpy.ndarray) – The coefficients of the one-body terms (h[p, q]). This is an \(n_\text{qubits}\times n_\text{qubits}\) numpy array of floats. By default we store the numpy array with keys: \(a^\dagger_p a_q\) (1,0).

  • two_body_tensor (numpy.ndarray) – The coefficients of the two-body terms (h[p, q, r, s]). This is an \(n_\text{qubits}\times n_\text{qubits}\times n_\text{qubits}\times n_\text{qubits}\) numpy array of floats.By default we store the numpy array with keys: \(a^\dagger_p a^\dagger_q a_r a_s\) (1, 1, 0, 0).

unique_iter(complex_valued=False)[source]

Iterate all terms that are not in the same symmetry group.

Four point symmetry:
  1. pq = qp.

  2. pqrs = srqp = qpsr = rspq.

Eight point symmetry(when complex_valued is False):
  1. pq = qp.

  2. pqrs = rqps = psrq = srqp = qpsr = rspq = spqr = qrsp.

Parameters

complex_valued (bool) – Whether the operator has complex coefficients. Default: False.

class mindquantum.core.operators.PolynomialTensor(n_body_tensors=None)[source]

Class to store the coefficient of the fermionic ladder operators in a tensor form. For instance, in a molecular Hamiltonian (degree 4 polynomial) which conserves particle number, there are only three kinds of terms, namely constant term, single excitation \(a^\dagger_p a_q\) and double excitation terms \(a^\dagger_p a^\dagger_q a_r a_s\), and their corresponding coefficients can be stored in an scalar, \(n_\text{qubits}\times n_\text{qubits}\) matrix and \(n_\text{qubits}\times n_\text{qubits} n_\text{qubits}\times n_\text{qubits}\) matrix. Note that each tensor must have an even number of dimensions due to the parity conservation. Much of the functionality of this class is similar to that of FermionOperator.

Parameters

n_body_tensors (dict) – A dictionary storing the tensors describing n-body interactions. The keys are tuples that indicate the type of tensor. For instance, n_body_tensors[()] would return a constant, while a n_body_tensors[(1, 0)] would be an \(n_\text{qubits}\times n_\text{qubits}\) numpy array, and n_body_tensors[(1,1,0,0)] would return a \(n_\text{qubits}\times n_\text{qubits} n_\text{qubits}\times n_\text{qubits}\) numpy array and those constant and array represent the coefficients of terms of the form identity, \(a^\dagger_p a_q\), \(a^\dagger_p a^\dagger_q a_r a_s\), respectively. Default: None.

Note

Here ‘1’ represents \(a^\dagger\), while ‘0’ represent \(a\).

Examples

>>> import numpy as np
>>> from mindquantum.core.operators import PolynomialTensor
>>> constant = 1
>>> one_body_term = np.array([[1,0],[0,1]])
>>> two_body_term = two_body_term = np.array([[[[1,0],[0,1]],[[1,0],[0,1]]],[[[1,0],[0,1]],[[1,0],[0,1]]]])
>>> n_body_tensors = {(): 1, (1,0): one_body_term,(1,1,0,0):two_body_term}
>>> poly_op = PolynomialTensor(n_body_tensors)
>>> poly_op
() 1
((0, 1), (0, 0)) 1
((1, 1), (1, 0)) 1
((0, 1), (0, 1), (0, 0), (0, 0)) 1
((0, 1), (0, 1), (1, 0), (1, 0)) 1
((0, 1), (1, 1), (0, 0), (0, 0)) 1
((0, 1), (1, 1), (1, 0), (1, 0)) 1
((1, 1), (0, 1), (0, 0), (0, 0)) 1
((1, 1), (0, 1), (1, 0), (1, 0)) 1
((1, 1), (1, 1), (0, 0), (0, 0)) 1
((1, 1), (1, 1), (1, 0), (1, 0)) 1
>>> # get the constant
>>> poly_op.constant
1
>>> # set the constant
>>> poly_op.constant = 2
>>> poly_op.constant
2
>>> poly_op.n_qubits
2
>>> poly_op.one_body_tensor
array([[1, 0],
       [0, 1]])
>>> poly_op.two_body_tensor
array([[[[1, 0],
         [0, 1]],
        [[1, 0],
         [0, 1]]],
       [[[1, 0],
         [0, 1]],
         [[1, 0],
          [0, 1]]]])
property constant

get the value of the identity term

property one_body_tensor

get the one-body term

property two_body_tensor

get the two body term

class mindquantum.core.operators.Projector(proj)[source]

Projector operator.

For a projector shown as below:

\[\left|01\right>\left<01\right|\otimes I^2\]

The string format would be ‘01II’.

Note

The lower index qubit is at the right end of string format of bra and ket.

Parameters

proj (str) – The string format of the projector.

Examples

>>> from mindquantum.core.operators import Projector
>>> p = Projector('II010')
>>> p
I2 ⊗ ¦010⟩⟨010¦
class mindquantum.core.operators.QubitExcitationOperator(term=None, coefficient=1.0)[source]

The Qubit Excitation Operator is defined as: \(Q^{\dagger}_{n} = \frac{1}{2} (X_{n} - iY_{n})\) and \(Q_{n} = \frac{1}{2} (X_{n} + iY_{n})\). Compared with Fermion excitation operators, Qubit excitation operators are some kind of “localized”, i.e., the Fermion excitation operator \(a^{\dagger}_{7} a_{0}\) involves qubit ranging from 0 to 7 under JW transformation, while Qubit excitation \(Q^{\dagger}_{7} Q_{0}\) will only affect the 0th and 7th qubits. In addition, double excitations described using Qubit excitation operators use much less CNOTs than the corresponding Fermion excitation operators.

Parameters
  • terms (str) – The input term of qubit excitation operator. Default: None.

  • coefficient (Union[numbers.Number, str, ParameterResolver]) – The coefficient for the corresponding single operators Default: 1.0.

Examples

>>> from mindquantum.algorithm.nisq.chem import Transform
>>> from mindquantum.core.operators import QubitExcitationOperator
>>> op = QubitExcitationOperator(((4, 1), (1, 0), (0, 0)), 2.5)
>>> op
2.5 [Q4^ Q1 Q0]
>>> op.fermion_operator
2.5 [4^ 1 0]
>>> op.to_qubit_operator()
0.3125 [X0 X1 X4] +
-0.3125j [X0 X1 Y4] +
0.3125j [X0 Y1 X4] +
(0.3125+0j) [X0 Y1 Y4] +
0.3125j [Y0 X1 X4] +
(0.3125+0j) [Y0 X1 Y4] +
(-0.3125+0j) [Y0 Y1 X4] +
0.3125j [Y0 Y1 Y4]
>>> Transform(op.fermion_operator).jordan_wigner()
(0.3125+0j) [X0 X1 Z2 Z3 X4] +
-0.3125j [X0 X1 Z2 Z3 Y4] +
0.3125j [X0 Y1 Z2 Z3 X4] +
(0.3125+0j) [X0 Y1 Z2 Z3 Y4] +
0.3125j [Y0 X1 Z2 Z3 X4] +
(0.3125+0j) [Y0 X1 Z2 Z3 Y4] +
(-0.3125+0j) [Y0 Y1 Z2 Z3 X4] +
0.3125j [Y0 Y1 Z2 Z3 Y4]
property imag

Convert the coeff to its imag part.

Returns

QubitExcitationOperator, the image part of this qubit excitation operator.

Examples

>>> from mindquantum.core.operators import QubitExcitationOperator
>>> f = QubitExcitationOperator(((1, 0),), 1 + 2j)
>>> f += QubitExcitationOperator(((1, 1),), 'a')
>>> f.imag.compress()
2.0 [Q1^]
normal_ordered()[source]

Return the normal ordered form of the Qubit excitation operator.

Returns

QubitExcitationOperator, the normal ordered operator.

Examples

>>> from mindquantum.core.operators import QubitExcitationOperator
>>> op = QubitExcitationOperator("7 1^")
>>> op
1.0 [Q7 Q1^]
>>> op.normal_ordered()
1.0 [Q1^ Q7]

Note

Unlike Fermion excitation operators, Qubit excitation operators will not multiply -1 when the order is swapped.

property real

Convert the coeff to its imag part.

Returns

QubitExcitationOperator, the real part of this qubit excitation operator.

Examples

>>> from mindquantum.core.operators import QubitExcitationOperator
>>> f = QubitExcitationOperator(((1, 0),), 1 + 2j)
>>> f += QubitExcitationOperator(((1, 1),), 'a')
>>> f.real.compress()
1.0 [Q1] +
a [Q1^]
to_qubit_operator()[source]

Convert the Qubit excitation operator to the equivalent Qubit operator.

Returns

QubitOperator, The corresponding QubitOperator according to the definition of Qubit excitation operators.

Examples

>>> from mindquantum.core.operators import QubitExcitationOperator
>>> op = QubitExcitationOperator("7^ 1")
>>> op.to_qubit_operator()
0.25 [X1 X7] +
-0.25j [X1 Y7] +
0.25j [Y1 X7] +
(0.25+0j) [Y1 Y7]
class mindquantum.core.operators.QubitOperator(term=None, coefficient=1.0)[source]

A sum of terms acting on qubits, e.g., 0.5 * ‘X1 X5’ + 0.3 * ‘Z1 Z2’. A term is an operator acting on n qubits and can be represented as: coefficient * local_operator[0] x … x local_operator[n-1] where x is the tensor product. A local operator is a Pauli operator (‘I’, ‘X’, ‘Y’, or ‘Z’) which acts on one qubit. In mathematical notation a QubitOperator term is, for example, 0.5 * ‘X1 X5’, which means that a Pauli X operator acts on qubit 1 and 5, while the identity operator acts on all the rest qubits.

Note that a Hamiltonian composed of QubitOperators should be a hermitian operator, thus requires the coefficients of all terms must be real.

QubitOperator has the following attributes set as follows: operators = (‘X’, ‘Y’, ‘Z’), different_indices_commute = True.

Parameters
  • term (str) – The input term of qubit operator. Default: None.

  • coefficient (Union[numbers.Number, str, ParameterResolver]) – The coefficient of this qubit operator, could be a number or a variable represent by a string or a symbol or a parameter resolver. Default: 1.0.

Examples

>>> from mindquantum.core.operators import QubitOperator
>>> ham = ((QubitOperator('X0 Y3', 0.5)
...         + 0.6 * QubitOperator('X0 Y3')))
>>> ham2 = QubitOperator('X0 Y3', 0.5)
>>> ham2 += 0.6 * QubitOperator('X0 Y3')
>>> ham2
1.1 [X0 Y3]
>>> ham3 = QubitOperator('')
>>> ham3
1.0 []
>>> ham_para = QubitOperator('X0 Y3', 'x')
>>> ham_para
x [X0 Y3]
>>> ham_para.subs({'x':1.2})
1.2 [X0 Y3]
count_gates()[source]

Returns the gate number when treated in single Hamiltonian

Returns

int, number of the single qubit quantum gates.

property imag

Convert the coeff to its imag part.

Returns

QubitOperator, the imag part of this qubit operator.

Examples

>>> from mindquantum.core.operators import QubitOperator
>>> f = QubitOperator('X0', 1 + 2j) + QubitOperator('Y0', 'a')
>>> f.imag.compress()
2.0 [X0]
property real

Convert the coeff to its real part.

Returns

QubitOperator, the real part of this qubit operator.

Examples

>>> from mindquantum.core.operators import QubitOperator
>>> f = QubitOperator('X0', 1 + 2j) + QubitOperator('Y0', 'a')
>>> f.real.compress()
1.0 [X0] +
a [Y0]
class mindquantum.core.operators.TimeEvolution(ops: QubitOperator, time=None)[source]

The time evolution operator that can generate a crosponded circuit.

The time evolution operator will do the following evolution:

\[\left|\varphi(t)\right>=e^{-iHt}\left|\varphi(0)\right>\]

Note

The hamiltonian should be a parameterized or non parameterized QubitOperator. If the QubitOperator has multiple terms, the first order trotter decomposition will be used.

Parameters
  • ops (QubitOperator) – The qubit operator hamiltonian, could be parameterized or non parameterized.

  • time (Union[numbers.Number, dict, ParameterResolver]) – The evolution time, could be a number or a parameter resolver. If None, the time will be set to 1. Default: None.

Examples

>>> from mindquantum.core.operators import TimeEvolution, QubitOperator
>>> q1 = QubitOperator('Z0 Y1', 'a')
>>> q2 = QubitOperator('X0 Z1', 'b')
>>> ops1 = q1 + q2
>>> ops2 = q2 + q1
>>> TimeEvolution(ops1).circuit
q0: ─────────────●───────────────●───────H────────●───────────────●────H──
                 │               │                │               │
q1: ──RX(π/2)────X────RZ(2*a)────X────RX(7π/2)────X────RZ(2*b)────X───────
>>> TimeEvolution(ops2).circuit
q0: ──H────●───────────────●───────H───────●───────────────●──────────────
           │               │               │               │
q1: ───────X────RZ(2*b)────X────RX(π/2)────X────RZ(2*a)────X────RX(7π/2)──
property circuit

Get the first order trotter decomposition circuit of this time evolution operator.

mindquantum.core.operators.commutator(left_operator, right_operator)[source]

Compute the commutator of two operators.

Parameters
Raises

TypeError – operator_a and operator_b are not of the same type.

Examples

>>> from mindquantum.core.operators import QubitOperator,FermionOperator
>>> from mindquantum.core.operators import commutator
>>> qub_op1 = QubitOperator("X1 Y2")
>>> qub_op2 = QubitOperator("X1 Z2")
>>> commutator(qub_op1, qub_op1)
0
>>> commutator(qub_op1, qub_op2)
2j [X2]
mindquantum.core.operators.count_qubits(operator)[source]

Calculate the number of qubits on which operator acts before removing the unused qubit

Note

In some case, we need to remove the unused index.

Parameters

operator (Union[FermionOperator, QubitOperator, QubitExcitationOperator]) – FermionOperator or QubitOperator or QubitExcitationOperator.

Returns

int, The minimum number of qubits on which operator acts.

Raises

TypeError – Operator of invalid type.

Examples

>>> from mindquantum.core.operators import QubitOperator,FermionOperator
>>> from mindquantum.core.operators.utils import count_qubits
>>> qubit_op = QubitOperator("X1 Y2")
>>> count_qubits(qubit_op)
3
>>> fer_op = FermionOperator("1^")
>>> count_qubits(fer_op)
2
mindquantum.core.operators.down_index(index)[source]

The index order, by default we set the spinless orbits as even-odd-even-odd (0,1,2,3,…). The spin_down orbitals (beta orbital) with index odd.

Parameters

index (int) – spatial orbital index.

Returns

An integer that is the index of the associated spin-down orbital.

Examples

>>> from mindquantum.core.operators import down_index
>>> down_index(1)
3
mindquantum.core.operators.get_fermion_operator(operator)[source]

Convert the tensor (PolynomialTensor) to FermionOperator.

Parameters

operator (PolynomialTensor) – The PolynomialTensor you want to convert to FermionOperator.

Returns

fermion_operator, An instance of the FermionOperator class.

mindquantum.core.operators.hermitian_conjugated(operator)[source]

Return Hermitian conjugate of FermionOperator or QubitOperator.

Parameters

operator (Union[FermionOperator, QubitOperator, QubitExcitationOperator]) – The input operator.

Returns

operator (Union[FermionOperator, QubitOperator, QubitExcitationOperator]), the hermitian form of the input operator.

Examples

>>> from mindquantum.core.operators import QubitOperator
>>> from mindquantum.core.operators import hermitian_conjugated
>>> q = QubitOperator('X0', {'a' : 2j})
>>> hermitian_conjugated(q)
-2.0*I*a [X0]
mindquantum.core.operators.normal_ordered(fermion_operator)[source]

Calculate and return the normal order of the FermionOperator. By convention, normal ordering implies terms are ordered from highest mode index (on left) to lowest (on right). Also, creation operators come first then follows the annihilation operator. e.g 3 4^ \(\rightarrow\) - 4^ 3.

Parameters

fermion_operator (FermionOperator) – Only Fermion type Operator has such forms.

Returns

FermionOperator, the normal_ordered FermionOperator.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> from mindquantum.core.operators import normal_ordered
>>> op = FermionOperator("3 4^", 'a')
>>> normal_ordered(op)
-a [4^ 3]
mindquantum.core.operators.number_operator(n_modes=None, mode=None, coefficient=1.0)[source]

Return a fermionic number operator for the reverse_jordan_wigner transform.

Parameters
  • n_modes (int) – The number of modes in the system. Default: None.

  • mode (int, optional) – The mode on which to return the number operator. If None, return total number operator on all sites. Default: None.

  • coefficient (float) – The coefficient of the term. Default: 1.

Returns

FermionOperator, a fermionic number operator for the reverse_jordan_wigner transform.

Examples

>>> from mindquantum.core.operators import FermionOperator
>>> from mindquantum.core.operators import number_operator
>>> nmode = 3
>>> number_operator(nmode)
1.0 [0^ 0] +
1.0 [1^ 1] +
1.0 [2^ 2]
>>> mode = 3
>>> number_operator(None, mode)
1.0 [3^ 3]
mindquantum.core.operators.sz_operator(n_spatial_orbitals)[source]

Return the sz operator.

Parameters

n_spatial_orbitals (int) – number of spatial orbitals (n_qubits // 2).

Returns

FermionOperator, corresponding to the sz operator over n_spatial_orbitals.

Note

The default index order spin_up(alpha) corresponds to even index, while the spin_down(beta) corresponds to odd index.rpartition()

Examples

>>> from mindquantum.core.operators import sz_operator
>>> sz_operator(3)
0.5 [0^ 0] +
-0.5 [1^ 1] +
0.5 [2^ 2] +
-0.5 [3^ 3] +
0.5 [4^ 4] +
-0.5 [5^ 5]
mindquantum.core.operators.up_index(index)[source]

The index order, by default we set the spinless orbits as even-odd-even-odd (0,1,2,3,…). The spin_up orbitals (alpha orbitals) with index even.

Parameters

index (int) – spatial orbital index.

Returns

An integer that is the index of the associated spin-up orbital.

Examples

>>> from mindquantum.core.operators import up_index
>>> up_index(1)
2