Exemplo n.º 1
0
def compile_controlled_phase(gate) -> QCircuit:
    if not isinstance(gate, PhaseGateImpl):
        return QCircuit.wrap_gate(gate)
    if len(gate.control) == 0:
        return QCircuit.wrap_gate(gate)
    count = len(gate.control)
    result = QCircuit()
    phase = gate.parameter

    if count == 1:
        result += H(target=gate.target)
        result += CNOT(gate.control, gate.target)
        result += H(target=gate.target)
        result += Phase(gate.parameter + numpy.pi, target=gate.target)
    elif count == 2:
        result += Rz(angle=phase / (2**2), target=gate.control[0])
        result += Rz(angle=phase / (2**(1)),
                     target=gate.control[1],
                     control=gate.control[0])
        result += Rz(angle=phase, target=gate.target, control=gate.control)

    elif count >= 3:
        result += Rz(angle=phase / (2**count), target=gate.control[0])
        for i in range(1, count):
            result += Rz(angle=phase / (2**(count - i)),
                         target=gate.control[i],
                         control=gate.control[0:i])
        result += Rz(angle=phase, target=gate.target, control=gate.control)
    return result
Exemplo n.º 2
0
def compile_toffoli(gate) -> QCircuit:
    if gate.name.lower != 'x':
        return QCircuit.wrap_gate(gate)
    control = gate.control
    c1 = control[1]
    c0 = control[0]
    target = gate.target
    result = QCircuit()
    result += H(target)
    result += CNOT(c1, target)
    result += T(target).dagger()
    result += CNOT(c0, target)
    result += T(target)
    result += CNOT(c1, target)
    result += T(target).dagger()
    result += CNOT(c0, target)
    result += T(c1)
    result += T(target)
    result += CNOT(c0, c1)
    result += H(target)
    result += T(c0)
    result += T(c1).dagger()
    result += CNOT(c0, c1)

    return (result)
Exemplo n.º 3
0
def change_basis(target, axis, daggered=False):
    """
    helper function; returns circuit that performs change of basis.
    Parameters
    ----------
    target:
        the qubit having its basis changed
    axis:
        The axis of rotation to shift into.
    daggered: bool:
        adjusts the sign of the gate if axis = 1, I.E, change of basis about Y axis.

    Returns
    -------
    QCircuit that performs change of basis on target qubit onto desired axis

    """
    if isinstance(axis, str):
        axis = RotationGateImpl.string_to_axis[axis.lower()]

    if axis == 0:
        return H(target=target)
    elif axis == 1 and daggered:
        return Rx(angle=-numpy.pi / 2, target=target)
    elif axis == 1:
        return Rx(angle=numpy.pi / 2, target=target)
    else:
        return QCircuit()
Exemplo n.º 4
0
def test_basic_gates():
    I = sympy.I
    cos = sympy.cos
    sin = sympy.sin
    exp = sympy.exp
    BS = QubitWaveFunction.from_int
    angle = sympy.pi
    gates = [
        X(0),
        Y(0),
        Z(0),
        Rx(target=0, angle=angle),
        Ry(target=0, angle=angle),
        Rz(target=0, angle=angle),
        H(0)
    ]
    results = [
        BS(1), I * BS(1),
        BS(0),
        cos(-angle / 2) * BS(0) + I * sin(-angle / 2) * BS(1),
        cos(-angle / 2) * BS(0) + I * sin(-angle / 2) * I * BS(1),
        exp(-I * angle / 2) * BS(0), 1 / sympy.sqrt(2) * (BS(0) + BS(1))
    ]
    for i, g in enumerate(gates):
        wfn = simulate(g, backend="symbolic", variables={angle: sympy.pi})
        assert (wfn == strip_sympy_zeros(results[i]))
Exemplo n.º 5
0
def test_moments():
    c = QCircuit()
    c += CNOT(target=0, control=(1, 2, 3))
    c += H(target=[0, 1])
    c += Rx(angle=numpy.pi, target=[0, 3])
    c += Z(target=1)
    c += Phase(phi=numpy.pi, target=4)
    moms = c.moments
    assert len(moms) == 3
    assert (moms[0].gates[1].parameter == assign_variable(numpy.pi))
    assert (moms[0].gates[1].target == (4, ))
