Skip to content

Commit

Permalink
add D_s gate (#368)
Browse files Browse the repository at this point in the history
**Context:** Add the ABC triples for the s-parameterized Dgate in order
to change the basis of any Gaussian state from Bargmann into
characteristic function.

**Description of the Change:** Add a new helper function "Zmat" in math,
add a new ABC triples for D_s gate, and add corresponding tests.

TODO: use this gate to add the to_characteristic() function for states.

**Benefits:**

**Possible Drawbacks:**

**Related GitHub Issues:**

---------

Co-authored-by: SamFerracin <[email protected]>
Co-authored-by: Filippo Miatto <[email protected]>
  • Loading branch information
3 people authored Mar 26, 2024
1 parent 71995a7 commit 6d66a52
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
### New features
* Added a function ``to_fock`` to map different representations into Fock representation.
[(#355)](https://github.com/XanaduAI/MrMustard/pull/355)

* Added a new Abc triple for s-parametrized displacement gate.
[(#368)](https://github.com/XanaduAI/MrMustard/pull/368)

### Breaking changes

Expand Down
15 changes: 15 additions & 0 deletions mrmustard/math/backend_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,21 @@ def Xmat(num_modes: int):
O = np.zeros((num_modes, num_modes))
return np.block([[O, I], [I, O]])

@staticmethod
@lru_cache()
def Zmat(num_modes: int):
r"""The matrix :math:`Z_n = \begin{bmatrix}I_n & 0\\ 0 & -I_n\end{bmatrix}.`
Args:
num_modes: A positive integer representing the number of modes.
Returns:
The :math:`2N\times 2N` array
"""
I = np.identity(num_modes)
O = np.zeros((num_modes, num_modes))
return np.block([[I, O], [O, -I]])

@staticmethod
@lru_cache()
def rotmat(num_modes: int):
Expand Down
31 changes: 31 additions & 0 deletions mrmustard/physics/triples.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,34 @@ def fock_damping_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar]:
c = 1.0 + 0j

return A, b, c


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Maps between representations
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


def displacement_map_s_parametrized_Abc(s: int) -> Union[Matrix, Vector, Scalar]:
r"""
The ``(A, b, c)`` triple of a single-mode ``s``\-parametrized dispalcement map :math:`D(\gamma)`.
Given the complex variables for this single-mode is :math:`(z^*, z)` corresponding to [out_ket, in_ket] unitary ordering,
the indices of the final triple correspond to the variables :math:`(\gamma^*, z^*, \gamma, z)` of the Bargmann function of the s-parametrized displacement map, and correspond to ``out_bra, in_bra, out_ket, in_ket`` wires.
Args:
s: the parametrization related to the ordering of creation and annihilation operators in the expression of any operator. :math:`s=0` is the "symmetric" ordering, which is symmetric under the exchange of creation and annihilation operators, :math:`s=-1` is the "normal" ordering, where all the creation operators are on the left and all the annihilation operators are on the right, and :math:`s=1` is the "anti-normal" ordering, which is the vice versa of the normal ordering. By using s-parametrized displacement map to generate the s-parametrized characteristic function :math:`\chi_s = Tr[\rho D_s]`, and then by doing the complex fourier transform, we get the s-parametrized quasi-probaility distribution: :math:`s=0` is the Wigner distribution, :math:`s=-1` is the Husimi Q distribution, and :math:`s=1` is the Glauber P distribution.
Returns:
The ``(A, b, c)`` triple of the single-mode ``s``-parametrized dispalcement map :math:`D_s(\gamma)`.
"""
A = math.block(
[
[(s - 1) / 2 * math.Xmat(num_modes=1), -math.Zmat(num_modes=1)],
[-math.Zmat(num_modes=1), math.Xmat(num_modes=1)],
]
)
A = A[[0, 2, 1, 3], :][
:, [0, 2, 1, 3]
] # Change the order of this map into the normal ordering as a single mode channel
b = _vacuum_B_vector(4)
c = 1.0 + 0j
return A, b, c
20 changes: 20 additions & 0 deletions tests/test_physics/test_triples.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,23 @@ def test_fock_damping_Abc(self, n_modes):
assert math.allclose(A1, np.kron(math.astensor([[0, 1], [1, 0]]), math.eye(2 * n_modes)))
assert math.allclose(b1, np.zeros((4 * n_modes)))
assert math.allclose(c1, 1)

def test_displacement_gate_s_parametrized_Abc(self):
A1, b1, c1 = triples.displacement_map_s_parametrized_Abc(0)
A1_correct = np.array([[0, -0.5, -1, 0], [-0.5, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]])
assert math.allclose(A1, A1_correct[[0, 2, 1, 3], :][:, [0, 2, 1, 3]])
print(b1.shape)
assert math.allclose(b1, np.zeros(4))
assert math.allclose(c1, 1)

A2, b2, c2 = triples.displacement_map_s_parametrized_Abc(1)
A2_correct = np.array([[0, 0, -1, 0], [0, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]])
assert math.allclose(A2, A2_correct[[0, 2, 1, 3], :][:, [0, 2, 1, 3]])
assert math.allclose(b2, np.zeros(4))
assert math.allclose(c2, 1)

A3, b3, c3 = triples.displacement_map_s_parametrized_Abc(-1)
A3_correct = np.array([[0, -1, -1, 0], [-1, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]])
assert math.allclose(A3, A3_correct[[0, 2, 1, 3], :][:, [0, 2, 1, 3]])
assert math.allclose(b3, np.zeros(4))
assert math.allclose(c3, 1)

0 comments on commit 6d66a52

Please sign in to comment.