.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/measurement_devices/example_001_number_detector.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_measurement_devices_example_001_number_detector.py: Number Detector Example ======================= This example demonstrates the use of the :class:`~symop.devices.models.detectors.number_detector.NumberDetector`. We show three related measurement concepts: 1. **Observation** returns the full outcome distribution for a measurement without selecting a particular branch. 2. **Detection** samples one concrete measurement outcome and returns the corresponding post-measurement state. 3. **Postselection** conditions the state on a chosen measurement outcome. The example first measures a simple product input state and then repeats the observation/detection process after interference on a 50/50 beam splitter. For a number detector, the outcomes correspond to the possible photon numbers detected in the measured path. .. GENERATED FROM PYTHON SOURCE LINES 28-42 .. code-block:: Python from __future__ import annotations import numpy as np from symop.devices.models.beamsplitters.beamsplitter import BeamSplitter from symop.devices.models.detectors.number_detector import NumberDetector from symop.devices.models.sources.number_state_source import NumberStateSource from symop.modes.envelopes.gaussian import GaussianEnvelope from symop.modes.labels.path import Path from symop.modes.labels.polarization import Polarization from symop.polynomial.state.ket import KetPolyState import symop.viz as VI .. GENERATED FROM PYTHON SOURCE LINES 43-50 **Setup** Create a two-photon source and a number detector. The source emits photons into a path with a Gaussian spectral envelope and horizontal polarization. Since ``n=2``, each source prepares a two-photon excitation in its output mode. .. GENERATED FROM PYTHON SOURCE LINES 50-60 .. code-block:: Python src = NumberStateSource( envelope=GaussianEnvelope(omega0=100.0, sigma=50.0, tau=0.0), polarization=Polarization.H(), n=2, ) det = NumberDetector() .. GENERATED FROM PYTHON SOURCE LINES 61-66 **Generate the input state** Start from vacuum and populate two distinct paths with identical two-photon states. The joint state therefore contains a total of four photons, distributed across two input paths. .. GENERATED FROM PYTHON SOURCE LINES 66-75 .. code-block:: Python vac = KetPolyState.vacuum() state_a = src(vac, ports={"out": Path("src_out")}).with_label("in") state_b = src(vac, ports={"out": Path("src_out_aux")}).with_label("in_aux") state = state_a.join(state_b).with_label("joint") VI.display(state) .. raw:: html
2026-04-24T11:36:47.267831 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 76-85 **Observe the measurement** Observation is a non-destructive query. It does not collapse the state. Instead, it returns the full probability distribution over all possible detector outcomes for the selected path. Here the detector measures the path ``src_out``. Since the total state contains four photons, the possible number outcomes are determined by how many photons can be found in that path. .. GENERATED FROM PYTHON SOURCE LINES 85-89 .. code-block:: Python observation = det.observe(state=state, ports={"in": Path("src_out")}) VI.display(observation) .. raw:: html
2026-04-24T11:36:47.325109 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 90-95 **Detect** Detection represents one concrete realization of the measurement. It returns a sampled outcome together with the corresponding post-measurement state. .. GENERATED FROM PYTHON SOURCE LINES 95-99 .. code-block:: Python detection = det.detect(state=state, ports={"in": Path("src_out")}) VI.display(detection) .. raw:: html
2026-04-24T11:36:47.400589 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 100-103 **Post-measurement state after detection** This is the collapsed state associated with the sampled detection event. .. GENERATED FROM PYTHON SOURCE LINES 103-106 .. code-block:: Python VI.display(detection.state) .. raw:: html
2026-04-24T11:36:47.502589 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 107-112 **Postselection** Postselection conditions the original state on a chosen outcome. In this case we reuse the outcome sampled above and explicitly build the corresponding conditional branch. .. GENERATED FROM PYTHON SOURCE LINES 112-120 .. code-block:: Python postselection = det.postselect( state=state, ports={"in": Path("src_out")}, outcome=detection.outcome, ) VI.display(postselection) .. raw:: html
2026-04-24T11:36:47.600971 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 121-124 **Postselected state** This is the state conditioned on the selected outcome. .. GENERATED FROM PYTHON SOURCE LINES 124-127 .. code-block:: Python VI.display(postselection.state) .. raw:: html
2026-04-24T11:36:47.706662 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 128-133 **Interfere the input state on a beam splitter** Next, we interfere the two input paths on a 50/50 beam splitter. Interference changes the amplitudes and therefore changes the measurement probabilities at the output ports. .. GENERATED FROM PYTHON SOURCE LINES 133-148 .. code-block:: Python bs = BeamSplitter(theta=np.pi / 4) state_interfered = bs( state, ports={ "in0": Path("src_out"), "in1": Path("src_out_aux"), "out0": Path("bs_out0"), "out1": Path("bs_out1"), }, ).with_label("interfered") VI.display(state_interfered) .. raw:: html
2026-04-24T11:36:48.104933 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 149-155 **Observe the output distribution after interference** We now observe the photon-number distribution in one beam-splitter output path. The set of possible outcomes is still determined by the allowed photon numbers in that path, but the probabilities are changed by interference. .. GENERATED FROM PYTHON SOURCE LINES 155-162 .. code-block:: Python interfered_observation = det.observe( state=state_interfered, ports={"in": Path("bs_out0")}, ) VI.display(interfered_observation) .. raw:: html
2026-04-24T11:36:48.614218 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 163-164 Quick Plot .. GENERATED FROM PYTHON SOURCE LINES 164-166 .. code-block:: Python VI.plot(interfered_observation) .. image-sg:: /examples/measurement_devices/images/sphx_glr_example_001_number_detector_001.png :alt: $\mathrm{Observation}\left(\mathrm{outcomes}=3,\ \mathbb{E}=1.9999999999999991\right)$ :srcset: /examples/measurement_devices/images/sphx_glr_example_001_number_detector_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none (
, ) .. GENERATED FROM PYTHON SOURCE LINES 167-171 **Detect one output event after interference** As before, detection returns one concrete sampled outcome and the corresponding collapsed branch. .. GENERATED FROM PYTHON SOURCE LINES 171-178 .. code-block:: Python interfered_detection = det.detect( state=state_interfered, ports={"in": Path("bs_out0")}, ) VI.display(interfered_detection) .. raw:: html
2026-04-24T11:36:48.859959 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. GENERATED FROM PYTHON SOURCE LINES 179-180 **Post-measurement state after interfered detection** .. GENERATED FROM PYTHON SOURCE LINES 180-181 .. code-block:: Python VI.display(interfered_detection.state) .. raw:: html
2026-04-24T11:36:49.002374 image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/


.. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.830 seconds) .. _sphx_glr_download_examples_measurement_devices_example_001_number_detector.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_001_number_detector.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_001_number_detector.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_001_number_detector.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_