Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Updating MEAP for chapters 8 and 9. #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
cgranade merged 1 commit into master from crazy4pi314/update-ch8-9-meap
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Chris Granade
Copyright (c) 2019 Sarah Kaiser and Chris Granade.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Learn Quantum Computing with Python and Q# <br> Sample Code #

This repository provides sample code for [_Learn Quantum Computing with Python and Q#_](https://www.manning.com/books/learn-quantum-computing-with-python-and-q-sharp) (Dr. Sarah Kaiser and Chris Granade, Manning Publications), currently in Manning Early Access Preview.
This repository provides sample code for [_Learn Quantum Computing with Python and Q#_](https://www.manning.com/books/learn-quantum-computing-with-python-and-q-sharp) (Dr. Sarah Kaiser and Dr. Chris Granade, Manning Publications), currently in Manning Early Access Preview.

Below, we provide some instructions on getting started with each sample; please see Appendix A (coming soon) for more details.

Expand Down
27 changes: 20 additions & 7 deletions ch02/interface.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# interface.py: Contains classes that define the interface to the qubit
# simulator in simulator.py.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from abc import ABCMeta, abstractmethod
from contextlib import contextmanager

# tag::qubit_interface[]
class Qubit(metaclass=ABCMeta):
@abstractmethod
def h(self): pass # <1>
def h(self): pass # <1>

@abstractmethod # <2>
@abstractmethod # <2>
def measure(self) -> bool: pass

@abstractmethod
def reset(self): pass # <3>
def reset(self): pass # <3>
# end::qubit_interface[]

# tag::device_interface[]
class QuantumDevice(metaclass=ABCMeta):
@abstractmethod
def allocate_qubit(self) -> Qubit: # <1>
def allocate_qubit(self) -> Qubit: # <1>
pass

@abstractmethod
def deallocate_qubit(self, qubit: Qubit): # <2>
def deallocate_qubit(self, qubit: Qubit): # <2>
pass

@contextmanager
def using_qubit(self): # <3>
def using_qubit(self): # <3>
qubit = self.allocate_qubit()
try:
yield qubit
finally:
qubit.reset() # <4>
qubit.reset() # <4>
self.deallocate_qubit(qubit)
# end::device_interface[]
15 changes: 14 additions & 1 deletion ch02/qrng.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# qrng.py: Defines and runs a quantum random number generator (qrng) using
# the interface defined in interface.py and the simulator in simulator.py.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from interface import QuantumDevice
from simulator import SingleQubitSimulator

# tag::qrng[]
def qrng(device: QuantumDevice) -> bool:
def qrng(device: QuantumDevice) -> bool:
with device.using_qubit() as q:
q.h()
return q.measure()
Expand Down
14 changes: 13 additions & 1 deletion ch02/simulator.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# simulator.py: Defines a class that implements a single qubit simulator.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from interface import QuantumDevice, Qubit
import numpy as np

Expand Down Expand Up @@ -36,5 +48,5 @@ def allocate_qubit(self) -> SimulatedQubit:
if self.available_qubits:
return self.available_qubits.pop()

def deallocate_qubit(self, qubit: SimulatedQubit):
def deallocate_qubit(self, qubit: SimulatedQubit):
self.available_qubits.append(qubit)
51 changes: 34 additions & 17 deletions ch03/bb84.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,56 +1,73 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# bb84.py: Defines and runs a simulation of the BB84 protocol for quantum key
# distribution. Uses the single qubit simulator defined in simulator.py,
# and the interface to the simulator defined in interface.py.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from interface import QuantumDevice, Qubit
from simulator import SingleQubitSimulator
from typing import List

# tag::bb84_utility[]
def sample_random_bit(device: QuantumDevice) -> bool:
def sample_random_bit(device: QuantumDevice) -> bool:
with device.using_qubit() as q:
q.h()
result = q.measure()
q.reset() # <1>
q.reset() # <1>
return result

def prepare_message_qubit(message: bool, basis: bool, q: Qubit) -> None: # <2>
def prepare_message_qubit(message: bool, basis: bool, q: Qubit) -> None: # <2>
if message:
q.x()
if basis:
q.h()

def measure_message_qubit(basis: bool, q: Qubit) -> bool:
def measure_message_qubit(basis: bool, q: Qubit) -> bool:
if basis:
q.h()
result = q.measure()
q.reset() # <3>
q.reset() # <3>
return result

def convert_to_hex(bits: List[bool]) -> str: # <4>
def convert_to_hex(bits: List[bool]) -> str: # <4>
return hex(int(
"".join(["1" if bit else "0" for bit in bits]),
2
))
# end::bb84_utility[]

# tag::bb84_single[]
def send_single_bit_with_bb84(your_device : QuantumDevice, eve_device : QuantumDevice) -> tuple:
def send_single_bit_with_bb84(
your_device: QuantumDevice,
eve_device: QuantumDevice
) -> tuple:

[your_message, your_basis] = [
sample_random_bit(your_device) for _ in range(2) # <1>
sample_random_bit(your_device) for _ in range(2) # <1>
]

eve_basis = sample_random_bit(eve_device) # <2>
eve_basis = sample_random_bit(eve_device) # <2>

with your_device.using_qubit() as q:
prepare_message_qubit(your_message, your_basis, q) # <3>
prepare_message_qubit(your_message, your_basis, q) # <3>

# QUBIT SENDING... # <4>
# QUBIT SENDING... # <4>

eve_result = measure_message_qubit(eve_basis, q) # <5>
eve_result = measure_message_qubit(eve_basis, q) # <5>

return ((your_message, your_basis), (eve_result, eve_basis)) # <6>
return ((your_message, your_basis), (eve_result, eve_basis)) # <6>
# end::bb84_single[]

# tag::bb84[]
def simulate_bb84(n_bits: int) -> tuple:
def simulate_bb84(n_bits: int) -> tuple:
your_device = SingleQubitSimulator()
eve_device = SingleQubitSimulator()

Expand All @@ -62,7 +79,7 @@ def simulate_bb84(n_bits : int) -> tuple:
((your_message, your_basis), (eve_result, eve_basis)) = \
send_single_bit_with_bb84(your_device, eve_device)

if your_basis == eve_basis: # <1>
if your_basis == eve_basis: # <1>
assert your_message == eve_result
key.append(your_message)

Expand All @@ -72,9 +89,9 @@ def simulate_bb84(n_bits : int) -> tuple:
# end::bb84[]

# tag::one_time[]
def apply_one_time_pad(message: List[bool], key: List[bool]) -> List[bool]:
def apply_one_time_pad(message: List[bool], key: List[bool]) -> List[bool]:
return [
message_bit ^ key_bit # <1>
message_bit ^ key_bit # <1>
for (message_bit, key_bit) in zip(message, key)
]
# end::one_time[]
Expand Down
23 changes: 18 additions & 5 deletions ch03/interface.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# interface.py: Contains classes that define the interface to the qubit
# simulator in simulator.py.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from abc import ABCMeta, abstractmethod
from contextlib import contextmanager

Expand All @@ -7,7 +20,7 @@ class Qubit(metaclass=ABCMeta):
def h(self): pass

@abstractmethod
def x(self): pass # <1>
def x(self): pass # <1>

@abstractmethod
def measure(self) -> bool: pass
Expand All @@ -19,19 +32,19 @@ def reset(self): pass
# tag::device_interface[]
class QuantumDevice(metaclass=ABCMeta):
@abstractmethod
def allocate_qubit(self) -> Qubit: # <1>
def allocate_qubit(self) -> Qubit: # <1>
pass

@abstractmethod
def deallocate_qubit(self, qubit: Qubit): # <2>
def deallocate_qubit(self, qubit: Qubit): # <2>
pass

@contextmanager
def using_qubit(self): # <3>
def using_qubit(self): # <3>
qubit = self.allocate_qubit()
try:
yield qubit
finally:
qubit.reset() # <4>
qubit.reset() # <4>
self.deallocate_qubit(qubit)
# end::device_interface[]
37 changes: 25 additions & 12 deletions ch03/qkd.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# qkd.py: Defines functions needed to perform a basic quantum key exchange
# protocol.
##
# Copyright (c) Sarah Kaiser and Chris Granade.
# Code sample from the book "Learn Quantum Computing with Python and Q#" by
# Sarah Kaiser and Chris Granade, published by Manning Publications Co.
# Book ISBN 9781617296130.
# Code licensed under the MIT License.
##

from interface import QuantumDevice, Qubit
from simulator import SingleQubitSimulator

# tag::exchange_bits[]
def prepare_classical_message(bit: bool, q: Qubit) -> None: # <1>
def prepare_classical_message(bit: bool, q: Qubit) -> None: # <1>
if bit:
q.x() # <2>

def eve_measure(q: Qubit) -> bool:
def eve_measure(q: Qubit) -> bool:
return q.measure() # <3>

def send_classical_bit(device: QuantumDevice, bit: bool) -> None:
def send_classical_bit(device: QuantumDevice, bit: bool) -> None:
with device.using_qubit() as q:
prepare_classical_message(bit, q)
result = eve_measure(q)
Expand All @@ -19,41 +32,41 @@ def send_classical_bit(device : QuantumDevice, bit : bool) -> None:


# tag::qrng[]
def qrng(device: QuantumDevice) -> bool:
def qrng(device: QuantumDevice) -> bool:
with device.using_qubit() as q:
q.h()
return q.measure()
# end::qrng[]

# tag::exchange_bits_plusminus_basis[]
def prepare_classical_message_plusminus(bit: bool, q: Qubit) -> None:
def prepare_classical_message_plusminus(bit: bool, q: Qubit) -> None:
if bit:
q.x()
q.h() # <1>

def eve_measure_plusminus(q: Qubit) -> bool:
def eve_measure_plusminus(q: Qubit) -> bool:
q.h() # <2>
return q.measure()

def send_classical_bit_plusminus(device: QuantumDevice, bit: bool) -> None:
def send_classical_bit_plusminus(device: QuantumDevice, bit: bool) -> None:
with device.using_qubit() as q:
prepare_classical_message_plusminus(bit, q)
result = eve_measure_plusminus(q)
assert result == bit
# end::exchange_bits_plusminus_basis[]

# tag::exchange_bits_diff_basis[]
def prepare_classical_message(bit: bool, q: Qubit) -> None: # <1>
def prepare_classical_message(bit: bool, q: Qubit) -> None: # <1>
if bit:
q.x()

def eve_measure_plusminus(q: Qubit) -> bool:
q.h() # <2>
def eve_measure_plusminus(q: Qubit) -> bool:
q.h() # <2>
return q.measure()

def send_classical_bit_wrong_basis(device: QuantumDevice, bit: bool) -> None:
def send_classical_bit_wrong_basis(device: QuantumDevice, bit: bool) -> None:
with device.using_qubit() as q:
prepare_classical_message(bit, q)
result = eve_measure_plusminus(q)
assert result == bit, "Two parties do not have the same bit value" # <3>
assert result == bit, "Two parties do not have the same bit value" # <3>
# end::exchange_bits_diff_basis[]
Loading

AltStyle によって変換されたページ (->オリジナル) /