Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An extended RZZ pass for unbounded parameters#2072

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
yaelbh wants to merge25 commits intoQiskit:main
base:main
Choose a base branch
Loading
fromyaelbh:liran

Conversation

@yaelbh
Copy link
Collaborator

Closes#2032.
The transpiler pass of#2043 is extended to accommodate unbounded parameters, including parameter expressions.
Many thanks to Liran Shirizly for the idea.
The tests are currently failing - I'm investigating - opening in draft mode.

@yaelbhyaelbh marked this pull request as draftDecember 4, 2024 15:15
@yaelbhyaelbh marked this pull request as ready for reviewDecember 5, 2024 18:15
@yaelbh
Copy link
CollaboratorAuthor

All the bugs have been fixed, it's not in draft mode anymore but ready for review.

@yaelbhyaelbh requested a review fromwshanksDecember 5, 2024 18:23
@yaelbh
Copy link
CollaboratorAuthor

Is there a risk that the pass will run again and again, forever?
Converting back to draft until this question is clarified.

@yaelbhyaelbh marked this pull request as draftDecember 6, 2024 05:11
Copy link
Collaborator

@wshankswshanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is very clever, Yael and Liran.

I think the concern about running forever is coming from the use of themodified variable in a loop? That variable is just used to determine whether to reuse the original data or new data and not to restart the loop, so I think it is okay.

I have a couple concerns about this PR, but they may not be issues:

  1. Should we be concerned about the blowing up in size of the input circuit?

    The simple circuit with a single rzz with anglep goes from having a data attribute like:

    [CircuitInstruction(operation=Instruction(name='rzz', num_qubits=2, num_clbits=0, params=[Parameter(p)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0), Qubit(QuantumRegister(2, 'q'), 1)), clbits=())]

    To one like:

    Details

    [CircuitInstruction(operation=Instruction(name='global_phase', num_qubits=0, num_clbits=0, params=[ParameterExpression(1.5707963267949*(1 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5)))*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2 + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2 + 1.5707963267949*(sign(-p + 12.5663706143592*floor(0.0795774715459477*p) + 9.42477796076938) + 1)*((sign(p - 12.5663706143592*floor(0.0795774715459477*p) - 3.14159265358979) + 1)*sign(p - 12.5663706143592*floor(0.0795774715459477*p) - 3.14159265358979)**2/2 - sign(p - 12.5663706143592*floor(0.0795774715459477*p) - 3.14159265358979)**2 + 1)*sign(-p + 12.5663706143592*floor(0.0795774715459477*p) + 9.42477796076938)**2 - 0.785398163397448*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 - 0.785398163397448*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2)]), qubits=(), clbits=()), CircuitInstruction(operation=Instruction(name='rz', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=()), CircuitInstruction(operation=Instruction(name='rx', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*(1 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5)))*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2 + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2 + 1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=()), CircuitInstruction(operation=Instruction(name='rz', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2)]), qubits=(Qubit(QuantumRegister(2, 'q'), 1),), clbits=()), CircuitInstruction(operation=Instruction(name='rzz', num_qubits=2, num_clbits=0, params=[ParameterExpression(-(1 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5)))*(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2 + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2/2 + (p - 6.28318530717959*floor(0.159154943091895*p + 0.5))*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5)) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2/2 + (sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 + (sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2/2)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0), Qubit(QuantumRegister(2, 'q'), 1)), clbits=()), CircuitInstruction(operation=Instruction(name='rx', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*(1 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5)))*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) + 1.5707963267949)**2 + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5))**2 + 1.5707963267949*(sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979) + 1)*((sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949) + 1)*sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2/2 - sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.5) - 1.5707963267949)**2 + 1)*sign(-p + 6.28318530717959*floor(0.159154943091895*p + 0.5) + 3.14159265358979)**2)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=())]

    Perhaps in the weighing of pros and cons, this large expression is better than not being able to use parametrized circuits with rzz or needing to wrap parameter values in some external method.

  2. Do we need to be careful about adding a link between the rzz gate and the rx gate? In practice, they were added at the same time and so rx is always present when rzz is. The first version of the pass just added an assumption of there being anXGate though, notRXGate. Perhaps it is fine the way it is. Or should there be a check that the backend supportsRXGate as well to be safe?

  3. I wonder if the parameterized and numerical code paths should be more aligned? Perhaps not, things are readable the way they are. The parameterized path uses a single function adding on parts as it goes while the numerical one has four separate functions. The parameterized version doesn't have the option of splitting up like the numerical one does.

