Esempio n. 1
0
def controlled_gate(gate, c_qubit):
    input_qubits = [c_qubit] + gate.input_qubits
    if gate.func is None:
        U = gate.tensor
        sh, _ = U.shape
        I = np.eye(sh)
        zero0 = np.zeros((sh, sh))
        zero1 = np.zeros((sh, sh))
        A = np.hstack([I, zero0])
        B = np.hstack([zero1, U])
        gate = qtc.Gate(input_qubits, tensor=np.vstack([A, B]))
        return gate
    else:

        def func(params):
            U = gate.func(params)
            sh, _ = U.shape
            I = np.eye(sh)
            zero0 = np.zeros((sh, sh))
            zero1 = np.zeros((sh, sh))
            A = np.hstack([I, zero0])
            B = np.hstack([zero1, U])
            return np.vstack([A, B])

        func_jit = jit(func)
        res = qtc.Gate(input_qubits, params=gate.params, func=func_jit)
        return res
Esempio n. 2
0
    def allocate_gates(self):
        q_input = copy.deepcopy(self._q_support)
        del_qnum = self._gate_input_num - self._gate_output_num
        prior_measure_qubits = []
        gate_index = 0
        disentangler_index = 0
        def get_disentangler_params():
            if self._disentangler_params_num is None:
                return None
            else:
                return np.array(onp.random.randn(self._disentangler_params_num))
        def get_gate_params():
            if self._gate_params_num is None:
                return None
            else:
                return np.array(onp.random.randn(self._gate_params_num))
        while True:
            for i in range(self._gate_input_num - 1, len(q_input) - 1, self._gate_input_num):
                input_qubits = [q_input[i], q_input[i+1]]
                self._gates.append(qtnc.Gate(input_qubits=input_qubits, params=get_disentangler_params(),
                    func =self._disentangler_func, is_updated=self._is_updated, name="disentangler"))
                disentangler_index += 1
            i = 0
            while self._gate_input_num <= len(q_input) - i:
                input_qubits = []
                for j in range(self._gate_input_num):
                    input_qubits.append(q_input[i + j])
                self._gates.append(qtnc.Gate(input_qubits=input_qubits, params=get_gate_params(),
                    func=self._gate_func, is_updated=self._is_updated, name="gate"))
                gate_index += 1
                prior_measure_qubits.extend(q_input[i:i+del_qnum])
                del q_input[i:i+del_qnum]
                i += self._gate_output_num
            if len(q_input) < self._gate_input_num:
                break
            q_input = q_input[::-1]

        self._prior_measure_qubits =q_input + prior_measure_qubits[::-1]
Esempio n. 3
0
    def allocate_gates(self):
        q_input = copy.deepcopy(self._q_support)
        del_qnum = self._gate_input_num - self._gate_output_num
        used_qubits = 0
        def get_gate_params():
            if self._gate_params_num is None:
                return None
            else:
                return np.array(onp.random.randn(self._gate_params_num))
        for i in range(0, len(q_input) - self._gate_input_num + 1, del_qnum):
            input_qubits = [q_input[i + j] for j in range(self._gate_input_num)]
            used_qubits = input_qubits[-1]
            self._gates.append(qtnc.Gate(input_qubits=input_qubits, params=get_gate_params(), 
                func=self._gate_func, is_updated=self._is_updated))

        q_input = q_input[:used_qubits+1]
        self._prior_measure_qubits = q_input[::-1]
