예제 #1
0
파일: tensor_math.py 프로젝트: xbe/qcc
def hipster_multi():
    """Multi-qubit, optimized application."""

    nbits = 7
    for bits in helper.bitprod(nbits):
        psi = state.bitstring(*bits)
        for target in range(1, nbits):
            # Full matrix (O(n*n).
            op = (ops.Identity(target - 1) * ops.Cnot(target - 1, target) *
                  ops.Identity(nbits - target - 1))
            psi1 = op(psi)

            # Single Qubit (O(n))
            psi = apply_controlled_gate(ops.PauliX(), target - 1, target, psi)
            if not psi.is_close(psi1):
                raise AssertionError('Invalid Single Gate Application.')

    psi = state.bitstring(1, 1, 0, 0, 1)
    pn = ops.Cnot(1, 4)(psi, 1)
    if not pn.is_close(apply_controlled_gate(ops.PauliX(), 1, 4, psi)):
        raise AssertionError('Invalid Cnot')
    pn = ops.Cnot(4, 1)(psi, 1)
    if not pn.is_close(apply_controlled_gate(ops.PauliX(), 4, 1, psi)):
        raise AssertionError('Invalid Cnot')
    pn = ops.ControlledU(0, 1, ops.ControlledU(1, 4, ops.PauliX()))(psi)

    psi = state.qubit(alpha=0.6) * state.ones(2)
    pn = ops.Cnot(0, 2)(psi)
    if not pn.is_close(apply_controlled_gate(ops.PauliX(), 0, 2, psi)):
        raise AssertionError('Invalid Cnot')
예제 #2
0
def fulladder_matrix(psi: state.State):
  """Non-quantum-exploiting, classic full adder."""

  psi = ops.Cnot(0, 3)(psi, 0)
  psi = ops.Cnot(1, 3)(psi, 1)
  psi = ops.ControlledU(0, 1, ops.Cnot(1, 4))(psi, 0)
  psi = ops.ControlledU(0, 2, ops.Cnot(2, 4))(psi, 0)
  psi = ops.ControlledU(1, 2, ops.Cnot(2, 4))(psi, 1)
  psi = ops.Cnot(2, 3)(psi, 2)
  return psi
예제 #3
0
    def test_controlled_z(self):
        """Exercise 4.18 in Nielson, Chuang, CZ(0, 1) == CZ(1, 0)."""

        z0 = ops.ControlledU(0, 1, ops.PauliZ())
        z1 = ops.ControlledU(1, 0, ops.PauliZ())
        self.assertTrue(z0.is_close(z1))

        z0 = ops.ControlledU(0, 7, ops.PauliZ())
        z1 = ops.ControlledU(7, 0, ops.PauliZ())
        self.assertTrue(z0.is_close(z1))
예제 #4
0
  def test_dft(self):
    """Build 'manually' a 3 qubit gate, Nielsen/Chuang Box 5.1."""

    h = ops.Hadamard()

    op = ops.Identity(3)
    op = op(h, 0)
    op = op(ops.ControlledU(1, 0, ops.Rk(2)), 0)  # S-gate
    op = op(ops.ControlledU(2, 0, ops.Rk(3)), 0)  # T-gate
    op = op(h, 1)
    op = op(ops.ControlledU(1, 0, ops.Rk(2)), 1)  # S-gate
    op = op(h, 2)
    op = op(ops.Swap(0, 2), 0)

    op3 = ops.Qft(3)
    self.assertTrue(op3.is_close(op))
예제 #5
0
def run_experiment(a1: np.complexfloating, a2: np.complexfloating,
                   target: float) -> None:
    """Construct swap test circuit and measure."""

    # The circuit is quite simple:
    #
    # |0> --- H --- o --- H --- Measure
    #               |
    # a1  --------- x ---------
    #               |
    # a2  ----------x ---------

    psi = state.bitstring(0) * state.qubit(a1) * state.qubit(a2)
    psi = ops.Hadamard()(psi, 0)
    psi = ops.ControlledU(0, 1, ops.Swap(1, 2))(psi)
    psi = ops.Hadamard()(psi, 0)

    # Measure once.
    p0, _ = ops.Measure(psi, 0)
    if abs(p0 - target) > 0.05:
        raise AssertionError(
            'Probability {:.2f} off more than 5% from target {:.2f}'.format(
                p0, target))
    print('Similarity of a1: {:.2f}, a2: {:.2f} ==>  %: {:.2f}'.format(
        a1, a2, 100.0 * p0))
예제 #6
0
    def test_v_vdag_v(self):
        """Figure 4.8 Nielson, Chuang."""

        # Make Toffoli out of V = sqrt(X).
        #
        v = ops.Vgate()  # Could be any unitary, in principle!
        ident = ops.Identity()
        cnot = ops.Cnot(0, 1)

        o0 = ident * ops.ControlledU(1, 2, v)
        c2 = cnot * ident
        o2 = (ident * ops.ControlledU(1, 2, v.adjoint()))
        o4 = ops.ControlledU(0, 2, v)
        final = o4 @ c2 @ o2 @ c2 @ o0

        v2 = v @ v
        cv1 = ops.ControlledU(1, 2, v2)
        cv0 = ops.ControlledU(0, 1, cv1)

        self.assertTrue(final.is_close(cv0))
