sequence 0.8.3.dev260767962__tar.gz → 0.8.5.dev8889859__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.
Files changed (113) hide show
  1. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/PKG-INFO +41 -13
  2. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/README.md +35 -10
  3. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/pyproject.toml +4 -1
  4. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/bsm.py +1 -1
  5. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/memory.py +11 -8
  6. sequence-0.8.5.dev8889859/sequence/constants.py +58 -0
  7. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/generation/single_heralded.py +30 -28
  8. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/app.py +0 -2
  9. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/eventlist.py +10 -12
  10. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/quantum_manager.py +6 -8
  11. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/quantum_utils.py +33 -26
  12. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/timeline.py +0 -5
  13. sequence-0.8.5.dev8889859/sequence/network_management/__init__.py +4 -0
  14. sequence-0.8.5.dev8889859/sequence/network_management/forwarding.py +102 -0
  15. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/network_management/network_manager.py +54 -13
  16. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/network_management/reservation.py +4 -4
  17. sequence-0.8.5.dev8889859/sequence/network_management/routing_distributed.py +800 -0
  18. sequence-0.8.5.dev8889859/sequence/network_management/routing_static.py +78 -0
  19. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/dqc_net_topo.py +2 -2
  20. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/node.py +36 -4
  21. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/router_net_topo.py +49 -22
  22. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/topology.py +5 -5
  23. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/utils/config_generator.py +1 -1
  24. sequence-0.8.3.dev260767962/sequence/constants.py +0 -36
  25. sequence-0.8.3.dev260767962/sequence/network_management/__init__.py +0 -4
  26. sequence-0.8.3.dev260767962/sequence/network_management/routing.py +0 -117
  27. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/__init__.py +0 -0
  28. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/app/__init__.py +0 -0
  29. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/app/random_request.py +0 -0
  30. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/app/request_app.py +0 -0
  31. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/app/teleport_app.py +0 -0
  32. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/__init__.py +0 -0
  33. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/beam_splitter.py +0 -0
  34. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/circuit.py +0 -0
  35. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/detector.py +0 -0
  36. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/fiber_stretcher.py +0 -0
  37. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/interferometer.py +0 -0
  38. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/light_source.py +0 -0
  39. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/mirror.py +0 -0
  40. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/optical_channel.py +0 -0
  41. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/photon.py +0 -0
  42. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/spdc_lens.py +0 -0
  43. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/switch.py +0 -0
  44. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/transducer.py +0 -0
  45. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/components/transmon.py +0 -0
  46. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/__init__.py +0 -0
  47. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/entanglement_protocol.py +0 -0
  48. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/generation/__init__.py +0 -0
  49. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/generation/barret_kok.py +0 -0
  50. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/generation/generation_base.py +0 -0
  51. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/generation/generation_message.py +0 -0
  52. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/purification/__init__.py +0 -0
  53. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/purification/bbpssw_bds.py +0 -0
  54. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/purification/bbpssw_circuit.py +0 -0
  55. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/purification/bbpssw_protocol.py +0 -0
  56. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/swapping.py +0 -0
  57. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/entanglement_management/teleportation.py +0 -0
  58. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/__init__.py +0 -0
  59. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/argonne.png +0 -0
  60. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/attributions_req +0 -0
  61. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/bsmnode.png +0 -0
  62. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/detector.png +0 -0
  63. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/logo.png +0 -0
  64. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/photonsource.png +0 -0
  65. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/quantum.png +0 -0
  66. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/repeater.png +0 -0
  67. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/router.png +0 -0
  68. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/sequence.jpg +0 -0
  69. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/bsmnode.svg +0 -0
  70. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/detector.svg +0 -0
  71. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/photonsource.svg +0 -0
  72. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/quantum.svg +0 -0
  73. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/repeater.svg +0 -0
  74. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/router.svg +0 -0
  75. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/svg/temp.svg +0 -0
  76. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/assets/temp.png +0 -0
  77. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/css_styles.py +0 -0
  78. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/default_params.json +0 -0
  79. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/default_templates.json +0 -0
  80. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/graph_comp.py +0 -0
  81. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/layout.py +0 -0
  82. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/menus.py +0 -0
  83. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/run_gui.py +0 -0
  84. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/simulator_bindings.py +0 -0
  85. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/starlight.json +0 -0
  86. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/test.txt +0 -0
  87. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/gui/user_templates.json +0 -0
  88. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/__init__.py +0 -0
  89. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/entity.py +0 -0
  90. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/event.py +0 -0
  91. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/process.py +0 -0
  92. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/kernel/quantum_state.py +0 -0
  93. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/message.py +0 -0
  94. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/protocol.py +0 -0
  95. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qkd/BB84.py +0 -0
  96. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qkd/__init__.py +0 -0
  97. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qkd/cascade.py +0 -0
  98. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qlan/correction.py +0 -0
  99. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qlan/graph_gen.py +0 -0
  100. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/qlan/measurement.py +0 -0
  101. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/resource_management/__init__.py +0 -0
  102. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/resource_management/memory_manager.py +0 -0
  103. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/resource_management/resource_manager.py +0 -0
  104. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/resource_management/rule_manager.py +0 -0
  105. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/__init__.py +0 -0
  106. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/qkd_topo.py +0 -0
  107. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/qlan/client.py +0 -0
  108. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/qlan/orchestrator.py +0 -0
  109. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/topology/qlan_star_topo.py +0 -0
  110. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/utils/__init__.py +0 -0
  111. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/utils/encoding.py +0 -0
  112. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/utils/log.py +0 -0
  113. {sequence-0.8.3.dev260767962 → sequence-0.8.5.dev8889859}/sequence/utils/noise.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sequence
