def test_eval(): x = Parameter('x') assert substitute(x, {x: 5}) == 5 y = Parameter('y') assert substitute(x + y, {x: 5, y: 6}) == 11 assert substitute(x + y, {x: 5}) == 5 + y assert substitute(quil_exp(x), {y: 5}) != np.exp(5) assert substitute(quil_exp(x), {x: 5}) == np.exp(5) assert np.isclose(substitute(quil_sin(x * x**2 / y), { x: 5.0, y: 10.0 }), np.sin(12.5)) assert np.isclose(substitute(quil_sqrt(x), { x: 5.0, y: 10.0 }), np.sqrt(5.0)) assert np.isclose(substitute(quil_cis(x), { x: 5.0, y: 10.0 }), np.exp(1j * 5.0)) assert np.isclose(substitute(x - y, {x: 5.0, y: 10.0}), -5.) assert substitute(quil_cis(x), {y: 5}) == quil_cis(x) assert np.allclose(substitute_array([quil_sin(x), quil_cos(x)], {x: 5}), [np.sin(5), np.cos(5)])
def test_contained_parameters(): x = Parameter("x") assert _contained_parameters(x) == {x} y = Parameter("y") assert _contained_parameters(x + y) == {x, y} assert _contained_parameters(x ** y ** quil_sin(x * y * 4)) == {x, y}
def test_apply_match_delay_qubits(): settings = {FormalArgument("q"): Qubit(0), Parameter("foo"): 1.0} instr = DelayQubits([Qubit(1), FormalArgument("q")], duration=Parameter("foo")) actual = fill_placeholders(instr, settings) expected = DelayQubits([Qubit(1), Qubit(0)], 1.0) assert actual == expected
def test_apply_match_shift_phase(): settings = {FormalArgument("q"): Qubit(0), Parameter("theta"): np.pi} instr = ShiftPhase(Frame([FormalArgument("q")], "ff"), Parameter("theta") / (2.0 * np.pi)) actual = fill_placeholders(instr, settings) expected = ShiftPhase(Frame([Qubit(0)], "ff"), 0.5) assert actual == expected
def test_parsing_defwaveform(): parse_equals("DEFWAVEFORM foo:\n" " 1.0, 1.0, 1.0\n", DefWaveform("foo", [], [1.0, 1.0, 1.0])) parse_equals( "DEFWAVEFORM foo:\n" " 1.0+2.0*i, 1.0-2.0*i, 3.0\n", DefWaveform("foo", [], [1 + 2j, 1 - 2j, 3 + 0j]), ) parse_equals( "DEFWAVEFORM foo(%theta):\n" " 1.0+2.0*i, 1.0-2.0*i, 3.0*%theta\n", DefWaveform("foo", [Parameter("theta")], [1 + 2j, 1 - 2j, Mul(3.0, Parameter("theta"))]), ) parse_equals( "DEFWAVEFORM q0_ro_rx/filter:\n 1.0, 1.0, 1.0", DefWaveform("q0_ro_rx/filter", [], [1.0, 1.0, 1.0]), )
def test_parsing_defcal(): parse_equals("DEFCAL X 0:\n" " NOP\n", DefCalibration("X", [], [Qubit(0)], [NOP])) parse_equals( "DEFCAL X q:\n" " NOP\n" " NOP\n", DefCalibration("X", [], [FormalArgument("q")], [NOP, NOP]), ) parse_equals( "DEFCAL RZ(%theta) 0:\n" ' SHIFT-PHASE 0 "rf" %theta/(-2*pi)\n', DefCalibration( "RZ", [Parameter("theta")], [Qubit(0)], [ShiftPhase(Frame([Qubit(0)], "rf"), Div(Parameter("theta"), -2 * np.pi))], ), )
def test_def_gate_with_variables(): # Note that technically the RX gate includes -i instead of just i but this messes a bit with the test since # it's not smart enough to figure out that -1*i == -i theta = Parameter('theta') rx = np.array([[quil_cos(theta / 2), 1j * quil_sin(theta / 2)], [1j * quil_sin(theta / 2), quil_cos(theta / 2)]]) defgate = 'DEFGATE RX(%theta):\n' \ ' COS(%theta/2), i*SIN(%theta/2)\n' \ ' i*SIN(%theta/2), COS(%theta/2)\n\n' parse_equals(defgate, DefGate('RX', rx, [theta]))
def _transform_rpcq_qubit_gate_info_to_qvm_noise_supported_gate( qubit_id: int, gate: GateInfo) -> Optional[Gate]: if gate.operator == Supported1QGate.RX: if len(gate.parameters) == 1 and gate.parameters[0] == 0.0: return None parameters = [ Parameter(param) if isinstance(param, str) else param for param in gate.parameters ] return Gate(gate.operator, parameters, [unpack_qubit(qubit_id)]) if gate.operator == Supported1QGate.RZ: return Gate(Supported1QGate.RZ, [Parameter("theta")], [unpack_qubit(qubit_id)]) if gate.operator == Supported1QGate.I: return Gate(Supported1QGate.I, [], [unpack_qubit(qubit_id)]) _log.warning("Unknown qubit gate operator: {}".format(gate.operator)) return None
def test_def_gate_with_parameters(): theta = Parameter('theta') rx = np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)], [-1j * quil_sin(theta / 2), quil_cos(theta / 2)]]) p = Program().defgate("RX", rx, [theta]) assert p.out() == 'DEFGATE RX(%theta):\n' \ ' COS(%theta/2), -i*SIN(%theta/2)\n' \ ' -i*SIN(%theta/2), COS(%theta/2)\n\n' dg = DefGate('MY_RX', rx, [theta]) MY_RX = dg.get_constructor() p = Program().inst(MY_RX(np.pi)(0)) assert p.out() == 'MY_RX(pi) 0\n'
def u2_replacement(phi: float, lam: float): """ implemented with a custom gate """ # implemented with X90 pulse: https://qiskit.org/documentation/stubs/qiskit.circuit.library.U2Gate.html # p = Program() # p += RZ(phi + np.pi/2, 0) # p += RX(np.pi/2, 0) # p += RZ(lam - np.pi/2, 0) phi_param = Parameter('phi') lam_param = Parameter('lam') matrix = np.array( [[1 / np.sqrt(2), -quil_exp(1j * lam_param) * 1 / np.sqrt(2)], [ quil_exp(1j * phi_param) * 1 / np.sqrt(2), quil_exp(1j * (phi_param + lam_param)) * 1 / np.sqrt(2) ]]) definition = DefGate('U2', matrix, [phi_param, lam_param]) U2 = definition.get_constructor() p = Program() p += definition p += U2(phi, lam)(0) return p
def u3_replacement(theta: float, phi: float, lam: float): """ implemented with a custom gate """ # implemented with two X90 pulse: https://arxiv.org/pdf/1707.03429.pdf # p = Program() # p += RZ(phi + 3*np.pi, 0) # p += RX(np.pi/2, 0) # p += RZ(np.pi + theta, 0) # p += RX(np.pi/2, 0) # p += RZ(lam, 0) # formula from https://qiskit.org/documentation/stubs/qiskit.circuit.library.U3Gate.html (13.07.2020) gives wrong results # p = Program() # p += RZ(phi - np.pi/2, 0) # p += RX(np.pi/2, 0) # p += RZ(np.pi - theta, 0) # p += RX(np.pi/2, 0) # p += RZ(lam - np.pi/2, 0) theta_param = Parameter('theta') phi_param = Parameter('phi') lam_param = Parameter('lam') matrix = np.array( [[ quil_cos(theta_param / 2), -quil_exp(1j * lam_param) * quil_sin(theta_param / 2) ], [ quil_exp(1j * phi_param) * quil_sin(theta_param / 2), quil_exp(1j * (phi_param + lam_param)) * quil_cos(theta_param / 2) ]]) definition = DefGate('U3', matrix, [theta_param, phi_param, lam_param]) U3 = definition.get_constructor() p = Program() p += definition p += U3(theta, phi, lam)(0) return p
def test_expression_to_string(): x = Parameter("x") assert str(x) == "%x" y = Parameter("y") assert str(y) == "%y" assert str(x + y) == "%x + %y" assert str(3 * x + y) == "3*%x + %y" assert str(3 * (x + y)) == "3*(%x + %y)" assert str(x + y + 2) == "%x + %y + 2" assert str(x - y - 2) == "%x - %y - 2" assert str(x - (y - 2)) == "%x - (%y - 2)" assert str((x + y) - 2) == "%x + %y - 2" assert str(x + (y - 2)) == "%x + %y - 2" assert str(x ** y ** 2) == "%x^%y^2" assert str(x ** (y ** 2)) == "%x^%y^2" assert str((x ** y) ** 2) == "(%x^%y)^2" assert str(quil_sin(x)) == "SIN(%x)" assert str(3 * quil_sin(x + y)) == "3*SIN(%x + %y)"
def test_expression_to_string(): x = Parameter('x') assert str(x) == '%x' y = Parameter('y') assert str(y) == '%y' assert str(x + y) == '%x + %y' assert str(3 * x + y) == '3*%x + %y' assert str(3 * (x + y)) == '3*(%x + %y)' assert str(x + y + 2) == '%x + %y + 2' assert str(x - y - 2) == '%x - %y - 2' assert str(x - (y - 2)) == '%x - (%y - 2)' assert str((x + y) - 2) == '%x + %y - 2' assert str(x + (y - 2)) == '%x + %y - 2' assert str(x**y**2) == '%x^%y^2' assert str(x**(y**2)) == '%x^%y^2' assert str((x**y)**2) == '(%x^%y)^2' assert str(quil_sin(x)) == 'SIN(%x)' assert str(3 * quil_sin(x + y)) == '3*SIN(%x + %y)'
def test_parametric_calibration_match(): matches = [ ("DEFCAL RX(0.0) 0", "RX(0.0) 0"), ("DEFCAL RX(0.0) 0", "RX(0*pi) 0"), ("DEFCAL RX(pi/2) 0", "RX(pi/2) 0"), ("DEFCAL RX(pi/2) q", "RX(pi/2) 0"), ("DEFCAL RX(pi/2) q", "RX(pi/2) 1"), ("DEFCAL RZ(pi/2) 0", "RZ(pi/2) 0"), ("DEFCAL RX(%theta) 0", "RX(pi) 0"), ] for cal, instr in matches: assert _match(cal, instr) is not None assert np.isclose(_match(cal, instr).settings[Parameter("theta")], np.pi) mismatches = [ ("DEFCAL RX(pi) q", "RX(0) 0"), ("DEFCAL RX(pi) 0", "RX(0) 0"), ("DEFCAL RX(pi) 0", "RY(pi) 0"), ] for cal, instr in mismatches: assert not _match(cal, instr)
def _variable(variable): # type: (QuilParser.VariableContext) -> Parameter return Parameter(variable.IDENTIFIER().getText())
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union, cast import networkx as nx import numpy as np from pyquil.quilatom import Parameter, unpack_qubit from pyquil.quilbase import Gate if sys.version_info < (3, 7): from pyquil.external.dataclasses import dataclass else: from dataclasses import dataclass DEFAULT_QUBIT_TYPE = "Xhalves" DEFAULT_EDGE_TYPE = "CZ" THETA = Parameter("theta") "Used as the symbolic parameter in RZ, CPHASE gates." @dataclass class MeasureInfo: operator: Optional[str] = None qubit: Optional[Union[int, str]] = None target: Optional[Union[int, str]] = None duration: Optional[float] = None fidelity: Optional[float] = None @dataclass class GateInfo: operator: Optional[str] = None
def test_lifted_gate_with_nonconstant_params(): gate = RX(Parameter("theta"), 0) with pytest.raises(TypeError): lifted_gate(gate, 1)