如何在 Cirq/Tensorflow Quantum 中实施受控 Rx?

How do I implement a controlled Rx in Cirq/Tensorflow Quantum?

我正在尝试在 Cirq/Tensorflow Quantum 中实现受控旋转门。

https://cirq.readthedocs.io/en/stable/gates.html 处的 readthedocs.io 指出:

"Gates can be converted to a controlled version by using Gate.controlled(). In general, this returns an instance of a ControlledGate. However, for certain special cases where the controlled version of the gate is also a known gate, this returns the instance of that gate. For instance, cirq.X.controlled() returns a cirq.CNOT gate. Operations have similar functionality Operation.controlled_by(), such as cirq.X(q0).controlled_by(q1)."

我已经实现了

cirq.rx(theta_0).on(q[0]).controlled_by(q[3])

我收到以下错误:

~/.local/lib/python3.6/site-packages/cirq/google/serializable_gate_set.py in 
serialize_op(self, op, msg, arg_function_language)
    193                         return proto_msg
    194         raise ValueError('Cannot serialize op {!r} of type {}'.format(
--> 195             gate_op, gate_type))
    196 
    197     def deserialize_dict(self,

ValueError: Cannot serialize op cirq.ControlledOperation(controls=(cirq.GridQubit(0, 3),), sub_operation=cirq.rx(sympy.Symbol('theta_0')).on(cirq.GridQubit(0, 0)), control_values=((1,),)) of type <class 'cirq.ops.controlled_gate.ControlledGate'>

我将量子位和符号初始化为:

q = cirq.GridQubit.rect(1, 4)
symbol_names = x_0, x_1, x_2, x_3, theta_0, theta_1, z_2, z_3

我确实在各种电路中重复使用电路。

我的问题:如何在 Cirq/Tensorflow Quantum 中正确实施受控 Rx?

P.S。我找不到 Google Cirq

的标签

跟进: 这如何推广到受控 Ry 和受控 Rz 的类似情况?

对于 Rz,我在 https://threeplusone.com/pubs/on_gates.pdf 处发现了门分解,涉及 H.on(q1)、CNOT(q0, q1)、H.on(q2),但这还不是具有任意角度的 CRz。我会在H之前引入角度吗?

对于Ry,我还没有找到分解,CRy也没有。

您拥有的是 Cirq 中受控 X 旋转的完全正确实现。它可以用于模拟和其他类似 cirq.unitary 的东西,没有任何问题。

TFQ 仅支持 Cirq 中的门的子集。例如,cirq.ControlledGate 可以有任意数量的控制量子位,在某些情况下,这会使它更难分解为与 NiSQ 硬件平台兼容的原始门(这就是为什么 cirq.decompose 不对 ControlledOperations 做任何事情)。 TFQ 只支持这些原始风格的门,要获得支持的门的完整列表,你可以这样做:

tfq.util.get_supported_gates().keys()

在你的情况下,可以想出一个更简单的这个门的实现。首先我们可以注意到 cirq.rx(some angle) 等于 cirq.X**(some angle / pi) 偏移一个全局相位:

>>> a = cirq.rx(0.3)
>>> b = cirq.X**(0.3 / np.pi)
>>> cirq.equal_up_to_global_phase(cirq.unitary(a), cirq.unitary(b))
True

让我们现在开始使用 X。那么我们之后的操作就是:

>>> qs = cirq.GridQubit.rect(1,2)
>>> a = (cirq.X**0.3)(qs[0]).controlled_by(qs[1])
>>> b = cirq.CNOT(qs[0], qs[1]) ** 0.3
>>> cirq.equal_up_to_global_phase(cirq.unitary(a), cirq.unitary(b))
True

因为 cirq.CNOT 在 TFQ 支持的门中,它应该是可序列化的,没有任何问题。如果你想制作门的符号化版本,你只需将 0.3 替换为 sympy.Symbol.

跟进的答案:如果你想做一个 CRz,你可以做你上面做的同样的事情,将 CNOT 门换成 CZ 门。对于 CRy 来说,这并不容易。为此,我建议做一些组合:cirq.Y(0) 和 cirq.YY(0, 1).

编辑: tfq-nightly 构建和可能在 0.4.0 之后发布的版本现在包括对任意控制门的支持。因此,在这些版本的 tfq 上,您现在也可以执行 cirq.Y(...).controlled_by(...) 之类的操作来获得所需的结果。