示例#1
0
def test_hologram(silent=True):
    if not silent:
        print("\nTesting Hologram")

    S = 2
    qpm = 2
    setup = PhotonicSetup(pathnames=['a'], S=S, qpm=qpm)
    setup.add_hologram(path='a')

    states = [
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|20000>_a"),  # 2 photons in -2
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|02000>_a"),  # 2 photons in -1
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|00200>_a"),  # 2 photons in  0
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|00020>_a"),  # 2 photons in  1
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|00002>_a"),  # 2 photons in  2
    ]

    for i, start in enumerate(states):
        end = setup.simulate_wavefunction(initial_state=start)
        expected = states[(i + 1) % 5]
        if not silent:
            print("start   =", start)
            print("end     =", end)
            print("expected=", expected)
        assert (end == expected)
示例#2
0
def test_mirror(silent=True):
    if not silent:
        print("\nTesting Mirror")

    S = 2
    qpm = 2

    setup = PhotonicSetup(pathnames=['a'], S=S, qpm=qpm)
    paths = setup.paths
    setup.add_mirror(path='a')

    statesx = [
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|20000>_a"),  # 2 photons in -2
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|02000>_a"),  # 2 photons in -1
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|00200>_a"),  # 2 photons in  0
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|00020>_a"),  # 2 photons in  1
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|00002>_a"),  # 2 photons in  2
    ]

    statesy = [
        PhotonicStateVector.from_string(paths=paths, string="1.0|21301>_a"),
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|33000>_a"),  # 2 photons in -1
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|21312>_a"),  # 2 photons in  0
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|00033>_a"),  # 2 photons in  1
        PhotonicStateVector.from_string(
            paths=paths, string="1.0|10312>_a"),  # 2 photons in  2
    ]

    for states in [statesx, statesy]:
        for i, start in enumerate(states):
            end = setup.simulate_wavefunction(initial_state=start)
            expected = states[-(i + 1)]

            if not silent:
                print(
                    "Mirror Circuit:\n",
                    SimulatorCirq().create_circuit(
                        abstract_circuit=setup.setup))
                print("start   =", start)
                print("end     =", end)
                print("expected=", expected)
            assert (end == expected)
示例#3
0
def test_SPDC(silent=False):
    # Qubit Wavefunction for the expeced state:
    # here are the three basis functions for the -2,-1,0,1,2 mode representation
    # where each mode has 2 qubits
    # mp, minus plus, pm, plus minus, zz, zero zero

    def make_SPDC_state_vector(S, paths) -> PhotonicStateVector:
        """
        Normalized SPDC State vector
        :param S: Spin number ( Modes will be -S ... 0 ... +S)
        :return: SPDC State in 2S+1 modes
        """
        assert (len(paths.keys()) == 2)

        def one_photon_path(occ_mode: int) -> str:
            key = S + occ_mode
            tmp = ["0"] * (2 * S + 1)
            tmp[key] = "1"
            return "".join(tmp)

        def term(a: int, b: int, coeff: float = 1.0 / sqrt(3)) -> str:
            return "+" + str(coeff) + "|" + one_photon_path(
                occ_mode=a) + ">_a|" + one_photon_path(occ_mode=b) + ">_b"

        return PhotonicStateVector.from_string(paths=paths,
                                               string=term(1, -1) +
                                               term(0, 0) + term(-1, 1))

    S = 2
    qpm = 2
    setup = PhotonicSetup(pathnames=['a', 'b'], S=S, qpm=qpm)
    paths = setup.paths
    expected = make_SPDC_state_vector(S=S, paths=paths)

    setup.prepare_SPDC_state(path_a='a', path_b='b')
    end = setup.simulate_wavefunction()

    if not silent:
        print("S       =", S)
        print("q per m =", qpm)
        print("expected=", expected)
        print("end     =", end)
    assert (end == expected)
示例#4
0
def test_projector(qpm):
    S = 1
    setup = PhotonicSetup(pathnames=['a', 'b'], S=S, qpm=qpm)
    state = PhotonicStateVector.from_string(
        paths=setup.paths, string="0.7071|001>_a|111>_b+0.7071|010>_a|111>_b")
    setup.prepare_unary_type_state(state=state)
    setup.add_one_photon_projector(path='a')

    wfn = setup.simulate_wavefunction()
    assert (str(
        PhotonicStateVector.from_string(
            paths=setup.paths, string="1.0|000>_a|111>_b")) == str(wfn))

    counts = setup.sample(samples=100)
    reduced_paths = PhotonicPaths(path_names=['b'], S=S, qpm=qpm)
    assert (str(
        PhotonicStateVector.from_string(paths=reduced_paths,
                                        string="100|111>_b")) == str(counts))
