Source code for qlazy.lib.mpstate_func

# -*- coding: utf-8 -*-
""" functions for MPState """

import numpy as np
from collections import Counter

from qlazy.util import get_qgate_qubit_num, is_measurement_gate, is_reset_gate
import qlazy.config as cfg

[docs]def mps_operate_qcirc(mps, cmem, qcirc, shots, cid): qcirc_unitary, qcirc_non_unitary = qcirc.split_unitary_non_unitary() # unitary part while True: kind = qcirc_unitary.kind_first() if kind is None: break (kind, qid, para, c, ctrl, tag) = qcirc_unitary.pop_gate() if ctrl is None or (ctrl is not None and cmem.bits[ctrl] == 1): phase = para[0] * para[2] if get_qgate_qubit_num(kind) == 1: mps.operate_1qubit_gate(cfg.GATE_STRING[kind], qid[0], phase) elif get_qgate_qubit_num(kind) == 2: mps.operate_2qubit_gate(cfg.GATE_STRING[kind], qid[0], qid[1], phase) else: raise ValueError("invalid gate description: {}".format(kind, qid, para, c, ctrl)) # non-unitary part if qcirc_non_unitary.kind_first() is None: # non-unitary part includes no gates frequency = None elif qcirc_non_unitary.all_gates_measurement() is True: # non-unitary part includes measurements only q_list = [] c_list = [] bits_array = np.array([0] * cmem.cmem_num) while True: kind = qcirc_non_unitary.kind_first() if kind is None: break (kind, qid, para, c, ctrl, tag) = qcirc_non_unitary.pop_gate() if ctrl is None or (ctrl is not None and cmem.bits[ctrl] == 1): q_list.append(qid[0]) c_list.append(c) md = mps.m(qid=q_list, shots=shots) frequency = Counter() for k, v in md.frequency.items(): m_list = list(map(int, list(k))) b_list = [0] * cmem.cmem_num for i, q in enumerate(q_list): b_list[c_list[i]] = m_list[i] b_list = [b_list[c] for c in cid] bits = "".join(map(str, b_list)) frequency[bits] = v else: frequency = Counter() for n in range(shots): qc_tmp = qcirc_non_unitary.clone() if n == shots - 1: mps_tmp = mps else: mps_tmp = mps.clone() b_list = [0] * cmem.cmem_num while True: kind = qc_tmp.kind_first() if kind is None: break (kind, qid, para, c, ctrl, tag) = qc_tmp.pop_gate() if ctrl is None or (ctrl is not None and cmem.bits[ctrl] == 1): phase = para[0] if is_measurement_gate(kind) is True: mval = int(mps_tmp.measure(qid=[qid[0]])) b_list[c] = mval cmem.set_bits(b_list) elif is_reset_gate(kind) is True: mps_tmp.reset(qid=[qid[0]]) elif get_qgate_qubit_num(kind) == 1: mps_tmp.operate_1qubit_gate(cfg.GATE_STRING[kind], qid[0], phase) elif get_qgate_qubit_num(kind) == 2: mps_tmp.operate_2qubit_gate(cfg.GATE_STRING[kind], qid[0], qid[1], phase) else: raise ValueError("invalid gate description: {}".format(kind, qid, para, c, ctrl)) b_list = [b_list[c] for c in cid] bits = "".join(map(str, b_list)) frequency[bits] += 1 return frequency