From 712a4a60b4e8a58622bbc8bbf43888788c697d6a Mon Sep 17 00:00:00 2001 From: Laasya-73 <77721581+Laasya-73@users.noreply.github.com> Date: Mon, 17 Aug 2026 22:19:11 -0500 Subject: [PATCH 1/6] Support domain inclusion in TrueMeasure chains --- demos/true_measure_domain_inclusion.ipynb | 2141 +++++++++++++++++++ qmcpy/true_measure/abstract_true_measure.py | 29 +- test/test_true_measures.py | 99 + 3 files changed, 2266 insertions(+), 3 deletions(-) create mode 100644 demos/true_measure_domain_inclusion.ipynb diff --git a/demos/true_measure_domain_inclusion.ipynb b/demos/true_measure_domain_inclusion.ipynb new file mode 100644 index 000000000..cb3540df0 --- /dev/null +++ b/demos/true_measure_domain_inclusion.ipynb @@ -0,0 +1,2141 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c303c30a", + "metadata": {}, + "source": [ + "# Chaining `TrueMeasure` Transformations with Compatible Domains\n", + "\n", + "This notebook demonstrates a generalization of the compatibility rule used when chaining `TrueMeasure` transformations in QMCPy.\n", + "\n", + "Previously, consecutive transformations were considered compatible only when the range of the preceding transformation exactly matched the domain of the next transformation.\n", + "\n", + "This notebook shows why exact equality is unnecessarily restrictive and demonstrates the proposed range-in-domain condition for one-dimensional intervals and multidimensional axis-aligned boxes." + ] + }, + { + "cell_type": "markdown", + "id": "7b6b5d08", + "metadata": {}, + "source": [ + "## Motivation\n", + "\n", + "A chained transformation passes the output of one transformation into the next.\n", + "\n", + "Consider two consecutive transformations\n", + "\n", + "$$\n", + "T_{j-1}: D_{j-1} \\rightarrow R_{j-1}\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "T_j: D_j \\rightarrow R_j.\n", + "$$\n", + "\n", + "The output of $T_{j-1}$ becomes the input to $T_j$.\n", + "\n", + "Therefore, the important compatibility question is:\n", + "\n", + "> Can every value produced by $T_{j-1}$ be accepted by $T_j$?\n", + "\n", + "Previously, QMCPy effectively required\n", + "\n", + "$$\n", + "R_{j-1} = D_j.\n", + "$$\n", + "\n", + "However, exact equality is stronger than necessary.\n", + "\n", + "For the domain/range compatibility of two consecutive transformations, exact equality is not required. It is sufficient that every value produced by the preceding transformation lies inside the domain accepted by the next transformation:\n", + "\n", + "$$\n", + "R_{j-1} \\subseteq D_j.\n", + "$$\n", + "\n", + "This condition addresses whether the two transformations are compatible at their shared boundary. Other requirements of the individual transformations remain unchanged." + ] + }, + { + "cell_type": "markdown", + "id": "5a6535f6", + "metadata": {}, + "source": [ + "### Simple example\n", + "\n", + "Suppose the previous transformation produces values only in\n", + "\n", + "$$\n", + "R_{j-1} = [0.25, 0.75],\n", + "$$\n", + "\n", + "while the next transformation accepts every value in\n", + "\n", + "$$\n", + "D_j = [0,1].\n", + "$$\n", + "\n", + "The two sets are not equal:\n", + "\n", + "$$\n", + "[0.25,0.75] \\neq [0,1].\n", + "$$\n", + "\n", + "However,\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "Every output of the previous transformation therefore lies within the input domain accepted by the next transformation.\n", + "\n", + "Rejecting this composition only because the two intervals are not identical is unnecessarily restrictive." + ] + }, + { + "cell_type": "markdown", + "id": "da58e3d8", + "metadata": {}, + "source": [ + "## Compatibility rule\n", + "\n", + "For a one-dimensional range\n", + "\n", + "$$\n", + "R = [r_L,r_U]\n", + "$$\n", + "\n", + "and domain\n", + "\n", + "$$\n", + "D = [d_L,d_U],\n", + "$$\n", + "\n", + "the range is contained within the domain when\n", + "\n", + "$$\n", + "d_L \\leq r_L\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "r_U \\leq d_U.\n", + "$$\n", + "\n", + "Both conditions must hold.\n", + "\n", + "For example,\n", + "\n", + "$$\n", + "[1,3] \\subseteq [0,4]\n", + "$$\n", + "\n", + "because\n", + "\n", + "$$\n", + "0 \\leq 1\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "3 \\leq 4.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "93d58e11", + "metadata": {}, + "source": [ + "### Multidimensional case\n", + "\n", + "QMCPy also works with multidimensional domains and ranges.\n", + "\n", + "For an axis-aligned box,\n", + "\n", + "$$\n", + "R =\n", + "[r_1^L,r_1^U]\n", + "\\times\n", + "\\cdots\n", + "\\times\n", + "[r_d^L,r_d^U]\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "D =\n", + "[d_1^L,d_1^U]\n", + "\\times\n", + "\\cdots\n", + "\\times\n", + "[d_d^L,d_d^U].\n", + "$$\n", + "\n", + "Compatibility is checked independently in every coordinate.\n", + "\n", + "For every dimension $i$,\n", + "\n", + "$$\n", + "d_i^L \\leq r_i^L\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "r_i^U \\leq d_i^U.\n", + "$$\n", + "\n", + "If even one coordinate violates the condition, the chained transformation is incompatible." + ] + }, + { + "cell_type": "markdown", + "id": "fa1820ac", + "metadata": {}, + "source": [ + "### Scope of this change\n", + "\n", + "The initial compatibility rule is intentionally limited to support metadata represented by:\n", + "\n", + "- one-dimensional intervals;\n", + "- multidimensional axis-aligned boxes;\n", + "- finite or unbounded numerical endpoints.\n", + "\n", + "For example,\n", + "\n", + "$$\n", + "[1,3]\\times[2,5]\\times(-\\infty,\\infty)\n", + "$$\n", + "\n", + "can be checked coordinate by coordinate.\n", + "\n", + "This change does **not** attempt to represent disconnected supports such as\n", + "\n", + "$$\n", + "[0,5]\\cup[10,20],\n", + "$$\n", + "\n", + "or arbitrary nonrectangular regions.\n", + "\n", + "Those cases would require a richer representation of a measure's support and are outside the scope of this change." + ] + }, + { + "cell_type": "markdown", + "id": "174a45d0", + "metadata": {}, + "source": [ + "### Visualizing the multidimensional rule\n", + "\n", + "In two dimensions, compatibility means that the entire inner rectangle must lie inside the outer domain rectangle.\n", + "\n", + "The check is still performed coordinate by coordinate." + ] + }, + { + "cell_type": "code", + "execution_count": 613, + "id": "190451cb", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:30.394831Z", + "iopub.status.busy": "2026-08-18T03:05:30.394280Z", + "iopub.status.idle": "2026-08-18T03:05:31.354591Z", + "shell.execute_reply": "2026-08-18T03:05:31.352721Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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p8tTVooXL+5eK3Tg36233moffPCBTZkyxT777DN3/IsuuijT4+zZs8fOOOMMe/jhhzPcR11WqlSpYnmNYBQAELeWLVvm+nHmxUPHzinVQikA+fjjj619+/Z29NFH2z//+U/75JNPbN26dXb33Xdn2hyuicJfeukl9/9jjjnGLU855RS375lnnhnc74UXXrATTjjB1eIdf/zxNm7cuCNqVN966y2XB+3z+uuvR8yvgua///3vbp8mTZrYrFmzjthn8eLFdvbZZ7uASsGhat52794d3H7llVe6JugHH3zQatas6c5BNY8HDx60O+64wwUtRx11lE2cODHdcQcNGmTHHXecC54aNGhg9957b7qgObyZ3nudxx57zM1dqbyovGMRaKt80tLSbMKECa6G8ZJLLnG1nqNGjcr0eU899ZTLg/KfW08//bQr59Cayz179th5553nyiZaKSkp9uKLL7pz0HFVg6v3YN68efb1119n+LwrrrjChg4dah06dDC/+RqMfv7559a5c2fXxJGdviuqUj733HNdpF6hQgX363PmzJn5ll8AQP6qVq2a+5ufFw8dOydU66nvnn79+h1RE6Yaq8suu8wFiJoUPDsWLFjglgpk1fyq7zovcFKw8MADD9jPP//sgkAFKy+//HK65w8ePNh1D9A+nTp1OuL4mqVAtWQKnr/55htXg6sAMZSCIT23cuXKrmlWNWzKz4ABA9Lt9+mnn7paN31/K/gZNmyYXXDBBe55Ova///1vu/76623t2rXpaicVeCv4f/LJJ+3555+3J554ItMymTNnjv32229uqfPV873g3Qtg1Z8xWvPnz3dBucrCo/NesWKFbd++3fKDyq1x48YuCNyyZYvt27fPleH+/fvtzTffjPp4qk1VoB4aVOqHi34g6XwLAl+DUV38zZo1s7Fjx2Zrf138CkY//PBDV/hnnXWWC2a///77PM8rAABeLaMCTdVYRqJ0BTabN2/OVoF5o/dVA6hg1msWVaD3+OOPu0BStadaqjn22WefTff8W265JbhPpLvgKKhcvny5vfLKK+47V8GYAttQkyZNcv0Otc9JJ53katjGjBljr776aroaPOVNtYQKptRsraXuwnPXXXfZsccea0OGDHGB3pdffhl8zj333OP6VCp41He2+ohOnjw50zJRcKvXV1ClQO38889P169UPyQaNmxo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Gll966232sknn+wCVQWmmvcUAAAACTCavn379sH/p6amHtFXM9pm8AEDBrhHJJGm81Ht69dffx3VawAAAKCQDGDSqHkFjxpcUrZsWdeXNPQBAAAA5Fkwescdd7i5Pp955hk3OOiFF15wfUjr1Kljr7zySrSHAwAAQAKLupn+gw8+cEHnmWee6QYatWvXzho1amT16tWz119/3U1IDwAAAORJzajuDd+gQYNg/1CtyxlnnGGff/55tIcDAABAAos6GFUgunr1avf/448/3iZPnhysMa1UqVLscwgAAIBCK+pgVE3zutuSDB482MaOHWulSpVy0y2pPykAAIlI82/PmTPHzTrTrFkztwydkxtAjPqMKuj0dOjQwZYvX24LFy50/UY19ycAAIlIN4DReIpI0xICiGEwGk4Dl/QAAAAA8iUY1f3j9di0aVO6+8TLhAkTcnJIAAAAJKCog1HNKXrfffe5+8nXrl3bihQpkjc5AwAAQKEXdTA6fvx4e+mll+yKK67ImxwB/3/aMM3UsGrVKjt48KAVL1486lvNAoAfrr/+ejftYZUqVezZZ5/lTQBiHYzqXvRt27aN9mlAVHR3r+7du1NqAAoMdVvbunWrm+pw/fr1rvVQdyssWjTqiWuAhBL1J+Saa66xSZMm5U1uAAAooBSI1qhRwwWioqXSAMS4ZjQ1NdWee+45++STT9xUTiVKlEi3fdSoUdEeEgAAAAkq6mD0p59+subNm7v/L1myJN02BjMh1hYvXmwHDhxwP3qaNm1KAQMAkOjBqO4uAeSXf/7zn7Zu3TpLTk62tWvXUvAAABQy9KoGAABAfNeMXnTRRW46J02to/9n5t13341V3pDANm/e7AYCeFQ7qrTq1av7mi8AAOBDMFqxYsVgf1D9HwAAAMi3YHTixIkR/w8AAADkBn1GAQAAEN81o6ecckq2p21atGhRbvMEAACABJGtYLRbt27pJr0fN26cNWnSxNq0aePSvv76a1u6dKn169cv73IKAACAxAxGhw0blu52oDfddJPdf//9R+zz559/xj6HAAAAKLSi7jM6ZcoU69279xHpl19+ub3zzjuxyhcAAAASQNTBaOnSpe2rr746Il1ppUqVilW+AAAAkACivh3oLbfcYjfccIMbqNSqVSuX9s0339iECRPs3nvvzYs8AgAAoJCKOhgdPHiwNWjQwJ588kl77bXXXNoJJ5zg5h/t0aNHXuQRAIC4p7sUTp482UaMGGEpKSnuJjFKAxDDYPTgwYP24IMP2lVXXUXgCQBAiJIlS1r37t3dA0Ae9RktXry4PfLIIy4oBQAAAPJ9ANM555xjn332Wa5fGAAAAIi6z+g///lP12908eLF1qJFCytbtmy67V26dKFUAQAAkDfBqHeXpVGjRh2xTbcMPXToULSHBI5Qrlw5GzNmjP3888924MABK1GihEsDgHh39913244dO6xSpUr2wAMP+J0doPAFo4cPH86bnABh89n279+fMgFQ4Lz88su2bt06S05OJhgF8qLPKAAAONLmzZtdC6ECUdFSaQDyIBjVAKbOnTtbo0aN3EP9RL/44oucHAoAAAAJLOpgVBPdd+jQwcqUKWM33XSTe6hJVaPsJ02alDe5RMJav369rV271i0BAEDhE3WfUXXG1lyjt956azBNAakGNN1///126aWXxjqPSGCnnnpqsO+VglIAAJDgNaOrVq1yTfTh1FS/evXqWOULAAAACSDqYLRu3bo2e/bsI9I/+eQTtw2IhS1btlj16tVt69atlpSU5JZKAwAACd5Mf9ttt7lm+R9++MHatm3r0r766it76aWX7Mknn8yLPCIBBQKBI4JPpQEAgAQPRm+44QarVauWPf744zZ58mSXdsIJJ9hbb71lXbt2zYs8AgAAoJCKOhiVCy+80D0AAACAfA9GZeHChe5WjXLiiSfaKaeckquMAAAAIPFEHYxu2rTJLrnkEps7d667767oHrxnnXWWvfnmm27QCQAAAJAno+lvvPFG27Vrly1dutS2bdvmHkuWLLGdO3e6gU0AAABAntWMzpgxw03jpEFLniZNmtjYsWOtY8eO0R4OAAAACSzqmtHDhw9biRIljkhXmrYBAAAAeRaMnn322XbzzTfbX3/9FUzT7Rp1e1Ddnx4AAADIs2B0zJgxrn9o/fr1rWHDhu5xzDHHuLSnn3462sMBAFAolCtXzn1H1qlTx/3fWwKIcZ9R3fJz0aJFrt/o8uXLXZr6j3bo0CHaQwEAUGiULl3a+vfv7x4A8nie0SJFiti5557rHgAAAECeN9N/+umnbtS8muPDpaSkuInvv/jiixxnBAAAAIkn28Ho6NGj7dprr7UKFSocsa1ixYp2/fXX26hRo2KdPwAAABRi2W6m//HHH+3h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jjvO7a+pMqZPn+5DrgtXudarV8996MMf+mJC7so2HMFobK5ZmTdvnpvaTcGWpnl64IEH3DRayHm5HjhwIDB8+HAXgJYqVSpQt27dQL9+/QLbt2+nWEPMmTMn4t9Mryy1VNmGP6d58+bufdD1OnHiRMo0BmWr/2e2f6wV0T95W/cKAAAAREafUQAAAPiGYBQAAAC+IRgFAACAbwhGAQAA4BuCUQAAAPiGYBQAAAC+IRgFAACAbwhGAQAA4BuCUQCII8OHD7fmzZsH16+88krr1q2br3kCgLxEMAogoW3YsMFuvPFGa9CggZUsWdLq1q1rnTt3ttmzZ1s8ePLJJ+2ll16K6TF1vEqVKsXkWM8995ydeeaZVqFCBStSpIjt2LEjJscFkDiK+50BAPDL77//bqeffroLzB599FFr2rSpHThwwGbOnGn9+/e35cuX59lr63VKlCiR5X4VK1a0eLZ37177xz/+4R5DhgzxOzsACiBqRgEkrH79+rnavAULFti//vUvO+644+zEE0+0gQMH2tdffx3cb82aNda1a1crV66cqwHs0aOHbdy4Md2xnnnmGWvYsKElJSVZ48aN7dVXX023Xa+jfbp06WJly5a1Bx54wKU/9NBDVrNmTStfvrxdffXVlpqamu554c30qoW86aab7M4777QqVapYrVq1XNN+qFGjRrnAWq+jml6d5+7du922uXPnWt++fS0lJcXlSQ/v+fv377fbb7/dkpOT3XNbt27t9s/MLbfcYoMHD7bTTjstytIHgP8hGAWQkLZt22YzZsxwNaAKvMJ5zdiHDx92gaj2/+yzz2zWrFm2atUq69mzZ3DfqVOn2s0332y33XabLVmyxK6//noX8M2ZMyfdMRX0XXjhhbZ48WK76qqrbPLkyS7twQcftO+++85q165t48aNyzLvL7/8ssvzN998Y4888ojdd999Ll+eokWL2lNPPWVLly51+3766acueJW2bdva6NGjXVC9fv1691AAKgMGDLD58+fbm2++aT/99JN1797d1Xj++uuvuShpAMhCAAAS0DfffBPQn8B333030/0+/vjjQLFixQJr1qwJpi1dutQ9d8GCBW69bdu2gWuvvTbd87p37x4477zzguva/5Zbbkm3T5s2bQL9+vVLl9a6detAs2bNgut9+vQJdO3aNbjevn37wBlnnJHuOaeeempg0KBBGZ7DlClTAlWrVg2uT5w4MVCxYsV0+/zxxx/uPNetW5cu/ZxzzgkMGTIkkJU5c+a4c9y+fXuW+wJAKGpGASSk/8WHWfv5559dU7ceniZNmriaU23z9lHf01Ba97Z7WrZsecSx1RQeqk2bNlnm6eSTT063rhrVTZs2Bdc/+eQTO+ecc1xzu5r/r7jiCtu6davr35kR1dYeOnTIdVVQdwTvodrg3377Lcs8AUBOMYAJQEI69thjXX/JvBykFC5Sd4CcCB/4pPNQdwJvUNYFF1xgN9xwg+uXqn6lX375peuPmpaWZmXKlIl4TPUpLVasmC1cuNAtQykoBYC8Qs0ogISkIK1Tp042duxY27NnzxHbvSmKTjjhBPvzzz/dw7Ns2TK3XTWk3j5fffVVuudr3dueET1P/T5DhQ6cygkFkwpMH3/8cTeoSDWdf/31V7p9NMhKtaChTjnlFJemGtZGjRqle2iQFADkFYJRAAlLgagCsFatWtk777zjBuqo6VyDf7zm8g4dOriR6ZdddpktWrTIjbzv3bu3tW/fPtjsfscdd7i5OzVaXsfQaPZ33303ODAoIxr0NGHCBJs4caL98ssvNmzYMDfoKDcUPGraqKefftoNtNKo/vHjx6fbp379+q4mVHOpbtmyxTXfK2jVOerclPfVq1e7cx05cqRNnz4903laf/jhB1u5cmWwuV/rGvAFANmSrgcpACSYv/76K9C/f/9AvXr1AklJSYHk5ORAly5d3ICc0ME9SitbtmygfPnybnDShg0b0h1n3LhxgQYNGgRKlCgROO644wKvvPJKuu36czt16tQjXv+BBx4IVKtWLVCuXDk3WOnOO+/McgDTzTffnO4Y2q79PKNGjQrUrl07ULp06UCnTp1cXsIHF/373/92g5qUPmzYMJeWlpYWGDp0aKB+/fruPHSMCy+8MPDTTz9lWH56ro4R/tAgKQDIjiL6J3thKwAAABBbNNMDAADANwSjAAAA8A3BKAAAAHxDMAoAAADfEIwCAADANwSjAAAA8A3BKAAAAHxDMAoAAADfEIwCAADANwSjAAAA8A3BKAAAAHxDMAoAAADzy/8DiRI7zTm9l2oAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib.patches import Rectangle\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 7))\n", + "\n", + "# Outer domain: [0,1] x [0,1]\n", + "outer_domain = Rectangle(\n", + " (0, 0),\n", + " 1,\n", + " 1,\n", + " fill=False,\n", + " linewidth=3,\n", + " label=\"Outer domain: [0,1] × [0,1]\",\n", + ")\n", + "\n", + "# Valid range: [0.1,0.8] x [0.2,0.9]\n", + "valid_range = Rectangle(\n", + " (0.1, 0.2),\n", + " 0.7,\n", + " 0.7,\n", + " fill=False,\n", + " linewidth=3,\n", + " linestyle=\"--\",\n", + " label=\"Valid inner range\",\n", + ")\n", + "\n", + "# Invalid range: [0.1,0.8] x [0.2,1.1]\n", + "invalid_range = Rectangle(\n", + " (0.1, 0.2),\n", + " 0.7,\n", + " 0.9,\n", + " fill=False,\n", + " linewidth=2,\n", + " linestyle=\":\",\n", + " label=\"Invalid inner range\",\n", + ")\n", + "\n", + "ax.add_patch(outer_domain)\n", + "ax.add_patch(valid_range)\n", + "ax.add_patch(invalid_range)\n", + "\n", + "ax.set_xlim(-0.15, 1.25)\n", + "ax.set_ylim(-0.15, 1.25)\n", + "\n", + "ax.set_xlabel(\"Coordinate 1\")\n", + "ax.set_ylabel(\"Coordinate 2\")\n", + "ax.set_title(\"Coordinate-wise Domain Compatibility\")\n", + "\n", + "ax.axhline(0, linewidth=0.8)\n", + "ax.axvline(0, linewidth=0.8)\n", + "\n", + "ax.legend()\n", + "ax.set_aspect(\"equal\")\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "003ec6b8", + "metadata": {}, + "source": [ + "The dashed rectangle is compatible because both coordinate intervals are contained within the unit-domain intervals:\n", + "\n", + "$$\n", + "[0.1,0.8]\\subseteq[0,1]\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "[0.2,0.9]\\subseteq[0,1].\n", + "$$\n", + "\n", + "The dotted rectangle is incompatible because its second coordinate extends to $1.1$:\n", + "\n", + "$$\n", + "[0.2,1.1]\\nsubseteq[0,1].\n", + "$$\n", + "\n", + "This illustrates why multidimensional compatibility can be checked independently along each coordinate for axis-aligned boxes." + ] + }, + { + "cell_type": "markdown", + "id": "a272eee8", + "metadata": {}, + "source": [ + "### Unbounded intervals and endpoint representation\n", + "\n", + "Some QMCPy measures have unbounded domains or ranges, such as\n", + "\n", + "$$\n", + "(-\\infty,\\infty)\n", + "$$\n", + "\n", + "or\n", + "\n", + "$$\n", + "[0,\\infty).\n", + "$$\n", + "\n", + "Infinity is not an element of these sets. In the implementation, `-np.inf` and `np.inf` are numerical representations of unbounded lower and upper endpoints.\n", + "\n", + "The current `TrueMeasure` metadata records lower and upper bounds, but it does not separately record whether a finite endpoint is open or closed.\n", + "\n", + "Because the current metadata stores only numerical lower and upper bounds, the implemented compatibility test is most precisely understood as comparing the stored interval envelopes. When discussing endpoint behavior mathematically, this is closely related to comparing closures of the represented supports:\n", + "\n", + "$$\n", + "\\overline{R}_{j-1} \\subseteq \\overline{D}_j.\n", + "$$\n", + "\n", + "For example,\n", + "\n", + "$$\n", + "\\overline{(0,1)}=[0,1].\n", + "$$\n", + "\n", + "At the numerical level, the same coordinate-wise comparisons are used:\n", + "\n", + "$$\n", + "d_L \\leq r_L\n", + "\\qquad\\text{and}\\qquad\n", + "r_U \\leq d_U.\n", + "$$\n", + "\n", + "For example, a stored range with bounds $[-5,5]$ is compatible with an unbounded real-valued domain because\n", + "\n", + "$$\n", + "-\\infty \\leq -5\n", + "\\qquad\\text{and}\\qquad\n", + "5 \\leq \\infty.\n", + "$$\n", + "\n", + "This initial change does not attempt to distinguish cases such as $(0,1)$ and $[0,1]$ when their stored numerical bounds are identical. Explicit open/closed endpoint metadata would require a richer support representation and can be considered separately." + ] + }, + { + "cell_type": "code", + "execution_count": 614, + "id": "4c2905b1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:31.384153Z", + "iopub.status.busy": "2026-08-18T03:05:31.383506Z", + "iopub.status.idle": "2026-08-18T03:05:33.157320Z", + "shell.execute_reply": "2026-08-18T03:05:33.152822Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "from qmcpy import DigitalNetB2, Kumaraswamy, Uniform\n", + "from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure\n", + "from qmcpy.util import ParameterError" + ] + }, + { + "cell_type": "markdown", + "id": "4d729766", + "metadata": {}, + "source": [ + "## Previous behavior: exact equality\n", + "\n", + "Previously, chained `TrueMeasure` compatibility was determined using an exact comparison between the next transformation's domain and the preceding transformation's range.\n", + "\n", + "Conceptually, the check was equivalent to:" + ] + }, + { + "cell_type": "code", + "execution_count": 615, + "id": "83f256a3", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.167238Z", + "iopub.status.busy": "2026-08-18T03:05:33.166058Z", + "iopub.status.idle": "2026-08-18T03:05:33.179525Z", + "shell.execute_reply": "2026-08-18T03:05:33.175481Z" + } + }, + "outputs": [], + "source": [ + "def previous_compatibility_check(transform_range, domain):\n", + " \"\"\"Reproduce the previous exact-equality compatibility rule.\"\"\"\n", + " return not (np.asarray(domain) != np.asarray(transform_range)).any()" + ] + }, + { + "cell_type": "code", + "execution_count": 616, + "id": "ffb5f7ad", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.188006Z", + "iopub.status.busy": "2026-08-18T03:05:33.187242Z", + "iopub.status.idle": "2026-08-18T03:05:33.206781Z", + "shell.execute_reply": "2026-08-18T03:05:33.201198Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 616, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transform_range = np.array([[0.25, 0.75]])\n", + "domain = np.array([[0.0, 1.0]])\n", + "\n", + "previous_compatibility_check(transform_range, domain)" + ] + }, + { + "cell_type": "markdown", + "id": "f34229e8", + "metadata": {}, + "source": [ + "The previous rule rejects this pair because\n", + "\n", + "$$\n", + "[0.25,0.75] \\neq [0,1].\n", + "$$\n", + "\n", + "But this does not mean the transformation is invalid. Every value in the preceding range is still inside the next domain." + ] + }, + { + "cell_type": "code", + "execution_count": 617, + "id": "e4502c55", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.215665Z", + "iopub.status.busy": "2026-08-18T03:05:33.214936Z", + "iopub.status.idle": "2026-08-18T03:05:33.229160Z", + "shell.execute_reply": "2026-08-18T03:05:33.224421Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 617, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "AbstractTrueMeasure._range_in_domain(\n", + " transform_range,\n", + " domain,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c18c7454", + "metadata": {}, + "source": [ + "The new compatibility rule accepts the same pair because\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "This captures the actual requirement for composition: every value produced by the previous transformation can be passed safely to the next transformation." + ] + }, + { + "cell_type": "markdown", + "id": "35f6ae8f", + "metadata": {}, + "source": [ + "## What changed in QMCPy?\n", + "\n", + "The previous `TrueMeasure` composition logic required the domain of the current transformation to exactly match the range of the preceding transformation.\n", + "\n", + "The previous compatibility check was:\n", + "\n", + "```python\n", + "if (self.domain != self.transform.range).any():\n", + " self.sub_compatibility_error = True\n", + "```\n", + "\n", + "For two consecutive transformations,\n", + "\n", + "$$\n", + "T_{j-1}: D_{j-1} \\rightarrow R_{j-1}\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "T_j: D_j \\rightarrow R_j,\n", + "$$\n", + "\n", + "this effectively required\n", + "\n", + "$$\n", + "R_{j-1} = D_j.\n", + "$$\n", + "\n", + "This rejects cases where the preceding range is smaller than, but still completely contained within, the next domain.\n", + "\n", + "For example,\n", + "\n", + "$$\n", + "R_{j-1}=[0.25,0.75]\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "D_j=[0,1]\n", + "$$\n", + "\n", + "were considered incompatible because\n", + "\n", + "$$\n", + "[0.25,0.75] \\neq [0,1].\n", + "$$\n", + "\n", + "However, every value produced by the preceding transformation is a valid input to the next transformation because\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "### Updated compatibility check\n", + "\n", + "The implementation now checks whether the preceding transformation's range is contained within the current transformation's domain:\n", + "\n", + "```python\n", + "if not self._range_in_domain(self.transform.range, self.domain):\n", + " self.sub_compatibility_error = True\n", + "```\n", + "\n", + "For one coordinate, let\n", + "\n", + "$$\n", + "R_{j-1}=[r_L,r_U]\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "D_j=[d_L,d_U].\n", + "$$\n", + "\n", + "The range is compatible with the next domain when\n", + "\n", + "$$\n", + "d_L \\leq r_L\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "r_U \\leq d_U.\n", + "$$\n", + "\n", + "For multiple dimensions, the same comparison is performed independently for every coordinate $i$:\n", + "\n", + "$$\n", + "d_i^L \\leq r_i^L\n", + "\\qquad\\text{and}\\qquad\n", + "r_i^U \\leq d_i^U.\n", + "$$\n", + "\n", + "Therefore, the compatibility rule changes from\n", + "\n", + "$$\n", + "\\boxed{R_{j-1}=D_j}\n", + "$$\n", + "\n", + "to\n", + "\n", + "$$\n", + "\\boxed{R_{j-1}\\subseteq D_j}.\n", + "$$\n", + "\n", + "Exact equality is still accepted because it is a special case of containment.\n", + "\n", + "The implementation also preserves QMCPy's existing broadcasting behavior between a common `(1, 2)` domain and a coordinate-specific `(d, 2)` range.\n", + "\n", + "For example, a common domain\n", + "\n", + "```text\n", + "[[0, 1]]\n", + "```\n", + "\n", + "can be compared against a two-dimensional range\n", + "\n", + "```text\n", + "[[0.1, 0.8],\n", + " [0.2, 0.9]]\n", + "```\n", + "\n", + "because both coordinate intervals satisfy\n", + "\n", + "$$\n", + "[0.1,0.8]\\subseteq[0,1]\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "[0.2,0.9]\\subseteq[0,1].\n", + "$$\n", + "\n", + "This change only generalizes **domain-range compatibility**. It does not change the individual transformations themselves, the direct unit-cube requirement for a `StdUniform` discrete distribution, or the separate importance-sampling compatibility logic." + ] + }, + { + "cell_type": "code", + "execution_count": 618, + "id": "f5062f63", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.234406Z", + "iopub.status.busy": "2026-08-18T03:05:33.234037Z", + "iopub.status.idle": "2026-08-18T03:05:33.261633Z", + "shell.execute_reply": "2026-08-18T03:05:33.260143Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CasePrevious equality ruleNew inclusion rule
0Exact equalityTrueTrue
1Strict inclusionFalseTrue
2Infinite domainFalseTrue
3Positive half-lineFalseTrue
4Lower-bound failureFalseFalse
5Upper-bound failureFalseFalse
\n", + "
" + ], + "text/plain": [ + " Case Previous equality rule New inclusion rule\n", + "0 Exact equality True True\n", + "1 Strict inclusion False True\n", + "2 Infinite domain False True\n", + "3 Positive half-line False True\n", + "4 Lower-bound failure False False\n", + "5 Upper-bound failure False False" + ] + }, + "execution_count": 618, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "examples = [\n", + " (\"Exact equality\", [[0, 1]], [[0, 1]]),\n", + " (\"Strict inclusion\", [[0.25, 0.75]], [[0, 1]]),\n", + " (\"Infinite domain\", [[-5, 5]], [[-np.inf, np.inf]]),\n", + " (\"Positive half-line\", [[1, 3]], [[0, np.inf]]),\n", + " (\"Lower-bound failure\", [[-0.1, 0.75]], [[0, 1]]),\n", + " (\"Upper-bound failure\", [[0.25, 1.1]], [[0, 1]]),\n", + "]\n", + "\n", + "rows = []\n", + "\n", + "for name, transform_range, domain in examples:\n", + " rows.append(\n", + " {\n", + " \"Case\": name,\n", + " \"Previous equality rule\": previous_compatibility_check(\n", + " transform_range,\n", + " domain,\n", + " ),\n", + " \"New inclusion rule\": AbstractTrueMeasure._range_in_domain(\n", + " transform_range,\n", + " domain,\n", + " ),\n", + " }\n", + " )\n", + "\n", + "pd.DataFrame(rows)" + ] + }, + { + "cell_type": "markdown", + "id": "b867d665", + "metadata": {}, + "source": [ + "The new rule does not make incompatible transformations valid.\n", + "\n", + "It only distinguishes between:\n", + "\n", + "- a range that is different from, but safely contained within, the next domain; and\n", + "- a range that actually extends outside the next domain." + ] + }, + { + "cell_type": "markdown", + "id": "9c6c54db", + "metadata": {}, + "source": [ + "## A real chained `TrueMeasure` example\n", + "\n", + "Consider an inner `Uniform` transformation whose output is restricted to\n", + "\n", + "$$\n", + "[0.25,0.75].\n", + "$$\n", + "\n", + "A `Kumaraswamy` transformation accepts inputs from\n", + "\n", + "$$\n", + "[0,1].\n", + "$$\n", + "\n", + "Therefore,\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "Under the previous exact-equality rule, this chain was marked incompatible.\n", + "\n", + "Under the new containment rule, the two transformations are domain-compatible and the chain can be evaluated successfully." + ] + }, + { + "cell_type": "code", + "execution_count": 619, + "id": "0cc5f4ca", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.266076Z", + "iopub.status.busy": "2026-08-18T03:05:33.265704Z", + "iopub.status.idle": "2026-08-18T03:05:33.289879Z", + "shell.execute_reply": "2026-08-18T03:05:33.285086Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Inner range:\n", + "[[0.25 0.75]]\n", + "\n", + "Outer domain:\n", + "[[0 1]]\n", + "\n", + "Range contained in domain: True\n", + "\n", + "Compatibility error:\n", + "False\n" + ] + } + ], + "source": [ + "inner = Uniform(\n", + " DigitalNetB2(1, seed=7),\n", + " lower_bound=0.25,\n", + " upper_bound=0.75,\n", + ")\n", + "\n", + "outer = Kumaraswamy(inner)\n", + "\n", + "print(\"Inner range:\")\n", + "print(inner.range)\n", + "\n", + "print(\"\\nOuter domain:\")\n", + "print(outer.domain)\n", + "\n", + "print(\n", + " \"\\nRange contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(\n", + " inner.range,\n", + " outer.domain,\n", + " ),\n", + ")\n", + "\n", + "print(\"\\nCompatibility error:\")\n", + "print(outer.sub_compatibility_error)" + ] + }, + { + "cell_type": "code", + "execution_count": 620, + "id": "667b1394", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.299853Z", + "iopub.status.busy": "2026-08-18T03:05:33.298299Z", + "iopub.status.idle": "2026-08-18T03:05:33.320951Z", + "shell.execute_reply": "2026-08-18T03:05:33.315555Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.49764069],\n", + " [0.6423285 ],\n", + " [0.40482463],\n", + " [0.55578408],\n", + " [0.53096826],\n", + " [0.67279285],\n", + " [0.44112426],\n", + " [0.58532942]])" + ] + }, + "execution_count": 620, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "samples = outer.gen_samples(8)\n", + "\n", + "samples" + ] + }, + { + "cell_type": "code", + "execution_count": 621, + "id": "9c657499", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.332388Z", + "iopub.status.busy": "2026-08-18T03:05:33.331269Z", + "iopub.status.idle": "2026-08-18T03:05:33.345110Z", + "shell.execute_reply": "2026-08-18T03:05:33.342928Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sample shape: (8, 1)\n", + "All samples finite: True\n" + ] + } + ], + "source": [ + "print(\"Sample shape:\", samples.shape)\n", + "print(\"All samples finite:\", np.isfinite(samples).all())" + ] + }, + { + "cell_type": "markdown", + "id": "e049c5b4", + "metadata": {}, + "source": [ + "The chain now executes successfully because the output of the inner transformation always lies inside the domain of the outer transformation.\n", + "\n", + "The important change is not that the two intervals became equal. They remain different.\n", + "\n", + "The change is that QMCPy now recognizes their domain-compatible containment relationship." + ] + }, + { + "cell_type": "markdown", + "id": "5dbb3ffc", + "metadata": {}, + "source": [ + "## Multidimensional composition\n", + "\n", + "Now consider an inner transformation with two coordinate ranges:\n", + "\n", + "$$\n", + "[0.1,0.8] \\times [0.2,0.9].\n", + "$$\n", + "\n", + "The outer Kumaraswamy transformation accepts the unit interval in each coordinate:\n", + "\n", + "$$\n", + "[0,1] \\times [0,1].\n", + "$$\n", + "\n", + "Coordinate 1 satisfies\n", + "\n", + "$$\n", + "[0.1,0.8] \\subseteq [0,1],\n", + "$$\n", + "\n", + "and coordinate 2 satisfies\n", + "\n", + "$$\n", + "[0.2,0.9] \\subseteq [0,1].\n", + "$$\n", + "\n", + "Therefore the entire box is compatible." + ] + }, + { + "cell_type": "code", + "execution_count": 622, + "id": "8cb4394c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.350048Z", + "iopub.status.busy": "2026-08-18T03:05:33.349612Z", + "iopub.status.idle": "2026-08-18T03:05:33.363622Z", + "shell.execute_reply": "2026-08-18T03:05:33.361703Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Inner range:\n", + "[[0.1 0.8]\n", + " [0.2 0.9]]\n", + "\n", + "Outer domain:\n", + "[[0 1]]\n", + "\n", + "Range contained in domain: True\n", + "\n", + "Compatibility error:\n", + "False\n" + ] + } + ], + "source": [ + "inner_2d = Uniform(\n", + " DigitalNetB2(2, seed=7),\n", + " lower_bound=[0.1, 0.2],\n", + " upper_bound=[0.8, 0.9],\n", + ")\n", + "\n", + "outer_2d = Kumaraswamy(inner_2d)\n", + "\n", + "print(\"Inner range:\")\n", + "print(inner_2d.range)\n", + "\n", + "print(\"\\nOuter domain:\")\n", + "print(outer_2d.domain)\n", + "\n", + "print(\n", + " \"\\nRange contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(\n", + " inner_2d.range,\n", + " outer_2d.domain,\n", + " ),\n", + ")\n", + "\n", + "print(\"\\nCompatibility error:\")\n", + "print(outer_2d.sub_compatibility_error)" + ] + }, + { + "cell_type": "code", + "execution_count": 623, + "id": "a2f42b67", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.371293Z", + "iopub.status.busy": "2026-08-18T03:05:33.369800Z", + "iopub.status.idle": "2026-08-18T03:05:33.384262Z", + "shell.execute_reply": "2026-08-18T03:05:33.380731Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0.60960507 0.77497487]\n", + " [0.3371496 0.54168863]\n", + " [0.7365757 0.34514116]\n", + " [0.47524005 0.60047814]\n", + " [0.53970404 0.47173912]\n", + " [0.22682022 0.69013017]\n", + " [0.66124946 0.64063827]\n", + " [0.39411447 0.40037581]]\n", + "\n", + "Shape: (8, 2)\n" + ] + } + ], + "source": [ + "samples_2d = outer_2d.gen_samples(8)\n", + "\n", + "print(samples_2d)\n", + "print(\"\\nShape:\", samples_2d.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "bad34b5a", + "metadata": {}, + "source": [ + "This example also demonstrates an important QMCPy representation detail.\n", + "\n", + "The inner `Uniform` stores one interval for each coordinate, while the outer `Kumaraswamy` stores a common unit-domain interval.\n", + "\n", + "The compatibility check therefore preserves NumPy broadcasting between `(d,2)` and `(1,2)` representations." + ] + }, + { + "cell_type": "markdown", + "id": "c2d70373", + "metadata": {}, + "source": [ + "## An actually incompatible chain\n", + "\n", + "Containment should not permit ranges that extend outside the next transformation's domain.\n", + "\n", + "Suppose the inner range is\n", + "\n", + "$$\n", + "[-0.1,0.75]\n", + "$$\n", + "\n", + "while the outer domain is\n", + "\n", + "$$\n", + "[0,1].\n", + "$$\n", + "\n", + "Because\n", + "\n", + "$$\n", + "-0.1 < 0,\n", + "$$\n", + "\n", + "the range is not contained within the domain." + ] + }, + { + "cell_type": "code", + "execution_count": 624, + "id": "14aa4bca", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.392340Z", + "iopub.status.busy": "2026-08-18T03:05:33.391774Z", + "iopub.status.idle": "2026-08-18T03:05:33.402921Z", + "shell.execute_reply": "2026-08-18T03:05:33.400443Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Range contained in domain: False\n", + "Compatibility error: True\n" + ] + } + ], + "source": [ + "invalid_inner = Uniform(\n", + " DigitalNetB2(1, seed=7),\n", + " lower_bound=-0.1,\n", + " upper_bound=0.75,\n", + ")\n", + "\n", + "invalid_outer = Kumaraswamy(invalid_inner)\n", + "\n", + "print(\n", + " \"Range contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(\n", + " invalid_inner.range,\n", + " invalid_outer.domain,\n", + " ),\n", + ")\n", + "print(\"Compatibility error:\", invalid_outer.sub_compatibility_error)" + ] + }, + { + "cell_type": "code", + "execution_count": 625, + "id": "ab92fe35", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.410438Z", + "iopub.status.busy": "2026-08-18T03:05:33.410120Z", + "iopub.status.idle": "2026-08-18T03:05:33.421157Z", + "shell.execute_reply": "2026-08-18T03:05:33.416482Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ParameterError\n", + "The sub-transform range must be contained within the transform domain.\n" + ] + } + ], + "source": [ + "try:\n", + " invalid_outer.gen_samples(8)\n", + "except ParameterError as error:\n", + " print(type(error).__name__)\n", + " print(error)" + ] + }, + { + "cell_type": "markdown", + "id": "14da55da", + "metadata": {}, + "source": [ + "The generalized rule does not remove compatibility checking.\n", + "\n", + "It allows strict inclusion, but still rejects transformations whose preceding range contains values outside the next domain." + ] + }, + { + "cell_type": "markdown", + "id": "aeac0215", + "metadata": {}, + "source": [ + "## Visualizing range-in-domain compatibility\n", + "\n", + "The compatibility condition can also be seen geometrically.\n", + "\n", + "The outer transformation accepts values in the domain $[0,1]$.\n", + "\n", + "- The range $[0.25,0.75]$ lies completely inside the domain, so it is compatible.\n", + "- The range $[-0.1,0.75]$ extends outside the lower boundary of the domain, so it is incompatible." + ] + }, + { + "cell_type": "code", + "execution_count": 626, + "id": "69c0b932", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.428505Z", + "iopub.status.busy": "2026-08-18T03:05:33.428164Z", + "iopub.status.idle": "2026-08-18T03:05:33.558209Z", + "shell.execute_reply": "2026-08-18T03:05:33.557423Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS5xJREFUeJzt3Qd4FNX6x/E3JPQqSpFmQUCQKiqCekFEQbGg3gs27IINBfVaUbA3VCxYUSx/FNQrqCACKiiCYgMEpRfpvQUCpO3/+R3v7N2EJOwkmbT9fp5nHXe2zc6E5Lznfc85caFQKGQAAAAAACDflcr/twQAAAAAAATdAAAAAAAEiEw3AAAAAAABIegGAAAAACAgBN0AAAAAAASEoBsAAAAAgIAQdAMAAAAAEBCCbgAAAAAAAkLQDQAAAABAQAi6AQDF2uGHH25XXnllYR9GkTN48GCLi4sr7MMoUVasWOHO6dtvvx3ep5+9SpUqRfV6vVbXxaP30T69r6dTp07uBgAoOQi6AaAE8hrz3i0hIcHq1q3rAoQ1a9YU9uEVi0DeO3elSpWyatWqWYsWLaxPnz42c+ZMi2U7d+60Bx980Fq1auWCzfLly1vz5s3trrvusrVr11pJ8P7779vQoUOtKNA5VaA+e/bswj4UAEAuJeT2hQCAou+hhx6yI444wvbu3Ws//vijC8a///57mzdvnpUrV85KgoULF7rAOL+1bt3abr/9dvf/iYmJNn/+fPvoo4/sjTfesAEDBtizzz5rRdnAgQPt7rvvztf3XLZsmXXp0sVWrlxp//rXv1wnRJkyZez333+3N99808aMGWOLFi2ykhB0699I//79M+w/7LDDbM+ePVa6dOlcva9eqw6wnEyaNGm/oFudHOoI0s8kAKD4IegGgBLszDPPtOOOO879/7XXXmuHHHKIPfnkk/bZZ59Zz549rSQoW7ZsIO+ryoDLLrsswz6du0suucSee+45a9Sokd1www1WVCm4O1CA50dqaqpdcMEFtmHDBps6daqdfPLJGR5/9NFH3fkpyVT5kJfOqmheq04MAEDJQnk5AMSQU045xW2XLl0a3pecnGwPPPCAtW3b1qpWrWoVK1Z0z5syZUqW41mHDBlir7/+ujVs2NAFvMcff7z9/PPP+32WssLNmjVzgYbKj5UFVXm7MnaR0tPTXSnvMccc455bq1Yt69u3r23bti1XY7q90vrp06fbbbfdZjVq1HDf6fzzz7dNmzZZXqiU+r333rPq1au7IDMUCoUf2717t8uM169f352XJk2auHMV+RzRsd18883h86P3bN++vc2dO9c9/tprr9lRRx3lzoXG9kaO95Vp06a5LHODBg3c5+jzlHlXFvVAY7q9zx47dqy7Jnq9zvuXX355wO/+n//8x+bMmWP33XfffgG3VKlSxZ2TSPqO+rnSd1SHjzoxMg9v8MZEK3t+9tlnu/9Xh8ewYcPc4zovnTt3dtdQmWZloSN51/u7775zPzcHH3ywO5bLL798v5+hTz/91Lp372516tRx310/ww8//LClpaWFn6NzPn78ePvrr7/CQwy8n9msxnRHVgF07drVHafeX1UmWV37yDHdWYkc063ODf37kquuuip8PPr8QYMGuYx7Vj/TqkDQkAhVuAAACh9BNwDEEC+AO+iggzKM0R0+fLhr6CtTqaBADXkFEFmNI1XQ8/TTT7sA55FHHnHvqQxoSkpK+DkKWnr16uWCgscff9w9fs0119ivv/663/vpff7973/bSSedZM8//7wLLkaOHOk+P/I9/erXr58LEhWcKCP9+eefu4AzrxQUKoBX8Pjnn3+6fQquzj33XJcB79atmys9V9Ct76XAPzMFzgrQr7jiCne+VbqugFOB5gsvvGA33nije+0PP/xgV1999X6BbFJSkvtOL774ojtP2irIjIaGF+j9L7roInvqqadcYHbhhRfali1bcnydqiOkd+/eUX2OAkNVU8THx7ufgeuuu84++eQTF7Bv3749w3MV9KoqQx0IOiYFubpWeg+dT1Vr6GezcuXK7nsuX758v8/T83UedT71HP0M9ejRI0Pgq/fT9dM10c+aOgTU4RRZhq9OBZVxq5NAHSy6HWh8t45fx6kOIx2/3lc/d7rlRdOmTV3w7gXS3vH84x//cNdB1QejR4/O8Bp1on388cfumpaUISQAUOyFAAAlzogRIxRphL766qvQpk2bQqtWrQp9/PHHoRo1aoTKli3r7ntSU1ND+/bty/D6bdu2hWrVqhW6+uqrw/uWL1/u3vPggw8Obd26Nbz/008/dfs///zz8L4WLVqE6tWrF0pMTAzvmzp1qnveYYcdFt43bdo0t2/kyJEZPv/LL7/Mcn9W9H5XXHHFft+9S5cuofT09PD+AQMG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91i7ke2s1but3Fb3tb84/2HPyuZd++yVqUvdFgCAWP5bfeWVVxZowJeVDh062Lp166xq1aoWixYuXOgCzJzo+j7wwAN26KGHWvny5a1Lly62ePHiHF/z3Xff2TnnnGN16tRxgevYsWNz1Q7aunWrXXrppValShXX8XHNNdfYrl27DtipktXto48+Cj8vq8dHjRoVfrxXr17u56J9+/ZRHSeA4FBenkcp6Sk2eMZg+2zpZxYfF29poTRL21fTEveZjZv/q306/yc7tf6pdlPrmyyhVMk43X9t2R3elkmg3wYAULSlpqfasNnDbMqqKRZv8ZZmlSy+bJIlpSbZhOUTbNyycXZuw3NtcIfBVrpUaStuypQpY7Vr1873901JSbHSpYv++ahZs+YBs/hPPfWUvfDCC/bOO+/YEUccYffff7917drV/vzzTytXrlyWr9m9e7e1atXKrr76arvgggtyfXwKuBX8Tp482Z3Tq666yvr06WPvv/9+ls+vX7++e36k119/3Z5++mk788wzM+wfMWKEdevWLXw/8jyoc0E3/XwAKFwlIwosJOo1VcD9+dLP3X0F3JK07LYMzxu/zGz8tzOspLnp/VmFfQgAAESpzX9vf6vc9O4Mf7u9v+WPnPSIyxjmVqdOnaxly5YukBs+fLgLeK6//nobPHiwe/ySSy6xtLQ0Gz16dPg1CsSUgX322Wft8ssvty+//NIeeeQRmzdvnsXHx7tM5fPPP28NGzbMtsz61FNPtW3btoWDLmV+ldndvHmzCy5PPvnkHI9b2VUFo8qUvvzyyzZz5kx79dVXXab35ptvdllfvb+O4d5777WLL7446u8sCxYssGuvvdZ++eUXO/LII10AfPrpp9uYMWPClQKrVq2y22+/3SZNmmSlSpWyU045xX3vww8/3PLaXhs6dKgNHDjQzjvvPLfv3XfftVq1arns9UUXXZTl6xTgZg5y/Zo/f767nj///LMdd9xxbt+LL75oZ511lg0ZMsRl0TPTNc/ciaLz1LNnT6tUqVKG/breQXS4AMhfpCnz4PfNv7sMd8hKVvk4AACxRn/L9Td97ua5eX4vZVMrVqzoAldlWB966CGX5fSynp9//nmG8uKJEydaUlKSnX/++eEM62233eYC1K+//toFoHosPT09qs/X56qEWcGyxn0rIFcQH427777bbr31VhcsKljf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E5o5c2bo+++/DzVq1Ch08cUXhx9fvXp1qEmTJu5x2bFjh5vxukWLFqElS5aE1q1bF75p9l0UnFGjRoXKli0bevvtt91M9H369AlVq1YttH79evd47969Q3fffXf4+dOnTw8lJCSEhgwZEpo/f76bGbB06dKhuXPnctmK4fV84okn3KoBH3/8cYZ/h4mJiYX4LZCba5kZs5cX7+u5cuVKt5LAzTffHFq4cGFo3LhxoZo1a4YeeeSRQvwWyM211N9JXcsPPvggtGzZstCkSZNCDRs2dKuBoPDp792sWbPcTU3lZ5991v3/X3/95R7XtdQ19egaVqhQIfTvf//btYOGDRsWio+PD3355ZeF+C2Qm2s5cuRI16bVNYxsA23fvp0TWgyvZ2aFOXt5YEH3li1bXJBdqVKlUJUqVUJXXXVVhkb78uXL3cmaMmWKu6+t7md103NRsF588cVQgwYNXPClpVB+/PHH8GMdO3Z0jffMy7s1btzYPV/LZowfP55LVkyv52GHHZblv0P9okLx+7cZiaC7+F/PGTNmuA5qBXhaPuzRRx+lY7oYXksthTp48GAXaJcrVy5Uv3790I033hjatm1bIR09ImXXJvWuoba6pplf07p1a3f99W9zxIgRnNRieC31/zk9H8Xv32ZRCbrj9J+Cza0DAAAAABAbmKkDAAAAAICAEHQDAAAAABAQgm4AAAAAAAJC0A0AAAAAQEAIugEAAAAACAhBNwAAAAAAASHoBgAAAAAgIATdAAAAAAAEhKAbAIASolOnTta/f//CPgwAABCBoBsAgCLgnHPOsW7dumX52LRp0ywuLs5+//33Aj8uAACQNwTdAAAUAddcc41NnjzZVq9evd9jI0aMsOOOO85atmxZKMcGAAByj6AbAIAi4Oyzz7YaNWrY22+/nWH/rl277KOPPrIePXrYxRdfbHXr1rUKFSpYixYt7IMPPsjxPZUdHzt2bIZ91apVy/AZq1atsp49e7r91atXt/POO89WrFiRz98OAIDYRdANAEARkJCQYJdffrkLiEOhUHi/Au60tDS77LLLrG3btjZ+/HibN2+e9enTx3r37m0//fRTrj8zJSXFunbtapUrV3Yl7NOnT7dKlSq5Mvfk5OR8+mYAAMQ2gm4AAIqIq6++2pYuXWrffvtthtLyCy+80A477DC74447rHXr1nbkkUdav379XHD84Ycf5vrzRo8ebenp6TZ8+HCXOW/atKn7vJUrV9rUqVPz6VsBABDbCLoBACgijj76aOvQoYO99dZb7v6SJUtcBlrjvZXtfvjhh11wrDJwZaQnTpzoAuTcmjNnjvsMZbr1frrpvffu3euCfwAAkHcJ+fAeAAAgnyjAVhZ72LBhLuvcsGFD69ixoz355JP2/PPP29ChQ13gXbFiRbc8WE5l4BrTHVmq7pWUR44XV8n6yJEj93utxpcDAIC8I+gGAKAI0aRmt956q73//vv27rvv2g033OCCZ4231iRnGtstKgtftGiRNWvWLNv3UuC8bt268P3FixdbUlJS+P6xxx7rSsxr1qxpVapUCfibAQAQmygvBwCgCFGJd69eveyee+5xAfOVV17p9jdq1MgtKTZjxgybP3++9e3b1zZs2JDje3Xu3NleeuklmzVrlv3yyy92/fXXW+nSpcOPX3rppXbIIYe4YF5l7MuXL3djuW+55ZYsly4DAAD+EXQDAFAES8y3bdvmZhavU6eO2zdw4ECXmda+Tp06We3atd0yYjl55plnrH79+nbKKafYJZdc4iZi03JjHv3/d999Zw0aNLALLrjATaSmz9aYbjLfAADkj7hQ5sFeAAAAAAAgX5DpBgAAAAAgIATdAAAAAAAEhKAbAAAAAICAEHQDAAAAABAQgm4AAAAAAAJC0A0AAAAAQEAIugEAAAAACAhBNwAAAAAAASHoBgAAAAAgIATdAAAAAAAEhKAbAAAAAICAEHQDAAAAAGDB+H83smQNNd4CYAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Outer transformation domain\n", + "domain_lower = 0.0\n", + "domain_upper = 1.0\n", + "\n", + "# A valid preceding range\n", + "valid_lower = 0.25\n", + "valid_upper = 0.75\n", + "\n", + "# An invalid preceding range\n", + "invalid_lower = -0.1\n", + "invalid_upper = 0.75\n", + "\n", + "plt.figure(figsize=(10, 4))\n", + "\n", + "# Draw the outer domain\n", + "plt.hlines(\n", + " y=2,\n", + " xmin=domain_lower,\n", + " xmax=domain_upper,\n", + " linewidth=6,\n", + ")\n", + "plt.scatter(\n", + " [domain_lower, domain_upper],\n", + " [2, 2],\n", + " s=70,\n", + ")\n", + "\n", + "# Draw the valid inner range\n", + "plt.hlines(\n", + " y=1,\n", + " xmin=valid_lower,\n", + " xmax=valid_upper,\n", + " linewidth=6,\n", + ")\n", + "plt.scatter(\n", + " [valid_lower, valid_upper],\n", + " [1, 1],\n", + " s=70,\n", + ")\n", + "\n", + "# Draw the invalid inner range\n", + "plt.hlines(\n", + " y=0,\n", + " xmin=invalid_lower,\n", + " xmax=invalid_upper,\n", + " linewidth=6,\n", + ")\n", + "plt.scatter(\n", + " [invalid_lower, invalid_upper],\n", + " [0, 0],\n", + " s=70,\n", + ")\n", + "\n", + "# Labels\n", + "plt.text(\n", + " domain_upper + 0.03,\n", + " 2,\n", + " \"Outer domain [0, 1]\",\n", + " va=\"center\",\n", + ")\n", + "\n", + "plt.text(\n", + " valid_upper + 0.03,\n", + " 1,\n", + " \"Valid range [0.25, 0.75]\",\n", + " va=\"center\",\n", + ")\n", + "\n", + "plt.text(\n", + " invalid_upper + 0.03,\n", + " 0,\n", + " \"Invalid range [-0.1, 0.75]\",\n", + " va=\"center\",\n", + ")\n", + "\n", + "# Show the domain boundaries\n", + "plt.axvline(\n", + " domain_lower,\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "\n", + "plt.axvline(\n", + " domain_upper,\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "\n", + "plt.yticks([])\n", + "plt.xlabel(\"Value\")\n", + "plt.title(\"Range-in-Domain Compatibility\")\n", + "\n", + "plt.xlim(-0.2, 1.45)\n", + "plt.ylim(-0.6, 2.6)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "71bc28b4", + "metadata": {}, + "source": [ + "The middle interval is compatible because\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "The bottom interval is incompatible because part of its range lies outside the accepted domain:\n", + "\n", + "$$\n", + "[-0.1,0.75] \\nsubseteq [0,1].\n", + "$$\n", + "\n", + "This illustrates why exact equality is not required. The preceding range only needs to remain completely within the next transformation's domain." + ] + }, + { + "cell_type": "markdown", + "id": "6cb86fb2", + "metadata": {}, + "source": [ + "### Two different questions\n", + "\n", + "For chained `TrueMeasure` compatibility,\n", + "\n", + "$$\n", + "T_{j-1}\n", + "\\longrightarrow\n", + "R_{j-1} \\subseteq D_j\n", + "\\longrightarrow\n", + "T_j.\n", + "$$\n", + "\n", + "The question is whether the output of one existing transformation can legally become the input of the next. Gaussian-to-Logistic transport asks a different question: how to construct a deterministic transformation between two probability measures,\n", + "\n", + "$$\n", + "X_G \\xrightarrow{\\Phi} U \\xrightarrow{F_L^{-1}} X_L.\n", + "$$\n", + "\n", + "These are related through transformation boundaries, but they are not the same operation.\n", + "\n", + "# Exploring Gaussian, Uniform, and Logistic transformations\n", + "\n", + "The domain-inclusion change solves compatibility between transformations whose existing maps can already be composed.\n", + "\n", + "A separate question is how transformations between different probability measures should be ordered.\n", + "\n", + "This distinction is important for Gaussian, Uniform, and Logistic distributions." + ] + }, + { + "cell_type": "markdown", + "id": "e371beb8", + "metadata": {}, + "source": [ + "Let\n", + "\n", + "$$\n", + "U \\sim \\mathrm{Uniform}(0,1).\n", + "$$\n", + "\n", + "A standard Gaussian variable can be generated using the Gaussian inverse CDF:\n", + "\n", + "$$\n", + "X_G = \\Phi^{-1}(U).\n", + "$$\n", + "\n", + "Similarly, a standard Logistic variable can be generated using\n", + "\n", + "$$\n", + "X_L = F_L^{-1}(U),\n", + "$$\n", + "\n", + "where $F_L$ is the Logistic CDF.\n", + "\n", + "Thus both inverse-CDF transformations naturally have the form\n", + "\n", + "$$\n", + "(0,1) \\rightarrow \\mathbb{R}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "27e23c13", + "metadata": {}, + "source": [ + "## Gaussian to Logistic\n", + "\n", + "If the starting variable is Gaussian,\n", + "\n", + "$$\n", + "X_G \\sim N(0,1),\n", + "$$\n", + "\n", + "we cannot directly apply another inverse CDF expecting a unit-uniform input.\n", + "\n", + "We first map the Gaussian variable back to the unit interval using its CDF:\n", + "\n", + "$$\n", + "U = \\Phi(X_G).\n", + "$$\n", + "\n", + "Then apply the Logistic inverse CDF:\n", + "\n", + "$$\n", + "X_L = F_L^{-1}(U).\n", + "$$\n", + "\n", + "Therefore,\n", + "\n", + "$$\n", + "X_G\n", + "\\xrightarrow{\\Phi}\n", + "U\n", + "\\xrightarrow{F_L^{-1}}\n", + "X_L.\n", + "$$\n", + "\n", + "The mathematical transport is\n", + "\n", + "$$\n", + "\\mathrm{Gaussian}\n", + "\\rightarrow\n", + "\\mathrm{Uniform}\n", + "\\rightarrow\n", + "\\mathrm{Logistic}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "31f4f483", + "metadata": {}, + "source": [ + "Similarly,\n", + "\n", + "$$\n", + "X_L\n", + "\\xrightarrow{F_L}\n", + "U\n", + "\\xrightarrow{\\Phi^{-1}}\n", + "X_G\n", + "$$\n", + "\n", + "gives\n", + "\n", + "$$\n", + "\\mathrm{Logistic}\n", + "\\rightarrow\n", + "\\mathrm{Uniform}\n", + "\\rightarrow\n", + "\\mathrm{Gaussian}.\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 627, + "id": "9971e708", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.561586Z", + "iopub.status.busy": "2026-08-18T03:05:33.561327Z", + "iopub.status.idle": "2026-08-18T03:05:33.565751Z", + "shell.execute_reply": "2026-08-18T03:05:33.564715Z" + } + }, + "outputs": [], + "source": [ + "from scipy.stats import norm, logistic" + ] + }, + { + "cell_type": "code", + "execution_count": 628, + "id": "4ae2f185", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.568562Z", + "iopub.status.busy": "2026-08-18T03:05:33.568239Z", + "iopub.status.idle": "2026-08-18T03:05:33.579232Z", + "shell.execute_reply": "2026-08-18T03:05:33.577822Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Gaussian xPhi(x)Logistic transport
0-2.00.022750-3.760171
1-1.00.158655-1.668268
20.00.5000000.000000
31.00.8413451.668268
42.00.9772503.760171
\n", + "
" + ], + "text/plain": [ + " Gaussian x Phi(x) Logistic transport\n", + "0 -2.0 0.022750 -3.760171\n", + "1 -1.0 0.158655 -1.668268\n", + "2 0.0 0.500000 0.000000\n", + "3 1.0 0.841345 1.668268\n", + "4 2.0 0.977250 3.760171" + ] + }, + "execution_count": 628, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x_gaussian = np.array([-2.0, -1.0, 0.0, 1.0, 2.0])\n", + "\n", + "u = norm.cdf(x_gaussian)\n", + "x_logistic = logistic.ppf(u)\n", + "\n", + "pd.DataFrame(\n", + " {\n", + " \"Gaussian x\": x_gaussian,\n", + " \"Phi(x)\": u,\n", + " \"Logistic transport\": x_logistic,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 629, + "id": "08e326eb", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.582175Z", + "iopub.status.busy": "2026-08-18T03:05:33.581892Z", + "iopub.status.idle": "2026-08-18T03:05:33.593505Z", + "shell.execute_reply": "2026-08-18T03:05:33.592557Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Original GaussianRecovered GaussianAbsolute error
0-2.0-2.08.881784e-16
1-1.0-1.00.000000e+00
20.00.00.000000e+00
31.01.00.000000e+00
42.02.02.220446e-15
\n", + "
" + ], + "text/plain": [ + " Original Gaussian Recovered Gaussian Absolute error\n", + "0 -2.0 -2.0 8.881784e-16\n", + "1 -1.0 -1.0 0.000000e+00\n", + "2 0.0 0.0 0.000000e+00\n", + "3 1.0 1.0 0.000000e+00\n", + "4 2.0 2.0 2.220446e-15" + ] + }, + "execution_count": 629, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u_back = logistic.cdf(x_logistic)\n", + "x_gaussian_back = norm.ppf(u_back)\n", + "\n", + "pd.DataFrame(\n", + " {\n", + " \"Original Gaussian\": x_gaussian,\n", + " \"Recovered Gaussian\": x_gaussian_back,\n", + " \"Absolute error\": np.abs(x_gaussian - x_gaussian_back),\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a47742ab", + "metadata": {}, + "source": [ + "The recovered Gaussian values agree with the original values up to floating-point roundoff (approximately $10^{-15}$ in this example).\n", + "\n", + "Numerically, this confirms the inverse relationship\n", + "\n", + "$$\n", + "\\Phi^{-1}\\left(F_L\\left(F_L^{-1}(\\Phi(x))\\right)\\right)\n", + "\\approx x.\n", + "$$\n", + "\n", + "The tiny nonzero errors are ordinary floating-point numerical error, not a failure of the mathematical inverse relationship." + ] + }, + { + "cell_type": "markdown", + "id": "32d9d79c", + "metadata": {}, + "source": [ + "### Visualizing the Gaussian-to-Logistic transport\n", + "\n", + "The complete deterministic map from a Gaussian value to a Logistic value is\n", + "\n", + "$$\n", + "T(x)=F_L^{-1}(\\Phi(x)).\n", + "$$\n", + "\n", + "The following plot shows how Gaussian input values are mapped into Logistic output values." + ] + }, + { + "cell_type": "code", + "execution_count": 630, + "id": "2d70d570", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-18T03:05:33.596674Z", + "iopub.status.busy": "2026-08-18T03:05:33.596352Z", + "iopub.status.idle": "2026-08-18T03:05:33.926487Z", + "shell.execute_reply": "2026-08-18T03:05:33.924934Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAjV9JREFUeJzt3Qd4VMXXBvA3vXcSkpAQSOi9994RAQERUAEREbuIoqKilM/C3wKIvaGiiKiAHSkiKL33DiEBQkkhlfT9njPLbrJppG225P09z5Ls3TY7ezfcc2fOGRuNRqMBERERERFRBdhW5MFEREREREQMLIiIiIiIqFJwxIKIiIiIiCqMgQUREREREVUYAwsiIiIiIqowBhZERERERFRhDCyIiIiIiKjCGFgQEREREVGFMbAgIiIiIqIKY2BBRFbryy+/hI2NDSIjI03dFLMl/TN79myDbbt27UKXLl3g5uambt+/f7/J2lcdSP9LP1eW++67D3Xq1Km05yMiKi0GFkRUpHPnzuGxxx5DgwYN4Orqqi5NmjTBo48+ioMHD7LXqpAcJN5+++1F3rZ79251UCpBVGXIysrC6NGjER8fjwULFmDp0qUICwtDdSABqPTlW2+9BXN36dIlFZAYK+j7559/VF+U5lJdGfszILJE9qZuABGZn99++w1jxoyBvb097rnnHrRs2RK2trY4fvw4Vq5ciQ8//FAFHuZ+wDl+/HiMHTsWTk5Opm6K2bpx44b6nHXOnDmD8+fP49NPP8UDDzxg0rZVFy+99BKef/75Mh/UzpkzRwWdrVq1MrhNPrvc3NwKtalx48YqqMxv5syZcHd3x4svvlih57YWJX0GRNUVAwsiMiAHlnIwLkHDhg0bEBQUZHD7/Pnz8cEHH6hAw9zZ2dmpCxXP2dnZ4PrVq1fVT29v70rrttTUVDWtioomgV3+4K6iHBwcKvwcNWvWxL333muw7Y033kCNGjUKbc9PAprMzMxC+5U1yc7OrnDgRmStzP/IgIiq1P/+9z91ILhkyZJCQYWQA6AnnngCoaGh+m0yNUrmdYeHh6sDisDAQNx///2Ii4sr1dzvouaYr1u3Dt26dVMHuHKWtGHDhnjhhRcM7rN48WI0bdpUTdPy8fFBu3btsGzZshJzLH7++WcMGTIEwcHBaiQjIiIC8+bNQ05OjsFz9+rVC82aNcPRo0fRu3dv9Rq1atVS/WPupJ+lzy5evIg77rhD/e7v749nnnmm0PvMn2Mhj+vZs6f6XaZDyW3SDzp///03unfvroIE+VyGDx+OY8eOFflZSr/dfffd6nORzzH/lC6ZZiOflYuLC5o3b66uCxkNk+uyD7Vt2xb79u2DOZLga/LkyergW9oqI3pfffVVofvJ/i+jZp6enqq/Jk6ciAMHDhSaulbW/V/6q3379ur3SZMm6ack6Z6zqO+ZHAgvWrRI37+yPwwaNEhNpasIeV2ZMvntt9+q76J8p9asWaNukyllkqvj5+enPmv5TH/88cdin2P16tXqOyfPIc+lex6d5ORkTJs2Tb03uU9AQAD69++PvXv3Fvre7tmzR722vG7dunXx0UcfletzzD89buHChervhby2nFwp6TMgqq44YkFEhaZB1atXDx07dix1z8hB0NmzZ9V/sBJUHDlyBJ988on6uX379jLPw5bHyQFoixYtMHfuXPUf+enTp7FlyxaD6R4S4Nx555148sknkZ6ergKcHTt2qAPa4sh//HKgNn36dPVTDpZffvllJCUl4c033zS4b0JCgjr4GjlyJO666y51UPTcc8+pg7PBgwejovkrX3/9tTroMgYJIAYOHKg+RzkoWr9+Pd5++211YPTwww8X+ZipU6eq4Om1115TfSsHTnLQJeTx8p4leJQDYZlCJYFd165d1YFdwQNZCUzq16+vnkuj0ei3y+con4+8lpz5lrYNHTpUHfjJgfMjjzyi7vf666+rPj9x4kSFRsdkP5GpXf/3f/+HyiDvWw5e5X3IZygHrT/88IM6mL9+/braF3UH8vK+du7cqfq7UaNGKqiV4KKi+79MU5Ltst8++OCDKtgTciBdHDmAln1fPkOZ4iZn3f/991/1/ZQgryLkO7RixQrVHzKiodsXJJAZNmyYmk4poxjLly9X+4X8jZHgPr///vtPBZby+Xt4eODdd9/FqFGjEBUVpf+OPPTQQ+o7KK8j+V4SuMnjJLht06aNwff2tttuU/vPuHHjVNvkM3B0dFQnPMryOerIiRb5GyP9LZ/HiBEjVKBTls+AqFrQEBHdlJiYKEeAmjvuuKNQnyQkJGiuXbumv6Slpelvy/+7znfffaeea/PmzfptEydO1ISFhRW67yuvvKLuq7NgwQJ1XV6nOMOHD9c0bdq0xM9uyZIl6nnOnTtXYlunTp2qcXV11aSnp+u39ezZUz3266+/1m/LyMjQBAYGakaNGqWpiKNHj2oCAgI0bdq0Uf16K9JnQ4YMKfK2Xbt2qXbKe83fz7Jt7ty5Bvdt3bq1pm3btgbb5H7S/zobN25U23744QeD+7Vq1Uq1OS4uTr/twIEDGltbW82ECRMKfZbjxo0r8n3IbVu3btVv++uvv9Q2FxcXzfnz5/XbP/74Y7Vd2lMRb7/9tnqeOXPm3PK+sp/Ifd98881i77Nw4UJ1n2+++Ua/LTMzU9O5c2eNu7u7JikpSW376aef1P3k/jo5OTmaPn36FPq8yrP/F/W5F/c9+/vvv9V9n3jiiUL3zc3N1ZSWfN/ke5GfPK/sA0eOHCl0/4LfNemnZs2aqT4o+ByOjo6a06dPG+xbsn3x4sX6bV5eXppHH320xDbqvrfyuef/3ur2X2lDWT5H3T7h6empuXr1aqk/A6LqilOhiEhPztoLOZNfkJzdk+kTusv777+vv02mG+jIWb3Y2Fh06tRJXc8/TaG0dPP75QxvcXOZ5T4XLlxQpVHLIn9b5YyjtFXONqalpank9PykH/LPJ5cznh06dFCjMyWRs8HSD8Vd5OyonLWV55FRBV2/VzY5w5ufvM9btb0oMTExqvKNnM319fXVb5cz6jIV5Y8//rjla+vImebOnTvrr+tGxvr06YPatWsX2n6r9mZkZJTY13IGXM4qv/LKKyo/qKLkvcqonJwJz5/TICM8KSkp2LRpk9om03hk+5QpU/T3k5EXqapWGft/Wfz0009q1FD6oKDKqOok0+fkcy3puyajCImJiWofLOpvQr9+/dRoWv59S6aQ5f/8pV9kRFKSpksi0zVlRCz/91auy9QnmSJVls9RR0ZP5O8eEZWMgQUR6ckUBCH/sRb08ccfqylP33zzTaHbpDSpTB2QaTNyMCH/AcvBs5CDibKSilQyxUambMhzSjK5TGfIf5AlU5LkwF8O9GXKjRyw5Z8qVdI0E5nG4OXlpQ5cpK264KFgW0NCQgodeEnOgBwklUQq/Eg/lHSRdsuUC5kqUzB3pDwKtlM3j76sbS+KTCUSMs+/IJmWI8GZ5OXkp/v8C8ofPAj5HET+nJ3822/VXpm6dau+lmlDus+lrIFoUX0h+1vB6VnSD7rbdT8lR0lyc/KTaYaVsf+XtSCD5BTlDworU3GftQTPcoJB9kV5bdkfpaJcUX8TCu4XRe2vkt90+PBhta/I90em5BUVeMp7LVgsQMpmC12+VWk/x1u9RyIyxBwLIjI4mJODIfnPuyDdGeSiFpuTucxbt27FjBkzVNlFOeCXgyDJT8h/MFTc2dGCCcVyMLh582Zs3LgRv//+uzr7+/3336uz2mvXrlWVnuQAQObfy8GL3C5nZSWhUs5OSwnIosiBvJxdlYBCDjblDKkc9MgZVAlUCh64FVdRKn/OQFHkQFASSEsiZ9OlfKeMbpSUEyKkjTInvCgy0qK7T2naXlXyn60uTbvK29fvvfee6suSyFlquZ8kQxd1Zt3clGb/NydFfdaSvyH5FT169FDfS/m7IiMCkquQv8BCWT5/+TsjIx6rVq1S/SA5UTIKJbkZFcl5qsj+TESGGFgQkQFJqvzss8/UmXQ5K3grckZRytLKwbwc1OucOnWqyDOQcnBfUMGzg0LOJPbt21dd3nnnHZUELPXz5WBLpk0IOSspZ3flIsmhkmT96quvqgP2ospdSjUdSfiUAxE54MmfTF2ZJBm2pIRYaatUa5Kff/755y0TPqX0r1RZKooEV7r7GIvuuXWvlZ9MH5OEXVOVk5UgriRShenpp59W069k+ktF2yl9IUUCJAjNf7ZbN41O11fyU/ZVCfzyj1pIsnBp3Gr/L8sUJgmg//rrLzWyaKxRi4Ik0JfvoLxu/nVkJLCoCAlQZHqbXGRqkyRty3c+f2AhU6UKljg+efKk+qlLLC/t51iS6rw4IFFxOBWKiAw8++yz6kBIqqdcuXLllmeQdWcaC26X0oxFHeDINIj8K3fL/H05A5mfHAAVpFuASubUi4KlbGUetZyNlnbI6tFFKaqtcnAvZ1SrkpzNlTncv/zyi0GAUxypcCP5JFKOMz/pCwkCpexm/qo4lU0O5qT/pRRn/sBQRrbkzLG0z1zJQblUspIATjfVryLkvV6+fFmNIOjIqJNUyJKROl25Xsmdkf1QqlLpyEFs/tyk4pRm/9cdNBcVqBck+QGyzxc1knerEaHyku+aHHjnH42U0c6C+3BpyfMUnEIl+71Me9L1Sf7PQ6Zu5v+Oy3WZiiUlb8vyOZakLJ8BUXXBEQsiMiDzjmWqgiQ1ypx63crbcgAiZ/blNjnDJ/kHQqYVycGxzH+WAymZ8y4Hm0WNAsjZZZlyJDkOkiQpZ3NlzrXMf86f0CnTlGQqiIyeyJlDOTMpB//ymro1EQYMGKCSL2UuusxDl5KTMt1FHlPcAaSMDMioiZT8lNeXAx9ZXdhYB1fFkbPQMu9d2l8aUs7yiy++UKU6JeBr3bq1CqzkoEgO7qVsrQRWxiTTTuSssJz5l9KlunKzMn1Otw6GOZKyx9JWXc5GacgIXFHTq2SUST4LOUiVRHaZYiVnwKUEquT3SDCt2/fkvjLiJ6MlMkoh5WYlkNQFDSWd7S7N/i9BuiQzS5leeU05yJXpikXlAsg6LLKehpRwlZFE3RRFCXDlNim3Wtmk7RLUyWvJVD95DxJUSY5J/hMLpSWFFuT9S3lp+XskB/9SAllyZqSMcn4SbMgUKQlk5G+LfE+k+IDsC7rFA0v7OZakLJ8BUbVh6rJURGSepPTjww8/rKlXr57G2dlZlQNt1KiR5qGHHtLs37/f4L4XLlzQjBgxQuPt7a1KQo4ePVpz6dKlQqVMxdq1a1XJSSkv2bBhQ1XusWC5zQ0bNqhyssHBwep+8lPKl548edKgHGmPHj00fn5+GicnJ01ERIRmxowZqmRuSeVmt2zZounUqZN6P/K8zz77rL7kaf7SplK2sqhytsWVzDU2KUv71FNPaerWratxcHBQ5S979+6t+fPPP4tso5ubW6HtBfu5LOVmxfr16zVdu3ZVfSevP3ToUFU6t6jXKKpUanFlc+X+BcuIlqb0a2XTvWZxl6VLl6r7XblyRTNp0iRNjRo11P7ZvHnzIkuOSh/cfffdGg8PD/W9uO+++9T+J8+1fPly/f3Ks/+Ln3/+WdOkSRONvb29QdnTovbR7Oxs1ZfyHZbn9Pf31wwePFizZ8+eCpebLa4E7Oeff66pX7+++n7K60r7itsHi3oOeQ/yXnQlY+X73bJlS9Wfsn/L7x988IHBY3Tf2927d6vSsfK3S57nvffeK/T8pfkcb7UfFvcZEFVXNvKPqYMbIiKi6kCmAsmInSzsJqNtVLmkLLZUKSuqAAURGR9zLIiIiIygYCUvyROQ6WMyfdCYOTFERKbCHAsiIiIjePzxx1VwIXkpkmAs1cikLLNUeGL5UiKyRgwsiIiIjEDWnZDEYllrRZLBJXFZRiyMkSxNRGQOmGNBREREREQVxhwLIiIiIiKqMAYWRERERERUYcyxKCNZVOjSpUtqMZySFjgiIiIiIrJ0sjKFLFIpi0/KArklYWBRRhJUhIaGVuTzISIiIiKyKNHR0QgJCSnxPgwsykhGKnSdK7XIqXSjPAkJCfDx8bllpEsVx/6uOuxr9rW14r7NvrZG3K/LJykpSZ1U1x0Dl4SBRRnppj9JUMHAovRf5OzsbNVfDCyMj/1dddjX7GtrxX2bfW2NuF9XTGlSAHj6mIiIiIiIKoyBBRERERERVRgDCyIiIiIiqjDmWBhJTk4OsrKyjPX0FjenUfoiPT2dORZm1t8ODg6ws7OrimYRERGRlWNgYYRav5cvX8b169cr+6ktuk90lRi49of59be3tzcCAwP52RAREVGFMLCoZLqgIiAgAK6urjxYu3mgK1Wh7O3t2R9m1N9yv7S0NFy9elVdDwoKqormERERkZViYFHJ0590QYWfn19lPrVFY2Bhvv3t4uKifkpwIfstp0URERFReTF5uxLpcipkpILIUuj2V+YEERERUUUwsDAC5hGQJeH+SkRERJWBgQUREREREVUYAwsiIiIiIqowBhZUaUaMGAEfHx/ceeed7FUiIiKiaoaBBVWaJ598El9//TV7lIiIiKgaYmBBlaZXr17w8PAo8ra4uDjUrFkTkZGR5XpuebyUQy3L48eOHYu333671NuJiIiIzE1KRjYiY1NhCRhYkF7Pnj1VhaD8F1nXICUlpcK99MYbb2DYsGGoU6dOkbfv379fvV5xgcOrr76K4cOHF/v4orz00kvqcYmJiaXaTkRERGROrial466PtuGez3bgSlI6zB0DC9IvqrZv3z689dZbiImJMbi4u7ujVatWaNasWaHLpUuXbtmDsrrzkiVLMHny5EK3HT16FBMnTlT5GaJ///548MEHDQIMefznn39e5ONLIu2LiIjAN998U6rtRERERObi9NUUjPhgK47GJOHi9RuYtnw/zB0DC1JOnTqF5ORk9OjRA4GBgfqLTD/SjSgcPny40CU4OPiWPfjHH3/AyckJnTp1Mti+cuVKtGzZUr3u9OnT1bZnn30W586dQ9OmTbFly5YSH//dd9+plaMl+NGZNGkSWrRooR+NGDp0KJYvX16oTcVtJyIiIjK13ZHxuPOjrSqgELW8XTDvjqYwdwwsSNmzZw/s7e3VQXll+/fff9GmTRuDbZmZmZg6dSoGDhyoAozu3bvrRyz+/PNPNG7cGI888oj+8W3bti0yV6JBgwZ47bXX1PVXXnkF69evV4/38vJS2zp06ICdO3ciIyPD4LHFbSciIiIypTWHY3D3ZztwPS1LXW8c5ImVj3RBvYCi81jNCQMLUvbu3YucnBz4+fmpqU9y6dq1a5l6p1+/fhg9erQaYQgJCcG2bdvU9qioKAQFBRnc99ChQ4iNjcX48eMLPY8EOPI8Bw8eRHx8PM6fP1/kyIjkZEiuxKeffqp+Ll68GGvWrEGtWrX095HHSRBz+fJlg8cWt52IiIjIVL7ccg4Pf7sXmdm56nq3ejWwYmon1PR0togPxd7UDSDzCSzGjRuHOXPm6Le5ubmV6TlktKAoN27cKBRYSE6HLjgoim673E8e7+xc9Bfq9ttvR5MmTTB37lysXbtWTaHKT6ZK6fI0SrOdiIiIqKrl5mowf81xfLz5rH7byNa18MaoFnC0t5xxAAYWRjZ08X+4llz10238PZzw6+PdyhRYvP7666hXr16h29555x01uqCbclRWNWrUQEJCgsE2mXIloyPffvst7rrrLoPbZOTkxx9/VEnWcp+iHq8jIxTHjx9Xj5FytgXJiIfw9/cv1XYiIiKiqpSelYMZPx7ErwfyCuI80isCMwY2LPYErLliYGFkElRcNvPyYGfPnsX169fRunXrIm+XJG2Z5lReUlGqYAUmR0dHfPDBB7j77rtVYCFrYIiNGzdixYoVaqqUjEAIaVdRFZwkGJLHSsWoL7/8ErNmzcIPP/xQqO0yLUuCk9JsJyIiIqoq8amZePDr3dh9XnsC1dYGmDO8GcZ3CrPID4GBRRWMHJj760ritqxXUVzithyET5s2rdxtkQTtF154QY06+Pr66rdLUCBJ2vPnz1cXIVOaevfujSNHjiA8PFz/+JkzZ6rH+/j4qG1SjnbIkCHqeWUKl9y3c+fOKtjInyguid8DBgwo1KbithMRERFVhXOxqZi0ZCci47TTsl0c7PDuuNbo36TwDAxLwcDCyMoyHclU5GC8UaNG+ryD/CTHQUrRyu3l1bx5czXqICMRDz30UKHbZDRCytnKfWTEouAieHIfCRbk8VJJSqYxDRo0SC2Y9/zzz6v7dOzYEYMHD1aBhkyPEunp6Vi9erX+uk5x24mIiIiqqpzslK93I+Fm5aca7k744r52aBHibdEfgOVkg5DRSG6FjEoURdaUkMRrmbpUES+++CLeffdd5OZqqxwUNV1KgpjiVtZ++eWXsWjRIvV4GfWQvIqPPvrI4D6///67QbAgi/JJWdmC618Ut52IiIjI2H49cEmVk9UFFQ1qumP1o10sPqgQHLGgEknAUbDSUnncdtttKpfj4sWLCA0NLfPjZdqTjJyU5fEODg6qBG1ptxMREREZi0ajwYebzuB/a07ot0k52Q/ubQNPZwer6HgGFnTLwEKqM1UGydOoSHWDsuZ5PPDAA2XaTkRERGQMWTm5mLX6MJbvitZvu6tdCF4d0RwOdtYzgch63gkZLbCQs/syRUkusnAdEREREZVOcnoW7v9yl0FQ8cyABpg/qoVVBRWCIxZUomXLlrGHiIiIiMrh0vUbKqg4fjlZXXe0s8Wbo1tgeKtaVtmfDCyIiIiIiCrZ4YuJKqi4enOhZG9XB3wyvh061M0rvW9tLHb8RablyHz9gpdHH320yPvLAmoF7+vs7Fzl7SYiIiIi67bm8GWM/mibPqgI83PFyoe7WHVQYdEjFrt27UJOTo5BLkD//v1LzAHw9PTEiRN5mfiWtkw6EREREZl35acP/jmDN//KO95sU9sbn05oBz930yyaXJUsNrDw9/c3uP7GG28gIiICPXv2LPYxEkgEBgZWQeuIiIiIqDpJz8rBzJWHsGrfRf22O1oF441RLeDsYIfqwGIDi/wyMzPV6s3Tp08vcRQiJSUFYWFhapE1Wcn5tddeu+UaDRkZGeqik5SUpH7KcxRc7E2uS6Squ1Bh7Bfz62/d/lrUPk0l033n2W/Gx76uWuxv9rU1MuZ+HZuSgYe/2Ys9Udf1257uXx+P9IpQx6aW/P9EWdpuFYHF6tWrcf36ddx3333F3qdhw4b44osv0KJFCyQmJuKtt95Cly5dcOTIEYSEhJS4KvWcOXMKbU9ISEB2drbBtqysLNX5sr3gbdVd/mlrZF79Lfuq7LfyvUhLSzNqu6yN9FtycrL6j8rW1mJT1iwC+5r9ba24b1t+X5++loanVp1ATFKmuu5kb4u5t0WgbwNfdbxo6aTPSstGYwWnkAcOHAhHR0f8+uuvpX6MBAGNGzfGuHHjMG/evDKNWMjKz7KjSM5Gfunp6YiMjETdunWZGF7Ewau9vVXEsVbX37Lfnjt3ThVEYEGDsv8nJX8LfHx8GFgYGfu6arG/2dfWyBj79YbjVzFt+X6kZmpP6AV6OuGT8W3RrJYXrIUc+0qfyQnIgse+BVn8kd758+exfv16rFy5skyPc3BwQOvWrXH69OkS7+fk5KQuBckOWXCnlOv5q06RVv7Ylf1ifv2t21+L2qfp1th3VYd9XbXY3+xra1RZ+7X8X/vZv+fw2p/HoPtvt0WIl0rSrulpXVVHy9JXFn8UsWTJEgQEBGDIkCFlnipy6NAhBAUFGa1tRERERGRdMrNz8dxPB/HqH3lBxZAWQfj+wc5WF1SUlb2lD2lJYDFx4sRC0z4mTJiAWrVqqRwJMXfuXHTq1An16tVT+RhvvvmmGu144IEHTNR6IiIiIrIk8amZeOibPdh5Ll6/7cm+9TGtX33OyrD0EQuZAhUVFYX777+/0G2yPSYmRn9d5tRNmTJF5VXcdtttar7Y1q1b0aRJkyputWXq1asXpk2bZvTXkRwVGabcv38/zMXx48dVUCr5B61atTJ1c4iIiMgETlxOxh3vb9EHFY72tnh3XGs81b8BgwprGLEYMGBAseU0//nnH4PrCxYsUBcqTKppySiOVNcy9etKYrwEhDVq1NB/jr1791aBobe3N0zhlVdegZubm1pc0d3d3SRtICIiItNZczgG01ccQNrNJG1/D22SduvaPvxYrCWwIOtjZ2dXZYsYSmUwSeK/lTNnzqgcHlkDpSJrrUjlMiIiIrIcubkaLNxwCu9uOKXf1qyWJz4Z3w7B3i4mbZs5suipUGQcqampKkdFzs5Lcvvbb79d6D5SgveZZ55ReSxyNr9jx44Go0RffvmlGmH466+/1HQzKVM2ePBg/fS02bNn46uvvsLPP/+sr0okj88/FUp+l9EKIY+X7TLK8fXXX8PPz8+gDLC44447MH78+CLfk+55v//+e7U6u0xr+vbbb9Vtn332mZoiJ9saNWqEDz74QP84ecyePXtUjo78Lu0W0dHRuOuuu9R79PX1xfDhw9Vr6Eg7pT2vvvoqgoOD1ToqZXmcrLMifS/v89FHH1VBUP6+f+6559TojlQsk7yhzz//XH/74cOHMXToUHh4eKBmzZqqT2JjY8uwBxAREVFKRjamfrPHIKiQlbR/fKgLg4piMLCgQmbMmIFNmzapg/61a9eqA/69e/ca3Oexxx7Dtm3bsHz5chw8eBCjR4/GoEGDcOpU3pdPFluTA2QJBP7++2+V9yLBiJCfcoAtj5FgQy6yYGF+cuD8008/qd9lGpLcZ9GiReq1pKrXL7/8or/v1atX8fvvvxeZb5Pf888/jyeffBLHjh1T659IcPHyyy+rAEC2yWrss2bNUkGPkNeU1dmffvpp9bu0Ww7y5bFy4P7vv/9iy5YtKgiT9yIjEzobNmxQ7V63bh1+++23Uj9u48aNapREfko7JEiTi44Efd999x3effdd1eaPP/5YP0VLppb17dsXLVu2xK5du7BmzRpcuXJF9TURERGVTmRsKka8vwXrjl5R121tgBdua4QFY1rB2cGO3VgcWSCPSi8xMVGSOtTPgm7cuKE5evSo+mlJJk6cqBk+fLj6PTk5WePo6KhZsWKF/va4uDiNi4uL5sknn1TXz58/r7Gzs9NcvHjR4Hn69u2rmTlzpvp9yZIlqp9Onz6tyc3N1WRmZmree+89Tc2aNYt8XZ1z586px+3bt09d37hxo7qekJBgcL+HH35YM3jwYP31t99+WxMeHq5eqyi65124cKHB9oiICM2yZcsMts2bN0/TuXNn/fWWLVtqXnnlFf31pUuXaho2bGjwWhkZGaqP/vrrL/17k/cq28v6uLCwME12drb+PqNHj9aMGTNG/X7ixAn1PtatW1fk+5S2DxgwQPW37nWio6PVY+SxRbHU/dYc5OTkaK5du6Z+EvvamnDfZl9X5/36nxNXNc1fWaMJe+43dZHfZVt1lVjCsW9BzLGoCsmXtZf8XLwBnzpAVjpw7XjhxwTfrD4UewrITDW8zbs24OoLpMYCiRcMb3PyAPwiyt1UOVMuZ89lapOOTNnRTeURsv6HjBg0aNDA4LEyRUem7ui4uroiIiJCn2AvU3tkZKEySIWv9u3b4+LFi2o6lpzRl2lEt1oQrl27dgZTvuT9Tp48WT1f/lWrvbyKXzHzwIEDamFFGXkouIK1PJ9O8+bNDfIqSvs4GSGRXBMd6TfpcyFTxOQ2mc5VXNtkpEOmjhUkr1HwMyMiIiItOV75ZPNZzF9zHLk3awPVD3BXi97VqeHGbioFBhZVYfcSYNMbhtua3wWM+hRIugh8UsRB4uxE7c/VDwMXdhneNuIToOUY4Mgq4A/t1CK9iD7A+FUwppSUFHVwK7kH+Q+ARf6qSQUTo+Wgv7gqXmUlq6bLdB+ZZiXVwY4cOaKmQt2K5IPkfx/i008/NQikRMH3lZ88rm3btvocjfz8/f2LfK2yPK6ofpM1W4SLS8mJYvIakl/xf//3f2ptl/yBFheDJCIiKlp6Vo5a9O7n/Zf02/o3qammPrk78XC5tNhTVaHdJKDh4MIjFsKzFvDgpuIfe8eHRY9YiKYjgJD2hUcsKkBGGOTAdseOHahdW/s6Uur15MmT+rPkclAvIxYy+tC9e/dyv5aczZfnudV9RFH3k8UNFy5cqEYt+vXrp3IyykISmyWx+uzZs7jnnntK/bg2bdqoJHBZ8d3T09Poj8tPRkEkyJAcGHnPRb2G5KXUqVNHJaPfagSHiIiourt4/QamLt2NwxeT9NuekEXv+taHrSRXUKkxebsqeARqpzblv8g0KOHgXPg23TQoUaN+4dtkGpRwq1H4tgpMg9KNOMjUIEngloRrqTAkU4xsbfN2FZlOIwfikkS8cuVKnDt3Djt37lSrnJdm1EBHDn4l8VsSnKVqUf7KRzpS4lUOjiX5+dq1a/pRBnH33XfjwoULasThVknbxZkzZ45qtyRCS/AkU45kNfd33nmn2MfIe5d1NqSikyRhy/uXBPcnnnhCtaeyH1ewz2SleXm/sv6H7jlWrFihbpcKUvHx8bj33ntV8rZMf5LKXJMmTbplEEdERFTdbDsTh+Hv/acPKlwd7fDRvW0wvX8DBhXlwMCCCnnzzTfVSIRMqZGz4t26dVNTePKTg28JLKRakuRfSIlUOZDVjXKUhuQ1yGMl70GmAkmVpIIkf0IO/qWak4wwSDUqHcmDGDVqlAqG5PXLQ0Y9pNysvB8ZDZBRGcnXqFu3brGPkdyRzZs3q/c6cuRIVapWgjHJlShpJKK8jyvoww8/xJ133olHHnlElceVfpR8ESEjMP/9958KIqQClbwnWTFdytvmDw6JiIiqM5ma/enms7j38x2ITdFWZqzt64pVj3TFoGZBpm6exbKRDG5TN8KSJCUlqQPaxMTEQgeDcoAoZ5DloFSmoZCW7GKSEF1wzn9lkNKqkuwsIw5Uvv7mflt+Mi1NRoikwAEDN+NiX1ct9jf72pr3ayc3Tzy/6jB+P6hdW0t0r18Di8e1hrcrF7Mty7FvQcyxIIskeR8yBUgu+Re0IyIiIipOZPwNPP/VYZy+lpe/+ljveniqfwPYMZ+iwhhYkEWSBHIJLubPn29QCpeIiIioKGsOX8aMHw8jNVNbadHDyR7vjGmlqj9R5WBgQRYpMjLS1E0gIiIiC5Cdk4u31p7ER5vy1oxqWNMDH41vi7pcn6JSMbAgIiIiIqsUl5KBx7/bh61n4vTbhrYIwvw7W8DVkYfBlY09SkRERERWZ3/0dTzyzR5cSkxX1+1tbfBkz9p4pF/jEhfCpfJjYGEELLRFloT7KxERWdv/a9/tjMbsX44gM0ebT+Hv4YTFY1uhnhe4eKwRMbCoRLJitUhLS4OLi0tlPjWR0cj+mn//JSIislRpmdmYtfoIftqbt/BsuzAffHBPG9Rwd1TlZsl4GFhUIhlWk4XIrl69ql8QrbLXbbBExlzHgsrf33I/CSpkf5X9lsPCRERkyU5fTcYj3+7FySsp+m33damDF4c0hoOdrVrHgoyLgUUlCwwMVD91wQVpD2DlyywLiDGwML/+lqBCt98SERFZolX7LuDFVYeRlpmjrrs62uH1kc0xvFUtUzetWmFgUcnkQC4oKAgBAQHIysqq7Ke3SHKQK6s1yqqNXJ3YvPpbpj9xpIKIiCxVelYO5vx6ROVU5C8l+/49bVAvwN2kbauOGFgYiRys8YAt70BXptw4OzszsKgC7G8iIqoOzsWmqqlPx2KS9NvuaheCOcOawcWRVZ9MgYEFEREREVmU3w5ewvM/HUJKRra67uxgi/+7oznubBti6qZVawwsiIiIiMgiZGTn4LXfj+Grbef12yL83fDBPW3RMNDDpG0jBhZEREREZAGi49Pw6LK9OHghUb/tjlbBeHVEc7g58Vy5OeCnQERERERmbc3hy5jx4wEkp2unPjna22LOsKYY2z6UFSfNCAMLIiIiIjLbqk+v/n4MS7fnTX2q4+eqqj41DfYyaduoMAYWRERERGR2Tl1JxuPf7cPxy8n6bUOaB+GNUc3h4exg0rZR0RhYEBEREZFZLfT6/a5ozP71CNKztKtlO9nb4pWhTTGuA6c+mTMGFkRERERkFhJvZOGFVYfw+8EY/bYGNd3x3t1t0KAmqz6ZOwYWRERERGRye84n4Mnl+3Ah4YZ+2z0da2PW7U3g7MAF7ywBAwsiIiIiMpncXA0+3HQG76w7iZxcjdrm6WyP+aNaYHDzIH4yFoSBBRERERGZxNWkdDy1Yj+2nI7Tb2sX5oOFY1shxMeVn4qFYWBBRERERFVu44mreGbFAcSlZqrrNjbA473r4Ym+9WFvZ8tPxAIxsCAiIiKiKnMjMwev/3kMX2/LW5uipqcTFoxphS4RNfhJWDAGFkRERERUJQ5fTMS07/fj9NUU/ba+jQLw5uiW8HVz5Kdg4RhYEBEREZFRSVL2J5vP4p11J5CVo9GvTfHSkMa4t1MYbGQeFFk8BhZEREREZDQXr9/A9O/3Y8e5eP22ZrU8sXBMK9QL4NoU1oSBBREREREZxc/7L+Kl1YeRnJ6trsvAxEM9I/BUvwZwtGeCtrVhYEFERERElb6C9qzVh/HLgUv6bbW8XfDOXS3RMdyPvW2lGFgQERERUaXZdiYOT6/Yj0uJ6fptI1rXwpzhTeHp7MCetmIMLIiIiIiowjKyc9Tq2ZKkrdHmZ6sVtP9vRHMMaxnMHq4GGFgQERERUYXLyD694gBOXEnWb+sU7ot37mqFYG8X9m41wcCCiIiIiMolKycX7288jff+Po3sXO0whYOdDZ4Z0BBTuofD1pZlZKsTi03Hnz17tqp5nP/SqFGjEh/zww8/qPs4OzujefPm+OOPP6qsvURERETW5OSVZIz4YAsWrj+lDyqaBHni18e7YWrPCAYV1ZBFj1g0bdoU69ev11+3ty/+7WzduhXjxo3D66+/jttvvx3Lli3DHXfcgb1796JZs2ZV1GIiIiIiy1/s7tN/z+KdtSeRmZOrttnZ2uDR3vXwWO96LCNbjVl0YCGBRGBgYKnuu2jRIgwaNAgzZsxQ1+fNm4d169bhvffew0cffWTklhIRERFZvnOxqari096o6/pt9QLcVRnZFiHeJm0bmZ7FToUSp06dQnBwMMLDw3HPPfcgKiqq2Ptu27YN/fr1M9g2cOBAtZ2IiIiIipebq8GXW85h8KLN+qBCFrub2iMcvz3ejUEFWfaIRceOHfHll1+iYcOGiImJwZw5c9C9e3ccPnwYHh6Fl4e/fPkyatasabBNrsv2kmRkZKiLTlJSkvqZm5urLnRr0k8ajYb9VUXY31WHfc2+tlbct9nX+V1ISMNzPx3CtrPx+m1hfq54884WaBfmo99nzB336/Ipy2drsYHF4MGD9b+3aNFCBRphYWFYsWIFJk+eXGmvIzkZErQUlJCQgOxs7fL0dOsdMjk5WQUXtrYWPUhmEdjf7GtrxP2a/W2tzHnfztVosPLAVSzeHIXUzLyDy7ta18Tj3UPh4qhBfHxesGHuzLmvzZn0mdUHFgV5e3ujQYMGOH36dJG3Sy7GlStXDLbJ9VvlaMycORPTp083GLEIDQ2Fj48PPD09K6n11k2+yFK1S/qMX2T2tzXhvs2+tlbct9nXkXGpmLnyMHacywscgr2dMX9kc3StVwOWiPt1+ZRUHKnQfWElUlJScObMGYwfP77I2zt37owNGzZg2rRp+m2SvC3bS+Lk5KQuBckBMg+SS08CC/ZZ1WF/s6+tEfdr9re1Mqd9Wyo+ffHfOby97gTSs/JGKca0C8VLtzeGh7MDLJk59bWlKEtfWWxg8cwzz2Do0KFq+tOlS5fwyiuvwM7OTpWUFRMmTECtWrXUVCbx5JNPomfPnnj77bcxZMgQLF++HLt378Ynn3xi4ndCREREZB7rUjz740Hsj86r+BTi44I3RrZAt/qWOUpBVctiA4sLFy6oICIuLg7+/v7o1q0btm/frn4XUiEqf4TVpUsXtXbFSy+9hBdeeAH169fH6tWruYYFERERobqvnv3RP2ew+O/T+nUppOLTxM51MGNgQ7g5WezhIlUxi91TZMShJP/880+hbaNHj1YXIiIiIgIOX0zEjB8P4liMtuqlCPd3w/9GtUC7Or7sIqoegQURERERlU96Vg4WbTiFTzafVXkVutWzZV2KJ/rWh7ODHbuWyoyBBREREVE1sisyHs/9dBBnr6XqtzUO8lTrUjSr5WXStpFlY2BBREREVA0kpmXhjTXH8N3OaP02RztbPN6nHh7qFQEHO1ZKoophYEFERERkxWRBuF8PxmDur0cRm5Kh394q1Bv/u7MFGtT0MGn7yHowsCAiIiKyUtHxaXhp9WFsOnlNv83dyV5Ve7q3U5jKqyCqLAwsiIiIiKywhKwsdLdg/UmDhe4GNq2J2cOaIsjLxaTtI+vEwIKIiIjIisgCdzNXHjIoIRvo6Yy5w5tiQNNAk7aNrBsDCyIiIiIrkJyehbfXnsRX2yKh0VaQ1S9098zAhmoKFJExcQ8jIiIisvDk7L+OXMbsX47iclK6QQnZN0Y2R8tQb5O2j6oPBhZEREREFioyNhWv/HLEIDnbxcEOT/Wvj/u71oU9S8hSFWJgQURERGSBK2d/8M8ZfLTpDDKz85KzezX0x7zhzRDq62rS9lH1xMCCiIiIyIJsOHYFs389guj4G/ptQV7OePn2JhjULBA2klhBZAIMLIiIiIgsZE2KOb8exfpjV/Tb7G1tMLl7XTzRpz7cmJxNJsbAgoiIiMiMZWTn4NPNZ/HextMGa1J0DvfDvDuaol4AV84m88DAgoiIiMhMbT55TSVnn4tN1W8L8HDCi0MaY1jLYE57IrPCwIKIiIjIzFxISMNrfxzDH4cu67fZ2dqoNSmk4pOHs4NJ20dUFAYWRERERGbiRmYOPvznND7efBYZ+ao9ta/jg7nDm6m1KYjMFQMLIiIiIjNY5O6XA5fw+h/HEJOYt8hdDXdHPD+4MUa1qcVpT2T2GFgQERERmdDxK6lY9ONJ7IpMMKj2NKlrHTzetz48Oe2JLAQDCyIiIiITiEvJwFt/ncDyXdHQ5Nsui9zNur0JIvzd+bmQRWFgQURERFSFsnJysXTbeSxcfxJJ6dn67XVruGHW7Y3Rp1FNfh5kkRhYEBEREVWRf09dw9xfj+LU1RT9NjdHWzzepz7u7xYOR3tbfhZksRhYEBERERnZqSvJqnzsxhPXDLZLUvaUjgFoEBoIW1sGFWTZGFgQERERGUlsSgYWrDup8ihycvMyKVqFemP2sKZoUcsT8fHx7H+yCgwsiIiIiCpZelYOvthyDh9sPIOUjLw8iiAvZzw7qCGGt6wFW1sb5ObmrVVBZOkYWBARERFV8noU/1tzAhev39Bvd3O0wyO962Fyt7pwdrBjf1Pp5GQDsSeAmk1hCRhYEBEREVWC3ZHxmPf7MRyIvq7fZmsDjGlfG0/1r48AD2f2M5Us6waQEAkENAayM4A36wMZicCz5wBXX5g7BhZEREREFXA+LhVv/Hkcfx6+bLC9ZwN/vHBbYzQM9GD/UtEy04Bzm4GorcD5bcClfYCzFzDjNGDvBAx8FajRAHCyjH2IgQURERFRORe4W/z3aXy74zyycvISsxvW9MALQxqrwILIQNIl4PxW7e/N7wRSrwLfjQHcA4GwzkDz0dqfOm3Gw5IwsCAiIiIqg9SMbHz+3zl8svmsQWJ2DXcnPD2gAUa3DYG9HUvH0k2XDwFb3wOitgHXz2u3NRikDSy8w4An9gM+dQAbG1g6BhZEREREpVwxe/nOKCzacFqVkdVxcbDDA93rYmrPCLg78dCqWidaXz6oDSBkVCKsK9D5ESA7E7h2DGh4m3Y0onZnwD1A+xgJJnzrwlpw7yciIiIqQW6uBn8cjsFbf51AZFyafrudrQ3Gtg/Fk33rI8CTidnVMtFakws4ugG7vwDWzgIyUwA7JyCknTZXQoS0BaZuRnXAwIKIiIioGFtOx2L+muM4eCHRYPuQ5kFq2lO4vzv7rrq4kQBE7TBMtB48H2g/GajZDOj+NBDWBQhurU28roYYWBAREREVcPhiogoo/j0Va7C9U7gvnh/cWK2cTdUg0VqmNUX0AVx8gD+eBQ6tMEy0lttEaAftpZpjYEFERER00+mrKVi4/iR+Oxhj0CeNgzzx3KCGqtKTjRUk2VIxDq4AzvytzZHQJVrf8yNQvz/Q8zmg90zAp65VJFobAwMLIiIiqvai49OwaMMprNx7Abl5lWMR4uOCZwY0xLCWwbCV1e7IehKtrxzSTmm6sBMY8bF2+tKB5UBaLNBwsDbJWi4eNbWPqVHP1K02ewwsiIiIqNq6kpSOxX+fwve7og3WovBzc8Sjvevhnk614WRvZ9I2UiXIzZESTEBuNmy+vROI3mGYaJ0aC3jVAu75AbDl511eDCyIiIioWi5u9+E/Z7B0+3lkZOfqt3s626uysfd1qQM3lo61XDeua4MHmdIkeRLJMcDj+wFbe+2aEXW6FZ1ozaCiQhhYEBERUbWReCMLn/17Fl/8dw6pmXIWW8vN0Q6Tu9XF5O7h8HJxMGkbqRySYrSrWAe1BBLOA4taAtAA7jW105majQI02s9bc9tbsLHlAobGwMCCiIiIqsVq2V9ujcTHm84gKT1vtWwne1tM6ByGh3pGwM+9epYItUgp14ATfwBR27XlXxMigcDmwEP/Ad61gREfASHtAd/wvETr3LyRKTIOBhZERERk1QHF19vO49N/zyI+NVO/3cFOFrerjcf61ENNLm5nOYnWXiFAk2FA7Engt2na9SMaDLqZaN1Je38JJFqONXWrqyUGFkRERGR1UjKy8dXWSDXtKSEtS79dCjuNahOCJ/rWR6ivq0nbSLdwegOw7T0geheQmaxNtO74oDawkDUjnjsPOHuyG80IAwsiIiKyGsnpWfoRiusFAoqhLYNVQBHB1bLNMNF6Z96K1m3vA1qNA3KyABs7oPtTQO0uQK02eYnWdg7aC5kVBhZERERkFQGFGqH471yhgGJ4q1pqyhMDCjORfBlw9gIcXIC1LwFb3zNMtPYI1N6v4SDthSyGUQOLMWPG4PvvvzfKc7/++utYuXIljh8/DhcXF3Tp0gXz589Hw4YNi33Ml19+iUmTJhlsc3JyQnp6ulHaSERERMaVJAHFFm1AIRWf8gcUd9wMKMI5QmFacWeA81u0oxG6ROtx32uDhnr9AP9G2oAif6I1WSSjBha7du0y2nNv2rQJjz76KNq3b4/s7Gy88MILGDBgAI4ePQo3N7diH+fp6YkTJ07or9twByYiIrLIgGLJf5H4/L+zBlWeVEDRuhYe682AwmQL0V0+pK3W1H6ydrrSL09oA4r8idaSIyHCe5mmnWSegcVLL72EZs2aqUujRo1gb181s6vWrFlTaDQiICAAe/bsQY8ePYp9nAQSgYE3h9iIiIjIoiSkZmLJ1kh8ueWcQUBhZ2ujH6GoW6P4E4xkBBoN8O/b2sXoJFdCJVo7AhG9Af+GwLB3Abca2ulPZNUqHAX4+flh3bp1WLBgAU6dOoXg4GA0bdpUBRopKSmoKomJieqnr69vifeTNoWFhSE3Nxdt2rTBa6+9ptpbnIyMDHXRSUpKUj/l8XKhW5N+0mg07K8qwv6uOuxr9rW1Msd9+0pSupru9N3OaKTlW9hOAooRrYPxSK8I1PHTBhTm1G5L7OsSpSeqFa1tZDXr+LPQjP5KbbY58acKHDRdn9SOSKhEa2ft2hE+dbWPNfF7tLi+NhNl6S8bjfRwOSQnJ8PDw6PQ9nPnzuHw4cP6y7fffouqeMPDhg3D9evX8d9//xV7v23btqngp0WLFioQeeutt7B582YcOXIEISEhRT5m9uzZmDNnTqHtZ8+eLfL9U9Gfj25/seVKl0bH/q467Gv2tbUyp337wvV0fL0rBr8evoasHI1BQHFbkxqY3CkYId7OsFTm1NdFyk5XAYJNWiy8frkPdrHHYQMNcl1rICuoPZL7v6UNIORw0synl5t9X5sp6bPw8HB17CwpBUYJLFq1aqWmI5nDtKKHH34Yf/75pwoqigsQipKVlYXGjRtj3LhxmDdvXqlHLEJDQ5GQkHDLzqW8L7L0l4+PD7/IVYD9XXXY1+xra2UO+/aJy8n4aPNZ/HYwBjm5GoOVsse0C8WU7nVRy8cFls4c+lpPDgnjzwJR27QjEnJx8YXmgfWAJhc2fzwDTXAbi020Nqu+tiBy7Ct9VprAotxToVq3bo2OHTvir7/+UrkVOvv371eJ1H/88QeqwmOPPYbffvtNjTyUJagQDg4O6n2cPn262PtI1Si5FCQ7JHfK0pPcFvZZ1WF/s6+tEffr6tHfB6Kv4/2Np7H26BWD7e5O9hjfOQz3d60Lf4/C/y9bMpPt25JofeWwNqAIbgWc2wx8NVRaBAQ2A+oPAOp0g41qly0wdKHcYtH4d6TsyrJfljuwWLJkCV555RV069YNq1evVonTksj9008/4bbbboOxyUDL448/jlWrVuGff/5B3bo35++VQU5ODg4dOlQl7SUiIqLi/0/fdjYOH2w8g/9Oxxrc5uPqoIKJCZ3rwMuVC6JVWOxp4Ohqw0TrRrcDY78FarUD7vlRW7GJidZU1cnbknsgZ/P79++vDtL79u2r8hg6dLhZQsyIpNTssmXL8PPPP6u5cpcvX1bbvby81LoWYsKECahVq5Za80LMnTsXnTp1Qr169VQ+xptvvonz58/jgQceMHp7iYiIyFBurgbrjl3Bx5vOYG/UdYPbano64cEeERjXIRSujlzPt/yJ1ju1QUSdrto1Iy7tA/5bCNTuCHSbBoR1AWR6k3B0Ber3525K5Vbub+qVK1dURaVPP/0UTZo0UQvV3XfffVUSVIgPP/xQ/ezVq1ehkRRph4iKijIYvpF5dVOmTFFBiMwVa9u2LbZu3araT0RERFUjPSsHq/ZdxKf/nsXZa6kGt4X5ueKhnhEY2aYWnOzt+JGUhS6Beu9SYOfHwJUjKjcCbgGA183p4k2GA81GArbsWzKjwEKmHskq1z/88AOGDBmiErllpW05mJ8xYwaMrTQ55zJFKj8piSsXIiIiqnqJaVn4Zsd5LNkSidiUvMIoomFNDzzSOwJDmgfB3o6JtaVOtJbRCFmMThagu+1N7aiErT1QsznQYap2RCJ/orW9o5E+XaIKBBZffPEFxo4dq78+aNAgbNy4EbfffjsiIyPx/vvvs3+JiIgIF6/fwOf/nsPyXVEGa1CITuG+mNojAr0a+qvEWrpForWsXi2jDd+NBU6uyUu0rtcf8AjS3rfVOO2FyFICi/xBhY4sOCdTiwYPHlzRdhEREZGFO3opCZ9sPoNfC5SMtbUBBjcLwoM9wtEy1NukbTTrEQkp96pGJLZpcyUykoCp/wJBLYD2U4D2DzDRmsxKpWdD1alTRwUXREREVP3IVOUtp+Pw8eYz+PeUYYUnWYPirnaheKB7XYTdXCWb8iVaX9ytzYuQpGoZvVn9MJAapw0euj4B1O4C+DfU3r9+P3YdmR2jlFmQxGgiIiKqPjKzc/HbwUv4/L9zOHIpqVDJWCkXO6FzGPzcrWsNigpJT4LN3/PgffY/2MQdz0u0bnc/4OwJTPxNO73JjlWxyDJwTyUiIqJyi0/NxLId5/H1tvO4mmyYkB3q64Ip3cMxum0oXByrcRWifCta4/w2ICcTGPUp4Oimpjpl12gE284PwSasK+AXkZdo7R1q6pYTlQkDCyIiIiqz01eT8fl/kVi59wIysnMNbmteywtTe4ZjUNPA6lnhSRKtZWqTqy9w+RDwzSggRVYSt9EmX4f31N7P1g6aqf8iJT4evr6+ssSxqVtOZJrAQsrKhoaGFqrgIHMro6OjUbt27Yq1jIiIiMyK/B8veRMy3WnTyWsGt0lC9oAmgZjcvS7ahflUrwpP2RnAxb3akq8yIhG9Qxs8jPkG8A4DWt2tzY+QXAkXJquT9arQOhYxMTEICAgw2B4fH69uk5W4iYiIyDoWtFu97yK+2HIOJ6+kGNzm7mSvErLv61IHtf1cUS2kJ2mrNHnUBAKbA4d/0iZaO3rkJVrXvbmAr+RK9Jtt6hYTmXdgIWctijobkZKSAmdn54q2i4iIiEzsWnIGvtkRhW93RKlcivxCfFxUMHFX+1B4OjvA6skidEdWacu/ynoSkmjd+TFtYNFgEPDgJu00JyZaUzVW5sBi+vTp6qcEFbNmzYKra97ZCRml2LFjB1q1alW5rSQiIqIqc+RSIj7eeAZ/HY9DVk7e+hNCpjlN7lYX/ZvUtM78CUm0TjinndIkU5va3AeEttcGFif+1K5k3WGKdmqTJFoLyaWQC1E1V+bAYt++ffoRi0OHDsHRMW9pePm9ZcuWeOaZZyq3lURERGT0crFrjlzGV1sjsed8gsFtdrY2GNI8CPd3q4tW1ragnSRa29hqKzFtmAfs+wZIuXwz0bop0PhmX3R5XLu+BBFVXmCxceNG9XPSpElYtGgRPD09y/oUREREZCauJqVj2c4oLNsRVahcrKezPe7uGIaJXcIQ5OUC60y03glMXgsENAI8AoGWY7WjEqEdDROtbatxuVwiY+dYLFmypLwPJSIiIhOSWQd7o66r0Yk/D8cUmu7UIMAdI1vUwL3d6sPdOW9mgsUmWkvJ1zpdtdc/7ALEnQYc3bWJ1jISIQnWQqY4EVHVBxZz584t8faXX365vE9NRERERqru9OuBS/hqWyQOX0wqslzshC5h6FjHBwkJCXB1tMDlrrIzgZN/5uVISFAhidYzzgBuNYBBb2h/1mzORGuiSlbuvxirVq0yuJ6VlYVz587B3t4eERERDCyIiIjMxMXrN/DN9vNYvjMKCWlZBrf5uDpgXIfauKdTGGp5a6c75eYaLnhn9onWklideg3o+qQ2V2LVQ4Cbv3ZKU7vJ2p+uftrH1O9v6lYTWa1yBxa6JO78kpKScN9992HEiBEVbRcRERFVcLrTtrNxarrTuqNXkGs42wnNanliYuc6GNoyGM4OFpY/cD0KWPeydlRCl2gd0g7o8gRg5wA8dYRVmohMoFLHOCWRe86cORg6dCjGjx9fmU9NREREpZCcnqUWs1u6/Xyhxewc7GxwW/MgTOhcB21qe5v/6tiSaH1pn3btiKhtgGcwMHSRNj8i6VK+RGtZ0don73Es/UpkEpU+eTIxMVFdiIiIqGrXnvhmexR+3n8RaZk5BrcFeDjhno5hGNchFAGeZryIbUYykJUOuPsDx/8AfpwEZKdrA4mQ9toF6HSBg1RyIiLrCCzefffdQkOuMTExWLp0KQYPHlwZbSMiIqJbJGP/djBG5U/sj75e6Pa2YT6Y2KUOBjUNhKO9GS5mlxoLnN9imGjdYSow+A3titZ9X9aOSDDRmsi6A4sFCxYYXLe1tYW/vz8mTpyImTNnVkbbiIiIqAhnrqWodSd+3HMBiTcMk7HdHO1wR+taaoSiSbCnmSVaR2qnNMnoQ436wO4lwMb/A7xra1eybnc/ULen9v7eoUDnR03daiKqisBCKkDlH60QZj9Xk4iIyEJl5eSqJGwZndh6Jq7Q7Y0CPXBvpzAVVLg7mVGZ2COrgKO/aAOK5BhtovXt72gDi7YTgVZ3A161TN1KIqoEFfrL8/nnn6uRi1OnTqnr9evXx7Rp0/DAAw9URtuIiIiqPSkVK2Vil++KxrUCK2PL9KbbmwepUrEmT8Y2SLTerp3O5BsOXNgNJF4AWtylHZWo3TEv0do9wHTtJSLzCSxkAbx33nkHjz/+ODp37qy2bdu2DU899RSioqJuuYAeERERFS0nV4PNp67h2+3n8ffxq4VKxdbxc1VTne5sGwIfNxOtjJ2ZBji6an//4T7gxJ/aRGsHN22VpoybFakGvmqa9hGR5QQWH374IT799FOMGzdOv23YsGFo0aKFCjYYWBAREZXN1eR0lTch+RMXEm4Y3GZna4MBTWqqgKJLhB9sZansqpRyTTudSS4yKnHlCDDjNODiDdRqq82bqN0ZCGzBFa2JqqlyBxay0na7du0KbW/bti2ys7Mr2i4iIqJqNToh0502HLuK7ALDE0FezhjbvjbGdghFzaoqFavRwDYpGkg4ANTvC2RnAgubaUck9InWkwDbmwvrdXm8atpFRNYZWMgCeDJqIdOh8vvkk09wzz33VEbbiIiIrNal6zewYnc0fth9QeVR5CepEj3q++OejrXRp1EA7O2qoFTsjevAoR/UaIRN1Db4JsdA4+QBPHcesHcExn0H1GjIRGsiMl7y9tq1a9GpUyd1fceOHSq/YsKECZg+fbr+fgWDDyIioupa2UlyJmR0YtPJa4VyJ2Qhu9HtQjCmXW3U9ruZv2AMMgIhidaydoSdo7asa04WsGYmENwaaD4aiT7N4dGkH2x0oxIRfYzXHiKq3oHF4cOH0aZNG/X7mTNn1M8aNWqoi9ymwxK0RERU3UXFpWH5rij8sOdCocpOkirRq2EAxrYPNd7ohJSFl2GQC3uAdS8DF3fnJVo3Ga69j6x2PfMC4OAMTW4usuLjtfkTRETGDiw2btxY3ocSERFZvYzsHKw9ckUFFFtOF153ItjLGXe1D8Vd7UIR7O1i3ETriN5Av9mAk7s2WOgzCwiTROuWhonWDlWUw0FEVqncgYVMeQoNDS1yREJuq127dkXbRkREZHFOX03B97ui8NPei4hPzTS4zd7WBn0bB2Bsh9oqh0IqPVXKaMT189rRBxl12PYB8NdM7W1etbUBhFRsEv4NgbHfVvw1iYgqM7CoW7cuYmJiEBBguLhNXFycui0nJ6e8T01ERGRR0rNy8MehGCzfGY2dkfGFbg/zc8WY9qFq3YkAj0oYFYg9BZz95+aIhKxofQnoPw/o+oQ2F2LkZ9qAwiuk4q9FRGTswEKj0RQ5WpGSkgJnZw6lEhGR9TsWk6QSsVftu4ikdMNS6452thjYLBDj2oeiU3gF1p2QROuY/dopTbJ6tWcwsO19YN/Sm4nWdwJhsqK1tpAKAhppL0RE5h5Y6Ko9SVAxa9YsuLrmVa2QUQqpDNWqVavKbSUREZGZSLyRhV/2X8SK3Rdw6GJiodvrBbirROyRbULgW5FVsbcuBk7+BVyQROsb2qlOgc21gUXvF4GBr+WtfE1EZImBxb59+/QjFocOHYKjY94fTfm9ZcuWeOaZZyq3lURERCaUm6vBtrNxat2JNYcvIyM71+B2ZwdbDGkejHEdQtE2zKdsFRFTY/OmNEVvByb8DMj6EdeOA85eQJ+XbiZay4rWDtrHSC4FEZGlBxa6alCTJk3CokWL4OnpaYx2ERERmdyFhDT8uOdCkYvYiea1vNS6E8Nb1YKXy82D/lslWqfFAW41JFoBPu4OXDlsmGidkawNLIa/b4R3RERkhjkWS5YsqdyWEBERmUki9l9HLqtgYsuZWBUL5Oft6oARrWthdNtQNAm+xck1CR6uHdPmR0Rt145MZKQAz50DZOE5yY/oOo2J1kRUvQOLuXPnlnj7yy+/XN6nJiIiqlIyvffIpSQ11Wl1EYnYMrNJysPKmhP9mgTAyf7matTFJVqnJwL1+wMpl4EPuwC29kBQK6DZSKB2F+3Ihej2VBW8OyIiMw8sVq1aZXA9KysL586dg729PSIiIhhYEBGR2UtIzcTqm4nYUuGpoNq+rrirXYhKxC52EbvrUcDepdrRCF2idc1m2sBCEq0n/QkEtQQc3Yz/hoiILDGw0CVx55eUlIT77rsPI0aMqGi7iIiIjCInV4N/T11TU53WHb2CzJzCidi3NQ9SoxMd6vgalonNn2jtFwG0nwykxQO7PgNqdwb6vKgdkQhqkfcYKQVLRFQNlDuwKIokcs+ZMwdDhw7F+PHjK/OpiYiIKuR8XKoKJn7aewExiemFbm8V6q0WsRvSIgiezjcTsXNlsVc74NivwIa5QOxJ7XavUKDtRO3vMhox4wxga8tPiIiqtUoNLERiYqK6EBERmdqNzBz8eThG5U5sP1t4RWw/N0eMbFMLo9uFooG/m7bE66GvtCMSkmzd5TGg08OAaw0grCvQY4Z2ZMI71DABoyzlZYmIrFS5A4t33323UOJbTEwMli5disGDB1dG24iIiMpM/j/aH31d5U38euASUjIME7HtbG3Qu6E/7mpTE308Y2AfEAS4eAC/P62d0qRPtB4BhHbQPkjKwMqFiIgqP7BYsGCBwXVbW1v4+/tj4sSJmDlzZnmfloiIqFxiUzJURScZnTh5JaXQ7eE13PBE/Wvo73QMbpd3Aj/fTLQe9bm27GubiUDjYUBIOyZaExFVZWAhFaDMwfvvv48333wTly9fVqt+L168GB063DzDVIQffvgBs2bNQmRkJOrXr4/58+fjtttuq9I2ExFR5cjOycWmk9dUMLHh2FVk5+YtOuGDJHRzPI07/aPhMfgVtI4Ihs2yMcDxXUUnWudPuCYioqrNsbh+/To+//xzHDt2TF1v2rQp7r//fnh5eaEqfP/995g+fTo++ugjdOzYEQsXLsTAgQNx4sQJBAQEFLr/1q1bMW7cOLz++uu4/fbbsWzZMtxxxx3Yu3cvmjVrViVtJiKiijtzLUWfiH0tOSPfLRrMtf8SfZyOIyQnWrspKwTwStHmQYz8GHDyYqI1EZER2GhkMmo57N69Wx3Eu7i46EcIdu3ahRs3bmDt2rVo06YNjE2Cifbt2+O9995T13NzcxEaGorHH38czz//fKH7jxkzBqmpqfjtt9/02zp16oRWrVqp4KQ0pKSuBE6SoC5VsOjW5HOJj4+Hr6+UbWTVFGNjf1cd9nXV9nX05WvYdiEdP+65iD3n41DP5hI62B5He9vj6vf7Hd/CqHaheDT2Vbh7+WpHIyQvwrt2FbbUOnDfZl9bI+7X5VOWY99yj1g89dRTGDZsGD799FO1KJ7Izs7GAw88gGnTpmHz5s0wpszMTOzZs8cgn0MOWvv164dt27YV+RjZLiMc+UlwtHr1aqO2lYiIykfOfe2KTMCPu85iz6GjOJPlp6Y47XV6Bj42KcjS2OGCc33Y1emDrSM6w97ZHcBSdjcRkQmUO7CQEYv8QYV6Mnt7PPvss2jXrh2MLTY2Fjk5OahZs6bBdrl+/PjxIh8jeRhF3V+2FycjI0Nd8kdtuqhXLnRr0k9ycMD+qhrs76rDvjaey3EJ2Ll5Da4f34QG6Ycwx/Y0om38MQBvIgEe+NF5FIIad0KH7gMQ5uNr8JlQxXHfrjrsa/a1uSvL39VyBxYyFBIVFYVGjRoZbI+OjoaHhwesheRjyKJ/BSUkJKgRGirdDpmcnKyCC06FMj72d9VhX1cemxsJsLmwCwevZeGTmAjcOL8HqxxfRoLGHbvREO9k34lDtk0wsoU/hjcPQJPAjrCRnAkN1FRLqlzct6sO+5p9be7kGM7ogYXkK0yePBlvvfUWunTporZt2bIFM2bMUAnSxlajRg3Y2dnhypUrBtvlemBgYJGPke1lub+QqVb5p0/JiIXkcfj4+DDHogx/NOUAQPqMgYXxsb+rDvu6gmIOwGbvl8g4swXO10+pTSk5HbE160nYow76Z/wPpzXB6BTujzvbBGNCsCOCAmrw70gV4L5dddjX7Gtzl3920i3vW94XkYBCDhYnTJigP3Pv4OCAhx9+GG+88QaMzdHREW3btsWGDRtUZSfdl1OuP/bYY0U+pnPnzup2yQHRWbdundpeHCcnJ3UpSA6QeZBcerKvsM+qDvubfW1WZBg99gRwfqt2NesGA3E9Yhj27j6Aegc34L+M+tiZ2x+7chviIvzVQ2p6e+C2to1xZ9sQhPq66pMu+Xek6vDvCPvaGnG/LruyHO/aV+TAftGiRWqq0JkzZ9S2iIgIuLq6oqrISIIsyCc5HVKZSsrNStWnSZMmqdsl6KlVq5Zqo3jyySfRs2dPvP322xgyZAiWL1+uckU++eSTKmszEZHVy8mSrGvA3hHY9gGw+X/AjQRobOyQ7NsMK6/Vx2vfb0BmtgQR8/UPc7S3xfBmgRjdNhRdIvxga2tj0rdBRERVuI6FkECiefPmMAWZjnXt2jW8/PLLKgFbysauWbNGn6AtOSD5oyyZsiVrV7z00kt44YUX1AJ5UhGKa1gQEVVAZipwYRdwfhsQtRW4sBsY8THQZBjgVw+Jze/H2pS6+PC0L85e1D0oLxmwZYgX7mwXimEtguHl6sCPgoiouq1jUV1xHYuyY93oqsX+Zl8bXVo8ELUNqNcPsHcClo4EzmwAnL21K1qHdUZ6vdvxx0UntSL29rOFk6t93RwxonUtjG4XgkaBt14TiPt11WJ/s6+tEfdrM17HgoiIqpFDPwKR/2kDims3S3pPXg+Etgf6zgIG/B80/g2x70ISftgdjV/XnkZKhmHlPJnZ1LthAEa3C0WfRgFq6hMREVkPBhZERJRHBrGvndBOabp8CBjyjmQ7Av8tAHIytSMS3Z7S/ry5ovU1jyZYte8CVnz7H05fTSnUm+H+bipvYmSbWqjp6czeJiKyUgwsiIiqeyAhgUNGMrByqnZE4kY8YGMHBLUE0q8DLj7AAxsAh7ygICsnFxuPXsGK3Rew8cRV5OQazqp1c7TD7S2CcVf7ELSp7aNdc4KIiKxauQMLqbQkSdL333+/wfYvvvhCJVQ/99xzldE+IiIyZqJ1diYw+S/A0V1qCgIdpmhHI0LaA07ueY+7GVScvpqsgomVey8gNiWz0NN3qOuLu9qFYnCzQLg58dwVEVF1Uu6/+h9//LGqsFRQ06ZNMXbsWAYWRETmkmh9IwHwiwBiDgKf9gZys/MSresPzBu1GPNN0U+RmY3fDsZgxa5o7D6fUOj2QE9njGpbC3e2DUXdGm5V8KaIiMiqAgsp7xoUFFRou7+/P2JiYiraLiIiKo/UWODMRu1ohIxKXDsGRPQFxq8E/BsCg+cDtbsA/o20IxTFkIKBBy8kYvmuaPx64FKhRGxHO1v0b1JTVXXqXt8fdlxzgoio2it3YBEaGootW7agbt26BttlW3BwcLXvWCIio5ORhtiT2hWt/eoBdbsD57cAKx8AajS4mWg9TftTSGnY9g+U+JTX0zKxet9FFVAcv5xc6PaGNT0wpn2oKhXr4+ZorHdGRETVKbCYMmUKpk2bhqysLPTp00dt27BhA5599lk8/fTTldlGIiLK7+RfwJ6vDBOtuz+tDSzq9QdmnAHcapS6z3JzNdh+Lg7f74rGn4cvIzM7b/E64epoh2Etg1VA0SrUm4nYRERUuYHFjBkzEBcXh0ceeQSZmdoEPmdnZ5VbMXPmzPI+LRER6WSmaROtJYCQUYmuT2gXpUu5AmQkaUcfwiTRukNeorWjq/ZSCleS0vHjngtqEbvzcWmFbm9d2xtj24diSItguDMRm4iIjBVYSOnA+fPnY9asWTh27BhcXFxQv359ODk5lfcpiYiqN0m0dvIE7OyB358B9izJl2jdCbC7+fe1zQTtpRyypUzsiWv4fleU+lmwTKyPqwNGtglRoxMNanpUxrsiIqJqosK1AN3d3dG+ffvKaQ0RUXWSeCGv7Ksu0fqBv4GQtkCdbtpk6zBJtG5cYqJ1aUTGpqqRCRmhuJqcUej27vVrqGBCErKd7O0q9FpERFQ9lSmwmD59OubNmwc3Nzf1e0neeeediraNiMj6Eq0v7gVajdNuWzoSiD0B+NXXTmnq+iTge7MgRtM7KvyS6Vk5+OvIZSzfGY1tZ+OKLBN7V7sQjG4XilDf0k2fIiIiqpTAYt++fSpZW/d7cbjCKhGRzDvKAHZ+qs2RkEtanDbROqI34BEIjPoU8AgG3P0rtbvOXEvBdzui8NPeC0hI0/7N1rG3tUHfxgEY2742ejRgmVgiIjJRYLFx40b971999RVCQkJgW2B4XmqfR0dHV14LiYgsJdH64m7tlKbUa8CQtwA7R2D7h9pRiHaTbyZay4rWN3MXglpW2stnZMvoxBUs23Ee28/GF7o9vIabmuok+RP+HsyFIyIiM8qxkPUrZCG8gIAAg+3x8fHqtpycnMpoHxGRecrJBmxsYZsYBZtVY4GY/UBuFuDsBdTpLjVctXkR0w5VOD/iVrkT3+2Mwg97LiA+VVuhL/8idoObB+LuDrXRoa4vR5OJiMg8AwsZmShKSkqKKjtLRGRVEi/mlX2Vnz51gDHfItfVH/CpDbQcU3SitRGCCllnYt3RK1i28zy2nI4rcnTi7o611eiELxexIyIicw0sdEnbkkfx8ssvw9U1L+FPRil27NiBVq1aVW4riYhMkWgt+RA16gHHfgW+v1d7myRaS+nXen211x1coBn5GWyMOCqhExWXhu92ReGH3dGITTEcnXCws8GgZkFqdKJTOEcniIjIAgILXdK2jFgcOnQIjo6O+tvk95YtW+KZZ56p3FYSERlb7Gng5BrDROvW44Hh7wG1uwB3fQ3U7gy455v+KdOdjCwrJxcbjl3Btzui8O+p2EK31/FzxbgOtXFn2xD4uTN3goiILCiw0CVwT5o0CYsWLYKnp6cx2kVEVDWJ1vX7AbXaAqfWAn/PA2q1A9rdrw0iQjto7+/mBzQZXqWfyIWENFUm9vvd0bhWYN0Jqew0sGmgmu7UOdwPtrY2Vdo2IiKiSs2xWLJkSXkfSkRkGru/APYvAy7lS7T2DtUGFm0nAu0nA/amO+ufm6vBv6djsXRbJP4+fhUFFsVGqK+LGp0Y3TaUlZ2IiMh6AosbN26o6VC6HIvz589j1apVaNy4MQYOHFiZbSQiqkCi9XZgxEdAUAsgIwXwCgVajNGOSAQ0yUuudnQzWS8npmXhhz3R+Gb7eUTGpRncZmdrg/6Na6rRiW71anB0goiIrC+wGD58OEaOHImHHnoI169fR8eOHeHg4IDY2Fi16vbDDz9cuS0lIiou0Tr+LOAXob3+1VDg3Gbt7371tAGEbhSi6xNm1YeHLybi622R+OXAJaRnGeZrBHk5q0RsWXsiwJOV9oiIyIoDi71792LBggXq9x9//BE1a9ZUid0//fSTqhbFwIKIjEISpmXNiPwjEmmxwPTjgGcQ0EamND1QONHaTKRn5eCPQzH4ett57I++Xuj2rvX8ML5THfRrHAB7O+NXmiIiIjJ5YJGWlgYPD+3qsWvXrlWjF7IKd6dOndS0KCKiSpF1A7iwG0g4B7SZIEMUwNfDgZzMm4nWk7RBhIuP9v7N7zTLjo+OT1OVnVbsji60kJ2Hkz1GtQ3BvZ3CUC/A3WRtJCIiMklgUa9ePaxevRojRozAX3/9haeeekptv3r1KitFEVHFpMYBWxdpqzZd2qdNtHbzB1reDdjZAw+s1y5QZ8JE69ImY28+dQ1Lt53H3yeuqllb+TUK9MCEznVwR+tguDqW+88xERGRWSj3/2Qy3enuu+9WAUWfPn3QuXNn/ehF69atK7ONRGTNki7lrWZt7wwMfBWwcwAO/aQt99rirsKJ1v4NYc4Sb2SpReyWbj+P8wWSsWUhu9uaB2F8pzC0DfNRi40SERFV68DizjvvRLdu3RATE2Ow0nbfvn3VtCgiokLklH1WmrYCk+RGrHwQuH5z6qRvBNDoNu3vzp7A9CMW14Gnr6bgq62R+GnvBaRl5hjcFizJ2B0lGbs2S8USEZFVKlNgMX36dMybNw9ubm7qd52lS5cWuq9UhiKiai4nG7h80DDRuskw4PYFgFcI0HCwdjRCLh41YYlyNRpsPHEVX22LwuaT1wrd3r1+DZU70bcRk7GJiMi6lSmwkKpPWVlZ+t+Lw6F9omqeaC1Bg29dYMeHwNqXADsnIKQd0PY+oP4A7X3lPoPnw1KlZGTjh11RWLLlHKIS0g1uc3W0w6g2IZjYpQ6TsYmIqNooU2CxcePGIn8nompMRiFO/GGYaN37RaDns0DTEUBIeyC4tdknWpfW+bhUfLk1Ej/svqCCi4IrY0/sXAej24XCy8XBZG0kIiIyBZYhIaLSS4oBorZqg4hOD2sXpTv2K3DoRyCsM9B8tPanJFrrRiXkYuE0Gg22nI5ToxNFVXfqHO6HSV3roG/jmmqlbCIiouqo3IFF/hyLgtOgnJ2dVTlaWZ3b19e3Iu0jIlORo2ddxaJ1rwBHVwMJkXmJ1k2GawOLvi8DA/4v775W5EZmDlbuu4Avt0Ti1NUUg9uc7G0xonUt3NHEGx0ahqh1fIiIiKqzcgcWkmMhq2/n5OSgYUNt6ceTJ0/Czs4OjRo1wgcffICnn34a//33H5o0uXn2kojMO9H6yiHtaISMSkTtAB7ZBrjV0E5jajCo6ERrK5nilN+15Aws3RapysUmpGnzyvJXdxrfuQ7GtpfpTvaIj483WTuJiIisIrDQjUYsWbJEvyBeYmIiHnjgAVWGdsqUKfp1LmQBPSIyw0Tr2FNAUAtZyQ1Y0BRIuZyXaC2rXGtytfft/QKqg1NXkvHZv+ewav9FZGbffO83ta/jg0ld62JAk5qwt9OOTuRKvxEREVHFAos333wT69atM1hl28vLC7Nnz8aAAQPw5JNPqkX05HciMgNZ6cC5TXmL0UmitY0t8HyUdtRBFqaTfAgrSrQubf7E1jNx+PTfs/jnhGG5WHtbG9zeIgiTu4WjeYiXydpIRERk1YGFjE5cvXq10DSna9euISkpSf3u7e2NzMzMireSiMouOQaI3g5kpgFtxgPZN4BlYwD3AO10pgGjtD9tb1Yvan5nteplGZH47eAlNUJxNEb7N0vHw8leLWYn5WKDvV1M1kYiIqJqMxXq/vvvx9tvv4327durbbt27cIzzzyDO+64Q13fuXMnGjRoUHmtJaKSxZ6Gzb9vwefcFtgmRWm31e6iDSxcfIBph7SjElaYaF1aiTeysGxHFL7ceg5XkjIMbqvl7YL7u9XFmPahcHdi0TwiIqKyKPf/nB9//LHKnxg7diyys7W13O3t7TFx4kQsWLBAXZck7s8++6y8L0FEpU20DmgK9J6pDRiuHEZmnV5watAbtmFdAI/AvMd5h1bbPo2OT8Pn/53Dit3RSMvMMbitZYgXHugejsHNAvX5E0RERFRFgYW7uzs+/fRTFUScPXtWbQsPD1fbdVq1alXepyeigvkROZmAs6d2zYhfpwGZydpE61ptAXd/7f38IqB5cDNS4+PhJKWeWQIVhy8m4sNNZ/DnoRjk5lt/QmKwfo1rYkr3cJWYLaWyiYiIqPwqPNYvgUSLFi0q+jRElN+N60D0zrzF6C7tBXo+B/R4BghoDHR/SjvFSRKtHZzZd0UkZG87G4cP/zmDf0/FGtzm7GCLO9uGqITsujXc2HdERETmEFhcv34dn3/+OY4dO6auSyL35MmTVXUoIiqD5Mvaak2STO0ZBGx8Ddj5MeBe82ai9f8B9fpp71uzqfZCheTmarD26GV8uOksDkRfN7ithrsjJnaug3s7hcHHzZG9R0REZC6Bxe7duzFw4EC4uLigQ4cOaptMi3rttdewdu1atGnTpjLbSWR9jqwGTq3VBhQJ57TbRn2urc7U+VGg41TAN7xaJ1qXpcLT6n0X8dHmMzh7LdXgttq+rniwR7gapXB2sDNZG4mIiKxduQMLSdweNmyYyrOQpG0hSdyyQN60adOwefPmymwnkeXKzQEuH9KuHSFBxLB3tRWajv0KxJ4A6g8AwnQrWt9MtPYJM3WrLUJKRjaW74xSJWMvJ6Ub3NY4yBMP94rAbUzIJiIiMv8Ri/xBhXoye3s8++yzaNeuHYwpMjIS8+bNw99//43Lly8jODgY9957L1588UU4OhY/xaFXr17YtGmTwbapU6fio48+Mmp7qRpWbLKzl4n+wPf3Amc33Uy0dtQmWqfGagOLkZ8yubqc4lIy8OXWSHy1NRJJ6dqqdDqdwn3xUM8I9Gzgz4RsIiIiSwgsZMXtqKgoVVI2v+joaHh4eMCYjh8/jtzcXFXytl69ejh8+DCmTJmC1NRUvPXWWyU+Vu43d+5c/XVXV1ejtpWqgfREIGpHXqK1jEI8c1obXPhFaBOspexrcBvDRGtWbCqzy4np+GjTGSzfFYX0rFyD2wY0qYmHekWgTW2fSvhQiYiIqMoCizFjxqhEbTmQ79Kli9q2ZcsWzJgxA+PGjYMxDRo0SF10pMztiRMn8OGHH94ysJBAIjAwX11/ovIkWideAELaATcSgP+FA5pcwC1AO6Wp6QhtaVgJLPrnBbFUsTUopGTsj7svIDMnL6Cwt7XBiNa1MLVnOOoFGPeEBhERERkpsJADeKn7PmHCBP0CeQ4ODnj44Ycxf/58VLXExET4St3+W/j222/xzTffqOBi6NChmDVrFkctqGRp8cDx3/NyJCTR2isUeOqwdkqTJFwHtWSitRGci03FBxtPY9W+i8jOtwiFi4MdxnWojQe610Wwtwv3YCIiIksOLCSXYdGiRXj99ddx5swZtS0iIgLx8fF47LHH8Mknn6CqnD59GosXL77laMXdd9+NsLAwlZNx8OBBPPfcc2qkY+XKlcU+JiMjQ110kpKS1E+ZiiUXujXpJ1lXwCL6SxKtrxzWBhEu3kCLsUDSJdj88jgQ2Ayo3x8aSbIO7SRvTPuYJndof0pOhVxMzKL6uxinriTj/X/O4LeDhovauTvZYXynMNzftQ783J3UNlO+T2voa0vBvmZ/Wyvu2+xrc1eW/+NsNPK/YiU6cOCAKjWbk5NT5sc+//zztxztkDUz8ud1XLx4ET179lSJ2Z999lmZXk+Sv/v27asCEwmKijJ79mzMmTOn0HZZbdzYuSTWtEMmJyer/rI107wC+0u74Lr7A9jH7IVtVgo0to5IbzwSqb1fVdOcbDJToXGyjM/bEvq7OCeupuKL7Zfw98l45P/D5OFkh7FtAtXFy6XC63pWGkvua0vDvmZ/Wyvu2+xrcyf/z0nagcwOkhxriwksrl27hri4uBLvI29MV/np0qVLKqDo1KkTvvzyyzL/xy7J3rJy+Jo1a9SaHKUdsQgNDUVCQsItO5fy/mhKf/n4+Jj+4EsSraN3wkZGJKK2QdNkONDxITXFyea/d7SjEXKp1Qawt8wVrc2qv0tJFrN7b+MZbDh+1WC7r6sD7u9WF+M71YaHswPMjSX2taViX7O/rRX3bfa1uZNjX/l/rjSBhfmc+gPg7++vLqUhIxW9e/dG27ZtsWTJknL9p75//371MygoqNj7ODk5qUtB8no8kCg9yccxSZ8lXwEcXABnT2DTm8A/rxkkWtvIAnTSprrd1MValqIzWX+X0Z7zCVi04RQ2n7xmsL2GuxOm9gjHPZ1qw9XRrP5MWWxfWwP2NfvbWnHfZl+bs7L8/2be/2OXEFTISIXkS0hehYx06OgqPsl9ZJrT119/rVYGlzyQZcuW4bbbboOfn5/KsZBF/nr06IEWLVqY8N1QpYo/B5zfoi37KuVf488Cd3wEtBoHhPfSLkAnpV+5orXJRygWrD+Jf04YBhSBns54qGc4xnaozVWyiYiILEyZA4uRI0eWePv169dhbOvWrVN5EXIJCQkxuE03sysrK0slZqelpanrMn1q/fr1WLhwoZoCJdOZRo0ahZdeesno7SUjJ1pLENH6HkByINa+pK3gVLMZUK+fdlpT3R7a+4e2117IZA5fTMTC9aew/tgVg+0hPi54pFc9jGpbC072diZrHxEREVVhYOHl5XXL26UErTHdd9996lKSOnXq6IMMIYFEwVW3yUJtXQyc/UflSiAjKW9FawkaBr0ODH9fW9GJzMbxy0lYuO4U1hy5bLC9lrcLHu8jAUUIHOw4lYiIiKhaBRaSz0BUlYnWau2ImAPAPT8AtnbA2U3asq5dnwBqd9EGFboVrb1r88Mxs7KxCzecwu8HYwpNeXqsTz3c1S4UjvYMKIiIiKyBReZYkJXKTAUc3bQ/vxgIXDlyM9HaXzulSQINV1/g3h9N3VK6hTPXUvDuhlP45cAlg6U9/D2c8GivCOZQEBERWSEGFmQacrQpidVR27VJ1pInISsXPLFPG1zU7Ql0eFA7IuEXISUz+ElZgPNxqXh3g6yUfcFgYbsa7o54qGcE7u0UxqRsIiIiK8XAgqou0fryISA7HajdUZt0/VE3KbKnTbSO6KPKv6qAQ4KIga/yk7EgV5LSVdnYFbuikZ0vovBxdVABxfjOYWZfNpaIiIgqhv/Tk/EkRAKHf4LN+a3wjdoO28wUIKwrMOkPIKAJcPcPQGgHJlpbsOtpmfhw0xl8tTUS6Vm5+u1eLg54sEc4JnapA3cn/pkhIiKqDvg/PlWO9CRtorVMawpqCciK1rGngX8XqODhRpsH4dKwD2xD2mnvL0nYDQaw9y1UWmY2lmyJxEebziA5PVu/XYKIyd3qYnL3uvA0w5WyiYiIyHgYWFD56KYsHfoR2LJIO7VJEq1da2irNQlZkO65SGhsbHEjPh4uvr7aVa7JYmVm52L5riiVRxGbkqHfLpWdxncKwyO9IuDnXnileiIiIrJ+DCyodEFEwrm81azlZ+8XgOZ3AvbOQM2mQPsHtCta+9XLS7S2u7l75eZNkSHLlJOrwS8HLuKddScRHX9Dv93WBhjdNhRP9quPYG8Xk7aRiIiITIuBBRWzovURoEYD7foQq6YCB7+/mWjdFIjoDfjW1d638e3aC1klWWRyw7GreGvtCRy/nGxw223NAzG9f0PUC3A3WfuIiIjIfDCwIC3Jj4j8VzsaoVa0TgQm/grU7QG0mQA0G3Uz0dqHPVZN7ItKwOt/HMfOyHiD7d3q1cCMgQ3RMpSrmxMREVEeBhbVNdH6wk7gwh6gxwxt3sOfzwGxJ7XBQ5fHtaVfa91MtK4jZWGpuoiKS8P8v44XWi1bAonnBjZEl3o1TNY2IiIiMl8MLKqL7Exg3cvaHAlZT0KXaN1mPOAZDIxdpl3hWpcXQdVOQmomFv99Gku3RyIrJ28tivAabnh2UEMMbBoIGy5USERERMXgUaRVJlpHAlHbgPNbgZSrwD0rAHtHIOaAdv2IdpMLJ1p7Bpm65WQi6Vk5ah2K9zaeNigd6+fmiGn96mNsh9pwsGM1LyIiIioZAwtrSLS+kQC41QDizwFLBgPJMoXFRhtESAAh95F1I+7/09StJTOSqyo9XcKbf53Axet5lZ6cHWzxQLdwTO0ZDg+uRUFERESlxMDC0mRnAJf2aUcjZFQiagcQ1AK47zfAKwRoOQ6o3YmJ1lSirWdi8dofx3D4YpJ+mwxe3dkmBNMHNECQF0vHEhERUdkwsLA0Z/4GvhsLOLrfTLR+DKjTXXubnQPQ7xVTt5DM2NlrKSqgWH/sqsH2ng388fzgRmgc5GmythEREZFlY2BhaSSIePAfoGZzJlpTqSXeyMK7G06pXIrs3LzE7CZBnnjhtsboVp+VnoiIiKhiGFhYGid3ILi1qVtBFiI7Jxff7YrGgnUnEZ+aqd9e09MJMwY2wsjWtWAry2cTERERVRADCyIr9d/pWLz6+3GcuJK3YraTvS2m9ozAQz3D4erIrz8RERFVHh5ZEFmZc7GpmP3zCfx75rrB9mEtg/Hc4Eao5c3EbCIiIqp8DCyIrCiPYrHkUWwzXOCuZYgXXh7aBG3DfE3aPiIiIrJuDCyILFxOrgbLd0Xh7bWGeRQBHk54blAjjGAeBREREVUBBhZEFmzP+QS88sthg/UoJI/i3naBmDawKTxcHE3aPiIiIqo+GFgQWaDYlAzM//M4fthzwWD7kBZBeH5gQ7hobsDNiV9vIiIiqjo88iCysPKxS7efxzvrTiI5PVu/vVGgB2YPa4pO4X7Izc1FfPwNk7aTiIiIqh8GFkQWYsfZOLzyyxEcv5xXPtbD2R5P92+AezuFwd7O1qTtIyIiouqNgQWRmbuSlI7X/jiGn/dfMtg+um0Inh3UCP4eTiZrGxEREZEOAwsiM5WZnYsvt57DovWnkJqZo9/erJYn5g5vhja1fUzaPiIiIqL8GFgQmaHtZ+Pw0urDOH01Rb/N29UBMwY2xNj2tWFna2PS9hEREREVxMCCyIzEpWTgtT+O46e9edWebGyAuzvUxjMDGsLHjeVjiYiIyDwxsCAyA7m5GvywJxqv/3kc19Oy9Ntbhnrj1TuaoVktL5O2j4iIiOhWGFgQmdiJy8l4afUh7IpMMKj2JKtmj+vAaU9ERERkGRhYEJlIWmY23t1wGp/9exbZuRr99uGtgvHikMYI8HDmZ0NEREQWg4EFkQn8ffwKZq0+govX8xayq1vDDfOGN0O3+jX4mRAREZHFYWBBVIViEm9gzi9HsebIZf02RztbPNwrQl2cHez4eRAREZFFYmBBVAVycjX4Zvt5/G/NcYM1KbrW81OjFOH+7vwciIiIyKIxsCAyslNXkvHcTwexN+q6flsNd0e8NKSJyqewkXqyRERERBaOgQWREVfO/uCf03h/42lk5eQlZ4/rEIrnBzWGl6sD+56IiIisBgMLIiPYcz4BM1cexMkrKQbJ2a+PbI5O4X7scyIiIrI6DCyIKlFqRjbe/OsEvtoWCc3NQQo7WxtM7RGOJ/rWZ3I2ERERWS0GFkSV5J8TV/HiqsMGJWSb1fLE/FEt0DSYK2cTERGRdWNgQVRB8amZmPvrEazef0m/zdnBFtP7N8D9XevC3s6WfUxERERWj4EFUTlpNBr8ejAGs385ooILnS4RfiqXIszPjX1LRERE1QYDC6JyuJacgVmrDxssdOfpbK9KyI5uF8ISskRERFTtWOwcjTp16qiDt/yXN954o8THpKen49FHH4Wfnx/c3d0xatQoXLlypcraTFYySnHgEgYs2GQQVAxuFoj1T/fEXe1DGVQQERFRtWTRIxZz587FlClT9Nc9PDxKvP9TTz2F33//HT/88AO8vLzw2GOPYeTIkdiyZUsVtJYsXWxKBl5aZThK4evmqFbOHtIiyKRtIyIiIjI1iw4sJJAIDAws1X0TExPx+eefY9myZejTp4/atmTJEjRu3Bjbt29Hp06djNxasuRRit8OxuDlnw8jIS1Lv/225oGYO7wZarg7mbR9RERERObAogMLmfo0b9481K5dG3fffbcakbC3L/ot7dmzB1lZWejXr59+W6NGjdRjt23bVmxgkZGRoS46SUlJ6mdubq660K1JP8nBuSX2l4xSvPzzEaw5kjdlztfVAXOGNdWPUpjb+7Lk/rY07Gv2tbXivs2+tkbcr8unLMcTFhtYPPHEE2jTpg18fX2xdetWzJw5EzExMXjnnXeKvP/ly5fh6OgIb29vg+01a9ZUtxXn9ddfx5w5cwptT0hIQHZ2diW8k+qxQyYnJ6uDXVtby0nrWXc8DvM3ROL6jbzPuU99Hzzfry583RwQHx8Pc2Sp/W2J2Nfsa2vFfZt9bY24X5ePHFNYZGDx/PPPY/78+SXe59ixY2qkYfr06fptLVq0UEHD1KlTVSDg5FR5U1MkYMn/WjJiERoaCh8fH3h6elba61j7F1mS66XPLOFAN05GKX45ij8P5wWcPrpRiuaBZp+cbWn9bcnY1+xra8V9m31tjbhfl09xs4GKvC/MyNNPP4377ruvxPuEh4cXub1jx45qBCEyMhINGzYsdLvkYmRmZuL69esGoxZSFaqkPA0JUooKVOSAjQdtpScHupbQZ+uOXsHMlQcRm5JpUPFp3h2WlUthKf1tDdjX7GtrxX2bfW2NuF+XXVmOJcwqsPD391eX8ti/f7964wEBAUXe3rZtWzg4OGDDhg2qzKw4ceIEoqKi0Llz5wq1myxfSkY25v16FN/vjjYYpZDk7NtbBJn9KAURERGRqZlVYFFakmy9Y8cO9O7dW1WGkuuSuH3vvfeq6R/i4sWL6Nu3L77++mt06NBBlZedPHmymtYkeRkyjenxxx9XQQUrQlVvuyLjMX3FfkTH39Bv69c4AK+PbAF/D8sZpSAiIiIyJYsMLGRq0vLlyzF79mxVsalu3boqsMifCyEVoGREIi0tTb9twYIFalRDRizkcQMHDsQHH3xgondBppaRnYMF607h481noNFot7k52uHloU1wVzsudEdERERk9YGFVIOStSdutTK3VMXJz9nZGe+//766UPV2/HISpi3fj+OX8yodtAvzwTt3tUJtP1eTto2IiIjIEllkYEFUXjm5Gnz+31m89ddJZOZo6zI72Nlgev+GeLBHOOxsmUtBREREVB4MLKjaiI5Pw9M/HMDOc3nrTzSs6YF3xrRE02Avk7aNiIiIyNIxsCCrJ1Piftp7EbN/OaKqPwkp8jSlezim928AZwc7UzeRiIiIyOIxsCCrlngjCy+uOoTfDsbot9XydsHbd7VEp3A/k7aNiIiIyJowsCCrLiMrCdoXr+eVkR3VJgSzhzWBh7ODSdtGREREZG0YWJDVyc7JxeK/T2Px36eQe7MwmKezvVqXYkiLIFM3j4iIiMgqMbAgq0vQnvb9fuw5n6Df1qGOLxaMbaWmQBERERGRcTCwIKvxy4FLeHHlISTfTNCW0rFP9q2PR3vXYxlZIiIiIiNjYEEWTyo9ScWnH/dc0G8L8XHBorGt0TbMx6RtIyIiIqouGFiQRTsQfR1PLt+HyLg0/bbhrYIx745m8GSCNhEREVGVYWBBFik3V4OPN5/F22tPIPtmhrabox3+b0QzjGgdYurmEREREVU7DCzI4sSmZOCp7/fj31Ox+m0tQ73x7thWCPNzM2nbiIiIiKorBhZkUbadiVNTn64mZ+hX0H6kVwSm9WsABztbUzePiIiIqNpiYEEWISdXo9aleHdD3toUNdyd1ChFl3o1TN08IiIiomqPgQWZvavJ6WoF7a1n4vTbutWrgQVjWsHfw8mkbSMiIiIiLQYWZNb+OxWLad/vQ2xKprpuawM81a8BHuHaFERERERmhYEFmaXsnFwsXH8K7/9zGpqbU59qejqptSk6hfuZunlEREREVAADCzI7lxPT8cTyfdh5Ll6/rWcDf7xzV0v4uXPqExEREZE5YmBBZmXjiat4esUBxKdqpz7Z2drgmQENMbVHOGxlHhQRERERmSUGFmQ2VZ/eWXcC7288o98W5OWMxeNao10dX5O2jYiIiIhujYEFmcWCd098t8+g6lPfRgF4a3RL+Lg5mrRtRERERFQ6DCzIpPacj8cj3+7FlaQM/dSn5wY1xJTu4bCR1e+IiIiIyCIwsCCT0Gg0WLIlEq/9cQzZN1e8kzUp3hvXGh1Z9YmIiIjI4jCwoCqXkpGN5346iN8Pxui3dajri/fubo0AD2d+IkREREQWiIEFVamTV5Lx0Dd7cPZaqn7b1J7hmDGgIeztbPlpEBEREVkoBhZUZX45cAkzVx7Gjawcdd3DyR5v3dUSA5sG8lMgIiIisnAMLMjoMrNz8b8NkVix74p+W6NAD3x0b1vUqeHGT4CIiIjICjCwIKO6dP0GHvl2D/ZHJ+q3jWoTgv+7oxlcHO3Y+0RERERWgoEFGc32s3F49Nu9iLu5irajvS3mDGuKse1DWUqWiIiIyMowsCCjlJL9cmsk/u/3Y2pFbRHs6YQPx7dFy1Af9jgRERGRFWJgQZUqPSsHL6w6hJV7L+q3da9fA7MHhKFuLS/2NhEREZGVYmBBlebi9RuYunQ3Dl9M0m97qGcEnu5fH4nXE9jTRERERFaMgQVVim1n4vDosr2Iv5lP4eJghzdHt8DtLYKRm5vLXiYiIiKycgwsqML5FEu2ROLVP/LyKWr7uuKTCW3RKNCTvUtERERUTTCwoHK7kanNp1i1Ly+fokcDf7w7thW8XR3Zs0RERETVCAMLKpcLCWmYunQPjlzKy6d4pFcEnh7QEHa2NuxVIiIiomqGgQWV2dYzsWp9ioS0LHXd1dEOb41uiduaB7E3iYiIiKopBhZUJku3RWL2r0f1+RRhfq74ZHw7NAz0YE8SERERVWMMLKhUsnJyMfuXI/h2R5R+W0+VT9EaXq4O7EUiIiKiao6BBd1SQmomHv52D7afjddvm9ojHM8OasR8CiIiIiJSGFhQiU5eScbkr3YhOv6Guu5oZ4vXRzbHqLYh7DkiIiIi0mNgQcVaf/QKnly+D6mZOep6DXcnfDy+LdqG+bDXiIiIiMgAAwsqctG7jzadxf/+Og6NNkcbTYM98emEdgj2dmGPEREREVEhtrBA//zzD2xsbIq87Nq1q9jH9erVq9D9H3rooSptu7lLz8rB9BUHMH9NXlAxpHkQfnioM4MKIiIiIrKuEYsuXbogJibGYNusWbOwYcMGtGvXrsTHTpkyBXPnztVfd3V1NVo7Lc3VpHQ8uHQP9kdf1297ql8DPNG3ngrCiIiIiIisKrBwdHREYGCg/npWVhZ+/vlnPP7447c8AJZAIv9jSevQhURM+Xo3Lielq+suDnZ4566WGMxF74iIiIjIWqdCFfTLL78gLi4OkyZNuuV9v/32W9SoUQPNmjXDzJkzkZaWhupuzeEYjP54qz6oCPZyxo8Pd2ZQQURERETWPWJR0Oeff46BAwciJKTkEqh33303wsLCEBwcjIMHD+K5557DiRMnsHLlymIfk5GRoS46SUlJ6mdubq66WHqS9if/nsP8NSf029rW9sYH97SBv4dTpb0/eR55LUvvL0vB/mZfWyPu1+xva8V9m31t7spy/GZWgcXzzz+P+fPnl3ifY8eOoVGjRvrrFy5cwF9//YUVK1bc8vkffPBB/e/NmzdHUFAQ+vbtizNnziAiIqLIx7z++uuYM2dOoe0JCQnIzs6GpcrOycXr6yPx86Fr+m23NamBlwbUhV1WKuLjUyt1h0xOTlbBha2tVQySmTX2N/vaGnG/Zn9bK+7b7GtzJ8dwpWWjkaM9M3Ht2jU1pakk4eHhKsdCZ968eVi8eDEuXrwIBweHMr1eamoq3N3dsWbNGjXiUdoRi9DQUBVYeHp6whIl3sjCI9/uw7azeX09vV99PNo7wihJ2vJHU/rLx8eHgUUVYH9XHfY1+9pacd9mX1sj7tflI8e+cgyXmJh4y2Nfsxqx8Pf3V5fSkphoyZIlmDBhQpmDCrF//371U0YuiuPk5KQuBcmZd0s8+34+LhWTvtyFs9e0IxKO9rZ4884WGN6qllFfVwIWS+0zS8T+Zl9bI+7X7G9rxX2bfW3OynLsZtFHeX///TfOnTuHBx54oNBtMoIhU6Z27typrst0Jxnd2LNnDyIjI1XCtwQkPXr0QIsWLVAd7I6Mx4gPtuqDCj83R3w3paPRgwoiIiIisn5mNWJRnqRtWdMif85F/hK0kpitq/ok06fWr1+PhQsXqilQMp1p1KhReOmll1Ad/Lz/Imb8cBCZOdoEnHoB7vhiYnvU9uM6HkRERERUzQOLZcuWFXtbnTp11FQpHQkkNm3ahOpG+mDRhlNYuP6UflvXen744J628HIp+/QxIiIiIiKrCyyoZBnZOXjux4NYvf+SftvY9qGYd0czONhZ9Cw4IiIiIjIzDCysVEJqJh5cuhu7IhPUdSn29PygRniwR7hRKj8RERERUfXGwMIKRcWl4b4lO3E2Vpuk7exgi4VjWmFQs+KrXxERERERVQQDCytzIPo6Jn+1C7Epmeq6rKD9+cR2aBHibeqmEREREZEVY2BhRTYcu4LHlu3DjawcfeWnJfe1R6gvKz8RERERkXExsLAS3+44j1mrDyP3ZiGsDnV98en4dvByZeUnIiIiIjI+BhZWUE72rbUn8P7GM/ptQ1oE4e3RLeHsYGfSthERERFR9cHAwoJlZufiuZ8OYtW+i/ptU7rXxczBjWFry8pPRERERFR1GFhYqKT0LDz8zR5sOR2nrksF2Vdub4L7utY1ddOIiIiIqBpiYGGBYhJvYNKSXTh+OVldd7K3xaKxrTGoWaCpm0ZERERE1RQDCwtzLCZJBRWXk9LVdR9XB3w2sT3ahvmYumlEREREVI0xsLAgW07H4qGle5Ccka2u1/Z1xZeT2iPc393UTSMiIiKiao6BhYVIycjGY8v26oOKlqHeauG7Gu5Opm4aERERERFs2QeWwd3JXuVR2NvaoF/jAHw3pSODCiIiIiIyGxyxsCA9Gvjj+6md0DLEG/Z2jAmJiIiIyHwwsLAwbcN8Td0EIiIiIqJCeNqbiIiIiIgqjIEFERERERFVGAMLIiIiIiKqMAYWRERERERUYQwsiIiIiIiowhhYEBERERFRhTGwICIiIiIiBhZERERERGR6HLEgIiIiIqIKY2BBREREREQVxsCCiIiIiIgqjIEFERERERFVGAMLIiIiIiKqMAYWRERERERUYfYVf4rqRaPRqJ9JSUmmborFyM3NRXJyMuzt7WFry1iW/W09uG+zr60V9232tTXifl0+umNe3TFwSRhYlJEcIIvQ0NDyfDZERERERBZ5DOzl5VXifWw0pQk/yCDavXTpEjw8PGBjY8OeKWWkK4FYdHQ0PD092WdGxv6uOuxr9rW14r7NvrZG3K/LR0IFCSqCg4NvOfOEIxZlJB0aEhJSzo+mepOggoEF+9sacd9mX1sr7tvsa2vE/brsbjVSocMJ70REREREVGEMLIiIiIiIqMIYWJDROTk54ZVXXlE/if1tTbhvs6+tFfdt9rU14n5tfEzeJiIiIiKiCuOIBRERERERVRgDCyIiIiIiqjAGFkREREREVGEMLKjKDRs2DLVr14azszOCgoIwfvx4teggVa7IyEhMnjwZdevWhYuLCyIiIlQSfWZmJrvaCF599VV06dIFrq6u8Pb2Zh9Xsvfffx916tRRfzc6duyInTt3so+NYPPmzRg6dKhaCEsWgV29ejX72Uhef/11tG/fXi24GxAQgDvuuAMnTpxgfxvBhx9+iBYtWujXr+jcuTP+/PNP9rURMLCgKte7d2+sWLFC/QH96aefcObMGdx55538JCrZ8ePH1UrxH3/8MY4cOYIFCxbgo48+wgsvvMC+NgIJ2EaPHo2HH36Y/VvJvv/+e0yfPl0Fxnv37kXLli0xcOBAXL16lX1dyVJTU1X/SiBHxrVp0yY8+uij2L59O9atW4esrCwMGDBAfQZUuWRh4zfeeAN79uzB7t270adPHwwfPlz930iVi1WhyOR++eUXdaYmIyMDDg4Opm6OVXvzzTfVmZuzZ8+auilW68svv8S0adNw/fp1UzfFasgIhZzZfe+999R1CZhDQ0Px+OOP4/nnnzd186yWjFisWrVK/X0m47t27ZoauZCAo0ePHuxyI/P19VX/J8rIPlUejliQScXHx+Pbb79VU0gYVBhfYmKi+mNKZEkjQXKWsV+/fvpttra26vq2bdtM2jaiyv77LPg32rhycnKwfPlyNTIkU6KocjGwIJN47rnn4ObmBj8/P0RFReHnn3/mJ2Fkp0+fxuLFizF16lT2NVmM2NhYdSBQs2ZNg+1y/fLlyyZrF1FlklE4Gens2rUrmjVrxs41gkOHDsHd3V0tkvfQQw+p0bgmTZqwrysZAwuqFDIdQYbNS7rInH+dGTNmYN++fVi7di3s7OwwYcIEaDQafhpG6Gtx8eJFDBo0SOUATJkyhf1spP2aiKg8JNfi8OHD6kw6GUfDhg2xf/9+7NixQ+XCTZw4EUePHmV3VzLmWFClzQ2Ni4sr8T7h4eFwdHQstP3ChQtqvvTWrVs5LGmEvpaKW7169UKnTp3U/H+ZRkLG26+ZY1H5U6Gk0taPP/5oMNdfDgokj4WjncbDHIuq8dhjj6n9WCpySRU/qhoynVKqJUqBE6o89pX4XFSN+fv7q0t5h4CFJG9T5fa1jFRIFa62bdtiyZIlDCqqcL+myiFBm+y/GzZs0AcW8jdDrssBGZGlklF6KUAgU3L++ecfBhVVTP6O8Lij8jGwoColQ5C7du1Ct27d4OPjo0rNzpo1S501YBJV5ZKgQkYqwsLC8NZbb6mz7zqBgYGV/GokuUJSjEB+Sk6ADLmLevXqqXm9VH5SalZGKNq1a4cOHTpg4cKFKvFy0qRJ7NZKlpKSovKxdM6dO6f2ZUkolvWHqHKnPy1btkyNVshaFrqcIS8vL7X2EFWemTNnYvDgwWofTk5OVv0uwdxff/3Fbq5sGqIqdPDgQU3v3r01vr6+GicnJ02dOnU0Dz30kObChQv8HCrZkiVLJGmlyAtVvokTJxbZ1xs3bmR3V4LFixdrateurXF0dNR06NBBs337dvarEcj+WtR+LPs3Va7i/j7L326qXPfff78mLCxM/f3w9/fX9O3bV7N27Vp2sxEwx4KIiIiIiCqMWZxERERERFRhDCyIiIiIiKjCGFgQEREREVGFMbAgIiIiIqIKY2BBREREREQVxsCCiIiIiIgqjIEFERERERFVGAMLIiIiIiKqMAYWRERERERUYQwsiIiIiIiowhhYEBGRUfXq1QvTpk2zmtchIqKi2Wg0Gk0xtxERkZm7fPkyXn/9dfz++++4cOECvLy8UK9ePdx7772YOHEiXF1dTd1ExMfHw8HBAR4eHlbxOkUFNK1atcLChQur9HWJiMyNvakbQERE5XP27Fl07doV3t7eeO2119C8eXM4OTnh0KFD+OSTT1CrVi0MGzbM5N3r6+trVa9DRERF41QoIiIL9cgjj8De3h67d+/GXXfdhcaNGyM8PBzDhw9XIxhDhw5V91uzZg26deumAhA/Pz/cfvvtOHPmjMFz1alTp9AZdzkLP3v2bP31H3/8UQUvLi4u6nn69euH1NTUW95WcIrSrdoj93/iiSfw7LPPqmAhMDDQoB3Fyf86pXkOuc9jjz2mLjLSU6NGDcyaNQv5B/Jv1S/33XcfNm3ahEWLFsHGxkZdIiMji2zfd999p/onJiZGv23SpElo0aIFEhMTb/n+iIjMHQMLIiILFBcXh7Vr1+LRRx+Fm5tbkfeRg1whB/jTp09XAciGDRtga2uLESNGIDc3t9SvJwfD48aNw/33349jx47hn3/+wciRI9VBeEm3FaU07fnqq6/U+9qxYwf+97//Ye7cuVi3bl2Z+qg0zyH3keBs586dKjh455138Nlnn5X6NeQxnTt3xpQpU1Q/yCU0NLTI+44dOxYNGjRQo0vilVdewfr16/Hnn3+qwIaIyNJxKhQRkQU6ffq0OnBv2LChwXY5656enq5+l6Bj/vz5GDVqlMF9vvjiC/j7++Po0aNo1qxZqV5PDpizs7NVwBAWFqa2yQiFOHnyZLG3FaU07ZGz+HLgLerXr4/33ntPBSH9+/cvVXtL+xwSBCxYsEAFYdKXMo1MrkugUBoSEDg6OqpcFhkVKYm8xquvvoo777xT3Xfx4sX4999/1ZQ1ndWrV6sgKCMjQ12krW+++aYKfoiIzB1HLIiIrIiced+/fz+aNm2qDkzFqVOn1IiCTJPy9PRU03tEVFRUqZ+3ZcuW6Nu3rwoYRo8ejU8//RQJCQm3vK0opWmPBAX5BQUF4erVq2Xqi9I8R6dOnfQjO0JGH6R9OTk5MAaZ9tWkSRM1erJq1Sr1Oel8/fXXeOONN9S0sj179mDXrl2qbQwqiMhSMLAgIrJAUvlJDjpPnDhhsF0O1uU2mcuvI7kWUjFJDvhlWpBcRGZmpv4+Mh2p4NSlrKws/e92dnZqGpFM25EDYznbLmf4z507V+JtRSlNe6S6U37yXssydauynuNW/VJWkl9y/PhxFbjUrFlTv11yLJ555hksX74cwcHBapt8hjI1i4jIUjCwICKyQJL0LNNkZHqPLkm6uFwMCT5eeuklNaogCd5FjSbIVKT8ScVJSUmFAgM5MJcqVHPmzMG+ffvUFCA5636r28rTnqqiC2p0tm/frqZNSbBU2n6R91qaEY69e/eqJPvPP/9cvXdJFNf57bff1GiJbvSGiMgScdImEZGF+uCDD9TBfLt27VSVIpn6I2fYZQqNnBVv27YtfHx8VBAi5WdlKpBMN3r++ecLPVefPn3w5ZdfqtEEqdb08ssv6w+udQfgkp8wYMAABAQEqOvXrl1TgUFJtxVU2vZUFXl9SSSfOnWqOvCX0Za333671P0iJBiQ9yzVoNzd3VUVKvkc8pPbhgwZghdeeEE/DUwCCXnNNm3aFMp3GTNmDA4ePIiOHTuq1ycisgQMLIiILFRERIQaHZAqQzNnzlQL5Mk6FjIdSabVSDlaOcCV6TVSelUOXGWK0rvvvqtKreYnj5cz8ZIDIAnJ8+bNMzgzL7kQmzdvVqVX5ay9JGnLAfjgwYNVJajibiuotO2pKhMmTMCNGzfQoUMHFTA8+eSTePDBB0vdL0L6WhYjlH6X55Lb8488yLSvQYMGqTLAuiBKAgbpHwk0ZHqUTHvSJd2L77//XvVLbGxslfQDEVFl4MrbRERULZnTitkyynTPPfdgy5YtavqVVNmS8rSyTUrxEhFZAo5YEBERmVj79u3VaEbv3r1VzoZcJPCRXAwiIkvBwIKIiMgMyAKDciEislScCkVERERERBXGcrNERERERFRhDCyIiIiIiKjCGFgQEREREVGFMbAgIiIiIqIKY2BBREREREQVxsCCiIiIiIgqjIEFERERERFVGAMLIiIiIiKqMAYWRERERERUYQwsiIiIiIiowhhYEBERERERKur/ATLikNY5oJhcAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x_gaussian_grid = np.linspace(-3.5, 3.5, 400)\n", + "\n", + "uniform_values = norm.cdf(x_gaussian_grid)\n", + "\n", + "x_logistic_grid = logistic.ppf(uniform_values)\n", + "\n", + "plt.figure(figsize=(8, 5))\n", + "\n", + "plt.plot(\n", + " x_gaussian_grid,\n", + " x_logistic_grid,\n", + " linewidth=2,\n", + " label=r\"$F_L^{-1}(\\Phi(x))$\",\n", + ")\n", + "\n", + "# Identity line for reference\n", + "plt.plot(\n", + " x_gaussian_grid,\n", + " x_gaussian_grid,\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + " label=\"Identity reference\",\n", + ")\n", + "\n", + "plt.xlabel(\"Gaussian input $x_G$\")\n", + "plt.ylabel(\"Logistic output $x_L$\")\n", + "plt.title(\"Gaussian → Uniform → Logistic Transport\")\n", + "\n", + "plt.legend()\n", + "plt.grid(alpha=0.25)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e2a3ea36", + "metadata": {}, + "source": [ + "The transformation is monotone because both the Gaussian CDF $\\Phi$ and the Logistic inverse CDF $F_L^{-1}$ are monotone.\n", + "\n", + "The intermediate uniform value is\n", + "\n", + "$$\n", + "u=\\Phi(x_G),\n", + "$$\n", + "\n", + "and the final output is\n", + "\n", + "$$\n", + "x_L=F_L^{-1}(u).\n", + "$$\n", + "\n", + "Therefore the complete transport is\n", + "\n", + "$$\n", + "T(x_G)=F_L^{-1}(\\Phi(x_G)).\n", + "$$\n", + "\n", + "This clarifies the ordering: the Uniform distribution is not an arbitrary extra step. It is the intermediate probability scale that connects the Gaussian CDF to the Logistic inverse CDF." + ] + }, + { + "cell_type": "markdown", + "id": "945affc1", + "metadata": {}, + "source": [ + "## What this reveals about the current `TrueMeasure` abstraction\n", + "\n", + "The domain-inclusion change answers one question:\n", + "\n", + "> When two existing transformations are composed, is the output range of the first valid input for the second?\n", + "\n", + "However, Gaussian-to-Logistic transport introduces a second question.\n", + "\n", + "The current `TrueMeasure._transform` interface is primarily designed around transformations that generate a measure from the input supplied by the preceding sampler. For common inverse-CDF constructions, the map is naturally\n", + "\n", + "$$\n", + "(0,1) \\rightarrow \\text{target support}.\n", + "$$\n", + "\n", + "A Gaussian-to-Logistic transport instead requires the forward Gaussian CDF\n", + "\n", + "$$\n", + "\\Phi:\\mathbb{R}\\rightarrow(0,1)\n", + "$$\n", + "\n", + "followed by the Logistic inverse CDF\n", + "\n", + "$$\n", + "F_L^{-1}:(0,1)\\rightarrow\\mathbb{R}.\n", + "$$\n", + "\n", + "Therefore, domain-range inclusion alone does not automatically create this transport.\n", + "\n", + "The inclusion change makes existing compatible transformation chains more general, while explicit distribution-to-distribution transport may require additional transformation semantics." + ] + }, + { + "cell_type": "markdown", + "id": "c5c1d083", + "metadata": {}, + "source": [ + "## Transport versus importance sampling\n", + "\n", + "A Logistic distribution may also be used as an importance-sampling proposal for a Gaussian target.\n", + "\n", + "That is a different operation from transporting Gaussian samples into Logistic samples.\n", + "\n", + "If\n", + "\n", + "$$\n", + "p(x)\n", + "$$\n", + "\n", + "is the Gaussian target density and\n", + "\n", + "$$\n", + "q(x)\n", + "$$\n", + "\n", + "is the Logistic proposal density, then samples are generated from\n", + "\n", + "$$\n", + "X \\sim q\n", + "$$\n", + "\n", + "and weighted using\n", + "\n", + "$$\n", + "w(X)=\\frac{p(X)}{q(X)}.\n", + "$$\n", + "\n", + "The corresponding integrand becomes\n", + "\n", + "$$\n", + "g(X)\\frac{p(X)}{q(X)}.\n", + "$$\n", + "\n", + "In this case, Logistic is a proposal distribution rather than an intermediate deterministic transport.\n", + "\n", + "These two concepts should remain separate:\n", + "\n", + "1. **Transformation composition:** can the output space of one deterministic transformation feed the next?\n", + "2. **Importance sampling:** can another measure be used to generate samples and corrected using density ratios?" + ] + }, + { + "cell_type": "markdown", + "id": "e1994b43", + "metadata": {}, + "source": [ + "# Conclusions\n", + "\n", + "This investigation establishes the following:\n", + "\n", + "1. The previous chained `TrueMeasure` compatibility rule effectively required exact equality between the range of one transformation and the domain of the next:\n", + "\n", + " $$\n", + " R_{j-1} = D_j.\n", + " $$\n", + "\n", + "2. Exact equality is unnecessarily restrictive for domain compatibility. For the current interval and axis-aligned box representation, compatibility can instead be generalized to coordinate-wise range-in-domain containment:\n", + "\n", + " $$\n", + " R_{j-1} \\subseteq D_j.\n", + " $$\n", + "\n", + " Equality remains valid because it is a special case of containment.\n", + "\n", + "3. In one dimension, for\n", + "\n", + " $$\n", + " R_{j-1} = [r_L,r_U]\n", + " $$\n", + "\n", + " and\n", + "\n", + " $$\n", + " D_j = [d_L,d_U],\n", + " $$\n", + "\n", + " compatibility requires\n", + "\n", + " $$\n", + " d_L \\leq r_L\n", + " \\qquad\\text{and}\\qquad\n", + " r_U \\leq d_U.\n", + " $$\n", + "\n", + " The same rule extends coordinate-wise to multidimensional axis-aligned boxes. QMCPy's `(1,2)` and `(d,2)` representations remain interoperable through NumPy broadcasting.\n", + "\n", + "4. The behavior change can be seen directly in the motivating example:\n", + "\n", + " Previous behavior required\n", + "\n", + " $$\n", + " [0.25,0.75] = [0,1],\n", + " $$\n", + "\n", + " which is false, so the chain was considered incompatible.\n", + "\n", + " Under the updated rule,\n", + "\n", + " $$\n", + " [0.25,0.75] \\subseteq [0,1],\n", + " $$\n", + "\n", + " so the chain is correctly accepted as domain-compatible because every output of the preceding transformation lies inside the input domain of the next transformation.\n", + "\n", + "5. The change does not weaken compatibility checking. A range that actually extends outside the next domain is still rejected. For example,\n", + "\n", + " $$\n", + " [-0.1,0.75] \\nsubseteq [0,1].\n", + " $$\n", + "\n", + "6. The initial scope is one-dimensional intervals and multidimensional axis-aligned boxes with finite or unbounded numerical endpoints, represented using values such as `-np.inf` and `np.inf`. Because the metadata does not separately encode open and closed finite endpoints, the comparison operates on stored interval envelopes. Disconnected supports such as\n", + "\n", + " $$\n", + " [0,5]\\cup[10,20]\n", + " $$\n", + "\n", + " and arbitrary nonrectangular domains are outside the scope of this change.\n", + "\n", + "7. Exploring Gaussian, Uniform, and Logistic transformations clarifies an additional point. A Gaussian-to-Logistic deterministic transport is naturally\n", + "\n", + " $$\n", + " X_G\n", + " \\xrightarrow{\\Phi}\n", + " U\n", + " \\xrightarrow{F_L^{-1}}\n", + " X_L,\n", + " $$\n", + "\n", + " or conceptually,\n", + "\n", + " $$\n", + " \\mathrm{Gaussian}\n", + " \\rightarrow\n", + " \\mathrm{Uniform}\n", + " \\rightarrow\n", + " \\mathrm{Logistic}.\n", + " $$\n", + "\n", + " The complete transport can be written as\n", + "\n", + " $$\n", + " T(x)=F_L^{-1}(\\Phi(x)).\n", + " $$\n", + "\n", + "8. The reverse transport is\n", + "\n", + " $$\n", + " X_L\n", + " \\xrightarrow{F_L}\n", + " U\n", + " \\xrightarrow{\\Phi^{-1}}\n", + " X_G.\n", + " $$\n", + "\n", + " The numerical round-trip experiment recovers the original Gaussian values up to floating-point roundoff, confirming the expected inverse relationship.\n", + "\n", + "9. This also shows an important limitation of the current change: domain-range inclusion makes existing transformation chains more flexible, but it does not by itself create arbitrary distribution-to-distribution transport maps.\n", + "\n", + " A Gaussian-to-Logistic transport requires a forward Gaussian CDF followed by a Logistic inverse CDF, while many current `TrueMeasure` transformations are structured primarily around generating a target measure from the preceding sampler.\n", + "\n", + "10. Transport and importance sampling should therefore remain conceptually separate.\n", + "\n", + " For transport, the concern is whether deterministic maps can be composed through compatible intermediate spaces.\n", + "\n", + " For importance sampling, a proposal density $q$ can instead be used to sample $X$ and correct for a target density $p$ using\n", + "\n", + " $$\n", + " g(X)\\frac{p(X)}{q(X)}.\n", + " $$\n", + "\n", + " The Logistic distribution can therefore play a different role as an importance-sampling proposal rather than as an intermediate deterministic transport.\n", + "\n", + "Hence, this change provides a small but useful generalization of `TrueMeasure` composition:\n", + "\n", + "$$\n", + "\\boxed{\n", + "R_{j-1} = D_j\n", + "\\quad\\longrightarrow\\quad\n", + "R_{j-1} \\subseteq D_j\n", + "}\n", + "$$\n", + "\n", + "for the current interval and axis-aligned box representation.\n", + "\n", + "It recognizes domain-compatible chained transformations that were previously rejected solely because their intermediate bounds were not identical, while preserving rejection of genuinely incompatible boundaries." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv (3.13.5.final.0)", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/qmcpy/true_measure/abstract_true_measure.py b/qmcpy/true_measure/abstract_true_measure.py index b7611b1f3..c51edc335 100644 --- a/qmcpy/true_measure/abstract_true_measure.py +++ b/qmcpy/true_measure/abstract_true_measure.py @@ -30,6 +30,29 @@ def _read_only_array(value): array.setflags(write=False) return array + @staticmethod + def _range_in_domain(transform_range, domain): + """Return whether a transform range is contained within a domain.""" + transform_range = np.asarray(transform_range) + domain = np.asarray(domain) + + if ( + transform_range.ndim != 2 + or domain.ndim != 2 + or transform_range.shape[1] != 2 + or domain.shape[1] != 2 + ): + return False + + try: + transform_range, domain = np.broadcast_arrays(transform_range, domain) + except ValueError: + return False + + lower_bounds_valid = np.all(domain[:, 0] <= transform_range[:, 0]) + upper_bounds_valid = np.all(transform_range[:, 1] <= domain[:, 1]) + return bool(lower_bounds_valid and upper_bounds_valid) + def _set_moments(self, mean, variance, standard_deviation, covariance): self._mean = self._read_only_array(mean) self._variance = self._read_only_array(variance) @@ -100,11 +123,11 @@ def _parse_sampler(self, sampler): sampler.d ) # take the dimension from the sub-sampler (composed transform) self.discrete_distrib = self.transform.discrete_distrib - if (self.domain != self.transform.range).any(): + if not self._range_in_domain(self.transform.range, self.domain): self.sub_compatibility_error = True if self.transform.sub_compatibility_error: raise ParameterError( - "The sub-transform domain must match the sub-sub-transform range." + "The sub-sub-transform range must be contained within the sub-transform domain." ) else: raise ParameterError( @@ -147,7 +170,7 @@ def _jacobian_transform_r(self, x, return_weights): jac = None if self.sub_compatibility_error: raise ParameterError( - "The transform domain must match the sub-transform range." + "The sub-transform range must be contained within the transform domain." ) if self.transform == self: # is \Psi_0 if return_weights: diff --git a/test/test_true_measures.py b/test/test_true_measures.py index ae58d9604..1c3109fe5 100644 --- a/test/test_true_measures.py +++ b/test/test_true_measures.py @@ -20,6 +20,7 @@ import unittest import warnings from qmcpy.true_measure.uniform_triangle import UniformTriangle, _UniformTriangleAdapter +from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure from qmcpy import SciPyWrapper @@ -42,6 +43,104 @@ def assert_sample_mean_and_covariance(measure): class TestTrueMeasure(unittest.TestCase): """General tests for TrueMeasures""" + def test_range_in_domain(self): + cases = [ + ("exact equality", [[0, 1]], [[0, 1]], True), + ("strict finite inclusion", [[0.25, 0.75]], [[0, 1]], True), + ("infinite domain", [[-5, 5]], [[-np.inf, np.inf]], True), + ("positive half-line", [[1, 3]], [[0, np.inf]], True), + ("lower-bound failure", [[-0.1, 0.75]], [[0, 1]], False), + ("upper-bound failure", [[0.25, 1.1]], [[0, 1]], False), + ( + "multidimensional box", + [[0.1, 0.8], [0.2, 0.9]], + [[0, 1], [0, 1]], + True, + ), + ( + "failure in one coordinate", + [[0.1, 0.8], [0.2, 1.1]], + [[0, 1], [0, 1]], + False, + ), + ( + "broadcast domain", + [[0.1, 0.8], [0.2, 0.9]], + [[0, 1]], + True, + ), + ( + "non-broadcastable rows", + [[0.1, 0.8], [0.2, 0.9]], + [[0, 1], [0, 1], [0, 1]], + False, + ), + ] + + for name, transform_range, domain, expected in cases: + with self.subTest(name=name): + self.assertIs( + AbstractTrueMeasure._range_in_domain(transform_range, domain), + expected, + ) + + def test_range_in_domain_rejects_invalid_bound_shapes(self): + invalid_cases = [ + ([0, 1], [[0, 1]]), + ([[0, 0.5, 1]], [[0, 1]]), + ([[0, 1]], [0, 1]), + ([[0, 1]], [[0, 0.5, 1]]), + ] + + for transform_range, domain in invalid_cases: + with self.subTest(transform_range=transform_range, domain=domain): + self.assertFalse( + AbstractTrueMeasure._range_in_domain(transform_range, domain) + ) + + def test_strict_range_in_domain_chain(self): + inner = Uniform( + DigitalNetB2(1, seed=7), lower_bound=0.25, upper_bound=0.75 + ) + outer = Kumaraswamy(inner) + + self.assertFalse(outer.sub_compatibility_error) + samples = outer.gen_samples(8) + self.assertEqual(samples.shape, (8, 1)) + self.assertTrue(np.isfinite(samples).all()) + + def test_multidimensional_range_in_domain_chain_broadcasts(self): + inner = Uniform( + DigitalNetB2(2, seed=7), + lower_bound=[0.1, 0.2], + upper_bound=[0.8, 0.9], + ) + outer = Kumaraswamy(inner) + + self.assertFalse(outer.sub_compatibility_error) + samples = outer.gen_samples(8) + self.assertEqual(samples.shape, (8, 2)) + self.assertTrue(np.isfinite(samples).all()) + + def test_out_of_domain_chain_preserves_deferred_errors(self): + inner = Uniform( + DigitalNetB2(1, seed=7), lower_bound=-0.1, upper_bound=0.75 + ) + incompatible = Kumaraswamy(inner) + + self.assertTrue(incompatible.sub_compatibility_error) + with self.assertRaisesRegex( + ParameterError, + "The sub-transform range must be contained within the transform domain.", + ): + incompatible.gen_samples(8) + + with self.assertRaisesRegex( + ParameterError, + "The sub-sub-transform range must be contained within the sub-transform domain.", + ): + Kumaraswamy(incompatible) + def test_abstract_methods(self): d = 2 tms = [ From 6e57fd828ed77265826b50933c25166347512378 Mon Sep 17 00:00:00 2001 From: Laasya-73 <77721581+Laasya-73@users.noreply.github.com> Date: Wed, 19 Aug 2026 17:24:29 -0500 Subject: [PATCH 2/6] Refine TrueMeasure domain inclusion demo --- demos/true_measure_domain_inclusion.ipynb | 2417 +++++---------------- 1 file changed, 568 insertions(+), 1849 deletions(-) diff --git a/demos/true_measure_domain_inclusion.ipynb b/demos/true_measure_domain_inclusion.ipynb index cb3540df0..c98f73425 100644 --- a/demos/true_measure_domain_inclusion.ipynb +++ b/demos/true_measure_domain_inclusion.ipynb @@ -2,1574 +2,143 @@ "cells": [ { "cell_type": "markdown", - "id": "c303c30a", + "id": "a4c44dd5", "metadata": {}, "source": [ "# Chaining `TrueMeasure` Transformations with Compatible Domains\n", "\n", - "This notebook demonstrates a generalization of the compatibility rule used when chaining `TrueMeasure` transformations in QMCPy.\n", + "## 1. Problem and proposed rule\n", "\n", - "Previously, consecutive transformations were considered compatible only when the range of the preceding transformation exactly matched the domain of the next transformation.\n", - "\n", - "This notebook shows why exact equality is unnecessarily restrictive and demonstrates the proposed range-in-domain condition for one-dimensional intervals and multidimensional axis-aligned boxes." - ] - }, - { - "cell_type": "markdown", - "id": "7b6b5d08", - "metadata": {}, - "source": [ - "## Motivation\n", - "\n", - "A chained transformation passes the output of one transformation into the next.\n", - "\n", - "Consider two consecutive transformations\n", - "\n", - "$$\n", - "T_{j-1}: D_{j-1} \\rightarrow R_{j-1}\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "T_j: D_j \\rightarrow R_j.\n", - "$$\n", - "\n", - "The output of $T_{j-1}$ becomes the input to $T_j$.\n", - "\n", - "Therefore, the important compatibility question is:\n", - "\n", - "> Can every value produced by $T_{j-1}$ be accepted by $T_j$?\n", - "\n", - "Previously, QMCPy effectively required\n", - "\n", - "$$\n", - "R_{j-1} = D_j.\n", - "$$\n", - "\n", - "However, exact equality is stronger than necessary.\n", - "\n", - "For the domain/range compatibility of two consecutive transformations, exact equality is not required. It is sufficient that every value produced by the preceding transformation lies inside the domain accepted by the next transformation:\n", - "\n", - "$$\n", - "R_{j-1} \\subseteq D_j.\n", - "$$\n", - "\n", - "This condition addresses whether the two transformations are compatible at their shared boundary. Other requirements of the individual transformations remain unchanged." - ] - }, - { - "cell_type": "markdown", - "id": "5a6535f6", - "metadata": {}, - "source": [ - "### Simple example\n", - "\n", - "Suppose the previous transformation produces values only in\n", - "\n", - "$$\n", - "R_{j-1} = [0.25, 0.75],\n", - "$$\n", - "\n", - "while the next transformation accepts every value in\n", - "\n", - "$$\n", - "D_j = [0,1].\n", - "$$\n", - "\n", - "The two sets are not equal:\n", - "\n", - "$$\n", - "[0.25,0.75] \\neq [0,1].\n", - "$$\n", - "\n", - "However,\n", - "\n", - "$$\n", - "[0.25,0.75] \\subseteq [0,1].\n", - "$$\n", - "\n", - "Every output of the previous transformation therefore lies within the input domain accepted by the next transformation.\n", - "\n", - "Rejecting this composition only because the two intervals are not identical is unnecessarily restrictive." - ] - }, - { - "cell_type": "markdown", - "id": "da58e3d8", - "metadata": {}, - "source": [ - "## Compatibility rule\n", - "\n", - "For a one-dimensional range\n", - "\n", - "$$\n", - "R = [r_L,r_U]\n", - "$$\n", - "\n", - "and domain\n", - "\n", - "$$\n", - "D = [d_L,d_U],\n", - "$$\n", - "\n", - "the range is contained within the domain when\n", - "\n", - "$$\n", - "d_L \\leq r_L\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "r_U \\leq d_U.\n", - "$$\n", - "\n", - "Both conditions must hold.\n", - "\n", - "For example,\n", - "\n", - "$$\n", - "[1,3] \\subseteq [0,4]\n", - "$$\n", - "\n", - "because\n", - "\n", - "$$\n", - "0 \\leq 1\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "3 \\leq 4.\n", - "$$" - ] - }, - { - "cell_type": "markdown", - "id": "93d58e11", - "metadata": {}, - "source": [ - "### Multidimensional case\n", - "\n", - "QMCPy also works with multidimensional domains and ranges.\n", - "\n", - "For an axis-aligned box,\n", - "\n", - "$$\n", - "R =\n", - "[r_1^L,r_1^U]\n", - "\\times\n", - "\\cdots\n", - "\\times\n", - "[r_d^L,r_d^U]\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "D =\n", - "[d_1^L,d_1^U]\n", - "\\times\n", - "\\cdots\n", - "\\times\n", - "[d_d^L,d_d^U].\n", - "$$\n", - "\n", - "Compatibility is checked independently in every coordinate.\n", - "\n", - "For every dimension $i$,\n", - "\n", - "$$\n", - "d_i^L \\leq r_i^L\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "r_i^U \\leq d_i^U.\n", - "$$\n", - "\n", - "If even one coordinate violates the condition, the chained transformation is incompatible." - ] - }, - { - "cell_type": "markdown", - "id": "fa1820ac", - "metadata": {}, - "source": [ - "### Scope of this change\n", - "\n", - "The initial compatibility rule is intentionally limited to support metadata represented by:\n", - "\n", - "- one-dimensional intervals;\n", - "- multidimensional axis-aligned boxes;\n", - "- finite or unbounded numerical endpoints.\n", - "\n", - "For example,\n", - "\n", - "$$\n", - "[1,3]\\times[2,5]\\times(-\\infty,\\infty)\n", - "$$\n", - "\n", - "can be checked coordinate by coordinate.\n", - "\n", - "This change does **not** attempt to represent disconnected supports such as\n", - "\n", - "$$\n", - "[0,5]\\cup[10,20],\n", - "$$\n", - "\n", - "or arbitrary nonrectangular regions.\n", - "\n", - "Those cases would require a richer representation of a measure's support and are outside the scope of this change." - ] - }, - { - "cell_type": "markdown", - "id": "174a45d0", - "metadata": {}, - "source": [ - "### Visualizing the multidimensional rule\n", - "\n", - "In two dimensions, compatibility means that the entire inner rectangle must lie inside the outer domain rectangle.\n", - "\n", - "The check is still performed coordinate by coordinate." - ] - }, - { - "cell_type": "code", - "execution_count": 613, - "id": "190451cb", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:30.394831Z", - "iopub.status.busy": "2026-08-18T03:05:30.394280Z", - "iopub.status.idle": "2026-08-18T03:05:31.354591Z", - "shell.execute_reply": "2026-08-18T03:05:31.352721Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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p8tTVooXL+5eK3Tg36233moffPCBTZkyxT777DN3/IsuuijT4+zZs8fOOOMMe/jhhzPcR11WqlSpYnmNYBQAELeWLVvm+nHmxUPHzinVQikA+fjjj619+/Z29NFH2z//+U/75JNPbN26dXb33Xdn2hyuicJfeukl9/9jjjnGLU855RS375lnnhnc74UXXrATTjjB1eIdf/zxNm7cuCNqVN966y2XB+3z+uuvR8yvgua///3vbp8mTZrYrFmzjthn8eLFdvbZZ7uASsGhat52794d3H7llVe6JugHH3zQatas6c5BNY8HDx60O+64wwUtRx11lE2cODHdcQcNGmTHHXecC54aNGhg9957b7qgObyZ3nudxx57zM1dqbyovGMRaKt80tLSbMKECa6G8ZJLLnG1nqNGjcr0eU899ZTLg/KfW08//bQr59Cayz179th5553nyiZaKSkp9uKLL7pz0HFVg6v3YN68efb1119n+LwrrrjChg4dah06dDC/+RqMfv7559a5c2fXxJGdviuqUj733HNdpF6hQgX363PmzJn5ll8AQP6qVq2a+5ufFw8dOydU66nvnn79+h1RE6Yaq8suu8wFiJoUPDsWLFjglgpk1fyq7zovcFKw8MADD9jPP//sgkAFKy+//HK65w8ePNh1D9A+nTp1OuL4mqVAtWQKnr/55htXg6sAMZSCIT23cuXKrmlWNWzKz4ABA9Lt9+mnn7paN31/K/gZNmyYXXDBBe55Ova///1vu/76623t2rXpaicVeCv4f/LJJ+3555+3J554ItMymTNnjv32229uqfPV873g3Qtg1Z8xWvPnz3dBucrCo/NesWKFbd++3fKDyq1x48YuCNyyZYvt27fPleH+/fvtzTffjPp4qk1VoB4aVOqHi34g6XwLAl+DUV38zZo1s7Fjx2Zrf138CkY//PBDV/hnnXWWC2a///77PM8rAABeLaMCTdVYRqJ0BTabN2/OVoF5o/dVA6hg1msWVaD3+OOPu0BStadaqjn22WefTff8W265JbhPpLvgKKhcvny5vfLKK+47V8GYAttQkyZNcv0Otc9JJ53katjGjBljr776aroaPOVNtYQKptRsraXuwnPXXXfZsccea0OGDHGB3pdffhl8zj333OP6VCp41He2+ohOnjw50zJRcKvXV1ClQO38889P169UPyQaNmxo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Gll966232sknn+wCVQWmmvcUAAAACTCavn379sH/p6amHtFXM9pm8AEDBrhHJJGm81Ht69dffx3VawAAAKCQDGDSqHkFjxpcUrZsWdeXNPQBAAAA5Fkwescdd7i5Pp955hk3OOiFF15wfUjr1Kljr7zySrSHAwAAQAKLupn+gw8+cEHnmWee6QYatWvXzho1amT16tWz119/3U1IDwAAAORJzajuDd+gQYNg/1CtyxlnnGGff/55tIcDAABAAos6GFUgunr1avf/448/3iZPnhysMa1UqVLscwgAAIBCK+pgVE3zutuSDB482MaOHWulSpVy0y2pPykAAIlI82/PmTPHzTrTrFkztwydkxtAjPqMKuj0dOjQwZYvX24LFy50/UY19ycAAIlIN4DReIpI0xICiGEwGk4Dl/QAAAAA8iUY1f3j9di0aVO6+8TLhAkTcnJIAAAAJKCog1HNKXrfffe5+8nXrl3bihQpkjc5AwAAQKEXdTA6fvx4e+mll+yKK67ImxwB/3/aMM3UsGrVKjt48KAVL1486lvNAoAfrr/+ejftYZUqVezZZ5/lTQBiHYzqXvRt27aN9mlAVHR3r+7du1NqAAoMdVvbunWrm+pw/fr1rvVQdyssWjTqiWuAhBL1J+Saa66xSZMm5U1uAAAooBSI1qhRwwWioqXSAMS4ZjQ1NdWee+45++STT9xUTiVKlEi3fdSoUdEeEgAAAAkq6mD0p59+subNm7v/L1myJN02BjMh1hYvXmwHDhxwP3qaNm1KAQMAkOjBqO4uAeSXf/7zn7Zu3TpLTk62tWvXUvAAABQy9KoGAABAfNeMXnTRRW46J02to/9n5t13341V3pDANm/e7AYCeFQ7qrTq1av7mi8AAOBDMFqxYsVgf1D9HwAAAMi3YHTixIkR/w8AAADkBn1GAQAAEN81o6ecckq2p21atGhRbvMEAACABJGtYLRbt27pJr0fN26cNWnSxNq0aePSvv76a1u6dKn169cv73IKAACAxAxGhw0blu52oDfddJPdf//9R+zz559/xj6HAAAAKLSi7jM6ZcoU69279xHpl19+ub3zzjuxyhcAAAASQNTBaOnSpe2rr746Il1ppUqVilW+AAAAkACivh3oLbfcYjfccIMbqNSqVSuX9s0339iECRPs3nvvzYs8AgAAoJCKOhgdPHiwNWjQwJ588kl77bXXXNoJJ5zg5h/t0aNHXuQRAIC4p7sUTp482UaMGGEpKSnuJjFKAxDDYPTgwYP24IMP2lVXXUXgCQBAiJIlS1r37t3dA0Ae9RktXry4PfLIIy4oBQAAAPJ9ANM555xjn332Wa5fGAAAAIi6z+g///lP12908eLF1qJFCytbtmy67V26dKFUAQAAkDfBqHeXpVGjRh2xTbcMPXToULSHBI5Qrlw5GzNmjP3888924MABK1GihEsDgHh39913244dO6xSpUr2wAMP+J0doPAFo4cPH86bnABh89n279+fMgFQ4Lz88su2bt06S05OJhgF8qLPKAAAONLmzZtdC6ECUdFSaQDyIBjVAKbOnTtbo0aN3EP9RL/44oucHAoAAAAJLOpgVBPdd+jQwcqUKWM33XSTe6hJVaPsJ02alDe5RMJav369rV271i0BAEDhE3WfUXXG1lyjt956azBNAakGNN1///126aWXxjqPSGCnnnpqsO+VglIAAJDgNaOrVq1yTfTh1FS/evXqWOULAAAACSDqYLRu3bo2e/bsI9I/+eQTtw2IhS1btlj16tVt69atlpSU5JZKAwAACd5Mf9ttt7lm+R9++MHatm3r0r766it76aWX7Mknn8yLPCIBBQKBI4JPpQEAgAQPRm+44QarVauWPf744zZ58mSXdsIJJ9hbb71lXbt2zYs8AgAAoJCKOhiVCy+80D0AAACAfA9GZeHChe5WjXLiiSfaKaeckquMAAAAIPFEHYxu2rTJLrnkEps7d667767oHrxnnXWWvfnmm27QCQAAAJAno+lvvPFG27Vrly1dutS2bdvmHkuWLLGdO3e6gU0AAABAntWMzpgxw03jpEFLniZNmtjYsWOtY8eO0R4OAAAACSzqmtHDhw9biRIljkhXmrYBAAAAeRaMnn322XbzzTfbX3/9FUzT7Rp1e1Ddnx4AAADIs2B0zJgxrn9o/fr1rWHDhu5xzDHHuLSnn3462sMBAFAolCtXzn1H1qlTx/3fWwKIcZ9R3fJz0aJFrt/o8uXLXZr6j3bo0CHaQwEAUGiULl3a+vfv7x4A8nie0SJFiti5557rHgAAAECeN9N/+umnbtS8muPDpaSkuInvv/jiixxnBAAAAIkn28Ho6NGj7dprr7UKFSocsa1ixYp2/fXX26hRo2KdPwAAABRi2W6m//HHH+3h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jjvO7a+pMqZPn+5DrgtXudarV8996MMf+mJC7so2HMFobK5ZmTdvnpvaTcGWpnl64IEH3DRayHm5HjhwIDB8+HAXgJYqVSpQt27dQL9+/QLbt2+nWEPMmTMn4t9Mryy1VNmGP6d58+bufdD1OnHiRMo0BmWr/2e2f6wV0T95W/cKAAAAREafUQAAAPiGYBQAAAC+IRgFAACAbwhGAQAA4BuCUQAAAPiGYBQAAAC+IRgFAACAbwhGAQAA4BuCUQCII8OHD7fmzZsH16+88krr1q2br3kCgLxEMAogoW3YsMFuvPFGa9CggZUsWdLq1q1rnTt3ttmzZ1s8ePLJJ+2ll16K6TF1vEqVKsXkWM8995ydeeaZVqFCBStSpIjt2LEjJscFkDiK+50BAPDL77//bqeffroLzB599FFr2rSpHThwwGbOnGn9+/e35cuX59lr63VKlCiR5X4VK1a0eLZ37177xz/+4R5DhgzxOzsACiBqRgEkrH79+rnavAULFti//vUvO+644+zEE0+0gQMH2tdffx3cb82aNda1a1crV66cqwHs0aOHbdy4Md2xnnnmGWvYsKElJSVZ48aN7dVXX023Xa+jfbp06WJly5a1Bx54wKU/9NBDVrNmTStfvrxdffXVlpqamu554c30qoW86aab7M4777QqVapYrVq1XNN+qFGjRrnAWq+jml6d5+7du922uXPnWt++fS0lJcXlSQ/v+fv377fbb7/dkpOT3XNbt27t9s/MLbfcYoMHD7bTTjstytIHgP8hGAWQkLZt22YzZsxwNaAKvMJ5zdiHDx92gaj2/+yzz2zWrFm2atUq69mzZ3DfqVOn2s0332y33XabLVmyxK6//noX8M2ZMyfdMRX0XXjhhbZ48WK76qqrbPLkyS7twQcftO+++85q165t48aNyzLvL7/8ssvzN998Y4888ojdd999Ll+eokWL2lNPPWVLly51+3766acueJW2bdva6NGjXVC9fv1691AAKgMGDLD58+fbm2++aT/99JN1797d1Xj++uuvuShpAMhCAAAS0DfffBPQn8B333030/0+/vjjQLFixQJr1qwJpi1dutQ9d8GCBW69bdu2gWuvvTbd87p37x4477zzguva/5Zbbkm3T5s2bQL9+vVLl9a6detAs2bNgut9+vQJdO3aNbjevn37wBlnnJHuOaeeempg0KBBGZ7DlClTAlWrVg2uT5w4MVCxYsV0+/zxxx/uPNetW5cu/ZxzzgkMGTIkkJU5c+a4c9y+fXuW+wJAKGpGASSk/8WHWfv5559dU7ceniZNmriaU23z9lHf01Ba97Z7WrZsecSx1RQeqk2bNlnm6eSTT063rhrVTZs2Bdc/+eQTO+ecc1xzu5r/r7jiCtu6davr35kR1dYeOnTIdVVQdwTvodrg3377Lcs8AUBOMYAJQEI69thjXX/JvBykFC5Sd4CcCB/4pPNQdwJvUNYFF1xgN9xwg+uXqn6lX375peuPmpaWZmXKlIl4TPUpLVasmC1cuNAtQykoBYC8Qs0ogISkIK1Tp042duxY27NnzxHbvSmKTjjhBPvzzz/dw7Ns2TK3XTWk3j5fffVVuudr3dueET1P/T5DhQ6cygkFkwpMH3/8cTeoSDWdf/31V7p9NMhKtaChTjnlFJemGtZGjRqle2iQFADkFYJRAAlLgagCsFatWtk777zjBuqo6VyDf7zm8g4dOriR6ZdddpktWrTIjbzv3bu3tW/fPtjsfscdd7i5OzVaXsfQaPZ33303ODAoIxr0NGHCBJs4caL98ssvNmzYMDfoKDcUPGraqKefftoNtNKo/vHjx6fbp379+q4mVHOpbtmyxTXfK2jVOerclPfVq1e7cx05cqRNnz4903laf/jhB1u5cmWwuV/rGvAFANmSrgcpACSYv/76K9C/f/9AvXr1AklJSYHk5ORAly5d3ICc0ME9SitbtmygfPnybnDShg0b0h1n3LhxgQYNGgRKlCgROO644wKvvPJKuu36czt16tQjXv+BBx4IVKtWLVCuXDk3WOnOO+/McgDTzTffnO4Y2q79PKNGjQrUrl07ULp06UCnTp1cXsIHF/373/92g5qUPmzYMJeWlpYWGDp0aKB+/fruPHSMCy+8MPDTTz9lWH56ro4R/tAgKQDIjiL6J3thKwAAABBbNNMDAADANwSjAAAA8A3BKAAAAHxDMAoAAADfEIwCAADANwSjAAAA8A3BKAAAAHxDMAoAAADfEIwCAADANwSjAAAA8A3BKAAAAHxDMAoAAADzy/8DiRI7zTm9l2oAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "from matplotlib.patches import Rectangle\n", - "\n", - "fig, ax = plt.subplots(figsize=(7, 7))\n", - "\n", - "# Outer domain: [0,1] x [0,1]\n", - "outer_domain = Rectangle(\n", - " (0, 0),\n", - " 1,\n", - " 1,\n", - " fill=False,\n", - " linewidth=3,\n", - " label=\"Outer domain: [0,1] × [0,1]\",\n", - ")\n", - "\n", - "# Valid range: [0.1,0.8] x [0.2,0.9]\n", - "valid_range = Rectangle(\n", - " (0.1, 0.2),\n", - " 0.7,\n", - " 0.7,\n", - " fill=False,\n", - " linewidth=3,\n", - " linestyle=\"--\",\n", - " label=\"Valid inner range\",\n", - ")\n", - "\n", - "# Invalid range: [0.1,0.8] x [0.2,1.1]\n", - "invalid_range = Rectangle(\n", - " (0.1, 0.2),\n", - " 0.7,\n", - " 0.9,\n", - " fill=False,\n", - " linewidth=2,\n", - " linestyle=\":\",\n", - " label=\"Invalid inner range\",\n", - ")\n", - "\n", - "ax.add_patch(outer_domain)\n", - "ax.add_patch(valid_range)\n", - "ax.add_patch(invalid_range)\n", - "\n", - "ax.set_xlim(-0.15, 1.25)\n", - "ax.set_ylim(-0.15, 1.25)\n", - "\n", - "ax.set_xlabel(\"Coordinate 1\")\n", - "ax.set_ylabel(\"Coordinate 2\")\n", - "ax.set_title(\"Coordinate-wise Domain Compatibility\")\n", - "\n", - "ax.axhline(0, linewidth=0.8)\n", - "ax.axvline(0, linewidth=0.8)\n", - "\n", - "ax.legend()\n", - "ax.set_aspect(\"equal\")\n", - "\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "003ec6b8", - "metadata": {}, - "source": [ - "The dashed rectangle is compatible because both coordinate intervals are contained within the unit-domain intervals:\n", - "\n", - "$$\n", - "[0.1,0.8]\\subseteq[0,1]\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "[0.2,0.9]\\subseteq[0,1].\n", - "$$\n", - "\n", - "The dotted rectangle is incompatible because its second coordinate extends to $1.1$:\n", - "\n", - "$$\n", - "[0.2,1.1]\\nsubseteq[0,1].\n", - "$$\n", - "\n", - "This illustrates why multidimensional compatibility can be checked independently along each coordinate for axis-aligned boxes." - ] - }, - { - "cell_type": "markdown", - "id": "a272eee8", - "metadata": {}, - "source": [ - "### Unbounded intervals and endpoint representation\n", - "\n", - "Some QMCPy measures have unbounded domains or ranges, such as\n", - "\n", - "$$\n", - "(-\\infty,\\infty)\n", - "$$\n", - "\n", - "or\n", - "\n", - "$$\n", - "[0,\\infty).\n", - "$$\n", - "\n", - "Infinity is not an element of these sets. In the implementation, `-np.inf` and `np.inf` are numerical representations of unbounded lower and upper endpoints.\n", - "\n", - "The current `TrueMeasure` metadata records lower and upper bounds, but it does not separately record whether a finite endpoint is open or closed.\n", - "\n", - "Because the current metadata stores only numerical lower and upper bounds, the implemented compatibility test is most precisely understood as comparing the stored interval envelopes. When discussing endpoint behavior mathematically, this is closely related to comparing closures of the represented supports:\n", - "\n", - "$$\n", - "\\overline{R}_{j-1} \\subseteq \\overline{D}_j.\n", - "$$\n", - "\n", - "For example,\n", - "\n", - "$$\n", - "\\overline{(0,1)}=[0,1].\n", - "$$\n", - "\n", - "At the numerical level, the same coordinate-wise comparisons are used:\n", - "\n", - "$$\n", - "d_L \\leq r_L\n", - "\\qquad\\text{and}\\qquad\n", - "r_U \\leq d_U.\n", - "$$\n", - "\n", - "For example, a stored range with bounds $[-5,5]$ is compatible with an unbounded real-valued domain because\n", - "\n", - "$$\n", - "-\\infty \\leq -5\n", - "\\qquad\\text{and}\\qquad\n", - "5 \\leq \\infty.\n", - "$$\n", - "\n", - "This initial change does not attempt to distinguish cases such as $(0,1)$ and $[0,1]$ when their stored numerical bounds are identical. Explicit open/closed endpoint metadata would require a richer support representation and can be considered separately." - ] - }, - { - "cell_type": "code", - "execution_count": 614, - "id": "4c2905b1", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:31.384153Z", - "iopub.status.busy": "2026-08-18T03:05:31.383506Z", - "iopub.status.idle": "2026-08-18T03:05:33.157320Z", - "shell.execute_reply": "2026-08-18T03:05:33.152822Z" - } - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "from qmcpy import DigitalNetB2, Kumaraswamy, Uniform\n", - "from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure\n", - "from qmcpy.util import ParameterError" - ] - }, - { - "cell_type": "markdown", - "id": "4d729766", - "metadata": {}, - "source": [ - "## Previous behavior: exact equality\n", - "\n", - "Previously, chained `TrueMeasure` compatibility was determined using an exact comparison between the next transformation's domain and the preceding transformation's range.\n", - "\n", - "Conceptually, the check was equivalent to:" - ] - }, - { - "cell_type": "code", - "execution_count": 615, - "id": "83f256a3", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.167238Z", - "iopub.status.busy": "2026-08-18T03:05:33.166058Z", - "iopub.status.idle": "2026-08-18T03:05:33.179525Z", - "shell.execute_reply": "2026-08-18T03:05:33.175481Z" - } - }, - "outputs": [], - "source": [ - "def previous_compatibility_check(transform_range, domain):\n", - " \"\"\"Reproduce the previous exact-equality compatibility rule.\"\"\"\n", - " return not (np.asarray(domain) != np.asarray(transform_range)).any()" - ] - }, - { - "cell_type": "code", - "execution_count": 616, - "id": "ffb5f7ad", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.188006Z", - "iopub.status.busy": "2026-08-18T03:05:33.187242Z", - "iopub.status.idle": "2026-08-18T03:05:33.206781Z", - "shell.execute_reply": "2026-08-18T03:05:33.201198Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 616, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "transform_range = np.array([[0.25, 0.75]])\n", - "domain = np.array([[0.0, 1.0]])\n", - "\n", - "previous_compatibility_check(transform_range, domain)" - ] - }, - { - "cell_type": "markdown", - "id": "f34229e8", - "metadata": {}, - "source": [ - "The previous rule rejects this pair because\n", - "\n", - "$$\n", - "[0.25,0.75] \\neq [0,1].\n", - "$$\n", - "\n", - "But this does not mean the transformation is invalid. Every value in the preceding range is still inside the next domain." - ] - }, - { - "cell_type": "code", - "execution_count": 617, - "id": "e4502c55", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.215665Z", - "iopub.status.busy": "2026-08-18T03:05:33.214936Z", - "iopub.status.idle": "2026-08-18T03:05:33.229160Z", - "shell.execute_reply": "2026-08-18T03:05:33.224421Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 617, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "AbstractTrueMeasure._range_in_domain(\n", - " transform_range,\n", - " domain,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "c18c7454", - "metadata": {}, - "source": [ - "The new compatibility rule accepts the same pair because\n", - "\n", - "$$\n", - "[0.25,0.75] \\subseteq [0,1].\n", - "$$\n", - "\n", - "This captures the actual requirement for composition: every value produced by the previous transformation can be passed safely to the next transformation." - ] - }, - { - "cell_type": "markdown", - "id": "35f6ae8f", - "metadata": {}, - "source": [ - "## What changed in QMCPy?\n", - "\n", - "The previous `TrueMeasure` composition logic required the domain of the current transformation to exactly match the range of the preceding transformation.\n", - "\n", - "The previous compatibility check was:\n", - "\n", - "```python\n", - "if (self.domain != self.transform.range).any():\n", - " self.sub_compatibility_error = True\n", - "```\n", - "\n", - "For two consecutive transformations,\n", - "\n", - "$$\n", - "T_{j-1}: D_{j-1} \\rightarrow R_{j-1}\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "T_j: D_j \\rightarrow R_j,\n", - "$$\n", - "\n", - "this effectively required\n", - "\n", - "$$\n", - "R_{j-1} = D_j.\n", - "$$\n", - "\n", - "This rejects cases where the preceding range is smaller than, but still completely contained within, the next domain.\n", - "\n", - "For example,\n", - "\n", - "$$\n", - "R_{j-1}=[0.25,0.75]\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "D_j=[0,1]\n", - "$$\n", - "\n", - "were considered incompatible because\n", - "\n", - "$$\n", - "[0.25,0.75] \\neq [0,1].\n", - "$$\n", - "\n", - "However, every value produced by the preceding transformation is a valid input to the next transformation because\n", - "\n", - "$$\n", - "[0.25,0.75] \\subseteq [0,1].\n", - "$$\n", - "\n", - "### Updated compatibility check\n", - "\n", - "The implementation now checks whether the preceding transformation's range is contained within the current transformation's domain:\n", - "\n", - "```python\n", - "if not self._range_in_domain(self.transform.range, self.domain):\n", - " self.sub_compatibility_error = True\n", - "```\n", - "\n", - "For one coordinate, let\n", - "\n", - "$$\n", - "R_{j-1}=[r_L,r_U]\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "D_j=[d_L,d_U].\n", - "$$\n", - "\n", - "The range is compatible with the next domain when\n", - "\n", - "$$\n", - "d_L \\leq r_L\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "r_U \\leq d_U.\n", - "$$\n", - "\n", - "For multiple dimensions, the same comparison is performed independently for every coordinate $i$:\n", - "\n", - "$$\n", - "d_i^L \\leq r_i^L\n", - "\\qquad\\text{and}\\qquad\n", - "r_i^U \\leq d_i^U.\n", - "$$\n", - "\n", - "Therefore, the compatibility rule changes from\n", - "\n", - "$$\n", - "\\boxed{R_{j-1}=D_j}\n", - "$$\n", - "\n", - "to\n", - "\n", - "$$\n", - "\\boxed{R_{j-1}\\subseteq D_j}.\n", - "$$\n", - "\n", - "Exact equality is still accepted because it is a special case of containment.\n", - "\n", - "The implementation also preserves QMCPy's existing broadcasting behavior between a common `(1, 2)` domain and a coordinate-specific `(d, 2)` range.\n", - "\n", - "For example, a common domain\n", - "\n", - "```text\n", - "[[0, 1]]\n", - "```\n", - "\n", - "can be compared against a two-dimensional range\n", - "\n", - "```text\n", - "[[0.1, 0.8],\n", - " [0.2, 0.9]]\n", - "```\n", - "\n", - "because both coordinate intervals satisfy\n", - "\n", - "$$\n", - "[0.1,0.8]\\subseteq[0,1]\n", - "$$\n", - "\n", - "and\n", - "\n", - "$$\n", - "[0.2,0.9]\\subseteq[0,1].\n", - "$$\n", - "\n", - "This change only generalizes **domain-range compatibility**. It does not change the individual transformations themselves, the direct unit-cube requirement for a `StdUniform` discrete distribution, or the separate importance-sampling compatibility logic." - ] - }, - { - "cell_type": "code", - "execution_count": 618, - "id": "f5062f63", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.234406Z", - "iopub.status.busy": "2026-08-18T03:05:33.234037Z", - "iopub.status.idle": "2026-08-18T03:05:33.261633Z", - "shell.execute_reply": "2026-08-18T03:05:33.260143Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
CasePrevious equality ruleNew inclusion rule
0Exact equalityTrueTrue
1Strict inclusionFalseTrue
2Infinite domainFalseTrue
3Positive half-lineFalseTrue
4Lower-bound failureFalseFalse
5Upper-bound failureFalseFalse
\n", - "
" - ], - "text/plain": [ - " Case Previous equality rule New inclusion rule\n", - "0 Exact equality True True\n", - "1 Strict inclusion False True\n", - "2 Infinite domain False True\n", - "3 Positive half-line False True\n", - "4 Lower-bound failure False False\n", - "5 Upper-bound failure False False" - ] - }, - "execution_count": 618, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "examples = [\n", - " (\"Exact equality\", [[0, 1]], [[0, 1]]),\n", - " (\"Strict inclusion\", [[0.25, 0.75]], [[0, 1]]),\n", - " (\"Infinite domain\", [[-5, 5]], [[-np.inf, np.inf]]),\n", - " (\"Positive half-line\", [[1, 3]], [[0, np.inf]]),\n", - " (\"Lower-bound failure\", [[-0.1, 0.75]], [[0, 1]]),\n", - " (\"Upper-bound failure\", [[0.25, 1.1]], [[0, 1]]),\n", - "]\n", - "\n", - "rows = []\n", - "\n", - "for name, transform_range, domain in examples:\n", - " rows.append(\n", - " {\n", - " \"Case\": name,\n", - " \"Previous equality rule\": previous_compatibility_check(\n", - " transform_range,\n", - " domain,\n", - " ),\n", - " \"New inclusion rule\": AbstractTrueMeasure._range_in_domain(\n", - " transform_range,\n", - " domain,\n", - " ),\n", - " }\n", - " )\n", - "\n", - "pd.DataFrame(rows)" - ] - }, - { - "cell_type": "markdown", - "id": "b867d665", - "metadata": {}, - "source": [ - "The new rule does not make incompatible transformations valid.\n", - "\n", - "It only distinguishes between:\n", - "\n", - "- a range that is different from, but safely contained within, the next domain; and\n", - "- a range that actually extends outside the next domain." - ] - }, - { - "cell_type": "markdown", - "id": "9c6c54db", - "metadata": {}, - "source": [ - "## A real chained `TrueMeasure` example\n", - "\n", - "Consider an inner `Uniform` transformation whose output is restricted to\n", - "\n", - "$$\n", - "[0.25,0.75].\n", - "$$\n", - "\n", - "A `Kumaraswamy` transformation accepts inputs from\n", - "\n", - "$$\n", - "[0,1].\n", - "$$\n", - "\n", - "Therefore,\n", - "\n", - "$$\n", - "[0.25,0.75] \\subseteq [0,1].\n", - "$$\n", - "\n", - "Under the previous exact-equality rule, this chain was marked incompatible.\n", - "\n", - "Under the new containment rule, the two transformations are domain-compatible and the chain can be evaluated successfully." - ] - }, - { - "cell_type": "code", - "execution_count": 619, - "id": "0cc5f4ca", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.266076Z", - "iopub.status.busy": "2026-08-18T03:05:33.265704Z", - "iopub.status.idle": "2026-08-18T03:05:33.289879Z", - "shell.execute_reply": "2026-08-18T03:05:33.285086Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inner range:\n", - "[[0.25 0.75]]\n", - "\n", - "Outer domain:\n", - "[[0 1]]\n", - "\n", - "Range contained in domain: True\n", - "\n", - "Compatibility error:\n", - "False\n" - ] - } - ], - "source": [ - "inner = Uniform(\n", - " DigitalNetB2(1, seed=7),\n", - " lower_bound=0.25,\n", - " upper_bound=0.75,\n", - ")\n", - "\n", - "outer = Kumaraswamy(inner)\n", - "\n", - "print(\"Inner range:\")\n", - "print(inner.range)\n", - "\n", - "print(\"\\nOuter domain:\")\n", - "print(outer.domain)\n", - "\n", - "print(\n", - " \"\\nRange contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(\n", - " inner.range,\n", - " outer.domain,\n", - " ),\n", - ")\n", - "\n", - "print(\"\\nCompatibility error:\")\n", - "print(outer.sub_compatibility_error)" - ] - }, - { - "cell_type": "code", - "execution_count": 620, - "id": "667b1394", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.299853Z", - "iopub.status.busy": "2026-08-18T03:05:33.298299Z", - "iopub.status.idle": "2026-08-18T03:05:33.320951Z", - "shell.execute_reply": "2026-08-18T03:05:33.315555Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[0.49764069],\n", - " [0.6423285 ],\n", - " [0.40482463],\n", - " [0.55578408],\n", - " [0.53096826],\n", - " [0.67279285],\n", - " [0.44112426],\n", - " [0.58532942]])" - ] - }, - "execution_count": 620, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "samples = outer.gen_samples(8)\n", - "\n", - "samples" - ] - }, - { - "cell_type": "code", - "execution_count": 621, - "id": "9c657499", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.332388Z", - "iopub.status.busy": "2026-08-18T03:05:33.331269Z", - "iopub.status.idle": "2026-08-18T03:05:33.345110Z", - "shell.execute_reply": "2026-08-18T03:05:33.342928Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sample shape: (8, 1)\n", - "All samples finite: True\n" - ] - } - ], - "source": [ - "print(\"Sample shape:\", samples.shape)\n", - "print(\"All samples finite:\", np.isfinite(samples).all())" - ] - }, - { - "cell_type": "markdown", - "id": "e049c5b4", - "metadata": {}, - "source": [ - "The chain now executes successfully because the output of the inner transformation always lies inside the domain of the outer transformation.\n", - "\n", - "The important change is not that the two intervals became equal. They remain different.\n", - "\n", - "The change is that QMCPy now recognizes their domain-compatible containment relationship." - ] - }, - { - "cell_type": "markdown", - "id": "5dbb3ffc", - "metadata": {}, - "source": [ - "## Multidimensional composition\n", - "\n", - "Now consider an inner transformation with two coordinate ranges:\n", - "\n", - "$$\n", - "[0.1,0.8] \\times [0.2,0.9].\n", - "$$\n", - "\n", - "The outer Kumaraswamy transformation accepts the unit interval in each coordinate:\n", - "\n", - "$$\n", - "[0,1] \\times [0,1].\n", - "$$\n", - "\n", - "Coordinate 1 satisfies\n", - "\n", - "$$\n", - "[0.1,0.8] \\subseteq [0,1],\n", - "$$\n", - "\n", - "and coordinate 2 satisfies\n", - "\n", - "$$\n", - "[0.2,0.9] \\subseteq [0,1].\n", - "$$\n", - "\n", - "Therefore the entire box is compatible." - ] - }, - { - "cell_type": "code", - "execution_count": 622, - "id": "8cb4394c", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.350048Z", - "iopub.status.busy": "2026-08-18T03:05:33.349612Z", - "iopub.status.idle": "2026-08-18T03:05:33.363622Z", - "shell.execute_reply": "2026-08-18T03:05:33.361703Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inner range:\n", - "[[0.1 0.8]\n", - " [0.2 0.9]]\n", - "\n", - "Outer domain:\n", - "[[0 1]]\n", - "\n", - "Range contained in domain: True\n", - "\n", - "Compatibility error:\n", - "False\n" - ] - } - ], - "source": [ - "inner_2d = Uniform(\n", - " DigitalNetB2(2, seed=7),\n", - " lower_bound=[0.1, 0.2],\n", - " upper_bound=[0.8, 0.9],\n", - ")\n", - "\n", - "outer_2d = Kumaraswamy(inner_2d)\n", - "\n", - "print(\"Inner range:\")\n", - "print(inner_2d.range)\n", - "\n", - "print(\"\\nOuter domain:\")\n", - "print(outer_2d.domain)\n", - "\n", - "print(\n", - " \"\\nRange contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(\n", - " inner_2d.range,\n", - " outer_2d.domain,\n", - " ),\n", - ")\n", - "\n", - "print(\"\\nCompatibility error:\")\n", - "print(outer_2d.sub_compatibility_error)" - ] - }, - { - "cell_type": "code", - "execution_count": 623, - "id": "a2f42b67", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.371293Z", - "iopub.status.busy": "2026-08-18T03:05:33.369800Z", - "iopub.status.idle": "2026-08-18T03:05:33.384262Z", - "shell.execute_reply": "2026-08-18T03:05:33.380731Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0.60960507 0.77497487]\n", - " [0.3371496 0.54168863]\n", - " [0.7365757 0.34514116]\n", - " [0.47524005 0.60047814]\n", - " [0.53970404 0.47173912]\n", - " [0.22682022 0.69013017]\n", - " [0.66124946 0.64063827]\n", - " [0.39411447 0.40037581]]\n", - "\n", - "Shape: (8, 2)\n" - ] - } - ], - "source": [ - "samples_2d = outer_2d.gen_samples(8)\n", - "\n", - "print(samples_2d)\n", - "print(\"\\nShape:\", samples_2d.shape)" - ] - }, - { - "cell_type": "markdown", - "id": "bad34b5a", - "metadata": {}, - "source": [ - "This example also demonstrates an important QMCPy representation detail.\n", - "\n", - "The inner `Uniform` stores one interval for each coordinate, while the outer `Kumaraswamy` stores a common unit-domain interval.\n", - "\n", - "The compatibility check therefore preserves NumPy broadcasting between `(d,2)` and `(1,2)` representations." - ] - }, - { - "cell_type": "markdown", - "id": "c2d70373", - "metadata": {}, - "source": [ - "## An actually incompatible chain\n", - "\n", - "Containment should not permit ranges that extend outside the next transformation's domain.\n", - "\n", - "Suppose the inner range is\n", - "\n", - "$$\n", - "[-0.1,0.75]\n", - "$$\n", - "\n", - "while the outer domain is\n", - "\n", - "$$\n", - "[0,1].\n", - "$$\n", - "\n", - "Because\n", - "\n", - "$$\n", - "-0.1 < 0,\n", - "$$\n", - "\n", - "the range is not contained within the domain." - ] - }, - { - "cell_type": "code", - "execution_count": 624, - "id": "14aa4bca", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.392340Z", - "iopub.status.busy": "2026-08-18T03:05:33.391774Z", - "iopub.status.idle": "2026-08-18T03:05:33.402921Z", - "shell.execute_reply": "2026-08-18T03:05:33.400443Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Range contained in domain: False\n", - "Compatibility error: True\n" - ] - } - ], - "source": [ - "invalid_inner = Uniform(\n", - " DigitalNetB2(1, seed=7),\n", - " lower_bound=-0.1,\n", - " upper_bound=0.75,\n", - ")\n", - "\n", - "invalid_outer = Kumaraswamy(invalid_inner)\n", - "\n", - "print(\n", - " \"Range contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(\n", - " invalid_inner.range,\n", - " invalid_outer.domain,\n", - " ),\n", - ")\n", - "print(\"Compatibility error:\", invalid_outer.sub_compatibility_error)" - ] - }, - { - "cell_type": "code", - "execution_count": 625, - "id": "ab92fe35", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.410438Z", - "iopub.status.busy": "2026-08-18T03:05:33.410120Z", - "iopub.status.idle": "2026-08-18T03:05:33.421157Z", - "shell.execute_reply": "2026-08-18T03:05:33.416482Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ParameterError\n", - "The sub-transform range must be contained within the transform domain.\n" - ] - } - ], - "source": [ - "try:\n", - " invalid_outer.gen_samples(8)\n", - "except ParameterError as error:\n", - " print(type(error).__name__)\n", - " print(error)" - ] - }, - { - "cell_type": "markdown", - "id": "14da55da", - "metadata": {}, - "source": [ - "The generalized rule does not remove compatibility checking.\n", - "\n", - "It allows strict inclusion, but still rejects transformations whose preceding range contains values outside the next domain." - ] - }, - { - "cell_type": "markdown", - "id": "aeac0215", - "metadata": {}, - "source": [ - "## Visualizing range-in-domain compatibility\n", - "\n", - "The compatibility condition can also be seen geometrically.\n", - "\n", - "The outer transformation accepts values in the domain $[0,1]$.\n", - "\n", - "- The range $[0.25,0.75]$ lies completely inside the domain, so it is compatible.\n", - "- The range $[-0.1,0.75]$ extends outside the lower boundary of the domain, so it is incompatible." - ] - }, - { - "cell_type": "code", - "execution_count": 626, - "id": "69c0b932", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.428505Z", - "iopub.status.busy": "2026-08-18T03:05:33.428164Z", - "iopub.status.idle": "2026-08-18T03:05:33.558209Z", - "shell.execute_reply": "2026-08-18T03:05:33.557423Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS5xJREFUeJzt3Qd4FNX6x/E3JPQqSpFmQUCQKiqCekFEQbGg3gs27IINBfVaUbA3VCxYUSx/FNQrqCACKiiCYgMEpRfpvQUCpO3/+R3v7N2EJOwkmbT9fp5nHXe2zc6E5Lznfc85caFQKGQAAAAAACDflcr/twQAAAAAAATdAAAAAAAEiEw3AAAAAAABIegGAAAAACAgBN0AAAAAAASEoBsAAAAAgIAQdAMAAAAAEBCCbgAAAAAAAkLQDQAAAABAQAi6AQDF2uGHH25XXnllYR9GkTN48GCLi4sr7MMoUVasWOHO6dtvvx3ep5+9SpUqRfV6vVbXxaP30T69r6dTp07uBgAoOQi6AaAE8hrz3i0hIcHq1q3rAoQ1a9YU9uEVi0DeO3elSpWyatWqWYsWLaxPnz42c+ZMi2U7d+60Bx980Fq1auWCzfLly1vz5s3trrvusrVr11pJ8P7779vQoUOtKNA5VaA+e/bswj4UAEAuJeT2hQCAou+hhx6yI444wvbu3Ws//vijC8a///57mzdvnpUrV85KgoULF7rAOL+1bt3abr/9dvf/iYmJNn/+fPvoo4/sjTfesAEDBtizzz5rRdnAgQPt7rvvztf3XLZsmXXp0sVWrlxp//rXv1wnRJkyZez333+3N99808aMGWOLFi2ykhB0699I//79M+w/7LDDbM+ePVa6dOlcva9eqw6wnEyaNGm/oFudHOoI0s8kAKD4IegGgBLszDPPtOOOO879/7XXXmuHHHKIPfnkk/bZZ59Zz549rSQoW7ZsIO+ryoDLLrsswz6du0suucSee+45a9Sokd1www1WVCm4O1CA50dqaqpdcMEFtmHDBps6daqdfPLJGR5/9NFH3fkpyVT5kJfOqmheq04MAEDJQnk5AMSQU045xW2XLl0a3pecnGwPPPCAtW3b1qpWrWoVK1Z0z5syZUqW41mHDBlir7/+ujVs2NAFvMcff7z9/PPP+32WssLNmjVzgYbKj5UFVXm7MnaR0tPTXSnvMccc455bq1Yt69u3r23bti1XY7q90vrp06fbbbfdZjVq1HDf6fzzz7dNmzZZXqiU+r333rPq1au7IDMUCoUf2717t8uM169f352XJk2auHMV+RzRsd18883h86P3bN++vc2dO9c9/tprr9lRRx3lzoXG9kaO95Vp06a5LHODBg3c5+jzlHlXFvVAY7q9zx47dqy7Jnq9zvuXX355wO/+n//8x+bMmWP33XfffgG3VKlSxZ2TSPqO+rnSd1SHjzoxMg9v8MZEK3t+9tlnu/9Xh8ewYcPc4zovnTt3dtdQmWZloSN51/u7775zPzcHH3ywO5bLL798v5+hTz/91Lp372516tRx310/ww8//LClpaWFn6NzPn78ePvrr7/CQwy8n9msxnRHVgF07drVHafeX1UmWV37yDHdWYkc063ODf37kquuuip8PPr8QYMGuYx7Vj/TqkDQkAhVuAAACh9BNwDEEC+AO+iggzKM0R0+fLhr6CtTqaBADXkFEFmNI1XQ8/TTT7sA55FHHnHvqQxoSkpK+DkKWnr16uWCgscff9w9fs0119ivv/663/vpff7973/bSSedZM8//7wLLkaOHOk+P/I9/erXr58LEhWcKCP9+eefu4AzrxQUKoBX8Pjnn3+6fQquzj33XJcB79atmys9V9Ct76XAPzMFzgrQr7jiCne+VbqugFOB5gsvvGA33nije+0PP/xgV1999X6BbFJSkvtOL774ojtP2irIjIaGF+j9L7roInvqqadcYHbhhRfali1bcnydqiOkd+/eUX2OAkNVU8THx7ufgeuuu84++eQTF7Bv3749w3MV9KoqQx0IOiYFubpWeg+dT1Vr6GezcuXK7nsuX758v8/T83UedT71HP0M9ejRI0Pgq/fT9dM10c+aOgTU4RRZhq9OBZVxq5NAHSy6HWh8t45fx6kOIx2/3lc/d7rlRdOmTV3w7gXS3vH84x//cNdB1QejR4/O8Bp1on388cfumpaUISQAUOyFAAAlzogRIxRphL766qvQpk2bQqtWrQp9/PHHoRo1aoTKli3r7ntSU1ND+/bty/D6bdu2hWrVqhW6+uqrw/uWL1/u3vPggw8Obd26Nbz/008/dfs///zz8L4WLVqE6tWrF0pMTAzvmzp1qnveYYcdFt43bdo0t2/kyJEZPv/LL7/Mcn9W9H5XXHHFft+9S5cuofT09PD+AQMG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91i7ke2s1but3Fb3tb84/2HPyuZd++yVqUvdFgCAWP5bfeWVVxZowJeVDh062Lp166xq1aoWixYuXOgCzJzo+j7wwAN26KGHWvny5a1Lly62ePHiHF/z3Xff2TnnnGN16tRxgevYsWNz1Q7aunWrXXrppValShXX8XHNNdfYrl27DtipktXto48+Cj8vq8dHjRoVfrxXr17u56J9+/ZRHSeA4FBenkcp6Sk2eMZg+2zpZxYfF29poTRL21fTEveZjZv/q306/yc7tf6pdlPrmyyhVMk43X9t2R3elkmg3wYAULSlpqfasNnDbMqqKRZv8ZZmlSy+bJIlpSbZhOUTbNyycXZuw3NtcIfBVrpUaStuypQpY7Vr1873901JSbHSpYv++ahZs+YBs/hPPfWUvfDCC/bOO+/YEUccYffff7917drV/vzzTytXrlyWr9m9e7e1atXKrr76arvgggtyfXwKuBX8Tp482Z3Tq666yvr06WPvv/9+ls+vX7++e36k119/3Z5++mk788wzM+wfMWKEdevWLXw/8jyoc0E3/XwAKFwlIwosJOo1VcD9+dLP3X0F3JK07LYMzxu/zGz8tzOspLnp/VmFfQgAAESpzX9vf6vc9O4Mf7u9v+WPnPSIyxjmVqdOnaxly5YukBs+fLgLeK6//nobPHiwe/ySSy6xtLQ0Gz16dPg1CsSUgX322Wft8ssvty+//NIeeeQRmzdvnsXHx7tM5fPPP28NGzbMtsz61FNPtW3btoWDLmV+ldndvHmzCy5PPvnkHI9b2VUFo8qUvvzyyzZz5kx79dVXXab35ptvdllfvb+O4d5777WLL7446u8sCxYssGuvvdZ++eUXO/LII10AfPrpp9uYMWPClQKrVq2y22+/3SZNmmSlSpWyU045xX3vww8/3PLaXhs6dKgNHDjQzjvvPLfv3XfftVq1arns9UUXXZTl6xTgZg5y/Zo/f767nj///LMdd9xxbt+LL75oZ511lg0ZMsRl0TPTNc/ciaLz1LNnT6tUqVKG/breQXS4AMhfpCnz4PfNv7sMd8hKVvk4AACxRn/L9Td97ua5eX4vZVMrVqzoAldlWB966CGX5fSynp9//nmG8uKJEydaUlKSnX/++eEM62233eYC1K+//toFoHosPT09qs/X56qEWcGyxn0rIFcQH427777bbr31VhcsKljf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E5o5c2bo+++/DzVq1Ch08cUXhx9fvXp1qEmTJu5x2bFjh5vxukWLFqElS5aE1q1bF75p9l0UnFGjRoXKli0bevvtt91M9H369AlVq1YttH79evd47969Q3fffXf4+dOnTw8lJCSEhgwZEpo/f76bGbB06dKhuXPnctmK4fV84okn3KoBH3/8cYZ/h4mJiYX4LZCba5kZs5cX7+u5cuVKt5LAzTffHFq4cGFo3LhxoZo1a4YeeeSRQvwWyM211N9JXcsPPvggtGzZstCkSZNCDRs2dKuBoPDp792sWbPcTU3lZ5991v3/X3/95R7XtdQ19egaVqhQIfTvf//btYOGDRsWio+PD3355ZeF+C2Qm2s5cuRI16bVNYxsA23fvp0TWgyvZ2aFOXt5YEH3li1bXJBdqVKlUJUqVUJXXXVVhkb78uXL3cmaMmWKu6+t7md103NRsF588cVQgwYNXPClpVB+/PHH8GMdO3Z0jffMy7s1btzYPV/LZowfP55LVkyv52GHHZblv0P9okLx+7cZiaC7+F/PGTNmuA5qBXhaPuzRRx+lY7oYXksthTp48GAXaJcrVy5Uv3790I033hjatm1bIR09ImXXJvWuoba6pplf07p1a3f99W9zxIgRnNRieC31/zk9H8Xv32ZRCbrj9J+Cza0DAAAAABAbmKkDAAAAAICAEHQDAAAAABAQgm4AAAAAAAJC0A0AAAAAQEAIugEAAAAACAhBNwAAAAAAASHoBgAAAAAgIATdAAAAAAAEhKAbAIASolOnTta/f//CPgwAABCBoBsAgCLgnHPOsW7dumX52LRp0ywuLs5+//33Aj8uAACQNwTdAAAUAddcc41NnjzZVq9evd9jI0aMsOOOO85atmxZKMcGAAByj6AbAIAi4Oyzz7YaNWrY22+/nWH/rl277KOPPrIePXrYxRdfbHXr1rUKFSpYixYt7IMPPsjxPZUdHzt2bIZ91apVy/AZq1atsp49e7r91atXt/POO89WrFiRz98OAIDYRdANAEARkJCQYJdffrkLiEOhUHi/Au60tDS77LLLrG3btjZ+/HibN2+e9enTx3r37m0//fRTrj8zJSXFunbtapUrV3Yl7NOnT7dKlSq5Mvfk5OR8+mYAAMQ2gm4AAIqIq6++2pYuXWrffvtthtLyCy+80A477DC74447rHXr1nbkkUdav379XHD84Ycf5vrzRo8ebenp6TZ8+HCXOW/atKn7vJUrV9rUqVPz6VsBABDbCLoBACgijj76aOvQoYO99dZb7v6SJUtcBlrjvZXtfvjhh11wrDJwZaQnTpzoAuTcmjNnjvsMZbr1frrpvffu3euCfwAAkHcJ+fAeAAAgnyjAVhZ72LBhLuvcsGFD69ixoz355JP2/PPP29ChQ13gXbFiRbc8WE5l4BrTHVmq7pWUR44XV8n6yJEj93utxpcDAIC8I+gGAKAI0aRmt956q73//vv27rvv2g033OCCZ4231iRnGtstKgtftGiRNWvWLNv3UuC8bt268P3FixdbUlJS+P6xxx7rSsxr1qxpVapUCfibAQAQmygvBwCgCFGJd69eveyee+5xAfOVV17p9jdq1MgtKTZjxgybP3++9e3b1zZs2JDje3Xu3NleeuklmzVrlv3yyy92/fXXW+nSpcOPX3rppXbIIYe4YF5l7MuXL3djuW+55ZYsly4DAAD+EXQDAFAES8y3bdvmZhavU6eO2zdw4ECXmda+Tp06We3atd0yYjl55plnrH79+nbKKafYJZdc4iZi03JjHv3/d999Zw0aNLALLrjATaSmz9aYbjLfAADkj7hQ5sFeAAAAAAAgX5DpBgAAAAAgIATdAAAAAAAEhKAbAAAAAICAEHQDAAAAABAQgm4AAAAAAAJC0A0AAAAAQEAIugEAAAAACAhBNwAAAAAAASHoBgAAAAAgIATdAAAAAAAEhKAbAAAAAICAEHQDAAAAAGDB+H83smQNNd4CYAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "# Outer transformation domain\n", - "domain_lower = 0.0\n", - "domain_upper = 1.0\n", - "\n", - "# A valid preceding range\n", - "valid_lower = 0.25\n", - "valid_upper = 0.75\n", - "\n", - "# An invalid preceding range\n", - "invalid_lower = -0.1\n", - "invalid_upper = 0.75\n", - "\n", - "plt.figure(figsize=(10, 4))\n", - "\n", - "# Draw the outer domain\n", - "plt.hlines(\n", - " y=2,\n", - " xmin=domain_lower,\n", - " xmax=domain_upper,\n", - " linewidth=6,\n", - ")\n", - "plt.scatter(\n", - " [domain_lower, domain_upper],\n", - " [2, 2],\n", - " s=70,\n", - ")\n", - "\n", - "# Draw the valid inner range\n", - "plt.hlines(\n", - " y=1,\n", - " xmin=valid_lower,\n", - " xmax=valid_upper,\n", - " linewidth=6,\n", - ")\n", - "plt.scatter(\n", - " [valid_lower, valid_upper],\n", - " [1, 1],\n", - " s=70,\n", - ")\n", - "\n", - "# Draw the invalid inner range\n", - "plt.hlines(\n", - " y=0,\n", - " xmin=invalid_lower,\n", - " xmax=invalid_upper,\n", - " linewidth=6,\n", - ")\n", - "plt.scatter(\n", - " [invalid_lower, invalid_upper],\n", - " [0, 0],\n", - " s=70,\n", - ")\n", - "\n", - "# Labels\n", - "plt.text(\n", - " domain_upper + 0.03,\n", - " 2,\n", - " \"Outer domain [0, 1]\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "plt.text(\n", - " valid_upper + 0.03,\n", - " 1,\n", - " \"Valid range [0.25, 0.75]\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "plt.text(\n", - " invalid_upper + 0.03,\n", - " 0,\n", - " \"Invalid range [-0.1, 0.75]\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "# Show the domain boundaries\n", - "plt.axvline(\n", - " domain_lower,\n", - " linestyle=\"--\",\n", - " linewidth=1,\n", - ")\n", - "\n", - "plt.axvline(\n", - " domain_upper,\n", - " linestyle=\"--\",\n", - " linewidth=1,\n", - ")\n", - "\n", - "plt.yticks([])\n", - "plt.xlabel(\"Value\")\n", - "plt.title(\"Range-in-Domain Compatibility\")\n", - "\n", - "plt.xlim(-0.2, 1.45)\n", - "plt.ylim(-0.6, 2.6)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "71bc28b4", - "metadata": {}, - "source": [ - "The middle interval is compatible because\n", - "\n", - "$$\n", - "[0.25,0.75] \\subseteq [0,1].\n", - "$$\n", - "\n", - "The bottom interval is incompatible because part of its range lies outside the accepted domain:\n", + "Consider consecutive transformations\n", "\n", "$$\n", - "[-0.1,0.75] \\nsubseteq [0,1].\n", + "T_{j-1}:D_{j-1}\\rightarrow R_{j-1},\n", + "\\qquad\n", + "T_j:D_j\\rightarrow R_j.\n", "$$\n", "\n", - "This illustrates why exact equality is not required. The preceding range only needs to remain completely within the next transformation's domain." - ] - }, - { - "cell_type": "markdown", - "id": "6cb86fb2", - "metadata": {}, - "source": [ - "### Two different questions\n", - "\n", - "For chained `TrueMeasure` compatibility,\n", + "QMCPy previously treated the shared boundary as compatible only when\n", "\n", "$$\n", - "T_{j-1}\n", - "\\longrightarrow\n", - "R_{j-1} \\subseteq D_j\n", - "\\longrightarrow\n", - "T_j.\n", + "R_{j-1}=D_j.\n", "$$\n", "\n", - "The question is whether the output of one existing transformation can legally become the input of the next. Gaussian-to-Logistic transport asks a different question: how to construct a deterministic transformation between two probability measures,\n", + "The output of $T_{j-1}$ becomes input to $T_j$, so exact equality is unnecessary. For domain compatibility, every output only needs to lie inside the domain accepted by the next transformation:\n", "\n", "$$\n", - "X_G \\xrightarrow{\\Phi} U \\xrightarrow{F_L^{-1}} X_L.\n", + "R_{j-1}\\subseteq D_j.\n", "$$\n", "\n", - "These are related through transformation boundaries, but they are not the same operation.\n", - "\n", - "# Exploring Gaussian, Uniform, and Logistic transformations\n", - "\n", - "The domain-inclusion change solves compatibility between transformations whose existing maps can already be composed.\n", - "\n", - "A separate question is how transformations between different probability measures should be ordered.\n", - "\n", - "This distinction is important for Gaussian, Uniform, and Logistic distributions." - ] - }, - { - "cell_type": "markdown", - "id": "e371beb8", - "metadata": {}, - "source": [ - "Let\n", + "One example captures the difference:\n", "\n", "$$\n", - "U \\sim \\mathrm{Uniform}(0,1).\n", + "[0.25,0.75]\\neq[0,1],\n", + "\\qquad\n", + "[0.25,0.75]\\subseteq[0,1].\n", "$$\n", "\n", - "A standard Gaussian variable can be generated using the Gaussian inverse CDF:\n", + "For one-dimensional bounds\n", "\n", "$$\n", - "X_G = \\Phi^{-1}(U).\n", + "R=[r_L,r_U],\n", + "\\qquad\n", + "D=[d_L,d_U],\n", "$$\n", "\n", - "Similarly, a standard Logistic variable can be generated using\n", + "compatibility means\n", "\n", "$$\n", - "X_L = F_L^{-1}(U),\n", + "d_L\\leq r_L\n", + "\\qquad\\text{and}\\qquad\n", + "r_U\\leq d_U.\n", "$$\n", "\n", - "where $F_L$ is the Logistic CDF.\n", - "\n", - "Thus both inverse-CDF transformations naturally have the form\n", + "The same inequalities are checked coordinate-wise for multidimensional axis-aligned boxes. The implemented scope covers intervals and boxes with finite or unbounded numerical bounds, while preserving NumPy broadcasting between common `(1,2)` bounds and coordinate-specific `(d,2)` bounds.\n", "\n", - "$$\n", - "(0,1) \\rightarrow \\mathbb{R}.\n", - "$$" + "> QMCPy currently stores numerical lower/upper support envelopes, including `-np.inf` and `np.inf`; explicit open/closed endpoints, disconnected supports, and arbitrary nonrectangular supports are not represented by this change." ] }, { "cell_type": "markdown", - "id": "27e23c13", + "id": "d94f50a6", "metadata": {}, "source": [ - "## Gaussian to Logistic\n", - "\n", - "If the starting variable is Gaussian,\n", - "\n", - "$$\n", - "X_G \\sim N(0,1),\n", - "$$\n", - "\n", - "we cannot directly apply another inverse CDF expecting a unit-uniform input.\n", + "## 2. What changed in QMCPy?\n", "\n", - "We first map the Gaussian variable back to the unit interval using its CDF:\n", - "\n", - "$$\n", - "U = \\Phi(X_G).\n", - "$$\n", + "The old chained-`TrueMeasure` check was\n", "\n", - "Then apply the Logistic inverse CDF:\n", + "```python\n", + "if (self.domain != self.transform.range).any():\n", + " self.sub_compatibility_error = True\n", + "```\n", "\n", - "$$\n", - "X_L = F_L^{-1}(U).\n", - "$$\n", + "It is now\n", "\n", - "Therefore,\n", + "```python\n", + "if not self._range_in_domain(self.transform.range, self.domain):\n", + " self.sub_compatibility_error = True\n", + "```\n", "\n", - "$$\n", - "X_G\n", - "\\xrightarrow{\\Phi}\n", - "U\n", - "\\xrightarrow{F_L^{-1}}\n", - "X_L.\n", - "$$\n", + "After broadcasting the bound arrays, the essential helper logic is\n", "\n", - "The mathematical transport is\n", + "```python\n", + "domain[:, 0] <= transform_range[:, 0]\n", + "transform_range[:, 1] <= domain[:, 1]\n", + "```\n", "\n", - "$$\n", - "\\mathrm{Gaussian}\n", - "\\rightarrow\n", - "\\mathrm{Uniform}\n", - "\\rightarrow\n", - "\\mathrm{Logistic}.\n", - "$$" + "Both inequalities must hold in every coordinate. Equality still works because it is a special case of containment, and broadcasting preserves the existing `(1,2)` versus `(d,2)` convention." ] }, { - "cell_type": "markdown", - "id": "31f4f483", - "metadata": {}, + "cell_type": "code", + "execution_count": 1, + "id": "8d512296", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-19T21:44:27.550157Z", + "iopub.status.busy": "2026-08-19T21:44:27.549925Z", + "iopub.status.idle": "2026-08-19T21:44:29.196026Z", + "shell.execute_reply": "2026-08-19T21:44:29.194739Z" + } + }, + "outputs": [], "source": [ - "Similarly,\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "from matplotlib.patches import Rectangle\n", + "from scipy.stats import logistic, norm\n", "\n", - "$$\n", - "X_L\n", - "\\xrightarrow{F_L}\n", - "U\n", - "\\xrightarrow{\\Phi^{-1}}\n", - "X_G\n", - "$$\n", + "from qmcpy import DigitalNetB2, Kumaraswamy, Uniform\n", + "from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure\n", + "from qmcpy.util import ParameterError\n", "\n", - "gives\n", "\n", - "$$\n", - "\\mathrm{Logistic}\n", - "\\rightarrow\n", - "\\mathrm{Uniform}\n", - "\\rightarrow\n", - "\\mathrm{Gaussian}.\n", - "$$" + "def previous_compatibility_check(transform_range, domain):\n", + " # Reproduce the previous broadcasted exact-equality rule.\n", + " return not (np.asarray(domain) != np.asarray(transform_range)).any()" ] }, { - "cell_type": "code", - "execution_count": 627, - "id": "9971e708", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.561586Z", - "iopub.status.busy": "2026-08-18T03:05:33.561327Z", - "iopub.status.idle": "2026-08-18T03:05:33.565751Z", - "shell.execute_reply": "2026-08-18T03:05:33.564715Z" - } - }, - "outputs": [], + "cell_type": "markdown", + "id": "85f8195a", + "metadata": {}, "source": [ - "from scipy.stats import norm, logistic" + "## 3. Behavior before and after\n", + "\n", + "A compact comparison shows the intended behavioral boundary. The following cells then exercise three real QMCPy chains rather than testing only the helper." ] }, { "cell_type": "code", - "execution_count": 628, - "id": "4ae2f185", + "execution_count": 2, + "id": "ed148c64", "metadata": { "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.568562Z", - "iopub.status.busy": "2026-08-18T03:05:33.568239Z", - "iopub.status.idle": "2026-08-18T03:05:33.579232Z", - "shell.execute_reply": "2026-08-18T03:05:33.577822Z" + "iopub.execute_input": "2026-08-19T21:44:29.198407Z", + "iopub.status.busy": "2026-08-19T21:44:29.198143Z", + "iopub.status.idle": "2026-08-19T21:44:29.209924Z", + "shell.execute_reply": "2026-08-19T21:44:29.208877Z" } }, "outputs": [ @@ -1594,227 +163,292 @@ " \n", " \n", " \n", - " Gaussian x\n", - " Phi(x)\n", - " Logistic transport\n", + " Case\n", + " Old equality rule\n", + " New containment rule\n", " \n", " \n", " \n", " \n", " 0\n", - " -2.0\n", - " 0.022750\n", - " -3.760171\n", + " Exact equality\n", + " True\n", + " True\n", " \n", " \n", " 1\n", - " -1.0\n", - " 0.158655\n", - " -1.668268\n", + " Strict inclusion\n", + " False\n", + " True\n", " \n", " \n", " 2\n", - " 0.0\n", - " 0.500000\n", - " 0.000000\n", + " Infinite containing domain\n", + " False\n", + " True\n", " \n", " \n", " 3\n", - " 1.0\n", - " 0.841345\n", - " 1.668268\n", + " Lower-bound violation\n", + " False\n", + " False\n", " \n", " \n", " 4\n", - " 2.0\n", - " 0.977250\n", - " 3.760171\n", + " Multidimensional inclusion\n", + " False\n", + " True\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Gaussian x Phi(x) Logistic transport\n", - "0 -2.0 0.022750 -3.760171\n", - "1 -1.0 0.158655 -1.668268\n", - "2 0.0 0.500000 0.000000\n", - "3 1.0 0.841345 1.668268\n", - "4 2.0 0.977250 3.760171" + " Case Old equality rule New containment rule\n", + "0 Exact equality True True\n", + "1 Strict inclusion False True\n", + "2 Infinite containing domain False True\n", + "3 Lower-bound violation False False\n", + "4 Multidimensional inclusion False True" ] }, - "execution_count": 628, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "x_gaussian = np.array([-2.0, -1.0, 0.0, 1.0, 2.0])\n", + "comparison_cases = [\n", + " (\"Exact equality\", [[0, 1]], [[0, 1]]),\n", + " (\"Strict inclusion\", [[0.25, 0.75]], [[0, 1]]),\n", + " (\"Infinite containing domain\", [[-5, 5]], [[-np.inf, np.inf]]),\n", + " (\"Lower-bound violation\", [[-0.1, 0.75]], [[0, 1]]),\n", + " (\n", + " \"Multidimensional inclusion\",\n", + " [[0.1, 0.8], [0.2, 0.9]],\n", + " [[0, 1]],\n", + " ),\n", + "]\n", + "\n", + "comparison = pd.DataFrame(\n", + " [\n", + " {\n", + " \"Case\": name,\n", + " \"Old equality rule\": previous_compatibility_check(bounds, domain),\n", + " \"New containment rule\": AbstractTrueMeasure._range_in_domain(\n", + " bounds, domain\n", + " ),\n", + " }\n", + " for name, bounds, domain in comparison_cases\n", + " ]\n", + ")\n", + "comparison" + ] + }, + { + "cell_type": "markdown", + "id": "5fad26b1", + "metadata": {}, + "source": [ + "### A. Strict 1D inclusion\n", + "\n", + "An inner `Uniform` produces values in $[0.25,0.75]$, while the outer `Kumaraswamy` accepts inputs in $[0,1]$." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e3f1220f", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-19T21:44:29.212669Z", + "iopub.status.busy": "2026-08-19T21:44:29.212435Z", + "iopub.status.idle": "2026-08-19T21:44:29.220857Z", + "shell.execute_reply": "2026-08-19T21:44:29.219801Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Inner range: [[0.25 0.75]]\n", + "Outer domain: [[0 1]]\n", + "Range contained in domain: True\n", + "Compatibility error: False\n", + "Sample shape: (8, 1)\n", + "All samples finite: True\n" + ] + } + ], + "source": [ + "inner = Uniform(\n", + " DigitalNetB2(1, seed=7),\n", + " lower_bound=0.25,\n", + " upper_bound=0.75,\n", + ")\n", + "outer = Kumaraswamy(inner)\n", + "samples_1d = outer.gen_samples(8)\n", + "\n", + "print(\"Inner range:\", inner.range)\n", + "print(\"Outer domain:\", outer.domain)\n", + "print(\n", + " \"Range contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(inner.range, outer.domain),\n", + ")\n", + "print(\"Compatibility error:\", outer.sub_compatibility_error)\n", + "print(\"Sample shape:\", samples_1d.shape)\n", + "print(\"All samples finite:\", np.isfinite(samples_1d).all())" + ] + }, + { + "cell_type": "markdown", + "id": "a27ca7cd", + "metadata": {}, + "source": [ + "### B. Multidimensional/broadcast inclusion\n", + "\n", + "Here a `(2,2)` inner range is checked against the outer measure's common `(1,2)` unit-domain interval." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3b524d4a", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-19T21:44:29.222806Z", + "iopub.status.busy": "2026-08-19T21:44:29.222615Z", + "iopub.status.idle": "2026-08-19T21:44:29.229709Z", + "shell.execute_reply": "2026-08-19T21:44:29.228187Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Inner range: [[0.1 0.8]\n", + " [0.2 0.9]]\n", + "Outer domain: [[0 1]]\n", + "Range contained in domain: True\n", + "Compatibility error: False\n", + "Sample shape: (8, 2)\n", + "All samples finite: True\n" + ] + } + ], + "source": [ + "inner_2d = Uniform(\n", + " DigitalNetB2(2, seed=7),\n", + " lower_bound=[0.1, 0.2],\n", + " upper_bound=[0.8, 0.9],\n", + ")\n", + "outer_2d = Kumaraswamy(inner_2d)\n", + "samples_2d = outer_2d.gen_samples(8)\n", "\n", - "u = norm.cdf(x_gaussian)\n", - "x_logistic = logistic.ppf(u)\n", + "print(\"Inner range:\", inner_2d.range)\n", + "print(\"Outer domain:\", outer_2d.domain)\n", + "print(\n", + " \"Range contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(inner_2d.range, outer_2d.domain),\n", + ")\n", + "print(\"Compatibility error:\", outer_2d.sub_compatibility_error)\n", + "print(\"Sample shape:\", samples_2d.shape)\n", + "print(\"All samples finite:\", np.isfinite(samples_2d).all())" + ] + }, + { + "cell_type": "markdown", + "id": "6c017194", + "metadata": {}, + "source": [ + "### C. Actual incompatibility\n", "\n", - "pd.DataFrame(\n", - " {\n", - " \"Gaussian x\": x_gaussian,\n", - " \"Phi(x)\": u,\n", - " \"Logistic transport\": x_logistic,\n", - " }\n", - ")" + "The range\n", + "\n", + "$$\n", + "[-0.1,0.75]\\nsubseteq[0,1]\n", + "$$\n", + "\n", + "extends below the next domain and must remain rejected." ] }, { "cell_type": "code", - "execution_count": 629, - "id": "08e326eb", + "execution_count": 5, + "id": "fd51b128", "metadata": { "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.582175Z", - "iopub.status.busy": "2026-08-18T03:05:33.581892Z", - "iopub.status.idle": "2026-08-18T03:05:33.593505Z", - "shell.execute_reply": "2026-08-18T03:05:33.592557Z" + "iopub.execute_input": "2026-08-19T21:44:29.233556Z", + "iopub.status.busy": "2026-08-19T21:44:29.233190Z", + "iopub.status.idle": "2026-08-19T21:44:29.239274Z", + "shell.execute_reply": "2026-08-19T21:44:29.238566Z" } }, "outputs": [ { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Original GaussianRecovered GaussianAbsolute error
0-2.0-2.08.881784e-16
1-1.0-1.00.000000e+00
20.00.00.000000e+00
31.01.00.000000e+00
42.02.02.220446e-15
\n", - "
" - ], - "text/plain": [ - " Original Gaussian Recovered Gaussian Absolute error\n", - "0 -2.0 -2.0 8.881784e-16\n", - "1 -1.0 -1.0 0.000000e+00\n", - "2 0.0 0.0 0.000000e+00\n", - "3 1.0 1.0 0.000000e+00\n", - "4 2.0 2.0 2.220446e-15" - ] - }, - "execution_count": 629, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "Range contained in domain: False\n", + "Compatibility error: True\n", + "Sampling result: ParameterError - The sub-transform range must be contained within the transform domain.\n" + ] } ], "source": [ - "u_back = logistic.cdf(x_logistic)\n", - "x_gaussian_back = norm.ppf(u_back)\n", - "\n", - "pd.DataFrame(\n", - " {\n", - " \"Original Gaussian\": x_gaussian,\n", - " \"Recovered Gaussian\": x_gaussian_back,\n", - " \"Absolute error\": np.abs(x_gaussian - x_gaussian_back),\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "a47742ab", - "metadata": {}, - "source": [ - "The recovered Gaussian values agree with the original values up to floating-point roundoff (approximately $10^{-15}$ in this example).\n", - "\n", - "Numerically, this confirms the inverse relationship\n", + "invalid_inner = Uniform(\n", + " DigitalNetB2(1, seed=7),\n", + " lower_bound=-0.1,\n", + " upper_bound=0.75,\n", + ")\n", + "invalid_outer = Kumaraswamy(invalid_inner)\n", "\n", - "$$\n", - "\\Phi^{-1}\\left(F_L\\left(F_L^{-1}(\\Phi(x))\\right)\\right)\n", - "\\approx x.\n", - "$$\n", + "print(\n", + " \"Range contained in domain:\",\n", + " AbstractTrueMeasure._range_in_domain(\n", + " invalid_inner.range, invalid_outer.domain\n", + " ),\n", + ")\n", + "print(\"Compatibility error:\", invalid_outer.sub_compatibility_error)\n", "\n", - "The tiny nonzero errors are ordinary floating-point numerical error, not a failure of the mathematical inverse relationship." + "try:\n", + " invalid_outer.gen_samples(8)\n", + "except ParameterError as error:\n", + " print(\"Sampling result:\", type(error).__name__, \"-\", error)" ] }, { "cell_type": "markdown", - "id": "32d9d79c", + "id": "d4d209de", "metadata": {}, "source": [ - "### Visualizing the Gaussian-to-Logistic transport\n", - "\n", - "The complete deterministic map from a Gaussian value to a Logistic value is\n", + "The change accepts strict containment without accepting genuinely out-of-domain transformations.\n", "\n", - "$$\n", - "T(x)=F_L^{-1}(\\Phi(x)).\n", - "$$\n", + "### One compatibility visual\n", "\n", - "The following plot shows how Gaussian input values are mapped into Logistic output values." + "For axis-aligned boxes, compatibility is checked coordinate by coordinate. The dashed box is fully contained; the dotted box violates the second-coordinate upper bound." ] }, { "cell_type": "code", - "execution_count": 630, - "id": "2d70d570", + "execution_count": 6, + "id": "490d7fe0", "metadata": { "execution": { - "iopub.execute_input": "2026-08-18T03:05:33.596674Z", - "iopub.status.busy": "2026-08-18T03:05:33.596352Z", - "iopub.status.idle": "2026-08-18T03:05:33.926487Z", - "shell.execute_reply": "2026-08-18T03:05:33.924934Z" + "iopub.execute_input": "2026-08-19T21:44:29.241535Z", + "iopub.status.busy": "2026-08-19T21:44:29.241347Z", + "iopub.status.idle": "2026-08-19T21:44:29.455867Z", + "shell.execute_reply": "2026-08-19T21:44:29.454754Z" } }, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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bl999dVqfR6qWob4WTN79mw0b95cXTy4T58++Pnnn4+5/bvvvov27dur7Tt37ozPPvusxmIlIqLwtH//ftx6661o2bIloqKi0KRJEwwaNAgrVqyo0uc57bTTcPvtt1f4cbNmzcK8efOqNBYyj6DX8C1cuBDjx4/HnDlzVLI3c+ZMDBw4EFu2bPF7iRW5Vt+VV16J6dOn44ILLsDbb7+NIUOGYO3atejUqRPM6vDhw8EOwRTk0koFBQXIy8vjpZVYroZm1mPV4XDA5XKpvzab7ZjbymXQKkuDpp7DW0ZBBpbuWOqzX6fDCYfNdzt/duzYoRKxxMREdf6R843sf9myZRg9ejQ2btxY6VjLugRcyfiPJzY2Vv2t6OMqSt4/ibG8ZFt5TERE0FOOsGbRKvKuVQNJ8k488UQ899xzalkOcvnVJL+iJk6cWGr7oUOHIjc3F5988oln3UknnYRu3bqppPF4srOz1Qc2KysLCQkJMKJDhw6pZFe+5OUC0vv27avQh4vKxjKtHixXlml5NWvWTH1X165dG3muPDyz6xmf+29rehtibUcTlzf3vomVGSsrVbgNoxri0daP+qzLdmZj3JZxqGWrhSOuI2rdrHazkBBx/HPBuHHjsHXrVrz33nuIiYnxuS8nJwfx8fGeWsAnnngCv/zyi7pmb9++fTFhwgSkpqaq+1966SWsWrUK11xzjSoHOSf169cP9913H+Li4lRz6aeffuqz/w8//BD16tXDtGnT8OuvvyItLU0tX3rppaoCRCePPXLkCJ588km1fPPNN6NNmzaIjIxU+5CE65JLLsFNN93kE7vUDK5evVolih06dMAdd9yBtm3beraRWsN33nlH/QAZMGAAkpKS8MMPP6gKF2G329Vju3btqv4vr+/0009XrW/3338/NmzYgC+//FKd26WC58cff1TncXkuSZ5lnzpp7ZP4pKylNS85OVntwztmqfiRJHvz5s0q8Zb7L7roIqxbt07lAkIS8LvuugvffPONKtezzz4bTz/9tDrujELKc/v27WjRooVqsfQmOYqUc1XmKkFNt4uKirBmzRpMmjTJs04+IPLmy8Hkj6yXA8ab1AiW1WehsLBQ3XTy4RKSQBk1iZK45ATqfaOqwTKtHixXlmlFjhWdU3NiS94Wn/tlne7SepfiwroXVqpwrcfosaQne+UlJ10594waNapUsif0ZE8qLO68805V0/biiy+qWq3HH38c9957r1rW7dmzRyVFM2bMUAmXnANff/11lcRIcrhr1y60atVKJWxCkh45L0hFgCRIUmnx+++/qwRQEpizzjqrzNilcuTqq6/Ga6+9phKvKVOmqMRMKluEVKxI87QkfbVq1cLixYtVHO+//756HqnBfPnll3H33Xerx33++eeqZa5hw4Z+n8/73Cr7luRXmsDlNezevRvnnnsuHnnkEfWcb7zxhmoSl8StadOmnn089dRTmDp1qioXSbCl3P/3v/+hXbt26hwujznvvPMwf/587Ny5UyWo3s8t/RjPOOMM3HDDDaqM8/PzVSyXX355lTe/B0IvJ3/5SHXkJxHBbqaUD4T8UvEmy3IA+CO/nvxtL+v9kQ+HHOAlya+L4zUnBDPrl5o9+WKsU6eOWmfU5DTUsExZrqHCrMeqvCb57pXaJrvFXup+qSGyR9g9/69Kx3u+suitLK1btz5mTJIUbtu2TdXQ1a9fX62T5EZq1aSbktRGSaWGJIayXmqehHRPkpo72bckRlIjJ0mjnAe8jR071qcmbNOmTVi5cqVKfoTsW44bPUb5v9TUSQInJImUWjOpaDnllFNUjdgff/yh9iHPKaRW7Ouvv1YJqdQgLliwQHWbkv8LqTGU2kupSNGfR/8rr0u/6TWOZ555pidmqbGSfvc6OTdLZY3UPo4ZM8azXpLCW265xROPdPWSGOW5JcmT1yW1o1IrJv35JcmW5Fh/7meffVbV9EkZ615++WVVZpJbeNdeBpMer3TbkFyoZI5S1UzfoC6/ELxrBOXXgVQrywdN/7AZjbz58gWj/xJmk27VYZlWD5Yry7S8JLGQk5vT6YTDWbqvmTQNOrTq6YNW2eeTWPW/x+ofJ82QUgEhzbf6dlJzJTWAcp/UUMkJXhI5KQd9m5SUFNVMqy+X1Ydv0aJF+Pjjj1UFhyRccr8kL/p28hh5rPd+JMnz3o/EJpUtsk6SPTnf9O/f3+d5ZN9SyyjbSJPjxRdf7LMPSVwlQfVeJ/+XhFO/Cemupf9fSHOzJIHS1CvnNSlPqX2Tmj/v7bp06eKzLMmzdHWSdX/99Ze6X++vKPTaSv25pSZTElapoSxp+/btKkk0Aj1eeS0lm3T1Y840CZ9URcsvvQMHDvisl2X911FJsr4i20u1sdxKMnJTqZSLvCa907YcCEaNNdSwTFmuocKsx6okBunp6aovXz7yAd8WXXQ6oROSo5Or5bll0EZlnk8qCeQ9kERImjXLIv3FJJEruY2c52Qfsl4SQkkAvbeR/nNSS6avk6ZVqQn13kaaUaXmSpqIJcGRfUhzpcxqoW8niaMkEN77keTSez+SBElNm6yTfnVyvzTbliTb6OdoPXadxCZN2/o6STTleaXW1vvcKs/vfexKbZ08l/QxlNpS2YfUHMox4b2dlKH3svzfu6uTvs77fv2v3CSxlGbf//u//yv1uhr813pmBCXj9nefaRI+eVN79uyp2tSlylg/cGTZu+ram3SAlfu9h6zLASTrzUI+OPKBkgNcqnWlJtIoB2ioY5myXEOFWY9VSWKlT5zq6I/StWU5rhxEuCp2aoqNiEV0hG8NiXeSJyN21b6dOaXuj7BHHLfpWJI06SsuzYjSX6xk65D0GZMESWq+pLZKauAkSRJSiyb3S62UPI8kUN7NrkLvXqSvk0oKef+9t/npp5/U4A4Z0OhdW+W9L73GyLtJ13u55DZSAyexSuIlzZ3+yMAKaQK+/vrrPeskydSfV6+N1JuTj+W7775TcwXKAAshiZmMfq4IqSV96623VPKtV+ZIE7O3Hj16qD6I8po4MthATbrS3DpixAj06tULvXv3Vm318iV33XXXqfuHDx+ORo0aqb54+kgpqX6WTp3nn3++6l8gVcsy8omIiELbkA+P/viviHv73Isr2xePVvV24QcXIqMwo0rmiz355JPVeUoGFEgCJ81uUuHwwgsv4M8//1QDDqWPmgySkHOZ3C/95+ScJee48pJERRI8SYaklkxq7qT/mgxy+OKLL9SozjfffFMlOvL/ypJ4pbJEKlyk5lCah/fu3av6IEpSJjHLOVeSNPm/vH7pQyd9B2UgRkXJa5BBIVL7JsnhAw88UOGpd6666io1ollG7cpADGl61kcl6wmn9AeUPnsyglkGm0j5bd26VeULr7zyimH775t+4mWZZkXerAcffFB1sly/fj2WLl3qGZghb6a09evkF44MBZcET6qTZQSPdPo08xx8REQUXJLgyHyvMt2IDBKQc46MjpUWJ0n49IRDBiDIwAsZVSoJlTxOmmMrQkbqSlLSsWNH1doj50EZlCB96eScKU260udPH4xRWRKv9KeTWKWSRRK+K664Qo181c/B8nySmEniJC1ycp+Mmq0MaYKWspHzuCR9UmsqtXEVIVOUSD9GyRUkZ5DkT/IHofeDkxHEUpsofUVlOhZJwm+//XZVC+vdNzDcBH0evpoWCvPwmb1JJ5hYpizXUGHWY7Wsucc6v148erMqa/j+t+B/x6zhM9Ol1YKhIk261UVqHSVhlfO6v2lzjKognObhIyIiIqoIadqWmlPp7vXbb7/hnnvuUXPshVKyFwxM+IiIKOikpq2yZNBGWT4c8qFn0Ia/2qikqKRKPy8Fhww0kWZc+Sujbi+77DI8+qjvVVWoNCZ8REQUdNXVrOo95YoRmh8pcNKfUG5UMeHbe5GIiIgoTDDhIyIiIjI5JnxEREREJseEj4iIiMjkmPARERERmRwTPiIiIiKTY8JHRERB48rJQd6aNeqmFRWVut+dl+e5X26uzEy/+8lbu9azjWPvXr/bFGzejPw1a333l5ODUCfz0cll3uSqLHJ1hopcs1eu+Rts8+bNq1DcVDmch4+IiIKm8K+/sPPqa9T/23z7DSJq1/a5v2j3bs/9ovGcFxB/2mml9rNz+AjA6VT/r33rWNQZM6bUNvsfmoKC337zWdds/luI7dmzXLHu3r0bkydPVtd7P3z4sJr0d8iQIWoS4NTU1HK+YmDHjh3qclrr1q1T14MN1NNPP62uOS/Xl5VLh4YauV7veeedF+wwTI8JHxERGYK7oADOw4dLJX1VLfakk2D97zJctnImSP/88w/69u2Ltm3b4p133lEJ26ZNm3DXXXfh888/x48//oiUlOBck3fbtm3o2bMn2rRpg1Akl0Sr6suiuVwuNbm2TLJNR7EkiIjIEP4dPQZFO3dW/xNZLGg04yk0eeF5RLVuXa6HjBkzBpGRkfjyyy/Rv39/NG3aFOeeey6WL1+OPXv24L777vPavQUffPCBz+OlyVKaLoUki6J79+5q29P81Fh6e+GFF9CqVSv1/O3atcObb77p0yz7/vvvq+vLyr6uvfZav/s4ePAgBg0apBIref758+eX2mbXrl248MILUatWLSQkJKjr0x44cMBz/0MPPaRqJOfOnatev2w3evRolVw9/vjjqF+/PurWrVvqMmczZsxA586dVZNzkyZN1GOOHDlSZpOu/jzyOuX1Sa3lFVdcgZxjNL/r+/joo4/QsWNHREVFqdfzyy+/qObu2rVrq/3Ie7d27Vqfx0q5vfLKK7jooosQGxurEmfZjzdZlvXR0dE4/fTT8frrr6vHZXp1Mfj2229x6qmnqjKW13nbbbchNzcXRsGEj4iIDNO8W1Jkkyaq2VW/xZbRBNrsjdc92yRddJHfbeo/NBlN3ngDtceMhrsCJ+L09HR88cUXKlEpWRMlSc7VV1+NhQsXqku3lcfPP/+s/kqyKE2xixcvLnPbJUuWYNy4cbjzzjuxceNG3Hzzzbjuuuvw1VdfqfsloTnnnHNUcib7mjVrlt/9SCIoTdLyuPfeew/PP/+8SgJ1csk5Sfbkta5evRrLli1TtZrS3FqyNlFqNKVZW2o6JfmTRPLff/9Vj/u///s/3H///fjpp588j5FatmeeeUbViEqitHLlyuNeGk2eR5LmTz75RN1k34899tgxH5OXl6eeX5I3eS5JPiVJHDFihErGpBZWkjZpPi6ZPE6ZMkWV4e+//67ul/dUykJs374dl156qWq+/+2339R74J3g6/HK+3DJJZeofcjxIM85duxYGIYWZrKysuQTqf4andvt1nJyctRfYpkaGY9Vlml55efna3/88Yf6KxyHDmkZ773nuclydR6nTqezwt+pP/74ozpvLFmyxO/9M2bMUPcfOHBALfvbNjExUXvttdfU/7dv3662Wbdu3XGfu1+/ftrIkSN91l122WXaeeed51m+8MILtREjRpS5jy1btqjn+/nnnz3r/vzzT7Xu6aefVstffvmlZrPZtF27dnm22bRpk8/jJk+erMXGxmrZ2dmebQYOHKg1b95clauuXbt22vTp08uM591339VSU1M9y1IuUj46f89z1113aX369Clzn7IPiXX9+vXasbhcLi0+Pl77+OOPPevkcffff79n+ciRI2rd559/rpbvuecerVOnTj77ue+++9Q2GRkZavmGG27QbrrpJp9tvvnmG81qtXqO9eN9FrxlZmZWea7CGj4iIgoa6a+XdMklnlt1998LRHlr8Crjm2++UU2k+k1vcv3zzz9x8skn+2wry7LeH3mc935kv7JtRESE6uena9++vU8zqmwjzZBy00nTqGzj/VzSxBofH+9ZrlevHjp06ODTV07WedceSk3mmWeeiUaNGqnHDhs2DGlpaapGriwln0cGyHjv0x9p8u7SpYvPOmmSHjlypKrZkyZdaaqW5mRp7vXm/Thpepbt9OfbsmULTjzxRJ/te/fu7bMs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GTx4MOLi4vDoo4+q9Y899hjq1auH+Ph43HDDDSgoKPB5XMkmXalNu+2223D33XcjJSUF9evXV83A3mbMmKGSV3keqbGU13nkyBF136pVq3DdddchKytLxSQ3/fGFhYWYMGECGjVqpB7bp08ftf2x3H777Zg4cSJOOumkCpY+EZkNEz4iMpz09HQsXbpU1eRJclOS3uTpdrtVsifbr169GsuWLcM///yDoUOHerZdsmQJxo0bhzvvvBMbN27EzTffrJKqr776ymefklhddNFF2LBhA66//nosWrRIrZs2bRp+/fVXNGjQAM8///xxY3/99ddVzD/99BMef/xxTJ06VcWls1qteOaZZ7Bp0ya17cqVK1WCKPr164eZM2eqxHXfvn3qJkmeGDt2LH744QcsWLAAv//+Oy677DJVc/f3338HUNJEFDY0IiKD+emnnzT5elq8ePExt/vyyy81m82m7dq1y7Nu06ZN6rE///yzWu7Xr582cuRIn8dddtll2nnnnedZlu1vv/12n2369u2rjR492mddnz59tK5du3qWR4wYoV144YWe5f79+2unnHKKz2NOPPFE7Z577inzNbz77rtaamqqZ/m1117TEhMTfbbZuXOnep179uzxWX/mmWdqkyZN0o7nq6++Uq8xIyPjuNsSkTmxho+IDOdoDnZ8f/75p2oWlZuuY8eOqgZQ7tO3kb6A3mRZv1/Xq1evUvuWZlNvffv2PW5MXbp08VmWmsGDBw96lpcvX44zzzxTNc1KU/GwYcOQlpam+tuVRWodXS6XataWpmv9JrWa27ZtO25MREQctEFEhtOmTRvVf606B2aU5K/puDJKDvaQ1yFNz/pAlAsuuACjRo1S/QSln9+3336r+gcWFRUhNjbW7z6lj5/NZsOaNWvUX2+S+BERHQ9r+IjIcCQRGjhwIGbPno3c3NxS9+vTi3To0AG7d+9WN90ff/yh7peaPn2b7777zufxsqzfXxZ5nPTD8+Y9WKQyJGGT5O+pp55SAymkxm7v3r0+28jAEqnN89a9e3e1TmoKW7du7XOTgSFERMfDhI+IDEmSPUlyevfujffff18NTpBmVhnwoDetDhgwQI14vfrqq7F27Vo1onf48OHo37+/p4n2rrvuUnPbyShc2YeMkl28eLFnMERZZKDH3Llz8dprr+Gvv/7C5MmT1UCLQEiCJlO+PPvss2pwiYwWnjNnjs82zZs3VzV6Mtfg4cOHVVOvJIbyGuW1Sezbt29Xr3X69On49NNPjzmP4fr167F161ZP07AsyyAXIgozwe5ESERUlr1792pjxozRmjVrpkVGRmqNGjXSBg8erAYheA9okHVxcXFafHy8GpCxf/9+n/08//zzWsuWLTW73a61bdtWe+ONN3zul6/CJUuWlHr+Rx99VKtdu7ZWq1YtNUDj7rvvPu6gjXHjxvnsQ+6X7XQzZszQGjRooMXExGgDBw5UsZQcUHHLLbeogRyyfvLkyWpdUVGR9uCDD2rNmzdXr0P2cdFFF2m///57meUnj5V9lLzJwBAiCi8W+SfYSScRERERVR826RIRERGZHBM+IiIiIpNjwkdERERkckz4iIiIiEyOCR8RERGRyTHhIyIiIjI5JnxEREREJseEj4iIiMjkmPARERERmRwTPiIiIiKTY8JHREREZHJM+IiIiIhgbv8Pz4xfblLu/N4AAAAASUVORK5CYII=", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -1822,306 +456,391 @@ } ], "source": [ - "x_gaussian_grid = np.linspace(-3.5, 3.5, 400)\n", - "\n", - "uniform_values = norm.cdf(x_gaussian_grid)\n", - "\n", - "x_logistic_grid = logistic.ppf(uniform_values)\n", + "fig, ax = plt.subplots(figsize=(6.5, 6.5))\n", "\n", - "plt.figure(figsize=(8, 5))\n", - "\n", - "plt.plot(\n", - " x_gaussian_grid,\n", - " x_logistic_grid,\n", - " linewidth=2,\n", - " label=r\"$F_L^{-1}(\\Phi(x))$\",\n", + "outer_box = Rectangle(\n", + " (0, 0), 1, 1, fill=False, linewidth=3, color=\"black\", label=\"Domain $[0,1]^2$\"\n", ")\n", - "\n", - "# Identity line for reference\n", - "plt.plot(\n", - " x_gaussian_grid,\n", - " x_gaussian_grid,\n", + "valid_box = Rectangle(\n", + " (0.1, 0.2),\n", + " 0.7,\n", + " 0.7,\n", + " fill=False,\n", + " linewidth=3,\n", " linestyle=\"--\",\n", - " linewidth=1,\n", - " label=\"Identity reference\",\n", + " color=\"tab:green\",\n", + " label=\"Contained range\",\n", + ")\n", + "invalid_box = Rectangle(\n", + " (0.1, 0.2),\n", + " 0.7,\n", + " 0.9,\n", + " fill=False,\n", + " linewidth=2.5,\n", + " linestyle=\":\",\n", + " color=\"tab:red\",\n", + " label=\"Out-of-domain range\",\n", ")\n", "\n", - "plt.xlabel(\"Gaussian input $x_G$\")\n", - "plt.ylabel(\"Logistic output $x_L$\")\n", - "plt.title(\"Gaussian → Uniform → Logistic Transport\")\n", - "\n", - "plt.legend()\n", - "plt.grid(alpha=0.25)\n", + "for box in (outer_box, valid_box, invalid_box):\n", + " ax.add_patch(box)\n", "\n", + "ax.set(\n", + " xlim=(-0.1, 1.2),\n", + " ylim=(-0.1, 1.2),\n", + " xlabel=\"Coordinate 1\",\n", + " ylabel=\"Coordinate 2\",\n", + " title=\"Coordinate-wise range-in-domain compatibility\",\n", + ")\n", + "ax.set_aspect(\"equal\")\n", + "ax.legend(loc=\"lower right\")\n", + "ax.grid(alpha=0.15)\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", - "id": "e2a3ea36", + "id": "02c17b09", "metadata": {}, "source": [ - "The transformation is monotone because both the Gaussian CDF $\\Phi$ and the Logistic inverse CDF $F_L^{-1}$ are monotone.\n", + "## 4. What this change solves\n", "\n", - "The intermediate uniform value is\n", + "The current PR solves only\n", "\n", "$$\n", - "u=\\Phi(x_G),\n", + "R_{j-1}=D_j\n", + "\\quad\\longrightarrow\\quad\n", + "R_{j-1}\\subseteq D_j.\n", "$$\n", "\n", - "and the final output is\n", + "This determines whether the output support of one existing `TrueMeasure` transformation can feed the domain of the next. It does **not** by itself implement arbitrary measure transport, Gaussian-to-Logistic importance sampling, forward CDF maps, or general transport/Jacobian abstractions." + ] + }, + { + "cell_type": "markdown", + "id": "d560ec14", + "metadata": {}, + "source": [ + "## 5. QMC, Transport, and Importance Sampling\n", "\n", - "$$\n", - "x_L=F_L^{-1}(u).\n", - "$$\n", + "### 5.1 QMC and the role of Uniform\n", "\n", - "Therefore the complete transport is\n", + "Sobol/DigitalNet points live in the unit cube, so direct QMC sampling begins with Uniform coordinates. Gaussian and Logistic samples are obtained separately from that reference space:\n", "\n", "$$\n", - "T(x_G)=F_L^{-1}(\\Phi(x_G)).\n", + "U\\xrightarrow{F_G^{-1}}X_G,\n", + "\\qquad\n", + "U\\xrightarrow{F_L^{-1}}X_L.\n", "$$\n", "\n", - "This clarifies the ordering: the Uniform distribution is not an arbitrary extra step. It is the intermediate probability scale that connects the Gaussian CDF to the Logistic inverse CDF." + "Uniform is the reference space from which QMC points originate. We therefore need to distinguish the direction of a mathematical transport from the direction in which the QMC algorithm is actually evaluated." ] }, { "cell_type": "markdown", - "id": "945affc1", + "id": "a76d04ee", "metadata": {}, "source": [ - "## What this reveals about the current `TrueMeasure` abstraction\n", - "\n", - "The domain-inclusion change answers one question:\n", - "\n", - "> When two existing transformations are composed, is the output range of the first valid input for the second?\n", + "### 5.2 Why the deterministic Logistic detour cancels\n", "\n", - "However, Gaussian-to-Logistic transport introduces a second question.\n", - "\n", - "The current `TrueMeasure._transform` interface is primarily designed around transformations that generate a measure from the input supplied by the preceding sampler. For common inverse-CDF constructions, the map is naturally\n", + "Let $F_G$ and $F_L$ be the Gaussian and Logistic CDFs. A deterministic Gaussian-to-Logistic transport is\n", "\n", "$$\n", - "(0,1) \\rightarrow \\text{target support}.\n", + "T_{G\\to L}(x)=F_L^{-1}(F_G(x)).\n", "$$\n", "\n", - "A Gaussian-to-Logistic transport instead requires the forward Gaussian CDF\n", + "If that Logistic value is immediately mapped to Uniform, then\n", "\n", "$$\n", - "\\Phi:\\mathbb{R}\\rightarrow(0,1)\n", + "F_L(T_{G\\to L}(x))\n", + "=F_L(F_L^{-1}(F_G(x)))\n", + "=F_G(x).\n", "$$\n", "\n", - "followed by the Logistic inverse CDF\n", + "Equivalently,\n", "\n", "$$\n", - "F_L^{-1}:(0,1)\\rightarrow\\mathbb{R}.\n", + "F_L\\circ F_L^{-1}\\circ F_G=F_G,\n", + "\\qquad\n", + "\\boxed{G\\rightarrow L\\rightarrow U\\equiv G\\rightarrow U}.\n", "$$\n", "\n", - "Therefore, domain-range inclusion alone does not automatically create this transport.\n", - "\n", - "The inclusion change makes existing compatible transformation chains more general, while explicit distribution-to-distribution transport may require additional transformation semantics." + "If Logistic is inserted only as a deterministic transport and is immediately mapped back to Uniform, it adds no new transformation: the Logistic inverse CDF and CDF cancel." ] }, { "cell_type": "markdown", - "id": "c5c1d083", + "id": "4c444800", "metadata": {}, "source": [ - "## Transport versus importance sampling\n", - "\n", - "A Logistic distribution may also be used as an importance-sampling proposal for a Gaussian target.\n", - "\n", - "That is a different operation from transporting Gaussian samples into Logistic samples.\n", + "### 5.3 Logistic as an importance-sampling proposal\n", "\n", - "If\n", + "Logistic becomes useful here when it is introduced as an alternative sampling measure rather than as an intermediate deterministic transport. Let $p_G$ be the Gaussian target density and $p_L$ the Logistic proposal density:\n", "\n", "$$\n", - "p(x)\n", + "I=\\int_{\\mathbb R}g(x)p_G(x)\\,dx\n", + "=\\int_{\\mathbb R}g(x)\\frac{p_G(x)}{p_L(x)}p_L(x)\\,dx.\n", "$$\n", "\n", - "is the Gaussian target density and\n", + "This is a **change of measure through a likelihood ratio**, not a Gaussian-CDF-to-Logistic-inverse-CDF point transport. With $x=F_L^{-1}(u)$ and $du=p_L(x)\\,dx$,\n", "\n", "$$\n", - "q(x)\n", + "\\boxed{\n", + "I=\\int_0^1\n", + "g(F_L^{-1}(u))\n", + "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))}\n", + "\\,du\n", + "}.\n", "$$\n", "\n", - "is the Logistic proposal density, then samples are generated from\n", + "The runtime QMC path is therefore\n", "\n", "$$\n", - "X \\sim q\n", + "\\boxed{\n", + "U_{\\mathrm{Sobol}}\n", + "\\xrightarrow{F_L^{-1}}\n", + "X_L\n", + "\\xrightarrow{\\times\\,p_G(X_L)/p_L(X_L)}\n", + "\\text{weighted integrand}\n", + "}.\n", "$$\n", "\n", - "and weighted using\n", + "There is no Gaussian-to-Uniform transformation in this runtime path; Sobol points already supply Uniform inputs. Logistic matters because it changes the sampling measure and hence the function presented to those points.\n", + "\n", + "Direct Gaussian QMC uses\n", "\n", "$$\n", - "w(X)=\\frac{p(X)}{q(X)}.\n", + "h_G(v)=g(F_G^{-1}(v)),\n", + "\\qquad\n", + "I=\\int_0^1h_G(v)\\,dv,\n", "$$\n", "\n", - "The corresponding integrand becomes\n", + "whereas Logistic importance-sampling QMC uses\n", "\n", "$$\n", - "g(X)\\frac{p(X)}{q(X)}.\n", + "h_L(u)=g(F_L^{-1}(u))\n", + "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))},\n", + "\\qquad\n", + "I=\\int_0^1h_L(u)\\,du.\n", "$$\n", "\n", - "In this case, Logistic is a proposal distribution rather than an intermediate deterministic transport.\n", + "Thus\n", "\n", - "These two concepts should remain separate:\n", + "$$\n", + "\\int_0^1h_G(v)\\,dv=\\int_0^1h_L(u)\\,du,\n", + "\\qquad\n", + "h_G\\neq h_L\\ \\text{in general}.\n", + "$$\n", "\n", - "1. **Transformation composition:** can the output space of one deterministic transformation feed the next?\n", - "2. **Importance sampling:** can another measure be used to generate samples and corrected using density ratios?" + "Both formulations estimate the same Gaussian integral but present different functions to the Sobol points. A proposal can therefore improve or worsen QMC behavior; Logistic is not universally better." ] }, { "cell_type": "markdown", - "id": "e1994b43", + "id": "6b1acc04", "metadata": {}, "source": [ - "# Conclusions\n", - "\n", - "This investigation establishes the following:\n", + "### 5.4 Connection: the likelihood ratio is a transport Jacobian\n", "\n", - "1. The previous chained `TrueMeasure` compatibility rule effectively required exact equality between the range of one transformation and the domain of the next:\n", + "Define the Logistic- and Gaussian-based Uniform coordinates\n", "\n", - " $$\n", - " R_{j-1} = D_j.\n", - " $$\n", - "\n", - "2. Exact equality is unnecessarily restrictive for domain compatibility. For the current interval and axis-aligned box representation, compatibility can instead be generalized to coordinate-wise range-in-domain containment:\n", + "$$\n", + "u=F_L(x),\n", + "\\qquad\n", + "v=F_G(x).\n", + "$$\n", "\n", - " $$\n", - " R_{j-1} \\subseteq D_j.\n", - " $$\n", + "Since $x=F_L^{-1}(u)$, the map between them is\n", "\n", - " Equality remains valid because it is a special case of containment.\n", + "$$\n", + "T(u)=F_G(F_L^{-1}(u)).\n", + "$$\n", "\n", - "3. In one dimension, for\n", + "Differentiating gives\n", "\n", - " $$\n", - " R_{j-1} = [r_L,r_U]\n", - " $$\n", + "$$\n", + "\\frac{dT}{du}=p_G(x)\\frac{dx}{du}.\n", + "$$\n", "\n", - " and\n", + "Because $du/dx=p_L(x)$,\n", "\n", - " $$\n", - " D_j = [d_L,d_U],\n", - " $$\n", + "$$\n", + "\\frac{dx}{du}=\\frac{1}{p_L(x)},\n", + "$$\n", "\n", - " compatibility requires\n", + "and therefore\n", "\n", - " $$\n", - " d_L \\leq r_L\n", - " \\qquad\\text{and}\\qquad\n", - " r_U \\leq d_U.\n", - " $$\n", + "$$\n", + "\\boxed{\n", + "T'(u)=\n", + "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))}\n", + "}.\n", + "$$\n", "\n", - " The same rule extends coordinate-wise to multidimensional axis-aligned boxes. QMCPy's `(1,2)` and `(d,2)` representations remain interoperable through NumPy broadcasting.\n", + "The Gaussian/Logistic importance-sampling likelihood ratio is exactly the Jacobian of the map between their two Uniform parameterizations in one dimension. Deterministic transport and importance sampling are distinct constructions, but this Jacobian explains their mathematical connection.\n", "\n", - "4. The behavior change can be seen directly in the motivating example:\n", + "The numerical check below stays away from $0$ and $1$, compares a stable finite-difference derivative with the density ratio, and then uses one deterministic DigitalNet point set for a compact same-target integral check." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f6da6902", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-19T21:44:29.458107Z", + "iopub.status.busy": "2026-08-19T21:44:29.457910Z", + "iopub.status.idle": "2026-08-19T21:44:29.618284Z", + "shell.execute_reply": "2026-08-19T21:44:29.617387Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Maximum interior absolute error: 8.440e-05\n", + "Mean interior absolute error: 1.535e-05\n", + "All verification values finite: True\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAuQAAAHWCAYAAAA//pxeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAo7dJREFUeJzs3QV4k8cfB/BvUqWFlpYCRYq7u7v7cB/uDhtjbGyMscEYMtx1uLu7D3f3ooXSQku9zft/7vpPaKGFBprGvp/nCeTeJnkvd0n7y+V3dypFURQQEREREZFRqI1zWiIiIiIiEhiQExEREREZEQNyIiIiIiIjYkBORERERGREDMiJiIiIiIyIATkRERERkRExICciIiIiMiIG5ERERERERsSAnIiIiIjIiBiQE1mQhw8fQqVSYfHixbpjnTp1QvLkyQ32+L/99ps8FpMo9+vXD6bi0KFDsk7if2PKkiWL7A8ic6N9D61bt+6ztxWvcfFaJ6KEY0BOZCZEECz+IJ49e9bYVaFPOHHihPyQ8ubNG6tuJ7ZD3J49eyZfHxcvXkxQO/J9T2QdGJATWZDMmTMjJCQE3377bZKdc8SIEfKc9D4QHTVqVJwB+a1btzBv3jxYeztYe0Au2iWhAbk5Eq9x8VonooSz1eO2RGTixAi6o6Njkp7T1tZWXixVUFAQnJ2dE+WxHBwcEuVxLI1Go0F4eHiSv3aTUmRkpHye1sDOzs7YVSAyOxwhJ7IgceV4x0WMzqVOnRpVqlTBu3fv5LGnT5+iS5cuSJs2rQwc8+fPj4ULF372nHHlkGtt2rQJBQoU0D3erl27PrrNhQsXULduXbi4uMhc9+rVq+O///776Hb3799HixYt4O7uDicnJ5QpUwbbt2//6HZPnjxB48aNZRCdJk0aDB48GGFhYZ99HjGfy/Xr19G2bVu4ubmhQoUK8meXL1+WubHZsmWTgaOnp6dsr9evX8e6/9ChQ+X1rFmzyscSF9Ev8eWQJ/R5xWXRokWoVq2afJ6ijfPly4dZs2Z9dDuR5lS7dm14eHggWbJksm6i7p+zefNm1K9fH+nTp5ePnz17dowePRpRUVGfbcdPtYN2jsHy5cvl60I8tva1MWHCBJQrVw6pUqWSdS1evHicecvax/jcaywwMBCDBg2SbS9uI9qqZs2aOH/+vO424n0gHuPcuXPy3No2mj179kfnffnyJbp27SrfJ+J1ULhwYSxZsiTO96F4LpMnT5btJs49c+ZMlCxZUt6mc+fOunb53Pv1Qwl5LWqJ97Wor7YPxfPq3bu3/AD0Ja9B0fc//fSTPKd4jzVq1AiPHz/+bA55YvcrkaWx3GEtIorTmTNnZHBWokQJGXCJP44+Pj7yj7D2j6EI1nfu3Cn/kAcEBMiARl/Hjh3Dhg0b0KdPH6RIkQJTp05Fs2bN4O3tLf8oC9euXUPFihVlMP7DDz/IkbU5c+bIAOnw4cMoXbq0vJ2on/hjHhwcjAEDBsj7iyBIBAPij3qTJk3k7UTqjAjoxTnE7UQQsnTpUhw4cECvuovgJGfOnBgzZgwURZHH9u7dKwMXEUiJYETUfe7cufJ/8QFCtF3Tpk1x+/ZtrFy5Ev/8848MgAXRnnFJ6POKjwi+RbAibi++pdi6datsbzES27dvX10AWatWLVmHH3/8ESlTppQBo+ibzxGBoviQNGTIEPm/aMdff/1VvibGjx8f7/0S0g7isdasWSNfb+Ln2gBuypQp8vm0a9dOBo2rVq2S/bFt2zb54UDf11ivXr1kW4rziA8sImgV97tx4waKFSumeyx/f3/Uq1cPLVu2RJs2bWTdROBqb2+v+/AiXl/itXn37l35eCK4Xbt2rQxARWrOwIEDP/rAFBoaih49esjAUvSn+IAg2lAcE699QbwG9JGQ16I2PaZUqVKybuJ8efLkkQG6aA/xmhPPTd/X4J9//ikff9iwYfK1JT5w1KhRQ37IF79L4pPY/UpkcRQiMguLFi0SkaFy5syZeG/z4MEDeRtxW62OHTsqzs7O8vqxY8cUFxcXpX79+kpoaKjuNl27dlXSpUun+Pr6xnq81q1bK66urkpwcHC8jz9y5Eh5LCZRtre3V+7evas7dunSJXl82rRpumONGzeWt7t3757u2LNnz5QUKVIolSpV0h0bNGiQvO/Ro0d1xwIDA5WsWbMqWbJkUaKiouSxyZMny9utWbNGd7ugoCAlR44c8vjBgwc/2cba59KmTZuPfqZtg5hWrlwpb3/kyBHdsfHjx8tjoq0+lDlzZtkf+j6v+MRVp9q1ayvZsmXTlTdu3PjZ140+j9+zZ0/Fyckp1usnLp9qB3FcrVYr165d++w5w8PDlQIFCijVqlX7oteYeP327dv3k3WtXLmyvN/EiRN1x8LCwpQiRYooadKkkXWI+fpatmxZrPqVLVtWSZ48uRIQEBDrfSLeay9fvox1LtEPH76H9H3fJ/S12KFDB9nOcfW9RqPR6zUo3jvidhkyZNA9T0G818TxKVOm6I6J17h4rRuyX4ksDVNWiKzEwYMH5ci4GEEWo0/afGbxN3D9+vVo2LChvO7r66u7iNu/ffs21tf7CSVGzcRX9VqFChWSI+FiZE/71feePXtkeon46l0rXbp0Ml1EjJKJkVhhx44dcqRPmz4iiBFbMeonRntFion2duL+zZs3191OfAUvbqcPMar6oZijf2LUU7SP+FZB+JL20ed5xSdmnUQ/iTpVrlxZtrEoC2JEXBAjkREREXrVL+bji5Fd8fhiVFeMpt68eRNfQ9RTjFh/6pxi1Fo8D3HOuNr4c68x7fM/deqUHC3+FPENQ8+ePXVlMXosymIUWKSyaPtLjEiLEXQt8a2OGFkWqV/iW52YxKhufN+OfI2EvBbFtyQi7UO8r8W3YR/SjqLr+xrs0KGDHLXWEu818Z4Tj5PQOidGvxJZGgbkRFZA/NEWXwsXLVpUfhUvgg2tV69eya+0xVfeIniIeRFfiQsiKNFXpkyZPjomcrLFH2PteUVglzt37o9ulzdvXhlQaHNTHz16FO/ttD/X/p8jR46Pctrjuu+niFSED/n5+cmUBJE7LIIL0T7a22mDX30l9HnF5/jx4zJ4Ebm8IvAUdRL5vTHrJAJfERiKlT1Easg333wjUykSklcvUiBEyoKrq6sMiMTjt2/f/que86faWPvBQQSXIjda5DSLc4rUnLjO97nXmPD333/j6tWr8PLykoGnyG+PK7AT6U0fTt7NlSuX/F+b+y76Q6QyqdXqBPVXfM/xayXktSjeX+IDrcjDTszXoHj+MYn3mnjPadsoPondr0SWhjnkRFZAjIaL/FiRMy4mRzVo0ED3M+3KDyLQ6tixY5z3FyNU+rKxsYnzuDYn25TFlQsrcovFUn5ismKRIkXkKKJouzp16hhl9Yx79+7JbztEXvCkSZNkwCk+aImRSpG3ra2TdjMXkVsscsx3794tc6InTpwoj8W3aZT4kCaCeRGI//7773LEUgRTYkRT5A9/7XOOq42PHj0q84wrVaokJ0CKkVcxAi0+QKxYseKLXmOi38RI7MaNG+U3MiL3fdy4cfJbIjGZ2JA+lVP9NUzttfg5huhXIkvDgJzICoigTKxoIUZHxUQqMWFTTE4TxEiV+ApapJCI0dakIs4r0kniWq9YpEOIUUgRZGrXV4/vdtqfa/8Xo6HiD3fMUfKvXRNZjMzt379fjjKLCXlad+7c+ei28a04E5eEPq+4iOBajHJv2bIl1oiiSE2KixidFBcxKU8EQWJynZhY161bt3h3ZhQTIEXgKgIprQcPHiTouenTDloidUoE/eJDQ8wlIkXg9jVEACgmCIqL+LZHTOYU7RAzIBcpLR8ucSkmpgraCaeiP8QKJyLojTlKnpD++pp2+ZLXonh/iQ9T4v2QmK/BD88j3mtikuunPrQbql+JLAlTVoishBg9FcGVWHZN5JWePn1aNxolUhrEH824/niLr74NQZxXrP4hRu1jft0tVn0QAaPIaRUBhSBG90V9T548qbudCJ5Emo0IlrS5yOJ2IrCKuZyaSIsRt/vausY1QidWmPiQNqBLyIY4CX1eCa2T+Pr/wyBHBHAf1luMqgqfSluJ6/HF6hhihDMh9GmHmOcUAWvMZRXFa0PkQn8J8TgfpkSIZQ9FesqHz12sEy5W+In5XEVZBLZiiT5tf7148QKrV6+Odb9p06bJUWrxjYIh2uVLXoviA4OYnyE+uMW1u6/2/vq+Bv/99185n0BLvNeeP3/+yW8bErtfiSwRR8iJzIxYGzyuNXk/XHItvq/QRS6nWLta/AEVk9BEjulff/0lR1bFMoPdu3eXf4RFnqpIT9i3b5+8bgh//PGHXMJNBN9i9FJMrBNBkAiWRO6vlliuTyyhJ+osJtCJHFSxNJsYrRUfJLSjlaLu06dPlxPPxEQ8MTIqlj0UI/FfQ3wwEKPEok5iYmSGDBlk+kNco8Xa4O3nn39G69at5Vfz4gNQXJsLJfR5xUV8mBEfssRji8mHYlKh2CFRBJwiQNISjyeCaJELLtJORDAlbieekwjG4iOWwhN5uyKNSdRNBFSiLROaNqBPO2iJeQ4i/UakXoiJvWI0e8aMGTJHWYxM60s814wZM8qJh2K9cBE0i9ezWPpTpOzEJIJ0kcoiAkWROy6CbrGUnwhMtRvdiImO4vUpljkUry8RsIqAVOTyi4A45mTH+Ig+EPn+Yo1zcXvRHuJ9l9B8c31ei2LZTvEz8UFB1F3khYvXhliqUUyaFvXQ9zUofi7er2J+ifjwLJ636B/x3kuqfiWySMZe5oWIFL2WP4vv8vjx488ue6glljfMly+f4unpqdy5c0ce8/HxkcvDeXl5KXZ2dvJn1atXV+bOnau7nz7LHsa11NyHy/4J58+fl0v1iWXjxHJ6VatWVU6cOPHRfcXSiM2bN1dSpkypODo6KqVKlVK2bdv20e0ePXqkNGrUSD6Wh4eHMnDgQGXXrl16LXv46tWrj3725MkTpUmTJvL8Yim9Fi1ayCUaxe3F/WIaPXq0XB5OLDkXc+m/uJ5/Qp9XXLZs2aIUKlRI3k8sUTdu3Dhl4cKFsc4p2lcs45gpUybFwcFBLuPXoEED5ezZs599/OPHjytlypRRkiVLpqRPn1754YcflN27dyeoLT/VDvG9PoQFCxYoOXPmlHXNkyePfK196WtMLF04dOhQpXDhwnIpTfE+ENdnzpz50bKH+fPnl20iljAU7SkeZ/r06R89vnifdO7cWb62xPJ8BQsW/GgJQ+37RCz9GJfNmzfL95+tre1nl0DU9qfoxy95LYr3g1j+MHXq1LJNxZKYot1E2+jzGtQueyiWVxw+fLh8HYnXhVhCVZwjpriWPUzMfiWyRCrxj7E/FBARERmLmE8hlg78XL61MYhNccS3XyJPO+ZSgERkWZhDTkREZKJEeo1Ia0nIhFEiMl/MISciIjIxIn9brHQjVkcSK+GI+RVEZLn4DiciIjIx33//vZyU2rVrV7muPBFZNuaQExEREREZEXPIiYiIiIiMiAE5EREREZERWV0OudjyWOzkJzZk+NotjImIiIiI4iJWFhdzQcTGY5/a6M0qA3IRjHt5eRm7GkRERERkBR4/fix3Df4UqwvItVsbi8YRWxAbghiF9/f3l9tOf+4TEZk/9rd1YX9bF/a3dWF/WxeNgeO1gIAAOQisjT0/xeoCcm2aigjGDRmQR0ZGysdnQG752N/Whf1tXdjf1oX9bV00SRSvJSRFmsO3RERERERGxICciIiIiMiIGJATERERERmR1eWQExERUeKJiopCRESExeQUi+cSGhrKOWBWQPOV/W1nZwcbG5tEqQsDciIiIvqiNZZfvHiBN2/eWNRz0q68wb1KLJ+SCP2dMmVKeHp6fvXrhQE5ERER6U0bjKdJkwZOTk4WEcCKAE2sumFra2sRz4cM19/ivsHBwXj58qUsp0uXDl+DATkRERHpnaaiDcZTpUplMa3HgNy6KF/5ASxZsmTyfxGUi/fC16SvcFInERER6UWbMy5GxomsmdP/3wNfO4+CATkRERF9EaZ1kLVTJVJqk1ED8iNHjqBhw4ZInz69fEKbNm367H3CwsLw888/I3PmzHBwcECWLFmwcOHCJKkvEREREVFiM2oOeVBQEAoXLowuXbqgadOmCbpPy5Yt4ePjgwULFiBHjhx4/vy5nCFLRERERGSOjBqQ161bV14SateuXTh8+DDu378Pd3d3eUyMkBMRERFZsipVqqBIkSKYPHmyST3eiBEjkDZtWvTv31+WX79+jbx58+L06dMJjtFat26NkiVL4rvvvoO1Mqsc8i1btqBEiRL4+++/kSFDBuTKlQvff/89QkJCjF01IiKLWnkgPFKDgNAIvAwMxcuAULwKDMPrd2F4ExyOtyERCAyNkLchMjedOnWSabJ//fVXrOMibfZLNodJKhs2bMDo0aOT7Hy7d++W7fSpy549e7Bx40ZUrlxZd78///wT33zzjV4DpiNGjJD3e/v2LayVWS17KEbGjx07BkdHR/kC8PX1RZ8+feSnsUWLFsWbcy4uWgEBAfJ/keZiqFQX8bjaxebJ8rG/rYs59ndoRBSevQnBE/8QPHsbitdB4bB7dR2qwGdQBb+GOtQf9uH+sI8Khq0mTF4cEA5HhGNbVFms11TSPZYaGiy0Gw8NVAiDHUJUyRCudkK4rTMi7ZyhsU2OKIeUUKdIiwiPfEjhngZpUjjIS1oXR/m/Wm0+6zubY38nZbtoL+ZGxBHjxo1Djx494ObmJo99+DxM6XmFh4fHW8+v8an+q1ixIp49e6YrFyxYEL1795ZxV8zlLz08POTPtOtyi5RikdGgTz3z58+P7NmzY+nSpejbty+M4UvbVduGccWV+vzeMKuAXDwx8Yls+fLlcHV1lccmTZqE5s2bY+bMmbr1IGMaO3YsRo0a9dFxsSuTWHvSUPUMDAyUHWTKn7YpcbC/rYup9ndElAbe/qF4+CoQfs/uI8r3DuzePUXykOd4HuGE6VFNYt1+o/3vKKq++/EDiVg5xlK6N5VMQIy/KSIgr2Jz6eP7iV+n2l+pgQB8gW63vsM+TXHdTTKpfDDQbjPeOGZAaPJMULllgWOabEiXOhVyeDjBzckOpsZU+9vYxBJvom3E31FD/S01FFHvatWq4d69e3JUVjtSLoLLmP/nzJlTpmEMGDBAd1/xLX2jRo3w66+/ynKNGjVQoEABuf60CCbt7e1lzCFSMAYOHChHtUU6xz///IM6derozj9+/HgZuIrNlcR5fvrpJzRr1kx3HvG4IkgV62OvWLFCnkO8BsW8u4kTJ+oeR8RA4nEeP34sz9OtWzcMHz5cN8ItYqBr167J+pUpU0beVwS+MQPJ+PpPbAsvgm3h6dOncvCzXLlyumPCv//+i169eukeY+vWrXLBDdFOMR9X1KVVq1bw8/PTvY+uXr2KYsWKyaDfw8MD9erVw6pVq9CzZ08kJW1/fynxPEVfiNF98YEkJvG7wyIDcrELkkhV0QbjgshTEi+oJ0+eyBf1h8QLc8iQIbFGyL28vOQnTRcXF4N+cBDn4C9wy8f+ti6m0N8iXeTq0wDcvn8X4Q9Ow97/NlIF30dO1RM0Vj2Hgyr2erh3bDJ8FJD7KSkSdC4xSh6TGgkfRXqlvP9dLeRVeaOZ+hDkQ/r9/3JP3M4FNzSZccouK4Lc8sImfSGkzloY+dK7IquHs1FH1E2hv01RaGioHNgSAaO4mBPRjyLYHDNmDNq1a4dBgwYhY8aMuk1dxP/a5yRuG/P5iddCzGOiLALxoUOH4tSpU1i9ejX69esnU2wbN24sV4UTwXjnzp3x6NEjuWa1+BAgBhZnzZol4xax4pxIoxHbr2tTP7SPK4JdkRkgiOviuPbcw4YNw/z582VQXqFCBbnIxc2bN3U/F30k4p9ChQrh3bt3GDlypFwY48KFC/I5aNNOEtJ/V65ckf+LPO+Yt/f29pbpJtpjJ06cQPHixT96zMuXL8sPFeIDi5YIyMUqe+J5C+IDg/hwJAJkEdQnpa95DYv7ivYUsan45uVLH9es3kXly5fH2rVr5QsrefLk8tjt27dlQ4g3U1xEp8bVseI+hvzlqn3T8he4dWB/W5ek7G8x4HDb5x0u3nmIc8/DceHJO9x99Q7i29UeNlvxk93K6Bt+YoO4DCpf8Uj/H/6OdsCmPJ7Y5UaEoxuiHFNB5ewOtaML1PbJYGPvBBs7R9g6OCG5Y3KMt3WQ54v6/9eyqyKOiWElRIYFIzIkABGhgVBCA6CEBQJhgbAJfQPH0Jd4pkobfdr/y6x6EWf9UqsCkNrmCqC5Arzegne+jih4Zj4UqOGazA7FMqVEGa9kKJw1HQp7uSGZ/Zfvhvcl+P7+WMyATrsOs5hzcOtFwkcEE1NuzxRwcdTvGxaxupuY1Pjbb7/JUea41pOO+fziOyZGrX/55Rd5XYx0i1QYMeIr0mEEEQjPnj1bBrVFixaVo9b79u1D2bJl5c/FiPXx48cxd+5cOdFSSwTrYiQ9rnOLkdepU6di+vTpMpgXxMpzIs1ES2QPxCSWiE6dOjVu3Lghg+P4nl9cRBAvBjNjjo4LH2YgiABdu5R1TJcuXZLtFPO4CNJjHsuQIYNMzREr6YmlrZM6TeVL1xPXtmFcfxP0+Rth1IBcBNZ3777/yvTBgwe4ePGiXEElU6ZMcnRbfE0ivhIR2rZtKyc0iE+a4kUgcsjFp1KxbGJc6SpEROZG/IF4+DoYZ24+wOvrh+D6/ASKRl1BK7U3VoT9jjtKDt1tL2neXxciFTUeKOlwV8kAH8esCE+RGXDLBAePLJjimRUZ3Z2QIaUTPJLbw9amvsGfSxuNAv/gcLwMCJOTQ1/4ZsP8Z3UR5XsXdm8fIkXwY3jhhRzZT6UKjJUmI4JxQUwgPXjrFdrcn4jMRx/ggCYXnrkUhjp7FeQtVBLFs7jDwTZpA3SKmwjGW8w+aZTmWdurLEpmiV59TR8ieBbpK2KBiC8lRqC1xOh6qlSpZE61lkgl0W6vLmIekdZQs2bNWI8hAlERrMckRprjI4JqMT+uevXq8d7mzp07MrVGjNyLeEmbzyyCZm1AnlDnz5+X6SWfIxbZ+HCUWBvQx0z9EUS8J1JbtJL9P477MO3DWhg1ID979iyqVq2qK2tTSzp27IjFixfLr1/EC0dLjIrv3btX5nSJThQvevH1yx9//GGU+hMRJYagsEgcu/UcD8/vQ7LHh1Eo4hKaqR7ARvX/0Zv/D7IUVt/Dpaj3QfgVJSuW2DRDqHte2KbLh1SZ8yKHZypUTZMcjnbGD1Jt1Cp4JHeQl3xwAXKnEYkrsT58+ASE4bpPAB4+uo9g74uwfXkNt4M+/IOuoJj6DjxUAahv8x8Q9B9weQ5eXHLDDhSCT+oKcMlfA6Xy50L21M7cPZISrFKlSqhdu7YcANSONMcc3fxwol9c26OL9JeYxGhpzGPakVcREIuBSGH79u1yRDimD7/Nd3Z2jrfeCRmEFBsvipHmefPmyVFrcX4RiIvgX18iIBf56Z8jRtBFKtOHe86IfH0xGq4l6iKC9K5du+qO+fmJHDbIUXxrZNSAXHw186lZrSIo/1CePHlkUE5EZM7Eqif7b77Evus+qPdwLOqq/kNt1f9Hhj74llOjqHBNyYwouxSolD01imR0RWGvlCiUMSVSp3g/EczciEDF09VRXirmEsF6Gd2qMN++fIdLT97g3EN/3Hj4BDffeclJqM6q96tmear80QSHAd/D0Bwag6sHs2CwUxekLVQTtQt4okjGlGa1ogsZh8hbFqkruXPnjnVcBIZiYDDmHDTxTf7XyJcvnwy8xWBjzKUC9SXSWURQvn///jgDZTEB89atWzIY16axaHPR9SVG18Wk0YSMkItR/mXLlsU6JtpMBOAifos5yVPUMWaQfvXqVZl+/GFajLUwqxxyIiJzD8J3nb+Ljdfe4srT9+vttrJ7Bxd17K9pb2q8cF5dAG89y8E9XxUUz5MVf6RObhWjv2J0v0AGV3lpV1rkkhbBy8AaOPbgFbxvngUeHkPOwDMorb6BZKro0T61SkEh1QPceavGpiP3MefIfaR1cUD9vG6oXsALpbN5wNaGkzINncctUkeMde4vJdJLxOROkZMdk0hlEQODYqQ5ZcqUMv1DO/HzS6VIkUKmxwwePFgGqWIyplidQ+SQi4UmRIZAQoi0EDGp84cffpATJcUcu1evXskVVcSos5iELLIIRF66WBBDfAD48ccfv6jOYnRcSEhArv22QYySa5dpFPUQv7fOnDkjV1L577//5MRX8RzEfjJaR48eRa1atWCtGJATERmQ2Exn3/lbeHN2HQr670UTtTf+CpshvujW3WZ/VDGUV1/FEaUInqapjOR5a6BY3lxo7ZmCI7z/lyaFI2oX8gLEBU3gK9r11lM8vXQIzk8OoXjkRaRAMK4p7zcjEekwdmfnIdvF3VitLoegPM1RrnxV5M/gahUfbJKamFT5JXncpuD333+XK6TEJAJLMbrboEEDuYKGmMP2tSPkgngcMfouJneK/VVEsC+CXTEhVB9iIqlYxUN8UBBLB4rAW6zEok23EUsIirxtkaYiRv/FB46Yk0YTSqSWiDx4kfaSkA834rmsWbNGt3yhqJd4zu3bt5cfSESqcosWLeTovvYDTmhoqNyYSaxfbq1UiimtfJ8ExFdO4o0lPpEactlDkQslJqdylRXLx/62Lgnpb7Em+IGrj3Hv6GrkfrkTFVWXYK96v9Zt9/Ah2KuJnswkJljWzJUSVfN6onyudHB24DjJl65Ec/jaQ2y/GYBLj9/ofrbR/tdY662Lbx6OOlWHY7HWqFm6qEyX+dr+tkYigBLBadasWeOcxGeutOtyi0CXH9q+jMiPFwtuiBSUhL5nZs2aJTd8FDt/mlt/f+q9oE/Myd/8RESJ5IFvEPYePgznq8tRV3MItVXvPsoHf6BJi7TOavQslg218zPPOTGIP6QiZSG3Z0H0qB6dGrTn2gvsvfoEfk9SIEyxhYMqepOSPOrHyBO6GJrjS3D8WAFsSN0AOSu3RdX8GZnSQpQI6tevL1d4EavkiaUSE8LOzg7Tpk2z6vbnCLkBcETFurC/rbu/wyM12Hn1OVac8kbnJ7+gjs2Zj+7zXHHHfnV5BOX6BiXKVkOxzO4cfUvilCH/M6tQ4u1elFDf/ug2vooLRtp/jzxl6qFVKS+ZHqPF93fcOEJOlkDhCDkRkXnzCwrHqjOP8e/JR3gZGL3yR1Xb6PWGhTDFDnuUUnictTkKlq+P1tlTcwTWCFIld0CrSoWASoXwwPdnLDwhlkxcjRrhB5BJ/UrexgVBOBWYGtv33saU/XfkCi0dymRGqazmmQ9NROaHKStERHq4+/IddmzfjuyPVmFBeAf4i/W1/291VFVUVl/CYee6cCvTHnVK5ZM7TZJpyOrhjKyNqkNpWA1nH/ph26GtyPJgJUIUO/jCVd4mUqNg++XnSHltKc6ndETm6t1QPKNh5hsREWkxICciSoDT917hzM7FKPdyFQaJSYJq4KZNRsyIaix/7mxvg7JFSyOi5DH05CoeJp9zXjJrKpTM2gn+QW2x7uxjZDntLXdIFRwRhu9s18A96B18Ny/DJru6SFGhN74pX8gkNlwiIsvDgJyI6BP5hcdv++DSjrmo478CfdXPY03SrGdzCltcWqNT+WxoWSIjUjhyNNzcuDnbo3vl7OhaMRuO3/PF0pOPoL61De5iQq5YBUcVgG6RqxF8cBM2Ha6G0BK90LR6ebnEHxFRYmFATkQURyB+6PoT3Ng1Fw3erkQFkWscIxC/ocmEAymbI2f1jjhUMLPcIp7Mm9jRs2LO1PLi/TofZu0pBK8b81BH9R9sVRo4qcLQWtmJiNN7sOVMZQSWHIxm1cvyQxgRJQoG5EREMQPxW6+weec2DH3zB6qqXscKxE9q8uGsVxcUKVMTvfNn4rrUFipTKif0btMUfkEN8O+B43A8NweNlQMyKLdTRaEZDiD89GGsPFMPQVV+Q8eyWbh+PBF9FQbkRERie2hvf/y18yZOP/CDC5Ljd4f3W9kf0RTC5Ww9UK9+E/RN5SSXPSTL5+5sj071K+NZiXzYeusZgo7NQvOILXBRhciNnoIjgb933cL8ow/Qs1I2dCyXhTnmRPRFGJATkVW76xOAhdsPY8Xt90PhAXDG4qjayK/2xs1cPdGwbiNUSuWkW5earIuYyNmiUmFEVpiNLaf6492BKagbuRdzI+vrlsAcu/MmVh6/he9qZEP9ErllCgwRUUIxICciq+QTEIq1mzaixN0p+FH1EDswGW+QQv7MVq3Cy2JD0LxaLlRPmczYVSUTYW+rRvPyBRFWeg7Wnn4Ah0OPgIBQ3c/rB21E2e27MOtwexRrPAhlc75fl56I6FMYkBORVQmLjMLqfafgfvIP9FMd1+WI97XdjD8j26Nh4fT4rmYuZPFwNnZVyUQ52NqgfbkcaF4yK1afeYxpB+4C716it+0WJFeFom/QTNxdugnT0vVG3aadkSNt9Ac9IqL4xJiuRERk2Q5d88bScf3R/GRjNBDB+P/d13giKG0JbOtfAdPaFGUwTglOZRF544eHVkGPCplxRCmq+1kO9TP09/kFr2bUwqw1WxEYGsFWpc9q0qQJ3Nzc0Lx5c7aWlbURA3Iisnj3XgZi6ox/kG11NXSLWC5XyxD8lOSY4dwHL9ofwqD+36FAhujdGon04exgix4NyqP495swI9tsnNXk0v2srPo6ul/rgM1/d8H2M7flSj5E8Rk4cCD+/fdfNpAVthEDciKyWKERUZi9+SCeT6+LAa9+QyaxnrjYHl1RY6WqHg7V3oXe341BuVzpjF1VsgBpXRzRt0MbOPfahympfsEjTRp5XKxj3l6zBcW31cLkqRNw92WgsatKX+n169dIkyYNHj58mKhtWaVKFaRIkSJRz9m6dWtMnDjxs8fMpZ2qfKKNvvScbdq0MVobaTEgJyKLdPyuL2pPPoJ5J58jv+qB7vgJTX7ML/Av6v3wL5qWK8jVMCjR5U3vioH9v8eDVvuxwK41QpXoXT09Vf5weHUZdSYfxdidNxAcHsnWN1N//vknvvnmG2TJkiXW8cqVK0OlUsW62NjY4N27dwY75+eMGDFC3vft27efPKbVuXNn+fPEEFedDdlGX9pOP//8s15tZAgMyInIovgHheO7NZfQbv4pPHodjNdwxZ+R7fBE8cDkVL8idZ9d6NWiIVyTcetzMqwq+TOh3Q8zsbzEGhzUFJWvwWmRjRGpUTDn8H0ZmJ+468tuMDPBwcFYsGABunbtGuu4SEe6cOECJkyYgOfPn8e6JE+eXN6mSJEiKFCgwEeXZ8+efdE5E0I8fvbs2bFs2bJPHhOioqKwbds2NGrUSO/zJKTOhmyjr2knfdrIUBiQE5FFEL/ot52+ia0TuuDA+euxfnYkWU1ca7IPA/sNQU5PF6PVkaxz4mfXhtWQtf82jMs4EyFw1P3M2y8YqxdOxLRlaxHASZ9J5sWLF3JUdsqUKShatCgcHR2RP39+HDt2LEH337FjBxwcHFCmTJlYx+/cuYPAwEBUqlQJnp6euotIn9C6ePEirl69+tElffr0X3TOXbt2wdnZOdb+COLxxPPz9X3/Ya9hw4ZYtWpVrPvGdezEiROws7NDyZIlv7qt4qqzIdsovnMmdhsZCgNyIrKINcWnzJyGEtvroIOyFSPs3o9otC+TCfu+r4LaRbLKX8BExpAldXJM7VYLs9sXRzrX6KA8i+o5xtnNQ+87PbBpfHccvvaYnZMERMAnLFy4EJMnT5blTJkyoV27dgna+Ovo0aMoXrz4R8fPnTsHW1tbFCpUKNHrHN85xWizGMlVq9+Hc+L5iODVw8NDd6xUqVI4ffo0wsLCPnlsy5YtMgjV/q78mraKq86GbKP4zpnYbWQoDMiJyKztOHsbxye1waBXv8gcXaGu+gzKeIRiXa+y+KNxQbg4Mj2FjE8EOXUKeGLP4EpoWzoTutvsgKMqQk767BC1ERlX18TURUvxJjjc2FW1aJcuXZKjwJs3b5b5zHny5MEff/wBb29vPH369LP3f/ToUZyjtefPn5cpH6lSpZLpF+JSvnx5vepWo0YNtGjRQo70ZsyYESdPnvzkOUVgWbhw4Y+e34fHxH3Dw8PliPenjok2iZmu8jVtFVedDdlG8Z0zsdvIULgxEBGZba74kpXL0Pzxn8ioev+14xFNYdwtNRpL6lSQG7gQmZoUjnYY06QgThaYgXlrRqND+Go4qCKRXf0c/R72x/IJe5Gt5ViUz5MBZunEdODkjM/fLl1hoO0H6QArWgPPL33+vmX7AuX6fVH1RIDWtGnTWJP+XFxip7Jt2rQJ48ePlyOj4lKzZk1ZFqO7ISEhMnXjQyLYFKt1jBo1SndMpEroY9++fXEej++cYvR3wIABHz2/EiVKxDqWLFkyXY51fMdu3Lgh87SrV6+uV1tNmjRJpn6MGTPms3U2ZBvFd87EbCND4gg5EZkd8dX+joldMODxEF0w/k5xxFTn/kjXZxu6NKjMYJxMXtmc6dBu6FQsKrAEFzXZ5TG1SsG3ms1IuaIuZq/dLpfuNDthgUDgs89fguOY0CqOJeS+4hxfSARjYuJgTGKUVaQvZMiQAUuXLsW4ceOwbt06mWJx5swZ+e2GCMYFcTt//+hv4z4MNitWrIgcOXLoLunSpYsVuP70009fVOe4zhkUFIR79+7FGukVaSQiAP1w9NfPz0/+nzp16niPiXQV8cEjZkD7ubbS5mOLlJCE1NmQbRTXORO7jQyJATkRmY2Q8ChMX74O6VfXRjvNVhm8CKc0ebC6xCr0HvI7J22SWXGyt0WvFg0Q1XkP5jh0RJgSHfTlVz9Cp6sdsWDScNx6HgCz4pACSJH+8xen9/m7OuJYQu4rzvEFxAiqmFgo0iZiBmgiP7pjx45ywuGPP/6IlStX6lIfxCipCBS1xOTG69djTxy/f/8+3rx5I38Wn/gC14SI65wPHjyQdRdpJFq7d++W63B/GGyKc4v0jpg50x8eE2kpYrnAhLaVNic7vuf1YZ0N3UZxnTOx28igFCvz9u1b8Rdc/m8oUVFRyqtXr+T/ZPnY30nj1osApeakQ8qvP/VXlJEu8hL6aypl5phByiXv10lUC/a3tUnK93dwWKQyfcUG5dYveXWv8Se/ZlWK/LxOWXD0vhIVpVFMRUhIiHL9+nX5vzk5deqUYmtrq+TJk0c5ceKEfA7NmzdXsmbNqvj7+ytLly5VGjRooGg08bf15cuX5WP4+fnpjq1Zs0axsbFRgoOD471fyZIllUuXLn1RveM657NnzxSVSqVs375dlk+ePKlky5ZNcXR0VCIjI2Pdv2PHjkqXLl3iPebj46PY2dnJ13pC20oQ7ZQyZUolLCzss3U2dBvFdc7PtZGof3h4uPz/c230Je8FfWJOjpATkckvZ7jqtDcaTT+G2z7vsCSqFvZEFccVTRYsLLAEnb+fgEJe7sauJtFXS2Zvg75tmuBZy51YpaqLKEWF7yJ6wz/SEb9vu44uS87AL4gTPr+GSMEQo6UiLaJZs2Yyj1iMAB8+fBgpU6aUo6tiWT+tVq1aIW/evOjUqZPuWMGCBVGsWDGsWbMmViqGeFxtznFcv8fEaHPMkVp9xHVOkeoxevRotG/fHpkzZ8bs2bPlZEcxwiw22tEKDQ2VOfHdu3eP99jWrVvliiIxR4I/11baEWhRD3t7+8/W2dBtFNc5E7ONDE0lonJYkYCAALi6usqdlz6cmJBYxNcjIu/I3d091jI7ZJnY34YTGBqB8Wv249/rsfNosyaPwpiWJVA21+fXpU1s7G/rYqz+fhUYhomrdmDVvdiBTnYXDf5uUwbFsxo+p/VTRLAigrGsWbPGOdnQVPXt21fmGK9YsSLOn4vgTUzgExMUtUv/TZ06VU5a/P3333W32759O4YOHSpTGhLyuhDpGg0aNPgo7UQf+p5Ta9asWdi4cSP27NkT7zGxskqFChXwww8/JLittHnnIud+7dq1X13n+4nQRvqeU4TAkZGRmDdvngy+P9VGX/Je0CfmZLRIRCbpsvdrrJ7YH7/ca4uK6su641Vyp8a6QbWNEowTJZXUKRwwtltjjG5cAI520X+qVdBgRMh4RC1qgBX7/pPBBOlHjPp+ag3s2rVry8mcr169kmURrB05cuSjvOf69eujR48eCVomURDBYcyR9y+h7zm1xLKF06ZN++QxEYyL1U/0aauE5HzrU+eridBG+p5TnzYyNI6QGwBH0KwL+zvxrT92CZ57+qK8+oosv1JcUD/ib3SrUwrdKmSDWm28DX7Y39bFFPr71otA9Fl+DrX9VuAHu9XymK/igqXpRqBLxy5wTZb06+yb4wi5+AAjRivFzov16tWL9zbz58+XO1OKNAxxqVKlikzb+Jpv1cWIe0REBEaOHAlLaSuhbdu2cgRZu+292OEzvtFyU2wj5f8j5GIFnS/dOC6xRsgZkFvoL3BKOuzvxBMWGYW5qzagyZ0fdcsZijzaxfatULz9GBTJnArGxv62LqbS30FhkZi7fCVaPfoV6VXRS7FpFBUW2bdCqW/HomCmpJ1HYY4BeVIFaIYOXC1VWyO0kSkF5NwYiIhMwrM3IViz4G/0DpgGB1WEbmR8aYbf0K1DB+62SVbN2cEWgzq3x4ZjhZB6b39UUl+Sy352jViFw/NvYluDWWhQKp+xq0nx+FQeNrGNBKMO34q8rIYNG8q1PsUnE5FQn1DHjx+Xn2g+XLCeiMzPf7ef49iUjhgUOEkXjJ/X5MDuCmswuHsXBuNE4ittlQrNKhaGe4/NmGfXTn57JFRWX0S+bU0wZ/1ORGmYV05kjowakIsdlMTC7DNmJGCL3RjEwvIdOnSItb0rEZkf8XWhmJxmv6whWiq7dcfXqmohrN0WtK9ZNlG/NiayBAUyuqHVd1MwOf14+CnRX+9nU79Am8udMXnmVLwNjv5QS0Tmw6gBed26dfHHH3+gSZMmet2vV69eMteobNmyBqsbERlWeKQGw9ZfxoL9l5FL9VgeC1PsMCX5IJQb+C/K5o7elpmIPubiaIfB3bthU8kVuKHJFH1MFYLcPjvwzYxjuOPz5VvLE1HSM7sc8kWLFsm1KpctWyaD+c8JCwuTl5gJ9tqJOuJiCOJxxcifoR6fTAv7W39vgsPRZ/kF/PdATE7LgO8jemGE3TKsyz4WPVs1gYOdjcm+f9jf1sXU+7tTvYrYn3ETHm3sg8zKMwyN6IGQ18FoPOM4/mlVGDXypjVou2gvlshSnxclbn9r3wNxxZX6/N4wq4Bc7OD0448/4ujRozJ/PCHGjh2LUaNGfXRcLHYvZtYaguiAwMBA2UFcZcXysb/18+h1ML7beBMP37z/Wn2vUgrFy32DdsW8EBT4FkEwXexv62IO/V00oyvutZ6LIZvOIyQ8eiOhoPAo9Fx6HoMqe6FtiXSJnvollqcTbSP+jhrqb6mxiN0oyXpEfWV/i9e/eC+IlVTEplIxid8dFheQiwYTaSoiuM6VK1eC7zd8+HAMGTIk1gi5l5cX3NzcDLpTp/jlJ85hqr/AKfGwvxPu5O1neL2qLzpFOuI3RG9F7eJoi+lti6JCjvdbNpsy9rd1MZf+FssyLu+fFgNWXcSxu6/lsXTwReWTv2D1m5Ho2aIBbBJx/X6x1JsY2BLbjyd0gMycWOJzIsP0t3gPiN8NYnnDD5c91OdxzeYVJz5lnD17FhcuXEC/fv1ifWUmnrBYu7JatWof3c/BwUFePiQaz5C/XMUvcEOfg0wH+/vzNhy7BK893dFIfUv+5rmvpMPhlE2woGNJ5EgTPTHNXLC/rYu59Ld7ckcs7lwKf+64gXXHr2OR/d/IrX6C7Dd7Ytr839CrSzc42SfOn33xd1W0S0hICJycnGCJaQucUG75lETob/EeEPcV74kPf0fo8zvDbAJyMZp95Ur0rn1aM2fOxIEDB+Q2t2JBdiIyzV94CzbvQ83zfZBZ/VIeC1Hs4Zo6IzZ1Lw835+iv2Ino69naqDGyYX7kTh6KsIPR760UqhD0f/4TZk15itY9f0Yal6/fyEeMCqZMmRIvX0a/p0VQbgkBrKE2BiLL629FUWSKingPiPeCeE98DaMG5O/evcPdu3d1ZbHT0cWLF+VXb5kyZZLpJk+fPsW///4rP2UUKFAg1v3TpEkjvx748DgRmYbIKA1mrliLtne/h4c6ekL1SyUlVmYfh/5tW8Le1rRHHInMVeuqxbE/1QbsW98NNVRnYaeKwoCgqVg85RnKdf8HuTy/PmXT09NT/q8Nyi2BdnKeiDkYkFs+JRH6WwTj2veC2QbkIgWlatWqurI217tjx45YvHgxnj9/Dm9vbyPWkIi+VHB4JGYtmIteL36Dsyp6paObGi+cKjsbA+qU5x87IgOrXigrrqRcixWL+6OtZps81ilqHbbNfoG37RegZI6vCyJEAJMuXTo5OCYmeVoC7eQ8kQ9s6ilKZPz+trOz++qRcS2VYmXr+ohJnaLhRQcYclKnn5+fHOnnG9rysb8/5hcUjn9n/4W+AZPlyJxwWpMHPvUWomGZ/DBn7G/rYgn9/cQ/GFvm/IpeIfOhVkX/yT+iKYyoFktQtSDTPS2tv8l0+lufmJOvNiJKVI/9gjFv2mgMCpyoC8b3KKUQ2nqd2QfjROYoo5sT2g0ci39S/YpQxU4eq6S+BNe1LbDx9D1jV4+IGJATUWK69SIQzWadwPo3ufFEiV7GcK2qNtJ2WYVK+bzY2ERG4prMDv36DMSMjH8jQEkmj53S5MHgDTex4NgD9guRkZnNKitEZNquPHmLbxeewptgkUvqho7hw9As+RXU7TEWWVOb17KGRJbIwdYGg7p2xoyVKWF/Yz3GRbaWx0dvuy53zx1SMxfndhAZCVNWiOirnbvvg87zjvw/GI/mmC4vmg8Yz2CcyISIzYH6t22CwIq/iGlkuuPTDtzFbxvOQaOxqmllRCaDATkRfZUTt57izZK2GK8ZDztEb6FdMosbVvUogzQpvn69YyJKXGJ1lKG182BE/by6Y8VVt9D7cnNMXboKUQzKiZIcA3Ii+mKHrj6EZnkrVFedRVWbSxhvNxsVc3pgSZdSSOEYPXmMiExTt4rZMLFFYeRSP8NC+/HwVPmj6/3BmLp4mdxDgIiSDgNyIvoiu8/dgdOaVqigjt5BN1hxwN0MTTCvQ4lE256biAyrWfGMGNaqOq4rWXS7enZ/9D2mLlqMCAblREmGATkR6W376RtIu7kVSqlvyrJYtWF2pvEY2L0bHO0SZ5MEIkoa1QtnQ1jLlTimKSjLyVWh6PX4R0ydvwDhkRwpJ0oKDMiJSC87zt5Cxm1tUUQdvX6xv5IcC7NPxcDOHWBnw18pROaoSoEs0LRZhcOaIrLspApD32fDMW3eHIRGRO8nQESGw7+eRKRXmornlnYorL4vy76KC1bknYkB7VvI1RuIyHxVypsRdu1W4IBSXJYdVRHo92IEZsydyaCcyMAYkBNRguw5fwcem9uimPqOLL9WUmB13hno06oR1AzGiSxCudwZ4Nx+udxdV3BQRaLfy98wY95spq8QGRADciL6rF1XX+CHdZegXaHYT0mOFXmmoU+rhtxIhMjClM6ZDqk6LsMupawuKH/19D76rzzPiZ5EBsKAnIg+ae91H/RbcR5vNMnk7pt7oopjWa5p6NuqMYNxIgtVPFtapO60FDuUsvguvBdWRVXD7ms+GLLmEtcpJzIABuREFK+DN1+iz/JziPz/RiFBSIb9hSejX5smTFMhsnDFs6aGe4dl2G5TRXds66VnGLb+Mnf0JEpkDMiJKE6n7zzH3RVD4BwVoDvWvHhGjG1akME4kZUok90Dc78tAfsYKygFXViPmas3QlG0SWxE9LUYkBPRR64+9oPvsi7ort6K1fajkQb+aFo0A8Y1K8RgnMjKVMqVGjPbFYOtWoWm6iOYbjcVrW8OxOx1OxiUEyUSBuREFMu9l4G4ubAn6qlOyHJmlQ9aZIvE380LcWlDIitVI19aTG1dCG1tD8BGpcBDFYCmV/tg0fZDxq4akUVgQE5EOk/fhODYnAForuyR5QjFBjNS/4IBXb6FLTf9IbJq9QplhE+Df3FFk0WW06reoOrpnlh7+Lyxq0Zk9hiQE5Hk+y4M22YOQ8eoDbKsUVSY5joEvbr3hYOtDVuJiFC/VF7cqbUUdzQZZGtkVfsgz/7OctMwIvpyDMiJCAGhEVgx83f0DF+ia40ZTr3QtdcwODvYsoWISKdphUI4UXYuninuslxQ/RAumzvgxK2nbCWiL8SAnMjKhUVGYd7syegXNEN3bJ5dO7Tq8xtcneyMWjciMk0d6pTHpvwz4K8kl+Wy6ut4t6Izrnj7GbtqRGaJATmRFdNoFPyzdD36+Y+DWhW9hNkydSPU6TUeaVI4Grt6RGSiVCoVejWvi8VZxiFYcZDHaqlO4dqiPnjgG2Ts6hGZHQbkRFZs3K6bmH/LAds0ZWR5MyqjVI8Z8ErlbOyqEZGJU6tV6PttW8xMM1JOAH+nOGJLWFF8u+AUfAJCjV09IrPCgJzISi0+/gBzjtxHJGzxXUQvDIvshfTfzkMuTxdjV42IzIS9rRp9uvfEZJehaB0+Aic0BfDEPwRdFp9BUFiksatHZDYYkBNZoV1XX2DUtusxjqhQqeUglMye1oi1IiJz5GRvi269vkNo6kK6Y9eeBaD/yguIjNIYtW5E5oIBOZGVOffABwFreiM7nuiOjaifF/ULpTNqvYjIfLk522NJl1JInSI6nxxQkPXOIsxes4W7eRIlAANyIivbhfPRkl5oqT6A9fa/oZTqBrqUz4puFbMZu2pEZOYypEyGhR1LIrkd8KftQvxitxxNbw7Gyv2njF01IpPHgJzISvgHhePAvGFoigOy7IhwlM3mLkfHiYgSQ8GMrpjaIj/yqx/KcnqVHwod6Ym9F++xgYk+gQE5kRUIj9Rg4bzJ6B6xXHdsRsqh6N2po1wpgYgosVQrlAW3qs7DY01qWS6gfgi7jV1x8ZEvG5koHgzIiSycoiiYtXId+viP1x2bY9cBnXsMgaOdjVHrRkSWqVXV4thWcCreKk6yXEV1AbcX98Hj11yjnCguDMiJLNyKfafQ6u4PSKYK1601XqP7GDkJi4jIUHo0q4v5GX5HuBL9wb+lshtb543EOy6HSPQRBuREFuzglYcoeLQXPFX+snxWkxserWche5oUxq4aEVk4G7UKfTp1wcwUA3XHeoQswNxFC+QuwURkIgH5kSNH0LBhQ6RPn15uw7tp06ZP3n7Dhg2oWbMmUqdODRcXF5QtWxa7d+9OsvoSmZMbz94gfF0PFFI/kGWRz3m/xhyUz5PB2FUjIiuRzN4GbXsOwxKbprJsq9Kgy/NRWLR1v7GrRmRSjBqQBwUFoXDhwpgxY0aCA3gRkO/YsQPnzp1D1apVZUB/4cIFg9eVyJy8CgxDtyXncD4yGzSKSm5pvTX/JLSsVNTYVSMiK5MmhSOKd56EA0pxWQ5UnLDqv3vYeumZsatGZDJsjXnyunXryktCTZ48OVZ5zJgx2Lx5M7Zu3YqiRRloEGlXVOm17Byevg3FHDTEfSUdcqd3x6DmDdhARGQUBTK6YWfD2Vix6QeMj2wFf7hg6LpLyOrhjAIZXNkrZPWMGpB/LY1Gg8DAQLi7u8d7m7CwMHnRCggI0N1XXAxVL7GyhaEen0yLqfX3qK3XcO5RdM64cD9VZYzvXBZidUNTqaM5M7X+JsNifyee2sVyYKLvX/A/FL0meWiEBt3/PYtNfcrF2OHTuNjf1kVj4N/n+jyuWQfkEyZMwLt379CyZct4bzN27FiMGjXqo+P+/v6IjIw06AcF0clqNefNWjpT6u+d5+/g9ukTAPLIsoujDSZ+kwORIYHwCzFq1SyGKfU3GR77O3F1LJ4KV5/44fDd6EED37fvMGHBvxjctgnsbY3/fmJ/WxeNgX+fi8e2+IB8xYoVMtAWKStp0qSJ93bDhw/HkCFDYo2Qe3l5wc3NTU4MNVQHi0mq4hz8g235TKW/Lz16jazHhmKl/TX8GdkOSzR1MK1NURTKFr05B1lWf1PSYH8nvmntXNF81kn4vnyGWfaTUfjtPczdmxL92rWAsbG/rYvGwL/PbW1tLTsgX7VqFbp164a1a9eiRo0an7ytg4ODvHxINLwh/5iKDjb0Och0GLu/xSTOK0uHooP6iiz3sd0Mr/IdUTl3WqPUx9IZu78pabG/E5dLMnvM71gSe6f1QWnclMea3v0Jm07kQdMKhWFs7G/rojLg73N9HvOLzn748GG5ukmOHDnkpVGjRjh69CiSwsqVK9G5c2f5f/369ZPknESmLCJKg6ULJqODZqMsRypqLMs4Cp1rljB21YiI4pQplRPytR2D85qcspxR5YvUe/rhsvdrthhZJb0D8mXLlslRaScnJwwYMEBekiVLhurVq8s0En2I/O+LFy/Ki/DgwQN53dvbW5du0qFDB93txeOL8sSJE1G6dGm8ePFCXt6+favv0yCyGPPWb0NP/4m68txkXdGjQwf5qZ+IyFSVzZUe1ypMwyslOn20ovoyzi8ZBr+g6F2FiayJShGZ7HrImzcvevTogcGDB8c6PmnSJMybNw83btxI8GMdOnRIriX+oY4dO2Lx4sXo1KkTHj58KG8nVKlSRY7Ox3f7hBA55K6urjKIN2QOuZ+fn1z9hV9pWz5j9ve2U9dQYHsTZFH7yPIWVELBviuRNXXyJK2HNeH727qwvw1LhCD/zFuIAU+/l5sGCRM9fsegPgPkTp9Jjf1tXTQG/vutT8ypd0Au8rGvXbsmU1Viunv3LgoUKIDQ0FCYMgbkZCm/wG8+f4Pns5ugquq8LF/VZIFvyy2oUiBzktXBGvEPtnVhfxteYGgElv/zPXqFRQ+sBShOWFtsKbp+8+k5YobA/rYuGhMKyPU+u1ihZP/+j7e83bdvn/wZERneu7BIHF70qy4Y91OS40zpqQzGicjspHC0Q/XOo7FbKS3LLqpglDs3GAevPDR21YiSjN6rrHz33Xcyb1zkepcrV04eO378uEwZmTJliiHqSEQxiC+1Rq89hl/CVgNisx9FhcVpf8KgupXYTkRklnJ6uuBuw+m4t6URsqufI6/aGwfW/4ms6SYji4ezsatHZHB6j5D37t1bLjt45coVDBo0SF6uXr2K1atXo2fPnoapJRHpLD/ljdVXg9AifCTuazzxr21zdO7YHWoj5FsSESWWuiVyYXeBiQhSHLA8sjqmhNZH7+XnERoRxUYmi/dF65A3adJEXogoaV19+ha/b70ur99QMqNp1Bgs6lIZbs727AoiMnvdm9XFgFdzsPNx9O+0G88D8Of2GxjduICxq0ZkUNzVgshMvA2JQJ/l5xEeFb0SgTCgbjEUzeJh1HoRESUWOxs1Rn1bFx7J3w8yLP3vEXZcec5GJouWoIBczD719fWV18X2oqIc34WIDJM3vuDfxegQMAd2iJTH6uT3ROfyWdjcRGRR0rg44p9WRaDdSiG76ikerhsBb98gY1eNyLgpK//88w9SpEihu84NR4iS1qoDZ/Dts9FIbfsWxdV3MMJ5JP5uUYjvRSKySBVzpkafKtnx+PBS/GU3D06qMExZnBG9B42EvS2/3CcrDcjFxjtaYrMeIko6YivpLIcHIrU6ekfaQDhjXLuKcHG0YzcQkcUaXCMXpl13htPbMFnuHjgLCzeWQq8W9Y1dNaJEp/fHTBsbG7x8+fKj469fv5Y/I6LEExQWif+W/oqy6uiJnM8Vd/jUmIICGd3YzERk0Wxt1GjVeTDWIXqDIDFKXuXKMBy4zPXJyfLoHZDHt7FnWFgY7O250gNRYlqwai26hK+Q18V646u8fkXzikXYyERkFdKnTAb3ppNwUxO98WAe9WP4bxiCZ29CjF01IuMsezh16lT5v8gfnz9/PpInT677WVRUFI4cOYI8efIkbu2IrNiOs7fxzb1fYauOXlVFrDfepV175o0TkVWpVigzZt36G5mudpKj5M2wH5MX/YN+A36Uo+hEVhWQi8mc2hHy2bNnx0pPESPjWbJkkceJ6Os99gtG1NYhyKyOTg87p8mJAh3GwDUZ88aJyPp0bVIHM737YlDgJFnu8mYqlu2qgE71uUMxWVlA/uDBA/l/1apVsWHDBrn8IRElvsgoDdYvnohBqqOyHKAkw6VS49ElWxo2NxFZJbGySrPOQ7Ftymk0UB2DiyoE+U4NxcUCO1AkcypjV4/oq+n9Xc/BgwcZjBMZ0NR9t1HSf6euvMB1ADrUrcw2JyKr5uXuBKX+BDxRojdDK6G6hSUrl8nJ70RWM0Ie05MnT7BlyxZ4e3sjPDw81s8mTYr+OomI9Hfq/mtMP3QPs5Rh+E5Zg7S279Ci8yDmSRIRAWhQMg8mX/kVLbx/x9CInjgZlgP2W69jXPNCbB+yroB8//79aNSoEbJly4abN2+iQIECePjwocwtL1asmGFqSWQF3gZHYPDqi9AogAa2+CuyLaa3KIKMbk7GrhoRkUkQC0t0adsWjSZ74tH/R8ZXn32MqnnSoE4BT2NXjyjpUlaGDx+O77//HleuXIGjoyPWr1+Px48fo3LlymjRosWX14TIyo3cchXP3obqyi1LZESDwhmMWiciIlMjJrePa1UCKtX7Yz9uuAyfgPe/P4ksPiC/ceMGOnToIK/b2toiJCRELoH4+++/Y9y4cYaoI5HF23X+Lupe+x55VN6ynNXDGSMb5jd2tYiITFKZbKnQq3J2eV0FDZqEbcHyf2dDI75iJLKGgNzZ2VmXN54uXTrcu3dP9zNfX9/ErR2RFXgZEIp3W4ahts1ZbLYfgUY2JzCpZWE4O3zRFA8iIqswuEYuFE9vjyV24zDSbik6vRqPVQfPGLtaREkTkJcpUwbHjh2T1+vVq4fvvvsOf/75J7p06SJ/RkQJJ+ZeLF82H82xT5YjYYNCpauhaCYuK0pE9LmlEP9uXQZhakdZdle9Q8bD3+POiwA2HFl+QC5WUSldurS8PmrUKFSvXh2rV6+WGwMtWLDAEHUkslgbj19BO5/xuvJC5+7oUK+qUetERGQusqdJgbc1JsBHSSnLldSXsGvZeLmfA5HFBuRRUVFyycNMmTLp0lfE7pyXL1+WkzszZ85sqHoSWRxv3yA47R2KNKo3snxIUxS1OwyToz5ERJQwzSoUxoq03+vKnQPnYtmu6I3ViMyFXn/5bWxsUKtWLfj7+xuuRkRWIEqjYOPSyaij+k+W/ZXkeFppHHJ5uhi7akREZrcUYtv23bEB0d8uJleFIvepH3H9afRgB5E50HsoTqw7fv/+fcPUhshKrNx7Ep3eTNeVF7sNQJtqpYxaJyIic5XWxRF29cbiqZJKlsuqr+PgsjEIj2TqClloQP7HH3/Idci3bduG58+fIyAgINaFiD7t1vMAZD4+DK6qYFneplRA8w79oVbHWFSXiIj03sVzTfphunLn4MVYuv0AW5EsMyAXK6tcunRJ7taZMWNGuLm5yUvKlCnl/0QUPzHRaN6qtSinuiLLLxQ3RNQeBy937sZJRPS1qSvftuuENarasuykCoPn2fG49JipK2T69F7o+ODBg4apCZEVmH/sAdb5eOKe6jf8bTcX2zz7YlBZbgBERJQYPJI7wLXRGDzaeAEnNfnwR2R7eK69hG39K8DRzoaNTJYTkFeuXNkwNSGycPdevcOkvbfl9QtKTrRQT8CudtXkqA4RESWO2kVzYOi1hVh7NTqN9u7Ld/hn720Mr5eXTUwmi+urESXRqio/rLsca4LRTw0KwtM1ekMLIiJKPD81KY3UKRx05blH7+OCN1eII9PFgJwoCaw5eAaFn6yAGtEBecWcHmhRPCPbnojIANyc7TG2SUFdOY3ih42r5nPVFTJZDMiJDOyR7zt4HPkJv9otxXr735DL/jX+alaIqSpERAZUI19aNCmaAa1tDmCvw1D8GDQey3YdZpuTSWJATmRAGo2CTcuno6bqjCxnVL1E9xqFkCFlMrY7EZGB/dIgH4raP4GLKkSuupL79AjcfsElmskCAvKRI0fi0aNHiXLyI0eOoGHDhkifPr0cLdy0adNn73Po0CEUK1YMDg4OyJEjBxYvXpwodSEyhHXHLqK93/sNgJa595fbPBMRkeG5O9sjef0/dBsGlVdfxa7lE+W8HiKzDsg3b96M7Nmzo3r16lixYgXCwsK++ORBQUEoXLgwZsyYkaDbP3jwAPXr10fVqlVx8eJFDBo0CN26dcPu3bu/uA5EhvLEPxjJ9w9HKlWgLO9WSqNp+77cAIiIKAnVK54Da9J+pyt3DJiL1QfPsg/IvANyEQifOXMG+fPnx8CBA+Hp6YnevXvLY/qqW7eu3PmzSZMmCbr97NmzkTVrVkycOBF58+ZFv3790Lx5c/zzzz96n5vIkBRFwfqVC1BPdVKW/ZXkeF1pDDKncmbDExElIfENfOt2XbBVqSjLYpfkVEd+xmO/6N2SiUzBF+WQFy1aFFOnTsWzZ8+wYMECPHnyBOXLl0ehQoUwZcoUvH37NvFrCuDkyZOoUaNGrGO1a9eWx4lMya4Ld9Hc5/0HxX9deqJV1eJGrRMRkbVK55oModX/wGslhSzXVp3C+uWz5OAJkVluDBSTeCFHREQgPDxcXndzc8P06dPxyy+/YN68eWjVqlXi1VRsM/7iBdKmTRvrmCgHBAQgJCQEyZJ9PFFOpNTETKsRtxU0Go28GIJ4XNEehnp8Mi0f9ndASAT8t/2GDKrXsnxMUxC12wyACuI2/OVv7vj+ti7sb8vRpFxBTD/XB4PejpPltr5TselkLXxT5v1uyexv66IxcLymz+N+UUB+7tw5LFq0CCtXrpSTKzt06CDzwMUkS2HatGkYMGBAogfkX2Ls2LEYNWrUR8f9/f0RGRlpsA4IDAyUnaxWcyEbS/dhf/+7dTcGRm0HVECoYoeL+X9Ea/tI+Pn5GbuqlAj4/rYu7G/LUrFeexxYvhfV1OeRRvUGmt2/4E6GWUjlbCd/zv62LhoDx2visQ0WkBcsWBA3b95ErVq1ZLqKWCXFxsYm1m3atGkj88sTm8hX9/HxiXVMlF1cXOIcHReGDx+OIUOGxBoh9/LykqP54n6G6mCRsybOwYDc8sXs73Peb7Dwlj3cbGuho80e/GvfGl0b14aDXez3CJkvvr+tC/vbsri7u2NpudEIPNkcwXDAgYiCOHziOSa3KiJ/zv62LhoDx2u2traGC8hbtmyJLl26IEOGDPHexsPDwyDD/2XLlsWOHTtiHdu7d688Hh8xgi8uHxINb8hgWXSwoc9BpkP0d6QGGLHpGt7BCaMiO2JdVCWMaNcMyRyiR17IcvD9bV3Y35alXc1y+OnqSOz09UAgnIBLz9GyRCZUyOkhf87+ti4qA8Zr+jym3mfX5op/SORw//7773o91rt37+SqLeKiXdZQXPf29taNbot0GK1evXrh/v37+OGHH+Qo/cyZM7FmzRoMHjxY36dBlOjmHrmPOy/f6cp5i1VE2Vzp2NJERCbE1kaNNi1b453KSXfsl81XERoRZdR6kXXTOyAX+dgikP5QcHBwnLnan3L27Fm5You4CCK1RFz/9ddfZfn58+e64FwQSx5u375djoqL9cvF8ofz58+XK60QGdOj18FYeehcrM0ofq6X16h1IiKiuBXN5IZ2pTPpyg98gzB3/zU2FxmN7ZeMkIvh/Q9dunRJ5mbpo0qVKp9cciiuXTjFfS5cuKDXeYgMSbyGD21bhn02kzFRaYnFUbUxon5euDnbs+GJiEzU0Np5sOuqD2zfPcNvdv/C6UQ47hfZipRftf4c0ZdJ8MtOpKmIQFxccuXKFSsoj4qKkqPmIqWEyNpsO30T3wbMgbMqDL/aLYV9ujxoUrSBsatFRESf4JrMDr/Uz418Gwcgp/qpPDZl9Wy0bduF7UamG5BPnjxZjgSKCZ0iNcXV1VX3M3t7e2TJkuWTkyuJLNHbkAiE7Bktl88S9muKo3WrTnF+i0RERKalUZGMmHKsKwa9jp4D19pvJvZdqY5WVVIZu2pkZRIckHfs2FGXx12uXDnY2XHlCKLlm7aip2aXXHM8WHHA4zKjUD11cjYMEZEZEIMnjVv3xIFp2+Ta5GlVb6A6Mh5vSi2Be3JHY1ePrEiCJnVqd7cUxKRLsaKKOBbXhchaXH3ijzI3/oSNKnoexDKHlmhTq5yxq0VERHrIkjo5HpUeJQdVhJbKbqzYuIVtSKYXkIv88ZcvX8rrKVOmlOUPL9rjRNZAo1FwcNVkFFPfleV7mnTI03gYHGy5ARARkblpW7s8ljq2ltfVKgWV7/yJcw98jV0tsiIJSlk5cOCAbgWVgwcPGrpORCZv04mraBu4QKaqCBs9B2BInvg3yyIiItMlBlMKNR+OG0sPIK/6MQqqH2LGuoko8t0Y2Kg5J4hMJCCvXLlynNeJrJF/UDii9o1CKlWgLO9QyqJu3W+MXS0iIvoKZXOmw5QsQ5HXe4Ast333LzYcb40WFQuzXcn0NgbatWsXjh07pivPmDEDRYoUQdu2beHv75/Y9SMyOZN3XEB5JXoToHeKI16X+xVpU0TnHhIRkflq1bQFtmgqyOtuqnd4cGChHIQhMrmAfOjQobrJm1euXJG7a9arV09uey+uE1myi4/f4N/zvqgZNh5zIutjiWN7tKhaytjVIiKiRJDGxREvin+PGxov9AwfjJkhNTFhzy22LRmc3vtRicA7X7588vr69evRsGFDjBkzBufPn5eBOZGlitIoGLHpCsTmskFIhrGR7bCiZWnY2+r9uZaIiExUozL50f7ONNz1DZblFae90aZUJhTI8H7/FaLEpnckITYBCg6OfpHu27cPtWrVktfFpE8ue0iWbOVpb1x9+n5pz0aF06Ncdg+j1omIiBKXrY0aIxvl15XFIMyvm6/K1bWITCYgr1ChgkxNGT16NE6fPo369evL47dv30bGjBkNUUcio3sTHI7bu2cjHV7LcnIHW4yon9fY1SIiIgMon8MD9Qum05VdnxzE1tM32NZkOgH59OnTYWtri3Xr1mHWrFnIkCF6qbedO3eiTp06hqgjkdGt3LIDIzWzcMDhO3Sz2Y5BNXLKXEMiIrJMP9XPi2x2/lhgNx6L7McjaPcfCAiNMHa1yELpnUOeKVMmbNu27aPj//zzT2LVicik3HoegKLX/4KNWkEyhCO1sy06lM1i7GoREZEBZUiZDB3LZUa5/67JckvNTszbshO9WzZiu5PxA3JBo9Hg7t27cvdOcT2mSpUqJVbdiIxOURTsWjsHA9XRX1U+0KRFnsZDOZGTiMgKtK5ZDkvPt0C3iOWwVWlQ7OqfuFmxMvKk4wRPMnJA/t9//8k1xx89eiSDlZhUKhWioqISs35ERrXvyiM0ez1btyPnFs9+GJjPi71CRGQlO3jmaDwcD1bvQ1a1D0qrb2LK2jnI3X+ojHmIjJZD3qtXL5QoUQJXr16Fn5+f3AxIexFlIksRGhGFR1v/QkaVrywf1RRCw+adjV0tIiJKQlXye2GLZ39dudnrOTh49TH7gIwbkN+5c0euO543b16kTJkSrq6usS5ElmL1vpNoF75eXo9U1LheeDiypUlh7GoREVESa9i8kxyUEcQgzb2tfyM8MnbKLlGSBuSlS5eW+eNElswnIBQe//2JZKroLZPXqOuiTf2axq4WEREZgRiMuVZwGKKU6DSVNmFrsfbQGfYFGS+HvH///vjuu+/w4sULFCxYEHZ2drF+XqhQ9CdIInO2Zv1q9FedkNdfKymQrNZPcHGM/VonIiLr0aZ+bay7VgutsBvJVaFwOjYGr8usQarkDsauGlljQN6sWTP5f5cuXXTHxMQGMcGTkzrJEpz39sd/d56jiZ2H/GpyVfKO6F3m/a5tRERkfVyd7KCqOhwBB47CRRWM5FGBmLL3On5vUtTYVSNrDMgfPHhgmJoQmQDxwfL3rddxUVMQ1cMmoKXNITRuPghqNWfTExFZu6YVCmPCf71w7a29zClXn36GdmVzILcn5xdREgfkmTNn/spTEpmurZef4+LjN/J6GOwRULATimdNbexqERGRCbC1UaN80z6YveC0LGsUYPS261jatRSXQaSkndQpLF26FOXLl0f69OnleuTC5MmTsXnz5q+rDZGRlzkct/Omruxgq8YPdfKwT4iISKdiztSonieNrnzsri/233jJFqKkDchnzZqFIUOGoF69enjz5o1uIyCxBKIIyonM1dqDZ/BD0HhkVr2Q5a4Vssqtk4mIiGL6qX5e2MpURgV11KdxcfMULoNISRuQT5s2DfPmzcPPP/8MGxsb3XGxWdCVK1e+rjZERuIXFI7kJ8biG5sT2Gs/FM2dLqB3lezsDyIi+kj21MnRsUxGLLMbg9n2k9ErdAHWHjrLlqKkC8jFpM6iRT+eUezg4ICgoKAvrwmREa3esg3fKIfl9RA4oFSVhkjBZQ6JiCgeA2rkxTObDPK6WAbR/tjfeBscwfaipAnIs2bNiosXL350fNeuXXL3TiJzc+9lIArdmAi1SpHlVY6t0LR8QWNXi4iITHwZxKjKPyJQiU5tbKLsx6qde41dLbKWgFzkj/ft2xerV6+WS8SdPn0af/75J4YPH44ffvjBMLUkMqBt65egvPqqvP5Ikwa5G30nZ9ITERF9SrOKRbHKvqm8bqvSIMelCXjsF8xGI8Mve9itWzckS5YMI0aMQHBwMNq2bStXW5kyZQpat26tfw2IjOjkHR/Uez5T99F0s0cP9M+XkX1CRESfZW+rRqZ63+P5pp1Ip/JDdfU5TNu0Gv27dGbrkV6+aBiwXbt2uHPnDt69e4cXL17gyZMn6Nq165c8FJHRaDQKzm+ajJzqp7J8VpMLNZr14FqyRESUYLWKZMV61066cqWHU3HlsT9bkPTyVd/LOzk5IU2a92txEpmTbWduodW7ZbryfzkGI18GV6PWiYiIzItKpULZJn1wQ+Mly4XV93Fo/WyZ1kuUqCkrYlUV8YJLiPPnzyf45ETG3ATIf8/f8FAFyPIOTVm0aBydB0hERKQPsaPz1Az9kPf5MFlu7LcAh663R9X80UE6UaKMkDdu3BjffPONvNSuXRv37t2TyxxWqVJFXhwdHeUx8bMvMWPGDGTJkkU+TunSpeVE0U8RGxDlzp1b5rJ7eXlh8ODBCA0N/aJzk3VaevIRjoVkxj1NOoQptnhechjSujgau1pERGSmGjb7Fsc00St0XVKyYfrOi4iM0hi7WmRJI+QjR46MNalzwIABGD169Ee3efz4sd4VEKu1iJVbZs+eLYNxEWyLwP7WrVtxpsOsWLECP/74IxYuXIhy5crh9u3b6NSpkxzBnzRpkt7nJ+vzNiQC0w/exVtNCRwML4JKzt6YVquisatFRERmLKuHM7bnG4aJl+7hgpIT8AXWnXuC1qUyGbtqZIk55GvXrkWHDh0+Ot6+fXusX79e7wqIILp79+7o3Lkz8uXLJwNzkZsuAu64nDhxAuXLl5eru4hR9Vq1aqFNmzafHVUn0pp9+J4MyoVI2KJqjYZwdtB7wSEiIqJY2jSohbv27/dkmbT3NoLDI9lK9Fl6RyEiTeT48ePImTNnrOPimEg50Ud4eDjOnTsn1zDXUqvVqFGjBk6ePBnnfcSo+LJly2QAXqpUKdy/fx87duzAt99+G+ftw8LC5EUrICA6Z1ij0ciLIYjHFZM5DPX49OVevA3FwmMPdOXM7k5oWSLjV/UV+9u6sL+tC/vbunxtf7s52aFn5WyYsOe2LL8MDMO8I/fRv1qORK4pmcP7W5/H1TsgHzRoEHr37i0nb4qAWDh16pQc0f7ll1/0eixfX19ERUUhbdq0sY6L8s2bN+O8jxgZF/erUKGCbMTIyEj06tULP/30U5y3Hzt2LEaNGvXRcX9/f3lfQ3VAYGCgrJ/4gEGmY/Xm7ZipWoS/Va1wS8mEnuXSI/Dtm696TPa3dWF/Wxf2t3VJjP5unNcVS0/a41VgKBqpT8Dx6Brcz/UXUjrZJXp9ybTf3+KxDRaQi/ztbNmyyY2AxEi1kDdvXixatAgtW7aEoR06dAhjxozBzJkzZc753bt3MXDgQJnTHtcHAjH6LnLUY46Qi4mgbm5ucHFxMVgHi5x2cQ4G5Kbjnk8gyj2aidI2N1FVfRG/uI5GyzJ1oFYnbAWh+LC/rQv727qwv61LYvX3kJq5kGlra5S1uQ6NosLcU83Qo1mDRK0rmf7729Y24WH2FyXOisA7MYJvDw8P2NjYwMfHJ9ZxUfb09IzzPiLoFukpYnKpULBgQQQFBaFHjx74+eefP2pQsRqMuHxI3M6QwbLoYEOfg/Sza/My9FdHf/PyUEmL+g2aw9bWJlGakf1tXdjf1oX9bV0So7+bFffCgv0lUTbsOtQqBTmuTMGLmjWRPmWyRK0rmfb7W5/HNGq0aG9vj+LFi2P//v2xPq2IctmyZeO8T3Bw8EdPUAT1Ahfhp/ice+CLGs9m6crbUndDuVzp2GBERJTobG3UyFpvMF4obrJcQ30WG7dsYktTvIw+fCvSSebNm4clS5bgxo0bMj9djHiLVVcEsaJLzEmfDRs2xKxZs7Bq1So8ePAAe/fulaPm4rg2MCeKSXxQO7lpFvKqo5flvKjJjmpNurORiIjIYGoWyoL1KdrpysXuTsVdn4TnFJN1Mfpab61atcKrV6/w66+/4sWLFyhSpAh27dqlm+jp7e0da0R8xIgR8usF8f/Tp0+ROnVqGYz/+eefRnwWZMoOXXuMxm8WA/9PFT+SuR8GZExp7GoREZEFE7FK0Ub98GDZWmRV+6Cs+jqmbV6O/j16GbtqZIJUipXleYhJna6urnj79q1BJ3X6+fnB3d2dOeRGptEomPf3d+gZukCWD2sKI+vAXciUyikRz8H+tibsb+vC/rYuhujvaVP/Qn+/sfL6FU0WKN0PopCXe6I8Npn2+1ufmDPBZ69YsSImTJggd8YkMhc7z91B85A1uvL1vIMSNRgnIiL6lEqNe+CaJrO8XlD9EIc3RQ8QEX1RQC520xSb9YhJmGKZw2HDhsnNgKxsgJ3MSESUBi/2/INUquicve2acmjeoL6xq0VERFakcCZ37M/QW1eu92oBTtx+YdQ6kRkH5GJy5fr16+WmPBMnTsSbN2/QokULuTxhly5dsGnTJoSEhBi2tkR62HD+CQ4FZZIjE5GKGs+KDkbqFB8vgUlERGRI9Rq3wylNHkQpKlxQcmL67ksc0KRY9E6YEWt616tXD3PmzMGzZ8+wZcsWpEuXTq50kipVKjRo0ECOnBMZU1hkFKbuv4ujmkJoEP4n2uMPtKhdhZ1CRERJLkdaFxzN+SNqh4/D9xG9cOJpJHZfi70HC1m3r85gF7tlihVOrly5Ii/Vq1fH8+fPE6d2RF9o5SlvPH0T/Y2NAjXKVaqFlE72bE8iIjKKNg3rwFudSVeesOcWojRM+6VoiTqlNHv27Bg8eDCaN2+emA9LpJfg8EhMP3hPV3Z3tkeXClnZikREZDQZUiZD+zLRkzuFuy/fydRKIpPYGIgosa07cBoTwn5HMVX0ikC9K2dHcgejL7lPRERWrm/V7HC2t4EtItHOZh+e7ZqE8EiNsatFJoBRClmUgNAIOP03EVVsLsnLHza98W3ZOsauFhEREVIld0CP8plQ73hz5FQ/RWBEMmw60QktKxVm61g5jpCTRVm75yi+UQ7K64FKMuSs1BqOdjbGrhYREZHUpXJOXFDnk9dTqEIQcmgyQiOi2DpW7osD8vDwcNy6dQuRkZGJWyOiL+QXFI7U5/6BnSr6F9tau0ZoUr4Q25OIiExGCkc7BJcZjDAlOkmhedR2bDp20djVInMLyIODg9G1a1c4OTkhf/788Pb2lsf79++Pv/76yxB1JEqQdbv2oQGOyuv+SnK4VR8Me1t+CURERKalRdXS2KCuKa87q8IQeZSj5NZO72hl+PDhuHTpEg4dOgRHR0fd8Ro1amD16tWJXT+iBHkZEIrMl/+BWhW9hNQah2ZoWCo3W4+IiEyOs4MtIssNQqhiJ8vNo3Zi/eGzxq4WmVNALnbknD59OipUqACVSqU7LkbL7917v9QcUVJav307aqtOy+uvFFdkqjMAtjYcHSciItPUvHJJrFNHLzrgqIqA6vgUuWwvWSe9I5ZXr14hTZo0Hx0PCgqKFaATJZUn/sHIc2OarrzOqTVqF8nODiAiIpOVzN4G6gqDEKw4yHIzzR6sPxg9sETWR++AvESJEti+fbuurA3C58+fj7JlyyZu7YgSYMv2LaiqviCvP1E8kKtef6jV/HBIRESmrWmlolhnU1ded1BFwP7kZLwL4yi5NdJ7HfIxY8agbt26uH79ulxhZcqUKfL6iRMncPjwYcPUkugTo+N7b75CKXUulFDfxuYUrdGnQEa2FxERmTyxLK9j5UF4d2AX7BGB4Chg8bH76Fc9l7GrRqY+Qi5yxy9evCiD8YIFC2LPnj0yheXkyZMoXry4YWpJFI8ZB+/hQmQ2NA8fibbhPyF/3d5MnSIiIrPxTflC+MNuIKqFT8KoyI6Ye/SB3OSOrMsX7dSZPXt2zJs3L/FrQ6Tn6Pjas4//X1IhKEMFVM6XgW1IRERmw8HWBoVqtseqjVdkOSA0EguOPsDgmhwltyZ6j5CL5Q0XL16MgIAAw9SISI/R8UhN9DKHwqAaOTk6TkREZqdFiYzwck+mKy889gBvgsONWicy8YBcLG8o1iL39PREixYtsHnzZkRE8KsVSvrR8cwX/kY59VUACgp7pUSVXKnZDUREZHbsbNToXy2nvO6AcLSM3IL1ew4Zu1pkygG5mMT59OlTuR65s7MzOnTogLRp06JHjx6c1ElJurJKL5stWGE/BpPtZnB0nIiIzFrTohlQO+UzHHEYhF/sliHthcnwC+IoubX4op1T1Go1atWqJVNXfHx8MGfOHJw+fRrVqlVL/BoSxTE6nu/2rPdl1xIcHSciIrMmNrNrUK0S7BC97GFdnMCGPQeNXS1KIl+1leGLFy8we/ZsjBs3DpcvX0bJkiUTr2ZE8diyfTOqqC/q1h0vUK8nc8eJiMjs1SuRC+sdmsjrNioFqS9OZy65ldA7IBeTORctWoSaNWvCy8sLs2bNQqNGjXDnzh38999/hqkl0f899gtG/hij45tTtEXlvFxZhYiIzJ+NWgXPGv3hrySX5fo4hg17jxi7WmSKAbnIF//5559RoEABufb4rVu38Ouvv8qlEIkMbev2zaisviSvc3SciIgsTd3iObHBvpG8bqvSwO38NLwN4eIZlk7vgHzLli148uQJ/vnnH5QoUcIwtSKKb3T8zvvR8U0p2qISR8eJiMjCcsndq/XHW8VJlhviCDbsP27sapGpBeQiVUVM6iQy5uj4Y01qFGTuOBERWaAGpfJgXYxR8hRnpyKQu3datATt1FmsWDHs378fbm5uKFq06Ccn0J0/fz4x60cUe3T8/58FN7u0QV+OjhMRkYWuS56ySj8E7NkMF1UIGimHsOrgf+hQt6Kxq0bGDMi/+eYbODg46K5/KiAnMoR5B66hthKpGx0vVL8XX4dERGSxGpbOjxUHGqBT1FpooMaV0wfwrlpZJHdIUOhGZiZBvTpy5Ejd9d9++82Q9SH6yPO3IVh54RX+jfoZxSJvo1AaG4zMk54tRUREFsveVg2nyv0xe08IFkTWxSu4IdvJR+hdhYtoWCK9k8GzZcuG169ff3T8zZs38mdEiW3O4fuIiFLk9fNKLlSq24qj40REZPG+KVcAi526yGBcmHf0PoLDo78tJisPyB8+fIioqKiPjoeFhcnVV4gS06vAMKw87a0r50vngqq507CRiYjI4jnY2sQaEfcLCsfy/97/TSQrDMjFcofiIuzevVtXFpeNGzdi9OjRyJo16xdVYsaMGciSJQscHR1RunRpnD59+pO3F6Pxffv2Rbp06WRue65cubBjx44vOjeZtvX7DqGc5hyA6BHy/tVycHSciIisRquSXkiTInoenzNCcP7QJoSEfzwwSuYtwTMDGjduLP8XEzo7duwY62d2dnYyoJ44caLeFVi9ejWGDBmC2bNny2B88uTJqF27ttxwKE2aj0dCw8PD5dKL4mfr1q1DhgwZ8OjRI6RMmVLvc5NpexMcjnQXp2GR/VFc02TG+BTDUDu/p7GrRURElGQc7WzQs3J2PN85Hn1tN8MxKhwbj1ZC2+rcC8YqA3KNRiP/F6PgZ86cgYeHR6JUYNKkSejevTs6d+4syyIw3759OxYuXIgff/zxo9uL435+fjhx4oT8ICCIDwNkeTbsO4YOiN4MIb3qNZpVKQm1miv8EBGRdWlbKhM27n8DN+WdLEcdn4rQSotksE5WmkP+4MGDRAvGxWj3uXPnUKNGjfcVUqtl+eTJk3HeR6TIlC1bVqaspE2bFgUKFMCYMWPizGsn8yU2QHA5P11uiCCst2+EusVyGLtaRERESS6ZvQ005QYgTIkeiGwWtQubjkdvlEeW4YsWswwKCsLhw4fh7e0tg+qYBgwYkODH8fX1lYG0CKxjEuWbN2/GeZ/79+/jwIEDaNeuncwbv3v3Lvr06YOIiIhYyzPGnGwqLloBAQG6EX/tqH9iE4+rKIrBHt8abDj4H9oohwAVEKAkQ8oqfSAGx02xTdnf1oX9bV3Y39bFlPu7ccVi2HC8BtpgJ5xUYQg5OgOh5ebI5RHJNPtbn8fVOyC/cOEC6tWrh+DgYBmYu7u7y8DayclJ5nXrE5B/6ZMT55k7dy5sbGxQvHhxPH36FOPHj48zIB87dixGjRr10XF/f39ERkYarI6BgYGyk8WIP+lHTFaxOzUd9qrobz3W2dRD3RxpZaqSKWJ/Wxf2t3Vhf1sXU+/vt4W6IPzSHvn3sVnkDqw9fAF1i37ZghoEg/e3eGyDBeSDBw9Gw4YNZa63q6sr/vvvP5nL3b59ewwcOFCvxxKpLyKo9vHxiXVclD094568J1ZWEecT99PKmzcvXrx4IUfr7e3tY91++PDhctJozBFyLy8vuLm5wcXFBYbqYDH5VZzDFN/Qpm7lgTNopuyXo+PBigOSVeyHtKkTJ03KENjf1oX9bV3Y39bF1Pu7dZ3K2Hq5MprhAFxUwQg9swSuVafAhvOrTLK/bW1tDReQX7x4EXPmzJEVF0GxSAcRGwL9/fffcvWVpk2bJvixRPAsRrj379+vW8VFNI4o9+vXL877lC9fHitWrJC30zbe7du3ZaD+YTAuiGURxeVD4r6GfLOJDjb0OSxRaEQUNCdmwFEVIcsbbGqjeYXCJt+O7G/rwv62Luxv62LK/Z3SyQH+Rfog6sJB2KgUNAnbjL2XB6NeMe7eaYr9rc9j6n12MTqtPYFIHRF55IIYLX/8+LG+DydHr+fNm4clS5bgxo0b6N27t0yF0a660qFDBznKrSV+LlIXxGi8CMTFiixiUqeY5Enmb8vJq2gatUtel5NXyvbjLHIiIqL/a1KjEnYpZeV1D1UAHu2dLVMuyLzpPUJetGhRuexhzpw5UblyZfz6668yh3zp0qVyxRN9tWrVCq9evZKPI9JOihQpgl27dukmeoqAP+YnDJFuIjYmEqkzhQoVkuuQi+B82LBhep+bTEtElAa3jq5DS1X0JNyNqmpoUqm4satFRERkMlIld4B3/l7AjROyXDNoGw7e/A7V8nKfDnOmUvT8WHX27FmZpF61alW8fPlSjmCLNcFFgC7WCC9cuDBMmcghF6P5b9++NWgOuRjFFxNeTfErL1O19uxjDF13GflVD9Dbdgt8y/6CTvUqwtSxv60L+9u6sL+ti7n09/O3IfhvYgt4azywOLI2smbKhPW9y3EnaxPrb31iTr1HyEuUeL8zlEhZEaPZRF8rSqNg5qF78vo1JSuG23yH49XKsGGJiIg+kM41GU4VHoNVZ6JThf293+DUAz+UyZaKbWWm9P448Mcff8jNgYgS0/Yrz/HAN0hX7lQuC1wcozdAICIioth6Vc4u9+fQmnHwLpvImgLytWvXIkeOHChXrhxmzpwp88eJvoZGo2DD3qNQIXoBfSd7G3Quz3VViYiI4pPFwxkNCqXXlS/e8cYlb382mLUE5JcuXcLly5dRpUoVTJgwAenTp0f9+vXlUoRisyAifR289gR/BQ7DHvthaKQ+jvZlMsPd+eMlLImIiOi9PlWzwx0BGGq7Cscd+uPI9mVsHjP1RRns+fPnl0sNim3sDx48iCxZsmDQoEHxbuZD9Cm39s6Hp8ofOdVP0dD2NLpV4Og4ERHR5+TxdEGXTC/R13YLXFQhKP98MW6/CGDDmaGvnlLq7OyMZMmSyU15IiKiN3MhSqgz91+h9pvVuvKdnF2RxsWRDUhERJQA5eu3x02Nl7xeTH0Xe7avY7tZS0AuJnX++eefcqRcrLpy4cIFjBo1Sq4jTqSP0zv/RXb1c3n9pCYf6tVtxAYkIiJKoKKZU2G/R1tducijBfB+zRRiiw/Iy5QpIyd1rlu3Tu6m+ejRI7nVfdeuXeVai0QJdePZW1TweZ/vds6ro5ykQkRERAlXtE4XPNREb6hYQX0VW3duZfNZekBevXp1XLlyRY6Kf//993KnTKIvcWDnOhRW35fXr2kyo0rd1mxIIiIiPZXNmRY7XFvpyrlvz8WLt6FsR0sOyEWqSr58+QxTG7Iaj/2CUejRIl35YOp2KJAxpVHrREREZI5UKhVy1+qB54q7LNdQn8WmPXuNXS3SQ4J26hwyZAhGjx4tJ3CK658yadIkfc5PVmrb7h3orb4ir4uv2YrV6WjsKhEREZmtagUyYs72pugVOl+WM1yZBf96teHGZYQtJyAX6SnaFVTOnz8vP4nFJb7jRDH5vgtDlhvzdN/P7EzRHL1yROe+ERERkf5EDOZVszdeb1mNVKpA1FOdwJKDx9ClQTU2p6UE5GKtca1Dhw4Zsj5kBZaceIi9EY0RamuDMuobyF6rBz/MERERfaXaRbJhya4GaBy+DYsi62DzubdoXSsSTvYJCvfIiPTqITFKLtYcv3jxIgoUKGC4WpHFehcWKQPyACUTBkf0RV4PW2wvmNnY1SIiIjJ7tjZqOFceiPLbaiEUDkAIsPrMY3Quzw33LGpSp52dHTJlyoSoqCjD1Ygs2spT3ggIjdSVO1fOB7WaqU5ERESJoXHpXEie3EVXnnfkPiKiNGxcS1tl5eeff8ZPP/0EPz8/w9SILFZYZBTmH4te5lDwdHHEN0XTG7VORERElsTRzgady2fRlZ+9DcWWi8+MWif6PL2TiqZPn467d+8iffr0yJw5s1x5JSYx6ZMoLttP38Dc0KFYYVMdG6MqoFvFvHCwtWFjERERJaL2ZTJj1qF7cA57ia62O/F07xFoiv7Fb6QtKSBv3LixYWpCFi1Ko+D1odloqr4vNwPKZ/cczUo1MHa1iIiILI5rMjt0L54cvc61g4MqAi9C3HDwWj9UL+hl7KpRYgXkI0eO1PcuRNh/5SEah20BVECUokJksc5I7sBZ30RERIbQpkpxHD1bGDVUZ+Gp8seGvfNRveAoNral5JALb968wfz58zF8+HBdLrlIVXn69Gli148sgKIouLdnHlKr3srybqU0GlevaOxqERERWaw0Lo64nbObrlz7zWqceeBr1DpRIgbkly9fRq5cuTBu3DhMmDBBBufChg0bZIBO9KGTd3xQL3CtruydtwdSJXdgQxERERlQnToNcUqTR17Prn6OUzuWsr0tJSAfMmQIOnXqhDt37sDR0VF3vF69ejhy5Ehi148swIXdi5FZ/VJeP6IphPq16xq7SkRERBYvW+rkOJOxo65cwWcpbj6P/raazDwgP3PmDHr27PnR8QwZMuDFixeJVS+yEFcev0HVVyvel7N0hpe7k1HrREREZC0q1W2DG5pM8noR9T3s27nB2FWixAjIHRwcEBAQ8NHx27dvI3Xq1Po+HFm4IztXIZ/6kbx+UZMd1es2M3aViIiIrEYhLzcc8GjzvvxwIZ74Bxu1TpQIAXmjRo3w+++/IyIiQpZVKhW8vb0xbNgwNGvGYIvee+AbhOJPFuvKx9J+izzpXNlERERESahw7S54rIkeNK2kvoxtu3ez/c09IJ84cSLevXuHNGnSICQkBJUrV0aOHDmQIkUK/Pnnn4apJZmlBYduwVuTBhGKDe5p0qF0vW+NXSUiIiKrUz5XWmxLET1o+kpxxaVrV+EXFG7salEMei8E7erqir179+LYsWNyxRURnBcrVgw1atTQ96HIgr0MCMWaCz5YFtUT/0Q2R5X0kRib1cPY1SIiIrI6IpshS/WeGLY+CpuiyiMM9sh54iGG1Mxl7KrR/33xziwVKlSQF6K4LDj+AOFRGnn9OVKhRs0SbCgiIiIjqVUkK8btr4+w19H540tOPETPStngzE36zC9lRaPRYOHChWjQoAEKFCiAggULypzyf//9V27+QiS8DYnA8v+8dY2RO20KVM2dho1DRERkJDZqFXpUyh7rb/WqM4/ZH+YWkIuAWwTf3bp1kztyimA8f/78ePTokVyXvEmTJoatKZmNTYdOoXHkTjggOj+tZ+VsUKtVxq4WERGRVWtaLAM8/r8xX3r44vqhNQiPjP42m8wkZWXx4sVy45/9+/ejatWqsX524MABNG7cWI6Ud+jQwRD1JDMRGhEFu9Mz8Yfddgy0XY/fHIaiYWFuBERERGRsjnY26Fo+C1Lu/x7NbY4gOMIBO85+g8ZlonfzJDMYIV+5ciV++umnj4JxoVq1avjxxx+xfPnyxK4fmZktJ6/iG80+eT05QlGhbHnY2ei9mA8REREZQLuymeFgA9ipouCqCobPwdnQaJh2bGwJjpTEiip16tSJ9+d169bFpUuXvqgSM2bMQJYsWeDo6IjSpUvj9OnTCbrfqlWr5MxhMTpPxhcZpUHg0VlwVoXJ8mZ1dTQuX8TY1SIiIqL/c3G0g2/hXtAo0amkjUM34sC1J2wfcwnI/fz8kDZt2nh/Ln7m7++vdwVWr16NIUOGYOTIkTh//jwKFy6M2rVr4+XLl5+838OHD/H999+jYsWKep+TDGP3xftoEr5VXo9U1Agp0RvJ7G3Y3ERERCakcY0q2KdEr36WVvUGN/fM4+Ic5hKQR0VFwdY2/pRzGxsbREZG6l2BSZMmoXv37ujcuTPy5cuH2bNnw8nJSa7m8qm6tGvXDqNGjUK2bNn0PiclPjHp13vfHLir3snyTpRDk6pl2dREREQmJo2LI+7m6qYr1327BqfvvTJqnaydrT4Bl1hNxcEhenbuh8LCotMU9BEeHo5z585h+PDhumNqtVpuMnTy5Ml47/f777/LnUK7du2Ko0eP6n1eSnxHbj5Dw+ANwP8XU3mWvydSOtmzqYmIiExQvToNcXLqFJRVX0d29XPs3L0UpXN8Z+xqWa0EB+QdO3b87G30XWHF19dXjnZ/mAojyjdv3ozzPmKH0AULFuDixYsJOof4oBDzw0JAQIBuTXVxMQTxuOIDjKEe3xRd2bUQlVW+8vpBTVE0qFndap6/Nfa3NWN/Wxf2t3Wxpv7O5J4MWzN0RNnnw2S5gs8yXHvSBXnTu8JaaAzc3/o8boID8kWLFsHYAgMD8e2332LevHnw8EjYNuxjx46VqS0fEvnuX5Jik9AOEHUVnSxG/C3dladvUdN/lS4B6qJXBxSMCoGfXwisgbX1t7Vjf1sX9rd1sbb+LlKuDq6tnYn86kcoor6Pf7atRtrmzWEtNAbub/HYiR6QG4IIqkXuuY+PT6zjouzp6fnR7e/duycnczZs2PCjTx8iv/3WrVvInv39LlSCSIcRk0ZjjpB7eXnBzc0NLi4uBnhW0XUSq7+Ic1jDG/rIpgP4UfVCXj+ryYX6DZvD3T05rIW19be1Y39bF/a3dbG2/i7v7o6ZB9siv99YWc7+dDPeoT0yuTvBGmgM3N+fmnv50W1hRPb29ihevLjcbEi7dKFoHFHu16/fR7fPkycPrly5EuvYiBEj5CeQKVOmyED7QyLnPa68d9HwhnyziQ429DlMwd2XgVh01xnbMAVdbHchwqscBnga5oOOKbOW/qZo7G/rwv62LtbW38XqdMLBpTuwQ1Mam6IqoPWxhxjduACshcqA/a3PYxo1IBfE6LXITy9RogRKlSqFyZMnIygoSK66os1Lz5Ahg0w9EeuUFygQ+0WSMmVK+f+HxylpzD58X/7/Cm4YF9kGG+uWY9MTERGZibI506Jx2jG49OStLK85+xgDa+SER/K4F/EgwzD6x79WrVphwoQJ+PXXX1GkSBE5WXPXrl26iZ7e3t54/vy5satJcXj2JgSbLjzVlctkc0fRTG5sKyIiIjMaIe5d5X26b1ikBouPPzRqnayR0UfIBZGeEleKinDo0KFP3nfx4sUGqhV9zsoDZ2GnCUEkHGW5d5UcbDQiIiIzUyufJ7Kldsb9V0GyvOnkVfSsnA0pHO2MXTWrYfQRcjJP/kHhyHnxLxx3GICBNutR3NMWlXImbOUbIiIiMh1qtQq9KmVHXtUjTLWbhr1KL2w+es7Y1bIqDMjpi2w8eAL1VCfkzpwdbPega8Uc8msvIiIiMj/fFE2PNslOo5HNSSRThUM5ORNhkVHGrpbVYEBOegsOj4TT2ZmwVUUvObnJvgFqFcnKliQiIjJTDrY2sCnXG2FKdJpKk6jd2HbqurGrZTUYkJPeNh69iMbKAXk9SHGAS6U+sLXhS4mIiMicfVOxOLaoqsjryVWh8D88G1EaxdjVsgqMokgv4ZEaRJyYCUdVhCxvsqmFhmXysxWJiIjMXHIHWwQW7YUoJToFtXHYFuy9zBVXkgIDctLL9jO30DRyp7werthAU7oPHO1s2IpEREQW4JvqFbFLKSOve6gC8GDvHLm1PBkWA3JKMI1GwauDs+CiCpblrarKaFy5JFuQiIjIQqRK7oDH+Xroyg0C1+H4bR+j1skaMCCnBNt3xRuNwzbL6xpFBf/CvbhGKRERkYVpULsOjmgKyete6le4tHuhsatk8RiQU4KIr6vu7pmLNKo3srxHKYVvakRP/CAiIiLLkdHNCVeydNGVq/muwCVvf6PWydIxIKcEOXnvNea/LoCpkY3xVnHCgzw9kDqFA1uPiIjIAtWo2wznNTlwU+OF2ZENMefwXWNXyaLZGrsCZB5mHb4HP7hgUmRLzNY0we46tYxdJSIiIjKQ3OlcMDjLWGy8HQ5ABdX1l7j36h2yp07ONjcAjpDTZ1158hZH7/jqyrUKZYaXuxNbjoiIyIK1r15CBuOCWGhl7uH7xq6SxWJATp8164OvqXpVyc5WIyIisnDFM7ujVBZ3XXnDhSd48TbUqHWyVAzI6ZPE11NNbg7F97arkQpvUT1PGuTxdGGrERERWYHe/x+EK6S6hynqf7Blz15jV8kiMYecPmn3zs3oY3MONXEOVdSXEFrlIFuMiIjISlTJnRrd3S/h5+Bxsrz56hy8qV8bKZ3sjV01i8IRcoqX+Foq9935uvKRlE1RIsZXV0RERGTZVCoVCldrAX8lejJnfRzHpoP/GbtaFocBOcVr8569qK4+L68/U9yRr3ZXthYREZGVqVM0Ozba1ZfXbVUaOJydiZDwKGNXy6IwIKc4vQkOR7qrc3TlLcmaonK+DGwtIiIiK2Nro0byir0RrETvP9JYsx+bT1wydrUsCgNyitOGAydRD8fldfE1VcYaveTXVkRERGR9GpUrhE3qGvJ6MlU4Qo7ORESUxtjVshgMyOkjweGRcDo7Q34tJWy0byC/riIiIiLr5Ghng4hSvRGh2Mhyk8gd2HnujrGrZTEYkNNHNhw+hybKAXk9SHGAc8U+8usqIiIisl6Nq5TBdlSQ11OqgvBi3wxEaRRjV8siMMqiWEIjooCT0+GgipDlDTa18U3ZAmwlIiIiK+eazA6vivSBRolOYW0SthF7Lj4wdrUsAgNyimX1mce4H+aK10oKhCp2UJfrL7+mIiIiImpSsyp2KmVkQzxXUmHNwdPQcJT8q3FjINIJj9Rg9uF7eB5VFyujqqKS0yP8U6kYW4iIiIgkj+QOeFRwADpeqITDmkLAKxX233yJmvnSsoW+AkfISWf9+Sd4/jZUXg+BIwpXagQne35mIyIiovea1a6Gk6qiYtsgWZ524A4UhbnkX4MBOUmRURrMPHRX1xoujrb4tkxmtg4RERHFktbFES1LZtSVLz95iyN3fNlKX4EBOUnbz95B24CFSAN/We5cPitSONqxdYiIiOgjvSpnh606eoS8hOomjuxYxVHyr8CAnOSSRT77p6O37VYcdRiENg4n0Ll8FrYMERERxSmjmxNaF3bDKvvRWOfwO9r7TcN/d1+xtRiQ05faffE+moZtktftEIlsRSohpZM9G5SIiIji1a16IWj+n0eeVe2D8zvns7W+EEfIrZxYqsh7z0x4qAJkWSxl1LRmFWNXi4iIiExcFg9nnM/cXVeu6bsM5x6+NmqdzBUDcit34Ko3Goes15WfFOiDVMkdjFonIiIiMg+16zfHWU0ueT2X+ilObl9s7CqZJQbkVkwsUXRn92x4qqIncu7VlETjOrWMXS0iIiIyEzk9XfBfxi66chWff3Hl8Ruj1skcMSC3YoeuP0Gjd6t15bt5esmljIiIiIgSqmr9NrikySavF1A/xKGtS9h45hiQz5gxA1myZIGjoyNKly6N06dPx3vbefPmoWLFinBzc5OXGjVqfPL2FP/o+I0dM5BBFZ3rdVBTFI3q1WdzERERkV7yZ0iJI56ddOXqLxbgkrcfW9GcAvLVq1djyJAhGDlyJM6fP4/ChQujdu3aePnyZZy3P3ToENq0aYODBw/i5MmT8PLyQq1atfD06dMkr7s523fFG03frdKVb+Tpiwwpkxm1TkRERGSeqjbqiMuarPJ6PvUjHN2yyNhVMitGD8gnTZqE7t27o3PnzsiXLx9mz54NJycnLFy4MM7bL1++HH369EGRIkWQJ08ezJ8/HxqNBvv370/yupvzyirr9x6G8v+livZpSqBJ/QbGrhYRERGZqQIZU+JI+vcrrri9OI5zj6LnqNHn2cKIwsPDce7cOQwfPlx3TK1WyzQUMfqdEMHBwYiIiIC7u3ucPw8LC5MXrYCA6OX9RBAvLoYgHlekhBjq8b/WjivPsetVKhzEJLS2OQjPAlVRLYWDydbX1Jl6f1PiYn9bF/a3dWF/f51qDdthyayD2KUphZOa/Ci/9xaWdikFa+1vjR6Pa9SA3NfXF1FRUUibNm2s46J88+bNBD3GsGHDkD59ehnEx2Xs2LEYNWrUR8f9/f0RGRkJQ3VAYGCg7GTxAcPUduWctOeWvB4Ge6xS1cHmskXg58dcL0vsb0p87G/rwv62Luzvr5PGATiW/TucvBUdUxy/+xr7Lj1EMS8XWGN/BwYGmkdA/rX++usvrFq1SuaViwmhcRGj7yJHPeYIucg7FxNCXVxcDNbBKpVKnsPUArQtl57h/usQXfnbMlmQK5OnUetk7ky5vynxsb+tC/vburC/v97Quvmx7/ZRKEp0ef6pF1hZKLP8O2lt/W1ra2seAbmHhwdsbGzg4+MT67goe3p+OkicMGGCDMj37duHQoUKxXs7BwcHefmQaHhDBk+igw19Dn1FRmlwavcqeKnc8VhJCyd7G/Sqkt2k6miuTLG/yXDY39aF/W1d2N9fJ5enC74pnB6bLj4Ta7rBwfswTt3LhnK5PK2uv9V6PKZRowd7e3sUL1481oRM7QTNsmXLxnu/v//+G6NHj8auXbtQokSJJKqt+dt+5jZ+CPkHB+y/x5+2C9CxbGZ4cFdOIiIiSkQDa+RCMZt72Gg/Ekvt/8L5bXNkWgjFz+jDeSKdRKwtvmTJEty4cQO9e/dGUFCQXHVF6NChQ6xJn+PGjcMvv/wiV2ERa5e/ePFCXt69e2fEZ2H6IqI08N0/GW6qd7BTRSG5TTh6VMpu7GoRERGRhcnq4YxqOd1QVH1Xlhu9WYrDN7g8tUkH5K1atZLpJ7/++qtcyvDixYty5Fs70dPb2xvPnz/X3X7WrFlydZbmzZsjXbp0uot4DIrfxmOX0DJ8k7weqajhW2wg3Jzt2WRERESU6Bo1bIajmuiU4kzqV7i2dZpcdplMeFJnv3795CUuYsJmTA8fPkyiWlmOoLBIRByagBSq6Mmcm1RV0bxWFWNXi4iIiCxUplRO2JZ7ACre6SbLLYNXYMf5rmhQIpexq2aSjD5CToa3Zt8JNNfsktdDFHuElh8K12R2bHoiIiIymOYNG2Knpoy8nloVAJ/dExEeyT074sKA3MK9fhcG99Pj4aCKXnN9rW0DNK9iuov0ExERkWVI4+KIJ8W+k6myQqvwTVh/9IKxq2WSGJBbuDU7dqMhjsrrbxRnpKjxPRztbIxdLSIiIrICrepUxQZVdXk9uSoUypGJeBdmmI0ZzRkDcgv22C8Yea5OgloVPYlitWNLNCqdz9jVIiIiIivh4miHiApDEaxE7wkjUmhX74keKKT3GJBbsGk7ziMDXsrrzxR3ZK8/GDZq09spi4iIiCxXs8olZMqsYK+KwuMz2/AyINTY1TIpJrHKCiW+c4/8sebqW6zHX2hjcwBuHmkxpGAmNjURERElKZEq61pzKPZvv4+pkU1wScmBoN23ML5FYfbE/3GE3AKJdT5/33ZdXo+CDZZF1UTVZr3k9rBERERESa1hqTyYlHq0DMaFdeef4MqTt+yI/2NAboE2X3qKS4/f6MqNi6RHsUxuRq0TERERWS+RMvtLg/fz2BQF+H3bNSjiCjEgtzTB4ZG4tm0m8quiN1BytFPjhzp5jF0tIiIisnJlsqVC3QKe8roaGmR+vAm7L9w3drVMAnPILczK3UcxNHIO7OyjsDyqOl5XGoP0KZMZu1pERERE+KleXjy/cQpjbGYjn/oR5u94i9CCM61+SWamrFiQp29CkPHsGLkJkFjqUHFIgZ6Vo3O1iIiIiIzNy90J9UtkQ07VE1luF7EBq/aegLVjQG5B1qxcjNqq0/L6K8UF7rWHI5k9NwEiIiIi09GmXg2sVdeR15OpwpHuv9/h/ToY1owBuYXYe/khmj6fpCuvdu2G+iVzGbVORERERB9K7mALp5o/ycFDobb6NNatmm/VEzwZkFsAsQXt082/I7M6ehOgU5q8qNFmEJc5JCIiIpP0Tdn8WOnWS1du+XKKVU/wZEBuAZZu2Y22kZvk9XDFBheLjESedK7GrhYRERFRnMTeKPXa9MdxTQFZzqjyxcttvyMgNMIqW4wBuZm7+uQNil35XW5FK6ywbYpvG9Q0drWIiIiIPilHWhfcKPYbwhQ7WW4TtRVLN+2wylZjQG7GIqM0OLBqEkqrb8ryQ01aZGnyC5zsuZolERERmb729athmX1zed1OFYUy10fjwkNfWBsG5GZszpH72Pw6Iy5qssvy5gzfoUqBzMauFhEREVGCONrZIGfTEbinSYcoRSXnwQ1bdwGhEdHf/FsLDqWaqevPAjB5321EKBnQLPw31HO8gp9bdzR2tYiIiIj0UilvRvyTdQSO3PbFBSUn4BuO8btv4ZcG+aymJTlCbobCIzX4bu0lRERFLw8UBRtUbdQRnq6Oxq4aERERkd46t2qJp8mjJ3gKC48/wKn7r62mJRmQm6E5Ww7C+7mPrlwzX1o0KZrBqHUiIiIi+lIpnewxrlkhXVksSf7n6oN4ExxuFY3KgNzMHLr6CDUuDsIW+xHIp3oINyc7jGlSkGuOExERkVmrmicNWpXwggoa9LDZirWhPbFg6RKr2DCIAbkZef42BC/XfY+8am9kVz/H33ZzMb5ZIaRO4WDsqhERERF9tV8a5kMX1wv4yW4lHFSR+PbZH1h16LzFtywDcjMRFhmFFQv+QUvskeVQxQ7HCv6BGvk9jV01IiIiokSR3MEWTTv0xzFNQVlOo3qDTAcH4NyD6N3ILRUDcjMgvqqZuWI9+r6dpDs2L0VvdGlS36j1IiIiIkps+TO44Xm1KXilRO86Xl59Fbf+HYSnb0IstrEZkJuB5ftOo/W9YXBURW8nuwlV8U2nH2Fvy+4jIiIiy9O8cjEsz/Q7IhQbWW6rbMfauWMQHB4JS8SIzsTtOHsHBY/2QjqVnyyf0+SCZ9uZyOThbOyqERERERmESqVCz2+/xezkfXTH+gTNwIz58+Tyz5aGAbkJO3D5EVJt+RaF1fdl+amSCg9rzEGZXOmNXTUiIiIig0pmb4MWPUZgtbqeLNurotDXZySmLl6GyCjLCsoZkJuow7dfYdvauSitviHL/kpybC0wBc0qFTN21YiIiIiShKerI/J2moZ9SklZdlKF4RvvvzBs3QWLCsoZkJugDeefoOviM9gQUQ6jI9ohQEmGZdknoWfzBsauGhEREVGSKpTJA8nb/StXXnmsSY0uEd9j/YUX6Ln0nMXklDMgNyEajYLpB+5gyJpLiNREL4K/IKo+xmRfjj7tW3LzHyIiIrJKZXKlR1TLZWgV+RseK2nlsf03X6LtvFPwCQiFuWNAbiJeBoRi0oxpeLP/n1jHmxfPiNHtqsJGrTJa3YiIiIiMrXKBLPizYy0ks4teeUV49Ngb2yb1wv7Lj2DOTCIgnzFjBrJkyQJHR0eULl0ap0+f/uTt165dizx58sjbFyxYEDt27IC5EjOFVx2+hIOTOuD7179guO0KlFTdlD/rVzUHxjcvBDsbk+gmIiIiIqOqmjsNVvUog1TO9mKnFoyzm4eu2IgM6+pj8qJleOwXbJY9ZPRIb/Xq1RgyZAhGjhyJ8+fPo3DhwqhduzZevox7R6YTJ06gTZs26Nq1Ky5cuIDGjRvLy9WrV2FO/ILCseLwZSwcNxD1DtRBK+yWx21UCprZncTfzQvh+9q5maZCREREFENhr5TY0Kcc6qUNQCX1ZXksj/oxBj3qi5uTG2HGig24/OSN3FjRXKgUI9dWjIiXLFkS06dPl2WNRgMvLy/0798fP/7440e3b9WqFYKCgrBt2zbdsTJlyqBIkSKYPXv2Z88XEBAAV1dXvH37Fi4uLjAE8Rz8/Pzg7u4OtTr6M8/b4Aicf+SLR7cvI/ThGWR5fRhVVefhoHo/GSFUscOi5F1Rq+MIZE+TwiB1o6Tpb7Jc7G/rwv62Luxv88syWLJ5Jypc+hF51d6xfnZDkwnHHCtD8SqNNLlKoWC2DMjm4RxroNPQ/a1PzGkLIwoPD8e5c+cwfPhw3THRIDVq1MDJkyfjvI84LkbUYxIj6ps2bYKpuvUiELUnH0Erm4PyqxUpRr9HKSpsVlVFSPmh6FqtDHfgJCIiIvoMsWN592b1cbZoSczcOA3NAv5FWtUb+TMRoOcNXwrcW4qLd7Khevgf6Fw+C0Y2zA9TZNSA3NfXF1FRUUibNnq2rJYo37wZnUf9oRcvXsR5e3E8LmFhYfIS89OK9lORuBiCeFzxxYP28bOmSgZHOzWuRmaNdbtXigv22VREcMFv0axWNbgks9Pdn8zHh/1Nlo39bV3Y39aF/W2eimXxQNFBv2H/lc54uH8+SrzdjWLqu7qfX9VEx1/50qWI9bfa0P2tz+MaNSBPCmPHjsWoUaM+Ou7v74/IyEiDdUBgYKDsZO1XIPnSOuPyk4zYHlUKzxxzITxNIWQuVBlVs6aCrVqFyJBA+IUYpDpkYHH1N1ku9rd1YX9bF/a3eSuW0QXFOg7Bkzd9MPvCJSiPTsIt4AYOaQrLn2d1UckUlaTqb/HYZhGQe3h4wMbGBj4+PrGOi7Knp2ec9xHH9bm9SIeJmeIiRshFjrqbm5tBc8hFjpI4h7aDB9XKIzu8cMY6upFwsgxx9TdZLva3dWF/Wxf2t2VwdwcKZUsPoK7czbOAzztUffIGRbOn/yiH3JB/v21tbc0jILe3t0fx4sWxf/9+uVKKtnFEuV+/fnHep2zZsvLngwYN0h3bu3evPB4XBwcHefmQaHhDBk+ig2Oeo1KuNAY7Fxnfh/1Nlo39bV3Y39aF/W1Z7NVqFMiYUl6Sur/1eUyjp6yI0euOHTuiRIkSKFWqFCZPnixXUencubP8eYcOHZAhQwaZeiIMHDgQlStXxsSJE1G/fn2sWrUKZ8+exdy5c438TIiIiIiI9Gf0gFwsY/jq1Sv8+uuvcmKmWL5w165duomb3t7esT5hlCtXDitWrMCIESPw008/IWfOnHKFlQIFChjxWRARERERmek65EnNWOuQk+Vif1sX9rd1YX9bF/a3ddGY0DrkjBaJiIiIiIyIATkRERERkRExICciIiIiMiIG5ERERERERsSAnIiIiIjIiBiQExEREREZEQNyIiIiIiIjYkBORERERGREDMiJiIiIiIyIATkRERERkRHZwsooiqLbztSQW7EGBgbC1tbWIFuxkmlhf1sX9rd1YX9bF/a3ddEYOF7Txpra2PNTrC4gFw0veHl5GbsqRERERGQFsaerq+snb6NSEhK2W9inoWfPniFFihRQqVQGOYf4RCQC/sePH8PFxcUg5yDTwf62Luxv68L+ti7sb+sSYOB4TYTYIhhPnz79Z0fgrW6EXDRIxowZk+RconMZkFsP9rd1YX9bF/a3dWF/WxcXA8ZrnxsZ12KCMxERERGRETEgJyIiIiIyIgbkBuDg4ICRI0fK/8nysb+tC/vburC/rQv727o4mFC8ZnWTOomIiIiITAlHyImIiIiIjIgBORERERGRETEgJyIiIiIyIgbkX2jGjBnIkiULHB0dUbp0aZw+ffqTt1+7di3y5Mkjb1+wYEHs2LHjS09NJt7f8+bNQ8WKFeHm5iYvNWrU+Ozrg8z7/a21atUqueFY48aNDV5HMl5/v3nzBn379kW6dOnkZLBcuXLxd7oF9/fkyZORO3duJEuWTG4iM3jwYISGhiZZfenLHDlyBA0bNpSb8ojfy5s2bfrsfQ4dOoRixYrJ93WOHDmwePFiJBkxqZP0s2rVKsXe3l5ZuHChcu3aNaV79+5KypQpFR8fnzhvf/z4ccXGxkb5+++/levXrysjRoxQ7OzslCtXrrDpLbC/27Ztq8yYMUO5cOGCcuPGDaVTp06Kq6ur8uTJkySvOxm+v7UePHigZMiQQalYsaLyzTffsOkttL/DwsKUEiVKKPXq1VOOHTsm+/3QoUPKxYsXk7zuZPj+Xr58ueLg4CD/F329e/duJV26dMrgwYPZ/CZux44dys8//6xs2LBBLF6ibNy48ZO3v3//vuLk5KQMGTJExmrTpk2TsduuXbuSpL4MyL9AqVKllL59++rKUVFRSvr06ZWxY8fGefuWLVsq9evXj3WsdOnSSs+ePb/k9GTi/f2hyMhIJUWKFMqSJUsMWEsyZn+LPi5Xrpwyf/58pWPHjgzILbi/Z82apWTLlk0JDw9PwlqSsfpb3LZatWqxjomArXz58uwUM4IEBOQ//PCDkj9//ljHWrVqpdSuXVtJCkxZ0VN4eDjOnTsn0xC01Gq1LJ88eTLO+4jjMW8v1K5dO97bk3n394eCg4MREREBd3d3A9aUjNnfv//+O9KkSYOuXbuyIyy8v7ds2YKyZcvKlJW0adOiQIECGDNmDKKiopKw5pRU/V2uXDl5H21ay/3792V6Ur169dgJFuakkWM12yQ5iwXx9fWVv3jFL+KYRPnmzZtx3ufFixdx3l4cJ8vr7w8NGzZM5rB9+EYny+jvY8eOYcGCBbh48WIS1ZKM2d8iIDtw4ADatWsnA7O7d++iT58+8kO32GCELKu/27ZtK+9XoUIFkVGAyMhI9OrVCz/99FMS1ZqSSnyxWkBAAEJCQuQcAkPiCDmRAf31119yot/GjRvlBCKyLIGBgfj222/lRF4PDw9jV4eSgEajkd+GzJ07F8WLF0erVq3w888/Y/bs2Wx/CyQm+YlvQGbOnInz589jw4YN2L59O0aPHm3sqpGF4Qi5nsQfXRsbG/j4+MQ6Lsqenp5x3kcc1+f2ZN79rTVhwgQZkO/btw+FChUycE3JGP197949PHz4UM7kjxmwCba2trh16xayZ8/OzrGg97dYWcXOzk7eTytv3rxydE2kRNjb2xu83pR0/f3LL7/ID93dunWTZbFKWlBQEHr06CE/iImUF7IMnvHEai4uLgYfHRf4StKT+GUrRkX2798f6w+wKIu8wriI4zFvL+zduzfe25N597fw999/yxGUXbt2oUSJEklUW0rq/hZLmV65ckWmq2gvjRo1QtWqVeV1sUQaWdb7u3z58jJNRfvBS7h9+7YM1BmMW15/izlAHwbd2g9j0XMFyVKUNXasliRTRy1w2SSxDNLixYvl0jg9evSQyya9ePFC/vzbb79Vfvzxx1jLHtra2ioTJkyQy+CNHDmSyx5acH//9ddfclmtdevWKc+fP9ddAgMDjfgsyFD9/SGusmLZ/e3t7S1XTerXr59y69YtZdu2bUqaNGmUP/74w4jPggzV3+LvtejvlStXymXx9uzZo2TPnl2unkamLTAwUC4/LC4i3J00aZK8/ujRI/lz0c+ivz9c9nDo0KEyVhPLF3PZQzMg1qfMlCmTDLzEMkr//fef7meVK1eWf5RjWrNmjZIrVy55e7Gszvbt241Qa0qK/s6cObN88394Eb/YyTLf3zExILf8/j5x4oRculYEdmIJxD///FMufUmW198RERHKb7/9JoNwR0dHxcvLS+nTp4/i7+9vpNpTQh08eDDOv8Xa/hX/i/7+8D5FihSRrw3x3l60aJGSVFTin6QZiyciIiIiog8xh5yIiIiIyIgYkBMRERERGREDciIiIiIiI2JATkRERERkRAzIiYiIiIiMiAE5EREREZERMSAnIiIiIjIiBuREREREREbEgJyIiIiIyIgYkBMRERER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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "u = np.linspace(0.01, 0.99, 500)\n", + "x_logistic = logistic.ppf(u)\n", + "transport = norm.cdf(x_logistic)\n", + "numerical_derivative = np.gradient(transport, u, edge_order=2)\n", + "density_ratio = norm.pdf(x_logistic) / logistic.pdf(x_logistic)\n", "\n", - " Previous behavior required\n", + "interior = slice(2, -2)\n", + "absolute_error = np.abs(numerical_derivative - density_ratio)\n", "\n", - " $$\n", - " [0.25,0.75] = [0,1],\n", - " $$\n", + "print(\n", + " \"Maximum interior absolute error:\",\n", + " f\"{absolute_error[interior].max():.3e}\",\n", + ")\n", + "print(\n", + " \"Mean interior absolute error:\",\n", + " f\"{absolute_error[interior].mean():.3e}\",\n", + ")\n", + "print(\n", + " \"All verification values finite:\",\n", + " np.isfinite(numerical_derivative).all()\n", + " and np.isfinite(density_ratio).all(),\n", + ")\n", "\n", - " which is false, so the chain was considered incompatible.\n", + "fig, ax = plt.subplots(figsize=(7.5, 4.8))\n", + "ax.plot(u, numerical_derivative, linewidth=2.5, label=r\"Numerical $T'(u)$\")\n", + "ax.plot(\n", + " u,\n", + " density_ratio,\n", + " linestyle=\"--\",\n", + " linewidth=2,\n", + " label=r\"$p_G(F_L^{-1}(u))/p_L(F_L^{-1}(u))$\",\n", + ")\n", + "ax.set(\n", + " xlabel=\"Logistic-based Uniform coordinate $u$\",\n", + " ylabel=\"Derivative / density ratio\",\n", + " title=\"Likelihood ratio as a transport Jacobian\",\n", + ")\n", + "ax.grid(alpha=0.25)\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b6cd52e8", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-19T21:44:29.620366Z", + "iopub.status.busy": "2026-08-19T21:44:29.620182Z", + "iopub.status.idle": "2026-08-19T21:44:29.627234Z", + "shell.execute_reply": "2026-08-19T21:44:29.626109Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Target E[X^2]: 1.0\n", + "Direct Gaussian-QMC estimate: 0.999295953\n", + "Logistic IS-QMC estimate: 1.000000026\n", + "All integral-check values finite: True\n" + ] + } + ], + "source": [ + "qmc_u = DigitalNetB2(1, seed=7).gen_samples(2**12).reshape(-1)\n", "\n", - " Under the updated rule,\n", + "gaussian_samples = norm.ppf(qmc_u)\n", + "direct_gaussian_qmc = np.mean(gaussian_samples**2)\n", "\n", - " $$\n", - " [0.25,0.75] \\subseteq [0,1],\n", - " $$\n", + "logistic_samples = logistic.ppf(qmc_u)\n", + "logistic_weights = norm.pdf(logistic_samples) / logistic.pdf(logistic_samples)\n", + "logistic_is_qmc = np.mean(logistic_samples**2 * logistic_weights)\n", "\n", - " so the chain is correctly accepted as domain-compatible because every output of the preceding transformation lies inside the input domain of the next transformation.\n", + "print(\"Target E[X^2]:\", 1.0)\n", + "print(\"Direct Gaussian-QMC estimate:\", f\"{direct_gaussian_qmc:.9f}\")\n", + "print(\"Logistic IS-QMC estimate:\", f\"{logistic_is_qmc:.9f}\")\n", + "print(\n", + " \"All integral-check values finite:\",\n", + " np.isfinite(gaussian_samples).all()\n", + " and np.isfinite(logistic_samples).all()\n", + " and np.isfinite(logistic_weights).all(),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "2938bb1c", + "metadata": {}, + "source": [ + "## 6. Takeaways and next step\n", "\n", - "5. The change does not weaken compatibility checking. A range that actually extends outside the next domain is still rejected. For example,\n", + "1. **Current PR:** chained `TrueMeasure` domain compatibility changes from exact equality to containment:\n", "\n", " $$\n", - " [-0.1,0.75] \\nsubseteq [0,1].\n", + " R_{j-1}=D_j\n", + " \\quad\\longrightarrow\\quad\n", + " R_{j-1}\\subseteq D_j.\n", " $$\n", "\n", - "6. The initial scope is one-dimensional intervals and multidimensional axis-aligned boxes with finite or unbounded numerical endpoints, represented using values such as `-np.inf` and `np.inf`. Because the metadata does not separately encode open and closed finite endpoints, the comparison operates on stored interval envelopes. Disconnected supports such as\n", - "\n", - " $$\n", - " [0,5]\\cup[10,20]\n", - " $$\n", - "\n", - " and arbitrary nonrectangular domains are outside the scope of this change.\n", - "\n", - "7. Exploring Gaussian, Uniform, and Logistic transformations clarifies an additional point. A Gaussian-to-Logistic deterministic transport is naturally\n", - "\n", - " $$\n", - " X_G\n", - " \\xrightarrow{\\Phi}\n", - " U\n", - " \\xrightarrow{F_L^{-1}}\n", - " X_L,\n", - " $$\n", - "\n", - " or conceptually,\n", - "\n", - " $$\n", - " \\mathrm{Gaussian}\n", - " \\rightarrow\n", - " \\mathrm{Uniform}\n", - " \\rightarrow\n", - " \\mathrm{Logistic}.\n", - " $$\n", - "\n", - " The complete transport can be written as\n", + "2. **Safety remains:** strict containment is accepted, while ranges that actually leave the next domain remain rejected.\n", "\n", - " $$\n", - " T(x)=F_L^{-1}(\\Phi(x)).\n", - " $$\n", + "3. **QMC direction:** Sobol points already begin in Uniform space; direct Gaussian and Logistic sampling are $U\\rightarrow X_G$ and $U\\rightarrow X_L$.\n", "\n", - "8. The reverse transport is\n", + "4. **Pure deterministic detour:** Gaussian $\\rightarrow$ Logistic $\\rightarrow$ Uniform collapses to Gaussian $\\rightarrow$ Uniform, so inserting Logistic only as a CDF/inverse-CDF transport adds nothing by itself.\n", "\n", - " $$\n", - " X_L\n", - " \\xrightarrow{F_L}\n", - " U\n", - " \\xrightarrow{\\Phi^{-1}}\n", - " X_G.\n", - " $$\n", + "5. **Importance sampling is the meaningful alternative:** Logistic changes the sampling measure through $p_G/p_L$, and in one dimension that likelihood ratio is the Jacobian\n", "\n", - " The numerical round-trip experiment recovers the original Gaussian values up to floating-point roundoff, confirming the expected inverse relationship.\n", - "\n", - "9. This also shows an important limitation of the current change: domain-range inclusion makes existing transformation chains more flexible, but it does not by itself create arbitrary distribution-to-distribution transport maps.\n", - "\n", - " A Gaussian-to-Logistic transport requires a forward Gaussian CDF followed by a Logistic inverse CDF, while many current `TrueMeasure` transformations are structured primarily around generating a target measure from the preceding sampler.\n", - "\n", - "10. Transport and importance sampling should therefore remain conceptually separate.\n", - "\n", - " For transport, the concern is whether deterministic maps can be composed through compatible intermediate spaces.\n", - "\n", - " For importance sampling, a proposal density $q$ can instead be used to sample $X$ and correct for a target density $p$ using\n", - "\n", - " $$\n", - " g(X)\\frac{p(X)}{q(X)}.\n", - " $$\n", - "\n", - " The Logistic distribution can therefore play a different role as an importance-sampling proposal rather than as an intermediate deterministic transport.\n", - "\n", - "Hence, this change provides a small but useful generalization of `TrueMeasure` composition:\n", - "\n", - "$$\n", - "\\boxed{\n", - "R_{j-1} = D_j\n", - "\\quad\\longrightarrow\\quad\n", - "R_{j-1} \\subseteq D_j\n", - "}\n", - "$$\n", - "\n", - "for the current interval and axis-aligned box representation.\n", + " $$\n", + " \\frac{d}{du}F_G(F_L^{-1}(u)).\n", + " $$\n", "\n", - "It recognizes domain-compatible chained transformations that were previously rejected solely because their intermediate bounds were not identical, while preserving rejection of genuinely incompatible boundaries." + "**Next question.** The current domain-inclusion PR should remain scoped as implemented. A separate follow-up can examine how QMCPy's existing importance-sampling machinery represents this Gaussian/Logistic relationship and whether any additional transport/Jacobian semantics are actually needed." ] } ], "metadata": { "kernelspec": { - "display_name": ".venv (3.13.5.final.0)", + "display_name": "qmcpy kernel", "language": "python", - "name": "python3" + "name": "qmcpy" }, "language_info": { "codemirror_mode": { From 6ed224f025800cc7323f751a08cb01d3d4964411 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Aug 2026 21:50:03 +0000 Subject: [PATCH 3/6] Address TrueMeasure review feedback Co-authored-by: fjhickernell <817530+fjhickernell@users.noreply.github.com> --- qmcpy/true_measure/abstract_true_measure.py | 5 +++++ test/booktests/tb_true_measure_domain_inclusion.py | 14 ++++++++++++++ test/test_true_measures.py | 4 ++++ 3 files changed, 23 insertions(+) create mode 100644 test/booktests/tb_true_measure_domain_inclusion.py diff --git a/qmcpy/true_measure/abstract_true_measure.py b/qmcpy/true_measure/abstract_true_measure.py index c51edc335..030105a5c 100644 --- a/qmcpy/true_measure/abstract_true_measure.py +++ b/qmcpy/true_measure/abstract_true_measure.py @@ -49,6 +49,11 @@ def _range_in_domain(transform_range, domain): except ValueError: return False + if np.any(transform_range[:, 0] > transform_range[:, 1]): + return False + if np.any(domain[:, 0] > domain[:, 1]): + return False + lower_bounds_valid = np.all(domain[:, 0] <= transform_range[:, 0]) upper_bounds_valid = np.all(transform_range[:, 1] <= domain[:, 1]) return bool(lower_bounds_valid and upper_bounds_valid) diff --git a/test/booktests/tb_true_measure_domain_inclusion.py b/test/booktests/tb_true_measure_domain_inclusion.py new file mode 100644 index 000000000..3238f2b02 --- /dev/null +++ b/test/booktests/tb_true_measure_domain_inclusion.py @@ -0,0 +1,14 @@ +import unittest +from testbook import testbook +from __init__ import TB_TIMEOUT, BaseNotebookTest + + +class NotebookTests(BaseNotebookTest): + + @testbook('../../demos/true_measure_domain_inclusion.ipynb', execute=True, timeout=TB_TIMEOUT) + def test_true_measure_domain_inclusion_notebook(self, tb): + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_true_measures.py b/test/test_true_measures.py index 1c3109fe5..60aaa01ef 100644 --- a/test/test_true_measures.py +++ b/test/test_true_measures.py @@ -90,6 +90,10 @@ def test_range_in_domain_rejects_invalid_bound_shapes(self): ([[0, 0.5, 1]], [[0, 1]]), ([[0, 1]], [0, 1]), ([[0, 1]], [[0, 0.5, 1]]), + ([[0.8, 0.2]], [[0, 1]]), + ([[0, 1]], [[0.8, 0.2]]), + ([[0.1, 0.8], [0.9, 0.2]], [[0, 1], [0, 1]]), + ([[0.1, 0.8], [0.2, 0.9]], [[0, 1], [0.9, 0.2]]), ] for transform_range, domain in invalid_cases: From 83b9dc9b417ae5cffd283dbe508bce11de19b86b Mon Sep 17 00:00:00 2001 From: Laasya-73 <77721581+Laasya-73@users.noreply.github.com> Date: Mon, 24 Aug 2026 14:40:15 -0500 Subject: [PATCH 4/6] Harden TrueMeasure domain inclusion and expand coverage --- demos/true_measure_domain_inclusion.ipynb | 186 +++++++++++++----- docs/api/discrete_distributions.md | 5 +- mkdocs.yml | 1 + qmcpy/true_measure/abstract_true_measure.py | 32 ++- .../tb_true_measure_domain_inclusion.py | 8 +- test/test_true_measures.py | 60 ++++-- 6 files changed, 219 insertions(+), 73 deletions(-) diff --git a/demos/true_measure_domain_inclusion.ipynb b/demos/true_measure_domain_inclusion.ipynb index c98f73425..00c8f6367 100644 --- a/demos/true_measure_domain_inclusion.ipynb +++ b/demos/true_measure_domain_inclusion.ipynb @@ -91,14 +91,14 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 28, "id": "8d512296", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:27.550157Z", - "iopub.status.busy": "2026-08-19T21:44:27.549925Z", - "iopub.status.idle": "2026-08-19T21:44:29.196026Z", - "shell.execute_reply": "2026-08-19T21:44:29.194739Z" + "iopub.execute_input": "2026-08-24T19:24:44.410561Z", + "iopub.status.busy": "2026-08-24T19:24:44.409591Z", + "iopub.status.idle": "2026-08-24T19:24:46.645979Z", + "shell.execute_reply": "2026-08-24T19:24:46.644328Z" } }, "outputs": [], @@ -109,14 +109,20 @@ "from matplotlib.patches import Rectangle\n", "from scipy.stats import logistic, norm\n", "\n", - "from qmcpy import DigitalNetB2, Kumaraswamy, Uniform\n", - "from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure\n", + "from qmcpy import (\n", + " AbstractTrueMeasure,\n", + " CubQMCSobolG,\n", + " CustomFun,\n", + " DigitalNetB2,\n", + " Kumaraswamy,\n", + " Uniform,\n", + ")\n", "from qmcpy.util import ParameterError\n", "\n", "\n", "def previous_compatibility_check(transform_range, domain):\n", " # Reproduce the previous broadcasted exact-equality rule.\n", - " return not (np.asarray(domain) != np.asarray(transform_range)).any()" + " return not (np.asarray(domain) != np.asarray(transform_range)).any()\n" ] }, { @@ -131,14 +137,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 29, "id": "ed148c64", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.198407Z", - "iopub.status.busy": "2026-08-19T21:44:29.198143Z", - "iopub.status.idle": "2026-08-19T21:44:29.209924Z", - "shell.execute_reply": "2026-08-19T21:44:29.208877Z" + "iopub.execute_input": "2026-08-24T19:24:46.650630Z", + "iopub.status.busy": "2026-08-24T19:24:46.649593Z", + "iopub.status.idle": "2026-08-24T19:24:46.680364Z", + "shell.execute_reply": "2026-08-24T19:24:46.679106Z" } }, "outputs": [ @@ -212,7 +218,7 @@ "4 Multidimensional inclusion False True" ] }, - "execution_count": 2, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -257,14 +263,14 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 30, "id": "e3f1220f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.212669Z", - "iopub.status.busy": "2026-08-19T21:44:29.212435Z", - "iopub.status.idle": "2026-08-19T21:44:29.220857Z", - "shell.execute_reply": "2026-08-19T21:44:29.219801Z" + "iopub.execute_input": "2026-08-24T19:24:46.686289Z", + "iopub.status.busy": "2026-08-24T19:24:46.685485Z", + "iopub.status.idle": "2026-08-24T19:24:46.720415Z", + "shell.execute_reply": "2026-08-24T19:24:46.715058Z" } }, "outputs": [ @@ -313,14 +319,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 31, "id": "3b524d4a", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.222806Z", - "iopub.status.busy": "2026-08-19T21:44:29.222615Z", - "iopub.status.idle": "2026-08-19T21:44:29.229709Z", - "shell.execute_reply": "2026-08-19T21:44:29.228187Z" + "iopub.execute_input": "2026-08-24T19:24:46.724795Z", + "iopub.status.busy": "2026-08-24T19:24:46.724399Z", + "iopub.status.idle": "2026-08-24T19:24:46.737550Z", + "shell.execute_reply": "2026-08-24T19:24:46.734862Z" } }, "outputs": [ @@ -376,14 +382,14 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 32, "id": "fd51b128", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.233556Z", - "iopub.status.busy": "2026-08-19T21:44:29.233190Z", - "iopub.status.idle": "2026-08-19T21:44:29.239274Z", - "shell.execute_reply": "2026-08-19T21:44:29.238566Z" + "iopub.execute_input": "2026-08-24T19:24:46.743432Z", + "iopub.status.busy": "2026-08-24T19:24:46.742993Z", + "iopub.status.idle": "2026-08-24T19:24:46.752101Z", + "shell.execute_reply": "2026-08-24T19:24:46.750435Z" } }, "outputs": [ @@ -426,21 +432,21 @@ "source": [ "The change accepts strict containment without accepting genuinely out-of-domain transformations.\n", "\n", - "### One compatibility visual\n", + "### D. One compatibility visual\n", "\n", "For axis-aligned boxes, compatibility is checked coordinate by coordinate. The dashed box is fully contained; the dotted box violates the second-coordinate upper bound." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 33, "id": "490d7fe0", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.241535Z", - "iopub.status.busy": "2026-08-19T21:44:29.241347Z", - "iopub.status.idle": "2026-08-19T21:44:29.455867Z", - "shell.execute_reply": "2026-08-19T21:44:29.454754Z" + "iopub.execute_input": "2026-08-24T19:24:46.754962Z", + "iopub.status.busy": "2026-08-24T19:24:46.754730Z", + "iopub.status.idle": "2026-08-24T19:24:46.996190Z", + "shell.execute_reply": "2026-08-24T19:24:46.995224Z" } }, "outputs": [ @@ -499,6 +505,96 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "id": "9e3e56de", + "metadata": {}, + "source": [ + "### E. Integration with a compatible chained measure\n", + "\n", + "Here the inner sampler and chained outer target both represent $\\mathcal{U}[0.25,0.75]$, while the inner range is strictly contained in the outer unit domain. Because the mean $\\mathbb{E}[X]=0.5$ is symmetry-driven, the second moment provides a stronger end-to-end check using QMCPy's standard integration API." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "5a1ad5ba", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-24T19:24:47.000674Z", + "iopub.status.busy": "2026-08-24T19:24:47.000331Z", + "iopub.status.idle": "2026-08-24T19:24:47.014019Z", + "shell.execute_reply": "2026-08-24T19:24:47.012979Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Chained-measure integration estimate: 0.500000000\n", + "Exact Uniform mean: 0.500000000\n", + "Absolute error: 5.551e-17\n", + "Within requested tolerance: True\n", + "Chained-measure second-moment estimate: 0.270833333335\n", + "Exact second moment: 0.270833333333\n", + "Absolute error: 1.847e-12\n", + "Within requested tolerance: True\n" + ] + } + ], + "source": [ + "integration_inner = Uniform(\n", + " DigitalNetB2(1, seed=7),\n", + " lower_bound=0.25,\n", + " upper_bound=0.75,\n", + ")\n", + "integration_outer = Uniform(\n", + " integration_inner,\n", + " lower_bound=0.25,\n", + " upper_bound=0.75,\n", + ")\n", + "integrand = CustomFun(integration_outer, g=lambda x: x[..., 0])\n", + "\n", + "integration_tolerance = 1e-6\n", + "solution, data = CubQMCSobolG(\n", + " integrand,\n", + " abs_tol=integration_tolerance,\n", + ").integrate()\n", + "solution = float(np.asarray(solution))\n", + "exact_value = 0.5\n", + "absolute_error = abs(solution - exact_value)\n", + "\n", + "print(\"Chained-measure integration estimate:\", f\"{solution:.9f}\")\n", + "print(\"Exact Uniform mean:\", f\"{exact_value:.9f}\")\n", + "print(\"Absolute error:\", f\"{absolute_error:.3e}\")\n", + "print(\"Within requested tolerance:\", absolute_error <= integration_tolerance)\n", + "\n", + "second_moment_integrand = CustomFun(\n", + " integration_outer,\n", + " g=lambda x: x[..., 0] ** 2,\n", + ")\n", + "second_moment_solution, second_moment_data = CubQMCSobolG(\n", + " second_moment_integrand,\n", + " abs_tol=integration_tolerance,\n", + ").integrate()\n", + "second_moment_solution = float(np.asarray(second_moment_solution))\n", + "a, b = 0.25, 0.75\n", + "exact_second_moment = (a**2 + a * b + b**2) / 3\n", + "second_moment_error = abs(second_moment_solution - exact_second_moment)\n", + "\n", + "print(\n", + " \"Chained-measure second-moment estimate:\",\n", + " f\"{second_moment_solution:.12f}\",\n", + ")\n", + "print(\"Exact second moment:\", f\"{exact_second_moment:.12f}\")\n", + "print(\"Absolute error:\", f\"{second_moment_error:.3e}\")\n", + "print(\n", + " \"Within requested tolerance:\",\n", + " second_moment_error <= integration_tolerance,\n", + ")\n" + ] + }, { "cell_type": "markdown", "id": "02c17b09", @@ -685,14 +781,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 35, "id": "f6da6902", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.458107Z", - "iopub.status.busy": "2026-08-19T21:44:29.457910Z", - "iopub.status.idle": "2026-08-19T21:44:29.618284Z", - "shell.execute_reply": "2026-08-19T21:44:29.617387Z" + "iopub.execute_input": "2026-08-24T19:24:47.018298Z", + "iopub.status.busy": "2026-08-24T19:24:47.017888Z", + "iopub.status.idle": "2026-08-24T19:24:47.195600Z", + "shell.execute_reply": "2026-08-24T19:24:47.194506Z" } }, "outputs": [ @@ -762,14 +858,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 36, "id": "b6cd52e8", "metadata": { "execution": { - "iopub.execute_input": "2026-08-19T21:44:29.620366Z", - "iopub.status.busy": "2026-08-19T21:44:29.620182Z", - "iopub.status.idle": "2026-08-19T21:44:29.627234Z", - "shell.execute_reply": "2026-08-19T21:44:29.626109Z" + "iopub.execute_input": "2026-08-24T19:24:47.198770Z", + "iopub.status.busy": "2026-08-24T19:24:47.198263Z", + "iopub.status.idle": "2026-08-24T19:24:47.216129Z", + "shell.execute_reply": "2026-08-24T19:24:47.214482Z" } }, "outputs": [ diff --git a/docs/api/discrete_distributions.md b/docs/api/discrete_distributions.md index daa782cb6..49b60fbb4 100644 --- a/docs/api/discrete_distributions.md +++ b/docs/api/discrete_distributions.md @@ -70,10 +70,7 @@ python -m pip install "qmcpy[mpmc]" qmcpy-install-mpmc ``` -The second command selects the `pyg_lib` wheel page matching the installed -PyTorch and accelerator builds. For GPU support or platform-specific wheels, -see the [PyTorch installation guide](https://pytorch.org/get-started/locally/) -and the [PyTorch Geometric installation guide](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html). +The second command selects the `pyg_lib` wheel page matching the installed PyTorch and accelerator builds. For GPU support or platform-specific wheels, see the [PyTorch installation guide](https://pytorch.org/get-started/locally/) and the [PyTorch Geometric installation guide](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html). ::: qmcpy.discrete_distribution.mpmc.mpmc.MPMC diff --git a/mkdocs.yml b/mkdocs.yml index 792731c47..35edf3f00 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -75,6 +75,7 @@ nav: - Importance Sampling with True Measures: - Statistics for True Measures: demos/statistics_for_TrueMeasure.ipynb - Some True Measures: demos/some_true_measures.ipynb + - TrueMeasure Domain Inclusion: demos/true_measure_domain_inclusion.ipynb - SciPyWrapper dependence and Custom distributions: demos/scipywrapper_dependence_custom/scipywrapper_demo.ipynb - ProductMeasure: demos/product_measure.ipynb - Acceptance-Rejection Sampling: demos/acceptance_rejection.ipynb diff --git a/qmcpy/true_measure/abstract_true_measure.py b/qmcpy/true_measure/abstract_true_measure.py index 030105a5c..929da50bc 100644 --- a/qmcpy/true_measure/abstract_true_measure.py +++ b/qmcpy/true_measure/abstract_true_measure.py @@ -33,25 +33,43 @@ def _read_only_array(value): @staticmethod def _range_in_domain(transform_range, domain): """Return whether a transform range is contained within a domain.""" - transform_range = np.asarray(transform_range) - domain = np.asarray(domain) + try: + transform_range = np.asarray(transform_range) + domain = np.asarray(domain) + except (TypeError, ValueError): + return False if ( transform_range.ndim != 2 or domain.ndim != 2 or transform_range.shape[1] != 2 or domain.shape[1] != 2 + or transform_range.shape[0] == 0 + or domain.shape[0] == 0 ): return False - try: - transform_range, domain = np.broadcast_arrays(transform_range, domain) - except ValueError: + if not ( + np.issubdtype(transform_range.dtype, np.number) + and np.issubdtype(domain.dtype, np.number) + and np.isrealobj(transform_range) + and np.isrealobj(domain) + and transform_range.dtype != np.bool_ + and domain.dtype != np.bool_ + ): return False - if np.any(transform_range[:, 0] > transform_range[:, 1]): + if np.isnan(transform_range).any() or np.isnan(domain).any(): return False - if np.any(domain[:, 0] > domain[:, 1]): + + if np.any(transform_range[:, 0] > transform_range[:, 1]) or np.any( + domain[:, 0] > domain[:, 1] + ): + return False + + try: + transform_range, domain = np.broadcast_arrays(transform_range, domain) + except ValueError: return False lower_bounds_valid = np.all(domain[:, 0] <= transform_range[:, 0]) diff --git a/test/booktests/tb_true_measure_domain_inclusion.py b/test/booktests/tb_true_measure_domain_inclusion.py index 3238f2b02..b34abcb60 100644 --- a/test/booktests/tb_true_measure_domain_inclusion.py +++ b/test/booktests/tb_true_measure_domain_inclusion.py @@ -5,10 +5,14 @@ class NotebookTests(BaseNotebookTest): - @testbook('../../demos/true_measure_domain_inclusion.ipynb', execute=True, timeout=TB_TIMEOUT) + @testbook( + "../../demos/true_measure_domain_inclusion.ipynb", + execute=True, + timeout=TB_TIMEOUT, + ) def test_true_measure_domain_inclusion_notebook(self, tb): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/test/test_true_measures.py b/test/test_true_measures.py index 60aaa01ef..3099128e8 100644 --- a/test/test_true_measures.py +++ b/test/test_true_measures.py @@ -1,4 +1,5 @@ from qmcpy import ( + AbstractTrueMeasure, BernoulliCont, BrownianMotion, DigitalNetB2, @@ -10,6 +11,7 @@ Lattice, Lebesgue, MaternGP, + SciPyWrapper, Uniform, ZeroInflatedExpUniform, ) @@ -20,8 +22,6 @@ import unittest import warnings from qmcpy.true_measure.uniform_triangle import UniformTriangle, _UniformTriangleAdapter -from qmcpy.true_measure.abstract_true_measure import AbstractTrueMeasure -from qmcpy import SciPyWrapper def dense_covariance(covariance): @@ -84,22 +84,52 @@ def test_range_in_domain(self): expected, ) - def test_range_in_domain_rejects_invalid_bound_shapes(self): + def test_range_in_domain_rejects_invalid_bounds(self): invalid_cases = [ - ([0, 1], [[0, 1]]), - ([[0, 0.5, 1]], [[0, 1]]), - ([[0, 1]], [0, 1]), - ([[0, 1]], [[0, 0.5, 1]]), - ([[0.8, 0.2]], [[0, 1]]), - ([[0, 1]], [[0.8, 0.2]]), - ([[0.1, 0.8], [0.9, 0.2]], [[0, 1], [0, 1]]), - ([[0.1, 0.8], [0.2, 0.9]], [[0, 1], [0.9, 0.2]]), + ("one-dimensional range", [0, 1], [[0, 1]]), + ("three-column range", [[0, 0.5, 1]], [[0, 1]]), + ("ragged range", [[0, 1], [0, 0.5, 1]], [[0, 1]]), + ("one-dimensional domain", [[0, 1]], [0, 1]), + ("three-column domain", [[0, 1]], [[0, 0.5, 1]]), + ( + "reversed transform range", + np.array([[0.8, 0.2]]), + np.array([[0.0, 1.0]]), + ), + ("reversed domain", [[0, 1]], [[0.8, 0.2]]), + ( + "reversed multidimensional transform range", + [[0.1, 0.8], [0.9, 0.2]], + [[0, 1], [0, 1]], + ), + ( + "reversed multidimensional domain", + [[0.1, 0.8], [0.2, 0.9]], + [[0, 1], [0.9, 0.2]], + ), + ("empty transform range", np.empty((0, 2)), [[0, 1]]), + ("empty domain", [[0, 1]], np.empty((0, 2))), + ( + "string bounds", + np.array([["a", "z"]]), + np.array([["a", "z"]]), + ), + ( + "object bounds", + np.array([[0, 1]], dtype=object), + np.array([[0, 1]], dtype=object), + ), + ("complex bounds", [[0 + 0j, 1 + 0j]], [[0 + 0j, 1 + 0j]]), + ("boolean bounds", [[False, True]], [[False, True]]), + ("NaN transform range", [[np.nan, 1]], [[0, 1]]), + ("NaN domain", [[0, 1]], [[np.nan, 1]]), ] - for transform_range, domain in invalid_cases: - with self.subTest(transform_range=transform_range, domain=domain): - self.assertFalse( - AbstractTrueMeasure._range_in_domain(transform_range, domain) + for name, transform_range, domain in invalid_cases: + with self.subTest(name=name): + self.assertIs( + AbstractTrueMeasure._range_in_domain(transform_range, domain), + False, ) def test_strict_range_in_domain_chain(self): From 0e00eaae072098b91e36cd2d9d6cc9f8097cafe4 Mon Sep 17 00:00:00 2001 From: Laasya-73 <77721581+Laasya-73@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:56:15 -0500 Subject: [PATCH 5/6] Handle TrueMeasure composition edge cases --- qmcpy/true_measure/abstract_true_measure.py | 6 + qmcpy/true_measure/bernoulli_cont.py | 3 +- qmcpy/true_measure/copula.py | 7 +- qmcpy/true_measure/gaussian.py | 3 +- qmcpy/true_measure/kumaraswamy.py | 18 ++- qmcpy/true_measure/uniform.py | 3 +- test/test_true_measures.py | 160 ++++++++++++++++++++ 7 files changed, 184 insertions(+), 16 deletions(-) diff --git a/qmcpy/true_measure/abstract_true_measure.py b/qmcpy/true_measure/abstract_true_measure.py index 929da50bc..ba3a3633f 100644 --- a/qmcpy/true_measure/abstract_true_measure.py +++ b/qmcpy/true_measure/abstract_true_measure.py @@ -6,6 +6,12 @@ from scipy import sparse +def _clip_unit_interval(u): + """Clip unit-interval values away from endpoints for stable quantiles.""" + eps = np.finfo(float).eps + return np.clip(u, eps, 1.0 - eps) + + class AbstractTrueMeasure(object): def __init__(self): diff --git a/qmcpy/true_measure/bernoulli_cont.py b/qmcpy/true_measure/bernoulli_cont.py index cadf9f727..78dfd0751 100644 --- a/qmcpy/true_measure/bernoulli_cont.py +++ b/qmcpy/true_measure/bernoulli_cont.py @@ -75,6 +75,7 @@ def _transform(self, x): return tf def _weight(self, x): + in_support = np.all((0 <= x) & (x <= 1), axis=-1) w = np.zeros(x.shape, dtype=float) for j in range(self.d): C = ( @@ -83,7 +84,7 @@ def _weight(self, x): else 2 * np.arctanh(1 - 2 * self.l[j]) / (1 - 2 * self.l[j]) ) w[..., j] = C * self.l[j] ** x[..., j] * (1 - self.l[j]) ** (1 - x[..., j]) - return np.prod(w, -1) + return np.where(in_support, np.prod(w, -1), 0.0) def _spawn(self, sampler, dimension): if dimension == self.d: # don't do anything if the dimension doesn't change diff --git a/qmcpy/true_measure/copula.py b/qmcpy/true_measure/copula.py index 67ade5612..3851ebd94 100644 --- a/qmcpy/true_measure/copula.py +++ b/qmcpy/true_measure/copula.py @@ -2,7 +2,7 @@ import numpy as np -from .abstract_true_measure import AbstractTrueMeasure +from .abstract_true_measure import AbstractTrueMeasure, _clip_unit_interval from ..util import DimensionError, MethodImplementationError, ParameterError @@ -97,11 +97,6 @@ def _unit_weight_with_warning(self, x): return np.ones(x.shape[:-1], dtype=float) -def _clip_unit_interval(u): - eps = np.finfo(float).eps - return np.clip(u, eps, 1.0 - eps) - - def _validate_marginals(marginals): try: parsed = list(marginals) diff --git a/qmcpy/true_measure/gaussian.py b/qmcpy/true_measure/gaussian.py index 37d58982b..7db292440 100644 --- a/qmcpy/true_measure/gaussian.py +++ b/qmcpy/true_measure/gaussian.py @@ -1,4 +1,4 @@ -from .abstract_true_measure import AbstractTrueMeasure +from .abstract_true_measure import AbstractTrueMeasure, _clip_unit_interval from ..util import DimensionError, ParameterError from ..discrete_distribution import DigitalNetB2 import numpy as np @@ -158,6 +158,7 @@ def mvn_scipy(self, value): self._mvn_scipy_cache = value def _transform(self, x): + x = _clip_unit_interval(x) return self.mu + np.einsum("...ij,kj->...ik", norm.ppf(x), self.a) def _weight(self, t): diff --git a/qmcpy/true_measure/kumaraswamy.py b/qmcpy/true_measure/kumaraswamy.py index 47d4bdd9d..3419acec0 100644 --- a/qmcpy/true_measure/kumaraswamy.py +++ b/qmcpy/true_measure/kumaraswamy.py @@ -158,13 +158,17 @@ def _transform(self, x): return (1 - (1 - x) ** (1 / self.beta)) ** (1 / self.alpha) def _weight(self, x): - return np.prod( - self.alpha - * self.beta - * x ** (self.alpha - 1) - * (1 - x**self.alpha) ** (self.beta - 1), - -1, - ) + in_support = np.all((0 <= x) & (x <= 1), axis=-1) + x_in_support = np.clip(x, 0, 1) + with np.errstate(divide="ignore", invalid="ignore"): + weight = np.prod( + self.alpha + * self.beta + * x_in_support ** (self.alpha - 1) + * (1 - x_in_support**self.alpha) ** (self.beta - 1), + -1, + ) + return np.where(in_support, weight, 0.0) def _spawn(self, sampler, dimension): if dimension == self.d: # don't do anything if the dimension doesn't change diff --git a/qmcpy/true_measure/uniform.py b/qmcpy/true_measure/uniform.py index 0dc8c496e..97f25ab70 100644 --- a/qmcpy/true_measure/uniform.py +++ b/qmcpy/true_measure/uniform.py @@ -100,7 +100,8 @@ def _transform(self, x): return x * self.delta + self.a def _weight(self, x): - return np.tile(self.inv_delta_prod, x.shape[:-1]) + in_support = np.all((self.a <= x) & (x <= self.b), axis=-1) + return np.where(in_support, self.inv_delta_prod, 0.0) def _spawn(self, sampler, dimension): if dimension == self.d: # don't do anything if the dimension doesn't change diff --git a/test/test_true_measures.py b/test/test_true_measures.py index 3099128e8..bcecba227 100644 --- a/test/test_true_measures.py +++ b/test/test_true_measures.py @@ -156,6 +156,59 @@ def test_multidimensional_range_in_domain_chain_broadcasts(self): self.assertEqual(samples.shape, (8, 2)) self.assertTrue(np.isfinite(samples).all()) + def test_recursive_transform_applies_each_layer(self): + points = np.array([[0.1], [0.25], [0.5], [0.75], [0.9]]) + + uniform_inner = Uniform( + DigitalNetB2(1, seed=7), lower_bound=0.25, upper_bound=0.75 + ) + uniform_outer = Uniform( + uniform_inner, lower_bound=0.25, upper_bound=0.75 + ) + + kumaraswamy_inner = Uniform( + DigitalNetB2(1, seed=7), lower_bound=0.25, upper_bound=0.75 + ) + kumaraswamy_outer = Kumaraswamy(kumaraswamy_inner) + + gaussian_inner = Uniform( + DigitalNetB2(1, seed=7), lower_bound=0.25, upper_bound=0.75 + ) + gaussian_outer = Gaussian(gaussian_inner) + + bernoulli_inner = BernoulliCont(DigitalNetB2(1, seed=7), lam=0.9) + bernoulli_outer = Kumaraswamy(bernoulli_inner, a=2.0, b=2.0) + + cases = [ + ("1(a) Uniform -> Uniform", uniform_inner, uniform_outer), + ( + "1(b)/1(c) Uniform -> Kumaraswamy", + kumaraswamy_inner, + kumaraswamy_outer, + ), + ("1(c) Uniform -> Gaussian", gaussian_inner, gaussian_outer), + ( + "1(d) BernoulliCont -> Kumaraswamy", + bernoulli_inner, + bernoulli_outer, + ), + ] + + for name, inner, outer in cases: + with self.subTest(name=name): + transformed = outer._jacobian_transform_r( + points, return_weights=False + ) + expected = outer._transform(inner._transform(points)) + np.testing.assert_allclose(transformed, expected) + + if name.startswith("1(a)"): + np.testing.assert_allclose( + transformed, 0.375 + 0.25 * points + ) + if name.startswith("1(d)"): + np.testing.assert_array_equal(inner.range, outer.domain) + def test_out_of_domain_chain_preserves_deferred_errors(self): inner = Uniform( DigitalNetB2(1, seed=7), lower_bound=-0.1, upper_bound=0.75 @@ -514,6 +567,34 @@ def test_spawn_recomputes_moment_attributes(self): ) np.testing.assert_allclose(dense_covariance(spawn.covariance), 3.0 * np.eye(4)) + def test_weight_is_zero_outside_support(self): + uniform = Uniform(DigitalNetB2(1, seed=7), 0.25, 0.75) + points = np.array([[0.1], [0.25], [0.3], [0.5], [0.75], [0.9]]) + + np.testing.assert_allclose( + uniform._weight(points), + [0.0, 2.0, 2.0, 2.0, 2.0, 0.0], + ) + + def test_weight_support_mask_handles_dimensions_and_batches(self): + uniform = Uniform( + DigitalNetB2(2, seed=7), + lower_bound=[0.0, -1.0], + upper_bound=[1.0, 1.0], + ) + points = np.array( + [ + [[0.0, -1.0], [0.5, 0.0], [1.0, 1.0]], + [[-0.1, 0.0], [0.5, 1.1], [0.5, 0.0]], + ] + ) + + weights = uniform._weight(points) + + self.assertEqual(weights.shape, (2, 3)) + np.testing.assert_allclose(weights, [[0.5, 0.5, 0.5], [0.0, 0.0, 0.5]]) + self.assertTrue(np.all(weights >= 0)) + class TestKumaraswamy(unittest.TestCase): def test_sample_mean_and_covariance(self): @@ -570,6 +651,36 @@ def test_uniform_special_case(self): dense_covariance(kumaraswamy.covariance), np.diag(expected_variance) ) + def test_weight_is_zero_outside_support(self): + kumaraswamy = Kumaraswamy(DigitalNetB2(1, seed=7), a=2, b=2) + points = np.array([[-0.5], [0.0], [0.5], [1.0], [1.5]]) + + weights = kumaraswamy._weight(points) + + np.testing.assert_allclose(weights, [0.0, 0.0, 1.5, 0.0, 0.0]) + self.assertTrue(np.all(weights >= 0)) + + singular_boundaries = Kumaraswamy( + DigitalNetB2(1, seed=7), a=0.5, b=0.5 + )._weight(np.array([[0.0], [1.0]])) + self.assertTrue(np.isposinf(singular_boundaries).all()) + + def test_weight_support_mask_handles_dimensions_and_batches(self): + kumaraswamy = Kumaraswamy(DigitalNetB2(2, seed=7), a=2, b=2) + points = np.array( + [ + [[0.5, 0.5], [0.25, 0.75]], + [[-0.1, 0.5], [0.5, 1.1]], + ] + ) + + weights = kumaraswamy._weight(points) + + self.assertEqual(weights.shape, (2, 2)) + np.testing.assert_allclose(weights[0], [2.25, 1.23046875]) + np.testing.assert_allclose(weights[1], [0.0, 0.0]) + self.assertTrue(np.all(weights >= 0)) + def test_spawn_recomputes_moment_attributes(self): kumaraswamy = Kumaraswamy( DigitalNetB2(2, seed=7), a=1, b=3 @@ -769,6 +880,25 @@ def test_deprecated_2d_construction_has_no_moment_parameters(self): self.assertNotIn(parameter, tm.parameters) +class TestBernoulliCont(unittest.TestCase): + def test_weight_is_zero_outside_support(self): + lam = 0.9 + bernoulli = BernoulliCont(DigitalNetB2(1, seed=7), lam=lam) + points = np.array([[-0.1], [0.0], [0.5], [1.0], [1.1]]) + + weights = bernoulli._weight(points) + normalizer = 2 * np.arctanh(1 - 2 * lam) / (1 - 2 * lam) + expected_in_support = ( + normalizer + * lam ** points[1:4, 0] + * (1 - lam) ** (1 - points[1:4, 0]) + ) + + np.testing.assert_allclose(weights[[0, 4]], 0.0) + np.testing.assert_allclose(weights[1:4], expected_in_support) + self.assertTrue(np.all(weights >= 0)) + + class TestUniformTriangle(unittest.TestCase): """Tests for UniformTriangle and _UniformTriangleAdapter.""" @@ -835,6 +965,36 @@ def test_sample_mean_and_covariance(self): assert_sample_mean_and_covariance(gaussian) + def test_transform_clips_unit_interval_endpoints(self): + gaussian = Gaussian(DigitalNetB2(1, seed=7)) + endpoints = gaussian._transform(np.array([[0.0], [1.0]])) + interior = np.array([[0.25], [0.5], [0.75]]) + + self.assertTrue(np.isfinite(endpoints).all()) + np.testing.assert_allclose( + gaussian._transform(interior), + scipy.stats.norm.ppf(interior), + rtol=0, + atol=0, + ) + + def test_unrandomized_direct_and_composed_samples_are_finite(self): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + direct = Gaussian( + DigitalNetB2(1, randomize="FALSE") + ).gen_samples(2) + composed = Gaussian( + Uniform( + DigitalNetB2(1, randomize="FALSE"), + 0.0, + 0.75, + ) + ).gen_samples(2) + + self.assertTrue(np.isfinite(direct).all()) + self.assertTrue(np.isfinite(composed).all()) + def test_gaussian_basic_output_reproducibility(self): """Test that basic Gaussian sample generation produces expected values with fixed seed.""" gaussian = Gaussian(Lattice(4, seed=self.seed), mean=0, covariance=1) From 345bb0dd30aa90951bd84e5b92927260abf9ee13 Mon Sep 17 00:00:00 2001 From: Laasya-73 <77721581+Laasya-73@users.noreply.github.com> Date: Sat, 5 Sep 2026 12:37:01 -0500 Subject: [PATCH 6/6] Polish TrueMeasure review fixes and documentation --- demos/true_measure_domain_inclusion.ipynb | 1795 +++++++++++------ docs/api/discrete_distributions.md | 5 +- qmcpy/discrete_distribution/dummy_sampler.py | 10 + qmcpy/true_measure/abstract_true_measure.py | 6 +- qmcpy/true_measure/brownian_motion.py | 3 +- qmcpy/true_measure/johnsons_su.py | 3 +- qmcpy/true_measure/product_measure.py | 27 +- qmcpy/true_measure/scipy_wrapper.py | 6 +- qmcpy/true_measure/student_t.py | 4 +- .../true_measure/zero_inflated_exp_uniform.py | 11 + scripts/colab_notebooks_manifest.json | 1 + test/test_true_measures.py | 149 +- 12 files changed, 1416 insertions(+), 604 deletions(-) diff --git a/demos/true_measure_domain_inclusion.ipynb b/demos/true_measure_domain_inclusion.ipynb index 00c8f6367..a2f18c171 100644 --- a/demos/true_measure_domain_inclusion.ipynb +++ b/demos/true_measure_domain_inclusion.ipynb @@ -5,149 +5,569 @@ "id": "a4c44dd5", "metadata": {}, "source": [ - "# Chaining `TrueMeasure` Transformations with Compatible Domains\n", + "# Chaining `TrueMeasure` Transformations When Domains Are Compatible\n", "\n", - "## 1. Problem and proposed rule\n", + "A `TrueMeasure` transformation takes values from one set, transforms them,\n", + "and passes the result to the next transformation in a chain.\n", "\n", - "Consider consecutive transformations\n", + "The important question is:\n", + "\n", + "> **Does the next transformation need the previous range to be exactly equal\n", + "> to its domain, or does it only need every incoming value to be valid?**\n", + "\n", + "This notebook shows why **containment** is the correct condition.\n", + "\n", + "We first look at a simple real-world example, reproduce what the previous\n", + "QMCPy compatibility rule would do, and then show the same transformation\n", + "working with the updated rule." + ] + }, + { + "cell_type": "markdown", + "id": "d94f50a6", + "metadata": {}, + "source": [ + "## 1. A real-world picture\n", + "\n", + "Suppose we model the **operating load of a battery system** as a normalized\n", + "fraction between `0` and `1`.\n", + "\n", + "A downstream response model is designed to accept any normalized load\n", + "\n", + "$$\n", + "x \\in [0,1].\n", + "$$\n", + "\n", + "However, under normal operating conditions, the battery is deliberately kept\n", + "between 25% and 75% load:\n", + "\n", + "$$\n", + "x \\in [0.25,0.75].\n", + "$$\n", + "\n", + "There is no incompatibility here.\n", + "\n", + "The downstream model accepts every value from `0` to `1`, and the upstream\n", + "stage produces only values between `0.25` and `0.75`.\n", + "\n", + "Mathematically,\n", + "\n", + "$$\n", + "[0.25,0.75] \\subseteq [0,1].\n", + "$$\n", + "\n", + "The fact that\n", + "\n", + "$$\n", + "[0.25,0.75] \\neq [0,1]\n", + "$$\n", + "\n", + "does **not** make the two stages incompatible.\n", + "\n", + "This is exactly the situation addressed by this change in QMCPy." + ] + }, + { + "cell_type": "markdown", + "id": "8a14030c", + "metadata": {}, + "source": [ + "## 2. The mathematical compatibility condition\n", + "\n", + "Consider two consecutive transformations\n", "\n", "$$\n", "T_{j-1}:D_{j-1}\\rightarrow R_{j-1},\n", - "\\qquad\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", "T_j:D_j\\rightarrow R_j.\n", "$$\n", "\n", - "QMCPy previously treated the shared boundary as compatible only when\n", + "The output of the first transformation becomes the input of the second:\n", "\n", "$$\n", - "R_{j-1}=D_j.\n", + "x \\in R_{j-1}\n", + "\\quad\\longrightarrow\\quad\n", + "T_j(x).\n", "$$\n", "\n", - "The output of $T_{j-1}$ becomes input to $T_j$, so exact equality is unnecessary. For domain compatibility, every output only needs to lie inside the domain accepted by the next transformation:\n", + "Therefore, the second transformation is valid whenever **every possible\n", + "output of the first transformation lies inside the domain of the second**:\n", "\n", "$$\n", - "R_{j-1}\\subseteq D_j.\n", + "\\boxed{R_{j-1}\\subseteq D_j}.\n", "$$\n", "\n", - "One example captures the difference:\n", + "The previous QMCPy check effectively required\n", "\n", "$$\n", - "[0.25,0.75]\\neq[0,1],\n", - "\\qquad\n", - "[0.25,0.75]\\subseteq[0,1].\n", + "R_{j-1}=D_j.\n", "$$\n", "\n", - "For one-dimensional bounds\n", + "Equality is sufficient, but it is stronger than necessary.\n", + "\n", + "For one-dimensional intervals,\n", "\n", "$$\n", - "R=[r_L,r_U],\n", + "R_{j-1}=[r_L,r_U],\n", "\\qquad\n", - "D=[d_L,d_U],\n", + "D_j=[d_L,d_U],\n", + "$$\n", + "\n", + "containment means\n", + "\n", + "$$\n", + "\\boxed{\n", + "d_L\\le r_L\n", + "\\quad\\text{and}\\quad\n", + "r_U\\le d_U\n", + "}.\n", "$$\n", "\n", - "compatibility means\n", + "For our battery example,\n", "\n", "$$\n", - "d_L\\leq r_L\n", + "0\\le0.25\n", "\\qquad\\text{and}\\qquad\n", - "r_U\\leq d_U.\n", + "0.75\\le1,\n", "$$\n", "\n", - "The same inequalities are checked coordinate-wise for multidimensional axis-aligned boxes. The implemented scope covers intervals and boxes with finite or unbounded numerical bounds, while preserving NumPy broadcasting between common `(1,2)` bounds and coordinate-specific `(d,2)` bounds.\n", + "so\n", "\n", - "> QMCPy currently stores numerical lower/upper support envelopes, including `-np.inf` and `np.inf`; explicit open/closed endpoints, disconnected supports, and arbitrary nonrectangular supports are not represented by this change." + "$$\n", + "[0.25,0.75]\\subseteq[0,1].\n", + "$$" ] }, { "cell_type": "markdown", - "id": "d94f50a6", + "id": "6c4c9d29", "metadata": {}, "source": [ - "## 2. What changed in QMCPy?\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/QMCSoftware/QMCSoftware/blob/develop/demos/true_measure_domain_inclusion.ipynb)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "15ab6588", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-05T15:28:35.491526Z", + "iopub.status.busy": "2026-09-05T15:28:35.491162Z", + "iopub.status.idle": "2026-09-05T15:28:35.500428Z", + "shell.execute_reply": "2026-09-05T15:28:35.499277Z" + } + }, + "outputs": [], + "source": [ + "# @title Execute this cell to install dependencies\n", + "try:\n", + " import google.colab\n", + " IN_COLAB = True\n", + "except ImportError:\n", + " IN_COLAB = False\n", + "if IN_COLAB:\n", + " !pip install -q qmcpy\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8d512296", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-05T15:28:35.503295Z", + "iopub.status.busy": "2026-09-05T15:28:35.503074Z", + "iopub.status.idle": "2026-09-05T15:28:36.936871Z", + "shell.execute_reply": "2026-09-05T15:28:36.936105Z" + } + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "from qmcpy import DigitalNetB2, Kumaraswamy, Uniform\n", + "from qmcpy.util import ParameterError" + ] + }, + { + "cell_type": "markdown", + "id": "85f8195a", + "metadata": {}, + "source": [ + "## 3. What happened before this change?\n", "\n", - "The old chained-`TrueMeasure` check was\n", + "The previous compatibility check compared the two sets using equality.\n", "\n", - "```python\n", - "if (self.domain != self.transform.range).any():\n", - " self.sub_compatibility_error = True\n", - "```\n", + "Conceptually, it asked\n", "\n", - "It is now\n", + "$$\n", + "R_{j-1}=D_j\\;?\n", + "$$\n", "\n", - "```python\n", - "if not self._range_in_domain(self.transform.range, self.domain):\n", - " self.sub_compatibility_error = True\n", - "```\n", + "For the battery example, that becomes\n", "\n", - "After broadcasting the bound arrays, the essential helper logic is\n", + "$$\n", + "[0.25,0.75]=[0,1]\\;?\n", + "$$\n", "\n", - "```python\n", - "domain[:, 0] <= transform_range[:, 0]\n", - "transform_range[:, 1] <= domain[:, 1]\n", - "```\n", + "which is false.\n", "\n", - "Both inequalities must hold in every coordinate. Equality still works because it is a special case of containment, and broadcasting preserves the existing `(1,2)` versus `(d,2)` convention." + "So the previous rule treated the chain as incompatible even though every\n", + "value produced by the first stage was a perfectly valid input for the second.\n", + "\n", + "The code below reproduces that previous equality rule so that we can compare\n", + "it directly with the mathematically correct containment rule." ] }, { "cell_type": "code", - "execution_count": 28, - "id": "8d512296", + "execution_count": 3, + "id": "ed148c64", "metadata": { "execution": { - "iopub.execute_input": "2026-08-24T19:24:44.410561Z", - "iopub.status.busy": "2026-08-24T19:24:44.409591Z", - "iopub.status.idle": "2026-08-24T19:24:46.645979Z", - "shell.execute_reply": "2026-08-24T19:24:46.644328Z" + "iopub.execute_input": "2026-09-05T15:28:36.938578Z", + "iopub.status.busy": "2026-09-05T15:28:36.938314Z", + "iopub.status.idle": "2026-09-05T15:28:36.951949Z", + "shell.execute_reply": "2026-09-05T15:28:36.951483Z" } }, "outputs": [], "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "from matplotlib.patches import Rectangle\n", - "from scipy.stats import logistic, norm\n", - "\n", - "from qmcpy import (\n", - " AbstractTrueMeasure,\n", - " CubQMCSobolG,\n", - " CustomFun,\n", - " DigitalNetB2,\n", - " Kumaraswamy,\n", - " Uniform,\n", + "def previous_equality_rule(transform_range, next_domain):\n", + " \"\"\"Reproduce the previous equality-based compatibility decision.\"\"\"\n", + " transform_range = np.asarray(transform_range, dtype=float)\n", + " next_domain = np.asarray(next_domain, dtype=float)\n", + "\n", + " try:\n", + " transform_range, next_domain = np.broadcast_arrays(\n", + " transform_range,\n", + " next_domain,\n", + " )\n", + " except ValueError:\n", + " return False\n", + "\n", + " return bool(np.all(transform_range == next_domain))\n", + "\n", + "\n", + "def containment_rule(transform_range, next_domain):\n", + " \"\"\"Check whether every transform output lies inside the next domain.\"\"\"\n", + " transform_range = np.asarray(transform_range, dtype=float)\n", + " next_domain = np.asarray(next_domain, dtype=float)\n", + "\n", + " try:\n", + " transform_range, next_domain = np.broadcast_arrays(\n", + " transform_range,\n", + " next_domain,\n", + " )\n", + " except ValueError:\n", + " return False\n", + "\n", + " lower_bounds_valid = np.all(\n", + " next_domain[:, 0] <= transform_range[:, 0]\n", + " )\n", + " upper_bounds_valid = np.all(\n", + " transform_range[:, 1] <= next_domain[:, 1]\n", + " )\n", + "\n", + " return bool(lower_bounds_valid and upper_bounds_valid)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e20bf2af", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Upstream operating range: [[0.25 0.75]]\n", + "Downstream accepted domain: [[0. 1.]]\n", + "\n", + "Previous equality rule accepts the chain: False\n", + "Containment rule accepts the chain: True\n" + ] + } + ], + "source": [ + "battery_operating_range = np.array([[0.25, 0.75]])\n", + "response_model_domain = np.array([[0.0, 1.0]])\n", + "\n", + "old_result = previous_equality_rule(\n", + " battery_operating_range,\n", + " response_model_domain,\n", ")\n", - "from qmcpy.util import ParameterError\n", "\n", + "new_result = containment_rule(\n", + " battery_operating_range,\n", + " response_model_domain,\n", + ")\n", "\n", - "def previous_compatibility_check(transform_range, domain):\n", - " # Reproduce the previous broadcasted exact-equality rule.\n", - " return not (np.asarray(domain) != np.asarray(transform_range)).any()\n" + "print(\"Upstream operating range:\", battery_operating_range)\n", + "print(\"Downstream accepted domain:\", response_model_domain)\n", + "print()\n", + "print(\"Previous equality rule accepts the chain:\", old_result)\n", + "print(\"Containment rule accepts the chain:\", new_result)" ] }, { "cell_type": "markdown", - "id": "85f8195a", + "id": "5fad26b1", "metadata": {}, "source": [ - "## 3. Behavior before and after\n", + "### What does this output mean?\n", + "\n", + "The two checks are answering different questions.\n", + "\n", + "The previous rule asks:\n", + "\n", + "> “Does the upstream stage produce **exactly the entire domain** expected by\n", + "> the downstream stage?”\n", + "\n", + "and returns False because\n", + "\n", + "$$\n", + "[0.25, 0.75] \\neq [0, 1].\n", + "$$\n", + "\n", + "The containment rule instead asks:\n", + "\n", + "> “Can every value produced upstream safely be passed downstream?”\n", + "\n", + "and returns True because\n", + "\n", + "$$\n", + "0 \\leq 0.25\n", + "\\qquad \\text{and} \\qquad\n", + "0.75 \\leq 1.\n", + "$$\n", + "\n", + "Therefore,\n", + "\n", + "$$\n", + "\\boxed{[0.25, 0.75] \\subseteq [0, 1]}.\n", + "$$\n", + "\n", + "This is the behavior the PR introduces." + ] + }, + { + "cell_type": "markdown", + "id": "6c017194", + "metadata": {}, + "source": [ + "## 4. Now use the actual QMCPy transformation chain\n", + "\n", + "We now represent the same situation using two `TrueMeasure`s.\n", "\n", - "A compact comparison shows the intended behavioral boundary. The following cells then exercise three real QMCPy chains rather than testing only the helper." + "The first transformation produces normalized operating loads in\n", + "\n", + "$$\n", + "[0.25,0.75].\n", + "$$\n", + "\n", + "The second transformation is a `Kumaraswamy` transformation. Its input domain\n", + "is the unit interval\n", + "\n", + "$$\n", + "[0,1].\n", + "$$\n", + "\n", + "A Kumaraswamy distribution is useful for quantities naturally bounded between\n", + "0 and 1, such as proportions, normalized scores, or utilization fractions.\n", + "\n", + "For this example we use\n", + "\n", + "$$\n", + "a=2,\n", + "\\qquad\n", + "b=2.\n", + "$$\n", + "\n", + "The important point for this PR is not the particular choice of distribution.\n", + "It is that the downstream transformation accepts the whole unit interval while\n", + "the upstream transformation produces only a valid subset of it." ] }, { "cell_type": "code", - "execution_count": 29, - "id": "ed148c64", + "execution_count": 5, + "id": "fd51b128", + "metadata": { + "execution": { + "iopub.execute_input": "2026-09-05T15:28:36.966639Z", + "iopub.status.busy": "2026-09-05T15:28:36.966489Z", + "iopub.status.idle": "2026-09-05T15:28:36.970611Z", + "shell.execute_reply": "2026-09-05T15:28:36.970195Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Range produced by the inner transformation:\n", + "[[0.25 0.75]]\n", + "\n", + "Domain accepted by the outer transformation:\n", + "[[0 1]]\n", + "\n", + "QMCPy reports a compatibility error: False\n" + ] + } + ], + "source": [ + "inner_measure = Uniform(\n", + " DigitalNetB2(1, randomize=\"FALSE\"),\n", + " lower_bound=0.25,\n", + " upper_bound=0.75,\n", + ")\n", + "\n", + "battery_response = Kumaraswamy(\n", + " inner_measure,\n", + " a=2.0,\n", + " b=2.0,\n", + ")\n", + "\n", + "print(\"Range produced by the inner transformation:\")\n", + "print(inner_measure.range)\n", + "\n", + "print(\"\\nDomain accepted by the outer transformation:\")\n", + "print(battery_response.domain)\n", + "\n", + "print(\n", + " \"\\nQMCPy reports a compatibility error:\",\n", + " battery_response.sub_compatibility_error,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9e3e56de", + "metadata": {}, + "source": [ + "### Why is `Compatibility error: False` the important result?\n", + "\n", + "The inner transformation produces only\n", + "\n", + "$$\n", + "[0.25,0.75].\n", + "$$\n", + "\n", + "The outer transformation accepts\n", + "\n", + "$$\n", + "[0,1].\n", + "$$\n", + "\n", + "These sets are **not equal**, so the previous equality-based rule would have\n", + "marked this composition as incompatible.\n", + "\n", + "With containment,\n", + "\n", + "$$\n", + "[0.25,0.75]\\subseteq[0,1],\n", + "$$\n", + "\n", + "so QMCPy correctly allows the transformation chain.\n", + "\n", + "This is the direct behavioral change introduced by the PR." + ] + }, + { + "cell_type": "markdown", + "id": "02c17b09", + "metadata": {}, + "source": [ + "## 5. Generate values through the complete chain\n", + "\n", + "Accepting the chain is useful only if it can actually be evaluated.\n", + "\n", + "Let the original DigitalNet coordinate be\n", + "\n", + "$$\n", + "u\\in[0,1].\n", + "$$\n", + "\n", + "The inner `Uniform(0.25, 0.75)` transformation is\n", + "\n", + "$$\n", + "r(u)\n", + "=\n", + "0.25+(0.75-0.25)u\n", + "=\n", + "0.25+0.5u.\n", + "$$\n", + "\n", + "Therefore,\n", + "\n", + "$$\n", + "r(u)\\in[0.25,0.75].\n", + "$$\n", + "\n", + "For a Kumaraswamy distribution with parameters $a=b=2$, the CDF is\n", + "\n", + "$$\n", + "F(y)=1-(1-y^2)^2,\n", + "\\qquad 0\\le y\\le1.\n", + "$$\n", + "\n", + "Its inverse CDF is\n", + "\n", + "$$\n", + "F^{-1}(r)\n", + "=\n", + "\\left[\n", + "1-(1-r)^{1/2}\n", + "\\right]^{1/2}.\n", + "$$\n", + "\n", + "The complete chained transformation is therefore\n", + "\n", + "$$\n", + "\\boxed{\n", + "y(u)\n", + "=\n", + "\\sqrt{\n", + "1-\\sqrt{\n", + "1-(0.25+0.5u)\n", + "}\n", + "}\n", + "}.\n", + "$$\n", + "\n", + "The next cell compares this formula with the values produced by QMCPy." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f6da6902", "metadata": { "execution": { - "iopub.execute_input": "2026-08-24T19:24:46.650630Z", - "iopub.status.busy": "2026-08-24T19:24:46.649593Z", - "iopub.status.idle": "2026-08-24T19:24:46.680364Z", - "shell.execute_reply": "2026-08-24T19:24:46.679106Z" + "iopub.execute_input": "2026-09-05T15:28:37.287457Z", + "iopub.status.busy": "2026-09-05T15:28:37.287316Z", + "iopub.status.idle": "2026-09-05T15:28:37.400058Z", + "shell.execute_reply": "2026-09-05T15:28:37.399472Z" } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Owner\\Downloads\\QMCSoftware\\qmcpy\\discrete_distribution\\digital_net_b2\\digital_net_b2.py:675: ParameterWarning: Without randomization, the first digtial net point is the origin\n", + " warnings.warn(\n" + ] + }, { "data": { "text/html": [ @@ -169,292 +589,367 @@ " \n", " \n", " \n", - " Case\n", - " Old equality rule\n", - " New containment rule\n", + " DigitalNet u\n", + " Operating load r(u)\n", + " Formula result\n", + " QMCPy result\n", " \n", " \n", " \n", " \n", " 0\n", - " Exact equality\n", - " True\n", - " True\n", + " 0.000\n", + " 0.2500\n", + " 0.366025\n", + " 0.366025\n", " \n", " \n", " 1\n", - " Strict inclusion\n", - " False\n", - " True\n", + " 0.500\n", + " 0.5000\n", + " 0.541196\n", + " 0.541196\n", " \n", " \n", " 2\n", - " Infinite containing domain\n", - " False\n", - " True\n", + " 0.250\n", + " 0.3750\n", + " 0.457636\n", + " 0.457636\n", " \n", " \n", " 3\n", - " Lower-bound violation\n", - " False\n", - " False\n", + " 0.750\n", + " 0.6250\n", + " 0.622597\n", + " 0.622597\n", " \n", " \n", " 4\n", - " Multidimensional inclusion\n", - " False\n", - " True\n", + " 0.125\n", + " 0.3125\n", + " 0.413333\n", + " 0.413333\n", + " \n", + " \n", + " 5\n", + " 0.625\n", + " 0.5625\n", + " 0.581861\n", + " 0.581861\n", + " \n", + " \n", + " 6\n", + " 0.375\n", + " 0.4375\n", + " 0.500000\n", + " 0.500000\n", + " \n", + " \n", + " 7\n", + " 0.875\n", + " 0.6875\n", + " 0.664066\n", + " 0.664066\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Case Old equality rule New containment rule\n", - "0 Exact equality True True\n", - "1 Strict inclusion False True\n", - "2 Infinite containing domain False True\n", - "3 Lower-bound violation False False\n", - "4 Multidimensional inclusion False True" + " DigitalNet u Operating load r(u) Formula result QMCPy result\n", + "0 0.000 0.2500 0.366025 0.366025\n", + "1 0.500 0.5000 0.541196 0.541196\n", + "2 0.250 0.3750 0.457636 0.457636\n", + "3 0.750 0.6250 0.622597 0.622597\n", + "4 0.125 0.3125 0.413333 0.413333\n", + "5 0.625 0.5625 0.581861 0.581861\n", + "6 0.375 0.4375 0.500000 0.500000\n", + "7 0.875 0.6875 0.664066 0.664066" ] }, - "execution_count": 29, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "comparison_cases = [\n", - " (\"Exact equality\", [[0, 1]], [[0, 1]]),\n", - " (\"Strict inclusion\", [[0.25, 0.75]], [[0, 1]]),\n", - " (\"Infinite containing domain\", [[-5, 5]], [[-np.inf, np.inf]]),\n", - " (\"Lower-bound violation\", [[-0.1, 0.75]], [[0, 1]]),\n", - " (\n", - " \"Multidimensional inclusion\",\n", - " [[0.1, 0.8], [0.2, 0.9]],\n", - " [[0, 1]],\n", - " ),\n", - "]\n", + "sample_count = 8\n", + "\n", + "# Use the same deterministic DigitalNet construction for a manual calculation.\n", + "reference_u = DigitalNetB2(\n", + " 1,\n", + " randomize=\"FALSE\",\n", + ").gen_samples(sample_count)\n", + "\n", + "inner_values = 0.25 + 0.5 * reference_u\n", + "\n", + "expected_response = np.sqrt(\n", + " 1.0 - np.sqrt(1.0 - inner_values)\n", + ")\n", + "\n", + "qmcpy_response = battery_response.gen_samples(sample_count)\n", "\n", "comparison = pd.DataFrame(\n", - " [\n", - " {\n", - " \"Case\": name,\n", - " \"Old equality rule\": previous_compatibility_check(bounds, domain),\n", - " \"New containment rule\": AbstractTrueMeasure._range_in_domain(\n", - " bounds, domain\n", - " ),\n", - " }\n", - " for name, bounds, domain in comparison_cases\n", - " ]\n", + " {\n", + " \"DigitalNet u\": reference_u[:, 0],\n", + " \"Operating load r(u)\": inner_values[:, 0],\n", + " \"Formula result\": expected_response[:, 0],\n", + " \"QMCPy result\": qmcpy_response[:, 0],\n", + " }\n", ")\n", - "comparison" - ] - }, - { - "cell_type": "markdown", - "id": "5fad26b1", - "metadata": {}, - "source": [ - "### A. Strict 1D inclusion\n", "\n", - "An inner `Uniform` produces values in $[0.25,0.75]$, while the outer `Kumaraswamy` accepts inputs in $[0,1]$." + "comparison" ] }, { "cell_type": "code", - "execution_count": 30, - "id": "e3f1220f", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:46.686289Z", - "iopub.status.busy": "2026-08-24T19:24:46.685485Z", - "iopub.status.idle": "2026-08-24T19:24:46.720415Z", - "shell.execute_reply": "2026-08-24T19:24:46.715058Z" - } - }, + "execution_count": 7, + "id": "e9045766", + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Inner range: [[0.25 0.75]]\n", - "Outer domain: [[0 1]]\n", - "Range contained in domain: True\n", - "Compatibility error: False\n", - "Sample shape: (8, 1)\n", - "All samples finite: True\n" + "Maximum difference between the mathematical formula and QMCPy: 0.000e+00\n", + "All generated values are finite: True\n" ] } ], "source": [ - "inner = Uniform(\n", - " DigitalNetB2(1, seed=7),\n", - " lower_bound=0.25,\n", - " upper_bound=0.75,\n", + "maximum_difference = np.max(\n", + " np.abs(qmcpy_response - expected_response)\n", ")\n", - "outer = Kumaraswamy(inner)\n", - "samples_1d = outer.gen_samples(8)\n", "\n", - "print(\"Inner range:\", inner.range)\n", - "print(\"Outer domain:\", outer.domain)\n", "print(\n", - " \"Range contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(inner.range, outer.domain),\n", + " \"Maximum difference between the mathematical formula and QMCPy:\",\n", + " f\"{maximum_difference:.3e}\",\n", ")\n", - "print(\"Compatibility error:\", outer.sub_compatibility_error)\n", - "print(\"Sample shape:\", samples_1d.shape)\n", - "print(\"All samples finite:\", np.isfinite(samples_1d).all())" + "\n", + "print(\n", + " \"All generated values are finite:\",\n", + " np.isfinite(qmcpy_response).all(),\n", + ")" ] }, { "cell_type": "markdown", - "id": "a27ca7cd", + "id": "f8a0abb5", "metadata": {}, "source": [ - "### B. Multidimensional/broadcast inclusion\n", + "### What did we just verify?\n", "\n", - "Here a `(2,2)` inner range is checked against the outer measure's common `(1,2)` unit-domain interval." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "3b524d4a", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:46.724795Z", - "iopub.status.busy": "2026-08-24T19:24:46.724399Z", - "iopub.status.idle": "2026-08-24T19:24:46.737550Z", - "shell.execute_reply": "2026-08-24T19:24:46.734862Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inner range: [[0.1 0.8]\n", - " [0.2 0.9]]\n", - "Outer domain: [[0 1]]\n", - "Range contained in domain: True\n", - "Compatibility error: False\n", - "Sample shape: (8, 2)\n", - "All samples finite: True\n" - ] - } - ], - "source": [ - "inner_2d = Uniform(\n", - " DigitalNetB2(2, seed=7),\n", - " lower_bound=[0.1, 0.2],\n", - " upper_bound=[0.8, 0.9],\n", - ")\n", - "outer_2d = Kumaraswamy(inner_2d)\n", - "samples_2d = outer_2d.gen_samples(8)\n", + "Each row follows the complete path\n", "\n", - "print(\"Inner range:\", inner_2d.range)\n", - "print(\"Outer domain:\", outer_2d.domain)\n", - "print(\n", - " \"Range contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(inner_2d.range, outer_2d.domain),\n", - ")\n", - "print(\"Compatibility error:\", outer_2d.sub_compatibility_error)\n", - "print(\"Sample shape:\", samples_2d.shape)\n", - "print(\"All samples finite:\", np.isfinite(samples_2d).all())" + "$$\n", + "u\n", + "\\longrightarrow\n", + "r(u)\n", + "\\longrightarrow\n", + "y(u).\n", + "$$\n", + "\n", + "The first transformation converts the DigitalNet coordinate into the restricted\n", + "operating range\n", + "\n", + "$$\n", + "r(u)\\in[0.25,0.75].\n", + "$$\n", + "\n", + "The second transformation then accepts that value because its domain is\n", + "\n", + "$$\n", + "[0,1].\n", + "$$\n", + "\n", + "The final comparison checks two independent calculations:\n", + "\n", + "1. the closed-form mathematical expression\n", + "\n", + " $$\n", + " y(u)\n", + " =\n", + " \\sqrt{\n", + " 1-\\sqrt{\n", + " 1-(0.25+0.5u)\n", + " }\n", + " },\n", + " $$\n", + "\n", + "2. the value returned by the actual QMCPy chained `TrueMeasure`.\n", + "\n", + "A maximum difference near machine precision means the actual QMCPy chain is\n", + "performing the same transformation predicted by the mathematics.\n", + "\n", + "So this is not only a compatibility-table change: the previously rejected\n", + "strict-subset chain can now be evaluated normally." ] }, { "cell_type": "markdown", - "id": "6c017194", + "id": "443bc49a", "metadata": {}, "source": [ - "### C. Actual incompatibility\n", + "## 6. What output range should we expect?\n", "\n", - "The range\n", + "Because\n", "\n", "$$\n", - "[-0.1,0.75]\\nsubseteq[0,1]\n", + "r\\in[0.25,0.75]\n", "$$\n", "\n", - "extends below the next domain and must remain rejected." + "and the Kumaraswamy inverse CDF is increasing, the smallest and largest possible\n", + "outputs occur at the two endpoints.\n", + "\n", + "For $a=b=2$,\n", + "\n", + "$$\n", + "y_{\\min}\n", + "=\n", + "\\sqrt{1-\\sqrt{1-0.25}}\n", + "\\approx0.3660,\n", + "$$\n", + "\n", + "and\n", + "\n", + "$$\n", + "y_{\\max}\n", + "=\n", + "\\sqrt{1-\\sqrt{1-0.75}}\n", + "\\approx0.7071.\n", + "$$\n", + "\n", + "Therefore the composite transformation produces values approximately in\n", + "\n", + "$$\n", + "\\boxed{\n", + "[0.3660,\\;0.7071]\n", + "}.\n", + "$$\n", + "\n", + "We can check this directly with a larger point set." ] }, { "cell_type": "code", - "execution_count": 32, - "id": "fd51b128", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:46.743432Z", - "iopub.status.busy": "2026-08-24T19:24:46.742993Z", - "iopub.status.idle": "2026-08-24T19:24:46.752101Z", - "shell.execute_reply": "2026-08-24T19:24:46.750435Z" - } - }, + "execution_count": 8, + "id": "158b2803", + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Range contained in domain: False\n", - "Compatibility error: True\n", - "Sampling result: ParameterError - The sub-transform range must be contained within the transform domain.\n" + "Theoretical composite output interval: [0.366025, 0.707107]\n", + "Observed sample minimum: 0.366025\n", + "Observed sample maximum: 0.707020\n", + "Every sample lies inside the theoretical interval: True\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Owner\\Downloads\\QMCSoftware\\qmcpy\\discrete_distribution\\digital_net_b2\\digital_net_b2.py:675: ParameterWarning: Without randomization, the first digtial net point is the origin\n", + " warnings.warn(\n" ] } ], "source": [ - "invalid_inner = Uniform(\n", - " DigitalNetB2(1, seed=7),\n", - " lower_bound=-0.1,\n", - " upper_bound=0.75,\n", + "many_samples = battery_response.gen_samples(2**12)\n", + "\n", + "theoretical_minimum = np.sqrt(\n", + " 1.0 - np.sqrt(1.0 - 0.25)\n", + ")\n", + "theoretical_maximum = np.sqrt(\n", + " 1.0 - np.sqrt(1.0 - 0.75)\n", ")\n", - "invalid_outer = Kumaraswamy(invalid_inner)\n", "\n", "print(\n", - " \"Range contained in domain:\",\n", - " AbstractTrueMeasure._range_in_domain(\n", - " invalid_inner.range, invalid_outer.domain\n", - " ),\n", + " \"Theoretical composite output interval:\",\n", + " f\"[{theoretical_minimum:.6f}, {theoretical_maximum:.6f}]\",\n", ")\n", - "print(\"Compatibility error:\", invalid_outer.sub_compatibility_error)\n", "\n", - "try:\n", - " invalid_outer.gen_samples(8)\n", - "except ParameterError as error:\n", - " print(\"Sampling result:\", type(error).__name__, \"-\", error)" + "print(\n", + " \"Observed sample minimum:\",\n", + " f\"{many_samples.min():.6f}\",\n", + ")\n", + "\n", + "print(\n", + " \"Observed sample maximum:\",\n", + " f\"{many_samples.max():.6f}\",\n", + ")\n", + "\n", + "print(\n", + " \"Every sample lies inside the theoretical interval:\",\n", + " bool(\n", + " np.all(many_samples >= theoretical_minimum)\n", + " and np.all(many_samples <= theoretical_maximum)\n", + " ),\n", + ")" ] }, { "cell_type": "markdown", - "id": "d4d209de", + "id": "6da698c3", "metadata": {}, "source": [ - "The change accepts strict containment without accepting genuinely out-of-domain transformations.\n", + "### Interpreting this output\n", "\n", - "### D. One compatibility visual\n", + "The upstream `Uniform` transformation deliberately uses only part of the\n", + "outer transformation's valid input domain.\n", "\n", - "For axis-aligned boxes, compatibility is checked coordinate by coordinate. The dashed box is fully contained; the dotted box violates the second-coordinate upper bound." + "That restriction propagates through the second transformation and produces a\n", + "correspondingly restricted output interval.\n", + "\n", + "The key point is:\n", + "\n", + "$$\n", + "\\text{using only part of a valid domain}\n", + "\\neq\n", + "\\text{being incompatible with that domain}.\n", + "$$\n", + "\n", + "The downstream transformation does not require its caller to generate every\n", + "possible value in $[0,1]$.\n", + "\n", + "It requires only that every value it actually receives belongs to $[0,1]$." + ] + }, + { + "cell_type": "markdown", + "id": "cc9a4e48", + "metadata": {}, + "source": [ + "## 7. Visualizing why containment is enough\n", + "\n", + "The outer transformation accepts the entire interval\n", + "\n", + "$$\n", + "D=[0,1].\n", + "$$\n", + "\n", + "The inner transformation produces\n", + "\n", + "$$\n", + "R=[0.25,0.75].\n", + "$$\n", + "\n", + "The figure below shows the relationship directly." ] }, { "cell_type": "code", - "execution_count": 33, - "id": "490d7fe0", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:46.754962Z", - "iopub.status.busy": "2026-08-24T19:24:46.754730Z", - "iopub.status.idle": "2026-08-24T19:24:46.996190Z", - "shell.execute_reply": "2026-08-24T19:24:46.995224Z" - } - }, + "execution_count": 9, + "id": "4ba66b23", + "metadata": {}, "outputs": [ { "data": { - "image/png": "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bl999dVqfR6qWob4WTN79mw0b95cXTy4T58++Pnnn4+5/bvvvov27dur7Tt37ozPPvusxmIlIqLwtH//ftx6661o2bIloqKi0KRJEwwaNAgrVqyo0uc57bTTcPvtt1f4cbNmzcK8efOqNBYyj6DX8C1cuBDjx4/HnDlzVLI3c+ZMDBw4EFu2bPF7iRW5Vt+VV16J6dOn44ILLsDbb7+NIUOGYO3atejUqRPM6vDhw8EOwRTk0koFBQXIy8vjpZVYroZm1mPV4XDA5XKpvzab7ZjbymXQKkuDpp7DW0ZBBpbuWOqzX6fDCYfNdzt/duzYoRKxxMREdf6R843sf9myZRg9ejQ2btxY6VjLugRcyfiPJzY2Vv2t6OMqSt4/ibG8ZFt5TERE0FOOsGbRKvKuVQNJ8k488UQ899xzalkOcvnVJL+iJk6cWGr7oUOHIjc3F5988oln3UknnYRu3bqppPF4srOz1Qc2KysLCQkJMKJDhw6pZFe+5OUC0vv27avQh4vKxjKtHixXlml5NWvWTH1X165dG3muPDyz6xmf+29rehtibUcTlzf3vomVGSsrVbgNoxri0daP+qzLdmZj3JZxqGWrhSOuI2rdrHazkBBx/HPBuHHjsHXrVrz33nuIiYnxuS8nJwfx8fGeWsAnnngCv/zyi7pmb9++fTFhwgSkpqaq+1966SWsWrUK11xzjSoHOSf169cP9913H+Li4lRz6aeffuqz/w8//BD16tXDtGnT8OuvvyItLU0tX3rppaoCRCePPXLkCJ588km1fPPNN6NNmzaIjIxU+5CE65JLLsFNN93kE7vUDK5evVolih06dMAdd9yBtm3beraRWsN33nlH/QAZMGAAkpKS8MMPP6gKF2G329Vju3btqv4vr+/0009XrW/3338/NmzYgC+//FKd26WC58cff1TncXkuSZ5lnzpp7ZP4pKylNS85OVntwztmqfiRJHvz5s0q8Zb7L7roIqxbt07lAkIS8LvuugvffPONKtezzz4bTz/9tDrujELKc/v27WjRooVqsfQmOYqUc1XmKkFNt4uKirBmzRpMmjTJs04+IPLmy8Hkj6yXA8ab1AiW1WehsLBQ3XTy4RKSQBk1iZK45ATqfaOqwTKtHixXlmlFjhWdU3NiS94Wn/tlne7SepfiwroXVqpwrcfosaQne+UlJ10594waNapUsif0ZE8qLO68805V0/biiy+qWq3HH38c9957r1rW7dmzRyVFM2bMUAmXnANff/11lcRIcrhr1y60atVKJWxCkh45L0hFgCRIUmnx+++/qwRQEpizzjqrzNilcuTqq6/Ga6+9phKvKVOmqMRMKluEVKxI87QkfbVq1cLixYtVHO+//756HqnBfPnll3H33Xerx33++eeqZa5hw4Z+n8/73Cr7luRXmsDlNezevRvnnnsuHnnkEfWcb7zxhmoSl8StadOmnn089dRTmDp1qioXSbCl3P/3v/+hXbt26hwujznvvPMwf/587Ny5UyWo3s8t/RjPOOMM3HDDDaqM8/PzVSyXX355lTe/B0IvJ3/5SHXkJxHBbqaUD4T8UvEmy3IA+CO/nvxtL+v9kQ+HHOAlya+L4zUnBDPrl5o9+WKsU6eOWmfU5DTUsExZrqHCrMeqvCb57pXaJrvFXup+qSGyR9g9/69Kx3u+suitLK1btz5mTJIUbtu2TdXQ1a9fX62T5EZq1aSbktRGSaWGJIayXmqehHRPkpo72bckRlIjJ0mjnAe8jR071qcmbNOmTVi5cqVKfoTsW44bPUb5v9TUSQInJImUWjOpaDnllFNUjdgff/yh9iHPKaRW7Ouvv1YJqdQgLliwQHWbkv8LqTGU2kupSNGfR/8rr0u/6TWOZ555pidmqbGSfvc6OTdLZY3UPo4ZM8azXpLCW265xROPdPWSGOW5JcmT1yW1o1IrJv35JcmW5Fh/7meffVbV9EkZ615++WVVZpJbeNdeBpMer3TbkFyoZI5S1UzfoC6/ELxrBOXXgVQrywdN/7AZjbz58gWj/xJmk27VYZlWD5Yry7S8JLGQk5vT6YTDWbqvmTQNOrTq6YNW2eeTWPW/x+ofJ82QUgEhzbf6dlJzJTWAcp/UUMkJXhI5KQd9m5SUFNVMqy+X1Ydv0aJF+Pjjj1UFhyRccr8kL/p28hh5rPd+JMnz3o/EJpUtsk6SPTnf9O/f3+d5ZN9SyyjbSJPjxRdf7LMPSVwlQfVeJ/+XhFO/Cemupf9fSHOzJIHS1CvnNSlPqX2Tmj/v7bp06eKzLMmzdHWSdX/99Ze6X++vKPTaSv25pSZTElapoSxp+/btKkk0Aj1eeS0lm3T1Y840CZ9URcsvvQMHDvisl2X911FJsr4i20u1sdxKMnJTqZSLvCa907YcCEaNNdSwTFmuocKsx6okBunp6aovXz7yAd8WXXQ6oROSo5Or5bll0EZlnk8qCeQ9kERImjXLIv3FJJEruY2c52Qfsl4SQkkAvbeR/nNSS6avk6ZVqQn13kaaUaXmSpqIJcGRfUhzpcxqoW8niaMkEN77keTSez+SBElNm6yTfnVyvzTbliTb6OdoPXadxCZN2/o6STTleaXW1vvcKs/vfexKbZ08l/QxlNpS2YfUHMox4b2dlKH3svzfu6uTvs77fv2v3CSxlGbf//u//yv1uhr813pmBCXj9nefaRI+eVN79uyp2tSlylg/cGTZu+ram3SAlfu9h6zLASTrzUI+OPKBkgNcqnWlJtIoB2ioY5myXEOFWY9VSWKlT5zq6I/StWU5rhxEuCp2aoqNiEV0hG8NiXeSJyN21b6dOaXuj7BHHLfpWJI06SsuzYjSX6xk65D0GZMESWq+pLZKauAkSRJSiyb3S62UPI8kUN7NrkLvXqSvk0oKef+9t/npp5/U4A4Z0OhdW+W9L73GyLtJ13u55DZSAyexSuIlzZ3+yMAKaQK+/vrrPeskydSfV6+N1JuTj+W7775TcwXKAAshiZmMfq4IqSV96623VPKtV+ZIE7O3Hj16qD6I8po4MthATbrS3DpixAj06tULvXv3Vm318iV33XXXqfuHDx+ORo0aqb54+kgpqX6WTp3nn3++6l8gVcsy8omIiELbkA+P/viviHv73Isr2xePVvV24QcXIqMwo0rmiz355JPVeUoGFEgCJ81uUuHwwgsv4M8//1QDDqWPmgySkHOZ3C/95+ScJee48pJERRI8SYaklkxq7qT/mgxy+OKLL9SozjfffFMlOvL/ypJ4pbJEKlyk5lCah/fu3av6IEpSJjHLOVeSNPm/vH7pQyd9B2UgRkXJa5BBIVL7JsnhAw88UOGpd6666io1ollG7cpADGl61kcl6wmn9AeUPnsyglkGm0j5bd26VeULr7zyimH775t+4mWZZkXerAcffFB1sly/fj2WLl3qGZghb6a09evkF44MBZcET6qTZQSPdPo08xx8REQUXJLgyHyvMt2IDBKQc46MjpUWJ0n49IRDBiDIwAsZVSoJlTxOmmMrQkbqSlLSsWNH1doj50EZlCB96eScKU260udPH4xRWRKv9KeTWKWSRRK+K664Qo181c/B8nySmEniJC1ycp+Mmq0MaYKWspHzuCR9UmsqtXEVIVOUSD9GyRUkZ5DkT/IHofeDkxHEUpsofUVlOhZJwm+//XZVC+vdNzDcBH0evpoWCvPwmb1JJ5hYpizXUGHWY7Wsucc6v148erMqa/j+t+B/x6zhM9Ol1YKhIk261UVqHSVhlfO6v2lzjKognObhIyIiIqoIadqWmlPp7vXbb7/hnnvuUXPshVKyFwxM+IiIKOikpq2yZNBGWT4c8qFn0Ia/2qikqKRKPy8Fhww0kWZc+Sujbi+77DI8+qjvVVWoNCZ8REQUdNXVrOo95YoRmh8pcNKfUG5UMeHbe5GIiIgoTDDhIyIiIjI5JnxEREREJseEj4iIiMjkmPARERERmRwTPiIiIiKTY8JHRERB48rJQd6aNeqmFRWVut+dl+e5X26uzEy/+8lbu9azjWPvXr/bFGzejPw1a333l5ODUCfz0cll3uSqLHJ1hopcs1eu+Rts8+bNq1DcVDmch4+IiIKm8K+/sPPqa9T/23z7DSJq1/a5v2j3bs/9ovGcFxB/2mml9rNz+AjA6VT/r33rWNQZM6bUNvsfmoKC337zWdds/luI7dmzXLHu3r0bkydPVtd7P3z4sJr0d8iQIWoS4NTU1HK+YmDHjh3qclrr1q1T14MN1NNPP62uOS/Xl5VLh4YauV7veeedF+wwTI8JHxERGYK7oADOw4dLJX1VLfakk2D97zJctnImSP/88w/69u2Ltm3b4p133lEJ26ZNm3DXXXfh888/x48//oiUlOBck3fbtm3o2bMn2rRpg1Akl0Sr6suiuVwuNbm2TLJNR7EkiIjIEP4dPQZFO3dW/xNZLGg04yk0eeF5RLVuXa6HjBkzBpGRkfjyyy/Rv39/NG3aFOeeey6WL1+OPXv24L777vPavQUffPCBz+OlyVKaLoUki6J79+5q29P81Fh6e+GFF9CqVSv1/O3atcObb77p0yz7/vvvq+vLyr6uvfZav/s4ePAgBg0apBIref758+eX2mbXrl248MILUatWLSQkJKjr0x44cMBz/0MPPaRqJOfOnatev2w3evRolVw9/vjjqF+/PurWrVvqMmczZsxA586dVZNzkyZN1GOOHDlSZpOu/jzyOuX1Sa3lFVdcgZxjNL/r+/joo4/QsWNHREVFqdfzyy+/qObu2rVrq/3Ie7d27Vqfx0q5vfLKK7jooosQGxurEmfZjzdZlvXR0dE4/fTT8frrr6vHZXp1Mfj2229x6qmnqjKW13nbbbchNzcXRsGEj4iIDNO8W1Jkkyaq2VW/xZbRBNrsjdc92yRddJHfbeo/NBlN3ngDtceMhrsCJ+L09HR88cUXKlEpWRMlSc7VV1+NhQsXqku3lcfPP/+s/kqyKE2xixcvLnPbJUuWYNy4cbjzzjuxceNG3Hzzzbjuuuvw1VdfqfsloTnnnHNUcib7mjVrlt/9SCIoTdLyuPfeew/PP/+8SgJ1csk5Sfbkta5evRrLli1TtZrS3FqyNlFqNKVZW2o6JfmTRPLff/9Vj/u///s/3H///fjpp588j5FatmeeeUbViEqitHLlyuNeGk2eR5LmTz75RN1k34899tgxH5OXl6eeX5I3eS5JPiVJHDFihErGpBZWkjZpPi6ZPE6ZMkWV4e+//67ul/dUykJs374dl156qWq+/+2339R74J3g6/HK+3DJJZeofcjxIM85duxYGIYWZrKysuQTqf4andvt1nJyctRfYpkaGY9Vlml55efna3/88Yf6KxyHDmkZ773nuclydR6nTqezwt+pP/74ozpvLFmyxO/9M2bMUPcfOHBALfvbNjExUXvttdfU/7dv3662Wbdu3XGfu1+/ftrIkSN91l122WXaeeed51m+8MILtREjRpS5jy1btqjn+/nnnz3r/vzzT7Xu6aefVstffvmlZrPZtF27dnm22bRpk8/jJk+erMXGxmrZ2dmebQYOHKg1b95clauuXbt22vTp08uM591339VSU1M9y1IuUj46f89z1113aX369Clzn7IPiXX9+vXasbhcLi0+Pl77+OOPPevkcffff79n+ciRI2rd559/rpbvuecerVOnTj77ue+++9Q2GRkZavmGG27QbrrpJp9tvvnmG81qtXqO9eN9FrxlZmZWea7CGj4iIgoa6a+XdMklnlt1998LRHlr8Crjm2++UU2k+k1vcv3zzz9x8skn+2wry7LeH3mc935kv7JtRESE6uena9++vU8zqmwjzZBy00nTqGzj/VzSxBofH+9ZrlevHjp06ODTV07WedceSk3mmWeeiUaNGqnHDhs2DGlpaapGriwln0cGyHjv0x9p8u7SpYvPOmmSHjlypKrZkyZdaaqW5mRp7vXm/Thpepbt9OfbsmULTjzxRJ/te/fu7bMs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GTx4MOLi4vDoo4+q9Y899hjq1auH+Ph43HDDDSgoKPB5XMkmXalNu+2223D33XcjJSUF9evXV83A3mbMmKGSV3keqbGU13nkyBF136pVq3DdddchKytLxSQ3/fGFhYWYMGECGjVqpB7bp08ftf2x3H777Zg4cSJOOumkCpY+EZkNEz4iMpz09HQsXbpU1eRJclOS3uTpdrtVsifbr169GsuWLcM///yDoUOHerZdsmQJxo0bhzvvvBMbN27EzTffrJKqr776ymefklhddNFF2LBhA66//nosWrRIrZs2bRp+/fVXNGjQAM8///xxY3/99ddVzD/99BMef/xxTJ06VcWls1qteOaZZ7Bp0ya17cqVK1WCKPr164eZM2eqxHXfvn3qJkmeGDt2LH744QcsWLAAv//+Oy677DJVc/f3338HUNJEFDY0IiKD+emnnzT5elq8ePExt/vyyy81m82m7dq1y7Nu06ZN6rE///yzWu7Xr582cuRIn8dddtll2nnnnedZlu1vv/12n2369u2rjR492mddnz59tK5du3qWR4wYoV144YWe5f79+2unnHKKz2NOPPFE7Z577inzNbz77rtaamqqZ/m1117TEhMTfbbZuXOnep179uzxWX/mmWdqkyZN0o7nq6++Uq8xIyPjuNsSkTmxho+IDOdoDnZ8f/75p2oWlZuuY8eOqgZQ7tO3kb6A3mRZv1/Xq1evUvuWZlNvffv2PW5MXbp08VmWmsGDBw96lpcvX44zzzxTNc1KU/GwYcOQlpam+tuVRWodXS6XataWpmv9JrWa27ZtO25MREQctEFEhtOmTRvVf606B2aU5K/puDJKDvaQ1yFNz/pAlAsuuACjRo1S/QSln9+3336r+gcWFRUhNjbW7z6lj5/NZsOaNWvUX2+S+BERHQ9r+IjIcCQRGjhwIGbPno3c3NxS9+vTi3To0AG7d+9WN90ff/yh7peaPn2b7777zufxsqzfXxZ5nPTD8+Y9WKQyJGGT5O+pp55SAymkxm7v3r0+28jAEqnN89a9e3e1TmoKW7du7XOTgSFERMfDhI+IDEmSPUlyevfujffff18NTpBmVhnwoDetDhgwQI14vfrqq7F27Vo1onf48OHo37+/p4n2rrvuUnPbyShc2YeMkl28eLFnMERZZKDH3Llz8dprr+Gvv/7C5MmT1UCLQEiCJlO+PPvss2pwiYwWnjNnjs82zZs3VzV6Mtfg4cOHVVOvJIbyGuW1Sezbt29Xr3X69On49NNPjzmP4fr167F161ZP07AsyyAXIgozwe5ESERUlr1792pjxozRmjVrpkVGRmqNGjXSBg8erAYheA9okHVxcXFafHy8GpCxf/9+n/08//zzWsuWLTW73a61bdtWe+ONN3zul6/CJUuWlHr+Rx99VKtdu7ZWq1YtNUDj7rvvPu6gjXHjxvnsQ+6X7XQzZszQGjRooMXExGgDBw5UsZQcUHHLLbeogRyyfvLkyWpdUVGR9uCDD2rNmzdXr0P2cdFFF2m///57meUnj5V9lLzJwBAiCi8W+SfYSScRERERVR826RIRERGZHBM+IiIiIpNjwkdERERkckz4iIiIiEyOCR8RERGRyTHhIyIiIjI5JnxEREREJseEj4iIiMjkmPARERERmRwTPiIiIiKTY8JHREREZHJM+IiIiIhgbv8Pz4xfblLu/N4AAAAASUVORK5CYII=", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3kAAAEOCAYAAAA0SN6FAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAO75JREFUeJzt3Qd4FNXex/ETCBAQQhHpTVCQjsIrTUWUoqKADS54EcUOFkBFrCCgomLFiiLYkKYgVxRURFFARURFaVJFFLAgRHqZ9/kd7+yd3ewmm2w2yU6+n+dZZSezs2fOnJk9/zllkhzHcQwAAAAAwBcK5XUCAAAAAAA5hyAPAAAAAHyEIA8AAAAAfIQgDwAAAAB8hCAPAAAAAHyEIA8AAAAAfIQgDwAAAAB8hCAPAAAAAHyEIA8AAAAAfIQgD/D4+OOPTVJSkpk+fbqv8qVWrVrmsssuy+tkANbGjRvteTZx4sRAjgwfPtwuy006J3RuxMvpp59uX9Fed/T/eFN6GjVqFPfviTVPkD/oHFXZ1DmbX+Xm+QMkEoI8+J4u/tG8Ev0HYtGiRbai/Ndff5mC5t1337X7DsCYX375xZ4P33zzDdmRg8hXAIkkOa8TAMTbq6++GvT+lVdeMR988EG65fXr1zcrV65M6CDv3nvvta0TZcqUCfrb6tWrTaFChXwd5D399NMEegnsrrvuMkOHDs3V73zhhRfMkSNH4rb9999/3+RVMKJrgVopmzVrlidp8CPyNX867bTTzN69e03RokXzOilAvkKQB9/797//HfT+888/t0Fe6HJJ5CAvI8WKFct0nd27d5ujjjrK+N2hQ4dsxT6RKwR79uwxJUqUMH6SnJxsX7mpSJEicd1+IpcxxM6P52l+pBuYKSkpeZ0MIN/x7619IAYKAu677z5TrVo1++Nx5plnmrVr16Zb74svvjBnnXWWKV26tP0xb9eunVm4cGFU37F//34zbNgwc9xxx9kgrHr16mbIkCF2uZe6kl5//fVm5syZdiyN1m3YsKGZM2dOYB11zbr11lvtv4899thAF1R3HEXomDx3nMUnn3xi+vfvbypUqGD31fXee++ZU0891QZ9pUqVMl26dDE//PBDpvsUaVxVuHEdStO5555rWzvU2qB8btCggXnrrbeCPnvw4EHbKnH88cfbdY4++mhzyimn2EBdtF9qxXPzyn15x36NGTPGPP7446ZOnTo2/1asWGH/vmrVKnPRRReZcuXK2W23aNHCzJo1K+j7//zzT3PLLbeYxo0bm5IlS5rU1FRz9tlnm2+//TbsuJCpU6fa9FatWtXmnba/c+dOe1wHDhxo81rbufzyy9Md64zGUC1dutTesVY5u+OOO+zf3n77bXtsqlSpYvdL+zdy5Ehz+PDhsNvQfrdv395uQ+l76KGH0n3fpk2bTNeuXe2xV1oHDRpk5s6dG7ZLcyzlP9qy89prr5nmzZub4sWL2+P0r3/9y2zevDlonR9//NFceOGFplKlSvY4qixrPeV7VsbkecvLuHHjAuXl//7v/8ySJUuCPrt161Z7DPVdWqdy5cqmW7duQWU83Pizn3/+2XTv3j0ofyOVg+zkr46R0itKn3s+eMc/SjRlIdprVCRuHurYnXzyyebTTz8Nu9727dvNFVdcYSpWrGiPX9OmTc3LL78ctM5JJ51kLrjggqBlOie1b999911g2ZQpU+wy94adW650/XZ7OSg/lTcKwrx0TdG1RevoHK1Xr17gXMssXzM6T6PNxwkTJpgzzjjDlgutp+vhs88+my6/3Gun0qRrlvJXeeGen7qG6r3yUufOsmXLojpeusbr+7U9letRo0ZFbOl+5pln7O+Q0qnrz4ABA9INFXDzRMdHZVd5ojxwx7zr96dly5b2+5TXH374YbprkX6f9Deto2v/xRdfnG58YLgxeVm55gF+RUseEMbo0aPt3UFV7lVR1A/DJZdcYitdro8++shW9vUjqh9wre/+SKsyo0pNJPrhVEX6s88+M1dffbXtKrp8+XLz2GOPmTVr1tiAzkvr6YdbP3gKHJ588klbqf3pp5/sD58qP/rcG2+8YbdRvnx5+7ljjjkmw+Or7Wmde+65x7bkibqx9u3b13Tu3Nk8+OCDtiKkioYqP6os5OREFaqc9+zZ01x77bX2O5V/+hFXANuxY8dAJe2BBx4wV155pc3TXbt2ma+++sp8/fXXdp1rrrnGdqMK1wXXpe3u27fP5rUqJQoWVKFp27at/eFXN0FVuhWgqQL+5ptvmvPPP99+dv369fZ4KF0KoLdt22aef/55W2lRBUIVHC+lVRUSbVMVy7Fjx9oWI5WPHTt22P1Ra7Iqh9qe8j4zf/zxhy1rClzUAq3KsGgbqowOHjzY/l9lUttTHj388MNB29B3K2BQWenRo4etaN122222Mqhti8qAyu+vv/5qbrrpJhs0TZo0ycyfPz9dmmIp/9HSjZa7777bplfH/7fffrP5qUq0yqIq4wcOHLBlVRXmG264waZ5y5Yt5p133rGVTlXos0r7nJaWZsuWKo86/5VvKgtu65/OP5UhfafOCQUqKoM6JyOdI+pSphtGWufGG2+0ZUdlVnmZU/mra8mIESNsOVB5180aadOmTZbKQlavUaHGjx9v80/fq5sbyjttT+eeghxvnqhCrnNFN7N0TkybNs0GZDp+Koei/dD1zXvzRfmvfFF+NGnSxC7Xv3VNU3q9tJ/ats5PXTtefPFFG0zpGifalgInbUf5p+uE0uQG1dHka7jzNCv5qOusAietr1bt//znP/YarW0oiPJS2nr37m3zWN+lGxPnnXeeee6552xwqc+J9lf7nlmXfd20UDCkng7u9VBBuq5loXQN042sDh06mOuuu85uW2nXjRDll7eFXGVN+ao80TVU6+nfr7/+ui0XuvZrP3S90g0x3cDRb5xoexqGoPUVdCq40+dVXnTtzayVNJpyDviaAxQwAwYMcCIV/fnz59u/1a9f39m/f39g+RNPPGGXL1++3L4/cuSIc/zxxzudO3e2/3bt2bPHOfbYY52OHTtmmIZXX33VKVSokPPpp58GLX/uuefs9yxcuDCwTO+LFi3qrF27NrDs22+/tcvHjh0bWPbwww/bZRs2bEj3fTVr1nT69u0beD9hwgS77imnnOIcOnQosDwtLc0pU6aMc9VVVwV9fuvWrU7p0qXTLQ81bNiwsHnrfp83bUqTlr355puBZTt37nQqV67snHjiiYFlTZs2dbp06ZKtY6rv0/LU1FRn+/btQX8788wzncaNGzv79u0LLNOxbNOmjT22Lv398OHD6bZbrFgxZ8SIEenKTqNGjZwDBw4Elvfq1ctJSkpyzj777KBttG7d2uZBZtq1a2e3q7IRSuUt1DXXXOOUKFEiaL/cbbzyyiuBZSrflSpVci688MLAskceecSuN3PmzMCyvXv3OieccIJdrn3MifLvHheVi0hlZ+PGjU7hwoWd++67L+izOgeTk5MDy5ctW2Y/N23aNCerdE54j4GbrqOPPtr5888/A8vffvttu/w///mPfb9jxw77XudcRpTverkef/xx+7mpU6cGlu3evds57rjjcjR/lyxZ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AYUKcSoBAJDTv6u6wQAg66iZAgAAAICPEOQBAAAAgI8Q5AEAAACAjxDkATHSeIG/9x0yafsO5suXn8cznH766WbgwIEmP8hPaYk2vZqdU69vvvkmV7/7sssuC3z3zJkz4/dFKvv7duXfl4/PzYIsL8+tRJFr1wCgAGN2TSBGew46psXoT/JtPi4f3smUSikS8e+bN282w4YNM3PmzDG///67qVy5sunevbu55557zNFHH52lik2zZs3M448/bgqit956y84GF6t27dqZBQsW2H/rMQnHHHOMad26tRkyZIhp1aqVyUlXXXWVGTFihClfvnzQ8qeffto8/PDD9vmPTZs2NWPHjjUnn3xyVNtU2vXZpUuXml9//dXMmDHDlievJ554wowePdqWtbjan2bM6Oom3xq62ZiU1IiV4L/++osKcA7znl86X+vUqWPuvvtu07t373x3bj3wwAP2urJq1So722SbNm3Mgw8+aOrVqxdYZ/jw4ebee+8N+pz+rs9EKytpqlWrlp3xMlT//v3tdqJNU65dA4ACjJY8oABbv369adGihfnxxx/NG2+8YdauXWuee+45M2/ePBtY/Pnnn7meJj0fKRGVK1fOlCpVKqZtqNV12bJltvKjAEnHY9KkSXaWuVNPPdV88MEHJh4PG05O/t/9vilTppjBgwfbwP/rr7+2lb7OnTub7du3R7XN3bt328+4Fb5wSpcuzUOOE0S052MinLfu+TVmzBh7fq1evdqcddZZ5tJLLzUbNmzId+fWJ598YgYMGGA+//xze+7rkT2dOnWy55hXw4YN7f64r88++yzqdGY1TUuWLAn6LveadPHFF2cpTVwDgPgjyAMKMFUg9AD3999/397hrlGjhjn77LPNhx9+aLZs2WLuvPPOwN3b0BY6tdrpjq3b6qAKie7Oul1w9BBb0XMEdUf62GOPtXejVYmYPn16UAvg9ddfb7s66q63KhjhqGKjyljJkiXt3d9HHnkk3Tr79+83N954o314bkpKijnllFNspcRL33fDDTfY7ytbtqypWLGieeGFF+z2L7/8chuoHXfccea9994LfEatnNpWmTJlbOvmueeea9atWxexu6b+rXSo9U3Bnyp7bl5lRMF2WlqaOe200+xnlO/t27c306ZNs0G3ezzi6dFHH7WtEMqLBg0a2KBfFdaXXnopqs+r/IwaNcqc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0HGTTZs2OYULF3a2bNkStM6ZZ57p3H777RG/FwDgb7TkAQAsjctTF8qVK1emyxEta9u2bdAyvVdrkbebpbpYhlIrVp06dQLvK1asaLtTqvXMu8zbHVMth+edd56pUaOGbf1q166dXf7TTz9l6WiNGzfOjB8/3syaNcscc8wxdplaB9euXWu3qzTopS6b+/btM+vWrTM7d+60LYDq9uhKTk4Ou29e55xzjilSpIj9Lrd7q1r41B3WNWXKFJtv6oKq773rrruyvE9ealVV/qsLqLsven3yySd2XwAABVNyXicAAJA/nHbaabYb4+23356lrpFeGhMWSoGPl8bGhVt25MgR++/du3fbdOil7o4KzhQI6X1WJnOZP3++ueGGG8wbb7xhmjRpElj+999/m+bNm9tth3IDwewoWrSoHW+oLpvq1qr/a9ZPBYiiLpWXXHKJuffee+2+lC5d2naxDB3b6FWoUKF0YwG9Y/i0L+puq6BY//fyBtEAgIKFIA8AEKBHKeg5bZokxat+/fp27JqX3qsFKTS4iNWqVavMH3/8YdNSvXp1u+yrr77K0jbUUqeA64477jAXXHBB0N9OOukk26Km2TjV0hZO5cqVzRdffGEDXzl06JANpPTZjCiI69ixo/nhhx/MRx99ZEaNGhX426JFi0zNmjXNnXfeGVi2adOmDLenoFOtii612n3//femffv29v2JJ55ol6kV1B1zCAAA3TUBAAGNGze2gYomSvG6+eabzbx58+xkKHoenbp1PvXUU3ZWx5ymLppqFdNEMOvXr7fdH/W90dq7d6/t6qkASDN8bt26NfAS7V/58uXtjJqaeGXDhg12MhjN8OlOPHPTTTfZIFOTvijo7N+/f+DB6xlRUKiumPqOY489NqjL5/HHH29bJNV6p66UyuOMJnORM844w8yePdu+lI7rrrsuKB0KsvVdmtH0rbfesvvy5Zdf2plS9RkAQMFEkAcACDJixIhA10mXWrCmTp1qA5RGjRqZe+65x66X3W6dmbVeaQbKadOmmQYNGthgS7N2Rmvbtm02IFJQWqVKFdsq577cMYILFiywwaRa+dRKecUVV9gxeW7LnoLaPn36mL59+5rWrVvb8XuaETQz6nbaq1cvO+5PwZdX165dzaBBg+xsmGotVcueOwNpJP369bNpUBCncYl67ILbiueaMGGC/bvSrBZYzeap2UW1fwCAgilJs6/kdSIAAAAAADmDljwAAAAA8BGCPAAAAADwEYI8AAAAAPARgjwAAAAA8BGCPAAAAADwEYI8AAAAAPARgjwAAAAA8BGCPAAAAADwEYI8AAAAAPARgjwAAAAA8BGCPAAAAADwEYI8AAAAADD+8f8MEm8WGQW7+wAAAABJRU5ErkJggg==", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -462,481 +957,637 @@ } ], "source": [ - "fig, ax = plt.subplots(figsize=(6.5, 6.5))\n", + "fig, ax = plt.subplots(figsize=(9, 2.8))\n", + "\n", + "ax.plot(\n", + " [0, 1],\n", + " [1, 1],\n", + " linewidth=8,\n", + " label=r\"Outer domain $D=[0,1]$\",\n", + ")\n", + "\n", + "ax.plot(\n", + " [0.25, 0.75],\n", + " [0.65, 0.65],\n", + " linewidth=8,\n", + " label=r\"Inner range $R=[0.25,0.75]$\",\n", + ")\n", + "\n", + "ax.scatter(\n", + " [0, 1],\n", + " [1, 1],\n", + " s=60,\n", + ")\n", + "\n", + "ax.scatter(\n", + " [0.25, 0.75],\n", + " [0.65, 0.65],\n", + " s=60,\n", + ")\n", + "\n", + "ax.set_xlim(-0.05, 1.05)\n", + "ax.set_ylim(0.4, 1.25)\n", + "ax.set_yticks([])\n", + "ax.set_xlabel(\"Normalized value\")\n", + "ax.set_title(\"The entire upstream range lies inside the downstream domain\")\n", + "ax.legend(loc=\"lower center\", ncol=2)\n", + "ax.grid(axis=\"x\", alpha=0.2)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e53d3628", + "metadata": {}, + "source": [ + "The shorter interval does not need to cover the longer interval.\n", + "\n", + "It only needs to fit inside it:\n", + "\n", + "$$\n", + "\\boxed{\n", + "[0.25,0.75]\\subseteq[0,1]\n", + "}.\n", + "$$\n", + "\n", + "That simple geometric relationship is the core of the compatibility change." + ] + }, + { + "cell_type": "markdown", + "id": "27194fb4", + "metadata": {}, + "source": [ + "## 8. The same idea in multiple dimensions\n", + "\n", + "The rule is applied coordinate by coordinate.\n", + "\n", + "Suppose a system has two normalized operating quantities:\n", + "\n", + "- coordinate 1 is restricted to\n", + "\n", + " $$\n", + " [0.10,0.80],\n", + " $$\n", + "\n", + "- coordinate 2 is restricted to\n", + "\n", + " $$\n", + " [0.20,0.90].\n", + " $$\n", + "\n", + "The next transformation accepts the unit interval in each coordinate:\n", + "\n", + "$$\n", + "D=[0,1]^2.\n", + "$$\n", + "\n", + "The upstream range is therefore\n", + "\n", + "$$\n", + "R=\n", + "[0.10,0.80]\n", + "\\times\n", + "[0.20,0.90].\n", + "$$\n", + "\n", + "Compatibility requires\n", "\n", - "outer_box = Rectangle(\n", - " (0, 0), 1, 1, fill=False, linewidth=3, color=\"black\", label=\"Domain $[0,1]^2$\"\n", - ")\n", - "valid_box = Rectangle(\n", - " (0.1, 0.2),\n", - " 0.7,\n", - " 0.7,\n", - " fill=False,\n", - " linewidth=3,\n", - " linestyle=\"--\",\n", - " color=\"tab:green\",\n", - " label=\"Contained range\",\n", - ")\n", - "invalid_box = Rectangle(\n", - " (0.1, 0.2),\n", - " 0.7,\n", - " 0.9,\n", - " fill=False,\n", - " linewidth=2.5,\n", - " linestyle=\":\",\n", - " color=\"tab:red\",\n", - " label=\"Out-of-domain range\",\n", - ")\n", + "$$\n", + "[0.10,0.80]\\subseteq[0,1]\n", + "$$\n", "\n", - "for box in (outer_box, valid_box, invalid_box):\n", - " ax.add_patch(box)\n", + "and\n", "\n", - "ax.set(\n", - " xlim=(-0.1, 1.2),\n", - " ylim=(-0.1, 1.2),\n", - " xlabel=\"Coordinate 1\",\n", - " ylabel=\"Coordinate 2\",\n", - " title=\"Coordinate-wise range-in-domain compatibility\",\n", - ")\n", - "ax.set_aspect(\"equal\")\n", - "ax.legend(loc=\"lower right\")\n", - "ax.grid(alpha=0.15)\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "9e3e56de", - "metadata": {}, - "source": [ - "### E. Integration with a compatible chained measure\n", + "$$\n", + "[0.20,0.90]\\subseteq[0,1].\n", + "$$\n", + "\n", + "Since both conditions hold,\n", "\n", - "Here the inner sampler and chained outer target both represent $\\mathcal{U}[0.25,0.75]$, while the inner range is strictly contained in the outer unit domain. Because the mean $\\mathbb{E}[X]=0.5$ is symmetry-driven, the second moment provides a stronger end-to-end check using QMCPy's standard integration API." + "$$\n", + "\\boxed{R\\subseteq D}.\n", + "$$" ] }, { "cell_type": "code", - "execution_count": 34, - "id": "5a1ad5ba", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:47.000674Z", - "iopub.status.busy": "2026-08-24T19:24:47.000331Z", - "iopub.status.idle": "2026-08-24T19:24:47.014019Z", - "shell.execute_reply": "2026-08-24T19:24:47.012979Z" - } - }, + "execution_count": 10, + "id": "ad1a30f8", + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Chained-measure integration estimate: 0.500000000\n", - "Exact Uniform mean: 0.500000000\n", - "Absolute error: 5.551e-17\n", - "Within requested tolerance: True\n", - "Chained-measure second-moment estimate: 0.270833333335\n", - "Exact second moment: 0.270833333333\n", - "Absolute error: 1.847e-12\n", - "Within requested tolerance: True\n" + "Inner range:\n", + "[[0.1 0.8]\n", + " [0.2 0.9]]\n", + "\n", + "Outer domain:\n", + "[[0 1]]\n", + "\n", + "QMCPy reports a compatibility error: False\n", + "Generated sample shape: (8, 2)\n", + "All generated values are finite: True\n" ] } ], "source": [ - "integration_inner = Uniform(\n", - " DigitalNetB2(1, seed=7),\n", - " lower_bound=0.25,\n", - " upper_bound=0.75,\n", + "inner_2d = Uniform(\n", + " DigitalNetB2(2, randomize=\"FALSE\"),\n", + " lower_bound=[0.10, 0.20],\n", + " upper_bound=[0.80, 0.90],\n", ")\n", - "integration_outer = Uniform(\n", - " integration_inner,\n", - " lower_bound=0.25,\n", - " upper_bound=0.75,\n", + "\n", + "outer_2d = Kumaraswamy(\n", + " inner_2d,\n", + " a=[2.0, 2.0],\n", + " b=[2.0, 2.0],\n", ")\n", - "integrand = CustomFun(integration_outer, g=lambda x: x[..., 0])\n", - "\n", - "integration_tolerance = 1e-6\n", - "solution, data = CubQMCSobolG(\n", - " integrand,\n", - " abs_tol=integration_tolerance,\n", - ").integrate()\n", - "solution = float(np.asarray(solution))\n", - "exact_value = 0.5\n", - "absolute_error = abs(solution - exact_value)\n", - "\n", - "print(\"Chained-measure integration estimate:\", f\"{solution:.9f}\")\n", - "print(\"Exact Uniform mean:\", f\"{exact_value:.9f}\")\n", - "print(\"Absolute error:\", f\"{absolute_error:.3e}\")\n", - "print(\"Within requested tolerance:\", absolute_error <= integration_tolerance)\n", - "\n", - "second_moment_integrand = CustomFun(\n", - " integration_outer,\n", - " g=lambda x: x[..., 0] ** 2,\n", + "\n", + "samples_2d = outer_2d.gen_samples(8)\n", + "\n", + "print(\"Inner range:\")\n", + "print(inner_2d.range)\n", + "\n", + "print(\"\\nOuter domain:\")\n", + "print(outer_2d.domain)\n", + "\n", + "print(\n", + " \"\\nQMCPy reports a compatibility error:\",\n", + " outer_2d.sub_compatibility_error,\n", ")\n", - "second_moment_solution, second_moment_data = CubQMCSobolG(\n", - " second_moment_integrand,\n", - " abs_tol=integration_tolerance,\n", - ").integrate()\n", - "second_moment_solution = float(np.asarray(second_moment_solution))\n", - "a, b = 0.25, 0.75\n", - "exact_second_moment = (a**2 + a * b + b**2) / 3\n", - "second_moment_error = abs(second_moment_solution - exact_second_moment)\n", "\n", "print(\n", - " \"Chained-measure second-moment estimate:\",\n", - " f\"{second_moment_solution:.12f}\",\n", + " \"Generated sample shape:\",\n", + " samples_2d.shape,\n", ")\n", - "print(\"Exact second moment:\", f\"{exact_second_moment:.12f}\")\n", - "print(\"Absolute error:\", f\"{second_moment_error:.3e}\")\n", + "\n", "print(\n", - " \"Within requested tolerance:\",\n", - " second_moment_error <= integration_tolerance,\n", - ")\n" + " \"All generated values are finite:\",\n", + " np.isfinite(samples_2d).all(),\n", + ")" ] }, { "cell_type": "markdown", - "id": "02c17b09", + "id": "448ea229", "metadata": {}, "source": [ - "## 4. What this change solves\n", + "### What does the two-dimensional result show?\n", "\n", - "The current PR solves only\n", + "The inner range has one interval for each coordinate:\n", "\n", "$$\n", - "R_{j-1}=D_j\n", - "\\quad\\longrightarrow\\quad\n", - "R_{j-1}\\subseteq D_j.\n", + "R=\n", + "\\begin{bmatrix}\n", + "0.10 & 0.80\\\\\n", + "0.20 & 0.90\n", + "\\end{bmatrix}.\n", "$$\n", "\n", - "This determines whether the output support of one existing `TrueMeasure` transformation can feed the domain of the next. It does **not** by itself implement arbitrary measure transport, Gaussian-to-Logistic importance sampling, forward CDF maps, or general transport/Jacobian abstractions." - ] - }, - { - "cell_type": "markdown", - "id": "d560ec14", - "metadata": {}, - "source": [ - "## 5. QMC, Transport, and Importance Sampling\n", + "The outer `Kumaraswamy` transformation uses the common unit-domain interval\n", "\n", - "### 5.1 QMC and the role of Uniform\n", + "$$\n", + "D=[0,1].\n", + "$$\n", "\n", - "Sobol/DigitalNet points live in the unit cube, so direct QMC sampling begins with Uniform coordinates. Gaussian and Logistic samples are obtained separately from that reference space:\n", + "QMCPy broadcasts that common domain across both coordinates and checks\n", "\n", "$$\n", - "U\\xrightarrow{F_G^{-1}}X_G,\n", - "\\qquad\n", - "U\\xrightarrow{F_L^{-1}}X_L.\n", + "0\\le0.10,\\qquad0.80\\le1,\n", + "$$\n", + "\n", + "and\n", + "\n", "$$\n", + "0\\le0.20,\\qquad0.90\\le1.\n", + "$$\n", + "\n", + "Every coordinate passes, so the chain is compatible and samples can be\n", + "generated normally.\n", "\n", - "Uniform is the reference space from which QMC points originate. We therefore need to distinguish the direction of a mathematical transport from the direction in which the QMC algorithm is actually evaluated." + "This demonstrates that the change applies not only to a single interval but\n", + "also to multidimensional axis-aligned boxes." ] }, { "cell_type": "markdown", - "id": "a76d04ee", + "id": "c9a49861", "metadata": {}, "source": [ - "### 5.2 Why the deterministic Logistic detour cancels\n", + "## 9. Containment does not mean “accept everything”\n", "\n", - "Let $F_G$ and $F_L$ be the Gaussian and Logistic CDFs. A deterministic Gaussian-to-Logistic transport is\n", + "The new rule is less restrictive than equality, but it is not weaker in the\n", + "sense of allowing invalid inputs.\n", + "\n", + "Consider an upstream transformation whose range is\n", "\n", "$$\n", - "T_{G\\to L}(x)=F_L^{-1}(F_G(x)).\n", + "[-0.10,0.75].\n", "$$\n", "\n", - "If that Logistic value is immediately mapped to Uniform, then\n", + "The next transformation still accepts only\n", "\n", "$$\n", - "F_L(T_{G\\to L}(x))\n", - "=F_L(F_L^{-1}(F_G(x)))\n", - "=F_G(x).\n", + "[0,1].\n", "$$\n", "\n", - "Equivalently,\n", + "Now\n", "\n", "$$\n", - "F_L\\circ F_L^{-1}\\circ F_G=F_G,\n", - "\\qquad\n", - "\\boxed{G\\rightarrow L\\rightarrow U\\equiv G\\rightarrow U}.\n", + "-0.10 < 0,\n", + "$$\n", + "\n", + "so part of the upstream range lies outside the downstream domain.\n", + "\n", + "Therefore,\n", + "\n", + "$$\n", + "[-0.10,0.75]\\nsubseteq[0,1].\n", "$$\n", "\n", - "If Logistic is inserted only as a deterministic transport and is immediately mapped back to Uniform, it adds no new transformation: the Logistic inverse CDF and CDF cancel." + "This chain must still be rejected." ] }, { - "cell_type": "markdown", - "id": "4c444800", + "cell_type": "code", + "execution_count": 11, + "id": "be14463b", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Invalid inner range:\n", + "[[-0.1 0.75]]\n", + "\n", + "Outer domain:\n", + "[[0 1]]\n", + "\n", + "QMCPy reports a compatibility error: True\n", + "\n", + "Sampling is correctly rejected:\n", + "ParameterError - The sub-transform range must be contained within the transform domain.\n" + ] + } + ], "source": [ - "### 5.3 Logistic as an importance-sampling proposal\n", + "invalid_inner = Uniform(\n", + " DigitalNetB2(1, randomize=\"FALSE\"),\n", + " lower_bound=-0.10,\n", + " upper_bound=0.75,\n", + ")\n", "\n", - "Logistic becomes useful here when it is introduced as an alternative sampling measure rather than as an intermediate deterministic transport. Let $p_G$ be the Gaussian target density and $p_L$ the Logistic proposal density:\n", + "invalid_outer = Kumaraswamy(\n", + " invalid_inner,\n", + " a=2.0,\n", + " b=2.0,\n", + ")\n", "\n", - "$$\n", - "I=\\int_{\\mathbb R}g(x)p_G(x)\\,dx\n", - "=\\int_{\\mathbb R}g(x)\\frac{p_G(x)}{p_L(x)}p_L(x)\\,dx.\n", - "$$\n", + "print(\"Invalid inner range:\")\n", + "print(invalid_inner.range)\n", "\n", - "This is a **change of measure through a likelihood ratio**, not a Gaussian-CDF-to-Logistic-inverse-CDF point transport. With $x=F_L^{-1}(u)$ and $du=p_L(x)\\,dx$,\n", + "print(\"\\nOuter domain:\")\n", + "print(invalid_outer.domain)\n", "\n", - "$$\n", - "\\boxed{\n", - "I=\\int_0^1\n", - "g(F_L^{-1}(u))\n", - "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))}\n", - "\\,du\n", - "}.\n", - "$$\n", + "print(\n", + " \"\\nQMCPy reports a compatibility error:\",\n", + " invalid_outer.sub_compatibility_error,\n", + ")\n", "\n", - "The runtime QMC path is therefore\n", + "try:\n", + " invalid_outer.gen_samples(8)\n", + "except ParameterError as error:\n", + " print(\n", + " \"\\nSampling is correctly rejected:\"\n", + " )\n", + " print(type(error).__name__, \"-\", error)" + ] + }, + { + "cell_type": "markdown", + "id": "be62911d", + "metadata": {}, + "source": [ + "### Why is this rejection correct?\n", "\n", - "$$\n", - "\\boxed{\n", - "U_{\\mathrm{Sobol}}\n", - "\\xrightarrow{F_L^{-1}}\n", - "X_L\n", - "\\xrightarrow{\\times\\,p_G(X_L)/p_L(X_L)}\n", - "\\text{weighted integrand}\n", - "}.\n", - "$$\n", + "This time the problem is not merely that the two intervals are different.\n", "\n", - "There is no Gaussian-to-Uniform transformation in this runtime path; Sobol points already supply Uniform inputs. Logistic matters because it changes the sampling measure and hence the function presented to those points.\n", + "The upstream transformation can actually produce values that the next\n", + "transformation does not accept.\n", "\n", - "Direct Gaussian QMC uses\n", + "Specifically,\n", "\n", "$$\n", - "h_G(v)=g(F_G^{-1}(v)),\n", - "\\qquad\n", - "I=\\int_0^1h_G(v)\\,dv,\n", + "-0.10\\notin[0,1].\n", "$$\n", "\n", - "whereas Logistic importance-sampling QMC uses\n", + "So the required containment condition fails:\n", "\n", "$$\n", - "h_L(u)=g(F_L^{-1}(u))\n", - "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))},\n", - "\\qquad\n", - "I=\\int_0^1h_L(u)\\,du.\n", + "R_{j-1}\\nsubseteq D_j.\n", "$$\n", "\n", - "Thus\n", + "The updated rule therefore distinguishes the two cases correctly:\n", "\n", - "$$\n", - "\\int_0^1h_G(v)\\,dv=\\int_0^1h_L(u)\\,du,\n", - "\\qquad\n", - "h_G\\neq h_L\\ \\text{in general}.\n", - "$$\n", + "| Situation | Relationship | Result |\n", + "|---|---|---|\n", + "| Exact match | $R=D$ | Accepted |\n", + "| Smaller valid range | $R\\subset D$ | Accepted |\n", + "| Range leaves domain | $R\\nsubseteq D$ | Rejected |\n", "\n", - "Both formulations estimate the same Gaussian integral but present different functions to the Sobol points. A proposal can therefore improve or worsen QMC behavior; Logistic is not universally better." + "This is the safety property we want." ] }, { "cell_type": "markdown", - "id": "6b1acc04", + "id": "05374cca", "metadata": {}, "source": [ - "### 5.4 Connection: the likelihood ratio is a transport Jacobian\n", + "## 10. General form of the rule\n", "\n", - "Define the Logistic- and Gaussian-based Uniform coordinates\n", + "For a $d$-dimensional axis-aligned range,\n", "\n", "$$\n", - "u=F_L(x),\n", - "\\qquad\n", - "v=F_G(x).\n", + "R=\n", + "\\prod_{k=1}^{d}\n", + "[r_{k,L},r_{k,U}],\n", "$$\n", "\n", - "Since $x=F_L^{-1}(u)$, the map between them is\n", + "and domain\n", "\n", "$$\n", - "T(u)=F_G(F_L^{-1}(u)).\n", + "D=\n", + "\\prod_{k=1}^{d}\n", + "[d_{k,L},d_{k,U}],\n", "$$\n", "\n", - "Differentiating gives\n", + "the transformation chain is compatible exactly when\n", "\n", "$$\n", - "\\frac{dT}{du}=p_G(x)\\frac{dx}{du}.\n", + "\\boxed{\n", + "d_{k,L}\\le r_{k,L}\n", + "\\quad\\text{and}\\quad\n", + "r_{k,U}\\le d_{k,U}\n", + "\\qquad\n", + "\\text{for every }k=1,\\ldots,d.\n", + "}\n", "$$\n", "\n", - "Because $du/dx=p_L(x)$,\n", + "This includes ordinary finite intervals as well as numerical envelopes using\n", "\n", "$$\n", - "\\frac{dx}{du}=\\frac{1}{p_L(x)},\n", + "-\\infty\n", + "\\qquad\\text{or}\\qquad\n", + "+\\infty.\n", "$$\n", "\n", - "and therefore\n", + "For example,\n", "\n", "$$\n", - "\\boxed{\n", - "T'(u)=\n", - "\\frac{p_G(F_L^{-1}(u))}{p_L(F_L^{-1}(u))}\n", - "}.\n", + "[-5,5]\\subseteq(-\\infty,\\infty).\n", "$$\n", "\n", - "The Gaussian/Logistic importance-sampling likelihood ratio is exactly the Jacobian of the map between their two Uniform parameterizations in one dimension. Deterministic transport and importance sampling are distinct constructions, but this Jacobian explains their mathematical connection.\n", + "QMCPy represents these using numeric bounds such as `-np.inf` and `np.inf`.\n", "\n", - "The numerical check below stays away from $0$ and $1$, compares a stable finite-difference derivative with the density ratio, and then uses one deterministic DigitalNet point set for a compact same-target integral check." + "This PR does not introduce representations for disconnected sets,\n", + "nonrectangular regions, or explicit open-versus-closed endpoints." ] }, { "cell_type": "code", - "execution_count": 35, - "id": "f6da6902", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:47.018298Z", - "iopub.status.busy": "2026-08-24T19:24:47.017888Z", - "iopub.status.idle": "2026-08-24T19:24:47.195600Z", - "shell.execute_reply": "2026-08-24T19:24:47.194506Z" - } - }, + "execution_count": 12, + "id": "ad8bd6c3", + "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Maximum interior absolute error: 8.440e-05\n", - "Mean interior absolute error: 1.535e-05\n", - "All verification values finite: True\n" - ] - }, { "data": { - "image/png": "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J8vr7w8NGzZM5rB9+EYny+jvY8eOYcGCBbh48WIS1ZKM2d8iIDtw4ADatWsnA7O7d++iT58+8kO32GCELKu/27ZtK+9XoUIFkVGAyMhI9OrVCz/99FMS1ZqSSnyxWkBAAEJCQuQcAkPiCDmRAf31119yot/GjRvlBCKyLIGBgfj222/lRF4PDw9jV4eSgEajkd+GzJ07F8WLF0erVq3w888/Y/bs2Wx/CyQm+YlvQGbOnInz589jw4YN2L59O0aPHm3sqpGF4Qi5nsQfXRsbG/j4+MQ6Lsqenp5x3kcc1+f2ZN79rTVhwgQZkO/btw+FChUycE3JGP197949PHz4UM7kjxmwCba2trh16xayZ8/OzrGg97dYWcXOzk7eTytv3rxydE2kRNjb2xu83pR0/f3LL7/ID93dunWTZbFKWlBQEHr06CE/iImUF7IMnvHEai4uLgYfHRf4StKT+GUrRkX2798f6w+wKIu8wriI4zFvL+zduzfe25N597fw999/yxGUXbt2oUSJEklUW0rq/hZLmV65ckWmq2gvjRo1QtWqVeV1sUQaWdb7u3z58jJNRfvBS7h9+7YM1BmMW15/izlAHwbd2g9j0XMFyVKUNXasliRTRy1w2SSxDNLixYvl0jg9evSQyya9ePFC/vzbb79Vfvzxx1jLHtra2ioTJkyQy+CNHDmSyx5acH//9ddfclmtdevWKc+fP9ddAgMDjfgsyFD9/SGusmLZ/e3t7S1XTerXr59y69YtZdu2bUqaNGmUP/74w4jPggzV3+LvtejvlStXymXx9uzZo2TPnl2unkamLTAwUC4/LC4i3J00aZK8/ujRI/lz0c+ivz9c9nDo0KEyVhPLF3PZQzMg1qfMlCmTDLzEMkr//fef7meVK1eWf5RjWrNmjZIrVy55e7Gszvbt241Qa0qK/s6cObN88394Eb/YyTLf3zExILf8/j5x4oRculYEdmIJxD///FMufUmW198RERHKb7/9JoNwR0dHxcvLS+nTp4/i7+9vpNpTQh08eDDOv8Xa/hX/i/7+8D5FihSRrw3x3l60aJGSVFTin6QZiyciIiIiog8xh5yIiIiIyIgYkBMRERERGREDciIiIiIiI2JATkRERERkRAzIiYiIiIiMiAE5EREREZERMSAnIiIiIjIiBuREREREREbEgJyIiIiIyIgYkBMRERER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", + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CasePrevious equality ruleContainment rule
0Exact equalityTrueTrue
1Strict subsetFalseTrue
2Finite interval inside real lineFalseTrue
3Lower-bound violationFalseFalse
4Two-dimensional subsetFalseTrue
\n", + "
" + ], "text/plain": [ - "
" + " Case Previous equality rule Containment rule\n", + "0 Exact equality True True\n", + "1 Strict subset False True\n", + "2 Finite interval inside real line False True\n", + "3 Lower-bound violation False False\n", + "4 Two-dimensional subset False True" ] }, + "execution_count": 12, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ - "u = np.linspace(0.01, 0.99, 500)\n", - "x_logistic = logistic.ppf(u)\n", - "transport = norm.cdf(x_logistic)\n", - "numerical_derivative = np.gradient(transport, u, edge_order=2)\n", - "density_ratio = norm.pdf(x_logistic) / logistic.pdf(x_logistic)\n", - "\n", - "interior = slice(2, -2)\n", - "absolute_error = np.abs(numerical_derivative - density_ratio)\n", + "examples = [\n", + " (\n", + " \"Exact equality\",\n", + " [[0.0, 1.0]],\n", + " [[0.0, 1.0]],\n", + " ),\n", + " (\n", + " \"Strict subset\",\n", + " [[0.25, 0.75]],\n", + " [[0.0, 1.0]],\n", + " ),\n", + " (\n", + " \"Finite interval inside real line\",\n", + " [[-5.0, 5.0]],\n", + " [[-np.inf, np.inf]],\n", + " ),\n", + " (\n", + " \"Lower-bound violation\",\n", + " [[-0.10, 0.75]],\n", + " [[0.0, 1.0]],\n", + " ),\n", + " (\n", + " \"Two-dimensional subset\",\n", + " [[0.10, 0.80], [0.20, 0.90]],\n", + " [[0.0, 1.0]],\n", + " ),\n", + "]\n", "\n", - "print(\n", - " \"Maximum interior absolute error:\",\n", - " f\"{absolute_error[interior].max():.3e}\",\n", - ")\n", - "print(\n", - " \"Mean interior absolute error:\",\n", - " f\"{absolute_error[interior].mean():.3e}\",\n", - ")\n", - "print(\n", - " \"All verification values finite:\",\n", - " np.isfinite(numerical_derivative).all()\n", - " and np.isfinite(density_ratio).all(),\n", + "summary = pd.DataFrame(\n", + " [\n", + " {\n", + " \"Case\": name,\n", + " \"Previous equality rule\": previous_equality_rule(\n", + " transform_range,\n", + " domain,\n", + " ),\n", + " \"Containment rule\": containment_rule(\n", + " transform_range,\n", + " domain,\n", + " ),\n", + " }\n", + " for name, transform_range, domain in examples\n", + " ]\n", ")\n", "\n", - "fig, ax = plt.subplots(figsize=(7.5, 4.8))\n", - "ax.plot(u, numerical_derivative, linewidth=2.5, label=r\"Numerical $T'(u)$\")\n", - "ax.plot(\n", - " u,\n", - " density_ratio,\n", - " linestyle=\"--\",\n", - " linewidth=2,\n", - " label=r\"$p_G(F_L^{-1}(u))/p_L(F_L^{-1}(u))$\",\n", - ")\n", - "ax.set(\n", - " xlabel=\"Logistic-based Uniform coordinate $u$\",\n", - " ylabel=\"Derivative / density ratio\",\n", - " title=\"Likelihood ratio as a transport Jacobian\",\n", - ")\n", - "ax.grid(alpha=0.25)\n", - "ax.legend()\n", - "plt.tight_layout()\n", - "plt.show()" + "summary" ] }, { - "cell_type": "code", - "execution_count": 36, - "id": "b6cd52e8", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-24T19:24:47.198770Z", - "iopub.status.busy": "2026-08-24T19:24:47.198263Z", - "iopub.status.idle": "2026-08-24T19:24:47.216129Z", - "shell.execute_reply": "2026-08-24T19:24:47.214482Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Target E[X^2]: 1.0\n", - "Direct Gaussian-QMC estimate: 0.999295953\n", - "Logistic IS-QMC estimate: 1.000000026\n", - "All integral-check values finite: True\n" - ] - } - ], + "cell_type": "markdown", + "id": "f591deeb", + "metadata": {}, "source": [ - "qmc_u = DigitalNetB2(1, seed=7).gen_samples(2**12).reshape(-1)\n", + "## 11. Reading the final comparison\n", "\n", - "gaussian_samples = norm.ppf(qmc_u)\n", - "direct_gaussian_qmc = np.mean(gaussian_samples**2)\n", + "The table summarizes exactly what changed.\n", "\n", - "logistic_samples = logistic.ppf(qmc_u)\n", - "logistic_weights = norm.pdf(logistic_samples) / logistic.pdf(logistic_samples)\n", - "logistic_is_qmc = np.mean(logistic_samples**2 * logistic_weights)\n", + "### Exact equality\n", "\n", - "print(\"Target E[X^2]:\", 1.0)\n", - "print(\"Direct Gaussian-QMC estimate:\", f\"{direct_gaussian_qmc:.9f}\")\n", - "print(\"Logistic IS-QMC estimate:\", f\"{logistic_is_qmc:.9f}\")\n", - "print(\n", - " \"All integral-check values finite:\",\n", - " np.isfinite(gaussian_samples).all()\n", - " and np.isfinite(logistic_samples).all()\n", - " and np.isfinite(logistic_weights).all(),\n", - ")" + "$$\n", + "[0,1]=[0,1].\n", + "$$\n", + "\n", + "Both rules accept it.\n", + "\n", + "### Strict containment\n", + "\n", + "$$\n", + "[0.25,0.75]\\subset[0,1].\n", + "$$\n", + "\n", + "The old equality rule rejects it, while the containment rule correctly accepts\n", + "it.\n", + "\n", + "### Unbounded containing domain\n", + "\n", + "$$\n", + "[-5,5]\\subset(-\\infty,\\infty).\n", + "$$\n", + "\n", + "Again, equality is unnecessary; containment is sufficient.\n", + "\n", + "### Genuine violation\n", + "\n", + "$$\n", + "[-0.10,0.75]\\nsubseteq[0,1].\n", + "$$\n", + "\n", + "Both the mathematics and QMCPy's updated behavior reject it.\n", + "\n", + "### Multiple dimensions\n", + "\n", + "Each coordinate is checked independently, so a rectangular range can be\n", + "contained in a larger rectangular domain even when their endpoint arrays are\n", + "not identical." ] }, { "cell_type": "markdown", - "id": "2938bb1c", + "id": "7f80cf0e", "metadata": {}, "source": [ - "## 6. Takeaways and next step\n", + "## 12. Takeaway\n", "\n", - "1. **Current PR:** chained `TrueMeasure` domain compatibility changes from exact equality to containment:\n", + "The change can be summarized in one line:\n", "\n", - " $$\n", - " R_{j-1}=D_j\n", - " \\quad\\longrightarrow\\quad\n", - " R_{j-1}\\subseteq D_j.\n", - " $$\n", + "$$\n", + "\\boxed{\n", + "R_{j-1}=D_j\n", + "\\quad\\longrightarrow\\quad\n", + "R_{j-1}\\subseteq D_j\n", + "}\n", + "$$\n", "\n", - "2. **Safety remains:** strict containment is accepted, while ranges that actually leave the next domain remain rejected.\n", + "but its practical meaning is important.\n", "\n", - "3. **QMC direction:** Sobol points already begin in Uniform space; direct Gaussian and Logistic sampling are $U\\rightarrow X_G$ and $U\\rightarrow X_L$.\n", + "A downstream transformation should not reject an upstream transformation\n", + "simply because the upstream stage uses only part of its valid input domain.\n", "\n", - "4. **Pure deterministic detour:** Gaussian $\\rightarrow$ Logistic $\\rightarrow$ Uniform collapses to Gaussian $\\rightarrow$ Uniform, so inserting Logistic only as a CDF/inverse-CDF transport adds nothing by itself.\n", + "In the battery example,\n", "\n", - "5. **Importance sampling is the meaningful alternative:** Logistic changes the sampling measure through $p_G/p_L$, and in one dimension that likelihood ratio is the Jacobian\n", + "$$\n", + "[0.25,0.75]\\subseteq[0,1],\n", + "$$\n", "\n", - " $$\n", - " \\frac{d}{du}F_G(F_L^{-1}(u)).\n", - " $$\n", + "so every upstream value is safe to pass to the next transformation.\n", + "\n", + "The previous equality-based rule would reject that composition.\n", + "\n", + "The updated containment rule:\n", + "\n", + "- accepts exact equality;\n", + "- accepts valid strict subsets;\n", + "- works coordinate-wise in multiple dimensions;\n", + "- supports finite and unbounded numeric envelopes;\n", + "- still rejects any range that actually leaves the next domain.\n", "\n", - "**Next question.** The current domain-inclusion PR should remain scoped as implemented. A separate follow-up can examine how QMCPy's existing importance-sampling machinery represents this Gaussian/Logistic relationship and whether any additional transport/Jacobian semantics are actually needed." + "The result is a more mathematically accurate compatibility check while keeping\n", + "the safety condition intact." ] } ], "metadata": { "kernelspec": { - "display_name": "qmcpy kernel", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "qmcpy" + "name": "python3" }, "language_info": { "codemirror_mode": { diff --git a/docs/api/discrete_distributions.md b/docs/api/discrete_distributions.md index 49b60fbb4..daa782cb6 100644 --- a/docs/api/discrete_distributions.md +++ b/docs/api/discrete_distributions.md @@ -70,7 +70,10 @@ python -m pip install "qmcpy[mpmc]" qmcpy-install-mpmc ``` -The second command selects the `pyg_lib` wheel page matching the installed PyTorch and accelerator builds. For GPU support or platform-specific wheels, see the [PyTorch installation guide](https://pytorch.org/get-started/locally/) and the [PyTorch Geometric installation guide](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html). +The second command selects the `pyg_lib` wheel page matching the installed +PyTorch and accelerator builds. For GPU support or platform-specific wheels, +see the [PyTorch installation guide](https://pytorch.org/get-started/locally/) +and the [PyTorch Geometric installation guide](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html). ::: qmcpy.discrete_distribution.mpmc.mpmc.MPMC diff --git a/qmcpy/discrete_distribution/dummy_sampler.py b/qmcpy/discrete_distribution/dummy_sampler.py index cf33720e5..cc8363cc9 100644 --- a/qmcpy/discrete_distribution/dummy_sampler.py +++ b/qmcpy/discrete_distribution/dummy_sampler.py @@ -30,6 +30,16 @@ class DummySampler(AbstractLDDiscreteDistribution): """ def __init__(self, dimension=1, replications=None, seed=None, warn=True): + r""" + Args: + dimension (Union[int, list, tuple, np.ndarray]): Dimension of the placeholder sampler. A list, tuple, or array specifies unique coordinate indices. Defaults to `1`. + replications (Union[None, int]): Replication metadata preserved when spawning placeholders. `None` records no explicit replication axis. Defaults to `None`. + seed (Union[None, int, np.random.SeedSequence]): Seed used to initialize the sampler state and spawn child samplers. Defaults to `None`. + warn (bool): Compatibility argument matching other discrete-distribution constructors. It is ignored because `DummySampler` cannot generate samples. Defaults to `True`. + + Raises: + ParameterError: If an array-like `dimension` is not one-dimensional with unique entries, if it exceeds the dimension limit, or if `replications` is negative. + """ # Keep the same constructor as other discrete distributions. del warn diff --git a/qmcpy/true_measure/abstract_true_measure.py b/qmcpy/true_measure/abstract_true_measure.py index ba3a3633f..abb0be649 100644 --- a/qmcpy/true_measure/abstract_true_measure.py +++ b/qmcpy/true_measure/abstract_true_measure.py @@ -19,12 +19,12 @@ def __init__(self): if not hasattr(self, "domain"): raise ParameterError( prefix - + "self.domain, 2xd ndarray of domain lower bounds (first col) and upper bounds (second col)" + + "self.domain, (d, 2) ndarray of domain lower bounds (first col) and upper bounds (second col)" ) if not hasattr(self, "range"): raise ParameterError( prefix - + "self.range, 2xd ndarray of range lower bounds (first col) and upper bounds (second col)" + + "self.range, (d, 2) ndarray of range lower bounds (first col) and upper bounds (second col)" ) if not hasattr(self, "parameters"): self.parameters = [] @@ -156,7 +156,7 @@ def _parse_sampler(self, sampler): self.sub_compatibility_error = True if self.transform.sub_compatibility_error: raise ParameterError( - "The sub-sub-transform range must be contained within the sub-transform domain." + "The nested sub-transform range must be contained within its transform domain." ) else: raise ParameterError( diff --git a/qmcpy/true_measure/brownian_motion.py b/qmcpy/true_measure/brownian_motion.py index 564223a00..88c85fe1b 100644 --- a/qmcpy/true_measure/brownian_motion.py +++ b/qmcpy/true_measure/brownian_motion.py @@ -1,4 +1,5 @@ from .gaussian import Gaussian +from .abstract_true_measure import _clip_unit_interval from ..discrete_distribution import DigitalNetB2 from ..util import ParameterError, ParameterWarning import warnings @@ -252,7 +253,7 @@ def _spawn(self, sampler, dimension): def _transform(self, x): if self.decomp_type == "BROWNIANBRIDGE": - z = norm.ppf(x) + z = norm.ppf(_clip_unit_interval(x)) w = self._bridge_transform(z) paths = self.drift_time_vec_plus_init + np.sqrt(self.diffusion) * w return paths[..., self._output_order] diff --git a/qmcpy/true_measure/johnsons_su.py b/qmcpy/true_measure/johnsons_su.py index 1d0cc54e2..d04dfbe2e 100644 --- a/qmcpy/true_measure/johnsons_su.py +++ b/qmcpy/true_measure/johnsons_su.py @@ -1,4 +1,4 @@ -from .abstract_true_measure import AbstractTrueMeasure +from .abstract_true_measure import AbstractTrueMeasure, _clip_unit_interval from ..util import DimensionError, ParameterError from ..discrete_distribution import DigitalNetB2 import numpy as np @@ -92,6 +92,7 @@ def __init__(self, sampler, gamma=1, xi=1, delta=2, lam=2): ) def _transform(self, x): + x = _clip_unit_interval(x) return self._lam * np.sinh((norm.ppf(x) - self._gamma) / self._delta) + self._xi def _weight(self, x): diff --git a/qmcpy/true_measure/product_measure.py b/qmcpy/true_measure/product_measure.py index 3f860e84b..258bff693 100644 --- a/qmcpy/true_measure/product_measure.py +++ b/qmcpy/true_measure/product_measure.py @@ -105,25 +105,22 @@ def __init__(self, sampler, marginals): """ Initialize a product measure from one sampler and several marginals. - Parameters - ---------- - sampler : AbstractDiscreteDistribution - The sampler for the whole product measure. Its dimension must - equal the sum of the marginal dimensions. + Args: + sampler (AbstractDiscreteDistribution): Sampler for the whole product measure. Its dimension must equal the sum of the marginal dimensions. + marginals (Union[list, tuple]): Nonempty sequence of independent `AbstractTrueMeasure` instances to place side by side. A marginal may itself be multidimensional. - marginals : list or tuple of AbstractTrueMeasure - Independent true measures to place side by side. A marginal may - itself be multidimensional. + Raises: + ParameterError: If `sampler` is not an `AbstractDiscreteDistribution`, or if `marginals` is empty or contains a non-`AbstractTrueMeasure` value. + DimensionError: If a marginal is not dimension-preserving or the sampler dimension differs from the sum of the marginal dimensions. - Why one sampler? - ---------------- - The product measure should be driven by one total-dimensional QMC - point set. We do not generate separate QMC samples from each marginal. - Instead, one sample u in [0,1]^d is split into blocks: + Note: + The product measure is driven by one total-dimensional QMC point + set. It does not generate separate QMC samples from each marginal. + Instead, one sample u in [0,1]^d is split into blocks: - u = (u_marginal_1, u_marginal_2, ..., u_marginal_k). + u = (u_marginal_1, u_marginal_2, ..., u_marginal_k). - This preserves the intended total-dimensional QMC construction. + This preserves the intended total-dimensional QMC construction. """ if not isinstance(marginals, (list, tuple)) or len(marginals) == 0: raise ParameterError("ProductMeasure requires a nonempty list of marginals.") diff --git a/qmcpy/true_measure/scipy_wrapper.py b/qmcpy/true_measure/scipy_wrapper.py index 9f528b175..6fbb24c6c 100644 --- a/qmcpy/true_measure/scipy_wrapper.py +++ b/qmcpy/true_measure/scipy_wrapper.py @@ -1,4 +1,4 @@ -from .abstract_true_measure import AbstractTrueMeasure +from .abstract_true_measure import AbstractTrueMeasure, _clip_unit_interval from ..util import DimensionError, ParameterError from ..discrete_distribution.abstract_discrete_distribution import ( AbstractDiscreteDistribution, @@ -107,8 +107,7 @@ def transform(self, u): ) # Clip so we never hit exactly 0 or 1 inside norm.ppf. - eps = np.finfo(float).eps - u_clip = np.clip(u, eps, 1.0 - eps) + u_clip = _clip_unit_interval(u) # Map to i.i.d. standard normals. z = scipy.stats.norm.ppf(u_clip) @@ -455,6 +454,7 @@ def _transform(self, x): if self._is_joint: return self._joint.transform(x) + x = _clip_unit_interval(x) t = np.empty_like(x, dtype=float) for j in range(self.d): t[..., j] = self.sds[j].ppf(x[..., j]) diff --git a/qmcpy/true_measure/student_t.py b/qmcpy/true_measure/student_t.py index 510b11388..e0e44ae51 100644 --- a/qmcpy/true_measure/student_t.py +++ b/qmcpy/true_measure/student_t.py @@ -2,6 +2,7 @@ import scipy.stats as stats from ..util import ParameterError, DimensionError +from .abstract_true_measure import _clip_unit_interval from .scipy_wrapper import SciPyWrapper @@ -39,8 +40,7 @@ def __init__(self, loc, shape, df): @staticmethod def _clip_u(u): - eps = np.finfo(float).eps - return np.clip(u, eps, 1.0 - eps) + return _clip_unit_interval(u) def transform(self, u): u = np.asarray(u, dtype=float) diff --git a/qmcpy/true_measure/zero_inflated_exp_uniform.py b/qmcpy/true_measure/zero_inflated_exp_uniform.py index 11526556f..2fbb6bfd6 100644 --- a/qmcpy/true_measure/zero_inflated_exp_uniform.py +++ b/qmcpy/true_measure/zero_inflated_exp_uniform.py @@ -187,6 +187,17 @@ class ZeroInflatedExpUniform(SciPyWrapper): """ def __init__(self, sampler, p_zero=0.4, lam=1.5, y_split=None): + r""" + Args: + sampler (Union[AbstractDiscreteDistribution, AbstractTrueMeasure]): One-dimensional sampler for the current construction. The deprecated `y_split` construction also accepts a two-dimensional sampler. + p_zero (float): Probability mass at zero, strictly between `0` and `1`. Defaults to `0.4`. + lam (float): Rate of the exponential component. Must be positive. Defaults to `1.5`. + y_split (Union[None, float]): Deprecated split point for the legacy two-dimensional construction. With a two-dimensional sampler, it must lie strictly between `0` and `1`. With a one-dimensional sampler, it is accepted for backward compatibility, emits a `DeprecationWarning`, and is otherwise ignored. Defaults to `None`. + + Raises: + DimensionError: If the sampler dimension is incompatible with the selected construction. + ParameterError: If `p_zero`, `lam`, or a two-dimensional `y_split` is outside its valid range. + """ if y_split is not None: warnings.warn( "`y_split` is deprecated. The 2D zero-inflated " diff --git a/scripts/colab_notebooks_manifest.json b/scripts/colab_notebooks_manifest.json index ed62ba8be..82b4a4be4 100644 --- a/scripts/colab_notebooks_manifest.json +++ b/scripts/colab_notebooks_manifest.json @@ -44,6 +44,7 @@ "demos/talk_paper_demos/Sorokin_random_LD_seq_QMC_fast_kernel_methods_2026/Sorokin_random_LD_seq_QMC_fast_kernel_methods_2026.ipynb", "demos/talk_paper_demos/pydata_chi_2023.ipynb", "demos/talk_paper_demos/why_add_q_to_mc_blog/why_add_q_to_mc_blog.ipynb", + "demos/true_measure_domain_inclusion.ipynb", "demos/vectorized_qmc.ipynb", "demos/vectorized_qmc_bayes.ipynb" ], diff --git a/test/test_true_measures.py b/test/test_true_measures.py index bcecba227..9dd78a5b3 100644 --- a/test/test_true_measures.py +++ b/test/test_true_measures.py @@ -12,11 +12,13 @@ Lebesgue, MaternGP, SciPyWrapper, + StudentT, Uniform, ZeroInflatedExpUniform, ) -from qmcpy.util import DimensionError, ParameterError +from qmcpy.util import DimensionError, ParameterError, ParameterWarning import numpy as np +import re import scipy.stats from scipy.sparse import issparse import unittest @@ -47,6 +49,12 @@ def test_range_in_domain(self): cases = [ ("exact equality", [[0, 1]], [[0, 1]], True), ("strict finite inclusion", [[0.25, 0.75]], [[0, 1]], True), + ( + "compatible unbounded interval", + [[-np.inf, np.inf]], + [[-np.inf, np.inf]], + True, + ), ("infinite domain", [[-5, 5]], [[-np.inf, np.inf]], True), ("positive half-line", [[1, 3]], [[0, np.inf]], True), ("lower-bound failure", [[-0.1, 0.75]], [[0, 1]], False), @@ -69,6 +77,12 @@ def test_range_in_domain(self): [[0, 1]], True, ), + ( + "broadcast transform range", + [[0.25, 0.75]], + [[0, 1], [-1, 2]], + True, + ), ( "non-broadcastable rows", [[0.1, 0.8], [0.2, 0.9]], @@ -157,6 +171,8 @@ def test_multidimensional_range_in_domain_chain_broadcasts(self): self.assertTrue(np.isfinite(samples).all()) def test_recursive_transform_applies_each_layer(self): + # This records current recursive execution only; it does not assert + # correctness of nominal range or moment metadata. points = np.array([[0.1], [0.25], [0.5], [0.75], [0.9]]) uniform_inner = Uniform( @@ -182,7 +198,7 @@ def test_recursive_transform_applies_each_layer(self): cases = [ ("1(a) Uniform -> Uniform", uniform_inner, uniform_outer), ( - "1(b)/1(c) Uniform -> Kumaraswamy", + "1(b) Uniform -> Kumaraswamy", kumaraswamy_inner, kumaraswamy_outer, ), @@ -209,6 +225,104 @@ def test_recursive_transform_applies_each_layer(self): if name.startswith("1(d)"): np.testing.assert_array_equal(inner.range, outer.domain) + def test_unrandomized_inverse_cdf_paths_are_finite(self): + cases = [ + ( + "JohnsonsSU", + JohnsonsSU(DigitalNetB2(1, randomize="FALSE")), + ), + ( + "BrownianMotion BrownianBridge", + BrownianMotion( + DigitalNetB2(2, randomize="FALSE"), + decomp_type="BROWNIANBRIDGE", + ), + ), + ( + "SciPyWrapper marginal", + SciPyWrapper( + DigitalNetB2(1, randomize="FALSE"), + scipy.stats.norm(), + ), + ), + ( + "SciPyWrapper MVN", + SciPyWrapper( + DigitalNetB2(2, randomize="FALSE"), + scipy.stats.multivariate_normal( + mean=[0.0, 0.0], + cov=[[1.0, 0.5], [0.5, 1.0]], + ), + ), + ), + ( + "StudentT", + StudentT( + DigitalNetB2(2, randomize="FALSE"), + loc=[0.0, 0.0], + shape=[[1.0, 0.25], [0.25, 1.0]], + df=5, + ), + ), + ] + + with warnings.catch_warnings(): + warnings.simplefilter("ignore", ParameterWarning) + for name, measure in cases: + with self.subTest(name=name): + samples = measure.gen_samples(2) + self.assertTrue(np.isfinite(samples).all()) + + def test_inverse_cdf_clipping_preserves_interior_values(self): + endpoints_1d = np.array([[0.0], [1.0]]) + points_1d = np.array([[0.1], [0.25], [0.5], [0.75], [0.9]]) + + johnsons_su = JohnsonsSU(DigitalNetB2(1, seed=7)) + self.assertTrue(np.isfinite(johnsons_su._transform(endpoints_1d)).all()) + johnsons_expected = johnsons_su._lam * np.sinh( + (scipy.stats.norm.ppf(points_1d) - johnsons_su._gamma) + / johnsons_su._delta + ) + johnsons_su._xi + np.testing.assert_allclose( + johnsons_su._transform(points_1d), + johnsons_expected, + rtol=0, + atol=0, + ) + + scipy_wrapper = SciPyWrapper(DigitalNetB2(1, seed=7), scipy.stats.norm()) + self.assertTrue(np.isfinite(scipy_wrapper._transform(endpoints_1d)).all()) + np.testing.assert_allclose( + scipy_wrapper._transform(points_1d), + scipy.stats.norm.ppf(points_1d), + rtol=0, + atol=0, + ) + + points_2d = np.array( + [[0.1, 0.25], [0.25, 0.5], [0.5, 0.75], [0.75, 0.9]] + ) + brownian_bridge = BrownianMotion( + DigitalNetB2(2, seed=7), + decomp_type="BROWNIANBRIDGE", + ) + endpoints_2d = np.array([[0.0, 0.0], [1.0, 1.0]]) + self.assertTrue( + np.isfinite(brownian_bridge._transform(endpoints_2d)).all() + ) + bridge_normals = scipy.stats.norm.ppf(points_2d) + bridge_expected = ( + brownian_bridge.drift_time_vec_plus_init + + np.sqrt(brownian_bridge.diffusion) + * brownian_bridge._bridge_transform(bridge_normals) + )[..., brownian_bridge._output_order] + np.testing.assert_allclose( + brownian_bridge._transform(points_2d), + bridge_expected, + rtol=0, + atol=0, + ) + def test_out_of_domain_chain_preserves_deferred_errors(self): inner = Uniform( DigitalNetB2(1, seed=7), lower_bound=-0.1, upper_bound=0.75 @@ -218,13 +332,17 @@ def test_out_of_domain_chain_preserves_deferred_errors(self): self.assertTrue(incompatible.sub_compatibility_error) with self.assertRaisesRegex( ParameterError, - "The sub-transform range must be contained within the transform domain.", + re.escape( + "The sub-transform range must be contained within the transform domain." + ), ): incompatible.gen_samples(8) with self.assertRaisesRegex( ParameterError, - "The sub-sub-transform range must be contained within the sub-transform domain.", + re.escape( + "The nested sub-transform range must be contained within its transform domain." + ), ): Kumaraswamy(incompatible) @@ -898,6 +1016,26 @@ def test_weight_is_zero_outside_support(self): np.testing.assert_allclose(weights[1:4], expected_in_support) self.assertTrue(np.all(weights >= 0)) + def test_weight_support_mask_handles_dimensions_and_batches(self): + bernoulli = BernoulliCont( + DigitalNetB2(2, seed=7), + lam=[0.9, 0.8], + ) + points = np.array( + [ + [[0.0, 0.0], [0.5, 0.5], [1.0, 1.0]], + [[-0.1, 0.5], [0.5, 1.1], [0.25, 0.75]], + ] + ) + + weights = bernoulli._weight(points) + + self.assertEqual(weights.shape, (2, 3)) + self.assertTrue(np.all(weights[0] > 0)) + np.testing.assert_allclose(weights[1, :2], 0.0) + self.assertGreater(weights[1, 2], 0.0) + self.assertTrue(np.all(weights >= 0)) + class TestUniformTriangle(unittest.TestCase): """Tests for UniformTriangle and _UniformTriangleAdapter.""" @@ -980,7 +1118,7 @@ def test_transform_clips_unit_interval_endpoints(self): def test_unrandomized_direct_and_composed_samples_are_finite(self): with warnings.catch_warnings(): - warnings.simplefilter("ignore") + warnings.simplefilter("ignore", ParameterWarning) direct = Gaussian( DigitalNetB2(1, randomize="FALSE") ).gen_samples(2) @@ -1447,7 +1585,6 @@ def test_brownian_bridge_output_order(self): def test_brownian_bridge_warning_for_non_power_of_2(self): """BrownianBridge issues ParameterWarning for suboptimal d but still produces valid output.""" - from qmcpy.util import ParameterWarning with self.assertWarns(ParameterWarning): bm = BrownianMotion(DigitalNetB2(6, seed=self.seed), decomp_type='BrownianBridge') samples = bm.gen_samples(4)