예제 #7
0
  def test_controlled_controlled(self):
    """Toffoli gate over 4 qubits to verify that controlling works."""

    cnot = ops.Cnot(0, 3)
    toffoli = ops.ControlledU(0, 1, cnot)
    self.assertTrue(toffoli.is_close(ops.Toffoli(0, 1, 4)))

    psi = toffoli(state.bitstring(0, 1, 0, 0, 1))
    self.assertTrue(psi.is_close(state.bitstring(0, 1, 0, 0, 1)))

    psi = toffoli(state.bitstring(1, 1, 0, 0, 1))
    self.assertTrue(psi.is_close(state.bitstring(1, 1, 0, 0, 0)))

    psi = toffoli(state.bitstring(0, 0, 1, 1, 0, 0, 1), idx=2)
    self.assertTrue(psi.is_close(state.bitstring(0, 0, 1, 1, 0, 0, 0)))
예제 #8
0
파일: phase_estimation.py 프로젝트: xbe/qcc
def phase1(psi, u, t):
    """Unpack binary fraction."""

    # Unpack the binary fractions of the phase into the first t qubits.
    #
    # t qubits
    # |0> - H -------------------- ... ----o --
    # |0> - H -----------------o-- ... --- | --
    # |0> - H ---------o-------|-- ... --- | --
    # |0> - H -o-------|-------|-- ... --- | --
    #          |       |       |           |
    # nbits qubits     |       |           |
    # |u> --- U^1 --- U^2 --- U^4 ... --- U^s^(t-1)
    #
    psi = ops.Hadamard(t)(psi)
    for idx, inv in enumerate(range(t - 1, -1, -1)):
        u2 = u
        for _ in range(idx):
            u2 = u2(u2)
        psi = ops.ControlledU(inv, t, u2)(psi, inv)
    return psi
예제 #9
0
def expo_u(psi: state.State, u: ops.Operator, t: int) -> state.State:
    """Exponentiate U."""

    # Unpack the binary fractions of the phase into the first t qubits.
    #
    # t qubits
    # |0> - H -------------------- ... ----o --
    # |0> - H -----------------o-- ... --- | --
    # |0> - H ---------o-------|-- ... --- | --
    # |0> - H -o-------|-------|-- ... --- | --
    #          |       |       |           |
    # nbits qubits     |       |           |
    # |u> --- U^1 --- U^2 --- U^4 ... --- U^s^(t-1)
    #
    psi = ops.Hadamard(t)(psi)
    for idx, inv in enumerate(range(t - 1, -1, -1)):
        u2 = u
        for _ in range(idx):
            u2 = u2(u2)
        psi = ops.ControlledU(inv, t, u2)(psi, inv)
    return psi
예제 #10
0
def simple_kick():
  psi = state.bitstring(0, 0, 1)
  psi = ops.Hadamard(2)(psi)
  psi = ops.ControlledU(0, 2, ops.Sgate())(psi)
  psi = ops.ControlledU(1, 2, ops.Tgate())(psi, 1)
  psi.dump()
예제 #11
0
def run_experiment(nbits_phase, nbits_grover, solutions) -> None:
  """Run full experiment for a given number of solutions."""

  # Building the Grover Operator, see grover.py
  n = 2**nbits_grover
  zero_projector = np.zeros((n, n))
  zero_projector[0, 0] = 1
  op_zero = ops.Operator(zero_projector)

  f = make_f(nbits_grover, solutions)
  u = ops.OracleUf(nbits_grover + 1, f)

  # The state for the counting algorithm.
  # We reserve nbits for the phase estimation.
  # We also reserve nbits for the Oracle.
  # These numbers could be adjusted to achieve better
  # accuracy. Yet, this keeps the code a little bit simpler,
  # while trading off a few off-by-1 estimation errors.
  #
  # We also add the |1> for the Oracle.
  #
  psi = (state.zeros(nbits_phase) * state.zeros(nbits_grover) * state.ones(1))

  # Apply Hadamard to all the qubits.
  for i in range(nbits_phase + nbits_grover + 1):
    psi.apply(ops.Hadamard(), i)

  # Construct the Grover Operator.
  reflection = op_zero * 2.0 - ops.Identity(nbits_grover)
  hn = ops.Hadamard(nbits_grover)
  inversion = hn(reflection(hn)) * ops.Identity()
  grover = inversion(u)

  # Now that we have the Grover Operator, we have to perform
  # phase estimation. This loop is a copy from phase_estimation.py
  # with more comments there.
  #
  for idx, inv in enumerate(range(nbits_phase - 1, -1, -1)):
    u2 = grover
    for _ in range(idx):
      u2 = u2(u2)
    psi = ops.ControlledU(inv, nbits_phase, u2)(psi, inv)

  # Reverse QFT gives us the phase as a fraction of 2*Pi
  psi = ops.Qft(nbits_phase).adjoint()(psi)

  # Get the state with highest probability and compute the phase
  # as a binary fraction. Note that the probability increases
  # as M, the number of solutions, gets closer and closer to N,
  # the total mnumber of states.
  maxbits, maxprob = psi.maxprob()
  phi_estimate = sum(maxbits[i] * 2**(-i - 1) for i in range(nbits_phase))

  # We know that after phase estimation, this holds:
  #
  #    sin(phi/2) = sqrt(M/N)
  #             M = N * sin(phi/2)^2
  #
  # Hence we can compute M. We keep the result to 2 digit to visualize
  # the errors. Note that the phi_estimate is a fraction of 2*PI, hence
  # the 1/2 in above formula cancels out against the 2 and we compute:
  M = round(n * math.sin(phi_estimate * math.pi)**2, 2)

  print('Estimate: {:.4f} prob: {:5.2f}% --> M: {:5.2f}, want: {:2d}'.format(
      phi_estimate, maxprob * 100.0, M, solutions))
예제 #12
0
 def test_controlled_rotations(self):
   psi = state.bitstring(1, 1, 1)
   psi02 = ops.ControlledU(0, 2, ops.Rk(1))(psi)
   psi20 = ops.ControlledU(2, 0, ops.Rk(1))(psi)
   self.assertTrue(psi02.is_close(psi20))