Tagged: gsoc2020 Toggle Comment Threads | Keyboard Shortcuts

  • sidhantsaraogi 11:51 pm on June 28, 2020 Permalink | Reply
    Tags: gsoc2020   

    GSOC Updates: End of Phase 1. 

    It’s been nearly a month since the “official” coding period for the Summer of Code started and it’s been a real delight. Working with QuTiP developers has been very rewarding especially because the community (and my mentors) is so welcoming. The receptiveness to new ideas and (even silly) questions reminding me of more academic environments which is quite nice. In the span of the last month, I have undoubtedly learned a lot about the quirks of git, making pull requests and working with code written by other devs. More important, however, has been incorporating feedback from the mentors (and the wider community) into code and documentation.

    For the past couple of weeks, my work has been divided into three areas (more or less):

    • Compatibility with OpenQASM: The Quantum Assembly Language (QASM) is an intermediate representation for quantum circuits, meant to abstract away the particulars of different circuit implementations. OpenQASM is supported by the two major quantum circuit simulation packages, Qiskit and Cirq. Over the last two weeks, I have added the ability to read QASM files into quantum circuits in QuTiP (#1291). Not only does this allow QIP sub-package to interface in a substantial way with Qiskit and Cirq, it also allows users to import a host of readymade circuit definitions (read as algorithms) specified as examples in the OpenQASM repository. The next step (already in the works) is to add the corresponding “export to QASM” features.

      The primary challenge I faced while writing import code was reading QASM syntax from scratch. While the Qiskit parser for the same uses a lexer and parser to achieve the same effect (taking advantage of the fact that OpenQASM has a language definition), I decided to use a more lightweight approach where we read the syntax in line-by-line. This was possible because the OpenQASM syntax is not all that complicated. I hope to outline some of the details of the implementation and its differences with other implementations in a short future blogpost.

      While OpenQASM is probably the most popular such instance of such an “assembly” language, there are a number of others such as cQASM and PyQuil, the numbers increasing by the day as more platforms and packages for quantum circuit simulation pop up. Hopefully as the QIP sub-package gains new capabilities, it can also accommodate more such representations, thereby allowing imports/exports between more packages.
    • Refining the Measurements PR (#1274): In my last blog post, I outlined a short guide to measurements in QuTiP as a companion to my PR which stitched together measurement functions in QuTiP and added the capability of projective measurements (and, as a result, measurement gates in the circuit). Some portion of the last week was spent refining the API for measurement, as well as making it more user-friendly. Community feedback was very crucial in this regard with the addition of a number of small but useful changes.
    • Last, but certainly not the least, the QuTiP team has planned to spin-off the QIP feature set as an add-on package for the core QuTiP package. Once separated, the QIP package is supposed to act as an optional extension to QuTiP, augmenting it with quantum information processing features. This serves the dual purpose of allowing more focussed development on the QIP features as well as enhancing maintainability of the core QuTiP package. I hope to help this transition with a test-run in the next few weeks. During the last week, we made a number of important decisions with respect to the maintenance of the new package, and I hope to outline them in a future blogpost. This is also meant to set the stage for further spin-offs of packages from QuTiP.

    My primary note to myself over the last few weeks has been to budget some time for revisions to code/documentation I add. This is undoubtedly necessary in the development process but not something I paid much attention to before. Thanks for reading!

  • sidhantsaraogi 7:17 pm on June 14, 2020 Permalink | Reply
    Tags: gsoc2020, qip   

    An Introduction to Quantum Measurements in QuTiP. 

    While the QIP module of QuTiP has been evolving to include a lot of new functionality, the ability to measure states has been absent till now. A significant development was the addition of quantum mechanical measurements by Simon Cross. While measurements using hermitian observables are pretty general, the form in which measurements in quantum information are usually specified is directly in terms of the projection operators. More importantly, this also allows measurements to be further generalized to positive-operator valued measurements. The aim of this post is two-fold:

    • To provide a basic overview of the different ways to carry out state measurements in QuTiP.
    • To provide an idea of the interchangeability and usefulness of the different functions.

    Note: The addition of projective measurements can be tracked in PR #1274.


    Observables in quantum mechanics can be specified by a hermitian operator. We will restrict our discussion to observables with only discrete values. Also, for the sake of brevity, we also restrict ourself to working with only pure states specified by kets. The measurement functions in QuTiP can handle both kets and density matrices.

    Associated with a discrete observable H are its eigenstates \left| q_1 \right>, \hdots, \left| q_n \right> and corresponding eigenvalues q_1, \hdots, q_n. Let’s consider an example in QuTiP with \sigma_z, which measures the z-component of the spin of a spin-½ particle. First, let’s get some imports out of the way!

    >>> from qutip import sigmaz, basis, tensor, identity
    >>> from qutip.measurement import measure, measurement_statistics
    >>> SIGMAZ = sigmaz()                                                       
    >>> SIGMAZ.eigenstates()                                                     
    (array([-1.,  1.]),
     array([Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
     Qobj data =
     [[ 0.]
            Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
     Qobj data =
      [ 0.]]], dtype=object))

    Since the eigenvectors of a hermitian operator are orthogonal, given that we have a state of the correct dimension, we can write the state \left| \psi \right> as:

    \left| \psi \right> = \sum_i c_i \left| q_i\right>

    Now, we can calculate the probability of measuring state \left| q_i \right> as p_i = \left| \left< q_i | \psi \right> \right|^2 . This is precisely the kind of measurement embodied when the measurement_statistics function is supplied with an observable and a ket vector.

    >>> state_0 = basis(2, 0) 
    >>> SIGMAZ = sigmaz() 
    >>> measurement_statistics(SIGMAZ, state_0)                                 
    (array([-1.,  1.]),
     array([Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
     Qobj data =
     [[ 0.]
            Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
     Qobj data =
      [ 0.]]], dtype=object),
     [0, 1.0])
    >>> measure(SIGMAZ, state_0)
    (1.0, Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
     Qobj data =
      [ 0.]])

    When supplied with the state \left| 0 \right>, we obtain that the eigenvalue 1 corresponding to the eigenstate [[-1], [0]] is returned with probability 1 which is what is expected. This can be confirmed by the usage of the measure function.

    However, when we only want to measure a few qubits on a state vector representing a number of qubits, it gets a little more complicated. On measurement, we want the measured qubit to collapse to the result while maintaining information about the rest of the qubits. Suppose we want to measure the first qubit in a two-qubit system with the \sigma_z \otimes I observable. In our example below, the two-qubit system is in the state \left| 0 + \right>, the first qubit in the “up” state in the S_z basis and the second qubit being in the “up”-state in the S_x basis.

    >>> sz_I = tensor(SIGMAZ, identity(2))
    >>> state_0plus = tensor(basis(2, 0), 1/(sqrt(2)) * (basis(2, 0)+ basis(2,1)))
    >>> measurement_statistics(sz_I, state_0plus)
    (array([-1., -1.,  1.,  1.]),
     array([Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket
     Qobj data =
            Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket
     Qobj data =
            Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket
     Qobj data =
            Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket
     Qobj data =
      [0.]]], dtype=object),
     [0, 0, 0.4999999999999999, 0.4999999999999999])

    As expected, the hermitian operator is decomposed into two sets of degenerate eigenstates corresponding to the -1 and 1 eigenvalues. We can still obtain the correct outcomes of the first qubit by considering the two eigenstates corresponding to the +1 eigenvalue (\left| 00 \right>, \left| 01 \right>, only states with non-zero probability correctly predicting \left| 0 \right> on the first qubit). While we can reconstruct the collapsed state that will be produced if we measure only the first qubit, the eigenstates themselves have lost the information about the second qubit.

    Before we understand how to measure a subset of qubits easily, it’s instructive to know more about how general measurements can be.


    A generalized measurement can be specified by a collection of positive semi-definite operators E_i \geq 0 that satisfy \sum_i E_i = I. This form of measurement is also known as positive-operator valued measurements (POVMs). Each E_i is associated with a particular outcome and can be decomposed as E_i = M_i^{\dagger} M_i. For a state, we can calculate the probability of measuring a particular outcome as p_i =  \left | \left< \psi | E_i | \psi \right>  \right|  and calculate the post-measurement state as

    \left| \psi \right> \rightarrow \frac{M_i \left| \psi \right>}{\sqrt{p_i}}

    While the operators E_i are enough to calculate the measurement probabilities, a particular decomposition specifying the M_i's is needed to calculate the resultant state.


    Projective measurements (PVMs) are just a special case of POVMs in which the measurement operators satisfy the additional property of the M_i being projectors, i.e. M_i M_j = \delta_{ij} M_i. With this property, we also get that E_i = M_i^{\dagger} = M_i. Both POVMs and PVMs can be handled by the measure and measure_statistics functions by specifying the first argument as the list of M_i's.

    Now, we are well-equipped to handle measurement on a subset of qubits. We just need to specify the correct projection operators. For our previous example, we can write our hermitian as:

    \sigma_z \otimes I = (-1) *  \left| 0 \right> \left< 0 \right | \otimes I + (1) * \left| 1 \right> \left< 1 \right | \otimes I

    Now, we can just plug-in our projection operators into the measurement function to measure on a two qubit system.

    >>> zeroid = tensor(ket2dm(basis(2, 0)), identity(2)) 
    >>> oneid = tensor(ket2dm(basis(2, 1)), identity(2)) 
    >>> sZ_I = [zeroid, oneid]
    >>> measurement_statistics(sZ_I, state_0plus)
    ([Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket
      Qobj data =
       [0.        ]
       [0.        ]], None], [0.9999999999999998, 0.0])

    The state obtained on measurement is \left| 0+ \right> with probability 1, as expected. In this case, the information about the second qubit is still maintained, as required.

    While we could specify all projective measurements using hermitian observables, we have seen it is often easier to specify them using the projection operators themselves. This is why both options are available. I hope to add another post on the usefulness of POVMs which generalize projective measurements. A particularly interesting example of their use is that of unambiguous state discrimination.


    1. Quantum Physics Notes, JD Cresser.
    2. Quantum Computing Lecture Notes, Mohan Sarovar.
  • sidhantsaraogi 8:48 pm on May 14, 2020 Permalink | Reply
    Tags: gsoc2020   

    Quantum Circuits and Noise (GSOC 2020) 

    I am participating in the Google Summer of Code under the NumFOCUS banner. In particular, I will be working on the QuTiP project. With the introduction of the QIP module last year by Boxi Li, QuTiP now has a proper circuits and noise module which I am aim to add more features to. I also aim to increase compatibility with other quantum computation libraries like Qiskit and Cirq. I look forward to working with my mentors at QuTiP and learn more about open systems solvers. You can find my project proposal here.

    • Boxi 3:23 am on May 17, 2020 Permalink | Reply

      Good start! Though last year I merely extended the qip module with a quantum device simulator, “introduction of the qip module” gives me to much credit 🙂
      Looking forward to your project!


Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc
Sidhant's Blog

Covering complexity, quantum algos and other miscellaneous things.

Ridiculous Recreations

Got to solve them all ...

Create your website at WordPress.com
Get started