<jupyter_start><jupyter_text>Easy Curcuitby <NAME> Install frameworks, and import libraries<jupyter_code>!pip install tensornetwork jax jaxlib colorama qcircuit
from qcircuit import QCircuit as qc
import numpy as np<jupyter_output><empty_output><jupyter_text>Let start creating a quantum circuit with an easy example (see image below). The circuit consists of two qubits, each of the qubit set to its initiall state:```1|0> + 0|1>```![picture](https://drive.google.com/uc?id=1EftxMH7R3eOrTxAA1FnEpgXEPv2e7oU_)On the first qubit I want to apply Hadamard gate which will bring the initial state of the first qubit to a superposition, in other words: $ H * (1|0> + 0|1>) = 1/\sqrt{2} \begin{pmatrix}   1 & 1  \\  1 & -1 \end{pmatrix} * \begin{pmatrix} 1 \\ 0 \end{pmatrix} = 1/\sqrt{2} \begin{pmatrix} 1 \\ 1 \end{pmatrix}$Or, saying in terms of states:$ 1/\sqrt{2} |0> + 1/\sqrt{2} |1> $,which means that a measurement will have equal probabilities to become 1 or 0. Now, I will apply CX (CNOT) gate on my system. CNOT gate acts on two qubit at the same time. One of the qubit serves as controll for the second one (target). Mathematicaly speaking, before applying CX gate on qubits I have to "connect" them. This "connection" can be done through tensor product (outer ptoduct): $ 1/\sqrt{2}(1|0> + 1|1>)$ x $(1|0> + 0|1>) =$  $1/\sqrt{2} (1|00> + 0|01> + 1|10> + 0|11>)$After the "connection" is done, CX gate is ready to act on the state vector of the system of two qubits:$ CX * \begin{pmatrix} 1/\sqrt{2} \\ 0 \\1/\sqrt{2} \\ 0 \end{pmatrix} = 1/\sqrt{2} \begin{pmatrix}   1 & 0 & 0 & 0  \\  0 & 1 & 0 & 0 \\  0 & 0 & 0 & 1 \\  0 & 0 & 1 & 0 \\\end{pmatrix} * \begin{pmatrix} 1 \\ 0 \\1 \\ 0 \end{pmatrix} = 1/\sqrt{2} \begin{pmatrix} 1 \\ 0 \\ 0 \\ 1 \end{pmatrix}$That means, after appling Hadamard and CNOT gate on the initial state of two qubit quantum curcuit, the resulting state of the circuit is:$1/\sqrt{2} (1|00> + 0|01> + 0|10> + 1|11>)$,which means that a measurement will have an equal probability of being |00> or |10>After we have learned what is under the mathematical hood, let me show how it can be easily implemented using QCurcuit class with build-in gate methods.First, I have to create an object of the QCirquit class, passing the size of the  circuit as an argument:```my_circuit = QCircuit(2)```Inside the quntum simulator the class automatically creates two qubits and sets them to the initiale states. Now, I will apply Hadamard gate (H() method). As an argument, I will pass the index of the qubit on which Hadamard gate acts:```my_circuit.H(0)```Following the same logic, I apply CX (CNOT) gate on my circuit passing as arguments control and target qubits respectively:```my_circuit.CX(control= [0], target = 1)```That's it! Now, I can measure the magnitutes of my resulting state simply by calling  ``` get_amplitude() ``` method. The magnitudes are being calculated as a length of the state vector on the Bloch sphere. In order to get the bitstring with its probability values, call  ``` get_bitstring() ``` method of the QCircuit class. Probability of the measurements being calculated as a multiplication of the coefficient before a [ket-vector](https://en.wikipedia.org/wiki/Bra%E2%80%93ket_notation) on its conjugated number.In addition, we can see the final state vector of the circuit calling  ``` get_state_vector() ``` method.Gathering all together, we will need a few lines of code to build the curcuit, apply gates and get the final state of the curcuit.<jupyter_code># Create two qubits quantum circuit
circuit_size = 2
my_circuit = qc.QCircuit(circuit_size)

# apply Hadamard gate on the q0
my_circuit.H(0)

# apply CX gate: q0 - controlled, q1-target
my_circuit.CX(control = [0], target = 1)

# get amplitude measurement and bitstring sampling
print("amplitude: ")
my_circuit.get_amplitude()
print("bitstring:")
bitstr, max_str = my_circuit.get_bitstring()
for index in range(2 ** circuit_size):
  b = np.binary_repr(index, width=circuit_size)
  probability = bitstr[index]
  print("|" + b + "> probability " + str(probability))

# state vector
state_vector = my_circuit.get_state_vector()
print("state vector", state_vector)<jupyter_output>amplitude: 
|00> amplitude 0.707
|01> amplitude 0.0
|10> amplitude 0.0
|11> amplitude 0.707
bitstring:
|00> probability 0.5
|01> probability 0.0
|10> probability 0.0
|11> probability 0.5
state vector [0.707+0.j 0.   +0.j 0.   +0.j 0.707+0.j]<jupyter_text>We can visualize the quantum cirquit by calling  ``` visualize() ``` method.Consider the lower case *x* as a controlled gate, and the upper case *X* as a target. Controled gates of the same color are the one being connected to each other.<jupyter_code>my_circuit.visualize()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11401475237091675, 'fraction_numerical': 0.03730242360379347, 'mean_word_length': 4.480369515011548, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 42, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '370086', 'license': 'Apache-2.0', 'n_tokens_mistral': 1641, 'n_tokens_neox': 1475, 'n_words': 628, 'path': 'tutorials/How_to_build_Simple_Quantum Circuit.ipynb', 'repo_name': 'MadhavJivrajani/QCircuit', 'size': '4749'}