myqclab 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- myqclab-0.1.0/PKG-INFO +86 -0
- myqclab-0.1.0/README.md +76 -0
- myqclab-0.1.0/myqclab/__init__.py +81 -0
- myqclab-0.1.0/myqclab/__main__.py +4 -0
- myqclab-0.1.0/myqclab/cli.py +46 -0
- myqclab-0.1.0/myqclab/codes.py +55 -0
- myqclab-0.1.0/myqclab.egg-info/PKG-INFO +86 -0
- myqclab-0.1.0/myqclab.egg-info/SOURCES.txt +13 -0
- myqclab-0.1.0/myqclab.egg-info/dependency_links.txt +1 -0
- myqclab-0.1.0/myqclab.egg-info/entry_points.txt +2 -0
- myqclab-0.1.0/myqclab.egg-info/requires.txt +2 -0
- myqclab-0.1.0/myqclab.egg-info/top_level.txt +1 -0
- myqclab-0.1.0/pyproject.toml +17 -0
- myqclab-0.1.0/setup.cfg +4 -0
- myqclab-0.1.0/setup.py +18 -0
myqclab-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: myqclab
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Quantum Computing Lab programs in Python and Qiskit
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: qiskit>=1.0.0
|
|
8
|
+
Requires-Dist: qiskit-aer>=0.14.0
|
|
9
|
+
Dynamic: requires-python
|
|
10
|
+
|
|
11
|
+
# Quantum Computing Lab Programs & `myqclab` Package
|
|
12
|
+
|
|
13
|
+
Compact, verified Python and Qiskit implementations of 9 core quantum algorithms for lab exams.
|
|
14
|
+
|
|
15
|
+
Available both as standalone scripts/notebooks and as an installable Python package **`myqclab`**.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Package Installation
|
|
20
|
+
|
|
21
|
+
Install directly in your environment:
|
|
22
|
+
```bash
|
|
23
|
+
pip install .
|
|
24
|
+
```
|
|
25
|
+
Or in editable/development mode:
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Package Usage
|
|
33
|
+
|
|
34
|
+
### 1. In Python / Jupyter Notebook
|
|
35
|
+
```python
|
|
36
|
+
import myqclab
|
|
37
|
+
|
|
38
|
+
# Show the code of any algorithm in the terminal (quotes optional!)
|
|
39
|
+
myqclab.show(grover)
|
|
40
|
+
myqclab.show("grover")
|
|
41
|
+
|
|
42
|
+
# Run the algorithm and print the circuit and simulation output
|
|
43
|
+
myqclab.run(grover)
|
|
44
|
+
|
|
45
|
+
# List all available programs
|
|
46
|
+
myqclab.list()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. From Terminal CLI
|
|
50
|
+
```bash
|
|
51
|
+
# Print code of a program
|
|
52
|
+
myqclab grover
|
|
53
|
+
myqclab show grover
|
|
54
|
+
|
|
55
|
+
# Execute program directly
|
|
56
|
+
myqclab run grover
|
|
57
|
+
|
|
58
|
+
# List all programs
|
|
59
|
+
myqclab list
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📚 Available Quantum Programs
|
|
65
|
+
|
|
66
|
+
| Program Name | Loop Variation | Algorithm | Manually Configurable Input |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `qe` | `qeloop` | Quantum Entanglement | `state = '00'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
69
|
+
| `tele` | `teleloop` | Quantum Teleportation | `state = '1'` (`'0'` or `'1'`) |
|
|
70
|
+
| `super` | `superloop` | Superdense Coding | `msg = '01'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
71
|
+
| `de` | `deloop` | Deutsch's Algorithm | `oracle_type = 'balanced_id'` (`'constant_0'`, etc.) |
|
|
72
|
+
| `dj` | `djloop` | Deutsch-Jozsa Algorithm | `oracle_type = 'balanced'`, `n = 3` |
|
|
73
|
+
| `simon` | `simonloop` | Simon's Algorithm | `s = '11'` |
|
|
74
|
+
| `bv` | `bvloop` | Bernstein-Vazirani | `s = '1011'` |
|
|
75
|
+
| `grover` | `groverloop` | Grover's Search | `target = '10'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
76
|
+
| `shor` | `shorloop` | Shor's Algorithm | `N = 15, a = 7` |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Standalone Running
|
|
81
|
+
|
|
82
|
+
Run any script with Python:
|
|
83
|
+
```bash
|
|
84
|
+
python qe.py
|
|
85
|
+
```
|
|
86
|
+
Or open any `.ipynb` file in Jupyter Notebook / JupyterLab / Google Colab.
|
myqclab-0.1.0/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Quantum Computing Lab Programs & `myqclab` Package
|
|
2
|
+
|
|
3
|
+
Compact, verified Python and Qiskit implementations of 9 core quantum algorithms for lab exams.
|
|
4
|
+
|
|
5
|
+
Available both as standalone scripts/notebooks and as an installable Python package **`myqclab`**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Package Installation
|
|
10
|
+
|
|
11
|
+
Install directly in your environment:
|
|
12
|
+
```bash
|
|
13
|
+
pip install .
|
|
14
|
+
```
|
|
15
|
+
Or in editable/development mode:
|
|
16
|
+
```bash
|
|
17
|
+
pip install -e .
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Package Usage
|
|
23
|
+
|
|
24
|
+
### 1. In Python / Jupyter Notebook
|
|
25
|
+
```python
|
|
26
|
+
import myqclab
|
|
27
|
+
|
|
28
|
+
# Show the code of any algorithm in the terminal (quotes optional!)
|
|
29
|
+
myqclab.show(grover)
|
|
30
|
+
myqclab.show("grover")
|
|
31
|
+
|
|
32
|
+
# Run the algorithm and print the circuit and simulation output
|
|
33
|
+
myqclab.run(grover)
|
|
34
|
+
|
|
35
|
+
# List all available programs
|
|
36
|
+
myqclab.list()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. From Terminal CLI
|
|
40
|
+
```bash
|
|
41
|
+
# Print code of a program
|
|
42
|
+
myqclab grover
|
|
43
|
+
myqclab show grover
|
|
44
|
+
|
|
45
|
+
# Execute program directly
|
|
46
|
+
myqclab run grover
|
|
47
|
+
|
|
48
|
+
# List all programs
|
|
49
|
+
myqclab list
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📚 Available Quantum Programs
|
|
55
|
+
|
|
56
|
+
| Program Name | Loop Variation | Algorithm | Manually Configurable Input |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `qe` | `qeloop` | Quantum Entanglement | `state = '00'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
59
|
+
| `tele` | `teleloop` | Quantum Teleportation | `state = '1'` (`'0'` or `'1'`) |
|
|
60
|
+
| `super` | `superloop` | Superdense Coding | `msg = '01'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
61
|
+
| `de` | `deloop` | Deutsch's Algorithm | `oracle_type = 'balanced_id'` (`'constant_0'`, etc.) |
|
|
62
|
+
| `dj` | `djloop` | Deutsch-Jozsa Algorithm | `oracle_type = 'balanced'`, `n = 3` |
|
|
63
|
+
| `simon` | `simonloop` | Simon's Algorithm | `s = '11'` |
|
|
64
|
+
| `bv` | `bvloop` | Bernstein-Vazirani | `s = '1011'` |
|
|
65
|
+
| `grover` | `groverloop` | Grover's Search | `target = '10'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
66
|
+
| `shor` | `shorloop` | Shor's Algorithm | `N = 15, a = 7` |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Standalone Running
|
|
71
|
+
|
|
72
|
+
Run any script with Python:
|
|
73
|
+
```bash
|
|
74
|
+
python qe.py
|
|
75
|
+
```
|
|
76
|
+
Or open any `.ipynb` file in Jupyter Notebook / JupyterLab / Google Colab.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import builtins
|
|
2
|
+
import sys
|
|
3
|
+
from .codes import PROGRAMS, DESCRIPTIONS, ALIASES, resolve_name
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
'show',
|
|
7
|
+
'get',
|
|
8
|
+
'run',
|
|
9
|
+
'list',
|
|
10
|
+
'list_programs',
|
|
11
|
+
'qe', 'qeloop',
|
|
12
|
+
'tele', 'teleloop',
|
|
13
|
+
'super', 'superloop',
|
|
14
|
+
'de', 'deloop',
|
|
15
|
+
'dj', 'djloop',
|
|
16
|
+
'simon', 'simonloop',
|
|
17
|
+
'bv', 'bvloop',
|
|
18
|
+
'grover', 'groverloop',
|
|
19
|
+
'shor', 'shorloop',
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
qe = 'qe'
|
|
23
|
+
qeloop = 'qeloop'
|
|
24
|
+
tele = 'tele'
|
|
25
|
+
teleloop = 'teleloop'
|
|
26
|
+
super = 'super'
|
|
27
|
+
superloop = 'superloop'
|
|
28
|
+
de = 'de'
|
|
29
|
+
deloop = 'deloop'
|
|
30
|
+
dj = 'dj'
|
|
31
|
+
djloop = 'djloop'
|
|
32
|
+
simon = 'simon'
|
|
33
|
+
simonloop = 'simonloop'
|
|
34
|
+
bv = 'bv'
|
|
35
|
+
bvloop = 'bvloop'
|
|
36
|
+
grover = 'grover'
|
|
37
|
+
groverloop = 'groverloop'
|
|
38
|
+
shor = 'shor'
|
|
39
|
+
shorloop = 'shorloop'
|
|
40
|
+
|
|
41
|
+
for _prog in list(PROGRAMS.keys()):
|
|
42
|
+
if not hasattr(builtins, _prog):
|
|
43
|
+
setattr(builtins, _prog, _prog)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def show(name):
|
|
47
|
+
key = resolve_name(name)
|
|
48
|
+
if key in PROGRAMS:
|
|
49
|
+
print(PROGRAMS[key].rstrip())
|
|
50
|
+
else:
|
|
51
|
+
print(f"Unknown program: {name}")
|
|
52
|
+
print(f"Available programs: {', '.join(sorted(PROGRAMS.keys()))}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get(name):
|
|
56
|
+
key = resolve_name(name)
|
|
57
|
+
return PROGRAMS.get(key)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def run(name):
|
|
61
|
+
key = resolve_name(name)
|
|
62
|
+
if key in PROGRAMS:
|
|
63
|
+
ns = {'__name__': '__main__'}
|
|
64
|
+
exec(PROGRAMS[key], ns)
|
|
65
|
+
else:
|
|
66
|
+
print(f"Unknown program: {name}")
|
|
67
|
+
print(f"Available programs: {', '.join(sorted(PROGRAMS.keys()))}")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def list_programs():
|
|
71
|
+
print("Available Quantum Programs in myqclab:\n")
|
|
72
|
+
max_len = max(len(k) for k in PROGRAMS.keys())
|
|
73
|
+
for k in sorted(PROGRAMS.keys()):
|
|
74
|
+
desc = DESCRIPTIONS.get(k, '')
|
|
75
|
+
print(f" {k.ljust(max_len + 2)} - {desc}")
|
|
76
|
+
print("\nUsage:")
|
|
77
|
+
print(" myqclab.show('grover') # or myqclab.show(grover)")
|
|
78
|
+
print(" myqclab.run('grover') # or myqclab.run(grover)")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
list = list_programs
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from . import show, run, list_programs, resolve_name
|
|
3
|
+
from .codes import PROGRAMS
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
args = sys.argv[1:]
|
|
8
|
+
if not args or args[0] in ('-h', '--help'):
|
|
9
|
+
print("Usage:")
|
|
10
|
+
print(" myqclab <program_name> # Print program code")
|
|
11
|
+
print(" myqclab show <program_name> # Print program code")
|
|
12
|
+
print(" myqclab run <program_name> # Execute program")
|
|
13
|
+
print(" myqclab list # List all available programs")
|
|
14
|
+
sys.exit(0)
|
|
15
|
+
|
|
16
|
+
cmd = args[0].lower()
|
|
17
|
+
if cmd == 'list':
|
|
18
|
+
list_programs()
|
|
19
|
+
return
|
|
20
|
+
|
|
21
|
+
if cmd == 'show':
|
|
22
|
+
if len(args) < 2:
|
|
23
|
+
print("Error: Specify a program name to show (e.g., 'myqclab show grover')")
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
show(args[1])
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
if cmd == 'run':
|
|
29
|
+
if len(args) < 2:
|
|
30
|
+
print("Error: Specify a program name to run (e.g., 'myqclab run grover')")
|
|
31
|
+
sys.exit(1)
|
|
32
|
+
run(args[1])
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
# If first argument is a program name directly (e.g., `myqclab grover`)
|
|
36
|
+
resolved = resolve_name(cmd)
|
|
37
|
+
if resolved in PROGRAMS:
|
|
38
|
+
show(resolved)
|
|
39
|
+
else:
|
|
40
|
+
print(f"Unknown command or program: {args[0]}")
|
|
41
|
+
list_programs()
|
|
42
|
+
sys.exit(1)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == '__main__':
|
|
46
|
+
main()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Auto-generated quantum program dictionary
|
|
2
|
+
|
|
3
|
+
PROGRAMS = {'qe': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nstate = '00'\n\nqc = QuantumCircuit(2, 2)\nif state[0] == '1':\n qc.x(0)\nif state[1] == '1':\n qc.x(1)\nqc.h(0)\nqc.cx(0, 1)\nqc.measure([0, 1], [0, 1])\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nprint(f'Input state: {state}')\nprint(qc.draw('text'))\nprint('Counts:', counts)\n", 'qeloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nstates = {'00': 'Phi+', '10': 'Phi-', '01': 'Psi+', '11': 'Psi-'}\n\nfor state, name in states.items():\n qc = QuantumCircuit(2, 2)\n if state[0] == '1':\n qc.x(0)\n if state[1] == '1':\n qc.x(1)\n qc.h(0)\n qc.cx(0, 1)\n qc.measure([0, 1], [0, 1])\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n print(f'=== {name} (input={state}) ===')\n print(qc.draw('text'))\n print('Counts:', counts)\n print()\n", 'tele': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nstate = '1'\n\nqc = QuantumCircuit(3, 3)\nif state == '1':\n qc.x(0)\nqc.barrier()\n\nqc.h(1)\nqc.cx(1, 2)\nqc.barrier()\n\nqc.cx(0, 1)\nqc.h(0)\nqc.barrier()\n\nqc.measure(0, 0)\nqc.measure(1, 1)\nqc.barrier()\n\nqc.cx(1, 2)\nqc.cz(0, 2)\nqc.measure(2, 2)\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nprint(f'Teleporting state |{state}>')\nprint(qc.draw('text'))\nprint('Counts (c2 c1 c0, c2 is Bob):', counts)\n", 'teleloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nfor state in ['0', '1']:\n qc = QuantumCircuit(3, 3)\n if state == '1':\n qc.x(0)\n qc.barrier()\n qc.h(1)\n qc.cx(1, 2)\n qc.barrier()\n qc.cx(0, 1)\n qc.h(0)\n qc.barrier()\n qc.measure(0, 0)\n qc.measure(1, 1)\n qc.barrier()\n qc.cx(1, 2)\n qc.cz(0, 2)\n qc.measure(2, 2)\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n print(f'=== Teleporting |{state}> ===')\n print(qc.draw('text'))\n print('Counts (c2 c1 c0, c2 is Bob):', counts)\n print()\n", 'super': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nmsg = '01'\n\nqc = QuantumCircuit(2, 2)\nqc.h(0)\nqc.cx(0, 1)\nqc.barrier()\n\nif msg[0] == '1':\n qc.x(0)\nif msg[1] == '1':\n qc.z(0)\nqc.barrier()\n\nqc.cx(0, 1)\nqc.h(0)\nqc.barrier()\nqc.measure([0, 1], [0, 1])\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nreceived = list(counts.keys())[0]\nprint(f'Sent: {msg} -> Received: {received}')\nprint(qc.draw('text'))\n", 'superloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nfor msg in ['00', '01', '10', '11']:\n qc = QuantumCircuit(2, 2)\n qc.h(0)\n qc.cx(0, 1)\n qc.barrier()\n if msg[0] == '1':\n qc.x(0)\n if msg[1] == '1':\n qc.z(0)\n qc.barrier()\n qc.cx(0, 1)\n qc.h(0)\n qc.barrier()\n qc.measure([0, 1], [0, 1])\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n received = list(counts.keys())[0]\n print(f'Sent: {msg} -> Received: {received}')\n\nprint()\nprint(qc.draw('text'))\n", 'de': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\noracle_type = 'balanced_id'\n\nqc = QuantumCircuit(2, 1)\nqc.x(1)\nqc.h([0, 1])\nqc.barrier()\n\nif oracle_type == 'constant_0':\n pass\nelif oracle_type == 'constant_1':\n qc.x(1)\nelif oracle_type == 'balanced_id':\n qc.cx(0, 1)\nelif oracle_type == 'balanced_not':\n qc.cx(0, 1)\n qc.x(1)\n\nqc.barrier()\nqc.h(0)\nqc.measure(0, 0)\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nres = list(counts.keys())[0]\nkind = 'Constant' if res == '0' else 'Balanced'\nprint(f'Oracle: {oracle_type} -> Measured {res} (Function is {kind})')\nprint(qc.draw('text'))\n", 'deloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\noracles = ['constant_0', 'constant_1', 'balanced_id', 'balanced_not']\n\nfor oracle_type in oracles:\n qc = QuantumCircuit(2, 1)\n qc.x(1)\n qc.h([0, 1])\n qc.barrier()\n if oracle_type == 'constant_0':\n pass\n elif oracle_type == 'constant_1':\n qc.x(1)\n elif oracle_type == 'balanced_id':\n qc.cx(0, 1)\n elif oracle_type == 'balanced_not':\n qc.cx(0, 1)\n qc.x(1)\n qc.barrier()\n qc.h(0)\n qc.measure(0, 0)\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n res = list(counts.keys())[0]\n kind = 'Constant' if res == '0' else 'Balanced'\n print(f'=== {oracle_type} ===')\n print(f'Measured {res} -> Function is {kind}')\n print(qc.draw('text'))\n print()\n", 'dj': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nn = 3\noracle_type = 'balanced'\n\nqc = QuantumCircuit(n + 1, n)\nqc.x(n)\nqc.h(range(n + 1))\nqc.barrier()\n\nif oracle_type == 'constant':\n qc.x(n)\nelif oracle_type == 'balanced':\n for i in range(n):\n qc.cx(i, n)\n\nqc.barrier()\nqc.h(range(n))\nqc.measure(range(n), range(n))\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nres = list(counts.keys())[0]\nkind = 'Constant' if res == '0' * n else 'Balanced'\nprint(f'{oracle_type.capitalize()} Oracle (n={n}): measured {res} -> Function is {kind}')\nprint(qc.draw('text'))\n", 'djloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nn = 3\nfor oracle_type in ['constant', 'balanced']:\n qc = QuantumCircuit(n + 1, n)\n qc.x(n)\n qc.h(range(n + 1))\n qc.barrier()\n if oracle_type == 'constant':\n qc.x(n)\n elif oracle_type == 'balanced':\n for i in range(n):\n qc.cx(i, n)\n qc.barrier()\n qc.h(range(n))\n qc.measure(range(n), range(n))\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n res = list(counts.keys())[0]\n kind = 'Constant' if res == '0' * n else 'Balanced'\n print(f'=== {oracle_type.capitalize()} Oracle ===')\n print(f'Measured {res} -> Function is {kind}')\n print(qc.draw('text'))\n print()\n", 'simon': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ns = '11'\nn = len(s)\n\nqc = QuantumCircuit(2 * n, n)\nqc.h(range(n))\nqc.barrier()\n\nk = s.find('1')\nfor i in range(n):\n if i != k:\n qc.cx(i, n + i)\n if s[i] == '1':\n qc.cx(k, n + i)\n\nqc.barrier()\nqc.h(range(n))\nqc.measure(range(n), range(n))\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nprint(f'Secret string s: {s}')\nprint(qc.draw('text'))\nprint('Measurement counts:', counts)\n\nfor y in counts:\n dot = sum(int(y[n - 1 - i]) * int(s[i]) for i in range(n)) % 2\n print(f'Measured y={y}: y . s mod 2 = {dot}')\n", 'simonloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nsecrets = ['11', '10', '01']\nfor s in secrets:\n n = len(s)\n qc = QuantumCircuit(2 * n, n)\n qc.h(range(n))\n qc.barrier()\n k = s.find('1')\n for i in range(n):\n if i != k:\n qc.cx(i, n + i)\n if s[i] == '1':\n qc.cx(k, n + i)\n qc.barrier()\n qc.h(range(n))\n qc.measure(range(n), range(n))\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n print(f'=== Secret s = {s} ===')\n print('Measurement counts:', counts)\n for y in counts:\n dot = sum(int(y[n - 1 - i]) * int(s[i]) for i in range(n)) % 2\n print(f'y={y}: y . s mod 2 = {dot}')\n print()\n", 'bv': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ns = '1011'\nn = len(s)\n\nqc = QuantumCircuit(n + 1, n)\nqc.x(n)\nqc.h(range(n + 1))\nqc.barrier()\n\nfor i, bit in enumerate(reversed(s)):\n if bit == '1':\n qc.cx(i, n)\n\nqc.barrier()\nqc.h(range(n))\nqc.measure(range(n), range(n))\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nresult = list(counts.keys())[0]\n\nprint(f'Secret string: {s}')\nprint(f'Found string: {result}')\nprint(qc.draw('text'))\nprint('Measurement counts:', counts)\n", 'bvloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\nsecrets = ['01', '10', '110', '1011']\nfor s in secrets:\n n = len(s)\n qc = QuantumCircuit(n + 1, n)\n qc.x(n)\n qc.h(range(n + 1))\n qc.barrier()\n for i, bit in enumerate(reversed(s)):\n if bit == '1':\n qc.cx(i, n)\n qc.barrier()\n qc.h(range(n))\n qc.measure(range(n), range(n))\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n result = list(counts.keys())[0]\n print(f'Secret: {s} -> Found: {result} (Match: {s == result})')\n", 'grover': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ntarget = '10'\n\nqc = QuantumCircuit(2, 2)\nqc.h([0, 1])\nqc.barrier()\n\nif target[1] == '0':\n qc.x(0)\nif target[0] == '0':\n qc.x(1)\nqc.cz(0, 1)\nif target[1] == '0':\n qc.x(0)\nif target[0] == '0':\n qc.x(1)\nqc.barrier()\n\nqc.h([0, 1])\nqc.x([0, 1])\nqc.cz(0, 1)\nqc.x([0, 1])\nqc.h([0, 1])\nqc.barrier()\n\nqc.measure([0, 1], [0, 1])\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nprint(f'Target state: {target}')\nprint(qc.draw('text'))\nprint('Measurement counts:', counts)\n", 'groverloop': "from qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ntargets = ['00', '01', '10', '11']\nfor target in targets:\n qc = QuantumCircuit(2, 2)\n qc.h([0, 1])\n qc.barrier()\n if target[1] == '0':\n qc.x(0)\n if target[0] == '0':\n qc.x(1)\n qc.cz(0, 1)\n if target[1] == '0':\n qc.x(0)\n if target[0] == '0':\n qc.x(1)\n qc.barrier()\n qc.h([0, 1])\n qc.x([0, 1])\n qc.cz(0, 1)\n qc.x([0, 1])\n qc.h([0, 1])\n qc.barrier()\n qc.measure([0, 1], [0, 1])\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n found = list(counts.keys())[0]\n print(f'Target: {target} -> Found: {found}')\n", 'shor': "import math\nfrom fractions import Fraction\nfrom qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ndef c_amod15(a, power):\n U = QuantumCircuit(4)\n for _ in range(power):\n if a in [2, 13]:\n U.swap(2, 3); U.swap(1, 2); U.swap(0, 1)\n if a in [7, 8]:\n U.swap(0, 1); U.swap(1, 2); U.swap(2, 3)\n if a in [4, 11]:\n U.swap(1, 3); U.swap(0, 2)\n if a in [7, 11, 13]:\n for q in range(4): U.x(q)\n U = U.to_gate()\n U.name = f'{a}^{power} mod 15'\n return U.control()\n\ndef qft_dagger(n):\n qc = QuantumCircuit(n)\n for qubit in range(n // 2):\n qc.swap(qubit, n - qubit - 1)\n for j in range(n):\n for m in range(j):\n qc.cp(-math.pi / float(2 ** (j - m)), m, j)\n qc.h(j)\n qc.name = 'QFT†'\n return qc\n\na = 7\nN = 15\nn_count = 3\n\nqc = QuantumCircuit(n_count + 4, n_count)\nfor q in range(n_count):\n qc.h(q)\nqc.x(n_count)\nqc.barrier()\n\nfor q in range(n_count):\n qc.append(c_amod15(a, 2**q), [q] + [n_count + i for i in range(4)])\nqc.barrier()\n\nqc.append(qft_dagger(n_count), range(n_count))\nqc.barrier()\nqc.measure(range(n_count), range(n_count))\n\ncounts = sim.run(transpile(qc, sim)).result().get_counts()\nprint(f'Shor Algorithm: N = {N}, a = {a}')\nprint(qc.draw('text'))\nprint('Measurement counts:', counts)\n\nfactors_found = set()\nfor output in counts:\n decimal = int(output, 2)\n phase = decimal / (2 ** n_count)\n frac = Fraction(phase).limit_denominator(N)\n r = frac.denominator\n if r % 2 == 0:\n g1 = math.gcd(a ** (r // 2) - 1, N)\n g2 = math.gcd(a ** (r // 2) + 1, N)\n for g in [g1, g2]:\n if 1 < g < N:\n factors_found.add(g)\n\nprint(f'Identified prime factors of {N}: {sorted(factors_found)}')\n", 'shorloop': "import math\nfrom fractions import Fraction\nfrom qiskit import QuantumCircuit, transpile\ntry:\n from qiskit_aer import AerSimulator\n sim = AerSimulator()\nexcept ImportError:\n from qiskit import Aer\n sim = Aer.get_backend('aer_simulator')\n\ndef c_amod15(a, power):\n U = QuantumCircuit(4)\n for _ in range(power):\n if a in [2, 13]:\n U.swap(2, 3); U.swap(1, 2); U.swap(0, 1)\n if a in [7, 8]:\n U.swap(0, 1); U.swap(1, 2); U.swap(2, 3)\n if a in [4, 11]:\n U.swap(1, 3); U.swap(0, 2)\n if a in [7, 11, 13]:\n for q in range(4): U.x(q)\n U = U.to_gate()\n U.name = f'{a}^{power} mod 15'\n return U.control()\n\ndef qft_dagger(n):\n qc = QuantumCircuit(n)\n for qubit in range(n // 2):\n qc.swap(qubit, n - qubit - 1)\n for j in range(n):\n for m in range(j):\n qc.cp(-math.pi / float(2 ** (j - m)), m, j)\n qc.h(j)\n qc.name = 'QFT†'\n return qc\n\nN = 15\nn_count = 3\n\nfor a in [2, 7, 8, 11, 13]:\n qc = QuantumCircuit(n_count + 4, n_count)\n for q in range(n_count):\n qc.h(q)\n qc.x(n_count)\n for q in range(n_count):\n qc.append(c_amod15(a, 2**q), [q] + [n_count + i for i in range(4)])\n qc.append(qft_dagger(n_count), range(n_count))\n qc.measure(range(n_count), range(n_count))\n\n counts = sim.run(transpile(qc, sim)).result().get_counts()\n factors = set()\n for output in counts:\n decimal = int(output, 2)\n phase = decimal / (2 ** n_count)\n r = Fraction(phase).limit_denominator(N).denominator\n if r % 2 == 0:\n for g in [math.gcd(a ** (r // 2) - 1, N), math.gcd(a ** (r // 2) + 1, N)]:\n if 1 < g < N:\n factors.add(g)\n print(f'N={N}, a={a} -> Factors: {sorted(factors)}')\n"}
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
ALIASES = {
|
|
7
|
+
'bell': 'qe',
|
|
8
|
+
'bellloop': 'qeloop',
|
|
9
|
+
'entanglement': 'qe',
|
|
10
|
+
'entanglementloop': 'qeloop',
|
|
11
|
+
'teleportation': 'tele',
|
|
12
|
+
'teleportationloop': 'teleloop',
|
|
13
|
+
'superdense': 'super',
|
|
14
|
+
'superdenseloop': 'superloop',
|
|
15
|
+
'deutsch': 'de',
|
|
16
|
+
'deutschloop': 'deloop',
|
|
17
|
+
'deutsch_jozsa': 'dj',
|
|
18
|
+
'deutsch_jozsaleop': 'djloop',
|
|
19
|
+
'deutschjozsa': 'dj',
|
|
20
|
+
'bernstein_vazirani': 'bv',
|
|
21
|
+
'bernsteinvazirani': 'bv',
|
|
22
|
+
'grover_search': 'grover',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
DESCRIPTIONS = {
|
|
26
|
+
'qe': 'Quantum Entanglement (single Bell state)',
|
|
27
|
+
'qeloop': 'Quantum Entanglement (loops over all 4 Bell states)',
|
|
28
|
+
'tele': 'Quantum Teleportation (single state teleportation)',
|
|
29
|
+
'teleloop': 'Quantum Teleportation (loops over |0> and |1>)',
|
|
30
|
+
'super': 'Superdense Coding (single message transmission)',
|
|
31
|
+
'superloop': 'Superdense Coding (loops over all 4 messages)',
|
|
32
|
+
'de': 'Deutsch Algorithm (single oracle evaluation)',
|
|
33
|
+
'deloop': 'Deutsch Algorithm (loops over all 4 oracles)',
|
|
34
|
+
'dj': 'Deutsch-Jozsa Algorithm (single oracle evaluation)',
|
|
35
|
+
'djloop': 'Deutsch-Jozsa Algorithm (loops over constant & balanced)',
|
|
36
|
+
'simon': 'Simon Algorithm (single secret period finding)',
|
|
37
|
+
'simonloop': 'Simon Algorithm (loops over multiple secret strings)',
|
|
38
|
+
'bv': 'Bernstein-Vazirani Algorithm (single hidden string search)',
|
|
39
|
+
'bvloop': 'Bernstein-Vazirani Algorithm (loops over multiple strings)',
|
|
40
|
+
'grover': 'Grover Search Algorithm (single target marked state)',
|
|
41
|
+
'groverloop': 'Grover Search Algorithm (loops over all 4 target states)',
|
|
42
|
+
'shor': 'Shor Algorithm (single N=15, a=7 order finding & factoring)',
|
|
43
|
+
'shorloop': 'Shor Algorithm (loops over multiple values of coprime a)',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
def resolve_name(name):
|
|
47
|
+
if not isinstance(name, str):
|
|
48
|
+
if hasattr(name, '__name__'):
|
|
49
|
+
name = name.__name__
|
|
50
|
+
else:
|
|
51
|
+
name = str(name)
|
|
52
|
+
key = name.strip().lower()
|
|
53
|
+
if key.endswith('.py'):
|
|
54
|
+
key = key[:-3]
|
|
55
|
+
return ALIASES.get(key, key)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: myqclab
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Quantum Computing Lab programs in Python and Qiskit
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: qiskit>=1.0.0
|
|
8
|
+
Requires-Dist: qiskit-aer>=0.14.0
|
|
9
|
+
Dynamic: requires-python
|
|
10
|
+
|
|
11
|
+
# Quantum Computing Lab Programs & `myqclab` Package
|
|
12
|
+
|
|
13
|
+
Compact, verified Python and Qiskit implementations of 9 core quantum algorithms for lab exams.
|
|
14
|
+
|
|
15
|
+
Available both as standalone scripts/notebooks and as an installable Python package **`myqclab`**.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Package Installation
|
|
20
|
+
|
|
21
|
+
Install directly in your environment:
|
|
22
|
+
```bash
|
|
23
|
+
pip install .
|
|
24
|
+
```
|
|
25
|
+
Or in editable/development mode:
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Package Usage
|
|
33
|
+
|
|
34
|
+
### 1. In Python / Jupyter Notebook
|
|
35
|
+
```python
|
|
36
|
+
import myqclab
|
|
37
|
+
|
|
38
|
+
# Show the code of any algorithm in the terminal (quotes optional!)
|
|
39
|
+
myqclab.show(grover)
|
|
40
|
+
myqclab.show("grover")
|
|
41
|
+
|
|
42
|
+
# Run the algorithm and print the circuit and simulation output
|
|
43
|
+
myqclab.run(grover)
|
|
44
|
+
|
|
45
|
+
# List all available programs
|
|
46
|
+
myqclab.list()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. From Terminal CLI
|
|
50
|
+
```bash
|
|
51
|
+
# Print code of a program
|
|
52
|
+
myqclab grover
|
|
53
|
+
myqclab show grover
|
|
54
|
+
|
|
55
|
+
# Execute program directly
|
|
56
|
+
myqclab run grover
|
|
57
|
+
|
|
58
|
+
# List all programs
|
|
59
|
+
myqclab list
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📚 Available Quantum Programs
|
|
65
|
+
|
|
66
|
+
| Program Name | Loop Variation | Algorithm | Manually Configurable Input |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `qe` | `qeloop` | Quantum Entanglement | `state = '00'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
69
|
+
| `tele` | `teleloop` | Quantum Teleportation | `state = '1'` (`'0'` or `'1'`) |
|
|
70
|
+
| `super` | `superloop` | Superdense Coding | `msg = '01'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
71
|
+
| `de` | `deloop` | Deutsch's Algorithm | `oracle_type = 'balanced_id'` (`'constant_0'`, etc.) |
|
|
72
|
+
| `dj` | `djloop` | Deutsch-Jozsa Algorithm | `oracle_type = 'balanced'`, `n = 3` |
|
|
73
|
+
| `simon` | `simonloop` | Simon's Algorithm | `s = '11'` |
|
|
74
|
+
| `bv` | `bvloop` | Bernstein-Vazirani | `s = '1011'` |
|
|
75
|
+
| `grover` | `groverloop` | Grover's Search | `target = '10'` (`'00'`, `'01'`, `'10'`, `'11'`) |
|
|
76
|
+
| `shor` | `shorloop` | Shor's Algorithm | `N = 15, a = 7` |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Standalone Running
|
|
81
|
+
|
|
82
|
+
Run any script with Python:
|
|
83
|
+
```bash
|
|
84
|
+
python qe.py
|
|
85
|
+
```
|
|
86
|
+
Or open any `.ipynb` file in Jupyter Notebook / JupyterLab / Google Colab.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.py
|
|
4
|
+
myqclab/__init__.py
|
|
5
|
+
myqclab/__main__.py
|
|
6
|
+
myqclab/cli.py
|
|
7
|
+
myqclab/codes.py
|
|
8
|
+
myqclab.egg-info/PKG-INFO
|
|
9
|
+
myqclab.egg-info/SOURCES.txt
|
|
10
|
+
myqclab.egg-info/dependency_links.txt
|
|
11
|
+
myqclab.egg-info/entry_points.txt
|
|
12
|
+
myqclab.egg-info/requires.txt
|
|
13
|
+
myqclab.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
myqclab
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "myqclab"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Quantum Computing Lab programs in Python and Qiskit"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"qiskit>=1.0.0",
|
|
13
|
+
"qiskit-aer>=0.14.0",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.scripts]
|
|
17
|
+
myqclab = "myqclab.cli:main"
|
myqclab-0.1.0/setup.cfg
ADDED
myqclab-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="myqclab",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
description="Quantum Computing Lab programs in Python and Qiskit",
|
|
7
|
+
packages=find_packages(),
|
|
8
|
+
install_requires=[
|
|
9
|
+
"qiskit>=1.0.0",
|
|
10
|
+
"qiskit-aer>=0.14.0",
|
|
11
|
+
],
|
|
12
|
+
entry_points={
|
|
13
|
+
"console_scripts": [
|
|
14
|
+
"myqclab = myqclab.cli:main",
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
python_requires=">=3.8",
|
|
18
|
+
)
|