{"id":13751567,"url":"https://github.com/SimoneGasperini/qiskit-symb","last_synced_at":"2025-05-09T18:31:34.666Z","repository":{"id":165617687,"uuid":"640953438","full_name":"SimoneGasperini/qiskit-symb","owner":"SimoneGasperini","description":"Symbolic evaluation of parameterized quantum circuits in Qiskit","archived":false,"fork":false,"pushed_at":"2025-01-13T20:52:18.000Z","size":478,"stargazers_count":34,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-12T22:00:03.779Z","etag":null,"topics":["qiskit","quantum-computing","symbolic-computation","sympy"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/qiskit-symb/","language":"Python","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/SimoneGasperini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-15T13:21:48.000Z","updated_at":"2025-03-28T15:14:58.000Z","dependencies_parsed_at":"2023-11-07T10:26:29.220Z","dependency_job_id":"c2274469-ed3d-4b80-a684-e56ec2f70d9c","html_url":"https://github.com/SimoneGasperini/qiskit-symb","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneGasperini%2Fqiskit-symb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneGasperini%2Fqiskit-symb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneGasperini%2Fqiskit-symb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneGasperini%2Fqiskit-symb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SimoneGasperini","download_url":"https://codeload.github.com/SimoneGasperini/qiskit-symb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253303024,"owners_count":21886873,"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":["qiskit","quantum-computing","symbolic-computation","sympy"],"created_at":"2024-08-03T09:00:48.778Z","updated_at":"2025-05-09T18:31:34.638Z","avatar_url":"https://github.com/SimoneGasperini.png","language":"Python","funding_links":[],"categories":["Community"],"sub_categories":[],"readme":"![](/img/logo.png)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg title=\"license\" src=\"https://img.shields.io/badge/license-Apache_2.0-blue.svg\"\u003e\n    \u003cimg title=\"python\" src=\"https://img.shields.io/badge/python-≥3.9-blue.svg\"\u003e\n    \u003ca href=\"https://qiskit.org/ecosystem/\" alt=\"Ecosystem\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Qiskit-Ecosystem-blueviolet.svg\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg title=\"build\" src='https://github.com/SimoneGasperini/qiskit-symb/actions/workflows/python-package.yml/badge.svg?branch=master'\u003e\n    \u003cimg title=\"coverage\" src='https://coveralls.io/repos/github/SimoneGasperini/qiskit-symb/badge.svg?branch=master'\u003e\n\u003c/p\u003e\n\n# Table of contents\n- [Introduction](#introduction)\n- [Installation](#installation)\n    - [User-mode](#user-mode)\n    - [Dev-mode](#dev-mode)\n- [Usage examples](#usage-examples)\n    - [_Sympify_ a Qiskit circuit](#sympify-a-qiskit-circuit)\n    - [_Lambdify_ a Qiskit circuit](#lambdify-a-qiskit-circuit)\n- [Qiskit Medium](#qiskit-medium)\n- [Contributors](#contributors)\n\n\n# Introduction\nThe `qiskit-symb` package is meant to be a Python tool to enable the symbolic evaluation of parametric quantum states defined by [Qiskit](https://github.com/Qiskit/qiskit) by parameterized quantum circuits.\n\nA Parameterized Quantum Circuit (PQC) is a quantum circuit where we have at least one free parameter (e.g. a rotation angle $\\theta$). PQCs are particularly relevant in Quantum Machine Learning (QML) models, where the values of these parameters can be learned during training to reach the desired output.\n\nIn particular, `qiskit-symb` can be used to create a symbolic representation of a parametric quantum state directly from the Qiskit quantum circuit. This has been achieved through the re-implementation of some basic classes defined in the [`qiskit/quantum_info/`](https://github.com/Qiskit/qiskit/tree/main/qiskit/quantum_info) module by using [sympy](https://github.com/sympy/sympy) as a backend for symbolic expressions manipulation.\n\n\n# Installation\n\n## User-mode\n```\npip install qiskit-symb\n```\n\n:warning: The package requires `qiskit\u003e=1`. See the official [Migration guides](https://docs.quantum.ibm.com/api/migration-guides) if you are used to a prevoius Qiskit version.\n\n## Dev-mode\n```\ngit clone https://github.com/SimoneGasperini/qiskit-symb.git\ncd qiskit-symb\npip install -e .\n```\n\n\n# Usage examples\n\n### _Sympify_ a Qiskit circuit\nLet's get started on how to use `qiskit-symb` to get the symbolic representation of a given Qiskit circuit. In particular, in this first basic example, we consider the following quantum circuit:\n```python\nfrom qiskit import QuantumCircuit\nfrom qiskit.circuit import Parameter, ParameterVector\n\ny = Parameter('y')\np = ParameterVector('p', length=2)\n\npqc = QuantumCircuit(2)\npqc.ry(y, 0)\npqc.cx(0, 1)\npqc.u(p[0], 0, p[1], 1)\n\npqc.draw('mpl')\n```\n![](/img/example_circuit.png)\n\nTo get the *sympy* representation of the unit-norm complex vector prepared by the parameterized circuit, we just have to create the symbolic `Statevector` instance and call the `to_sympy()` method:\n```python\nfrom qiskit_symb.quantum_info import Statevector\n\npsi = Statevector(pqc)\npsi.to_sympy()\n```\n```math\n\\left[\\begin{matrix}\\cos{\\left(\\frac{p[0]}{2} \\right)} \\cos{\\left(\\frac{y}{2} \\right)} \u0026 - e^{1.0 i p[1]} \\sin{\\left(\\frac{p[0]}{2} \\right)} \\sin{\\left(\\frac{y}{2} \\right)} \u0026 \\sin{\\left(\\frac{p[0]}{2} \\right)} \\cos{\\left(\\frac{y}{2} \\right)} \u0026 e^{1.0 i p[1]} \\sin{\\left(\\frac{y}{2} \\right)} \\cos{\\left(\\frac{p[0]}{2} \\right)}\\end{matrix}\\right]\n```\n\nIf you want then to assign a value to some specific parameter, you can use the `subs(\u003cdict\u003e)` method passing a dictionary that maps each parameter to the desired corresponding value:\n```python\nnew_psi = psi.subs({p: [-1, 2]})\nnew_psi.to_sympy()\n```\n```math\n\\left[\\begin{matrix}\\cos{\\left(\\frac{1}{2} \\right)} \\cos{\\left(\\frac{y}{2} \\right)} \u0026 e^{2.0 i} \\sin{\\left(\\frac{1}{2} \\right)} \\sin{\\left(\\frac{y}{2} \\right)} \u0026 - \\sin{\\left(\\frac{1}{2} \\right)} \\cos{\\left(\\frac{y}{2} \\right)} \u0026 e^{2.0 i} \\sin{\\left(\\frac{y}{2} \\right)} \\cos{\\left(\\frac{1}{2} \\right)}\\end{matrix}\\right]\n```\n\n### _Lambdify_ a Qiskit circuit\nGiven a Qiskit circuit, `qiskit-symb` also allows to generate a Python lambda function with actual arguments matching the Qiskit unbound parameters.\nLet's consider the following example starting from a `ZZFeatureMap` circuit, commonly used as a data embedding ansatz in QML applications:\n```python\nfrom qiskit.circuit.library import ZZFeatureMap\n\npqc = ZZFeatureMap(feature_dimension=3, reps=1)\npqc.draw('mpl')\n```\n![](/img/zzfeaturemap_circuit.png)\n\nTo get the Python function representing the final parameteric statevector, we just have to create the symbolic `Statevector` instance and call the `to_lambda()` method:\n```python\nfrom qiskit_symb.quantum_info import Statevector\n\npqc = pqc.decompose()\nstatevec = Statevector(pqc).to_lambda()\n```\n\nWe can now call the lambda-generated function `statevec` passing the `x` values we want to assign to each parameter. The returned object will be a *numpy* 2D-array (with `shape=(8,1)` in this case) representing the final output statevector `psi`.\n```python\nx = [1.24, 2.27, 0.29]\npsi = statevec(*x)\n```\n\nThis feature can be useful when, given a Qiskit PQC, we want to run it multiple times with different parameters values. Indeed, we can perform a single symbolic evalutation and then call the lambda generated function as many times as needed, passing different values of the parameters at each iteration.\n\n\n# Qiskit Medium\nRead my [blog post](https://medium.com/p/b6b4407fa705) introducing to `qiskit-symb` published on the official Qiskit Medium blog.\n\n![](/img/medium.png)\n\n\n# Contributors\n\n\u003ctable\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/SimoneGasperini\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/71086758?s=400\u0026v=4\" width=\"120px;\"/\u003e\u003cbr/\u003e\u003cb\u003eSimone Gasperini\u003c/b\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/sbrandhsn\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/148463728?v=4\" width=\"60px;\"/\u003e\u003cbr/\u003eSebastian\u003cbr/\u003eBrandhofer\u003c/a\u003e\u003c/td\u003e\n\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimoneGasperini%2Fqiskit-symb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSimoneGasperini%2Fqiskit-symb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimoneGasperini%2Fqiskit-symb/lists"}