Esempio n. 4
0
 def allocate_gates(self):
     q_input = copy.deepcopy(self._q_support)
     q_len = int(math.sqrt(len(q_input)))
     prior_measure_qubits = []
     def get_gate_params():
         if self._gate_params_num is None:
             return None
         else:
             return np.array(onp.random.randn(self._gate_params_num))
     for loop_i in range(int(math.log(self._q_width, self._gate_w_input_num))):
         print(loop_i)
         for h in range(0, q_len, self._gate_h_input_num**(loop_i+1)):
             for w in range(0, q_len, self._gate_w_input_num**(loop_i+1)):
                 input_qubits = []
                 for hin in range(h, h+self._gate_h_input_num**(loop_i+1), self._gate_h_input_num**loop_i):
                     for win in range(w, w+self._gate_w_input_num**(loop_i+1), self._gate_w_input_num**loop_i):
                         input_qubits.append(q_input[hin*q_len + win])
                         if hin != 0 and win != 0:
                             prior_measure_qubits.append(q_input[hin*q_len + win])
                 self._gates.append(qtnc.Gate(input_qubits=input_qubits, params=get_gate_params(), 
                     func=self._gate_func, is_updated=self._is_updated))
     prior_measure_qubits.append(q_input[0])
     self._prior_measure_qubits = prior_measure_qubits[::-1]
Esempio n. 5
0
 def allocate_gates(self):
     q_input = copy.deepcopy(self._q_support)
     del_qnum = self._gate_input_num - self._gate_output_num
     prior_measure_qubits = []
     def get_gate_params():
         if self._gate_params_num is None:
             return None
         else:
             return np.array(onp.random.randn(self._gate_params_num))
     while True:
         i = 0
         while self._gate_input_num <= len(q_input) - i:
             input_qubits = []
             for j in range(self._gate_input_num):
                 input_qubits.append(q_input[i + j])
             self._gates.append(qtnc.Gate(input_qubits=input_qubits, params=get_gate_params(), 
                 func=self._gate_func, is_updated=self._is_updated))
             prior_measure_qubits.extend(q_input[i:i+del_qnum])
             del q_input[i:i+del_qnum]
             i += self._gate_output_num
         if len(q_input) < self._gate_input_num:
             break
         q_input = q_input[::-1]
     self._prior_measure_qubits =q_input + prior_measure_qubits[::-1]
Esempio n. 6
0
def combine_gates(gates):
    input_qubits = []
    qubit_indexes = []
    cont_indexes = []
    cont_shapes = []
    params = []
    for gate in gates:
        cont_shapes.append(gate.shape)
        index_str = ""
        for q in gate.input_qubits:
            if q not in input_qubits:
                input_qubits.append(q)
                qubit_indexes.append(2 * len(gates) * (len(input_qubits) - 1))
            ind = input_qubits.index(q)
            index_str += oe.get_symbol(qubit_indexes[ind])
            qubit_indexes[ind] += 1
        for q in gate.input_qubits:
            ind = input_qubits.index(q)
            index_str += oe.get_symbol(qubit_indexes[ind])
        cont_indexes.append(index_str)
        if gate.params is not None:
            params.extend(gate.params)

    cont_str = ""
    for i in range(len(cont_indexes)):
        if i != 0:
            cont_str += ","
        cont_str += cont_indexes[i]

    cont_out_str = ""
    for i in range(len(input_qubits)):
        cont_out_str += oe.get_symbol(2 * len(gates) * i)
    for i in range(len(input_qubits)):
        cont_out_str += oe.get_symbol(qubit_indexes[i])
    cont_str = cont_str + "->" + cont_out_str

    if params is None:
        cont_tensors = []
        for gate in gates:
            cont_tensors.append(gate.tensor.T.reshape(gate.shape))
        tensor = oe.contract(cont_str,
                             *cont_tensors).reshape(2**len(input_qubits), -1).T
        gate = qtc.Gate(input_qubits, tensor=tensor)
        return gate

    else:

        def func(params):
            cont_tensors = []
            idx = 0
            for gate in gates:
                if gate.params is not None:
                    cont_tensors.append(
                        gate.get_tensor_from_params(
                            params[idx:idx + len(gate.params)]).T.reshape(
                                gate.shape))
                    idx += len(gate.params)
                else:
                    cont_tensors.append(gate.tensor.T.reshape(gate.shape))
            return oe.contract(cont_str,
                               *cont_tensors).reshape(2**len(input_qubits),
                                                      -1).T

        func_jit = jit(func)
        params = np.array(params)
        gate = qtc.Gate(input_qubits, params=params, func=func_jit)
        return gate