diff --git a/docs/conf.py b/docs/conf.py index edfc53e9..913e76d8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,7 +19,7 @@ # -- Project information ----------------------------------------------------- project = "Piquasso" -copyright = "2021, Budapest Quantum Computing Group" +copyright = "2021-2022, Budapest Quantum Computing Group" author = "Budapest Quantum Computing Group" diff --git a/docs/index.rst b/docs/index.rst index 776dfddd..d294a7e8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,6 +26,7 @@ One could easily install Piquasso with the following command: tutorials/separating-programs tutorials/boson-sampling tutorials/gaussian-boson-sampling + tutorials/pure-fock-tensorflow .. toctree:: :maxdepth: 3 @@ -35,6 +36,7 @@ One could easily install Piquasso with the following command: simulators/gaussian simulators/fock simulators/sampling + simulators/tensorflow .. toctree:: :maxdepth: 3 diff --git a/docs/simulators/tensorflow.rst b/docs/simulators/tensorflow.rst new file mode 100644 index 00000000..d4d546a3 --- /dev/null +++ b/docs/simulators/tensorflow.rst @@ -0,0 +1,8 @@ +Simulators with Tensorflow support +================================== + +Pure Fock Simulator and Tensorflow +---------------------------------- + +.. automodule:: piquasso._backends.tensorflow.simulator.TensorflowPureFockSimulator + :members: \ No newline at end of file diff --git a/docs/tutorials/pure-fock-tensorflow.ipynb b/docs/tutorials/pure-fock-tensorflow.ipynb new file mode 100644 index 00000000..7675443b --- /dev/null +++ b/docs/tutorials/pure-fock-tensorflow.ipynb @@ -0,0 +1,91 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Pure Fock simulation with Tensorflow" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "import piquasso as pq\n", + "import tensorflow as tf\n", + "\n", + "\n", + "theta_1 = tf.Variable(np.pi / 3)\n", + "theta_2 = tf.Variable(np.pi / 5)\n", + "\n", + "simulator = pq.TensorflowPureFockSimulator(d=3, config=pq.Config(cutoff=3))\n", + "\n", + "with pq.Program() as program:\n", + " pq.Q(all) | pq.StateVector((1, 1, 0))\n", + "\n", + " pq.Q(0, 1) | pq.Beamsplitter(theta=theta_1)\n", + " pq.Q(1, 2) | pq.Beamsplitter(theta=theta_2)\n", + "\n", + "with tf.GradientTape() as tape:\n", + " state = simulator.execute(program).state\n", + "\n", + " fock_probabilities = state.fock_probabilities\n", + "\n", + "tape.jacobian(fock_probabilities, [theta_1, theta_2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.10 ('.venv': venv)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "c95ba34a4f298ecad799e828cf91aef0abbe7e47377270a3962202d638804a48" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/piquasso/_backends/fock/pure/simulator.py b/piquasso/_backends/fock/pure/simulator.py index 278140f5..b27d95da 100644 --- a/piquasso/_backends/fock/pure/simulator.py +++ b/piquasso/_backends/fock/pure/simulator.py @@ -69,7 +69,7 @@ class PureFockSimulator(Simulator): :class:`~piquasso.instructions.gates.Fourier`, :class:`~piquasso.instructions.gates.Kerr`, :class:`~piquasso.instructions.gates.CrossKerr`, - :class:`~piquasso.instructions.gates.CubicPhse`, + :class:`~piquasso.instructions.gates.CubicPhase`, :class:`~piquasso.instructions.gates.GaussianTransform`, :class:`~piquasso.instructions.gates.Squeezing`, :class:`~piquasso.instructions.gates.QuadraticPhase`, @@ -84,7 +84,7 @@ class PureFockSimulator(Simulator): :class:`~piquasso.instructions.measurements.ParticleNumberMeasurement`. Supported channels: - :class:`~piquasso.instructions.channels.Attenuator` + :class:`~piquasso.instructions.channels.Attenuator`. """ _state_class = PureFockState diff --git a/piquasso/_backends/tensorflow/simulator.py b/piquasso/_backends/tensorflow/simulator.py index ed9e77ab..9ad32b11 100644 --- a/piquasso/_backends/tensorflow/simulator.py +++ b/piquasso/_backends/tensorflow/simulator.py @@ -19,4 +19,71 @@ class TensorflowPureFockSimulator(PureFockSimulator): + """Performs photonic simulations using Fock representation with pure states. + + This simulator is similar to + :class:`~piquasso._backends.fock.pure.simulator.PureFockSimulator`, but it + calculates with Tensorflow to enable calculating the gradient. + + The simulation (when executed) results in an instance of + :class:`~piquasso._backends.fock.pure.state.PureFockState`. + + Note: + Non-deterministic operations like + :class:`~piquasso.instructions.measurements.ParticleNumberMeasurement` are + non-differentiable, please use a deterministic attribute of the resulting state + instead. + + Example usage:: + + import tensorflow as tf + + alpha = tf.Variable(0.43) + + simulator = pq.TensorflowPureFockSimulator(d=1) + + with pq.Program() as program: + pq.Q() | pq.Vacuum() + + pq.Q(0) | pq.Displacement(alpha=alpha) + + with tf.GradientTape() as tape: + state = simulator.execute(program).state + + mean = state.mean_photon_number() + + gradient = tape.gradient(mean, [alpha]) + + Supported preparations: + :class:`~piquasso.instructions.preparations.Vacuum`, + :class:`~piquasso.instructions.preparations.Create`, + :class:`~piquasso.instructions.preparations.Annihilate`, + :class:`~piquasso.instructions.preparations.StateVector`. + + Supported gates: + :class:`~piquasso.instructions.gates.Interferometer`, + :class:`~piquasso.instructions.gates.Beamsplitter`, + :class:`~piquasso.instructions.gates.Phaseshifter`, + :class:`~piquasso.instructions.gates.MachZehnder`, + :class:`~piquasso.instructions.gates.Fourier`, + :class:`~piquasso.instructions.gates.Kerr`, + :class:`~piquasso.instructions.gates.CrossKerr`, + :class:`~piquasso.instructions.gates.CubicPhase`, + :class:`~piquasso.instructions.gates.GaussianTransform`, + :class:`~piquasso.instructions.gates.Squeezing`, + :class:`~piquasso.instructions.gates.QuadraticPhase`, + :class:`~piquasso.instructions.gates.Squeezing2`, + :class:`~piquasso.instructions.gates.ControlledX`, + :class:`~piquasso.instructions.gates.ControlledZ`, + :class:`~piquasso.instructions.gates.Displacement`, + :class:`~piquasso.instructions.gates.PositionDisplacement`, + :class:`~piquasso.instructions.gates.MomentumDisplacement`. + + Supported measurements: + :class:`~piquasso.instructions.measurements.ParticleNumberMeasurement` (non-differentiable). + + Supported channels: + :class:`~piquasso.instructions.channels.Attenuator` (non-differentiable). + """ # noqa: E501 + _calculator_class = TensorflowCalculator