print.html 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. <!DOCTYPE HTML>
  2. <html lang="en" class="sidebar-visible">
  3. <head>
  4. <!-- Book generated using mdBook -->
  5. <meta charset="UTF-8">
  6. <title>QCGPU User Guide</title>
  7. <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  8. <meta name="description" content="The user guide / prose documentation for QCGPU">
  9. <meta name="viewport" content="width=device-width, initial-scale=1">
  10. <meta name="theme-color" content="#ffffff" />
  11. <base href="">
  12. <link rel="stylesheet" href="book.css">
  13. <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
  14. <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
  15. <link rel="shortcut icon" href="favicon.png">
  16. <!-- Font Awesome -->
  17. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
  18. <link rel="stylesheet" href="highlight.css">
  19. <link rel="stylesheet" href="tomorrow-night.css">
  20. <link rel="stylesheet" href="ayu-highlight.css">
  21. <!-- Custom theme -->
  22. <!-- MathJax -->
  23. <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
  24. <!-- Fetch Clipboard.js from CDN but have a local fallback -->
  25. <script src="https://cdn.jsdelivr.net/clipboard.js/1.6.1/clipboard.min.js"></script>
  26. <script>
  27. if (typeof Clipboard == 'undefined') {
  28. document.write(unescape("%3Cscript src='clipboard.min.js'%3E%3C/script%3E"));
  29. }
  30. </script>
  31. <noscript>
  32. <style type="text/css">
  33. .javascript-only {
  34. display: none;
  35. }
  36. </style>
  37. </noscript>
  38. </head>
  39. <body class="light">
  40. <!-- Work around some values being stored in localStorage wrapped in quotes -->
  41. <script type="text/javascript">
  42. try {
  43. var theme = localStorage.getItem('mdbook-theme');
  44. var sidebar = localStorage.getItem('mdbook-sidebar');
  45. if (theme.startsWith('"') && theme.endsWith('"')) {
  46. localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
  47. }
  48. if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
  49. localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
  50. }
  51. } catch (e) { }
  52. </script>
  53. <!-- Set the theme before any content is loaded, prevents flash -->
  54. <script type="text/javascript">
  55. var theme;
  56. try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
  57. if (theme === null || theme === undefined) { theme = 'light'; }
  58. document.body.className = theme;
  59. document.querySelector('html').className = theme;
  60. </script>
  61. <!-- Hide / unhide sidebar before it is displayed -->
  62. <script type="text/javascript">
  63. var html = document.querySelector('html');
  64. var sidebar = 'hidden';
  65. if (document.body.clientWidth >= 1080) {
  66. try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
  67. sidebar = sidebar || 'visible';
  68. }
  69. html.classList.remove('sidebar-visible');
  70. html.classList.add("sidebar-" + sidebar);
  71. </script>
  72. <nav id="sidebar" class="sidebar" aria-label="Table of contents">
  73. <ol class="chapter"><li><a href="qcgpu.html"><strong aria-hidden="true">1.</strong> QCGPU</a></li><li><ol class="section"><li><a href="getting-started.html"><strong aria-hidden="true">1.1.</strong> Getting Started</a></li></ol></li><li><a href="user-guide/user-guide.html"><strong aria-hidden="true">2.</strong> User Guide</a></li><li><ol class="section"><li><a href="user-guide/registers.html"><strong aria-hidden="true">2.1.</strong> Quantum Registers</a></li><li><a href="user-guide/gates.html"><strong aria-hidden="true">2.2.</strong> Quantum Gates</a></li><li><a href="user-guide/operations.html"><strong aria-hidden="true">2.3.</strong> Quantum Operations</a></li><li><a href="user-guide/examples.html"><strong aria-hidden="true">2.4.</strong> Examples</a></li><li><a href="user-guide/decoherence.html"><strong aria-hidden="true">2.5.</strong> Decoherence</a></li></ol></li><li><a href="algorithms/algorithms.html"><strong aria-hidden="true">3.</strong> Algorithms</a></li><li><ol class="section"><li><a href="algorithms/bernstein-vazirani.html"><strong aria-hidden="true">3.1.</strong> Bernstein-Vazirani</a></li><li><a href="algorithms/deutsch-jozsa.html"><strong aria-hidden="true">3.2.</strong> Deutsch-Jozsa</a></li><li><a href="algorithms/grover.html"><strong aria-hidden="true">3.3.</strong> Grovers</a></li><li><a href="algorithms/shor.html"><strong aria-hidden="true">3.4.</strong> Shors</a></li><li><a href="algorithms/super-dense.html"><strong aria-hidden="true">3.5.</strong> Super Dense Coding</a></li></ol></li></ol>
  74. </nav>
  75. <div id="page-wrapper" class="page-wrapper">
  76. <div class="page">
  77. <div id="menu-bar" class="menu-bar">
  78. <div id="menu-bar-sticky-container">
  79. <div class="left-buttons javascript-only">
  80. <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
  81. <i class="fa fa-bars"></i>
  82. </button>
  83. <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
  84. <i class="fa fa-paint-brush"></i>
  85. </button>
  86. <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
  87. <li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
  88. <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
  89. <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
  90. <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
  91. <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
  92. </ul>
  93. <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
  94. <i class="fa fa-search"></i>
  95. </button>
  96. </div>
  97. <h1 class="menu-title">QCGPU User Guide</h1>
  98. <div class="right-buttons">
  99. <a href="print.html" title="Print this book" aria-label="Print this book">
  100. <i id="print-button" class="fa fa-print"></i>
  101. </a>
  102. </div>
  103. </div>
  104. </div>
  105. <div id="searchbar-outer" class="searchbar-outer">
  106. <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
  107. </div>
  108. <div id="searchresults-outer" class="searchresults-outer">
  109. <div class="searchresults-header" id="searchresults-header"></div>
  110. <ul id="searchresults">
  111. </ul>
  112. </div>
  113. <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
  114. <script type="text/javascript">
  115. document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
  116. document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
  117. Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
  118. link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
  119. });
  120. </script>
  121. <div id="content" class="content">
  122. <main>
  123. <a class="header" href="print.html#qcgpu" id="qcgpu"><h1>QCGPU</h1></a>
  124. <p><strong>QCGPU</strong> is a high performance, hardware accelerated quantum computer simulator written with <a href="https://rust-lang.org/">Rust</a> and <a href="https://www.khronos.org/opencl/">OpenCL</a>.</p>
  125. <p>QCGPU is free and open source. The source code is available on <a href="https://github.com/qcgpu/qcgpu-rust">GitHub</a>. Please report any places where the documentation is unclear, or where examples could be added or improved by creating an <a href="https://github.com/qcgpu/qcgpu-rust/issues">issue</a>.</p>
  126. <a class="header" href="print.html#help-wanted" id="help-wanted"><h2>Help Wanted</h2></a>
  127. <p>Please request any functionality you would like, need or appreciate by creating an <a href="https://github.com/qcgpu/qcgpu-rust/issues">issue</a>. If you would like to add functionality or fix issues, please create a <a href="https://github.com/qcgpu/qcgpu-rust/pulls">pull request</a> and I will get back to you (usually within the day).</p>
  128. <p>Any other feedback, suggestions or even tiny bits of criticism are welcome. When in doubt, file an <a href="https://github.com/qcgpu/qcgpu-rust/issues">issue</a>!</p>
  129. <a class="header" href="print.html#api-docs" id="api-docs"><h2>API Docs</h2></a>
  130. <p>Alongside this guide, you may also want the <a href="https://qcgpu.github.com/qcgpu/documentation">documentation</a>.</p>
  131. <a class="header" href="print.html#license" id="license"><h2>License</h2></a>
  132. <p>QCGPU is licensed under the <a href="https://github.com/qcgpu/qcgpu-rust/blob/master/LICENSE">MIT</a> License.</p>
  133. <a class="header" href="print.html#getting-started" id="getting-started"><h1>Getting Started</h1></a>
  134. <a class="header" href="print.html#installing-the-requirements" id="installing-the-requirements"><h2>Installing The Requirements</h2></a>
  135. <p>To use QCGPU, you will need Rust and OpenCL installed.</p>
  136. <p>The setup process for OpenCL will be different for every device. All apple devices (MacOS / OSX) will have OpenCL already installed.
  137. For some hints on how to install on linux, look at the <a href="https://github.com/QCGPU/qcgpu-rust/blob/master/EC2-install.md">AWS EC2 Install Instructions</a>.
  138. There is also a good chance that it is installed already. Check that <code>clinfo</code> for some other diagnostic command will run.</p>
  139. <p>Rust is very easy to install. Check out <a href="https://www.rustup.rs">rustup</a>.</p>
  140. <a class="header" href="print.html#adding-the-dependency" id="adding-the-dependency"><h2>Adding The Dependency</h2></a>
  141. <p>To use the library with rust, you must add the following to your <code>cargo.toml</code> file:</p>
  142. <pre><code class="language-toml">[dependencies]
  143. qcgpu = &quot;0.1&quot;
  144. </code></pre>
  145. <p>You should now be able to use the library by adding</p>
  146. <pre><code>extern crate qcgpu;
  147. </code></pre>
  148. <p>to <code>lib.rs</code> or <code>main.rs</code>, depending on if you are writing an executable or a library.</p>
  149. <a class="header" href="print.html#user-guide" id="user-guide"><h1>User Guide</h1></a>
  150. <p>This chapter covers the usage of the QCGPU library. It will also contain some information about the mathematics that each of the functions represents.</p>
  151. <p>All aspects of the library are covered by this chapter, whereas complete examples (in the form of algorithm implementations) are available in the <a href="../algorithms/algorithms.html">Algorithms Chapter</a></p>
  152. <a class="header" href="print.html#quantum-registers" id="quantum-registers"><h1>Quantum Registers</h1></a>
  153. <p>All of the simulation is done through quantum registers. QCGPU provides a struct as a register, but that contains fields to do with the OpenCL buffers and related items, so the creation of registers should be done through the provided methods.</p>
  154. <p>The library is optimized for complex superpositions, so the registers are all dense. This means that the number of qubits you can initialize is directly related to the capacity / available memory of the device.</p>
  155. <p>The register struct is called <code>State</code> and is available through <code>qcgpu::State</code>.</p>
  156. <p>To create a register, the easiest way to do it is with the <code>State::new</code> method.
  157. It takes two parameters, the number of qubits and the device to use. The device is given as a usize, and corresponds to the OpenCL device which the register will be on.</p>
  158. <p>The following example creates a register with 5 qubits on the 1st device.</p>
  159. <pre><pre class="playpen"><code class="language-rust"># extern crate qcgpu;
  160. use qcgpu::State;
  161. # fn main() {
  162. let mut register = State::new(5, 0);
  163. # }
  164. </code></pre></pre>
  165. <p>Notice that the register is mutable. This allows the register to change. Also, the device is 0 indexed.</p>
  166. <p>The implementation is equivilent to the description of a state vector \( \lvert \psi \rangle \) with</p>
  167. <p>\[ \lvert \psi \rangle = \sum_{j = 0}^{2^n - 1} \alpha_j \lvert j \rangle \]</p>
  168. <p>where \(n\) is the number of qubits, \(\alpha_j\) is the amplitude and the state is \(j\) runs over all \(2^n\) basis states.</p>
  169. <p>There is one other way to initialize a state. Given a bitstring, a register can be initialized in that state using the <code>State::from_bit_string</code> method. For example, to initialize a register with the value <code>0100</code> the following is used:</p>
  170. <pre><pre class="playpen"><code class="language-rust"># extern crate qcgpu;
  171. use qcgpu::State;
  172. # fn main() {
  173. let mut register = State::from_bit_string(&quot;|0100&gt;&quot;, 0);
  174. # }
  175. </code></pre></pre>
  176. <p>The second argument is the same as before. The register that is outputed from this method is equivilent to the state</p>
  177. <p>\[ \lvert 0100 \rangle\]</p>
  178. <a class="header" href="print.html#quantum-gates" id="quantum-gates"><h1>Quantum Gates</h1></a>
  179. <p>Gates are used to manipulate quantum registers and to implement quantum algorithms.</p>
  180. <a class="header" href="print.html#built-in-gates" id="built-in-gates"><h2>Built In Gates</h2></a>
  181. <p>There are a number of gates built in to QCGPU. They can all be applied the same way:</p>
  182. <pre><pre class="playpen"><code class="language-rust">
  183. # #![allow(unused_variables)]
  184. #fn main() {
  185. use qcgpu::State;
  186. let mut state = State::new(5, 0);
  187. state.h(0); // Applies the hadamard (`h`) gate to the 0th qubit
  188. #}</code></pre></pre>
  189. <p><code>h</code> can be replaced with any of the following:</p>
  190. <ul>
  191. <li>The hadmard gate: <strong>h</strong> - <code>state.h(0);</code></li>
  192. <li>The S gate: <strong>s</strong> - <code>state.s(0);</code></li>
  193. <li>The T gate: <strong>t</strong> - <code>state.t(0);</code></li>
  194. <li>The Pauli-X / NOT gate: <strong>x</strong> - <code>state.x(0);</code></li>
  195. <li>The Pauli-Y gate: <strong>y</strong> - <code>state.y(0);</code></li>
  196. <li>The Pauli-Z gate: <strong>z</strong> - <code>state.z(0);</code></li>
  197. <li>The CNOT gate: <strong>cx</strong> - <code>state.cx(0, 1); // CNOT with control = 0, target = 1</code></li>
  198. <li>The SWAP gate: <strong>swap</strong> - <code>state.swap(0,1); // Swaps the 0th and 1st qubit</code></li>
  199. <li>The Toffoli gate: <strong>toffoli</strong> - <code>state.toffoli(0, 1, 2); // Toffoli with control1 = 0, control1 = 1, target = 2</code></li>
  200. </ul>
  201. <p>These are all shorthand methods for the application of arbitrary gates. For example, the application of a hadamard gate above is shorthand for</p>
  202. <pre><pre class="playpen"><code class="language-rust">
  203. # #![allow(unused_variables)]
  204. #fn main() {
  205. use qcgpu::gates::{h};
  206. use qcgpu::State;
  207. let mut state = State::new(5, 0);
  208. state.apply_gate(h(), 0);
  209. #}</code></pre></pre>
  210. <p>You can also use any of the gates as controlled gates. For example, the application of the CNOT gate above is shorthand for</p>
  211. <pre><pre class="playpen"><code class="language-rust">
  212. # #![allow(unused_variables)]
  213. #fn main() {
  214. use qcgpu::gates::{x};
  215. use qcgpu::State;
  216. let mut state = State::new(5, 0);
  217. state.apply_controlled_gate(x(), 0, 1);
  218. #}</code></pre></pre>
  219. <a class="header" href="print.html#user-defined-gates" id="user-defined-gates"><h2>User Defined Gates</h2></a>
  220. <p>Gates in QCGPU are represented by the <code>Gate</code> struct, available through <code>qcgpu::Gate</code>.</p>
  221. <p>It is defined as follows:</p>
  222. <pre><pre class="playpen"><code class="language-rust">
  223. # #![allow(unused_variables)]
  224. #fn main() {
  225. extern crate num_complex;
  226. use num_complex::Complex32;
  227. struct Gate {
  228. a: Complex32,
  229. b: Complex32,
  230. c: Complex32,
  231. d: Complex32,
  232. }
  233. #}</code></pre></pre>
  234. <p>To create your own gate, you will need to add the <code>num_complex</code> crate to your dependencies.</p>
  235. <p>A gate is created as follows:</p>
  236. <pre><pre class="playpen"><code class="language-rust">
  237. # #![allow(unused_variables)]
  238. #fn main() {
  239. let x = Gate {
  240. Gate {
  241. a: Complex32::new(0.0, 0.0),
  242. b: Complex32::new(1.0, 0.0),
  243. c: Complex32::new(1.0, 0.0),
  244. d: Complex32::new(0.0, 0.0),
  245. }
  246. }
  247. #}</code></pre></pre>
  248. <p>This corresponds to the matrix</p>
  249. <p>\[x = \begin{bmatrix} 0 &amp; 1 \\ 1 &amp; 0 \end{bmatrix}\]</p>
  250. <p>This can be applied using the same long hand method as above:</p>
  251. <pre><pre class="playpen"><code class="language-rust">
  252. # #![allow(unused_variables)]
  253. #fn main() {
  254. let mut state = State::new(1, 0);
  255. state.apply_gate(x, 0);
  256. #}</code></pre></pre>
  257. <a class="header" href="print.html#quantum-operations" id="quantum-operations"><h1>Quantum Operations</h1></a>
  258. <p>There are a number of operations you can preform on quantum registers with QCGPU.</p>
  259. <a class="header" href="print.html#measurement" id="measurement"><h2>Measurement</h2></a>
  260. <p>You can measure the register in two ways. You can either do a single measurement and return an integer with the measured value or you can measure multiple times and return a <code>HashMap&lt;String, i32&gt;</code>, with the key being the bitstring, and the value being the number of times it was measured.</p>
  261. <p>The measurements don't collapse the state.</p>
  262. <p>They are used as follows:</p>
  263. <pre><pre class="playpen"><code class="language-rust">
  264. # #![allow(unused_variables)]
  265. #fn main() {
  266. use qcgpu::State;
  267. let mut state = State::new(5, 0);
  268. state.measure(); // Returns an integer
  269. state.measure_many(1000); // Measures 1000 times, returns a HashMap&lt;String, i32&gt;
  270. #}</code></pre></pre>
  271. <p>There is also a convenience method to measure the first \(n\) qubits in the register. Again, the state is not collapsed</p>
  272. <pre><pre class="playpen"><code class="language-rust">
  273. # #![allow(unused_variables)]
  274. #fn main() {
  275. use qcgpu::State;
  276. let mut state = State::new(5, 0);
  277. state.measure_first(3, 1000); // Measures the first 3 qubits 1000 times, returns a HashMap&lt;String, i32&gt;
  278. #}</code></pre></pre>
  279. <a class="header" href="print.html#probability" id="probability"><h2>Probability</h2></a>
  280. <p>QCGPU provides another method for getting the probability of each outcome.</p>
  281. <p>The probability is calculated for a state \(\lvert \psi \rangle = \sum_{j = 0}^{2^n - 1} \alpha_j \lvert j \rangle\),</p>
  282. <p>\[P(j) = |\alpha_j|^2\]</p>
  283. <p>The method <code>get_probabilities</code> returns a <code>Vec&lt;f32&gt;</code> with each of the values corresponding to \(|\alpha_j|^2\) for each index \(j\).</p>
  284. <pre><pre class="playpen"><code class="language-rust">
  285. # #![allow(unused_variables)]
  286. #fn main() {
  287. use qcgpu::State;
  288. let mut state = State::new(1, 0);
  289. state.h(0);
  290. state.get_probabilities(); // [0.5, 0.5]
  291. #}</code></pre></pre>
  292. <a class="header" href="print.html#examples" id="examples"><h1>Examples</h1></a>
  293. <p>Here is a complete example of using QCGPU to simulate the bell state.</p>
  294. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  295. use qcgpu::State;
  296. fn main() {
  297. // Create a new quantum register with 2 qubits on OpenCL device #0
  298. let mut register = State::new(2, 0);
  299. // Apply a hadamard gate to the first qubit
  300. register.h(0);
  301. // Apply a CNOT, with the control = 0, and target = 1
  302. register.cx(0, 1);
  303. // Measure the register 1000 times and print the output
  304. println!(&quot;Measured: {:?}&quot;, register.measure_many(1000));
  305. }
  306. </code></pre></pre>
  307. <p>The output should be something like</p>
  308. <pre><code class="language-shell">Measured: {&quot;00&quot;: 516, &quot;11&quot;: 484}
  309. </code></pre>
  310. <p>For more, non trivial examples, see the <a href="../algorithms/algorithms.html">Algorithms</a></p>
  311. <a class="header" href="print.html#decoherence" id="decoherence"><h1>Decoherence</h1></a>
  312. <p>QCGPU provides a way to easily simulate the effects of decoherence on the quantum computer. The effects are simulated by a random gate, corresponding to a random rotation around the \(z\) axis of the bloch sphere.</p>
  313. <p>The angle of the rotation is a normal distrobuted value, with the varience as the strength factor <code>d</code>.</p>
  314. <p>To avoid performance costs when not being used, decoherence can be enabled via a feature.</p>
  315. <p>Change the dependency in <code>cargo.toml</code> to</p>
  316. <pre><code class="language-toml">[dependencies]
  317. qcgpu = { version = &quot;0.1&quot;, features = [&quot;decoherence&quot;] }
  318. </code></pre>
  319. <p>Now you can add decoherence to your simulator.</p>
  320. <p>To set the amount of decoherence, the <code>set_decoherence</code> method is used. Its arguments are the strength of the decoherence.
  321. This will affect all following gate applications.</p>
  322. <pre><pre class="playpen"><code class="language-rust">
  323. # #![allow(unused_variables)]
  324. #fn main() {
  325. use qcgpu::State;
  326. let mut register = State::new(5, 0);
  327. register.set_decoherence(0.4);
  328. #}</code></pre></pre>
  329. <p>You can also manually decohere the register based on the previously set strength value. This method is automatically called by all gate applications.</p>
  330. <pre><pre class="playpen"><code class="language-rust">
  331. # #![allow(unused_variables)]
  332. #fn main() {
  333. register.decohere();
  334. #}</code></pre></pre>
  335. <a class="header" href="print.html#algorithms" id="algorithms"><h1>Algorithms</h1></a>
  336. <p>The following chapter details some implementations of non trivial quantum algorithms. They are based on the source code from <a href="http://www.libquantum.de/">libquantum</a> along with the lecture notes from <a href="https://cs.uwaterloo.ca/%7Ewatrous/LectureNotes.html">the University of Waterloo</a>.</p>
  337. <p>Note that some implementations may not yet be complete.</p>
  338. <a class="header" href="print.html#bernstein-vazirani-algorithm" id="bernstein-vazirani-algorithm"><h1>Bernstein-Vazirani Algorithm</h1></a>
  339. <p>This algorithm finds a hidden integer \(a \in { 0, 1}^n\)from
  340. an oracle \(f_a\)which returns a bit \(a \cdot x \equiv \sum_i a_i x_i \mod 2\)
  341. for an input \(x \in {0,1}^n\).</p>
  342. <p>A classical oracle returns \(f_a(x) = a \dot x \mod 2\), while the quantum oracle
  343. must be queried with superpositions of input \(x\)'s.</p>
  344. <p>To solve this problem classically, the hidden integer can be found by checking the
  345. oracle with the inputs \(x = 1,2,\dots,2^i,2^{n-1}\), where each
  346. query reveals the \(i\)th bit of \(a\) (\(a_i\)).
  347. This is the optimal classical solution, and is O(n). Using a quantum oracle and the
  348. Bernstein-Vazirani algorithm, \(a\) can be found with just one query to the oracle.</p>
  349. <a class="header" href="print.html#the-algorithm" id="the-algorithm"><h2>The Algorithm</h2></a>
  350. <ol>
  351. <li>Initialize \(n\) qubits in the state \(\lvert 0, \dots, 0\rangle\).</li>
  352. <li>Apply the Hadamard gate \(H\) to each qubit.</li>
  353. <li>Apply the inner product oracle.</li>
  354. <li>Apply the Hadamard gate \(H\) to each qubit.</li>
  355. <li>Measure the register</li>
  356. </ol>
  357. <p>From this procedure, we find that the registers measured value is equal to that of
  358. the original hidden integer.</p>
  359. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  360. use qcgpu::State;
  361. use qcgpu::gates::h;
  362. fn main() {
  363. let num_qubits = 16; // Number of qubits to use
  364. let a = 101; // Hidden integer, bitstring is 1100101
  365. // You should also make sure that a is representable with n qubits,
  366. // by settings a as a mod 2^n.
  367. // Bernstein-Vazirani algorithm
  368. let mut state = State::new(num_qubits, 1); // New quantum register, using the GPU.
  369. // Apply a hadamard gate to each qubit
  370. state.apply_all(h());
  371. // Apply the inner products oracle
  372. for i in 0..num_qubits {
  373. if a &amp; (1 &lt;&lt; i) != 0 {
  374. state.z(i as i32);
  375. }
  376. // Otherwise should apply identity gate, but computationally this doens't change the state.
  377. }
  378. // Apply hadamard gates before measuring
  379. state.apply_all(h());
  380. println!(&quot;Measurement Results: {:?}&quot;, state.measure_many(1000));
  381. // Measurement Results: {&quot;0000000001100101&quot;: 1000}
  382. }
  383. </code></pre></pre>
  384. <a class="header" href="print.html#deutsch-jozsa-algorithm" id="deutsch-jozsa-algorithm"><h1>Deutsch-Jozsa Algorithm</h1></a>
  385. <p>This algorithm was the first to show that quantum computers could have a speedup over classical computers.</p>
  386. <p>Consider a function \(f(x)\) which takes an input of an \(n\)-bit string \(x\) and returns 0 or 1.</p>
  387. <p>Suppose that \(f(x)\) is either a <strong>constant</strong> function that has the same value \(c \in {0, 1}, \forall x\), or a <strong>balanced</strong> function, where the value is 0 for half of the inputs, and 1 for the other half.</p>
  388. <p>The Deutsch-Jozsa problem is to find whether \(f\) is <em>constant</em> or <em>balanced</em>, in as few function evaluations as possible.</p>
  389. <p>Using classical computing, in the worst case, this requires \(2^{n-1}+1\) function evaluations.
  390. Using quantum computing, this can be done with just one function evaluation.</p>
  391. <p>The function \(f\), to be used in a quantum computer, must be specified by an oracle circuit \(U_{f}\) such that \(U_{f} \lvert x \rangle = (-1)^{f(x)}\lvert x \rangle\).</p>
  392. <a class="header" href="print.html#the-algorithm-1" id="the-algorithm-1"><h2>The Algorithm</h2></a>
  393. <ol>
  394. <li>Initialize \(n\) qubits in the state \(\lvert 0, \dots, 0\rangle\).</li>
  395. <li>Apply the Hadamard gate \(H\) to each qubit.</li>
  396. <li>Apply the oracle circuit \(U_f\).</li>
  397. <li>Apply the Hadamard gate \(H\) to each qubit.</li>
  398. <li>Measure each qubit. Let \(y = (y_{1}, \dots, y_{n})\) be the list of measurement outcomes.</li>
  399. </ol>
  400. <p>From this procedure, we find that \(f\) is constant if \(y\) is the all zero string.</p>
  401. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  402. use qcgpu::State;
  403. use qcgpu::gates::h;
  404. fn main() {
  405. // 3 qubits, f(x) = x_0 NOT x_1 x_2
  406. // Balanced
  407. let mut balanced_state = State::new(3, 1);
  408. balanced_state.apply_all(h());
  409. // Oracle U_f
  410. balanced_state.h(2);
  411. balanced_state.z(0);
  412. balanced_state.cx(1, 2);
  413. balanced_state.h(2);
  414. balanced_state.apply_all(h());
  415. println!(
  416. &quot;{}&quot;,
  417. if balanced_state.measure() == 0 {
  418. &quot;constant&quot;
  419. } else {
  420. &quot;balanced&quot;
  421. }
  422. );
  423. // 3 qubits, f(x) = 0
  424. // Constant
  425. let mut constant_state = State::new(3, 1);
  426. constant_state.apply_all(h());
  427. // Oracle is equivilant to the identity gate, thus has no effect on the
  428. // state.
  429. constant_state.apply_all(h());
  430. println!(
  431. &quot;{}&quot;,
  432. if constant_state.measure() == 0 {
  433. &quot;constant&quot;
  434. } else {
  435. &quot;balanced&quot;
  436. }
  437. );
  438. }
  439. </code></pre></pre>
  440. <a class="header" href="print.html#grovers-algorithm" id="grovers-algorithm"><h1>Grovers Algorithm</h1></a>
  441. <p>Given an unstructured set \(N = {a_1, a_2,\dots,a_n}\), find
  442. a given element \(a_i \in N\).</p>
  443. <p>This implementation looks for a given number \(target\) in the set \({0,1,\dots, \text{regwidth}}\).</p>
  444. <p>See <a href="https://cs.uwaterloo.ca/%7Ewatrous/LectureNotes.html">https://cs.uwaterloo.ca/~watrous/LectureNotes.html</a></p>
  445. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  446. extern crate rand;
  447. use qcgpu::State;
  448. use std::f32::consts::PI;
  449. fn main() {
  450. let mut state = State::new(8, 1);
  451. let target = 5;
  452. let reg_width = 3;
  453. let num_inversions = ((PI / 4.0) * ((1 &lt;&lt; reg_width) as f32).sqrt()) as i32;
  454. state.x(reg_width);
  455. for i in 0..(reg_width + 1) {
  456. state.h(i);
  457. }
  458. for _ in 0..(num_inversions) {
  459. iteration(&amp;mut state, target, reg_width);
  460. }
  461. state.h(reg_width);
  462. println!(&quot;Measured: {:?}&quot;, state.measure_first(reg_width, 1000));
  463. }
  464. fn oracle(state: &amp;mut State, target: i32, reg_width: i32) {
  465. for i in 0..reg_width {
  466. if get_bit(target, i) == 0 {
  467. state.x(i);
  468. }
  469. }
  470. state.toffoli(0, 1, reg_width + 1);
  471. let mut i = 1;
  472. while i &lt; reg_width {
  473. state.toffoli(i, reg_width + i, reg_width + i + 1);
  474. i += 1;
  475. }
  476. state.cx(reg_width + i, reg_width);
  477. i = reg_width - 1;
  478. while i &gt; 0 {
  479. state.toffoli(i, reg_width + i, reg_width + i + 1);
  480. i -= 1;
  481. }
  482. state.toffoli(0, 1, reg_width + 1);
  483. for i in 0..reg_width {
  484. if get_bit(target, i) == 0 {
  485. state.x(i);
  486. }
  487. }
  488. }
  489. fn inversion(state: &amp;mut State, reg_width: i32) {
  490. for i in 0..reg_width {
  491. state.x(i);
  492. }
  493. state.h(reg_width - 1);
  494. if reg_width == 3 {
  495. state.toffoli(0, 1, 2);
  496. } else {
  497. state.toffoli(0, 1, reg_width + 1);
  498. let mut i = 1;
  499. while i &lt; reg_width {
  500. state.toffoli(i, reg_width + i, reg_width + i + 1);
  501. i += 1;
  502. }
  503. state.cx(reg_width + i, reg_width - 1);
  504. i = reg_width - 2;
  505. while i &gt; 0 {
  506. state.toffoli(i, reg_width + i, reg_width + i + 1);
  507. i -= 1;
  508. }
  509. state.toffoli(0, 1, reg_width + 1);
  510. }
  511. state.h(reg_width - 1);
  512. for i in 0..reg_width {
  513. state.x(i);
  514. }
  515. }
  516. fn iteration(state: &amp;mut State, target: i32, reg_width: i32) {
  517. oracle(state, target, reg_width);
  518. for i in 0..reg_width {
  519. state.h(i);
  520. }
  521. inversion(state, reg_width);
  522. for i in 0..reg_width {
  523. state.h(i);
  524. }
  525. }
  526. /// Get the value of a bit
  527. fn get_bit(number: i32, n: i32) -&gt; i32 {
  528. if number &amp; (1 &lt;&lt; n) != 0 {
  529. return 1;
  530. }
  531. 0
  532. }
  533. </code></pre></pre>
  534. <a class="header" href="print.html#shors-algorithm" id="shors-algorithm"><h1>Shors Algorithm</h1></a>
  535. <p>This algorithm finds the prime factors (\)u\) and \(v\)) of an odd, composite integer \(n\),
  536. that is not a prime power.</p>
  537. <a class="header" href="print.html#the-algorithm-2" id="the-algorithm-2"><h2>The Algorithm</h2></a>
  538. <p>(pseudo code)</p>
  539. <pre><code class="language-pseudo">Repeat
  540. Randomly choose \\(a \in \{ 2, \dots, n - 1 \}\\)
  541. Compute \\(d = gcd(a, n)\\)
  542. If \\(d \geq 2\\) then
  543. Return \\(u = d\\) and \\(v = n/d\\)
  544. Else // We know \\(a \in \mathbb{Z}^*_N\\)
  545. Let \\(r\\) be the order of \\(a\\) in \\(\mathbb{Z}^*_N\\) // Order finding algorithm
  546. If \\(r\\) is even then
  547. Compute \\(x = a^{r/2} - 1 (\mod n)\\)
  548. Compute \\(d = \gcd(x, n)\\)
  549. If \\(d \geq 2\\) then
  550. Return \\(u = d\\) and \\(v = n/d\\)
  551. Until a value is returned.
  552. </code></pre>
  553. <p>See <a href="https://cs.uwaterloo.ca/%7Ewatrous/LectureNotes.html">https://cs.uwaterloo.ca/~watrous/LectureNotes.html</a></p>
  554. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  555. extern crate rand;
  556. use rand::{thread_rng, Rng};
  557. use qcgpu::{gcd, State};
  558. use qcgpu::gates::h;
  559. fn main() {
  560. let n = 15; // Number to factor
  561. println!(&quot;Factoring {}.&quot;, n);
  562. // Here we should check if the number is even, or if it is a power factor
  563. let mut rng = thread_rng();
  564. loop {
  565. let mut a = rng.gen_range(2, n); // Randomly choose \\(a \in \{ 2, \dots, n - 1 \}\\)
  566. let mut d = gcd(a, n);
  567. if d &gt;= 2 {
  568. // Found the factors; No Quantum needed
  569. println!(
  570. &quot;Factors are {} and {} (No quantum algorithm used)&quot;,
  571. d,
  572. n / d
  573. );
  574. break;
  575. } else {
  576. // We know \\(a \in \mathbb{Z}^*_N\\)
  577. let r = find_order(a, n);
  578. if r % 2 == 0 {
  579. let x = (a.pow((r as f32 / 2 as f32) as u32) - 1) % n;
  580. d = gcd(x, n);
  581. if d &gt;= 2 {
  582. println!(&quot;Factors are {} and {}&quot;, d, n / d);
  583. break;
  584. }
  585. } else {
  586. println!(&quot;Period is odd&quot;);
  587. }
  588. }
  589. }
  590. }
  591. </code></pre></pre>
  592. <a class="header" href="print.html#order-finding" id="order-finding"><h2>Order Finding</h2></a>
  593. <p>Given a positive integer \(n \geq 2\) and an element \(a \in \mathbb{Z}_n^* \),
  594. Find the order of \(a\) in \(\mathbb{Z}_n^*\).</p>
  595. <p>Order finding is the only quantum part in shors algorithm.</p>
  596. <p>\(\mathbb{Z}_n\) is the set of integers from \({0,\dots, n - 1}\) or \(\mathbb{z} \mod n\).
  597. The set \(\mathbb{Z}_n^* = {a \in \mathbb{Z}_n : \gcd(a,n) = 1}\)</p>
  598. <p>The set \( \mathbb{Z}_n^* \) forms a group wth the multiplication modulo \(n\) operation.
  599. Thus, for \( a \in \mathbb{Z}_n^* \) , \(\exists b \in \mathbb{Z}_n^*\) that uniquely satisfies</p>
  600. <p>\[
  601. ab \equiv 1 \mod n
  602. \]</p>
  603. <p>The order of a given element \(a \in \mathbb{Z}_n^*\) is the smallest positive integer \(r\) such that</p>
  604. <p>\[
  605. a^r \equiv 1 \mod n
  606. \]</p>
  607. <pre><pre class="playpen"><code class="language-rust">
  608. # #![allow(unused_variables)]
  609. #fn main() {
  610. fn find_order(a: i32, n: i32) -&gt; i32 {
  611. unimplemented!()
  612. }
  613. #}</code></pre></pre>
  614. <a class="header" href="print.html#super-dense-coding" id="super-dense-coding"><h1>Super Dense Coding</h1></a>
  615. <p>if Alice and Bob share a pair of entangled qubits, then Alice can encode two classical bits into her one entangled qubit,
  616. send it to Bob, and Bob can decode it with the help of his entangled qubit.</p>
  617. <pre><pre class="playpen"><code class="language-rust">extern crate qcgpu;
  618. use qcgpu::State;
  619. fn superdense(input: &amp;str) -&gt; i32 {
  620. let mut state = State::new(2, 0);
  621. let input_str = String::from(input);
  622. // Prepare the bell state
  623. state.h(0);
  624. state.cx(0, 1);
  625. // Alice prepares her qubit
  626. let alice = 1;
  627. if input_str.get(0..1) == Some(&quot;1&quot;) {
  628. state.z(alice);
  629. }
  630. if input_str.get(1..2) == Some(&quot;1&quot;) {
  631. state.x(alice);
  632. }
  633. println!(&quot;\nState after Alice prepares her qubit: \n{}&quot;, state);
  634. // Alice sends her qubit to Bob
  635. let bob = 0;
  636. state.cx(alice, bob);
  637. state.h(alice);
  638. println!(
  639. &quot;\nState after Bob receives Alice's qubit and 'decodes' it: \n{}&quot;,
  640. state
  641. );
  642. state.measure()
  643. }
  644. fn main() {
  645. use std::io;
  646. println!(&quot;Two bit string to send:&quot;);
  647. let mut input = String::new();
  648. match io::stdin().read_line(&amp;mut input) {
  649. Ok(_n) =&gt; {
  650. let result = superdense(input.as_str());
  651. println!(&quot;\nDecoded string is: {}&quot;, result);
  652. }
  653. Err(error) =&gt; println!(&quot;error: {}&quot;, error),
  654. }
  655. }
  656. </code></pre></pre>
  657. </main>
  658. <nav class="nav-wrapper" aria-label="Page navigation">
  659. <!-- Mobile navigation buttons -->
  660. <div style="clear: both"></div>
  661. </nav>
  662. </div>
  663. </div>
  664. <nav class="nav-wide-wrapper" aria-label="Page navigation">
  665. </nav>
  666. </div>
  667. <!-- Local fallback for Font Awesome -->
  668. <script>
  669. if (getComputedStyle(document.querySelector(".fa")).fontFamily !== "FontAwesome") {
  670. var link = document.createElement('link');
  671. link.rel = 'stylesheet';
  672. link.type = 'text/css';
  673. link.href = '_FontAwesome/css/font-awesome.css';
  674. document.head.insertBefore(link, document.head.firstChild)
  675. }
  676. </script>
  677. <script src="searchindex.js" type="text/javascript" charset="utf-8"></script>
  678. <script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
  679. <script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
  680. <script src="searcher.js" type="text/javascript" charset="utf-8"></script>
  681. <script>
  682. document.addEventListener('DOMContentLoaded', function() {
  683. window.print();
  684. })
  685. </script>
  686. <script src="highlight.js"></script>
  687. <script src="book.js"></script>
  688. <!-- Custom JS script -->
  689. </body>
  690. </html>