In this post, we describe an important aspect of constructing and compiling complex quantum operators—specifically, how large operators built from many smaller pieces can be represented and resolved.
Let’s say we want to create a unitary operator acting on a large Hilbert space. This operator isn’t monolithic—it’s built from smaller sub-operators, each of which may act on its own local Hilbert space. Some might act on just a few qubits, others on the full space. And each of those sub-operators may, in turn, be composed of even smaller building blocks. As a result, the overall operator can be naturally organized as a tree, with the highest-level operator at the root and more granular components forming the branches and leaves.
In the diagram, time flows from left to right. That is, an operator placed to the left of another in this structure will be applied earlier. Up to this point, we haven’t mentioned quantum circuits explicitly—although circuits could be one way to implement such a structure, the construction we’re describing is more general.
Now consider adding an operator at the lowest level of the tree, say to the branch all the way on the left.
In quantum computing, a unitary operator can be defined concretely using a sequence of low-level gates, similar in spirit to a classical list of instructions. But here’s the key difference: in quantum mechanics, the same operator can be executed in a variety of contexts which may change how they relate to the overall operator. For example:
- The operator might be executed in its inverse form.
- It might be controlled on the state of another qubit.
- It could appear inside a compute–uncompute block.
- Or it might occur within a Hadamard test, where it plays a role in an interference-based measurement.
Crucially, we don’t want to define a new operator for each such context. Instead, we define the operator once and annotate the tree with the context in which it should be interpreted. Since the context is not intrinsic to the operator itself—but rather to how it is being used—it makes sense to store that context in the parent node of the operator, not within the operator’s own definition.
And here’s where things get especially interesting: these contexts can interact with each other, and these interactions can be exploited for compilation. For example, when an operator is both controlled and wrapped in a compute–uncompute structure,
Thus, once we’ve constructed the overall operator tree, the first step in compilation is to resolve the hierarchy of contexts. This means systematically combining and simplifying the contexts so that the final operator realizes the correct unitary evolution in the most efficient manner.
This approach opens up a rich set of questions. Are there a finite set of physically meaningful contexts? Can their interactions be classified or composed in some principled way? Understanding these possibilities could guide future research and help define the semantics of high-level quantum programming.Coherent Computing is pioneering high-performance and user-friendly software platforms that unlock the full potential of quantum hardware. Get in touch with us to learn more.