1
$\begingroup$

In Stim, is it possible to compute the inner product $\langle\phi|\psi\rangle$ of two stabiliser states $|\phi\rangle$ and $|\psi\rangle$? It seems like this should be possible, since an algorithm to do this using the tableaus of these states is presented at the end of section III of Ref [1], but I have not been able to find a way in the Stim documentation.

Also, is it possible to compute the inner product/partial contraction over a restricted subset of qubits? For example, for a system with four qubits and states $|\phi\rangle=\frac{1}{\sqrt{2}}(\mathrm{i}|0\rangle_1|0\rangle_2+|1\rangle_1|0\rangle_2)$ and $|\psi\rangle=|0\rangle_1|0\rangle_2|1\rangle_3|0\rangle_4$ the inner product would be $$ \langle\phi|\psi\rangle=\frac{1}{\sqrt{2}}(-\mathrm{i}\langle0|_1\langle 0|_2+\langle 1|_1\langle 0|_2)|0\rangle_1|0\rangle_2|1\rangle_3|0\rangle_4 = -\frac{\mathrm{i}}{\sqrt{2}} |1\rangle_3|0\rangle_4, $$ which lives in the Hilbert space of dimension $2^2$ spanned by the third and fourth qubits. (Another way to phrase this would be as the action of the operator $\mathcal{O}=\langle\phi|\otimes \text{Id}$ on $|\psi\rangle$, where $\text{Id}$ is the identity operator on qubits 3 and 4.)


[1] Improved Simulation of Stabilizer Circuits, S. Aaronson, D. Gottesman, Phys. Rev. A 70, 052328 (2004)

$\endgroup$
2
  • $\begingroup$ Wow, they really changed the built-in "duplicate question" auto comment to be a lot more accusatory rather than "does [link] answer your question". $\endgroup$ Commented Jul 8, 2024 at 22:24
  • $\begingroup$ Thanks! This definitely answers the first part of my question. I don't think it resolves the second part though, as the result of a partial inner product is not a tableau state in general (e.g. in my example the state is not correctly normalised). Is there any way to deal with this issue? $\endgroup$ Commented Jul 10, 2024 at 6:44

1 Answer 1

1
+100
$\begingroup$

To get the partial overlap, run a circuit that maps the smaller state to $|0\rangle$ and then postselect on the Z axis of the qubits of the smaller state. Peek at expectations to determine overlap, and the remaining state will be in the upper qubits.

from typing import Optional, Tuple import numpy as np import stim def partial_postselection(state: stim.Tableau, target: stim.Tableau) -> Tuple[float, Optional[stim.Tableau]]: sim = stim.TableauSimulator() sim.set_inverse_tableau(state**-1) sim.do_tableau(target**-1, targets=range(len(target))) coin_flips = 0 for k in range(len(target)): z = sim.peek_z(k) if z == -1: return 0, None if z == 0: coin_flips += 1 sim.postselect_z(k, desired_value=False) d = len(state) - len(target) for k in range(d): sim.swap(k, len(target) + k) sim.set_num_qubits(d) return 2**-coin_flips, sim.current_inverse_tableau()**-1 

Testing it by comparing with einsum on the state vectors:

def test_fuzz(): for _ in range(1000): n1 = 5 n2 = 2 state = stim.Tableau.random(n1) target = stim.Tableau.random(n2) overlap, conditioned_state = partial_postselection(state, target) actual_state = conditioned_state.to_state_vector(endian='big') if overlap > 0 else None actual_overlap = overlap state_vector = state.to_state_vector(endian='big').reshape(2**n2, 2**(n1 - n2)) target_vector = target.to_state_vector(endian='big') expected_state = np.einsum("ij,i->j", state_vector, np.conj(target_vector)) expected_overlap = np.linalg.norm(expected_state, 2) if expected_overlap < 1e-10: assert actual_state is None else: expected_state /= expected_overlap expected_overlap **= 2 np.testing.assert_allclose(actual_overlap, expected_overlap, atol=1e-6, rtol=1e-5) fidelity = abs(np.dot(actual_state, np.conj(expected_state))) np.testing.assert_allclose(1, fidelity, atol=1e-6, rtol=1e-5) 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.