Skip to content

photon_unitary

qoptcraft.evolution.photon_unitary

photon_unitary(scattering_matrix, photons, method='permanent glynn')

Unitary matrix of a linear interferometer with a number of photons as input.

Parameters:

Name Type Description Default
scattering_matrix NDArray

scattering matrix of a linear optical interferometer.

required
photons int

number of photons.

required
method str

method to calculate the multiphoton unitary. Options are 'heisenberg', 'hamiltonian', 'permanent glynn' or 'permanent ryser'. Default is 'permanent glynn'.

'permanent glynn'

Returns:

Name Type Description
NDArray NDArray

image of the scattering matrix through the photonic homomorphism.

Source code in qoptcraft/evolution/photon_unitary.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def photon_unitary(
    scattering_matrix: NDArray,
    photons: int,
    method: Literal[
        "heisenberg", "hamiltonian", "permanent glynn", "permanent ryser"
    ] = "permanent glynn",
) -> NDArray:
    """Unitary matrix of a linear interferometer with a number of photons as input.

    Args:
        scattering_matrix (NDArray): scattering matrix of a linear optical interferometer.
        photons (int): number of photons.
        method (str): method to calculate the multiphoton unitary. Options are 'heisenberg',
            'hamiltonian', 'permanent glynn' or 'permanent ryser'. Default is 'permanent glynn'.

    Returns:
        NDArray: image of the scattering matrix through the photonic homomorphism.
    """
    if method.split()[0] == "permanent":
        return photon_unitary_permanent(scattering_matrix, photons, method=method.split()[1])
    if method == "heisenberg":
        return photon_unitary_heisenberg(scattering_matrix, photons)
    if method == "hamiltonian":
        return photon_unitary_hamiltonian(scattering_matrix, photons)
    raise ValueError(
        "Options for method are 'heisenberg', 'hamiltonian', 'permanent glynn' or 'permanent ryser'"
    )

photon_unitary_hamiltonian(scattering_matrix, photons)

"Unitary matrix of a linear interferometer with a number of photons as input. Calculated by evolving the hamiltonian of the interferometer.

Parameters:

Name Type Description Default
scattering_matrix NDArray

scattering matrix of a linear optical interferometer.

required
photons int

number of photons.

required

Returns:

Name Type Description
NDArray NDArray

image of the scattering matrix through the photonic homomorphism.

Source code in qoptcraft/evolution/photon_unitary.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def photon_unitary_hamiltonian(scattering_matrix: NDArray, photons: int) -> NDArray:
    """ "Unitary matrix of a linear interferometer with a number of photons as input.
    Calculated by evolving the hamiltonian of the interferometer.

    Args:
        scattering_matrix (NDArray): scattering matrix of a linear optical interferometer.
        photons (int): number of photons.

    Returns:
        NDArray: image of the scattering matrix through the photonic homomorphism.
    """
    S_hamiltonian = log_matrix(scattering_matrix, method="schur")  # ? Best method??
    U_hamiltonian = photon_hamiltonian(S_hamiltonian, photons)
    return sp.linalg.expm(U_hamiltonian)

photon_unitary_heisenberg(scattering_matrix, photons)

Standard evolution given by quantum mechanics.

Parameters:

Name Type Description Default
scattering_matrix NDArray

scattering matrix of a linear optical interferometer.

required
photons int

number of photons.

required

Returns:

Name Type Description
NDArray NDArray

image of the scattering matrix through the photonic homomorphism.

Source code in qoptcraft/evolution/photon_unitary.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def photon_unitary_heisenberg(scattering_matrix: NDArray, photons: int) -> NDArray:
    """Standard evolution given by quantum mechanics.

    Args:
        scattering_matrix (NDArray): scattering matrix of a linear optical interferometer.
        photons (int): number of photons.

    Returns:
        NDArray: image of the scattering matrix through the photonic homomorphism.
    """
    modes = scattering_matrix.shape[0]
    dim = hilbert_dim(modes, photons)
    unitary = np.zeros((dim, dim), dtype=np.complex64)
    photon_basis = get_photon_basis(modes, photons)

    for col, fock_in in enumerate(photon_basis):
        unitary[:, col] = fock_evolution_heisenberg(scattering_matrix, fock_in).state_in_basis()
    return unitary

photon_unitary_permanent(scattering_matrix, photons, method='glynn')

Unitary matrix of a linear interferometer with a number of photons as input. Calculated using permanents:

= Per(U_ST) / sqrt(s1! ...sm! t1! ... tm!)

Parameters:

Name Type Description Default
scattering_matrix NDArray

scattering matrix of a linear optical interferometer.

required
photons int

number of photons.

required
method str

method to calculate the permanent. Options are 'glynn' and 'ryser'. Defaults to 'glynn'.

'glynn'

Returns:

Name Type Description
NDArray NDArray

image of the scattering matrix through the photonic homomorphism.

Source code in qoptcraft/evolution/photon_unitary.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def photon_unitary_permanent(
    scattering_matrix: NDArray, photons: int, method: str = "glynn"
) -> NDArray:
    """Unitary matrix of a linear interferometer with a number of photons as input.
    Calculated using permanents:

    <S|phi(U)|T> = Per(U_ST) / sqrt(s1! ...sm! t1! ... tm!)

    Args:
        scattering_matrix (NDArray): scattering matrix of a linear optical interferometer.
        photons (int): number of photons.
        method (str): method to calculate the permanent. Options are 'glynn' and 'ryser'.
            Defaults to 'glynn'.

    Returns:
        NDArray: image of the scattering matrix through the photonic homomorphism.
    """
    modes = scattering_matrix.shape[0]
    dim = hilbert_dim(modes, photons)
    unitary = np.empty((dim, dim), dtype=np.complex128)
    photon_basis = get_photon_basis(modes, photons)

    for col, fock_in in enumerate(photon_basis):
        unitary[:, col] = fock_evolution_permanent(scattering_matrix, fock_in, method, photon_basis)
    return unitary