Skip to main content

Spin-½ Operator Transformations

At a glance

  • Special transformations can be done on operator expressions comprised exclusively of spin 1/2 operators.
  • Spin-1/2 operator expression can be reordered while respecting the bosonic algebra.
  • Particular simplifications can be done to operator expressions comprised of single site spin-1/2 operators, namely pauli strings.
Prerequisites

This document will assume you are familiar with general operator transformations and spin-1/2 operators. Feel free to consult them before reading this concept if you have not done so already.

Overview of transformations

There are currently three exclusively spin-1/2 operator transformations that are available in aleph:

  1. reorder_by_site sorts operators by site index for canonical ordering while obeying commutation relations
  2. simplify_paulis simplifies pauli operators according to the pauli algebra.
  3. commutator returns ABBAAB - BA for two spin-1/2 operators A,BA,B

The first transformation can be useful to put operator expression into a canonical order according to their sites without commuting terms within the local hilbert space. The second one on the other hand will simplify pauli operators according to the pauli algebra

[σmα,σnβ]=2iϵαβγδm,nσmγ[\sigma^{\alpha}_{m},\sigma^{\beta}_{n}] = 2i\epsilon_{\alpha \beta \gamma} \delta_{m,n} \sigma^{\gamma}_{m}

where α,β,γ{x,y,z}\alpha, \beta, \gamma \in \{ x,y,z \}. The last transformation calculates the commutator of two spin-1/2 operators, which can be further simplified or used in numerical calculations.

Using transformations

Reorder by site

The reorder_by_site function sorts operators in ascending order of site index while preserving quantum commutation rules. That is, given an operator expression

E=m=1MOm1Om2OmnE = \sum_{m=1}^{M} O_{m_1} O_{m_2} \dots O_{m_n}

the transformation orders EE into

E=m=1MOm1Om2OmnE' = \sum_{m=1}^{M} O_{m'_1} O_{m'_2} \dots O_{m'_n}

