def test_tensor_product_dm(self): num_qubit = 4 dm1 = qulacs.DensityMatrix(num_qubit) dm2 = qulacs.DensityMatrix(num_qubit) dm1.set_Haar_random_state(seed=0) dm2.set_Haar_random_state(seed=1) dm3 = qulacs.state.tensor_product(dm1, dm2) dm3_test = np.kron(dm1.get_matrix(), dm2.get_matrix()) self.assertTrue(np.allclose(dm3_test, dm3.get_matrix()), msg="check density matrix tensor product") del dm1 del dm2 del dm3
def test_permutate_qubit_dm(self): num_qubit = 3 dm = qulacs.DensityMatrix(num_qubit) dm.set_Haar_random_state(seed=0) order = np.arange(num_qubit) np.random.shuffle(order) arr = [] for ind in range(2**num_qubit): s = format(ind, "0{}b".format(num_qubit)) s = np.array(list(s[::-1])) v = np.array(["*"] * num_qubit) for ind in range(len(s)): v[order[ind]] = s[ind] s = ("".join(v))[::-1] arr.append(int(s, 2)) dm_perm = qulacs.state.permutate_qubit(dm, order) dm_perm_test = dm.get_matrix() dm_perm_test = dm_perm_test[arr, :] dm_perm_test = dm_perm_test[:, arr] self.assertTrue(np.allclose(dm_perm_test, dm_perm.get_matrix()), msg="check density matrix permutation") del dm_perm del dm
def _base_iterator(self, circuit: circuits.Circuit, qubit_order: ops.QubitOrderOrList, initial_state: Union[int, np.ndarray], perform_measurements: bool = True) -> Iterator: qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( circuit.all_qubits()) num_qubits = len(qubits) qubit_map = {q: i for i, q in enumerate(qubits)} matrix = to_valid_density_matrix(initial_state, num_qubits, dtype=self._dtype) if len(circuit) == 0: yield DensityMatrixStepResult(matrix, {}, qubit_map, dtype=self._dtype) matrix = np.reshape(matrix, (2**num_qubits, 2**num_qubits)) noisy_moments = self.noise.noisy_moments(circuit, sorted(circuit.all_qubits())) state = qulacs.DensityMatrix(num_qubits) state.load(matrix) for moment in noisy_moments: measurements = collections.defaultdict( list) # type: Dict[str, List[bool]] operations = moment.operations for op in operations: indices = [ num_qubits - 1 - qubit_map[qubit] for qubit in op.qubits ] indices.reverse() if isinstance(op, ops.MeasurementGate): # Not implemented raise NotImplementedError( "Measurement is not supported in qulacs simulator") else: gate = cast(ops.GateOperation, op).gate channel = protocols.channel(gate) qulacs_gates = [] for krauss in channel: krauss = krauss.astype(np.complex128) qulacs_gate = qulacs.gate.DenseMatrix(indices, krauss) qulacs_gates.append(qulacs_gate) qulacs_cptp_map = qulacs.gate.CPTP(qulacs_gates) qulacs_cptp_map.update_quantum_state(state) matrix = state.get_matrix() matrix = np.reshape(matrix, (2, ) * num_qubits * 2) yield DensityMatrixStepResult(density_matrix=matrix, measurements=measurements, qubit_map=qubit_map, dtype=self._dtype)
def test_density_matrix(self): num_qubit = 5 sv = qulacs.StateVector(num_qubit) dm = qulacs.DensityMatrix(num_qubit) sv.set_Haar_random_state(seed=0) dm.load(sv) svv = np.atleast_2d(sv.get_vector()).T mat = np.dot(svv, svv.T.conj()) self.assertTrue(np.allclose(dm.get_matrix(), mat), msg="check pure matrix to density matrix")
def test_partial_trace_dm(self): num_qubit = 5 num_traceout = 2 dm = qulacs.DensityMatrix(num_qubit) dm.set_Haar_random_state(seed=0) mat = dm.get_matrix() target = np.arange(num_qubit) np.random.shuffle(target) target = target[:num_traceout] target_cor = [num_qubit-1-i for i in target] target_cor.sort() dmt = mat.reshape([2,2]*num_qubit) for cnt,val in enumerate(target_cor): ofs = num_qubit - cnt dmt = np.trace(dmt, axis1=val-cnt, axis2=ofs+val-cnt) dmt = dmt.reshape([2**(num_qubit-num_traceout),2**(num_qubit-num_traceout)]) pdm = qulacs.state.partial_trace(dm, target) self.assertTrue(np.allclose(pdm.get_matrix(), dmt), msg="check density matrix partial trace") del dm,pdm
def _base_iterator(self, circuit: circuits.Circuit, qubit_order: ops.QubitOrderOrList, initial_state: Union[int, np.ndarray], perform_measurements: bool = True) -> Iterator: qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( circuit.all_qubits()) num_qubits = len(qubits) qubit_map = {q: i for i, q in enumerate(qubits)} matrix = density_matrix_utils.to_valid_density_matrix( initial_state, num_qubits, self._dtype) if len(circuit) == 0: yield DensityMatrixStepResult(matrix, {}, qubit_map, self._dtype) def on_stuck(bad_op: ops.Operation): return TypeError( "Can't simulate operations that don't implement " "SupportsUnitary, SupportsApplyUnitary, SupportsMixture, " "SupportsChannel or is a measurement: {!r}".format(bad_op)) def keep(potential_op: ops.Operation) -> bool: return (protocols.has_channel(potential_op) or (ops.op_gate_of_type(potential_op, ops.MeasurementGate) is not None) or isinstance(potential_op, (ops.SamplesDisplay, ops.WaveFunctionDisplay, ops.DensityMatrixDisplay))) matrix = np.reshape(matrix, (2**num_qubits, 2**num_qubits)) noisy_moments = self.noise.noisy_moments(circuit, sorted(circuit.all_qubits())) state = qulacs.DensityMatrix(num_qubits) state.load(matrix) for moment in noisy_moments: measurements = collections.defaultdict( list) # type: Dict[str, List[bool]] channel_ops_and_measurements = protocols.decompose( moment, keep=keep, on_stuck_raise=on_stuck) for op in channel_ops_and_measurements: #indices = [qubit_map[qubit] for qubit in op.qubits] indices = [ num_qubits - 1 - qubit_map[qubit] for qubit in op.qubits ] indices.reverse() if isinstance(op, (ops.SamplesDisplay, ops.WaveFunctionDisplay, ops.DensityMatrixDisplay)): continue # TODO: support more general measurements. meas = ops.op_gate_of_type(op, ops.MeasurementGate) if meas: # Not implemented raise NotImplementedError( "Measurement is not supported in qulacs simulator") else: # TODO: Use apply_channel similar to apply_unitary. gate = cast(ops.GateOperation, op).gate channel = protocols.channel(gate) qulacs_gates = [] for krauss in channel: krauss = krauss.astype(np.complex128) qulacs_gate = qulacs.gate.DenseMatrix(indices, krauss) qulacs_gates.append(qulacs_gate) qulacs_cptp_map = qulacs.gate.CPTP(qulacs_gates) qulacs_cptp_map.update_quantum_state(state) matrix = state.get_matrix() matrix = np.reshape(matrix, (2, ) * num_qubits * 2) yield DensityMatrixStepResult(density_matrix=matrix, measurements=measurements, qubit_map=qubit_map, dtype=self._dtype)