You are expected to complete this assignment individually. If you need help, you are invited to come to office hours and/or ask questions on Canvas. Clarification questions about the assignments may be asked publicly. Once you have specific bugs related to your code, make the posts private.
In this lab, we are adding the functionality to perform arbitrary operations on multiple qubits using matrix multiplication. In particular, we are generalizing the one- and two-qubit implementations to n qubits.
If you want to add "helper" functions that aren't specified in the assignment, you are welcome to do so. If you want it to be used by all classes, place it in the parent class. If it is specific to a subclass, place it there. We will only test the functions specified, but you're always allowed to add private or protected methods.
You should build off of your last week's assignment. You will add the files NQubit.java, QCircuit.java, QOracle.java.
Make sure you add to your Makefile as you complete classes. In addition, you need to create skeletons so that your code will compile properly.
The next step is to implement QCircuit. Each method of QCircuit implements a circuit (a sequence of quantum gates). Below, I'll give you the interface and, if the circuit wasn't taught in class, a picture of the circuit. You need to implement that circuit. For the two involving the oracle, read ahead to the Oracle section so that you see what you are calling.
This class has only methods - it has no state. For each method, the state comes in as input arguments and is returned, and there is no reason for it to store anything. Therefore, we will only implement static methods. There is no data stored in this class. You can see how to implement and call static methods here. Specifically, when called, you use the class name rather than a variable name prior to the period (e.g. QCircuit.entangle(...)).
The next step is to implement QOracle. This implements two oracles: Archimedes and BernVaz.
This class holds the state for two oracles: BernVaz and Archimedes. You need to figure out how, given a code(BernVaz) or set of codes (Archimedes) you can initialize the matrix to implement the desired functionality.