Qubits.java
package org.redfx.strange;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A class to manage names of qubits and the mapping to the qubit index.
*/
public class Qubits<T> {
private Map<T, Integer> qubits = new HashMap<>();
/**
* Initializes with the provided Qubit keys.
*
* @param keys the initial qubit keys
* @throws IllegalArgumentException if there are duplicate keys
*/
public Qubits(T... keys) {
for (T key : keys) {
newBit(key);
}
}
/**
* Gets the number of qubit keys.
*
* @return the number of qubits
*/
public int numberOfQubits() {
return qubits.size();
}
/**
* Returns a list of the qubit keys.
*
* @return the list of qubit keys
*/
public List<T> qubitKeys() {
return List.copyOf(qubits.keySet());
}
/**
* Registers a new qubit key and returns its index.
*
* @param key the key for the new qubit
* @return the index of the new qubit
* @throws IllegalArgumentException if the key already exists
*/
public int newBit(T key) {
if (qubits.containsKey(key)) {
throw new IllegalArgumentException("Qubit " + key + " already exists, use bit(key) to retrieve it.");
}
int index = qubits.size();
qubits.put(key, index);
return index;
}
/**
* Returns the index of the qubit for the given key.
*
* @param key the key for the qubit
* @return the index of the qubit
* @throws IllegalArgumentException if the key does not exist
*/
public int bit(T key) {
if (! qubits.containsKey(key)) {
throw new IllegalArgumentException("Qubit " + key + " isn't known, use newBit(key) to create it first.");
}
return qubits.get(key);
}
/**
* Creates a new Program with these qubits and the given steps.
*
* @param steps the steps to be included in the program
* @return a new Program instance containing the specified steps
*/
public Program programOf(Step... steps) {
return new Program(this.numberOfQubits(), steps);
}
/**
* <p>Getter for the field <code>qubits</code>.</p>
*
* @return an array of {@link org.redfx.strange.Qubit} objects
*/
public Map<T, Qubit> getQubits(Result result) {
Qubit[] qubits = result.getQubits();
Map<T, Qubit> qubitMap = new HashMap<>();
for (T key : qubitKeys()) {
qubitMap.put(key, qubits[bit(key)]);
}
return qubitMap;
}
// Factory methods for gates
public Gate cnot(T a, T b) { return Gate.cnot(bit(a), bit(b)); }
public Step cnotStep(T a, T b) { return new Step(cnot(a, b)); }
public Gate cz(T a, T b) { return Gate.cz(bit(a), bit(b)); }
public Step czStep(T a, T b) { return new Step(cz(a, b)); }
public Gate hadamard(T q) { return Gate.hadamard(bit(q)); }
public Step hadamardStep(T q) { return new Step(hadamard(q)); }
// ...
}