A couple of questions regarding the conversion between Jordan-Wigner (JW) and Bravyi-Kitaev (BK) states in Qiskit.

The JW $\rightarrow$ BK conversion matrix I refer to below is the one from equation (29) here. (I'm not referring to equation (24) in Ibid. for it contains a typo.)

  1. Is there a way to generate a circuit which would map JW-encoded states to BK-encoded states? (The circuit is actually very simple since it multiplies the input $n$-qubit vector by a $n\times n$ matrix $\operatorname{mod} 2$; since the matrix is upper-triangular, it is rather trivial to construct it out of CNOTs.)

  2. Assuming that the answer to the previous question is NO: is there a way to, at least, generate the matrix implementing the conversion between the Jordan-Wigner and Bravyi-Kitaev states, for a given number of qubits $n$?


I have not found such functionality in Qiskit. However, one can use the openfermion function openfermion.transforms._encoder_bk():

def _encoder_bk(n_modes):
    """ Helper function for bravyi_kitaev_code that outputs the binary-tree
    (dimension x dimension)-matrix used for the encoder in the
    Bravyi-Kitaev transform.

    n_modes (int): length of the matrix, the dimension x dimension

    Returns (numpy.ndarray): encoder matrix
    reps = int(numpy.ceil(numpy.log2(n_modes)))
    mtx = numpy.array([[1, 0], [1, 1]])
    for repetition in numpy.arange(1, reps + 1):
        mtx = numpy.kron(numpy.eye(2, dtype=int), mtx)
        for column in numpy.arange(0, 2 ** repetition):
            mtx[2 ** (repetition + 1) - 1, column] = 1
    return mtx[0:n_modes, 0:n_modes]

With the aid of this function, one constructs the JW → BK circuit as follows:

def jw_to_bk_circuit_qiskit(n):
    Creates a Qiskit circuit which performs the JW -> BK transformation on qubits.
    One needs this function to prepare initial states when using BK encoding.
    :param n: Number of qubits.

    # Initializing qubits:
    qc = qiskit.QuantumCircuit( n )

    # JW->BK encoder (lower-triangluar!) matrix
    bk_encoder = openfermion.transforms._encoder_bk( n )
    # print(bk_encoder)
    # Matrix multiplication mod 2 using CNOTs (starting from the bottom row)
    for i in reversed( range( 1, n ) ):
        for j in range( i  ):
            if bk_encoder[i, j] == 1:

    return qc

Not that it is crucial to perform the matrix multiplication using CNOTs starting from the bottom row, since the encoder matrix is lower-triangular.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.