{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "db39f5fc", "metadata": {}, "source": [ "# Correlated Distributions" ] }, { "attachments": {}, "cell_type": "markdown", "id": "befae02b", "metadata": {}, "source": [ "Occasionally, you may want to randomize multiple variables subject to some\n", "specific constraints.\n", "\n", "* When randomizing physics parameters, you may want `V_L` and `V_R`\n", "to be randomized subject to the constraint that `V_L == -V_R`.\n", "\n", "* When adding noise, you may want to randomize the strengths of two\n", "different noise types, such that their sum is always a certain value.\n", "\n", "This can be accomplished through any of the `CorrelatedDistribution` classes\n", "provided with QDFlow, or by creating a custom `CorrelatedDistribution`." ] }, { "cell_type": "code", "execution_count": 1, "id": "93d349a5", "metadata": {}, "outputs": [], "source": [ "from qdflow.util import distribution\n", "import numpy as np\n", "from qdflow import generate" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ca7da85b", "metadata": {}, "source": [ "A `CorrelatedDistribution` is essentially a multivariate distribution, where\n", "the variables are correlated in some way. A single draw from a\n", "`CorrelatedDistribution` will return an array of length `num_variables`.\n", "\n", "The simplest `CorrelatedDistribution` included in QDFlow is `FullyCorrelated`,\n", "which simply returns a number of copies of the same value." ] }, { "cell_type": "code", "execution_count": 2, "id": "76aa0be5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Single sample: [25.26557877 25.26557877 25.26557877 25.26557877 25.26557877]\n", "Multiple samples:\n", " [[28.88245652 28.88245652 28.88245652 28.88245652 28.88245652]\n", " [ 7.23354081 7.23354081 7.23354081 7.23354081 7.23354081]\n", " [19.31017469 19.31017469 19.31017469 19.31017469 19.31017469]]\n" ] } ], "source": [ "dist_single = distribution.Normal(20, 5) # A single-variable distribution\n", "\n", "# A correlated distribution that returns 5 copies of the same value\n", "num_variables = 5\n", "corr_dist = distribution.FullyCorrelated(dist_single, num_variables)\n", "\n", "rng = np.random.default_rng(seed=6)\n", "\n", "# Draw a single sample of each of the 5 variables\n", "single_sample = corr_dist.draw(rng)\n", "print(\"Single sample: \", single_sample)\n", "\n", "# Draw multiple samples of each variable\n", "num_samples = 3\n", "samples = corr_dist.draw(rng, size=num_samples)\n", "print(\"Multiple samples:\\n\", samples)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4cd2df78", "metadata": {}, "source": [ "When performing randomization, QDFlow expects each field in the randomization\n", "class to be given a seperate distribution.\n", "\n", "Distributions for each of the individual variables can be obtained from a\n", "`CorrelatedDistribution` via the `dependent_distributions()` method." ] }, { "cell_type": "code", "execution_count": 3, "id": "b7ae7512", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sample 1: 0.0012301533574825742\n", "Sample 2: 0.0012301533574825742\n" ] } ], "source": [ "# Create a correlated distribution with 2 variables\n", "dist_single = distribution.Normal(0, 1)\n", "num_variables = 2\n", "corr_dist = distribution.FullyCorrelated(dist_single, num_variables)\n", "\n", "# Obtain a list [dist_1, dist_2] of the individual distributions for each variable\n", "individual_dists = corr_dist.dependent_distributions()\n", "dist_1, dist_2 = individual_dists\n", "\n", "rng = np.random.default_rng(seed=7)\n", "\n", "# Draw a single sample from one of the individual distributions\n", "sample_1 = dist_1.draw(rng)\n", "print(\"Sample 1: \", sample_1)\n", "\n", "# Now draw a sample from the other individual distribution\n", "sample_2 = dist_2.draw(rng)\n", "print(\"Sample 2: \", sample_2)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "deab0de1", "metadata": {}, "source": [ "These individual distributions can then be used to specify how physics\n", "parameters should be randomized." ] }, { "cell_type": "code", "execution_count": 4, "id": "736bd555", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "V_L: -0.37779439216921556\n", "V_R: 0.37779439216921556\n" ] } ], "source": [ "# Create a randomization object with default distributions for each parameter\n", "phys_rand = generate.PhysicsRandomization.default()\n", "\n", "# Set V_L and V_R distributions such that they will always be negative of each other.\n", "phys_rand.V_L = 2 * dist_1\n", "phys_rand.V_R = -2 * dist_2\n", "\n", "# Generate a randomized set of physics parameters\n", "generate.set_rng_seed(8)\n", "n_devices = 6\n", "phys_params = generate.random_physics(phys_rand, n_devices)\n", "print(\"V_L: \", phys_params[0].V_L)\n", "print(\"V_R: \", phys_params[0].V_R)" ] } ], "metadata": { "kernelspec": { "display_name": "qdflow_venv", "language": "python", "name": "qdflow_venv" }, "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.12.2" } }, "nbformat": 4, "nbformat_minor": 5 }