3
- Version: 0.8.3.dev260767962
3
+ Version: 0.8.5.dev8889859
4
4
  Summary: Simulator of QUantum Network Communication (SeQUeNCe) is an open-source tool that allows modeling of quantum networks including photonic network components, control protocols, and applications.
5
5
  Keywords: quantum,network,discrete,event,simulator
6
6
  Author: Xiaoliang Wu, Joaquin Chung, Alexander Kolar, Alexander Kiefer, Eugene Wang, Tian Zhong, Rajkumar Kettimuthu, Martin Suchara, Robert Hayek, Ansh Singal, Caitao Zhan
@@ -22,19 +22,22 @@ Requires-Dist: matplotlib>=3.10.7
22
22
  Requires-Dist: networkx>=3.6.1
23
23
  Requires-Dist: numpy>=2.3.5
24
24
  Requires-Dist: pandas>=2.3.3
25
+ Requires-Dist: pandas-stubs~=2.3.3
25
26
  Requires-Dist: plotly>=6.5.0
26
27
  Requires-Dist: pytest>=9.0.2
27
28
  Requires-Dist: qutip>=5.2.2
28
29
  Requires-Dist: qutip-qip>=0.4.1
29
30
  Requires-Dist: scipy>=1.16.3
31
+ Requires-Dist: scipy-stubs~=1.16.3
32
+ Requires-Dist: seaborn>=0.13.2
30
33
  Requires-Dist: tqdm>=4.67.1
31
34
  Maintainer: Caitao Zhan, Robert Hayek
32
35
  Maintainer-email: Caitao Zhan <czhan@anl.gov>, Robert Hayek <rhayek@anl.gov>
33
36
  Requires-Python: >=3.11, <3.15
34
- Project-URL: Changelog, https://github.com/sequence-toolbox/SeQUeNCe/blob/master/CHANGELOG.md
35
- Project-URL: Documentation, https://sequence-rtd-tutorial.readthedocs.io/
36
37
  Project-URL: Homepage, https://github.com/sequence-toolbox/SeQUeNCe
38
+ Project-URL: Documentation, https://sequence-rtd-tutorial.readthedocs.io/
37
39
  Project-URL: Issues, https://github.com/sequence-toolbox/SeQUeNCe/issues
40
+ Project-URL: Changelog, https://github.com/sequence-toolbox/SeQUeNCe/blob/master/CHANGELOG.md
38
41
  Description-Content-Type: text/markdown
39
42
 
40
43
  <p align="center">
@@ -75,22 +78,46 @@ SeQUeNCe is an open source, discrete-event simulator for quantum networks. As de
75
78
 
76
79
  These modules can be edited by users to define additional functionality and test protocol schemes, or may be used as-is to test network parameters and topologies.
77
80
 