where {mi}\{ m'_i \} are such that mimi+1 m'_i \leq m'_{i+1}, i.e. they are now ordered. Importantly, in order to respect the bosonic algebra of spin-1/2 operators

[Am,Bn]=Cmδm,n,CmEnd(C2)[A_m,B_n] = C_{m} \delta_{m,n} , \quad C_{m} \in \text{End}(\mathbb{C}^{2})

no operators are commuted with each other during this process. We can see this with the input operator expression

S=2.0×X2Y0+3.0×Z1X0S = 2.0 \times X_2 Y_0 + 3.0 \times Z_1 X_0
var S = operator_sum(2.0 * (X(2) * Y(0)) + 3.0 * (Z(1) * X(0)), as_real);
var reordered = reorder_by_site(S);
// Result: 2.0 * Y(0) * X(2) + 3.0 * X(0) * Z(1)

The out of the reordering only occurs between operators with disjoint support (acting on different qubits) so quantum mechanical commutation relationships are preserved. If we instead had a term with X(0) * Y(0) , then it wouldn't be reordered since both operators act on the same site.

var S = operator_sum(2.0 * (X(2) * Y(0)) + 3.0 * (Z(1) * X(0)) + 1.0 * (X(0) * Y(0)), as_real);
var reordered = reorder_by_site(S);
// Result: 2.0 * Y(0) * X(2) + 3.0 * X(0) * Z(1) + 1.0 * X(0) * Y(0)

Further simplifications can be done by calling merge after the operator has been reordered. This reorder ensures that all terms with the same operators but in different orders can be identified with each other and hence simplified.

var S = X(1) * Y(0) + Y(0) * X(1); // Same operators, different order
var reordered = reorder_by_site(S);
// Result: Y(0) * X(1) + Y(0) * X(1)
merge(reordered);
// Result: 2.0 * Y(0) * X(1)

Simplifying pauli strings

Special expressions can be manipulated and simplified utilizing known properties of the operators, namely pauli operators i.e. {σ0,σx,σy,σz}={I,X,Y,Z}\{ \sigma^{0}, \sigma^x , \sigma^y , \sigma^z \} = \{I, X, Y, Z \}. General expressions made up of these operators are called pauli strings and are of the form

S=m=1Mσm1α1σm2α2σmnαn,σmjαj{σ0,σx,σy,σz}={I,X,Y,Z}.S = \sum_{m=1}^{M} \sigma^{\alpha_1}_{m_1} \sigma^{\alpha_2}_{m_2} \dots \sigma^{\alpha_n}_{m_n} , \quad \sigma^{\alpha_j}_{m_j} \in \{ \sigma^{0}, \sigma^x , \sigma^y , \sigma^z \} = \{I, X, Y, Z \}.

In this case, simplify_paulis applies Pauli algebra rules to operators in operator expressions on the same site resulting in the simplification of the pauli operators via the following identities,

X2=Y2=Z2=I, XY=iZ, YZ=iX, ZX=iYX^2 = Y^2 = Z^2 = I, \ XY = iZ, \ YZ = iX, \ ZX = iY

The function transforms the operator expression in place and returns a complex coefficient, merging like terms together ensuring all terms in the expression are unique. The behaviour of this function depends on the input type:

  • If the input is an OperatorProduct comprised of Pauli operators, the returned complex number is the value of the phase accrued from applying the Pauli algebra to the expression.
  • If the input is a ComplexOperatorSum comprised of Pauli operators, the returned number is 1.0 while the sum is updated.

Since Aleph enforces variable types to be immutable, simplify_paulis cannot modify the type of the object in place so the function is designed to keep the input object the same type, but modifies its contents. RealOperatorSums are not valid for this reason and will throw an error. The interface is the same for both input cases:

// operator as a product
var prod = operator_prod(X(0) * Y(0))
var phase = simplify_paulis(prod) // phase = (0.0,1,0), prod = Z(0)
// operator as a sum
var sum = operator sum(X(0) * Y(0))
var phase = simplify_paulis(sum) // phase = (1.0,0.0), sum = (0.0,1.0) * Z(0)

The variable declaration for the phase does not need to be present for both products and sums and can be called inline as simplify_paulis(input) if the phase information is not needed. An optional real number eps can be passed to prune the sum, discarding all Pauli strings with a coefficient cnc_n with a norm less than eps:

var sum = operator_sum(X(0)*Y(1) + 1e-12*Z(0))
var eps = 1e-8 // second term will be removed
simplify_paulis(sum,eps) // sum = (1.0,0.0) * X(0) * Y(1)

A more general workflow would involve performing several operations on a spinhalf operator expression with general transformations and then simplify further at the end with simplify_paulis. This may require some casting of the expression in terms of Pauli operators before applying the final simplifications. This way, flatten, merge, and prune can help reduce the number of final terms to fully simplify with simplify_paulis.

tip

When working with Pauli operators, its best practice to apply the general transformations first that potentially reduce the number of terms in the expression and then use simplify_paulis at the end.

var term1 = X(0)*Y(0) + Z(1); // Pauli products
var term2 = X(2) + Y(2);
var S = operator_sum(2.0*term1*term2 + 3.0*X(0)*Y(0)*X(2) + 1e-15*Z(3)); // Nested, duplicates, and noise

// Step 1: Flatten nested structures
flatten(S);
// Result: 2*X(0)*Y(0)*X(2) + 2*X(0)*Y(0)*Y(2) + 2*Z(1)*X(2) + 2*Z(1)*Y(2) + 3*X(0)*Y(0)*X(2) + 1e-15*Z(3)

// Step 2: Merge duplicate terms, can also reorder before if needed
merge(S);
// Result: 5*X(0)*Y(0)*X(2) + 2*X(0)*Y(0)*Y(2) + 2*Z(1)*X(2) + 2*Z(1)*Y(2) + 1e-15*Z(3)

// Step 3: Prune with custom tolerance
prune(S, 1e-10); // Removes 1e-15*Z(3)
// Result: 5*X(0)*Y(0)*X(2) + 2*X(0)*Y(0)*Y(2) + 2*Z(1)*X(2) + 2*Z(1)*Y(2)

// Step 4: Simplify Pauli products (XY -> iZ)
var final = simplify_paulis(S);
// Final: (0+5i) * Z(0) * X(2) + (0+2i) * Z(0) * Y(2) + (2+0i) * Z(1) * X(2) + (2+0i) * Z(1) * Y(2)

In the above example, steps 2,3,4 can be done in one call to simplify_paulis as the input expression is comprised solely of Pauli operators.

Compute commutators

Evaluating the commutator of two operators [A,B]=ABBA[A,B] = AB - BA is a fundamental operation in quantum mechanics. In the case of spin-1/2 degrees of freedom, operators commute with themselves and with those that have disjoint support. The commutator function uses this knowledge when applicable and returns an explicit calculation of the commutator of two spin-1/2 operator expressions.

var comm = commutator(X(0), Y(0)); // Returns (1+0i)*X(0)*Y(0) + (-1+-0i)*Y(0)*X(0)

Like any given operator expresison, the output is not simplified. Using general and spin-1/2 transformations, expressions can be simplified and truncated to suit your numerical needs or symbolic calculation. In the particular case of pauli operators we can simplify the result even further,

var comm = commutator(X(1), Y(1));
// Returns (1) * X(1) * Y(1) + (-1) * Y(1) * X(1)
simplify_paulis(comm);
// Returns (0+2i) * Z(1)

As mentioned above, in the case of the operators being identical or have disjoint support, the commutator automatically returns an empty operator representing zero.

var iden = commutator(X(0), X(0));
// Returns ()
var disJ = commutator(X(0), X(1));
// Returns ()

This is useful for optimization - you can skip expensive commutator calculations for disjoint operators, or identify which operators commute with your system Hamiltonian or circuit!

Detailed documentation

To check out more detailed documentation see Transformations in the Library Reference.

Documentation Contributors

Eunji Yoo

Sebastien J. Avakian

Jonathon Riddell