Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qml.transforms.to_zx translates float numbers to closest fractions #7003

Open
Qottmann opened this issue Feb 25, 2025 · 1 comment
Open

qml.transforms.to_zx translates float numbers to closest fractions #7003

Qottmann opened this issue Feb 25, 2025 · 1 comment
Labels
enhancement ✨ New feature or request

Comments

@Qottmann
Copy link
Contributor

Qottmann commented Feb 25, 2025

Feature details

PennyLane works with float numbers, pyzx works with proper fractions. We provide some functionality already to translate fixed angles in certain gates and decompositions to their proper fractions. So even though we provide some functionality for translating between pennylane as zx, interoperability is rather limited at this point.

To improve this, a first step would be to have automatic translation for general angles in RZ and RX gates.

def qfunc():
    qml.RZ(0.5, 0)

import pyzx as zx

g = qml.transforms.to_zx(qfunc)()
zx.draw(g)

Image

Instead of this angle, it would be nice to have the closest fraction of $0.5$

Implementation

One can use fraction.Fraction for translation

from fractions import Fraction
number = 0.5
fraction =  Fraction(number/np.pi).limit_denominator(64)
fraction
# Fraction(7, 44)

How important would you say this feature is?

2: Somewhat important. Needed this quarter.

Additional information

Having proper translation to pyzx enables us to use and compare to ZX-calculus based optimization and compilation techniques. It is currently a nice-to-have but I anticipate this to become more and more important so better to get ahead of this sooner rather than later

@Qottmann Qottmann added the enhancement ✨ New feature or request label Feb 25, 2025
@Qottmann
Copy link
Contributor Author

By the way, curiously, this is already handled by pyzx automatically when going the qasm route, so surely this should be relatively easy for PL to make use of?

import pennylane as qml
import numpy as np
from pyzx import Circuit
import pyzx as zx

qasm = qml.tape.QuantumScript([qml.RZ(np.pi/4, 0)], []).to_openqasm()
print(qasm)
# remove measure
qasm = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
creg c[1];
rz(0.7853981633974483) q[0];
"""

circ = Circuit.from_qasm(qasm)
g = circ.to_graph()
zx.draw(g)

Image

One nuisance is that the always-appended measure statement in the to_qasm output of pennylane is breaking it and needs to be manually removed. (perhaps this is worth a separate issue, but when the QScript is not specifying any measurements, why is a measure appended to the qasm program?)

For the time being, this can be removed with something like this

def remove_measurement_patterns(text):
    """
    Removes patterns of the form "measure q[n] -> c[m];" from the input text,
    where n and m are arbitrary integers.
    
    Args:
        text (str): Input text containing measurement patterns
        
    Returns:
        str: Text with measurement patterns removed
    """
    # Pattern explanation:
    # measure\s+      : matches "measure" followed by whitespace
    # q\[\d+\]       : matches q[n] where n is one or more digits
    # \s*->\s*       : matches -> with optional whitespace around it
    # c\[\d+\]       : matches c[m] where m is one or more digits
    # \s*;           : matches semicolon with optional whitespace before it
    pattern = r'measure\s+q\[\d+\]\s*->\s*c\[\d+\]\s*;'
    
    # Remove all occurrences of the pattern
    result = re.sub(pattern, '', text)
    
    return result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement ✨ New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant