跳转至

StringMarkOracle

QuICT.algorithm.oracle.StringMarkOracle

StringMarkOracle(target_string: Union[str, List[str]], mode: _ORACLE_MODE = 'phase')

Bases: CompositeGate

Construct a oracle that will flip phases on states denoted by strings.

Parameters:

  • target_string (str | List[str]) –

    a single string or a list of string that wants flip the phase on.

Source code in QuICT/algorithm/oracle/string_mark_oracle.py
def __init__(
    self,
    target_string: Union[str, List[str]],
    mode: _ORACLE_MODE = "phase"
):
    """
    Args:
        target_string (str | List[str]): a single string or a list of string that wants flip the phase on.
    """
    if len(target_string) < 1:
        raise ValueError("Target string cannot be empty.")

    super().__init__(name="O_str")

    if isinstance(target_string, str):
        target_string = [target_string]

    target_string = list(set(target_string))

    self.targ_bit_len = len(target_string[0])

    if not self._same_length(target_string, self.targ_bit_len):
        raise ValueError("Target strings must have the same length.")

    target_proc_gate: BasicGate
    total_ancilla = []
    if mode == "phase":
        target_proc_gate = X
        total_ancilla.append(self.targ_bit_len)
    else:
        target_proc_gate = H

    cg = CompositeGate()

    target_proc_gate | cg(self.targ_bit_len)

    prev_s = "1" * self.targ_bit_len
    for i in range(len(target_string)):
        cur_s = target_string[i]
        self._build_oracle_core(prev_s, cur_s) | cg
        prev_s = cur_s
    for idx, bit in enumerate(target_string[-1]):
        if bit == '0':
            X | cg(idx)

    target_proc_gate | cg(self.targ_bit_len)

    total_ancilla += MCZOneAux(self.targ_bit_len).ancilla_qubits

    h_rm_idx = []
    gate_list = cg.flatten_gates(True)
    for idx, gate in enumerate(gate_list):
        if gate.type != GateType.h:
            gate | self
            continue

        adj_h_idx = self._find_adj_h(gate_list, idx)
        if adj_h_idx > 0 and idx not in h_rm_idx:
            h_rm_idx += [idx, adj_h_idx]

        if idx not in h_rm_idx:
            gate | self

    self.set_ancilla(total_ancilla)