def test_measure(self): psi = state.zeros(2) psi = ops.Hadamard()(psi) psi = ops.Cnot(0, 1)(psi) p0, psi2 = ops.Measure(psi, 0) self.assertTrue(math.isclose(p0, 0.5, abs_tol=1e-5)) # Measure again - now state should have collapsed. p0, _ = ops.Measure(psi2, 0) self.assertTrue(math.isclose(p0, 1.0, abs_tol=1e-6))
def experiment_matrix(a, b, cin, expected_sum, expected_cout): """Run a simple classic experiment, check results.""" psi = state.bitstring(a, b, cin, 0, 0) psi = fulladder_matrix(psi) bsum, _ = ops.Measure(psi, 3, tostate=1, collapse=False) bout, _ = ops.Measure(psi, 4, tostate=1, collapse=False) print(f'a: {a} b: {b} cin: {cin} sum: {bsum} cout: {bout}') if bsum != expected_sum or bout != expected_cout: raise AssertionError('invalid results')
def test_measure_order(self): """Order of measurement must not make a difference.""" b00 = bell.bell_state(0, 0) _, b00 = ops.Measure(b00, 0, tostate=0) _, b00 = ops.Measure(b00, 1, tostate=0) self.assertTrue(math.isclose(b00.prob(0, 0), 1.0)) self.assertTrue(math.isclose(b00.prob(1, 1), 0.0)) b00 = bell.bell_state(0, 0) _, b00 = ops.Measure(b00, 1, tostate=0) _, b00 = ops.Measure(b00, 0, tostate=0) self.assertTrue(math.isclose(b00.prob(0, 0), 1.0)) self.assertTrue(math.isclose(b00.prob(1, 1), 0.0))
def bob_measures(psi: state.State, expect0: int, expect1: int): """Bob measures both bits (in computational basis).""" # Change Hadamard basis back to computational basis. psi = ops.Cnot(0, 1)(psi) psi = ops.Hadamard()(psi) p0, _ = ops.Measure(psi, 0, tostate=expect1) p1, _ = ops.Measure(psi, 1, tostate=expect0) if (not math.isclose(p0, 1.0, abs_tol=1e-6) or not math.isclose(p1, 1.0, abs_tol=1e-6)): raise AssertionError(f'Invalid Result p0 {p0} p1 {p1}') print(f'Expected/matched: |{expect0}{expect1}>.')
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))
def alice_measures(alice: state.State, expect0: np.complexfloating, expect1: np.complexfloating, qubit0: np.complexfloating, qubit1: np.complexfloating): """Force measurement and get teleported qubit.""" # Alices measure her state and get a collapsed |qubit0 qubit1>. # She let's Bob know which one of the 4 combinations she obtained. # We force measurement here, collapsing to a state with the # first two qubits collapsed. Bob's qubit is still unmeasured. _, alice0 = ops.Measure(alice, 0, tostate=qubit0) _, alice1 = ops.Measure(alice0, 1, tostate=qubit1) # Depending on what was measured and communicated, Bob has to # one of these things to his qubit2: if qubit0 == 0 and qubit1 == 0: pass if qubit0 == 0 and qubit1 == 1: alice1 = ops.PauliX()(alice1, idx=2) if qubit0 == 1 and qubit1 == 0: alice1 = ops.PauliZ()(alice1, idx=2) if qubit0 == 1 and qubit1 == 1: alice1 = ops.PauliX()(ops.PauliZ()(alice1, idx=2), idx=2) # Now Bob measures his qubit (2) (without collapse, so we can # 'measure' it twice. This is not necessary, but good to double check # the maths). p0, _ = ops.Measure(alice1, 2, tostate=0, collapse=False) p1, _ = ops.Measure(alice1, 2, tostate=1, collapse=False) # Alice should now have 'teleported' the qubit in state 'x'. # We sqrt() the probability, we want to show (original) amplitudes. bob_a = math.sqrt(p0.real) bob_b = math.sqrt(p1.real) print('Teleported (|{:d}{:d}>) a={:.2f}, b={:.2f}'.format( qubit0, qubit1, bob_a, bob_b)) if (not math.isclose(expect0, bob_a, abs_tol=1e-6) or not math.isclose(expect1, bob_b, abs_tol=1e-6)): raise AssertionError('Invalid result.')
def test_measure(self): b00 = bell.bell_state(0, 1) self.assertTrue(math.isclose(b00.prob(0, 1), 0.5, abs_tol=1e-6)) self.assertTrue(math.isclose(b00.prob(1, 0), 0.5, abs_tol=1e-6)) _, b00 = ops.Measure(b00, 0, tostate=0) self.assertTrue(math.isclose(b00.prob(0, 1), 1.0, abs_tol=1e-6)) self.assertTrue(math.isclose(b00.prob(1, 0), 0.0, abs_tol=1e-6)) # This state can't be measured, all zeros. _, b00 = ops.Measure(b00, 1, tostate=1) self.assertTrue(math.isclose(b00.prob(1, 0), 0.0, abs_tol=1e-6)) b00 = bell.bell_state(0, 1) self.assertTrue(math.isclose(b00.prob(0, 1), 0.5, abs_tol=1e-6)) self.assertTrue(math.isclose(b00.prob(1, 0), 0.5, abs_tol=1e-6)) _, b00 = ops.Measure(b00, 0, tostate=1) self.assertTrue(math.isclose(b00.prob(0, 1), 0.0, abs_tol=1e-6)) self.assertTrue(math.isclose(b00.prob(1, 0), 1.0, abs_tol=1e-6)) # This state can't be measured, all zeros. p, _ = ops.Measure(b00, 1, tostate=1, collapse=False) self.assertEqual(p, 0.0)
def run_experiment(nbits, flavor): """Run full experiment for a given flavor of f().""" f = make_f(nbits - 1, flavor) u = ops.OracleUf(nbits, f) psi = (ops.Hadamard(nbits - 1)(state.zeros(nbits - 1)) * ops.Hadamard()(state.ones(1))) psi = u(psi) psi = (ops.Hadamard(nbits - 1) * ops.Identity(1))(psi) # Measure all of |0>. If all close to 1.0, f() is constant. for idx in range(nbits - 1): p0, _ = ops.Measure(psi, idx, tostate=0, collapse=False) if not math.isclose(p0, 1.0, abs_tol=1e-5): return exp_balanced return exp_constant
def measure_bit(self, idx: int, tostate: int = 0, collapse: bool = True) -> (float, state.State): prob, self.psi = ops.Measure(self.psi, idx, tostate, collapse) return prob, self.psi
def measure_bit(self, idx, tostate=0, collapse=True): return ops.Measure(self.psi, idx, tostate, collapse)