78
- ## Installing
79
- SeQUeNCe requires [Python](https://www.python.org/downloads/) 3.11 or later. You can simply install SeQUeNCe using `pip`:
81
+ ## Installation
82
+ ### For Users
83
+ SeQUeNCe requires [Python](https://www.python.org/downloads/) 3.11 or later. You can install SeQUeNCe using `pip`:
80
84
  ```
81
85
  pip install sequence
82
86
  ```
83
87
 
84
- If you wish to make your own edits to the codebase, SeQUeNCe should be installed in [development mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) (a.k.a. editable install).
85
- To do so, clone and install the simulator as follows:
88
+ ### Development Environment Setup
89
+ If you wish to modify the source code, use an editable installation with [uv](https://docs.astral.sh/uv/):
90
+
91
+ #### Install uv ([Astral Instructions](https://docs.astral.sh/uv/getting-started/installation/))
92
+ ```bash
93
+ # macOS/Linux
94
+ curl -LsSf https://astral.sh/uv/install.sh | sh
95
+
96
+ # Windows
97
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
86
98
  ```
99
+
100
+ #### Clone the repository and create the virtual environment
101
+ Here we clone the repository and let uv configure the development environment with the target python version.
102
+ ```bash
87
103
  git clone https://github.com/sequence-toolbox/SeQUeNCe.git
88
- cd SeQUeNCe
89
- pip install --editable . --config-settings editable_mode=strict
104
+ cd sequence
105
+ uv sync
90
106
  ```
91
107
 
92
- For Linux and Mac users, you could use `make install_editable` instead of `pip install --editable . --config-settings editable_mode=strict`
108
+ #### Activate the virtual environment
109
+ Now that the virtual environment is created with all dependencies installed, you can activate it using the following command.
110
+
111
+ ```bash
112
+ source .venv/bin/activate # macOS/Linux
113
+ source .venv\Scripts\activate # Windows
114
+ ```
93
115
 
116
+ #### Running the test suite
117
+ SeQUeNCe includes a comprehensive test suite, this can be ran with the following command
118
+ ```
119
+ uv run pytest tests
120
+ ```
94
121
 
95
122
  ## Citation
96
123
  Please cite us, thank you!
@@ -111,7 +138,7 @@ publisher = {IOP Publishing},
111
138
  <!-- * X. Wu, A. Kolar, J. Chung, D. Jin, T. Zhong, R. Kettimuthu and M. Suchara. "SeQUeNCe: Simulator of QUantum Network Communication." GitHub repository, https://github.com/sequence-toolbox/SeQUeNCe, 2021. -->
112
139
 
113
140
  ## Running the GUI
114
- Once SeQUeNCe has been installed as described above, simply run the `gui.py` script found in the root of the project directory
141
+ Once SeQUeNCe has been installed as described above, run the `gui.py` script found in the root of the project directory
115
142
  ```
116
143
  python gui.py
117
144
  ```
@@ -122,9 +149,9 @@ Many examples of SeQUeNCe in action can be found in the [example](/example) fold
122
149
  ## Additional Tools
123
150
 
124
151
  ### Network Visualization
125
- The example directory contains an example json file `starlight.json` to specify a network topology, and the utils directory contains the script `draw_topo.py` to visualize json files. To use this script, the Graphviz library must be installed. Installation information can be found on the [Graphviz website](https://www.graphviz.org/download/).
152
+ The example directory contains an example .json file `starlight.json` to specify a network topology, and the utils directory contains the script `draw_topo.py` to visualize json files. To use this script, the Graphviz library must be installed. Installation information can be found on the [Graphviz website](https://www.graphviz.org/download/).
126
153
 
127
- To view a network, simply run the script and specify the relative location of your json file:
154
+ To view a network, run the script and specify the relative location of your .json file:
128
155
  ```
129
156
  python utils/draw_topo.py example/starlight.json
130
157
  ```
@@ -159,5 +186,6 @@ If you have questions, please contact [Caitao Zhan](https://caitaozhan.github.io
159
186
 
160
187
  * C. Zhan et al., ["Design and Simulation of the Adaptive Continuous Entanglement Generation Protocol"](https://arxiv.org/abs/2502.01964), QCNC 2025. [GitHub Repository](https://github.com/caitaozhan/adaptive-continuous)
161
188
 
189
+ * H. Miller et al., ["Simulation of a Heterogeneous Quantum Network"](https://arxiv.org/abs/2512.04211), arXiv preprint, 2025
162
190
 
163
191
  Please do a Pull Request to add your paper here!
@@ -36,22 +36,46 @@ SeQUeNCe is an open source, discrete-event simulator for quantum networks. As de
36
36
 
37
37
  These modules can be edited by users to define additional functionality and test protocol schemes, or may be used as-is to test network parameters and topologies.
38
38
 
39
- ## Installing
40
- SeQUeNCe requires [Python](https://www.python.org/downloads/) 3.11 or later. You can simply install SeQUeNCe using `pip`:
39
+ ## Installation
40
+ ### For Users
41
+ SeQUeNCe requires [Python](https://www.python.org/downloads/) 3.11 or later. You can install SeQUeNCe using `pip`:
41
42
  ```
42
43
  pip install sequence
43
44
  ```
44
45
 
45
- If you wish to make your own edits to the codebase, SeQUeNCe should be installed in [development mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) (a.k.a. editable install).
46
- To do so, clone and install the simulator as follows:
46
+ ### Development Environment Setup
47
+ If you wish to modify the source code, use an editable installation with [uv](https://docs.astral.sh/uv/):
48
+
49
+ #### Install uv ([Astral Instructions](https://docs.astral.sh/uv/getting-started/installation/))
50
+ ```bash
51
+ # macOS/Linux
52
+ curl -LsSf https://astral.sh/uv/install.sh | sh
53
+
54
+ # Windows
55
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
47
56
  ```
57
+
58
+ #### Clone the repository and create the virtual environment
59
+ Here we clone the repository and let uv configure the development environment with the target python version.
60
+ ```bash
48
61
  git clone https://github.com/sequence-toolbox/SeQUeNCe.git
49
- cd SeQUeNCe
50
- pip install --editable . --config-settings editable_mode=strict
62
+ cd sequence
63
+ uv sync
51
64
  ```
52
65
 
53
- For Linux and Mac users, you could use `make install_editable` instead of `pip install --editable . --config-settings editable_mode=strict`
66
+ #### Activate the virtual environment
67
+ Now that the virtual environment is created with all dependencies installed, you can activate it using the following command.
54
68
 
69
+ ```bash
70
+ source .venv/bin/activate # macOS/Linux
71
+ source .venv\Scripts\activate # Windows
72
+ ```
73
+
74
+ #### Running the test suite
75
+ SeQUeNCe includes a comprehensive test suite, this can be ran with the following command
76
+ ```
77
+ uv run pytest tests
78
+ ```
55
79
 
56
80
  ## Citation
57
81
  Please cite us, thank you!
@@ -72,7 +96,7 @@ publisher = {IOP Publishing},
72
96
  <!-- * X. Wu, A. Kolar, J. Chung, D. Jin, T. Zhong, R. Kettimuthu and M. Suchara. "SeQUeNCe: Simulator of QUantum Network Communication." GitHub repository, https://github.com/sequence-toolbox/SeQUeNCe, 2021. -->
73
97
 
74
98
  ## Running the GUI
75
- Once SeQUeNCe has been installed as described above, simply run the `gui.py` script found in the root of the project directory
99
+ Once SeQUeNCe has been installed as described above, run the `gui.py` script found in the root of the project directory
76
100
  ```
77
101
  python gui.py
78
102
  ```
@@ -83,9 +107,9 @@ Many examples of SeQUeNCe in action can be found in the [example](/example) fold
83
107
  ## Additional Tools
84
108
 
85
109
  ### Network Visualization
86
- The example directory contains an example json file `starlight.json` to specify a network topology, and the utils directory contains the script `draw_topo.py` to visualize json files. To use this script, the Graphviz library must be installed. Installation information can be found on the [Graphviz website](https://www.graphviz.org/download/).
110
+ The example directory contains an example .json file `starlight.json` to specify a network topology, and the utils directory contains the script `draw_topo.py` to visualize json files. To use this script, the Graphviz library must be installed. Installation information can be found on the [Graphviz website](https://www.graphviz.org/download/).
87
111
 
88
- To view a network, simply run the script and specify the relative location of your json file:
112
+ To view a network, run the script and specify the relative location of your .json file:
89
113
  ```
90
114
  python utils/draw_topo.py example/starlight.json
91
115
  ```
@@ -120,5 +144,6 @@ If you have questions, please contact [Caitao Zhan](https://caitaozhan.github.io
120
144
 
121
145
  * C. Zhan et al., ["Design and Simulation of the Adaptive Continuous Entanglement Generation Protocol"](https://arxiv.org/abs/2502.01964), QCNC 2025. [GitHub Repository](https://github.com/caitaozhan/adaptive-continuous)
122
146
 
147
+ * H. Miller et al., ["Simulation of a Heterogeneous Quantum Network"](https://arxiv.org/abs/2512.04211), arXiv preprint, 2025
123
148
 
124
149
  Please do a Pull Request to add your paper here!
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sequence"
3
- version = "0.8.3.dev260767962"
3
+ version = "0.8.5.dev8889859"
4
4
  authors = [
5
5
  { name = "Xiaoliang Wu, Joaquin Chung, Alexander Kolar, Alexander Kiefer, Eugene Wang, Tian Zhong, Rajkumar Kettimuthu, Martin Suchara, Robert Hayek, Ansh Singal, Caitao Zhan", email = "czhan@anl.gov" }
6
6
  ]
@@ -32,11 +32,14 @@ dependencies = [
32
32
  "networkx>=3.6.1",
33
33
  "numpy>=2.3.5",
34
34
  "pandas>=2.3.3",
35
+ "pandas-stubs~=2.3.3",
35
36
  "plotly>=6.5.0",
36
37
  "pytest>=9.0.2",
37
38
  "qutip>=5.2.2",
38
39
  "qutip-qip>=0.4.1",
39
40
  "scipy>=1.16.3",
41
+ "scipy-stubs~=1.16.3",
42
+ "seaborn>=0.13.2",
40
43
  "tqdm>=4.67.1",
41
44
  ]
42
45
 
@@ -678,8 +678,8 @@ class SingleHeraldedBSM(BSM):
678
678
  log.logger.debug(f'{self.name}: photonic BSM failed')
679
679
  else:
680
680
  p0, p1 = self.photons
681
- # if both memory successfully emit the photon in this round (consider memory emission inefficiency)
682
681
  if self.get_generator().random() > p0.loss and self.get_generator().random() > p1.loss:
682
+ # if both photons successfully arrive (not lost in memory or optical fiber) and the BSM is successful
683
683
  for idx, photon in enumerate(self.photons):
684
684
  detector = self.detectors[idx]
685
685
  detector.get(photon)
@@ -46,7 +46,7 @@ class MemoryArray(Entity):
46
46
 
47
47
  def __init__(self, name: str, timeline: "Timeline", num_memories=10,
48
48
  fidelity=0.85, frequency=80e6, efficiency=1, coherence_time=-1, wavelength=500,
49
- decoherence_errors: list[float] = None, cutoff_ratio = 1):
49
+ decoherence_errors: list[float] = None, cutoff_ratio: float = 1, cutoff_flag: bool = True):
50
50
  """Constructor for the Memory Array class.
51
51
 
52
52
  Args:
@@ -60,6 +60,7 @@ class MemoryArray(Entity):
60
60
  wavelength (int): wavelength (in nm) of photons emitted by memories (default 500).
61
61
  decoherence_errors (list[int]): pauli decoherence errors. Passed to memory object.
62
62
  cutoff_ratio (float): the ratio between cutoff time and memory coherence time (default 1, should be between 0 and 1).
63
+ cutoff_flag (bool): Flag to enable or disable expiry events
63
64
  """
64
65
 
65
66
  Entity.__init__(self, name, timeline)
@@ -77,7 +78,7 @@ class MemoryArray(Entity):
77
78
  for i in range(num_memories):
78
79
  memory_name = self.name + f"[{i}]"
79
80
  self.memory_name_to_index[memory_name] = i
80
- memory = Memory(memory_name, timeline, fidelity, frequency, efficiency, coherence_time, wavelength, decoherence_errors, cutoff_ratio)
81
+ memory = Memory(memory_name, timeline, fidelity, frequency, efficiency, coherence_time, wavelength, decoherence_errors, cutoff_ratio, cutoff_flag)
81
82
  memory.attach(self)
82
83
  self.memories.append(memory)
83
84
  memory.set_memory_array(self)
@@ -127,7 +128,7 @@ class MemoryArray(Entity):
127
128
 
128
129
  Args:
129
130
  name (str): name of memory
130
- Return:
131
+ Returns:
131
132
  (Memory): the memory object
132
133
  """
133
134
  index = self.memory_name_to_index.get(name, -1)
@@ -187,7 +188,7 @@ class Memory(Entity):
187
188
  """
188
189
 
189
190
  def __init__(self, name: str, timeline: "Timeline", fidelity: float, frequency: float,
190
- efficiency: float, coherence_time: float, wavelength: int, decoherence_errors: list[float] = None, cutoff_ratio: float = 1):
191
+ efficiency: float, coherence_time: float, wavelength: int, decoherence_errors: list[float] = None, cutoff_ratio: float = 1, cutoff_flag: bool = True):
191
192
  """Constructor for the Memory class.
192
193
 
193
194
  Args:
@@ -202,7 +203,8 @@ class Memory(Entity):
202
203
  decoherence_errors (list[float]): assuming the memory (qubit) decoherence channel being Pauli channel,
203
204
  probability distribution of X, Y, Z Pauli errors
204
205
  (default value is None, meaning not using BDS or further density matrix representation)
205
- cutoff_ratio (float): the ratio between cutoff time and memory coherence time (default 1, should be between 0 and 1).
206
+ cutoff_ratio (float): the ratio between cutoff time and memory coherence time (default 1, should be > 0).
207
+ cutoff_flag (bool): Flag for the cutoff behavior
206
208
  """
207
209
 
208
210
  super().__init__(name, timeline)
@@ -223,8 +225,9 @@ class Memory(Entity):
223
225
  if self.decoherence_errors is not None:
224
226
  assert len(self.decoherence_errors) == 3 and abs(sum(self.decoherence_errors) - 1) < EPSILON, \
225
227
  "Decoherence errors refer to probabilities for each Pauli error to happen if an error happens, thus should be normalized."
228
+ self.cutoff_flag = cutoff_flag
226
229
  self.cutoff_ratio = cutoff_ratio
227
- assert 0 < self.cutoff_ratio <= 1, "Ratio of cutoff time and coherence time should be between 0 and 1"
230
+ assert 0 < self.cutoff_ratio, "Ratio of cutoff time and coherence time should be greater than 0."
228
231
  self.generation_time = -1
229
232
  self.last_update_time = -1
230
233
  self.is_in_application = False
@@ -359,7 +362,7 @@ class Memory(Entity):
359
362
  self.entangled_memory = {'node_id': None, 'memo_id': None}
360
363
 
361
364
  # schedule expiration
362
- if self.coherence_time > 0:
365
+ if self.coherence_time > 0 and self.cutoff_flag:
363
366
  self._schedule_expiration()
364
367
 
365
368
  def bds_decohere(self) -> None:
@@ -460,7 +463,7 @@ class Memory(Entity):
460
463
  def get_bds_fidelity(self) -> float:
461
464
  """Will get the fidelity from the BDS state
462
465
 
463
- Return:
466
+ Returns:
464
467
  (float): the fidelity of the BDS state
465
468
  """
466
469
  state_obj = self.timeline.quantum_manager.get(self.qstate_key)
@@ -0,0 +1,58 @@
1
+ """Shared constants used across SeQUeNCe.
2
+
3
+ This module centralizes immutable values that are reused by simulation and
4
+ network components, including:
5
+
6
+ - Physical constants (for example, speed of light in meters per picosecond).
7
+ - Canonical quantum state vectors (basis states and Bell states).
8
+ - Numerical tolerances (`EPSILON`) for floating-point comparisons.
9
+ - Time unit conversion factors in picoseconds (`NANOSECOND` to `SECOND`).
10
+ - Built-in formalism and protocol identifier strings.
11
+ """
12
+
13
+ from typing import Final
14
+
15
+ #: Speed of light in meters per picosecond.
16
+ SPEED_OF_LIGHT: Final = 2e-4
17
+
18
+ #: Qubit computational basis state |0>.
19
+ KET0: Final = (1, 0)
20
+ #: Qubit computational basis state |1>.
21
+ KET1: Final = (0, 1)
22
+
23
+ #: Normalization factor 1/sqrt(2) used by Bell states.
24
+ SQRT_HALF: Final = 0.5 ** 0.5
25
+ #: Bell state |Phi+>.
26
+ PHI_PLUS: Final = (SQRT_HALF, 0, 0, SQRT_HALF)
27
+ #: Bell state |Phi->.
28
+ PHI_MINUS: Final = (SQRT_HALF, 0, 0, -SQRT_HALF)
29
+ #: Bell state |Psi+>.
30
+ PSI_PLUS: Final = (0, SQRT_HALF, SQRT_HALF, 0)
31
+ #: Bell state |Psi->.
32
+ PSI_MINUS: Final = (0, SQRT_HALF, -SQRT_HALF, 0)
33
+
34
+ #: Small tolerance value for floating-point comparisons.
35
+ EPSILON: Final = 1e-8
36
+
37
+ #: Number of picoseconds in one nanosecond.
38
+ NANOSECOND: Final = 10**3
39
+ #: Number of picoseconds in one microsecond.
40
+ MICROSECOND: Final = 10**6
41
+ #: Number of picoseconds in one millisecond.
42
+ MILLISECOND: Final = 10**9
43
+ #: Number of picoseconds in one second.
44
+ SECOND: Final = 10**12
45
+
46
+ #: Built-in ket-vector formalism identifier.
47
+ KET_STATE_FORMALISM: Final = "ket_vector"
48
+ #: Built-in density-matrix formalism identifier.
49
+ DENSITY_MATRIX_FORMALISM: Final = "density_matrix"
50
+ #: Built-in Fock density-matrix formalism identifier.
51
+ FOCK_DENSITY_MATRIX_FORMALISM: Final = "fock_density"
52
+ #: Built-in Bell-diagonal-state formalism identifier.
53
+ BELL_DIAGONAL_STATE_FORMALISM: Final = "bell_diagonal"
54
+
55
+ #: Built-in Barrett-Kok generation protocol identifier.
56
+ BARRET_KOK: Final = 'barret_kok'
57
+ #: Built-in single-heralded generation protocol identifier.
58
+ SINGLE_HERALDED: Final = 'single_heralded'
@@ -22,13 +22,29 @@ if TYPE_CHECKING:
22
22
 
23
23
  @EntanglementGenerationA.register(SINGLE_HERALDED)
24
24
  class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
25
+ """
26
+ Class for single heralded entanglement generation protocol A.
27
+ This protocol is used on the two end nodes of the entanglement generation process.
28
+
29
+ Attributes:
30
+ owner (Node): node that protocol instance is attached to.
31
+ name (str): label for protocol instance.
32
+ middle (str): name of the middle BSM node.
33
+ other (str): name of the other end node.
34
+ memory (Memory): memory object used for entanglement generation.
35
+ raw_fidelity (float): the raw fidelity of generated entangled pair.
36
+ raw_epr_errors (list[float]): the raw EPR pair Pauli error rates in X, Y, Z order.
37
+ bsm_res (list[int]): the BSM measurement results from the middle BSM node.
38
+ """
25
39
  def __init__(self, owner: Node, name: str, middle: str, other: str, memory: Memory,
26
40
  raw_fidelity: float = None, raw_epr_errors: list[float] = None):
27
41
  super().__init__(owner, name, middle, other, memory)
28
42
 
29
43
  self.protocol_type = SINGLE_HERALDED
30
- assert QuantumManager.get_active_formalism() == BELL_DIAGONAL_STATE_FORMALISM, \
31
- f"Single Heralded Entanglement generation protocol only supports Bell diagonal state formalism; got {QuantumManager.get_active_formalism()}"
44
+ active_formalism = QuantumManager.get_active_formalism()
45
+ assert_message = ("Single Heralded Entanglement generation protocol only"
46
+ f"supports Bell diagonal state formalism; got {active_formalism}")
47
+ assert active_formalism == BELL_DIAGONAL_STATE_FORMALISM, assert_message
32
48
 
33
49
  if raw_fidelity:
34
50
  self.raw_fidelity = raw_fidelity
@@ -40,8 +56,7 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
40
56
  if self.raw_epr_errors is None:
41
57
  self.raw_epr_errors = [1 / 3, 1 / 3, 1 / 3]
42
58
  if self.raw_epr_errors:
43
- assert len(self.raw_epr_errors) == 3, \
44
- "Raw EPR pair pauli error list should have three elements in X, Y, Z order."
59
+ assert len(self.raw_epr_errors) == 3, "Raw EPR pair pauli error list should have three elements in X, Y, Z order."
45
60
 
46
61
  self.bsm_res = [0, 0]
47
62
 
@@ -130,8 +145,7 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
130
145
 
131
146
  msg_type = msg.msg_type
132
147
 
133
- log.logger.debug("{} {} received message from node {} of type {}, round={}".format(
134
- self.owner.name, self.name, src, msg.msg_type, self.ent_round))
148
+ log.logger.debug(f"{self.owner.name} {self.name} received message from node {src} of type {msg.msg_type}, round={self.ent_round}")
135
149
 
136
150
  if msg_type is GenerationMsgType.NEGOTIATE: # primary -> non-primary
137
151
  # configure params
@@ -141,8 +155,7 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
141
155
 
142
156
  # get time for first excite event
143
157
  memory_excite_time = self.memory.next_excite_time
144
- min_time = max(self.owner.timeline.now(),
145
- memory_excite_time) + other_qc_delay - self.qc_delay + cc_delay # cc_delay time for NEGOTIATE_ACK
158
+ min_time = max(self.owner.timeline.now(), memory_excite_time) + other_qc_delay - self.qc_delay + cc_delay # cc_delay time for NEGOTIATE_ACK
146
159
  emit_time = self.owner.schedule_qubit(self.middle, min_time) # used to send memory
147
160
  self.expected_time = emit_time + self.qc_delay # expected time for middle BSM node to receive the photon
148
161
 
@@ -154,17 +167,13 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
154
167
 
155
168
  # send negotiate_ack
156
169
  other_emit_time = emit_time + self.qc_delay - other_qc_delay
157
- message = EntanglementGenerationMessage(GenerationMsgType.NEGOTIATE_ACK,
158
- self.remote_protocol_name,
159
- protocol_type=self.protocol_type,
160
- emit_time=other_emit_time)
170
+ message = EntanglementGenerationMessage(GenerationMsgType.NEGOTIATE_ACK, self.remote_protocol_name,
171
+ self.protocol_type, emit_time=other_emit_time)
161
172
  self.owner.send_message(src, message)
162
173
 
163
- # schedule start if necessary (current is first round, need second round),
164
- # else schedule update_memory (currently second round)
174
+ # schedule start if necessary (current is first round, need second round), else schedule update_memory (currently second round)
165
175
  # TODO: base future start time on resolution
166
- future_start_time = self.expected_time + self.owner.cchannels[
167
- self.middle].delay + 10 # delay is for sending the BSM_RES to end nodes, 10 is a small gap
176
+ future_start_time = self.expected_time + self.owner.cchannels[self.middle].delay + 10 # delay is for sending the BSM_RES to end nodes, 10 is a small gap
168
177
  if self.ent_round == 1:
169
178
  process = Process(self, "start", []) # for the second round
170
179
  else:
@@ -183,8 +192,7 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
183
192
 
184
193
  # schedule emit
185
194
  emit_time = self.owner.schedule_qubit(self.middle, msg.emit_time)
186
- assert emit_time == msg.emit_time, \
187
- f"Invalid eg emit times {emit_time} {msg.emit_time} {self.owner.timeline.now()}"
195
+ assert emit_time == msg.emit_time, f"Invalid eg emit times {emit_time} {msg.emit_time} {self.owner.timeline.now()}"
188
196
 
189
197
  process = Process(self, "emit_event", [])
190
198
  event = Event(msg.emit_time, process)
@@ -210,7 +218,7 @@ class SingleHeraldedA(EntanglementGenerationA, QuantumCircuitMixin):
210
218
  resolution = msg.resolution
211
219
 
212
220
  log.logger.debug("{} received MEAS_RES={} at time={:,}, expected={:,}, resolution={}, round={}".format(
213
- self.owner.name, detector, time, self.expected_time, resolution, self.ent_round))
221
+ self.owner.name, detector, time, self.expected_time, resolution, self.ent_round))
214
222
 
215
223
  if valid_trigger_time(time, self.expected_time, resolution):
216
224
  self.bsm_res[detector] += 1
@@ -244,9 +252,7 @@ class SingleHeraldedB(EntanglementGenerationB):
244
252
  bsm (SingleAtomBSM or SingleHeraldedBSM): bsm object calling method.
245
253
  info (Dict[str, any]): information passed from bsm.
246
254
  """
247
- assert bsm.encoding == SINGLE_HERALDED, \
248
- "SingleHeraldedB should only be used with SingleHeraldedBSM."
249
-
255
+ assert bsm.encoding == SINGLE_HERALDED, "SingleHeraldedB should only be used with SingleHeraldedBSM."
250
256
  assert info['info_type'] == 'BSM_res'
251
257
 
252
258
  res = info['res']
@@ -254,10 +260,6 @@ class SingleHeraldedB(EntanglementGenerationB):
254
260
  resolution = bsm.resolution
255
261
 
256
262
  for node in self.others:
257
- message = EntanglementGenerationMessage(GenerationMsgType.MEAS_RES,
258
- receiver=None,
259
- protocol_type=self.protocol_type,
260
- detector=res,
261
- time=time,
262
- resolution=resolution)
263
+ message = EntanglementGenerationMessage(GenerationMsgType.MEAS_RES, None, self.protocol_type,
264
+ detector=res, time=time, resolution=resolution)
263
265
  self.owner.send_message(node, message)
@@ -358,8 +358,6 @@ class QuantumGUI:
358
358
  Topology.ALL_Q_CONNECT: qconnections,
359
359
  Topology.ALL_C_CHANNEL: cchannels,
360
360
  Topology.ALL_TEMPLATES: templates,
361
-
362
- RouterNetTopo.IS_PARALLEL: False,
363
361
  Topology.STOP_TIME: int(1e12)
364
362
  }
365
363
 
@@ -4,12 +4,10 @@ This module defines the EventList class, used by the timeline to order and execu
4
4
  EventList is implemented as a min heap ordered by simulation time.
5
5
  """
6
6
 
7
- from typing import TYPE_CHECKING
8
-
9
- if TYPE_CHECKING:
10
- from .event import Event
11
-
12
7
  from heapq import heappop, heappush
8
+ from typing import Iterator
9
+
10
+ from .event import Event
13
11
 
14
12
 
15
13
  class EventList:
@@ -22,27 +20,27 @@ class EventList:
22
20
  """
23
21
 
24
22
  def __init__(self):
25
- self.data: list["Event"] = []
23
+ self.data: list[Event] = []
26
24
 
27
25
  def __len__(self):
28
26
  return len(self.data)
29
27
 
30
- def __iter__(self):
28
+ def __iter__(self) -> Iterator[Event]:
31
29
  yield from self.data
32
30
 
33
- def push(self, event: "Event") -> "None":
31
+ def push(self, event: Event) -> None:
34
32
  heappush(self.data, event)
35
33
 
36
- def pop(self) -> "Event":
34
+ def pop(self) -> Event:
37
35
  return heappop(self.data)
38
36
 
39
- def top(self) -> "Event":
37
+ def top(self) -> Event:
40
38
  return self.data[0]
41
39
 
42
40
  def isempty(self) -> bool:
43
41
  return len(self.data) == 0
44
42
 
45
- def remove(self, event: "Event") -> None:
43
+ def remove(self, event: Event) -> None:
46
44
  """Method to remove events from heap.
47
45
 
48
46
  The event is set as the invalid state to save the time of removing event from heap.
@@ -50,7 +48,7 @@ class EventList:
50
48
 
51
49
  event.set_invalid()
52
50
 
53
- def update_event_time(self, event: "Event", time: int):
51
+ def update_event_time(self, event: Event, time: int):
54
52
  """Method to update the timestamp of event and maintain the min-heap structure.
55
53
  """
56
54
  if time == event.time:
@@ -551,8 +551,8 @@ class QuantumManagerDensity(QuantumManager):
551
551
  key = keys[0]
552
552
  num_states = len(all_keys)
553
553
  state_index = all_keys.index(key)
554
- state_0, state_1, prob_0 = \
555
- measure_entangled_state_with_cache_density(tuple(map(tuple, state)), state_index, num_states)
554
+ state_0, state_1, prob_0 = measure_entangled_state_with_cache_density(tuple(map(tuple, state)),
555
+ state_index, num_states)
556
556
  if meas_samp < prob_0:
557
557
  new_state = array(state_0, dtype=complex)
558
558
  result = 0
@@ -795,15 +795,13 @@ class QuantumManagerDensityFock(QuantumManager):
795
795
  key = keys[0]
796
796
  num_states = len(all_keys)
797
797
  state_index = all_keys.index(key)
798
- states, probs = \
799
- measure_entangled_state_with_cache_fock_density(state_tuple, state_index, num_states, povm_tuple,
800
- self.truncation)
798
+ states, probs = measure_entangled_state_with_cache_fock_density(state_tuple, state_index, num_states,
799
+ povm_tuple, self.truncation)
801
800
 
802
801
  else:
803
802
  indices = tuple([all_keys.index(key) for key in keys])
804
- states, probs = \
805
- measure_multiple_with_cache_fock_density(state_tuple, indices, len(all_keys), povm_tuple,
806
- self.truncation)
803
+ states, probs = measure_multiple_with_cache_fock_density(state_tuple, indices, len(all_keys),
804
+ povm_tuple, self.truncation)
807
805
 
808
806
  # calculate result based on measurement sample.
809
807
  prob_sum = cumsum(probs)