Subsections

5 Creating and using operators


5.1 Pauli matrices

5.1.1 pauli -- pauli matrices$.$

pauli[$i$] creates the pauli matrices $(\sigma_0,\sigma_1,\sigma_2,\sigma_3)
=(\mathbb{1}_2,\sigma_x,\sigma_y,\sigma_z).$


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i12) [ pauli[0], pauli[...
...&\linebreak[0]0\cr 0&\linebreak[0]-1\cr } \right] \end{dmath}\end{boxedminipage}


Show that the ket ${\lvert 1 \rangle}_x$ is an eigenvector of $\sigma_x$ with eigenvalue $-1$.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i8) is ( pauli[1] . ket...
...batim}
\begin{dmath}[number={\%o8}]
\mathbf{true}\end{dmath}\end{boxedminipage}


Here are we check that all our definitions of the pauli matrices and kets are consistent in this sense.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i9) mapapply( lambda([i...
...]\mathbf{true},\linebreak[0]\mathbf{true} \right] \end{dmath}\end{boxedminipage}


Here we use anticommutator($op_1,op_2$) to test the anticommutation relations among the pauli matrices: $\{\sigma_i,\sigma_j\}= 2\delta_{i,j}$ for $i,j \in\{1,2,3\}.$


\begin{boxedminipage}{2.0\linewidth}
\index{genmatrix@{\bf genmatrix}}
\begin{ve...
...ix{1&\linebreak[0]0\cr
0&\linebreak[0]1\cr }\cr }\end{dmath}\end{boxedminipage}


The Maxima function mat_unblocker$\dagger$, flattens the blocks in the above expression, so we can write


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i4) identitymatrixp( ma...
...atim}
\begin{dmath}[number={\%o4}]
\mathbf{true}\end{dmath} \end{boxedminipage}


Now we load the itensor package, which provides the levi-civita tensor, and make use of the Maxima functions permutations$\dagger$ (which returns the set of all permutations of a list) and listify (which converts the set data type into the (ordered) list data type). The qinf package provides mapapply( $func,[list1, list2,\ldots]$), which apply s func to each of the lists and returns a list of the results. (see the Maxima documentation for apply$\dagger$.) With all these, we can test the commutation relations of the pauli matrices. (In reality, the matrix definitions are not complicated, we are actually testing the other functions.): $[\sigma_i,\sigma_j] = 2i\epsilon_{i,j,k}\sigma_k$.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i5) load(''itensor'');
...
...]\mathbf{true},\linebreak[0]\mathbf{true} \right] \end{dmath}\end{boxedminipage}


5.1.2 pauli_product -- tensor product of pauli matrices$.$

pauli_product( $i_1,\ldots,i_n$) returns the tensor product $\sigma_{i_1} \otimes \cdots \otimes \sigma_{i_n}$, where the indices $i_j$ are in $\{0,1,2,3\}$. As elsewhere in this document, $\sigma_0$ is the $2\times 2$ identity matrix.

The next three functions pauliexp($\rho$), invpauliexp($c$), and correlation_tensor( $c,i_1,\ldots,i_n$) are related. An example using them follows their definitions.

5.1.3 pauliexp -- expansion of operator in terms of tensor products of pauli matrices$.$

pauliexp($\rho$) returns the correlation tensor, that is, the coefficients in the expansion of the matrix $\rho$ in tensor products of pauli matrices. Explicitly, pauliexp returns the coefficients $c_{i_1,\ldots,i_n}$ in
(4) \begin{displaymath}
\rho = \sum_{i_1,\ldots,i_n=0}^3 c_{i_1,\ldots,i_n}  \sigma_{i_1} \otimes \cdots \otimes \sigma_{i_n}.
\end{displaymath}

