1
$\begingroup$

When using qiskit, we normally get the output inform of column vectors or matrix. But is it possible to convert then into bra ket notation using some python code? Can someone help me with this?

$\endgroup$
3
$\begingroup$

Qiskit doesn't expose a method to do this yet. There is a proposed feature under review now here: https://github.com/Qiskit/qiskit-terra/pull/6154 that adds a new output style for the Statevector.draw() method doing this which will generate LaTeX output in the ket notation.

If you'd like to leverage this now it shouldn't be too difficult to adapt the code from that pull request into a standalone function you can use until that feature is merged into Qiskit for a release.

$\endgroup$
1
$\begingroup$

I did such a function some months ago. Warning: this is a textual output. If you want something nice with $\LaTeX$ see Matthew's answer.

The code:

import numpy

# Numbers below this threshold will be printed as 0
ABSOLUTE_TOLERANCE: float = 1e-5

def _real2str(num: float, decimals: int, atol: float, force_ones: bool) -> str:
    ret = ""
    float_format = "{0:." + str(decimals) + "f}"
    if force_ones or abs(num - 1) > max(10 ** (-decimals) / 2, atol):
        ret += float_format.format(num)
    return ret


def _complex2str(num: complex, decimals: int, atol: float = ABSOLUTE_TOLERANCE) -> str:
    ret = ""
    real, imag = abs(num.real), abs(num.imag)
    if real > atol:
        ret += _real2str(num.real, decimals, atol, force_ones=imag > atol)
        if imag > atol:
            ret += "+" if num.imag > 0 else "-"
    if imag > atol:
        ret += "i" + _real2str(imag, decimals, atol, force_ones=False)
    if real > atol and imag > atol:
        ret = "(" + ret + ")"
    return ret


def _num2str(num, decimals: int, atol: float = 1e-7) -> str:
    return _complex2str(complex(num), decimals, atol=atol)


def msb2str(num: int, length: int) -> str:
    return "|{msb_state}〉".format(msb_state=bin(num)[2:].zfill(length))


def lsb2str(num: int, length: int) -> str:
    return "|{lsb_state}〉".format(lsb_state=bin(num)[2:][::-1].zfill(length))


def msbqstate2str(
    statevector: numpy.ndarray, decimals: int = 2, atol: float = ABSOLUTE_TOLERANCE
) -> str:
    ret = ""
    n = numpy.ceil(numpy.log2(statevector.size)).astype(int)
    for i in range(len(statevector)):
        if abs(statevector[i]) > 10 ** (-decimals) / 2:
            ret += "{coeff}{msb_state} + ".format(
                coeff=_num2str(statevector[i], decimals, atol), msb_state=msb2str(i, n)
            )
    return ret[:-3]


def lsbqstate2str(
    statevector: numpy.ndarray, decimals: int = 2, atol: float = ABSOLUTE_TOLERANCE
) -> str:
    ret = ""
    n = numpy.ceil(numpy.log2(statevector.size)).astype(int)
    for i in range(len(statevector)):
        if abs(statevector[i]) > atol:
            ret += "{coeff}{lsb_state} + ".format(
                coeff=_num2str(statevector[i], decimals, atol),
                lsb_state=lsb2str(i, n),
            )
    return ret[:-2]

and you can use it this way:

statevector = numpy.random.rand(4)
statevector /= numpy.linalg.norm(statevector)
print("LSB:")
print(lsbqstate2str(statevector))
print("MSB:")
print(msbqstate2str(statevector))
print("More digits:")
print(msbqstate2str(statevector, decimals=6))

Outputs something like:

LSB:
0.45|00〉 + 0.33|01〉 + 0.71|01〉 + 0.43|11〉 
MSB:
0.45|00〉 + 0.33|01〉 + 0.71|10〉 + 0.43|11〉
More digits:
0.453597|00〉 + 0.331723|01〉 + 0.708731|10〉 + 0.426510|11〉
$\endgroup$

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.