{"id":15045547,"url":"https://github.com/antimonit/quantum","last_synced_at":"2025-04-10T00:43:03.824Z","repository":{"id":52822244,"uuid":"210850479","full_name":"Antimonit/Quantum","owner":"Antimonit","description":"Kotlin framework for writing quantum algorithms using QASM-like syntax","archived":false,"fork":false,"pushed_at":"2024-06-25T12:53:02.000Z","size":320,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T00:42:57.269Z","etag":null,"topics":["jvm","kotlin","quantum","quantum-algorithms","quantum-computing","simulation"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Antimonit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-25T13:20:25.000Z","updated_at":"2025-04-09T10:14:48.000Z","dependencies_parsed_at":"2024-06-25T14:13:34.300Z","dependency_job_id":"b5ef2cc5-eda5-4174-9eb7-996d2863e9e9","html_url":"https://github.com/Antimonit/Quantum","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antimonit%2FQuantum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antimonit%2FQuantum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antimonit%2FQuantum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antimonit%2FQuantum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Antimonit","download_url":"https://codeload.github.com/Antimonit/Quantum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137998,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jvm","kotlin","quantum","quantum-algorithms","quantum-computing","simulation"],"created_at":"2024-09-24T20:52:00.186Z","updated_at":"2025-04-10T00:43:03.808Z","avatar_url":"https://github.com/Antimonit.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quantum computing in Kotlin\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.antimonit/quantum.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/io.github.antimonit/quantum)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![CircleCI](https://circleci.com/gh/Antimonit/Quantum/tree/master.svg?style=shield)](https://circleci.com/gh/Antimonit/Quantum/tree/main)\n[![Code Coverage](https://codecov.io/gh/Antimonit/Quantum/branch/master/graph/badge.svg)](https://codecov.io/gh/Antimonit/Quantum)\n\nKotlin framework for writing quantum algorithms using QASM-like syntax.\n\nBecause the code is still compiled by Kotlin compiler we are not limited by QASM language features.\nWe can use classical variables, loops, functions, etc. There is no need for binary-controlled gates\nas we can utilize standard `if` condition.\n\n# Examples\n\n## Quantum Teleportation\n\n![Quantum Teleportation](images/Quantum%20Teleportation.svg)\n\n```kotlin\nval message = ZERO // or ONE or random()\n\nprogram(Register(message, ZERO, ZERO)) {\n    // Entangle qubits q1 and q2 to form a fully entangled bell state\n    Hadamard[2]\n    CNot[2, 1]\n\n    // Entangle message/state held by q0 with the rest.\n    CNot[0, 1]\n    Hadamard[0]\n\n    // Measuring the first two qubits will change the state of the third qubit because\n    // of the entanglement. This will teleport the message from the first qubit to the\n    // third qubit.\n    val (secret, shared) = measureAndCollapse(0, 1)\n\n    // The last qubit can be in one of four superpositions now. We can use qubits\n    // measured in the previous step to conditionally apply some gates to put it\n    // into one specific superposition.\n    if (shared == ONE) X[2]\n    if (secret == ONE) Z[2]\n}\n\n// At this point the third qubit will be in the same superposition as the message\n// defined at the beginning.\n```\n\n## Grover's Algorithm\n\n![Grover's Algorithm](images/Grover's%20Algorithm.svg)\n\n```kotlin\nval oracle: Gate = oracleGate(ONE, ONE, ZERO)\n\nprogram(3) {\n    // Initialization\n    step { H[0]; H[1]; H[2] }\n\n    repeat(2) {\n        // Oracle\n        oracle[0, 1, 2]\n\n        // Diffusion\n        step { H[0]; H[1]; H[2] }\n        step { X[0]; X[1]; X[2] }\n        step { C(C(Z))[0, 1, 2] }\n        step { X[0]; X[1]; X[2] }\n        step { H[0]; H[1]; H[2] }\n    }\n\n    // Measurement\n}.measure() // Returns [ONE, ONE, ZERO] with high probability\n```\n\n## Quantum Adder\n\n![Quantum Adder](images/Quantum%20Adder.svg)\n\n```kotlin\n// We can even utilize entanglement to calculate two separate additions at the same time.\n\nprogram(4) {\n    // Prepare input\n    H[0]\n    CNot[0, 1]\n\n    // Encode two combinations of input into an entangled pair.\n    // By passing ∣00⟩ + ∣11⟩ / sqrt(2) as input to the adder\n    // we are essentially calculating both 0 + 0 and 1 + 1.\n\n    // Full Adder\n    CCNot[0, 1, 3]\n    CNot[0, 1]\n    CCNot[1, 2, 3]\n    CNot[1, 2]\n    CNot[0, 1]\n}\n\n// At this point it is equally likely to observe result of 0 + 0 = 00 and 1 + 1 = 10.\n```\n\n# Building blocks\n\n## [Complex numbers](quantum/src/main/kotlin/me/khol/quantum/math/Complex.kt)\n\u003cdetails\u003e\n\u003csummary\u003eDetails\u003c/summary\u003e\n\nComplex numbers can be created either from cartesian coordinates:\n```kotlin\nComplex(re: Number = 0, im: Number = 0)\n```\nor from polar coordinates:\n```kotlin\nComplex.fromPolar(theta: Number, radius: Number = 1)\n```\nFor most commonly used Complex numbers there are three predefined values:\n```kotlin\nval ONE = Complex(1, 0)\nval ZERO = Complex(0, 0)\nval I = Complex(0, 1)\n```\nThere are several overloaded operators that allow for easier addition, subtraction, multiplication \nand division of complex numbers.\n\u003c/details\u003e  \n\n## [Matrices](quantum/src/main/kotlin/me/khol/quantum/math/Matrix.kt)\n\u003cdetails\u003e\n\u003csummary\u003eDetails\u003c/summary\u003e\n\nMatrices can be created from number of rows and cols and 1D array of complex numbers:\n```kotlin\nMatrix(rows: Int, cols: Int, vararg values: Complex)\n```\nor directly from 2D array of complex numbers:\n```kotlin\nMatrix(m: List\u003cList\u003cComplex\u003e\u003e)\n```\nIdentity matrix n×n can be created using:\n```kotlin\nMatrix.identity(size: Int)\n```\nThere are many overloaded operators that allow for easier *addition* and *subtraction* of two \nmatrices, *multiplication* and *division* by a number, complex number or another matrix, \n*conjugate transpose* and *tensor* product. \n\u003c/details\u003e  \n\n## [Qubits](quantum/src/main/kotlin/me/khol/quantum/Qubit.kt) \nQubits are defined by two complex numbers which define their probability amplitudes:\n```kotlin\nQubit(alpha: Complex, beta: Complex)\n```\nTwo commonly used qubit states are predefined:\n```kotlin\nval ZERO = Qubit(Complex.ONE, Complex.ZERO)\nval ONE = Qubit(Complex.ZERO, Complex.ONE)\n```\n\nQubits can be converted to *bra* ⟨\u0026phi;∣ or *ket* ∣\u0026phi;⟩ matrices and define *dot*, *cross* \nand *tensor* products.\n\n\u003e Because two qubits may have different alpha and beta values although they represent the same\nphysical state they can be *normalized* so that two qubits can be programmatically compared.\nThis cannot be observed in the physical world but is invaluable in testing.\n\n## [Registers](quantum/src/main/kotlin/me/khol/quantum/Register.kt)\nRegisters are created from a list of qubits:\n```kotlin\nRegister(vararg qubits: Qubit)\n```\n\nIn contrast to a simple `List\u003cQubit\u003e` that can only hold independent qubits, a `Register` can\nalso hold *entangled* qubits, such as *Bell states*. This is crucial for creation of more \ncomplex algorithms that depend on entanglement.\n\n\u003e Just like single qubits, registers can be *normalized* for testing purposes.\n\n## [Gates](quantum/src/main/kotlin/me/khol/quantum/gate/Gate.kt)\nMost of the commonly used gates are already predefined:\n\n| [Identity][_Identity]                            | [X (Not)][_X]                                    | [Y][_Y]                                           | [Z][_Z]                                           | [S][_S]                                          | [T][_T]                                                   |\n|--------------------------------------------------|--------------------------------------------------|---------------------------------------------------|---------------------------------------------------|--------------------------------------------------|-----------------------------------------------------------|\n| $`\\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 1 \\end{bmatrix}`$ | $`\\begin{bmatrix} 0 \u0026 1 \\\\ 1 \u0026 0 \\end{bmatrix}`$ | $`\\begin{bmatrix} 0 \u0026 -i \\\\ i \u0026 0 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 -1 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 i \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 e^{i\\pi/4} \\end{bmatrix}`$ |\n\n| [Hadamard][_Hadamard]                                                | [Rx][_Rx]                                                                                                                              | [Ry][_Ry]                                                                                                                         | [Rz][_Rz]                                                                                 | [Phase][_Phase]                                            |\n|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|------------------------------------------------------------|\n| $`\\frac{1}{\\sqrt{2}} \\begin{bmatrix} 1 \u0026 1 \\\\ 1 \u0026 -1 \\end{bmatrix}`$ | $`\\begin{bmatrix} cos(\\frac{\\theta}{2}) \u0026 -i sin(\\frac{\\theta}{2}) \\\\ -i sin(\\frac{\\theta}{2}) \u0026 cos(\\frac{\\theta}{2}) \\end{bmatrix}`$ | $`\\begin{bmatrix} cos(\\frac{\\theta}{2}) \u0026 -sin(\\frac{\\theta}{2}) \\\\ sin(\\frac{\\theta}{2}) \u0026 cos(\\frac{\\theta}{2}) \\end{bmatrix}`$ | $`\\begin{bmatrix} e^{-i\\frac{\\theta}{2}} \u0026 0 \\\\ 0 \u0026 e^{i\\frac{\\theta}{2}} \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 e^{i\\theta} \\end{bmatrix}`$ |\n\n| [CNot (CX)][_CNot]                                                                                 | [Swap][_Swap]                                                                                      | [Square Root of Swap][_SwapRoot]                                                                                                                               | [Controlled][_Controlled]                                                                                      |\n|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|\n| $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 1 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 1 \\\\ 0 \u0026 0 \u0026 1 \u0026 0 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 1 \u0026 0 \\\\ 0 \u0026 1 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 1 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 \\frac{1}{2}(1+i) \u0026 \\frac{1}{2}(1-i) \u0026 0 \\\\ 0 \u0026 \\frac{1}{2}(1-i) \u0026 \\frac{1}{2}(1+i) \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 1 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 1 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 u_00 \u0026 u_01 \\\\ 0 \u0026 0 \u0026 u_10 \u0026 u_11 \\end{bmatrix}`$ |\n\n| [Toffoli (CCNot)][_CCNot]                                                                                                                                                                                                                                                                              | [Fredkin (CSwap)][_CSwap]                                                                                                                                                                                                                                                                              |\n|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \\end{bmatrix}`$ | $`\\begin{bmatrix} 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \u0026 0 \u0026 0 \\\\ 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 0 \u0026 1 \\end{bmatrix}`$ |\n\n[//]: https://alexanderrodin.com/github-latex-markdown/\n\n[_Identity]: quantum/src/main/kotlin/me/khol/quantum/gate/GateIdentity.kt\n[_Hadamard]: quantum/src/main/kotlin/me/khol/quantum/gate/GateHadamard.kt\n[_X]: quantum/src/main/kotlin/me/khol/quantum/gate/GateX.kt\n[_Y]: quantum/src/main/kotlin/me/khol/quantum/gate/GateY.kt\n[_Z]: quantum/src/main/kotlin/me/khol/quantum/gate/GateZ.kt\n[_S]: quantum/src/main/kotlin/me/khol/quantum/gate/GateS.kt\n[_T]: quantum/src/main/kotlin/me/khol/quantum/gate/GateT.kt\n[_Rx]: quantum/src/main/kotlin/me/khol/quantum/gate/GateRx.kt\n[_Ry]: quantum/src/main/kotlin/me/khol/quantum/gate/GateRy.kt\n[_Rz]: quantum/src/main/kotlin/me/khol/quantum/gate/GateRz.kt\n[_Phase]: quantum/src/main/kotlin/me/khol/quantum/gate/GatePhase.kt\n[_Swap]: quantum/src/main/kotlin/me/khol/quantum/gate/GateSwap.kt\n[_SwapRoot]: quantum/src/main/kotlin/me/khol/quantum/gate/GateSwapRoot.kt\n[_CNot]: quantum/src/main/kotlin/me/khol/quantum/gate/GateCNot.kt\n[_CCNot]: quantum/src/main/kotlin/me/khol/quantum/gate/GateCCNot.kt\n[_CSwap]: quantum/src/main/kotlin/me/khol/quantum/gate/GateCSwap.kt\n[_Controlled]: quantum/src/main/kotlin/me/khol/quantum/gate/GateControlled.kt\n\nIt should be rather straightforward to create custom gates.\n\nGates can be applied to a register. The size of the gate must match the number of qubits stored by\nthe register.\n```kotlin\nGateSwap * Register(Qubit.ONE, Qubit.ZERO) // Register(Qubit.ZERO, Qubit.ONE)\n``` \nGates that act on a single qubit can be also applied to qubits.\n```kotlin\nGateX * Qubit.ONE // Qubit.ZERO\n```\n\n## [Programs](quantum/src/main/kotlin/me/khol/quantum/Program.kt)\nInstead of manually applying gates to registers and qubits like this:\n```kotlin\nval bellState = CNot * Register(Hadamard * ZERO, ZERO)\n```\nprogram classes provide a less cluttered and more natural way to combine multiple gates into one,\nreorder inputs of a gate, apply gates to registers with different sizes and apply multiple gates \nto a register.\n\n### Precomputed Program\nPre-computes transformations of multiple gates as a standalone gate. As we apply gates \nwithin the program, their transformation matrices are combined.\nIt allows us to pre-compute a part of a larger program that is executed repeatedly and \napply the result gate instead.\n    \n```kotlin\n// Swap gate made using CNot gates \nval swap: Gate = gate(2) {\n    CNot[0, 1]\n    CNot[1, 0]\n    CNot[0, 1]\n}\n```\n\n### Runnable Program\nApplies multiple gates to a register, changing the state of its qubits with each step.\n\n```kotlin\n// Fully entangled Bell state (∣00⟩ + ∣11⟩) / sqrt(2)  \nval bellState: Register = program(2) {\n    Hadamard[0]\n    CNot[0, 1]\n}\n```\n\nCompared to `gate` that does not have any state per se, `program` has a register\nthat we can measure at any point. \n\n```kotlin\nfun measureAndCollapse(vararg qubitIndices: Int): List\u003cQubit\u003e\n```\n\nDoing so will collapse the state of specified qubits to ∣0⟩ or ∣1⟩ based on their probabilities. \nOther qubits in the register entangled with any of the measured qubits will have their probabilities\nupdated as well to satisfy constraints imposed by entangled states before the measurement.\n\n# Download\n\nThe project is also available as a maven dependency from MavenCentral repository:\n\n```kotlin\nimplementation(\"io.github.antimonit:quantum:1.0.1\")\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantimonit%2Fquantum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantimonit%2Fquantum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantimonit%2Fquantum/lists"}