$\rho$ must be a $2^n\times 2^n$ matrix. The coefficients are returned as a list of $2^n\times 2^n$ elements. The place of $c_{i_1,\ldots,i_n}$ in the returned list is determined by taking ${i_1,\ldots,i_n}$ to be the binary representation of an integer. For convenience, the coefficient can be retrieved by index with the function correlation_tensor.

5.1.4 invpauliexp -- inverse of expansion in terms of tensor products of pauli matrices$.$

invpauliexp($c$) is the inverse of pauiexp. Given a list $c$ representing the correlation tensor (i.e. expansion coefficients), invpauliexp returns the matrix $\rho$ given by (4).

5.1.5 correlation_tensor -- retrieve component of correlation tensor by index$.$

correlation_tensor( $c,i_1,\ldots,i_n$) returns the expansion coefficient for the term $\sigma_{i_1} \otimes \cdots \otimes \sigma_{i_n}$ in the expansion of $\rho$, where $c$ is the list of coefficients in the expansion of $\rho$ as given, for instance, by pauliexp.

5.1.6 Using pauliexp and invpauliexp; an example$.$

Here is an example using the three functions defined above. First we create three generic $2\times 2$ (complex) matrices.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i2) m1 : matrix([a1,b1]...
...2,d2]) $
(%i4) m3 : matrix([a3,b3],[c3,d3]) $
\end{verbatim}
\end{boxedminipage}


Here is the tensor product of the three matrices. This is not a generic element in the three qubit Hilbert space represented by $M(\mathbb{C},8)$. For instance, the three matrices have $12$ complex parameters while a generic matrix in the tensor product space has $64$ complex parameters.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i5) mp : m1 otimes m2 o...
...break[0]\mathrm{d1}\*\mathrm{d2}\*\mathrm{d3}\cr }\end{dmath}\end{boxedminipage}


We compute the correlation tensor of mp


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i6) pe : pauliexp(mp) $
\end{verbatim}
\end{boxedminipage}


Check that the tensor has $64$ elements and see what a coefficient looks like.


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i7) length(pe);
\end{ve...
...m{c1}+i\*\mathrm{a3}\*\mathrm{b1}\*\mathrm{b2}}{8}\end{dmath}\end{boxedminipage}


Check that the inverse of the expansion gives the original matrix back


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i9) is ( ratsimp( invpa...
...batim}
\begin{dmath}[number={\%o9}]
\mathbf{true}\end{dmath}\end{boxedminipage}


Here is the convenience function to return an element of the correlation tensor by index


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i10) correlation_tensor...
...m{c1}+i\*\mathrm{a3}\*\mathrm{b1}\*\mathrm{b2}}{8}\end{dmath}\end{boxedminipage}


5.2 spinor_rotation, spinor_rotation_trig$.$

spinor_rotation( $phi,theta,gamma$) returns the matrix that represents the operator that rotates a spinor through an angle gamma about the axis specified by phi (angle about the $z$-axis) and theta (inclination from the $z$-axis). The function spinor_rotation_trig( $phi,theta,gamma$) returns the same matrix expressed only with cosines and sines. This is the standard axis-angle parameterization. Explicitly the matrices are


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i2) spinor_rotation(phi...
...}\right)+\cos \left(\frac{\gamma}{2}\right)\cr }\end{dmath}.
\end{boxedminipage}


5.3 insert_operator -- insert single qubit operators in $n$-qubit operator

insert_operator( $nbits,[op1,i1,i2,..],[op2,j2,j2,...],...$) returns the operator $\mathbb{1}_2^{\otimes \mbox{nbits}}$, with some of the identity operators $\mathbb{1}_2$ substituted by the operators op1,op2,... at the indices specified by the indices $i1,i2,\ldots,j1,j2,\ldots$. Each replacement operator replaces a single qubit identity operator $\mathbb{1}_2$, even if the replacement operator has dimension other than $2$. For example

insert_operator(8,[pauli[1],1,3],[pauli[2],2,5],[pauli[3],8])
returns

