Pauli Operators
The PauliOperator class enables building quantum operator expressions using natural mathematical notation.
Arithmetic operators (*, +, -) combine Pauli operators into products and sums, making it easy to construct Hamiltonians and other quantum expressions.
Creating Operators
Use factory methods to create Pauli operators on specific qubits:
#include <iostream>
#include <qdk/chemistry/data/pauli_operator.hpp>
using namespace qdk::chemistry::data;
int main() {
// Create Pauli operators on specific qubits
auto X0 = PauliOperator::X(0); // Pauli X on qubit 0
auto Y1 = PauliOperator::Y(1); // Pauli Y on qubit 1
auto Z2 = PauliOperator::Z(2); // Pauli Z on qubit 2
auto I0 = PauliOperator::I(0); // Identity on qubit 0
from qdk_chemistry.data import PauliOperator
# Create Pauli operators on specific qubits
X0 = PauliOperator.X(0) # Pauli X on qubit 0
Y1 = PauliOperator.Y(1) # Pauli Y on qubit 1
Z2 = PauliOperator.Z(2) # Pauli Z on qubit 2
I0 = PauliOperator.I(0) # Identity on qubit 0
Building Expressions
Combine operators using arithmetic to build expressions:
// Scalar multiplication
auto scaled = 0.5 * PauliOperator::X(0);
auto scaled_complex = std::complex<double>(1, 2) * PauliOperator::Z(1);
// Products of operators
auto product = PauliOperator::X(0) * PauliOperator::Z(1);
// Sums of operators
auto sum_expr = PauliOperator::X(0) + PauliOperator::Y(1);
// Building a Hamiltonian-like expression
auto H = 0.5 * PauliOperator::X(0) * PauliOperator::X(1) +
0.5 * PauliOperator::Y(0) * PauliOperator::Y(1) +
1.0 * PauliOperator::Z(0) * PauliOperator::Z(1);
std::cout << H.to_string() << std::endl;
// "0.5 * X(0) * X(1) + 0.5 * Y(0) * Y(1) + Z(0) * Z(1)"
# Scalar multiplication
scaled = 0.5 * PauliOperator.X(0)
scaled_complex = (1 + 2j) * PauliOperator.Z(1)
# Products of operators
product = PauliOperator.X(0) * PauliOperator.Z(1)
# Sums of operators
sum_expr = PauliOperator.X(0) + PauliOperator.Y(1)
# Building a Hamiltonian-like expression
H = (
0.5 * PauliOperator.X(0) * PauliOperator.X(1)
+ 0.5 * PauliOperator.Y(0) * PauliOperator.Y(1)
+ 1.0 * PauliOperator.Z(0) * PauliOperator.Z(1)
)
print(H) # "0.5 * X(0) * X(1) + 0.5 * Y(0) * Y(1) + Z(0) * Z(1)"
Simplifying Expressions
The simplify() method applies Pauli algebra rules and combines like terms.
The distribute() method expands products over sums.
// Pauli algebra: X * X = I (identity)
auto xx = PauliOperator::X(0) * PauliOperator::X(0);
auto result = xx.simplify();
std::cout << result->to_string() << std::endl; // "1"
// Pauli algebra: X * Y = iZ
auto xy = PauliOperator::X(0) * PauliOperator::Y(0);
result = xy.simplify();
std::cout << result->to_string() << std::endl; // "i * Z(0)"
// Combining like terms
auto duplicate = PauliOperator::X(0) + PauliOperator::X(0);
result = duplicate.simplify();
std::cout << result->to_string() << std::endl; // "2 * X(0)"
// Distributing products over sums
auto nested =
PauliOperator::X(0) * (PauliOperator::Y(1) + PauliOperator::Z(1));
auto distributed = nested.distribute();
std::cout << distributed->to_string() << std::endl;
// "X(0) * Y(1) + X(0) * Z(1)"
# Pauli algebra: X * X = I (identity)
xx = PauliOperator.X(0) * PauliOperator.X(0)
result = xx.simplify()
print(result) # "1"
# Pauli algebra: X * Y = iZ
xy = PauliOperator.X(0) * PauliOperator.Y(0)
result = xy.simplify()
print(result) # "1j * Z(0)"
# Combining like terms
duplicate = PauliOperator.X(0) + PauliOperator.X(0)
result = duplicate.simplify()
print(result) # "2 * X(0)"
# Distributing products over sums
nested = PauliOperator.X(0) * (PauliOperator.Y(1) + PauliOperator.Z(1))
distributed = nested.distribute()
print(distributed) # "X(0) * Y(1) + X(0) * Z(1)"
Canonical Representation
Use to_canonical_string() to get a circuit-compatible string format, or to_canonical_terms() to get coefficient-string pairs:
// Get canonical string representation (little-endian: qubit 0 leftmost)
auto expr = PauliOperator::X(0) * PauliOperator::Z(2);
auto simplified = expr.simplify();
auto canonical = simplified->to_canonical_string(4); // 4 qubits total
std::cout << canonical << std::endl; // "XIZI"
// Get coefficient and string pairs for each term
auto terms = simplified->to_canonical_terms(4);
// terms[0] = {(1+0i), "XIZI"}
// For sums, get all terms
auto H2 = PauliOperator::X(0) + PauliOperator::Z(1);
auto sum_terms = H2.to_canonical_terms(2);
// sum_terms = [{(1+0i), "XI"}, {(1+0i), "IZ"}]
# Get canonical string representation (little-endian: qubit 0 leftmost)
expr = PauliOperator.X(0) * PauliOperator.Z(2)
simplified = expr.simplify()
canonical = simplified.to_canonical_string(4) # 4 qubits total
print(canonical) # "XIZI"
# Get coefficient and string pairs for each term
terms = simplified.to_canonical_terms(4)
print(terms) # [((1+0j), 'XIZI')]
# For sums, get all terms
H = PauliOperator.X(0) + PauliOperator.Z(1)
terms = H.to_canonical_terms(2)
print(terms) # [((1+0j), 'XI'), ((1+0j), 'IZ')]
Further Reading
The above examples can be downloaded as complete C++ and Python scripts.
QubitMapper: Maps molecular Hamiltonians to Pauli operator representations.