Exemplo n.º 6
0
def change_basis(target, axis, daggered=False):
    if isinstance(axis, str):
        axis = RotationGateImpl.string_to_axis[axis.lower()]

    if axis == 0:
        return H(target=target)
    elif axis == 1 and daggered:
        return Rx(angle=-numpy.pi / 2, target=target)
    elif axis == 1:
        return Rx(angle=numpy.pi / 2, target=target)
    else:
        return QCircuit()
Exemplo n.º 7
0
def test_circuit_from_moments():
    c = QCircuit()
    c += CNOT(target=0, control=(1, 2, 3))
    c += Phase(phi=numpy.pi, target=4)
    c += Rx(angle=Variable('a'), target=[0, 3])
    c += H(target=[0, 1])
    c += Rx(angle=Variable('a'), target=[2, 3])
    ## table[1] should equal 1 at this point, len(moments should be 3)
    c += Z(target=1)
    c += Rx(angle=Variable('a'), target=[0, 3])
    moms = c.moments
    c2 = QCircuit.from_moments(moms)
    assert c == c2
Exemplo n.º 8
0
def compile_toffoli(gate) -> QCircuit:
    """
    break down a toffoli gate into a sequence of CNOT and single qubit gates.
    Parameters
    ----------
    gate:
        the gate.

    Returns
    -------
        A QCircuit; the result of compilation.
    """

    if gate.name.lower != 'x':
        return QCircuit.wrap_gate(gate)
    control = gate.control
    c1 = control[1]
    c0 = control[0]
    target = gate.target
    result = QCircuit()
    result += H(target)
    result += CNOT(c1, target)
    result += T(target).dagger()
    result += CNOT(c0, target)
    result += T(target)
    result += CNOT(c1, target)
    result += T(target).dagger()
    result += CNOT(c0, target)
    result += T(c1)
    result += T(target)
    result += CNOT(c0, c1)
    result += H(target)
    result += T(c0)
    result += T(c1).dagger()
    result += CNOT(c0, c1)

    return (result)
Exemplo n.º 9
0
def test_canonical_moments():
    c = QCircuit()
    c += CNOT(target=0, control=(1, 2, 3))
    c += Rx(angle=Variable('a'), target=[0, 3])
    c += H(target=[0, 1])
    c += Rx(angle=Variable('a'), target=[2, 3])
    c += Rx(angle=Variable('a'), target=[0, 3])
    c += Z(target=1)
    c += Phase(phi=numpy.pi, target=4)
    moms = c.canonical_moments
    assert len(moms) == 6
    assert (moms[0].gates[1].parameter == assign_variable(numpy.pi))
    assert (moms[0].gates[1].target == (4, ))
    assert hasattr(moms[3].gates[0], 'axis')
    assert len(moms[0].qubits) == 5
Exemplo n.º 10
0
def change_basis(target, axis=None, name=None, daggered=False):
    """
    helper function; returns circuit that performs change of basis.
    Parameters
    ----------
    target:
        the qubit having its basis changed
    axis:
        The axis of rotation to shift into.
    daggered: bool:
        adjusts the sign of the gate if axis = 1, I.E, change of basis about Y axis.

    Returns
    -------
    QCircuit that performs change of basis on target qubit onto desired axis

    """
    if axis is None and name is None:
        raise TequilaException('axis or name must be given.')

    if name:
        name = name.lower()
        if name in ['h', 'hadamard'] and daggered:
            return Ry(angle=numpy.pi / 4, target=target)
        elif name in ['h', 'hadamard']:
            return Ry(angle=-numpy.pi / 4, target=target)
        else:
            name_to_axis = {'rx': 0, 'ry': 1, 'rz': 2}
            axis = name_to_axis.get(name, name)

    if isinstance(axis, str):
        axis = RotationGateImpl.string_to_axis[axis.lower()]

    if axis == 0:
        return H(target=target)
    elif axis == 1 and daggered:
        return Rx(angle=-numpy.pi / 2, target=target)
    elif axis == 1:
        return Rx(angle=numpy.pi / 2, target=target)
    else:
        return QCircuit()