I am working on a dataset where I have 6 input features that are numbers in the range of 1 - 1000 that need to be encoded as a quantum circuit. I am using TensorFlow Quantum for my research. While I have come across papers that explain angle encoding and amplitude encoding quite well, I have not quite been able to understand how to express the math in TFQ. I went through the Quantum MNIST tutorial on the TFQ pages but the way the images are encoded there is vastly different from how how numeric data rows would be encoded. Any help guiding me to encode this data would be appreciated!
I can lend some ideas, but since I don't know exactly what you're after I will have to guess a bit.
Looking at the original snippet from the MNIST tutorial:
def convert_to_circuit(image): """Encode truncated classical image into quantum datapoint.""" values = np.ndarray.flatten(image) qubits = cirq.GridQubit.rect(4, 4) circuit = cirq.Circuit() for i, value in enumerate(values): if value: circuit.append(cirq.X(qubits[i])) return circuit
It's clear that if a pixel is turned on there is an X gate applied to that qubit. Building off of this we can try something like:
def convert_to_circuit(row): """Encode a vector with features in [1, 1000] using angle-encoding""" values = (np.ndarray.flatten(row).astype(np.float32) - 1) / 999 qubits = cirq.GridQubit.rect(1, len(values)) circuit = cirq.Circuit(cirq.X(q) ** v for v,q in zip(values, qubits)) return circuit
Which applies an X rotation on each qubit proportional to that features value (if
row == 321 then qubit 5 would be given
cirq.X ** 0.321 and if
row == 1000 then qubit 6 in the circuit would be given a full
cirq.X ** 1.0 rotation). Here the rotations are normalized to the range $[0, 1]$. If I wanted to get them between $[-\pi, \pi]$ we could do something like:
def convert_to_circuit(row): """Encode a vector with features in [1, 1000] using angle-encoding""" values = (np.ndarray.flatten(row).astype(np.float32) - 1) / 999 values = values * (2 * np.pi) - np.pi qubits = cirq.GridQubit.rect(1, len(values)) circuit = cirq.Circuit(cirq.rx(v)(q) for v,q in zip(values, qubits)) return circuit
This is a rough implementation of "angle encoding" like is talked about here or here. You could then feed these datapoint circuits into any downstream TFQ model (as long as they acted on the same qubits of course).
For some more ideas check out the scheme used here or here it contains a few (decently well written) examples that might give you some inspiration on encoding you data. In general the field doesn't have complete consensus on what "the absolute best encoding to use for all cases" is so you have to try stuff, do some math and see what works. Hope this helps.