-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Controlled UGate with a parameterized angle fails with 4 or more controls #12135
Comments
Perhaps related to #11993 |
This is because of the eager attempts to synthesise controlled gates in arbitrary controls - chances are that before 4 controls, we have a particular path through the synthesis that simplifies everything down to something we can do symbolically, but not in this case. As an immediate workaround, depending on when you will call |
I think it may be related to this PR: #9688 in the code of
is overridden by: lam (float): angle lambda
In fact, I also mentioned it in issue #12048 |
Perhaps this is because the function qiskit/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py Lines 87 to 92 in 7175368
If you try to use parameters to construct MCRX gate, it fails here
How to reproduce: from qiskit import QuantumCircuit
from qiskit.circuit.parameter import Parameter
qc = QuantumCircuit(4)
th = Parameter('θ')
qc.mcrx(th, [0, 1, 2], 3, use_basis_gates=False)
qcinv = qc.inverse()
from qiskit.quantum_info import Operator
from qiskit.quantum_info.operators.predicates import is_identity_matrix
print(is_identity_matrix(Operator(qc).dot(qcinv.inverse()).data)) |
closing this issue as #12752 is merged |
Environment
What is happening?
A controlled UGate with a parametrized angle k and with 4 (or more) controls throws an error.
Such controlled parametrized gates are useful for constructing certain custom trial states for vqe.
How can we reproduce the issue?
TypeError Traceback (most recent call last)
Cell In[3], line 10
8 q=QuantumRegister(5)
9 qc = QuantumCircuit(q)
---> 10 ccU = UGate(k,0,0).control(4)
11 qc.append(ccU,[0,1,2,3,4])
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/library/standard_gates/u.py:130, in UGate.control(self, num_ctrl_qubits, label, ctrl_state, annotated)
128 gate.base_gate.label = self.label
129 else:
--> 130 gate = super().control(
131 num_ctrl_qubits=num_ctrl_qubits,
132 label=label,
133 ctrl_state=ctrl_state,
134 annotated=annotated,
135 )
136 return gate
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/gate.py:121, in Gate.control(self, num_ctrl_qubits, label, ctrl_state, annotated)
117 if not annotated:
118 # pylint: disable=cyclic-import
119 from .add_control import add_control
--> 121 return add_control(self, num_ctrl_qubits, label, ctrl_state)
123 else:
124 return AnnotatedOperation(
125 self, ControlModifier(num_ctrl_qubits=num_ctrl_qubits, ctrl_state=ctrl_state)
126 )
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/add_control.py:61, in add_control(operation, num_ctrl_qubits, label, ctrl_state)
58 if isinstance(operation, UnitaryGate):
59 # attempt decomposition
60 operation._define()
---> 61 cgate = control(operation, num_ctrl_qubits=num_ctrl_qubits, label=label, ctrl_state=ctrl_state)
62 if operation.label is not None:
63 cgate.base_gate = cgate.base_gate.to_mutable()
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/add_control.py:187, in control(operation, num_ctrl_qubits, label, ctrl_state)
183 controlled_circ.mcrx(
184 theta, q_control, q_target[bit_indices[qargs[0]]], use_basis_gates=True
185 )
186 elif phi == 0 and lamb == 0:
--> 187 controlled_circ.mcry(
188 theta,
189 q_control,
190 q_target[bit_indices[qargs[0]]],
191 q_ancillae,
192 use_basis_gates=True,
193 )
194 elif theta == 0 and phi == 0:
195 controlled_circ.mcp(lamb, q_control, q_target[bit_indices[qargs[0]]])
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py:331, in mcry(self, theta, q_controls, q_target, q_ancillae, mode, use_basis_gates)
320 _apply_mcu_graycode(
321 self,
322 theta_step,
(...)
327 use_basis_gates=use_basis_gates,
328 )
329 else:
330 cgate = _mcsu2_real_diagonal(
--> 331 RYGate(theta).to_matrix(),
332 num_controls=len(control_qubits),
333 use_basis_gates=use_basis_gates,
334 )
335 self.compose(cgate, control_qubits + [target_qubit], inplace=True)
336 else:
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/gate.py:62, in Gate.to_matrix(self)
52 """Return a Numpy.array for the gate unitary matrix.
53
54 Returns:
(...)
59 exception will be raised when this base class method is called.
60 """
61 if hasattr(self, "array"):
---> 62 return self.array(dtype=complex)
63 raise CircuitError(f"to_matrix not defined for this {type(self)}")
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/library/standard_gates/ry.py:124, in RYGate.array(self, dtype)
122 def array(self, dtype=None):
123 """Return a numpy.array for the RY gate."""
--> 124 cos = math.cos(self.params[0] / 2)
125 sin = math.sin(self.params[0] / 2)
126 return numpy.array([[cos, -sin], [sin, cos]], dtype=dtype)
File ~/Library/Python/3.12/lib/python/site-packages/qiskit/circuit/parameterexpression.py:415, in ParameterExpression.float(self)
413 except (TypeError, RuntimeError) as exc:
414 if self.parameters:
--> 415 raise TypeError(
416 "ParameterExpression with unbound parameters ({}) "
417 "cannot be cast to a float.".format(self.parameters)
418 ) from None
419 # In symengine, if an expression was complex at any time, its type is likely to have
420 # stayed "complex" even when the imaginary part symbolically (i.e. exactly)
421 # cancelled out. Sympy tends to more aggressively recognise these as symbolically
422 # real. This second attempt at a cast is a way of unifying the behaviour to the
423 # more expected form for our users.
424 cval = complex(self)
TypeError: ParameterExpression with unbound parameters (dict_keys([Parameter(k)])) cannot be cast to a float.```
What should happen?
If the number of controls is less than 4, then no error is thrown:
<qiskit.circuit.instructionset.InstructionSet at 0x107709330>```
Similar behavior is expected for 4 or more controls.
Any suggestions?
Thanks for your help.
CC:@diemilio
The text was updated successfully, but these errors were encountered: