From ab4ece3dc0c31c0444065594edaa28f27c9f6f66 Mon Sep 17 00:00:00 2001
From: Philip Mueller <philip.paul.mueller@bluemain.ch>
Date: Thu, 22 Aug 2019 13:40:05 +0200
Subject: [PATCH] Updated the part about the usage of the condition.

---
 .../1_1_pyYggdrasilDemo_conditions.ipynb      | 424 ++++++++++++++++++
 1 file changed, 424 insertions(+)

diff --git a/code/examples_pyYggdrasil/notebooks/1_1_pyYggdrasilDemo_conditions.ipynb b/code/examples_pyYggdrasil/notebooks/1_1_pyYggdrasilDemo_conditions.ipynb
index f28b1381..07e25e5e 100644
--- a/code/examples_pyYggdrasil/notebooks/1_1_pyYggdrasilDemo_conditions.ipynb
+++ b/code/examples_pyYggdrasil/notebooks/1_1_pyYggdrasilDemo_conditions.ipynb
@@ -602,6 +602,430 @@
     "    print(\"Because their dimensions are not the same\")"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Restricted Samples\n",
+    "The conditions operates always on an underling sample space with a certain dimension, for the sake of argument consider this dimension to be $n$.\n",
+    "Further consider the case that there are $c$ conditions that are in place.\n",
+    "This means that only $n – c =: d$ many dimensions are free, where $d$ is the _degree of freedom_. \n",
+    "\n",
+    "This means when working in sch a setting it is enough to only consider samples of dimension $d$ instead of $n$ and this is a restricted sample.\n",
+    "From an implementation perspective a restricted sample is just a restricted sample, but it has a very different interpretation.\n",
+    "The first component of that sample is not the value of the sample in the first dimension of the underlying sample space, but the first free (no condition is in place) dimension of the sample space, the second component is the second free dimension and so on.\n",
+    "\n",
+    "This is can be very complex and confusing, thus we will make a small example.\n",
+    "\n",
+    "Note: In the remaining part we will use sample containers, which were not treated yet, it is recommended to skip the remaining part and return after you have studied the section about the containers.\n",
+    "\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we generate a sample container with tree samples of dimension 4."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The samples are:\n",
+      "0 -> (1, 2, 3, 4)\n",
+      "1 -> (5, 6, 7, 8)\n",
+      "2 -> (9, 10, 11, 12)\n"
+     ]
+    }
+   ],
+   "source": [
+    "rawSamples = pyY.SampleCollection(4)\n",
+    "rawSamples.addNewSample(pyY.Sample([1,  2,  3,  4]))\n",
+    "rawSamples.addNewSample(pyY.Sample([5,  6,  7,  8]))\n",
+    "rawSamples.addNewSample(pyY.Sample([9, 10, 11, 12]))\n",
+    "\n",
+    "print(\"The samples are:\")\n",
+    "for i in range(len(rawSamples)):\n",
+    "    print(\"{} -> {}\".format(i, rawSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### A First Condition\n",
+    "Now we will create a fist condition.\n",
+    "The condition will restrict the first and the second dimensions to $-1$ and $-2$ respectively."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#\n",
+    "# Create the condition, use the DICT method\n",
+    "c = dict()\n",
+    "c[0] = -1  # Zero based index\n",
+    "c[1] = -2\n",
+    "\n",
+    "# Create the condition object\n",
+    "fCondi = pyR.MultiCondition(4, c)  # 4 ~ Underling dimension\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Restriction\n",
+    "Now we will restrict the samples in the container.\n",
+    "Since we restrict the first two dimensions, the two last dimensions are not restricted and “free”.\n",
+    "We thus expect a container of dimension two with three samples.\n",
+    "The samples inside the container are $\\{(3, 4),\\, (7, 8),\\, (11, 12)\\}$.\n",
+    "The reason for that is because this is the content of the samples in the free dimensions.\n",
+    "\n",
+    "The container supports restriction on a single sample or on a full container of samples.\n",
+    "Note that due to the immutability of the dimension attribute of a sample container a new sample container is created and returned.\n",
+    "The container that is passed to the function is not modified.\n",
+    "\n",
+    "Note that the restriction does not alter the order of the samples inside the container.\n",
+    "Also the type of the container is not altered."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fResSamples = fCondi.restrictSample(rawSamples)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we will inspect the the restricted samples"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The restricted samples, with the first condition, are:\n",
+      "0 -> (3, 4)\n",
+      "1 -> (7, 8)\n",
+      "2 -> (11, 12)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"The restricted samples, with the first condition, are:\")\n",
+    "for i in range(len(fResSamples)):\n",
+    "    print(\"{} -> {}\".format(i, fResSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Expanding\n",
+    "It is also possible to expand the samples again.\n",
+    "Expanding is roughly the inverse operation to restricting, with some differences.\n",
+    "First of all it transforms a sample of dimension $d$ back to a sample to dimension $n$.\n",
+    "For restoring the free dimensions that value in the restricted sample is used.\n",
+    "For the value that we do not have the conditions are used.\n",
+    "\n",
+    "This is also the reason why expanding is _not_ the inversion of restricting.\n",
+    "Because the value in the restricted dimensions are not restored to their original value.\n",
+    "\n",
+    "Note that as the restriction operation the expanding function is forced to allocate a new container.\n",
+    "The container that is passed to it is not modified, and a new container of dimension $n$ is returned.\n",
+    "As with the restriction function the order of the samples is preserved and not altered.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#\n",
+    "# Expaning the restricted samples\n",
+    "fExpSamples = fCondi.expandSample(fResSamples)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We now inspect the expanded samples.\n",
+    "As we can see the free dimensions are there where we have supposed them.\n",
+    "But the first two components of the samples are different from the original one.\n",
+    "The value that was applied there is the value of the condition that was defined above."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The expanded samples, with the first condition, are:\n",
+      "0 -> (-1, -2, 3, 4)\n",
+      "1 -> (-1, -2, 7, 8)\n",
+      "2 -> (-1, -2, 11, 12)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"The expanded samples, with the first condition, are:\")\n",
+    "for i in range(len(fExpSamples)):\n",
+    "    print(\"{} -> {}\".format(i, fExpSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Applying Conditions\n",
+    "We have seen that expanding restricted samples is not idempotent.\n",
+    "As a result the conditions will be applied to a set of sample.\n",
+    "With that we mean that all dimensions that are restricted will be set to the value that is forced by the condition.\n",
+    "\n",
+    "However if one just want to apply the condition to a bunch of samples, restricting and then expanding them again, is quite costly, since it involves two copies.\n",
+    "For that the condition supports a method of applying the condition directly to a container.\n",
+    "In contrast to the restriction and expanding functions which treats the imput argument as constant, this function actively modify its argument.\n",
+    "\n",
+    "This is also the most efficient way to set the several dimensions of a container to a certain value, when not operating on a `SampleCollection`.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#\n",
+    "# Because of the modification of the argument a copy must be made \n",
+    "# (this is only because _we_ the raw samples later)\n",
+    "fAppSamples = rawSamples.clone()\n",
+    "\n",
+    "# Apply the conditions\n",
+    "fCondi.applyConditions(fAppSamples)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As we see the result is the same as before.\n",
+    "With the difference that the conditions where applied directly without the need of creating temporaries.\n",
+    "And to repeat myself, the input argument was modified."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Samples when the conditions were applied:\n",
+      "0 -> (-1, -2, 3, 4)\n",
+      "1 -> (-1, -2, 7, 8)\n",
+      "2 -> (-1, -2, 11, 12)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"Samples when the conditions were applied:\")\n",
+    "for i in range(len(fAppSamples)):\n",
+    "    print(\"{} -> {}\".format(i, fAppSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### A Second Condition\n",
+    "Now we will demonstrate a second case.\n",
+    "The most important thing here is, to demonstrate what a restricted sample is.\n",
+    "And that restricted samples are technically normal samples.\n",
+    "\n",
+    "We will use a new condition.\n",
+    "This time we will force the second and the fourth component to $-3$ and $-4$ respectively.\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#\n",
+    "# Create the condition, use the DICT method\n",
+    "c = dict()\n",
+    "c[1] = -3  # Zero based index\n",
+    "c[3] = -4\n",
+    "\n",
+    "# Create the condition object\n",
+    "sCondi = pyR.MultiCondition(4, c)  # 4 ~ Underling dimension"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Restriction\n",
+    "Now we will also restrict the same samples (`rawSamples`) that we have used before.\n",
+    "But this time with a different condition.\n",
+    "Again we have an underlying dimension of $4$ and $2$ conditions, thus we have a degree of freedom of $2$.\n",
+    "When we restrict the samples we expect to see a container of dimension $2$ with $3$ samples in it.\n",
+    "The samples should be $\\{(1, 3),\\, (5, 7),\\, (9, 11)\\}$."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The restricted samples, with the _second_ condition, are:\n",
+      "0 -> (1, 3)\n",
+      "1 -> (5, 7)\n",
+      "2 -> (9, 11)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Restrict the sample\n",
+    "sResSamples = sCondi.restrictSample(rawSamples)\n",
+    "\n",
+    "print(\"The restricted samples, with the _second_ condition, are:\")\n",
+    "for i in range(len(sResSamples)):\n",
+    "    print(\"{} -> {}\".format(i, sResSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Expanding\n",
+    "We will now expand the samples again as we have done before.\n",
+    "Again you have to keep in mind that the operations are not idempotent.\n",
+    "But because we have different condition in place, the result will look different, than before.\n",
+    "\n",
+    "We expect that the second component of the samples is set to $-3$ and the fourth set to $-4$."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The reexpanded samples, with the _second_ condition, are:\n",
+      "0 -> (1, -3, 3, -4)\n",
+      "1 -> (5, -3, 7, -4)\n",
+      "2 -> (9, -3, 11, -4)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Expaning the restricted samples\n",
+    "sExpSamples = sCondi.expandSample(sResSamples)\n",
+    "\n",
+    "print(\"The reexpanded samples, with the _second_ condition, are:\")\n",
+    "for i in range(len(sExpSamples)):\n",
+    "    print(\"{} -> {}\".format(i, sExpSamples.getSample(i)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As we see this is indeed the case."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "##### Note to Expanding\n",
+    "Now we will come back to the stuff about that a restricted sample is something that only exists on a semantic level.\n",
+    "Only you knows that a sample is a restricted sample.\n",
+    "In fact you could have expanded any sample container of dimension two.\n",
+    "\n",
+    "To demonstrate this, we will now expand the `sResSamples` the restricted samples we got when we used the second condition, but we will use the first condition.\n",
+    "The result will be that we will get a sample container of dimension four.\n",
+    "The first dimension of the samples will be set to $-1$ and the second will be set to $-2$.\n",
+    "The first component on the restricted samples will be used as third component and the second one as fourth component, of the expanded samples.\n",
+    "\n",
+    "This shows that a sample has no idea, that it is the result of a restriction operation, nor the condition that was used.\n",
+    "\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The reexpanded samples, with the _first_ condition, are:\n",
+      "0 -> (-1, -2, 1, 3)\n",
+      "1 -> (-1, -2, 5, 7)\n",
+      "2 -> (-1, -2, 9, 11)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Expaning the restricted samples with the first condition\n",
+    "sfExpSamples = fCondi.expandSample(sResSamples)\n",
+    "\n",
+    "print(\"The reexpanded samples, with the _first_ condition, are:\")\n",
+    "for i in range(len(sfExpSamples)):\n",
+    "    print(\"{} -> {}\".format(i, sfExpSamples.getSample(i)))"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": null,
-- 
GitLab