示例#5
0
def test_projector_prep(qpm, silent=True):
    S = 1
    angles = [1.2309594173407747, 1.5707963267948966]

    setup = PhotonicSetup(pathnames=['a'], S=S, qpm=qpm)
    setup.add_parametrized_one_photon_projector(path='a',
                                                angles=angles,
                                                daggered=False)
    wfn = setup.simulate_wavefunction()

    result = PhotonicStateVector.from_string(
        paths=setup.paths,
        string="+ 0.5774|001>_a + 0.5774|010>_a + 0.5774|100>_a")

    if not silent:
        setup.print_circuit()
        print("wfn     = ", wfn)
        print("expected= ", result)

    assert (str(result) == str(wfn))
示例#6
0
def test_dove_prism(inout, silent=False):
    # dove prism is implemented with a global phase
    # but for this tests this is one
    # stupid qubit intitalization, but it makes the test better
    S = 1
    qpm = 2
    t = 1.0

    setup = PhotonicSetup(pathnames=['a'], S=S, qpm=qpm)
    setup.add_doveprism(path='a', t=t)

    istate = setup.initialize_state(state=inout[0])
    ostate = setup.initialize_state(state=inout[1])

    end = setup.simulate_wavefunction(initial_state=istate)

    if not silent:
        print(setup.setup)
        print("t       =", t)
        print("start   =", istate)
        print("end     =", end)
        print("expected=", ostate)
    assert (end == ostate)
from photonic import PhotonicSetup

# Directly prepare the 332 state in the digital encoding using quantum gates
# This is used in the the last part of the optimization
# Note that this is not the optical setup

if __name__ == "__main__":
    S = 1  # Modes will run from -S ... 0 ... +S (orbital angular momentum)
    qpm = 2  # Qubits per mode

    setup = PhotonicSetup(pathnames=['a', 'b', 'c'], S=S, qpm=qpm)
    setup.prepare_332_state(path_a='a', path_b='b', path_c='c', daggered=False)

    print("preparation circuti:\n", setup.setup)

    wfn = setup.simulate_wavefunction()

    print("Photonic Wavefunction = ", wfn)
    print("Qubit Wavefunction = ", wfn.state)

示例#8
0
def test_332(silent=False):
    # Qubit Wavefunction for the expeced state:
    # In 3 Paths with -1 0 +1 mode, each mode with 2 qubits
    # Paths are constructed as
    # A(-1 0 1) B(-1 0 1) C(-1 0 1)
    # |XXXXXX|XXXXXX|XXXXXX>
    # The 332 State in Photonic Notation (one photon in each mode noted as |abc> where a = occupied mode in path a)
    # |state> = |1 -1 1> + |0 0 0> + |-1 1 1>
    # 332 State in Qudit notation
    # |state> = |0 0 1>_a|1 0 0>_b|0 0 1>_c
    #          +|0 1 0>_a|0 1 0>_b|0 1 0>_c
    #          +|1 0 0>_a|0 0 1>_b|0 0 1>_c
    # The 332 State for 2-Qubits per mode is
    #        |state>= | 00 00 01 | 01 00 00 | 00 00 01 >
    #                +| 00 01 00 | 00 01 00 | 00 01 00 >
    #                +| 01 00 00 | 00 00 01 | 00 00 01 >

    def make_332_state_vector(S, paths) -> PhotonicStateVector:
        """
        Normalized 332 State vector
        :param S: Spin number ( Modes will be -S ... 0 ... +S)
        :return: 332 State in 2S+1 modes
        """
        def one_photon_path(occ_mode: int) -> str:
            key = S + occ_mode
            tmp = ["0"] * (2 * S + 1)
            tmp[key] = "1"
            return "".join(tmp)

        def term(a: int, b: int, c: int, coeff: float = 1.0 / sqrt(3)) -> str:
            return "+" + str(coeff) + "|" + one_photon_path(
                occ_mode=a) + ">_a|" + one_photon_path(
                    occ_mode=b) + ">_b|" + one_photon_path(occ_mode=c) + ">_c"

        return PhotonicStateVector.from_string(paths=paths,
                                               string=term(-1, 1, -1) +
                                               term(0, 0, 0) + term(-1, -1, 1))

    for S in [1, 2]:
        for qpm in [1, 2]:

            # path_a = dict()
            # path_b = dict()
            # path_c = dict()
            # qubit_counter = 0
            #
            # for path in [path_a, path_b, path_c]:
            #     for m in range(-S, S+1, 1):
            #         path[m] = PhotonicMode(qubits=[q for q in range(qubit_counter, qubit_counter + n_qubits_per_mode)],
            #                                name=str(m))
            #         qubit_counter = qubit_counter + n_qubits_per_mode

            setup = PhotonicSetup(pathnames=['a', 'b', 'c'], S=S, qpm=qpm)
            paths = setup.paths

            expected = make_332_state_vector(S=S, paths=paths)
            setup.prepare_332_state(path_a='a', path_b='b', path_c='c')

            if not silent:
                print(setup.setup)
                print("Paths:\n", paths)

            end = setup.simulate_wavefunction()

            if not silent:
                print("S       =", S)
                print("q per m =", qpm)
                print("end     =", end)
                print("expected=", expected)
            assert (end == expected)