One minor thing -- this is not related to this PR, but while looking at it I noticed the circuit drawings in the quad method docstrings are not aligned properly. Perhaps that could be incidentally fixed here as well.

@yaelbh
Copy link
CollaboratorAuthor

For (2), I expect other translation passes to translaterx (orX in the numeric case) to basis gates, if they are not already basis gates. This is related to my infinite loop concern. I still have to learn how the pass manager works, but I imagine that the passes run and rerun until a fixed point. If this is the case, suppose thatrx is not a basis gate. A pass modifies the DAG circuit to use basis gates instead, and, since the DAG circuit has been modified, ourrzz pass runs again. Which generates newrx gates, and so on. Note that this issue does not apply to the numeric case, where only the first execution of therzz pass modifies the DAG circuit.

For (1), I'm more concerned than you, to the point that I estimate that this will PR eventually will not be able to merge, because of the circuit size. This is certainly something that must be checked.

wshanks reacted with thumbs up emoji

@yaelbh
Copy link
CollaboratorAuthor

So the pass managers are just lists of passes that get to run sequentially, not involving loops and fixed points. I suggest at minimum to check ifrx a basis gate, and skip the pass otherwise. We can also, in this case, create an alternative circuit withoutrx gates, but I find it unnecessary, since at least for nowrx is present in all the backends that support fractional gates.

wshanks reacted with thumbs up emoji

