def teleportation(psi): qr = QuantumRegister(3) crz = ClassicalRegister(1) crx = ClassicalRegister(1) qc = QuantumCircuit(qr, crz, crx) init_gate = Initialize(psi) qc.append(init_gate, [alice]) qc.barrier() create_bell_pair(qc, common, bob) qc.barrier() create_alice(qc, alice, common) qc.barrier() measure_and_send(qc, alice, common) qc.barrier() create_bob(qc, bob, crz, crx) print(qc.draw()) result = execute(qc, Aer.get_backend('statevector_simulator')).result() print(result.get_statevector()) reverse_init_gate = init_gate.gates_to_uncompute() qc.append(reverse_init_gate, [bob]) print(qc.draw()) cr_result = ClassicalRegister(1) qc.add_register(cr_result) qc.measure(bob, 2) print(qc.draw()) result = execute(qc, Aer.get_backend('qasm_simulator')).result() print(result.get_counts())
def from_vector(statevector: np.ndarray) -> 'CircuitStateFn': """ Construct the CircuitStateFn from a vector representing the statevector. Args: statevector: The statevector representing the desired state. Returns: The CircuitStateFn created from the vector. """ normalization_coeff = np.linalg.norm(statevector) normalized_sv = statevector / normalization_coeff return CircuitStateFn(Initialize(normalized_sv), coeff=normalization_coeff)
def from_vector(statevector: np.ndarray) -> 'CircuitStateFn': """ Construct the CircuitStateFn from a vector representing the statevector. Args: statevector: The statevector representing the desired state. Returns: The CircuitStateFn created from the vector. Raises: ValueError: If a vector with complex values is passed, which the Initializer cannot handle. """ normalization_coeff = np.linalg.norm(statevector) normalized_sv = statevector / normalization_coeff if not np.all(np.abs(statevector) == statevector): # TODO maybe switch to Isometry? raise ValueError('Qiskit circuit Initializer cannot handle non-positive statevectors.') return CircuitStateFn(Initialize(normalized_sv), coeff=normalization_coeff)
def __init__( self, num_qubits: Union[int, List[int]], mu: Optional[Union[float, List[float]]] = None, sigma: Optional[Union[float, List[float]]] = None, bounds: Optional[Union[Tuple[float, float], List[Tuple[float, float]]]] = None, upto_diag: bool = False, name: str = "P(X)", ) -> None: r""" Args: num_qubits: The number of qubits used to discretize the random variable. For a 1d random variable, ``num_qubits`` is an integer, for multiple dimensions a list of integers indicating the number of qubits to use in each dimension. mu: The parameter :math:`\mu`, which is the expected value of the distribution. Can be either a float for a 1d random variable or a list of floats for a higher dimensional random variable. Defaults to 0. sigma: The parameter :math:`\sigma^2` or :math:`\Sigma`, which is the variance or covariance matrix. Default to the identity matrix of appropriate size. bounds: The truncation bounds of the distribution as tuples. For multiple dimensions, ``bounds`` is a list of tuples ``[(low0, high0), (low1, high1), ...]``. If ``None``, the bounds are set to ``(-1, 1)`` for each dimension. upto_diag: If True, load the square root of the probabilities up to multiplication with a diagonal for a more efficient circuit. name: The name of the circuit. """ _check_dimensions_match(num_qubits, mu, sigma, bounds) _check_bounds_valid(bounds) # set default arguments dim = 1 if isinstance(num_qubits, int) else len(num_qubits) if mu is None: mu = 0 if dim == 1 else [0] * dim if sigma is None: sigma = 1 if dim == 1 else np.eye(dim) if bounds is None: bounds = (-1, 1) if dim == 1 else [(-1, 1)] * dim if isinstance(num_qubits, int): # univariate case super().__init__(num_qubits, name=name) x = np.linspace(bounds[0], bounds[1], num=2**num_qubits) # type: Any else: # multivariate case super().__init__(sum(num_qubits), name=name) # compute the evaluation points using numpy.meshgrid # indexing 'ij' yields the "column-based" indexing meshgrid = np.meshgrid( *[ np.linspace(bound[0], bound[1], num=2**num_qubits[i]) # type: ignore for i, bound in enumerate(bounds) ], indexing="ij", ) # flatten into a list of points x = list(zip(*[grid.flatten() for grid in meshgrid])) from scipy.stats import multivariate_normal # compute the normalized, truncated probabilities probabilities = multivariate_normal.pdf(x, mu, sigma) normalized_probabilities = probabilities / np.sum(probabilities) # store the values, probabilities and bounds to make them user accessible self._values = x self._probabilities = normalized_probabilities self._bounds = bounds # use default the isometry (or initialize w/o resets) algorithm to construct the circuit # pylint: disable=no-member if upto_diag: self.isometry(np.sqrt(normalized_probabilities), self.qubits, None) else: from qiskit.extensions import Initialize # pylint: disable=cyclic-import initialize = Initialize(np.sqrt(normalized_probabilities)) circuit = initialize.gates_to_uncompute().inverse() self.compose(circuit, inplace=True)
def quantum_teleporation_experiment(): experiment = Experiment("quantum_teleportation") qc = QuantumCircuit(1) # Create a quantum circuit with one qubit psi = [1 / sqrt(2), 1 / sqrt(2)] # Define initial_state in a superposition state initial_state = Initialize(psi) qc.append(initial_state, [0]) # Apply initialisation operation to the 0th qubit result = execute(qc, Aer.get_backend('statevector_simulator')).result( ) # Do the simulation, returning the result exp_state = result.get_statevector(qc) qr = QuantumRegister(3) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.append(initial_state, [0]) circuit.barrier() circuit.h(qr[1]) circuit.cx(qr[1], qr[2]) circuit.barrier() circuit.cx(qr[0], qr[1]) circuit.h(qr[0]) circuit.barrier() circuit.cz(qr[0], qr[2]) circuit.cx(qr[1], qr[2]) circuit.measure(qr[2], cr) t = time.time() backend = Aer.get_backend('qasm_simulator') job_circuit = execute(circuit, backend=backend, shots=4096) device_counts = job_circuit.result().get_counts(circuit) experiment.write_measurement(device_counts) qc = QuantumRegister(3) circuit = QuantumCircuit(qc) circuit.append(initial_state, [0]) circuit.barrier() circuit.h(qc[1]) circuit.cx(qc[1], qc[2]) circuit.barrier() circuit.cx(qc[0], qc[1]) circuit.h(qc[0]) circuit.barrier() circuit.cz(qc[0], qc[2]) circuit.cx(qc[1], qc[2]) t = time.time() qst_circuit = state_tomography_circuits(circuit, qc[2]) job_circuit = execute(qst_circuit, backend=backend, shots=4096) tomo_circuit = StateTomographyFitter(job_circuit.result(), qst_circuit) tomo_circuit.data rho_circuit = tomo_circuit.fit() F_state = state_fidelity(exp_state, rho_circuit) pur = purity(rho_circuit) experiment.write_metric("purity", float(pur)) experiment.write_metric("fit_fidelity_state", float(F_state)) experiment.write_metric("execution time", int(time.time() - t)) experiment.write_parameter("backend", "qasm_simulator") experiment.write_parameter("number of shots", 4096) experiment.write_parameter("job id", str(job_circuit.job_id())) experiment.save_exoeriment() print("WOOHOO!") # that exact feeling when your code is working
teleportation_circuit.draw(output='mpl') # In[16]: #STEP 5 COMEBACK HERE! #import a helpful package for math stuff including sqrt from math import * #define a state for a single qubit psi = [1 / sqrt(2), 1 / sqrt(2)] from qiskit.extensions import Initialize #qcircuit.initialize #This initialize circuits NOT states init_gate = Initialize(psi) teleportation_circuit.append( init_gate, [0]) #use init gate on ALice's qubit to put it into that state. # In[17]: ''' Step 1 Alice has the first qubit in some state psi Bob has the third qubit Bob entangles his qubit with a the second qubit ancillary qubit to make the teleportation. ''' ###Set up entanglement between Bob's and ancillary qubit teleportation_circuit.h(1)
def __init__(self, num_qubits: Union[int, List[int]], mu: Optional[Union[float, List[float]]] = None, sigma: Optional[Union[float, List[float]]] = None, bounds: Optional[Union[Tuple[float, float], List[Tuple[float, float]]]] = None, upto_diag: bool = False, name: str = 'P(X)') -> None: r""" Args: num_qubits: The number of qubits used to discretize the random variable. For a 1d random variable, ``num_qubits`` is an integer, for multiple dimensions a list of integers indicating the number of qubits to use in each dimension. mu: The parameter :math:`\mu` of the distribution. Can be either a float for a 1d random variable or a list of floats for a higher dimensional random variable. sigma: The parameter :math:`\sigma^2` or :math:`\Sigma`, which is the variance or covariance matrix. bounds: The truncation bounds of the distribution as tuples. For multiple dimensions, ``bounds`` is a list of tuples ``[(low0, high0), (low1, high1), ...]``. If ``None``, the bounds are set to ``(0, 1)`` for each dimension. upto_diag: If True, load the square root of the probabilities up to multiplication with a diagonal for a more efficient circuit. name: The name of the circuit. """ _check_dimensions_match(num_qubits, mu, sigma, bounds) _check_bounds_valid(bounds) # set default arguments dim = 1 if isinstance(num_qubits, int) else len(num_qubits) if mu is None: mu = 0 if dim == 1 else [0] * dim if sigma is None: sigma = 1 if dim == 1 else np.eye(dim) if bounds is None: bounds = (0, 1) if dim == 1 else [(0, 1)] * dim if not isinstance(num_qubits, list): # univariate case super().__init__(num_qubits, name=name) x = np.linspace(bounds[0], bounds[1], num=2**num_qubits) # evaluation points else: # multivariate case super().__init__(sum(num_qubits), name=name) # compute the evaluation points using numpy's meshgrid # indexing 'ij' yields the "column-based" indexing meshgrid = np.meshgrid(*[ np.linspace(bound[0], bound[1], num=2**num_qubits[i]) for i, bound in enumerate(bounds) ], indexing='ij') # flatten into a list of points x = list(zip(*[grid.flatten() for grid in meshgrid])) # compute the normalized, truncated probabilities probabilities = [] from scipy.stats import multivariate_normal for x_i in x: # pylint: disable=line-too-long # map probabilities from normal to log-normal reference: # https://stats.stackexchange.com/questions/214997/multivariate-log-normal-probabiltiy-density-function-pdf if np.min(x_i) > 0: det = 1 / np.prod(x_i) probability = multivariate_normal.pdf(np.log(x_i), mu, sigma) * det else: probability = 0 probabilities += [probability] normalized_probabilities = probabilities / np.sum(probabilities) # store as properties self._values = x self._probabilities = normalized_probabilities self._bounds = bounds # use default the isometry (or initialize w/o resets) algorithm to construct the circuit # pylint: disable=no-member if upto_diag: self.isometry(np.sqrt(normalized_probabilities), self.qubits, None) else: from qiskit.extensions import Initialize # pylint: disable=cyclic-import initialize = Initialize(np.sqrt(normalized_probabilities)) circuit = initialize.gates_to_uncompute().inverse() self.compose(circuit, inplace=True)
def Q4C(NumberOfStrokes): # Define vectors for Each stroke Thaa = [10, 75, 10, 50, 25, 50, 25, 50, 75, 50, 0, 0, 0, 0, 0, 0] Ki = [75, 10, 75, 75, 95, 50, 5, 5, 10, 50, 0, 0, 0, 0, 0, 0] Thom = [10, 75, 25, 75, 25, 50, 50, 50, 75, 50, 0, 0, 0, 0, 0, 0] Nam = [50, 75, 75, 25, 5, 95, 95, 25, 25, 50, 0, 0, 0, 0, 0, 0] Ta = [50, 95, 95, 5, 5, 5, 75, 25, 5, 50, 0, 0, 0, 0, 0, 0] Dhin = [50, 50, 50, 95, 5, 50, 95, 25, 5, 50, 0, 0, 0, 0, 0, 0] Mi = [25, 5, 50, 95, 75, 95, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0] Cha = [50, 5, 50, 25, 25, 25, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0] Chapu = [75, 10, 75, 25, 5, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0] Kaarvai = [50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0] # Then calculate the norm from the frequency distribution Norm_Thaa = linalg.norm(Thaa) Norm_Ki = linalg.norm(Ki) Norm_Thom = linalg.norm(Thom) Norm_Nam = linalg.norm(Nam) Norm_Ta = linalg.norm(Ta) Norm_Dhin = linalg.norm(Dhin) Norm_Mi = linalg.norm(Mi) Norm_Cha = linalg.norm(Cha) Norm_Chapu = linalg.norm(Chapu) Norm_Kaarvai = linalg.norm(Kaarvai) # Then normalize the vector to be used with the QuGate Thaa_Norm = Thaa / Norm_Thaa Ki_Norm = Ki / Norm_Ki Thom_Norm = Thom / Norm_Thom Nam_Norm = Nam / Norm_Nam Ta_Norm = Ta / Norm_Ta Dhin_Norm = Dhin / Norm_Dhin Mi_Norm = Mi / Norm_Mi Cha_Norm = Cha / Norm_Cha Chapu_Norm = Chapu / Norm_Chapu Kaarvai_Norm = Kaarvai / Norm_Kaarvai InitialState = [ Thaa_Norm, Ki_Norm, Thom_Norm, Nam_Norm, Ta_Norm, Dhin_Norm, Mi_Norm, Cha_Norm, Chapu_Norm, Kaarvai_Norm ] ProbState = [Thaa, Ki, Thom, Nam, Ta, Dhin, Mi, Cha, Chapu, Kaarvai] # Print all the normalized input vectors #for item in InitialState: # print(item) # Select an arbitray input state using random function # Though this means that all the states have equal probability as input, # it is still a valid assumption for the use-case firstSelect = True while (firstSelect): input_state = random.randint(0, len(InitialState)) if (input_state != 6 or input_state != 9): firstSelect = False # Defining Backend for Quantum Simulator backend = Aer.get_backend('statevector_simulator') # Initialise our qubit and measure it NumberofQbits = 4 NumberofQuOutputBits = 4 # Define the Quantum Circuit qc = QuantumCircuit(NumberofQbits, NumberofQuOutputBits) FinalList = [] for i in range(0, NumberOfStrokes): redo_stroke = True # print("State " + str (i) + " is " + FindStrokeWithIndex(input_state)) FinalList.append(FindStrokeWithIndex(input_state)) while (redo_stroke): randomSelect = True # Now that the ciruit is setup - Algorithm to generate Music initializer = Initialize(InitialState[input_state]) initializer.label = str("input stroke") qc.append(initializer, [0, 1, 2, 3]) qc.h(0) qc.h(1) qc.h(2) qc.h(3) qc.measure_all() # qc.draw() # State Vector Simulator for Output result = execute(qc, backend).result() counts = result.get_counts() next_state = (list(counts.keys())[list( counts.values()).index(1)]).split()[0] if (int(next_state, 2) < 10 and ProbState[input_state][int(next_state, 2)] >= 25): redo_stroke = False input_state = int(next_state, 2) if (i == NumberOfStrokes - 2): if (input_state == 1 or input_state == 3 or input_state == 5 or input_state == 6): redo_stroke = False else: redo_stroke = True return (FinalList)
qc.measure(qr[b], crz) #Bobs transformation def bob_transformation(qc, qubit): qc.barrier() qc.x(qubit).c_if(crx, 1) qc.z(qubit).c_if(crz, 1) #note: bob's transformation may change depending upon the entanglement channel #creating a state that we want to teleport : alice will be the sender state = random_statevector(2, seed=3) state.probabilities() init_gate = Initialize(state.data) qc.append(init_gate, [0]) create_ent_channel(qc, 1, 2) bell_measurement(qc, 0, 1) bob_transformation(qc, 2) #qc.draw('mpl') #thus the bob qubit will be transformed to state which alice want to sent. #state of the alice's qubit get collapsed during the process '''#checking the bobs state backend=BasicAer.get_backend('statevector_simulator') in_state=state plot_bloch_multivector(in_state)''' disentangler = init_gate.gates_to_uncompute() #re
def initialize_teleport_state(qc, tel_qbit, state): init_gate = Initialize(state) init_gate.label = "init" qc.append(init_gate, [tel_qbit]) return qc
from matplotlib import * import teleport_algo # Initialise backend. backend = Aer.get_backend('statevector_simulator') # Initialise Circuit. inp = QuantumRegister(1, name='input register') out = QuantumRegister(1, name='output register') circuit = QuantumCircuit(inp, out) # Set input register to a random state. psi = random_state(1) array_to_latex(psi, pretext="|\\psi\\rangle =") plot_bloch_multivector(psi) init_gate = Initialize(psi) circuit.append(init_gate, [inp]) circuit.barrier() # Perform teleportation. teleport_algo.quantum_teleport(circuit, inp, out) # Execute simulation and display result. job = execute(circuit, backend) result = job.result() outputstate = result.get_statevector(circuit, decimals=4) array_to_latex(psi, pretext="|output\\rangle =") plot_bloch_multivector(outputstate) print(circuit.draw())
def __init__(self, num_qubits: Union[int, List[int]], cdfs: Union[Callable[[float], float], List[Callable[[float], float]]], sigma: Optional[Union[float, List[float]]] = None, bounds: Optional[Union[Tuple[float, float], List[Tuple[float, float]]]] = None, pdfs: Optional[Union[Callable[[float], float], List[Callable[[float], float]]]] = None, dx: Optional[float] = 1e-6, upto_diag: bool = False, name: str = 'P(X)') -> None: r""" Args: num_qubits: The number of qubits used to discretize the random variable. For a 1d random variable, ``num_qubits`` is an integer, for multiple dimensions a list of integers indicating the number of qubits to use in each dimension. cdfs: The cumulative marginal probability density functions for each dimension. sigma: The parameter :math:`\sigma^2` or :math:`\Sigma`, which is the correlation matrix. Defaults to the identity matrix of appropriate size. bounds: The truncation bounds of the distribution as tuples. For multiple dimensions, ``bounds`` is a list of tuples ``[(low0, high0), (low1, high1), ...]``. If ``None``, the bounds are set to ``(-1, 1)`` for each dimension. pdfs: The marginal probability density functions for each dimension. If ''None'', marginal pdf is calculated from the pdf by finite differences, but consider using automatic differentiation of cdf. dx: The spacing, if finite differences is used to calculate the pdf. upto_diag: If True, load the square root of the probabilities up to multiplication with a diagonal for a more efficient circuit. name: The name of the circuit. """ _check_dimensions_match(num_qubits, cdfs, pdfs, sigma, bounds) _check_bounds_valid(bounds) # set default arguments dim = 1 if isinstance(num_qubits, int) else len(num_qubits) mu = 0 if dim == 1 else [0] * dim if sigma is None: sigma = 1 if dim == 1 else np.eye(dim) if bounds is None: bounds = (-1, 1) if dim == 1 else [(-1, 1)] * dim if not isinstance(cdfs, list): cdfs = [cdfs] if pdfs is None: pdfs = [lambda x: derivative(cdf, x, dx=dx) for cdf in cdfs] if not isinstance(num_qubits, list): # univariate case super().__init__(num_qubits, name=name) x = np.linspace(bounds[0], bounds[1], num=2**num_qubits) else: # multivariate case super().__init__(sum(num_qubits), name=name) # compute the evaluation points using numpy's meshgrid # indexing 'ij' yields the "column-based" indexing meshgrid = np.meshgrid(*[ np.linspace(bound[0], bound[1], num=2**num_qubits[i]) for i, bound in enumerate(bounds) ], indexing='ij') # flatten into a list of points x = list(zip(*[grid.flatten() for grid in meshgrid])) from scipy.stats import multivariate_normal # compute the normalized, truncated probabilities probabilities = multivariate_normal.pdf(x, mu, sigma) xa = np.asarray(x, dtype=float) zeta = np.concatenate([ norm.ppf(cdfs[i](xa[:, i])).reshape(xa.shape[0], 1) for i in range(dim) ], 1) probabilities = multivariate_normal.pdf(zeta, mu, sigma) * np.exp( 0.5 * np.sum(np.square(zeta), axis=-1)) * np.sqrt((2 * np.pi)**dim) for i in range(xa.shape[1]): probabilities = probabilities * pdfs[i](xa[:, i]) normalized_probabilities = probabilities / np.sum(probabilities) # store the values, probabilities and bounds to make them user accessible self._values = x self._probabilities = normalized_probabilities self._bounds = bounds # use default the isometry (or initialize w/o resets) algorithm to construct the circuit # pylint: disable=no-member if upto_diag: self.isometry(np.sqrt(normalized_probabilities), self.qubits, None) else: from qiskit.extensions import Initialize # pylint: disable=cyclic-import initialize = Initialize(np.sqrt(normalized_probabilities)) circuit = initialize.gates_to_uncompute().inverse() self.compose(circuit, inplace=True)