示例#9
0
"""
# If you want to change S and qpm you need to think about new encodings for the P1 projector
S = 1  # Can not be changed for this example. Hamiltonians are wrong otherwise
qpm = 1  # Can not be changed for this example. Hamiltonians are wrong otherwise
trotter_steps = 1  # number of trotter steps for the BeamSplitter (for S=1 and qpm=1, one trotter step is fine)

if __name__ == "__main__":

    param_dove = tq.Variable(
        name="t"
    )  # the dove prism is already defined in units of pi within PhotonicSetup
    angle0 = tq.numpy.pi * tq.Variable(name="angle0")  # angles in units of pi
    angle1 = tq.numpy.pi * tq.Variable(name="angle1")  # angles in units of pi

    # Use the PhotonicSetup helper class to initialize the mapped parametrized photonic setup
    setup = PhotonicSetup(pathnames=['a', 'b', 'c', 'd'], S=S, qpm=qpm)
    setup.prepare_SPDC_state(path_a='a', path_b='b')
    setup.prepare_SPDC_state(path_a='c', path_b='d')
    setup.add_beamsplitter(path_a='b', path_b='c', t=0.25, steps=trotter_steps)
    setup.add_doveprism(path='c', t=param_dove)
    setup.add_beamsplitter(path_a='b', path_b='c', t=0.25, steps=trotter_steps)
    setup.add_parametrized_one_photon_projector(path='a',
                                                angles=[angle0, angle1])

    # this is the mapped photonic setup
    U_pre = setup.setup

    # now we will add the optimization parts which are only done on the digital quantum computer
    setup = PhotonicSetup(pathnames=['a', 'b', 'c', 'd'], S=S, qpm=qpm)
    # we have included the 332 state preparation on the digital machine into the PhotonicSetup class
    # for convenience
示例#10
0
from photonic import PhotonicSetup, PhotonicStateVector
import tequila as tq

if __name__ == "__main__":
    """
    Set The Parameters here:
    """
    S = 0  # Modes will run from -S ... 0 ... +S
    qpm = 2  # Qubits per mode
    initial_state = "|1>_a|1>_b"  # Notation has to be consistent with your S
    trotter_steps = 20  # number of trotter steps for the BeamSplitter
    samples = 1000  # number of samples to simulate
    simulator = None  # Pick the Simulator (None -> let tequila do it)
    t = 0.25  # beam-splitter parameter

    setup = PhotonicSetup(pathnames=['a', 'b'], S=S, qpm=qpm)

    # the beam splitter is parametrized as phi=i*pi*t
    setup.add_beamsplitter(path_a='a', path_b='b', t=t, steps=trotter_steps)

    # need explicit circuit for initial state
    state = setup.initialize_state(state=initial_state)
    # can only do product states right now, alltough more general ones are possible
    # with code adaption
    Ui = tq.QCircuit()
    assert (len(state.state) == 1)
    key = [k for k in state.state.keys()][0]
    for i, q in enumerate(key.array):
        if q == 1:
            Ui += tq.gates.X(target=i)