"""

def__init__(self,target:Optional[Union[Target,list[str]]]=None):
def__init__(self,target:Optional[Union[Target,List[str]]]=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If you prefer, you can usefrom __future__ import annotations at the top of the import statements and then the new style will work for type hints. Doing this causes the type hints to be converted into strings instead of being evaluated as objects (so it doesn't make thelist[...] syntax actually work on Python 3.9; if you try to use it outside of an annotation, there will be an error).

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't mind, do you have a preference?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We are inconsistent enough in this repo that I don't think it matters much in individual PRs like this, it would be more effective to have a PR that unifies across the repo and then we start being strict. My preference is to eventually settle on thenew-style, in which case this would beTarget | list[str] | None.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't have a strong preference though I do think it is nice to avoid the typing imports when possible. I mainly wanted to point the option out since I saw the commit message "old style typing required by CI".

@ihincks
Copy link
Collaborator

ihincks commentedDec 10, 2024
edited
Loading

Should we be concerned about the blowing up in size of the input circuit?

Thanks for writing this example out explicitly,@wshanks . I don't have any feedback at the moment, just a question and some comments.

First of all, I haven't yet looked at the implementation or any math notes, but based on the gates in the printout, I assume this is implementing something the following case logic (?):

  • θ in [0, pi/2]:rzz(θ)
  • θ in [pi/2, pi]:(z \kron z) . rzz(θ-pi/2)
  • θ in [-pi/2, 0]:(x \kron I) . rzz(-θ) . (x \kron I) + global phase
  • θ in [-pi, -pi/2]:(x \kron i) . (z \kron z) . rzz(-θ-pi/2) . (x \kron I) + global phase

If so, I guess it's not surprising that implementing case logic with parameter expressions end up rather complicated. If there were many thousands of these inside of an input, it would cause bottlenecks various places in the stack.

To me, one of the main sticking points is where and how the user opts-in to the two extra rx gates.

@yaelbh
Copy link
CollaboratorAuthor

The logic is described in a clear manner at the doc strings of the methodsquad1 -quad4. Note that the rzz angle must always be valid. The rx gates come from the fact that X is only sometimes present (so rx angle is either 0 or pi), the user is not involved.

@wshanks
Copy link
Collaborator

One thing I wonder about regarding the size of the expressions -- perhaps we could getbetween(x, lower, upper) added toParameterExpression in Qiskit? That would remove the need to carry some of the math in the parameter expressions here. I could see Qiskit not wanting it though sinceParameterExpression is float-like andbetween would naturally be a boolean, but here it is a function that returns 0.0 or 1.0. Maybe also something likewrap_angle (a shortcut formod(p + pi, 2 * pi) - pi) would help.

Also, I agree with Ian on the point about opting into this pass. I think currently (only handling numerical RZZ parameters) it is always run. For numerical RZZ parameters, that makes sense -- if you use only angles between 0 and pi/2, it does nothing. For the parameter case, it always adds the RX gates and the user might not want that if they are already keeping their angles between 0 and pi/2.

@yaelbh
Copy link
CollaboratorAuthor

Stefan Wörner proposes something along the lines of:

phi = np.pi/2 - np.abs(theta - np.pi * np.floor(theta / np.pi) - np.pi/2)omega_x = np.pi/2*(1 + np.sign(theta - np.pi*np.floor(theta/np.pi) - np.pi/2))omega_z = 2*np.pi - np.pi * np.ceil(np.abs(theta - np.pi)/np.pi*2)

This approach looks correct, and is expected to reduce the size of the final expressions.

stefan-woerner reacted with thumbs up emoji

@wshanks
Copy link
Collaborator

We want to make sure to take% (2 * pi) on all the thetas to be safe. Also,ceil andfloor are not implemented forParameterExpression currently. It seems possible to avoid them using onlyabs andsign. Here are some updated expressions from Stefan:

phi = pi / 2 - abs(theta % pi - pi / 2)omega_x = pi / 2 * (1 + (theta % pi - pi / 2).sign())omega_z = pi / 2 * (1 + ((theta + pi / 2) % (2 * pi) - pi).sign())

@yaelbh
Copy link
CollaboratorAuthor

In the code we should define a function that returns a general expression for an if-else condition, based onsign. The PR already contains such functions, but using the idea above (of taking the middle of the two values and adding/substracting half of the difference) produces smaller expressions.

Then call that if-else function with what we need forphi,omega_x, andomega_z.

@yaelbh
Copy link
CollaboratorAuthor

Expressions of the form

omega_x = pi / 2 * (1 + (theta % pi - pi / 2).sign())

don't take into account that the sign can be 0 (equality). Handling sign=0 makes quadratics unavoidable. By quadratic I refer to

<some expression>.sign() * <expression>.sign()

These quadratics greatly increase the size of the final expressions.

wshanks reacted with thumbs up emoji

@yaelbh
Copy link
CollaboratorAuthor

We can avoid the quadratics by adding/subtracting 0.1 (any number between 0 and 1 will do) and apply sign again:

(something.sign() + 0.1).sign()
wshanks reacted with thumbs up emoji

@wshanks
Copy link
Collaborator

One option we might consider if it seems like the parametric option has too much overhead is adding a pub->pub helper function that inserts the extra gates into the circuit along with inserting the corresponding parameter values into the output pub. The parametric rzz validation error message could suggest this function when it finds a value out of range.

yaelbh reacted with thumbs up emoji

@ihincks
Copy link
Collaborator

@wshanks That seems like a decent interim solution. It would break the flow a bit of create->transpile->execute, but I think it would be a net win over instantiating and then sending the large parameter expressions over the wire.

@yaelbh
Copy link
CollaboratorAuthor

I agree about the helper function, perhaps we will have to write an additional function to translate back parameter values to values of the original parameters.

I'm still curious to give here one more try to substantially reduce the expression size, based on ideas that were raised above:

  1. While currently true expressions evaluate to 1 and false expression evaluate to 0, change false expressions to evaluate to -1, and use the idea above of starting in the middle and turning left or right.
  2. Unify adjacent quads - an expression such asquad2 * pi + quad3 * pi can be written using a singlebetween.
  3. Replacebetween withgreater/smaller than if the wrapped angle is between-pi and something, or between something andpi. This is because the wrapped angle by definition cannot be smaller than-pi or greater thanpi.
  4. To resolve the case wheresign is 0, applysign twice instead of multiplying an expression by itself.

All this is valid if we are allowed to usemod. I'll try to run the existing code on a real device, and see if there are issues withmod down the stack.

Finally, if we after all decide to take this path, we will have to implement an opt-in solution.

@wshanks
Copy link
Collaborator

I think the absence of__mod__ inthis table means that it won't pass through qpy serialization, but__mod__ seems like a valid operation to add to that list.

@yaelbh
Copy link
CollaboratorAuthor

It seems that the concern about the expression not being able to be consumed by the stack is false. The following program runs well:

fromqiskit.circuitimportQuantumCircuit,Parameterfromqiskit.transpiler.passmanagerimportPassManagerfromqiskit_ibm_runtimeimportQiskitRuntimeService,SamplerV2fromqiskit_ibm_runtime.transpiler.passes.basisimportFoldRzzAngleservice=QiskitRuntimeService()backend=service.backend("ibm_aachen",use_fractional_gates=True)sampler=SamplerV2(mode=backend)p=Parameter("p")circ=QuantumCircuit(2,2)circ.rzz(p,0,1)circ.measure([0,1], [0,1])pm=PassManager([FoldRzzAngle()])circ=pm.run(circ)# The circuit after the pass contains global phase gates,# which have to be yet taken care of before submitting to the device.# Since we are only curious to see if our generated expression can be consumed,# it is enough to take the `rzz` instruction of the transpiled circiut.print(circ.data)circ.data= [circ.data[4]]job=sampler.run([(circ,-1)])print(job.job_id())res=job.result()print(res[0].data.c.get_counts())

By the way, if we take the pass manager from the plugin,

pm=generate_preset_pass_manager(optimization_level=0,backend=backend,translation_method="ibm_fractional",)

then the transpilation takes the path of usingcz.

@yaelbh
Copy link
CollaboratorAuthor

After implementing the optimizations,@wshanks's famous Details section shrinks from 8079 to 1943 characters:
[CircuitInstruction(operation=Instruction(name='global_phase', num_qubits=0, num_clbits=0, params=[ParameterExpression(1.5707963267949*sign(sign(p - 6.28318530717959*floor(0.159154943091895*p) - 4.71238898038469) + 0.1) + 1.5707963267949*sign(sign(p - 12.5663706143592*floor(0.0795774715459477*p + 0.25) - 3.14159265358979) + 0.1) - 0.785398163397448*sign(sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.25) - 1.5707963267949) + 0.1) + 2.35619449019234)]), qubits=(), clbits=()), CircuitInstruction(operation=Instruction(name='rz', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*sign(sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.25) - 1.5707963267949) + 0.1) + 1.5707963267949)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=()), CircuitInstruction(operation=Instruction(name='rx', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*sign(sign(p - 3.14159265358979*floor(0.318309886183791*p) - 1.5707963267949) + 0.1) + 1.5707963267949)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=()), CircuitInstruction(operation=Instruction(name='rz', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*sign(sign(p - 6.28318530717959*floor(0.159154943091895*p + 0.25) - 1.5707963267949) + 0.1) + 1.5707963267949)]), qubits=(Qubit(QuantumRegister(2, 'q'), 1),), clbits=()), CircuitInstruction(operation=Instruction(name='rzz', num_qubits=2, num_clbits=0, params=[ParameterExpression(1.5707963267949 - Abs(-p + 3.14159265358979*floor(0.318309886183791*p) + 1.5707963267949))]), qubits=(Qubit(QuantumRegister(2, 'q'), 0), Qubit(QuantumRegister(2, 'q'), 1)), clbits=()), CircuitInstruction(operation=Instruction(name='rx', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.5707963267949*sign(sign(p - 3.14159265358979*floor(0.318309886183791*p) - 1.5707963267949) + 0.1) + 1.5707963267949)]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),), clbits=())]

@ElePT
Copy link
Collaborator

I understand that this PR will be superseded by#2125 and there are no immediate plans to continue developing it, I will mark it as on hold for the time being. Let me know if this is incorrect.

@yaelbh
Copy link
CollaboratorAuthor

It's fine to mark it on hold. Just for accuracy,#2125 doesn't supersede this PR, but solves the same problem in a different way.

ElePT reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@wshankswshankswshanks left review comments

@ihincksihincksihincks left review comments

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Transpilation can result in rzz gates with invalid angles

4 participants

@yaelbh@ihincks@wshanks@ElePT

[8]ページ先頭

©2009-2025 Movatter.jp