class_docstr: Test tensor sample values.
class_docstr_tok: ["Test","tensor","sample","values","."]
docstr: Test that a tensor product involving qml.Projector works correctly
code: def test_projector(
      self, device, tol, skip_if
  ):  # pylint: disable=too-many-statements
      """Test that a tensor product involving qml.Projector works correctly"""
      n_wires = 3
      dev = device(n_wires)
  
      if dev.shots is None:
          pytest.skip(
              "Device is in analytic mode, cannot test sampling."
          )
  
      if "Projector" not in dev.observables:
          pytest.skip(
              "Skipped because device does not support the Projector observable."
          )
  
      skip_if(dev, {"supports_tensor_observables": False})
  
      theta = 1.432
      phi = 1.123
      varphi = -0.543
  
      @qml.qnode(dev)
      def circuit(state):
          qml.RX(theta, wires=[0])
          qml.RX(phi, wires=[1])
          qml.RX(varphi, wires=[2])
          qml.CNOT(wires=[0, 1])
          qml.CNOT(wires=[1, 2])
          return qml.sample(
              qml.PauliZ(wires=[0]) @ qml.Projector(state, wires=[1, 2])
          )
  
      res_basis = circuit([0, 0]).flatten()
      res_state = circuit([1, 0, 0, 0]).flatten()
      expected_mean = (
          np.cos(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2)
      ) ** 2 - (
          np.cos(varphi / 2) * np.sin(phi / 2) * np.sin(theta / 2)
      ) ** 2
      expected_var = (
          (np.cos(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2))
          ** 2
          + (np.cos(varphi / 2) * np.sin(phi / 2) * np.sin(theta / 2))
          ** 2
          - (
              (np.cos(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2))
              ** 2
              - (
                  np.cos(varphi / 2)
                  * np.sin(phi / 2)
                  * np.sin(theta / 2)
              )
              ** 2
          )
          ** 2
      )
      # res should only contain the eigenvalues of the projector matrix tensor product Z, i.e. {-1, 0, 1}
      assert np.allclose(
          sorted(np.unique(res_basis)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          sorted(np.unique(res_state)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_basis), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_state), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_basis), expected_var, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_state), expected_var, atol=tol(False)
      )
  
      res_basis = circuit([0, 1]).flatten()
      res_state = circuit([0, 1, 0, 0]).flatten()
      expected_mean = (
          np.sin(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2)
      ) ** 2 - (
          np.sin(varphi / 2) * np.sin(phi / 2) * np.sin(theta / 2)
      ) ** 2
      expected_var = (
          (np.sin(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2))
          ** 2
          + (np.sin(varphi / 2) * np.sin(phi / 2) * np.sin(theta / 2))
          ** 2
          - (
              (np.sin(varphi / 2) * np.cos(phi / 2) * np.cos(theta / 2))
              ** 2
              - (
                  np.sin(varphi / 2)
                  * np.sin(phi / 2)
                  * np.sin(theta / 2)
              )
              ** 2
          )
          ** 2
      )
      assert np.allclose(
          sorted(np.unique(res_basis)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          sorted(np.unique(res_state)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_basis), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_state), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_basis), expected_var, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_state), expected_var, atol=tol(False)
      )
  
      res_basis = circuit([1, 0]).flatten()
      res_state = circuit([0, 0, 1, 0]).flatten()
      expected_mean = (
          np.sin(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2)
      ) ** 2 - (
          np.sin(varphi / 2) * np.cos(phi / 2) * np.sin(theta / 2)
      ) ** 2
      expected_var = (
          (np.sin(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2))
          ** 2
          + (np.sin(varphi / 2) * np.cos(phi / 2) * np.sin(theta / 2))
          ** 2
          - (
              (np.sin(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2))
              ** 2
              - (
                  np.sin(varphi / 2)
                  * np.cos(phi / 2)
                  * np.sin(theta / 2)
              )
              ** 2
          )
          ** 2
      )
      assert np.allclose(
          sorted(np.unique(res_basis)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          sorted(np.unique(res_state)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_basis), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_state), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_basis), expected_var, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_state), expected_var, atol=tol(False)
      )
  
      res_basis = circuit([1, 1]).flatten()
      res_state = circuit([0, 0, 0, 1]).flatten()
      expected_mean = (
          np.cos(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2)
      ) ** 2 - (
          np.cos(varphi / 2) * np.cos(phi / 2) * np.sin(theta / 2)
      ) ** 2
      expected_var = (
          (np.cos(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2))
          ** 2
          + (np.cos(varphi / 2) * np.cos(phi / 2) * np.sin(theta / 2))
          ** 2
          - (
              (np.cos(varphi / 2) * np.sin(phi / 2) * np.cos(theta / 2))
              ** 2
              - (
                  np.cos(varphi / 2)
                  * np.cos(phi / 2)
                  * np.sin(theta / 2)
              )
              ** 2
          )
          ** 2
      )
      assert np.allclose(
          sorted(np.unique(res_basis)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          sorted(np.unique(res_state)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_basis), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.mean(res_state), expected_mean, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_basis), expected_var, atol=tol(False)
      )
      assert np.allclose(
          np.var(res_state), expected_var, atol=tol(False)
      )
  
      res = circuit(np.array([1, 0, 0, 1]) / np.sqrt(2))
      expected_mean = 0.5 * (
          (np.cos(theta / 2) * np.cos(phi / 2) * np.cos(varphi / 2))
          ** 2
          + (np.cos(theta / 2) * np.sin(phi / 2) * np.cos(varphi / 2))
          ** 2
          - (np.sin(theta / 2) * np.sin(phi / 2) * np.cos(varphi / 2))
          ** 2
          - (np.sin(theta / 2) * np.cos(phi / 2) * np.cos(varphi / 2))
          ** 2
      )
      expected_var = (
          0.5
          * (
              (np.cos(theta / 2) * np.cos(phi / 2) * np.cos(varphi / 2))
              ** 2
              + (
                  np.cos(theta / 2)
                  * np.sin(phi / 2)
                  * np.cos(varphi / 2)
              )
              ** 2
              + (
                  np.sin(theta / 2)
                  * np.sin(phi / 2)
                  * np.cos(varphi / 2)
              )
              ** 2
              + (
                  np.sin(theta / 2)
                  * np.cos(phi / 2)
                  * np.cos(varphi / 2)
              )
              ** 2
          )
          - expected_mean**2
      )
      assert np.allclose(
          sorted(np.unique(res)), [-1, 0, 1], atol=tol(False)
      )
      assert np.allclose(np.mean(res), expected_mean, atol=tol(False))
      assert np.allclose(np.var(res), expected_var, atol=tol(False))
  
imports: import pytest
  from flaky import flaky
  from scipy.sparse import csr_matrix
  import pennylane
  from pennylane import numpy
  from pennylane.measurements import ClassicalShadowMP, MeasurementTransform, SampleMeasurement, SampleMP, StateMeasurement, StateMP
label_desc: Use image node_id 4 for calling the TestTensorSample obj's underlying member method code with example usage: obj.test_projector(device, tol, skip_if) and returns: qml