\begin{displaymath}
\sigma_x \otimes \sigma_y \otimes \sigma_x \otimes \mathbb{1...
..._y \otimes \mathbb{1}_2 \otimes \mathbb{1}_2 \otimes \sigma_z.
\end{displaymath}

insert_operator is used to build the operators and gates listed below.


5.4 Gates

5.4.1 hadamard operator$.$

qinf defines both a variable and a function named hadamard. The value of the variable hadamard is as follows,


\begin{boxedminipage}{2.0\linewidth}
\begin{verbatim}(%i2) hadamard;
\end{verb...
...1}{\sqrt{2}}&\linebreak[0]-\frac{1}{\sqrt{2}}\cr }\end{dmath}\end{boxedminipage}


The function hadamard( $nbits,i1,i2,\ldots$) returns the tensor product of nbits one-qubit operators each of which is $\mathbb{1}_2$ except for the operators in positions i1,i2,... which are the hadamard operator given by the variable hadamard. The function is defined by hadamard(nbits,[t]) := insert_operator(nbits,cons(hadamard,t)), which is an idiom that will work for similar user defined functions as well. The dummy argument [t] causes all arguments after nbits to be collected in a single list. The Maxima function cons$\dagger$, invoked as cons($expr,list$), returns the list given by prepending expr to the list list.

5.4.2 controlled_gate -- gate with $n$ control qubits

A controlled gate applies an operator $m$ to a single qubit (the target) in a register only if each of a set of control qubits is set. Otherwise the operator is equivalent to the identity operator. In any case, the operator is the identity on every qubit other than the target. The function controlled_gate( $nbits,qop,t,clst$) creates a controlled gate with one or more control qubits embedded in a nbits-qubit operator. The target qubit is at the index t, while the control qubits are at the indices listed in the list clst. In the returned operator, the $\mathbb{1}_2$ operator is at the remaining positions. The controlled gate operator applies qop at qubit t if all of the control qubits are set (ie are $1$) and is equivalent to the identity operator otherwise. For instance a cnot operator on $H_2\otimes H_2$ is given by controlled_gate(2,pauli[1],2,[1]). The controlled gate in an $n$-qubit space with $n-1$ control bits and the $1$-qubit target operator $m$ is implemented in qinf as

\begin{displaymath}
\mathbb{1}_{2^n} + \left({\lvert 1 \rangle}{\langle 1 \rvert}\right)^{\otimes{n-1}}
\otimes (m-\mathbb{1}_2).
\end{displaymath}

In the case that this controlled gate operator is embedded in an operator in a larger space, the same formula is used, with additional factors of $\mathbb{1}_2$ inserted at the appropriate places. Also the target qubit may occupy any index. This is implemented via the insert_operator function described above.

5.4.3 cnot, cphase, crot$.$

cnot( $nbits,t,c1,c2,\ldots$) returns a cnot gate on an nbits-qubit register with the target at index t and control qubits at indices c1,c2,.... The definition of this function is cnot(nbits,t,[c]) := controlled_gate(nbits,pauli[1],t,c). The functions cphase and crot are defined in the same way except that operators pauli[3] and %i*pauli[2] respectively are substituted for pauli[1]. For example, the elementary cnot gate is given by cnot(2,2,1).

5.4.4 swap$.$

swap($nbits,t1,t2$) returns the operator that swaps qubits t1 and t2 in an nbits-qubit register. It is defined by swap(nbits,t1,t2) := cnot(nbits,t1,t2) . cnot(nbits,t2,t1) . cnot(nbits,t1,t2).

5.4.5 toffoli$.$

This function is provided for convenience. It is defined by toffoli(nbits,t,c1,c2) := cnot(nbits,t,c1,c2). Note that there are exactly two control qubits.

5.4.6 fredkin$.$

fredkin($nbits,t1,t2,c$) is controlled swap operator. The qubits at indices t1 and t2 are swapped if the control qubit at index c is set.



John Lapeyre 2008-09-02