Data Encoding
Code Demonstration
This section provides code implementations for key techniques introduced earlier, including quantum read-in strategies and block encoding, to give readers the opportunity to practice and deepen their understanding.
Read-in implementations
This subsection demonstrates toy examples of implementing data encoding methods in quantum computing, as discussed in earlier sections. Specifically, we cover basis encoding, amplitude encoding, and angle encoding. These examples aim to provide readers with hands-on experience in applying quantum data encoding techniques.
Basis encoding
PennyLane provides built-in support for basis encoding through its BasisEmbedding function. Below is the Python code demonstrating the basis encoding for the integer 6.
import pennylane as qml
dev = qml.device("default.qubit", range(3))
@qml.qnode(dev)
def circuit(x):
qml.BasisEmbedding(x, range(3))
return qml.state()
# Call the function
circuit(6)
Amplitude encoding
PennyLane offers built-in support for amplitude encoding via the AmplitudeEmbedding function. Below is a Python example demonstrating amplitude encoding for a randomly generated complex vector.
import pennylane as qml
import numpy as np
# Number of qubits
n_qubits = 8
# Define a quantum device with 8 qubits
dev = qml.device("default.qubit", wires=n_qubits)
@qml.qnode(dev)
def circuit(x):
qml.AmplitudeEmbedding(features=x, wires=range(n_qubits), normalize=True, pad_with=0.)
return qml.state()
# Generate a random complex vector of length 2^n_qubits
x_real = np.random.normal(loc=0, scale=1.0, size=2**n_qubits)
x_imag = np.random.normal(loc=0, scale=1.0, size=2**n_qubits)
x = x_real + 1j * x_imag
# Execute the circuit to encode the vector as a quantum state
circuit(x)
Angle encoding
PennyLane provides built-in support for angle encoding via the AngleEmbedding function. Below is a Python example demonstrating angle encoding for a randomly generated real vector.
import pennylane as qml
import numpy as np
# Number of qubits
n_qubits = 8
# Define a quantum device with 8 qubits
dev = qml.device("default.qubit", wires=n_qubits)
@qml.qnode(dev)
def circuit(x):
qml.AngleEmbedding(features=x, wires=range(n_qubits), rotation="X")
return qml.state()
# Generate a random real vector of length n_qubits
x = np.random.uniform(0, np.pi, (n_qubits))
# Execute the circuit to encode the vector as a quantum state
circuit(x)
Block encoding
Here, we provide an example of how we may construct a block encoding. We construct the block encoding via the linear combination. We use PennyLane to keep consistency, yet there are many other platforms that are available as well. Please note that it is time-consuming to do the Pauli decomposition (for $n$-qubit matrix, it takes time $\mathcal{O}(n4^n)$), so we suggest not trying a large matrix with this method.
import numpy as np
import pennylane as qml
import matplotlib.pyplot as plt
a = 0.36
b = 0.64
# matrix to be decomposed
A = np.array(
[[a, 0, 0, b],
[0, -a, b, 0],
[0, b, a, 0],
[b, 0, 0, -a]]
)
# decompose the matrix into sum of Pauli strings
LCU = qml.pauli_decompose(A)
LCU_coeffs, LCU_ops = LCU.terms()
# normalized square roots of coefficients
alphas = (np.sqrt(LCU_coeffs) / np.linalg.norm(np.sqrt(LCU_coeffs)))
dev = qml.device("default.qubit", wires=3)
# unitaries
ops = LCU_ops
# relabeling wires: 0 --> 1, and 1 --> 2
unitaries = [qml.map_wires(op, {0: 1, 1: 2}) for op in ops]
@qml.qnode(dev)
def lcu_circuit(): # block_encode
# PREP
qml.StatePrep(alphas, wires=0)
# SEL
qml.Select(unitaries, control=0)
# PREP_dagger
qml.adjoint(qml.StatePrep(alphas, wires=0))
return qml.state()
print(np.real(np.round(output_matrix,2)))