From 00d281d916021f9efa1c922e0dec338ae474817b Mon Sep 17 00:00:00 2001 From: Doresic <85789271+Doresic@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:06:46 +0100 Subject: [PATCH] Hierarchical optimization: Support for box constraints on offset and scaling parameters (#1238) * Initial working Implemented scaling and offset bounds for the analytical and numerical solver of the hierarchical problem. * Fix hierarchical test * Add test_constrained_inner_solver * Add tests for non coupled parameters * intentional failure * intentional failure * intentional failure * Test fix It seems L-BFGS-B would not converge to optimum in some cases if it was provided with the big bounds [-1e20, 1e20]. It seems like it is a scipy issue? Not sure. In any case, the numerical optimizer is better if the optimization is not provided with these dummy bounds. But in this case, we need to sample the bounds outside of the pypesto minimize function and provide it as x_guesses. * Add notebook changes * Update C.py * Revert "Update C.py" This reverts commit f099a2b1e053502da3267e4cf8f152e5ac334a0f. * Fix sampling + test * Cleanup * Some updates * Some more small updates * Add inner bounds to parameter plot * Fix import issues * Fix hier test * Fix parameter plot test * Remove figures * DIlan&Daniel review changes * Update parameters.py * Update solver.py --- doc/example/hierarchical.ipynb | 224 ++++++++++++++----------- pypesto/hierarchical/parameter.py | 34 +++- pypesto/hierarchical/petab.py | 5 + pypesto/hierarchical/problem.py | 27 ++- pypesto/hierarchical/solver.py | 110 +++++++++--- pypesto/hierarchical/util.py | 154 ++++++++++++++++- pypesto/visualize/parameters.py | 42 ++++- test/hierarchical/test_hierarchical.py | 204 +++++++++++++++++++++- 8 files changed, 649 insertions(+), 151 deletions(-) diff --git a/doc/example/hierarchical.ipynb b/doc/example/hierarchical.ipynb index 7664a3e29..684433e9b 100644 --- a/doc/example/hierarchical.ipynb +++ b/doc/example/hierarchical.ipynb @@ -18,9 +18,11 @@ "\n", "However, the current implementation only supports:\n", "- Gaussian (normal) noise distributions\n", - "- unbounded inner parameters $\\eta$\n", + "- unbounded inner noise parameters $\\sigma$\n", "- linearly-scaled inner parameters $\\eta$\n", "\n", + "Scaling $s$ and offset $b$ parameters can be bounded arbitrarily.\n", + "\n", "In the following we will demonstrate how to use hierarchical optimization, and we will compare optimization results for the following scenarios:\n", "\n", "* Standard non-hierarchical gradient-based optimization with adjoint sensitivity analysis\n", @@ -31,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -62,12 +64,12 @@ "\n", "We consider a version of the [Boehm et al.; Journal of Proeome Research 2014] model, modified to include scalings $s$, offsets $b$, and noise parameters $\\sigma^2$.\n", "\n", - "NB: We load two PEtab problems here, because the employed standard and hierarchical optimization methods have different expectations for parameter bounds. The difference between the two PEtab problems is that the `corrected_bounds` version estimates inner parameters ($\\eta$) in $[-\\infty, \\infty]$ for offset and scaling parameters, and in $[0, \\infty]$ for sigma parameters." + "NB: We load two PEtab problems here, because the employed standard and hierarchical optimization methods have different expectations for parameter bounds. The difference between the two PEtab problems is that the `corrected_bounds` version estimates inner noise parameters ($\\sigma$) in $[0, \\infty]$." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -88,12 +90,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The PEtab observable table contains placeholders for scaling parameters $s$ (`observableParameter1_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`), offsets $b$ (`observableParameter2_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`), and noise parameters $\\sigma^2$ (`noiseParameter1_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`) that are overridden by the `{observable,noise}Parameters` column in the measurement table. When using hierarchical optimization, the nine overriding parameters `{offset,scaling,sd}_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}` are to estimated in the inner problem." + "The PEtab observable table contains placeholders for scaling parameters $s$ (`observableParameter1_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`), offsets $b$ (`observableParameter2_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`), and noise parameters $\\sigma^2$ (`noiseParameter1_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}`) that are overridden by the `{observable,noise}Parameters` column in the measurement table. When using hierarchical optimization, the nine overriding parameters `{offset,scaling,sd}_{pSTAT5A_rel,pSTAT5B_rel,rSTAT5A_rel}` are to be estimated in the inner problem." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -207,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -365,8 +367,8 @@ " offset_pSTAT5A_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " -100.00000\n", + " 100.0\n", " 0.000000\n", " 1\n", " offset\n", @@ -375,8 +377,8 @@ " offset_pSTAT5B_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " -100.00000\n", + " 100.0\n", " 0.000000\n", " 1\n", " offset\n", @@ -385,8 +387,8 @@ " offset_rSTAT5A_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " -100.00000\n", + " 100.0\n", " 0.000000\n", " 1\n", " offset\n", @@ -395,8 +397,8 @@ " scaling_pSTAT5A_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " 0.00001\n", + " 100000.0\n", " 3.852612\n", " 1\n", " scaling\n", @@ -405,8 +407,8 @@ " scaling_pSTAT5B_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " 0.00001\n", + " 100000.0\n", " 6.591478\n", " 1\n", " scaling\n", @@ -415,8 +417,8 @@ " scaling_rSTAT5A_rel\n", " NaN\n", " lin\n", - " -inf\n", - " inf\n", + " 0.00001\n", + " 100000.0\n", " 3.152713\n", " 1\n", " scaling\n", @@ -439,12 +441,12 @@ "sd_pSTAT5B_rel \\sigma_{pSTAT5B,rel} lin 0.00000 \n", "sd_rSTAT5A_rel \\sigma_{rSTAT5A,rel} lin 0.00000 \n", "specC17 specC17 lin -5.00000 \n", - "offset_pSTAT5A_rel NaN lin -inf \n", - "offset_pSTAT5B_rel NaN lin -inf \n", - "offset_rSTAT5A_rel NaN lin -inf \n", - "scaling_pSTAT5A_rel NaN lin -inf \n", - "scaling_pSTAT5B_rel NaN lin -inf \n", - "scaling_rSTAT5A_rel NaN lin -inf \n", + "offset_pSTAT5A_rel NaN lin -100.00000 \n", + "offset_pSTAT5B_rel NaN lin -100.00000 \n", + "offset_rSTAT5A_rel NaN lin -100.00000 \n", + "scaling_pSTAT5A_rel NaN lin 0.00001 \n", + "scaling_pSTAT5B_rel NaN lin 0.00001 \n", + "scaling_rSTAT5A_rel NaN lin 0.00001 \n", "\n", " upperBound nominalValue estimate parameterType \n", "parameterId \n", @@ -459,15 +461,15 @@ "sd_pSTAT5B_rel inf 6.591478 1 sigma \n", "sd_rSTAT5A_rel inf 3.152713 1 sigma \n", "specC17 5.0 0.107000 0 None \n", - "offset_pSTAT5A_rel inf 0.000000 1 offset \n", - "offset_pSTAT5B_rel inf 0.000000 1 offset \n", - "offset_rSTAT5A_rel inf 0.000000 1 offset \n", - "scaling_pSTAT5A_rel inf 3.852612 1 scaling \n", - "scaling_pSTAT5B_rel inf 6.591478 1 scaling \n", - "scaling_rSTAT5A_rel inf 3.152713 1 scaling " + "offset_pSTAT5A_rel 100.0 0.000000 1 offset \n", + "offset_pSTAT5B_rel 100.0 0.000000 1 offset \n", + "offset_rSTAT5A_rel 100.0 0.000000 1 offset \n", + "scaling_pSTAT5A_rel 100000.0 3.852612 1 scaling \n", + "scaling_pSTAT5B_rel 100000.0 6.591478 1 scaling \n", + "scaling_rSTAT5A_rel 100000.0 3.152713 1 scaling " ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -478,13 +480,14 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Create a pypesto problem with hierarchical optimization (`problem`)\n", "importer = PetabImporter(petab_problem_hierarchical, hierarchical=True)\n", - "objective = importer.create_objective()\n", + "model = importer.create_model(verbose=False)\n", + "objective = importer.create_objective(model=model)\n", "problem = importer.create_problem(objective)\n", "# set option to compute objective function gradients using adjoint sensitivity analysis\n", "problem.objective.amici_solver.setSensitivityMethod(\n", @@ -493,7 +496,8 @@ "\n", "# ... and create another pypesto problem without hierarchical optimization (`problem2`)\n", "importer2 = PetabImporter(petab_problem, hierarchical=False)\n", - "objective2 = importer2.create_objective()\n", + "model2 = importer2.create_model(verbose=False)\n", + "objective2 = importer2.create_objective(model=model2)\n", "problem2 = importer2.create_problem(objective2)\n", "problem2.objective.amici_solver.setSensitivityMethod(\n", " amici.SensitivityMethod.adjoint\n", @@ -533,7 +537,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": { "scrolled": true }, @@ -542,27 +546,41 @@ "name": "stderr", "output_type": "stream", "text": [ - "Performing parallel task execution on 3 processes.\n", - "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 1645.47it/s]\n", - "2022-11-14 23:22:49 fides(WARNING) Stopping as trust region radius 9.72E-17 is smaller than machine precision.\n", - "2022-11-14 23:22:49 fides(WARNING) Stopping as trust region radius 7.82E-17 is smaller than machine precision.\n", - "2022-11-14 23:22:50 fides(WARNING) Stopping as trust region radius 1.57E-16 is smaller than machine precision.\n" + " 0%| | 0/3 [00:00" ] @@ -628,18 +659,17 @@ " size=(15, 6),\n", " order_by_id=True,\n", " colors=np.array(list(map(to_rgba, ('green', 'purple')))),\n", - ")\n", - "plt.savefig(\"num_ana.png\")" + ")" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { - "image/png": "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zZo107333qtDhw555kUrxdVDvMeOHdMDDzygJk2aKDg4WEOHDtWRI0ec+y8Pa//pT39Sq1at1KlTJ0nSm2++qd69eysgIEBhYWH65S9/qW+//dZ53OXXYe3aterVq5fsdru2bNkih8OhGTNmqEOHDrLb7Wrbtq3+9Kc/udT41Vdf6Y477pC/v7+io6OVlZXl3Ffaban/+7//U58+feTr66vmzZvrvvvuc+67Xp2oXQYOHKiwsDDnh5de7eqRCUmaPXu22rdv71y//Dv73HPPKTQ0VE2aNNHUqVN18eJFPfnkkwoODlabNm20aNEil34qey5cPYpy9uxZPfroowoNDZWvr6+6du2q1atXS5JOnTqlhIQEtW7dWv7+/oqKitLSpUsr/4Jdx9W3pRwOh1JTUxURESE/Pz9FR0frH//4h3N/WedtRa6f7du317Rp0zRy5EgFBgY6R7PKu/5drmnKlCkKDg5WWFiY/vjHP7r0e/U16/jx40pISFBwcLAaNWqk3r17a/v27ZLcv86biHBTx/z973/XTTfdpE6dOumhhx7SwoULr/n696efflozZ87Uzp07Vb9+fT3yyCPOfUVFRbrnnnuUmZmp3bt36+6779aQIUOUk5NT6uONHTtW6enpys3NdW5bvXq1vv/+e40YMUJz5sxRTEyMxo0bp9zcXOXm5pb6jevZ2dn62c9+psjISGVlZWnLli0aMmSILl26JEkqLi5WYmKidu7cqczMTPn4+Oi+++6Tw+HwxMtWrgsXLiguLk4BAQH68MMPtXXrVjVu3Fh33323y/+6MjMzdeDAAWVkZDgv0hcuXNC0adO0Z88erVy5UkeOHNHo0aOveYynnnpK06dP1/79+9WtWzclJSVp+vTpeuaZZ/Svf/1LS5Ysuebb7p9++mlNnjxZ2dnZ6tixoxISEsr83+OaNWt033336Z577tHu3buVmZmpvn37ujzHitSJ2qFevXp67rnn9PLLL+v48eOV7mfDhg365ptvtHnzZs2aNUvJycm699571bRpU23fvl2PPfaYHn30UedjVOVcuJLD4dCgQYO0detWvfXWW/rXv/6l6dOnq169epKkc+fOqVevXlqzZo327dunX/3qV/rv//5v7dixo9LP1R2pqalavHix5s2bp88++0yTJk3SQw89pE2bNrm0u/q8rej188UXX1R0dLR2796tZ5555rrXP0l644031KhRI23fvl0zZszQ1KlTlZGRUWr9RUVFGjBggL7++mu9++672rNnj6ZMmeK8Xrp7nTeShTqlX79+1uzZsy3LsqwLFy5YzZs3tz744APLsizrgw8+sCRZ77//vrP9mjVrLEnWDz/8UGafXbp0sV5++WXnert27ayXXnrJuR4ZGWk9//zzzvUhQ4ZYo0ePdq4PGDDAevzxx136vFzLmTNnLMuyrISEBOvWW2+t8PM8ceKEJcnau3evZVmWdfjwYUuStXv37jKPufyYjRo1umax2Wwuz0mStWLFCsuyLOvNN9+0OnXqZDkcDuf+kpISy8/Pz1q3bp1lWZY1atQoKzQ01CopKSm37o8//tiSZH333XcuNa1cudLZprCw0LLb7dbrr79eah+Xn+v8+fOd2z777DNLkrV//37Lsixr0aJFVlBQkHN/TEyM9eCDD5ZbW0XqvPzzgveMGjXKGjp0qGVZlnXLLbdYjzzyiGVZlrVixQrr8iU7OTnZio6OdjnupZdestq1a+fST7t27axLly45t3Xq1Mm6/fbbnesXL160GjVqZC1dutSyrKqdC1deN9atW2f5+PhYBw4cqPDzHjx4sPXEE08410u7rlytXbt2VsOGDa853xs0aODy+lz5mp47d87y9/e3tm3b5tLXmDFjrISEBMuySj9vy1La9TM+Pt6lzfWufwMGDLBuu+02l219+vSxfv/73zvXr7xm/fWvf7UCAgKsU6dOXbe+8uq88ppoGkZu6pADBw5ox44dSkhIkCTVr19fI0aM0IIFC1zadevWzfnvli1bSpLzFkRRUZEmT56szp07q0mTJmrcuLH2799fbqIfO3asc+g6Pz9fa9eudRkNqojL/3Mpy5dffqmEhATdcMMNCgwMdA6vl1VXly5d1LhxYzVu3PiaSXYffvihsrOzXZZWrVqV+dh79uzRwYMHFRAQ4OwzODhY586dc7k1FhUVpYYNG7ocu2vXLg0ZMkRt27ZVQECABgwYUGrdvXv3dv57//79KikpKff1kMr/OV7teq9vRetE7fL888/rjTfe0P79+yt1fJcuXVy+viY0NFRRUVHO9Xr16qlZs2bO36uqnAtXys7OVps2bdSxY8dS91+6dEnTpk1TVFSUgoOD1bhxY61bt67M38fnnnvOWU/jxo1d2j355JPXnO+PPfZYmbUdPHhQ33//ve68806XPhcvXnzNrfArz1up4tfPq4+73vkpuZ7v0o/nfHnne48ePRQcHFzq/spc503j9e+WQsUtWLBAFy9edPlDbVmW7Ha7XnnlFee2Bg0aOP99eULv5eHKyZMnKyMjQy+++KI6dOggPz8//eIXvyh30tvIkSP11FNPKSsrS9u2bVNERIRuv/12t2r38/Mrd/+QIUPUrl07vf7662rVqpUcDoe6du1aZl3vvfeeLly4UGrfERER18xHqV+/7F/1oqIi9erVS3/729+u2deiRQvnvxs1auSyr7i4WHFxcYqLi9Pf/vY3tWjRQjk5OYqLi7um7iuPvd5rcVl5P8erldenO3Widunfv7/i4uKUlJTkchvRx8fnmtvRl8+HK135OyT9+HtU2rYrb2dU5ly42vV+x1944QXNmTNHs2fPVlRUlBo1aqSJEyeW+fv42GOP6YEHHnCuX3kNbN68uTp06ODSvqw/+tKPz1H68VZu69atXfZdPWH36udZ0evn1cdV5Jwv7+dytev1V5nrvGkIN3XExYsXtXjxYs2cOVN33XWXy774+HgtXbpUN91003X72bp1q0aPHu2cbFpUVOQyWbA0zZo1U3x8vBYtWqSsrCznN7Zf1rBhQ5d7x6Xp1q2bMjMzlZKScs2+U6dO6cCBA3r99dedoWnLli3l9teuXbty97ujZ8+eWr58uUJCQhQYGFjh4z7//HOdOnVK06dPd84z2rlz53WPu/HGG+Xn56fMzEyNHTu20nVf6fLre/XPpip1onaYPn26unfv7py4K/0YNPLy8mRZljP4euIzoCp7LlytW7duOn78uL744otSR2+2bt2qoUOH6qGHHpL0Y2j/4osvFBkZWWp/wcHB5QYWd0RGRsputysnJ8c5gllRlbl+SuVf/yqjW7dumj9/vk6fPl3q61LZOk3Cbak6YvXq1Tpz5ozGjBmjrl27uizDhw+/5tZUWW688Ua98847ys7O1p49e/TLX/6yQpN2x44d6xweHzVqlMu+9u3ba/v27Tpy5IhOnjxZan9JSUn6+OOP9Zvf/EaffvqpPv/8c7366qs6efKkmjZtqmbNmum1117TwYMHtWHDBiUmJlbshfGABx98UM2bN9fQoUP14Ycf6vDhw9q4caN+97vflTuZs23btmrYsKFefvllffXVV3r33Xc1bdq06z6er6+vfv/732vKlCnOofCPPvqowj/D0iQnJ2vp0qVKTk7W/v37tXfvXj3//PNVqhO1Q1RUlB588EH9+c9/dm6LjY3ViRMnNGPGDB06dEhz587V2rVrq/xYlT0XrjZgwAD1799fw4cPV0ZGhg4fPqy1a9cqPT1d0o/XoYyMDG3btk379+/Xo48+qvz8/CrXXxEBAQGaPHmyJk2apDfeeEOHDh3SJ598opdffllvvPFGucdW9vpZ3vWvMhISEhQWFqb4+Hht3bpVX331lf75z38631FZ2TpNQripIxYsWKCBAweW+qF4w4cP186dO/Xpp59et59Zs2apadOm6tevn4YMGaK4uDj17NnzuscNHDhQLVu2VFxc3DXzVyZPnqx69eopMjLSecvjah07dtT69eu1Z88e9e3bVzExMVq1apXq168vHx8fLVu2TLt27VLXrl01adIkvfDCC9etyVP8/f21efNmtW3bVsOGDVPnzp01ZswYnTt3rtz/vbZo0UJpaWl6++23FRkZqenTp+vFF1+s0GM+88wzeuKJJ/Tss8+qc+fOGjFiRJXemh0bG6u3335b7777rrp3767//M//dL7zpCp1onaYOnWqyx+nzp076y9/+Yvmzp2r6Oho7dixQ5MnT67y41T2XCjNP//5T/Xp00cJCQmKjIzUlClTnCO8f/jDH9SzZ0/FxcUpNjbW+Ye6pkybNk3PPPOMUlNT1blzZ919991as2aNIiIiyj2ustfP8q5/ldGwYUOtX79eISEhuueeexQVFeXybrTK1mkSm3X1jVugFEVFRWrdurUWLVqkYcOGebscAADKxJwblMvhcOjkyZOaOXOmmjRpop///OfeLgkAgHIRblCunJwcRUREqE2bNkpLS6v0MCoAADWF21IAAMAoTCgGAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEb5fxRvn4m3iXSgAAAAAElFTkSuQmCC\n", + "image/png": "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ooS6d+8ul8tVGJ+2fF26dEkxMTEKDAzUmjVrtHbtWpUtW1YPPfSQx/+IUlNTtXv3bi1fvty90b106ZLGjh2rHTt2aOHChTp48KD69++f6zVeeeUVJSUladeuXYqOjlZCQoKSkpI0cuRI/fDDD/r4449z/cLCESNGaNiwYdq+fbvq1q2r2NjY6/7PbsmSJerevbs6deqkbdu2KTU1VXfffbfHx+jNnLBfyZIl9frrr2vy5Mk6cuRIgZfz1Vdf6ejRo1q9erUmTJigUaNG6eGHH1b58uW1ceNGDRo0SM8884z7NW5mPbiay+VSx44dtXbtWv3zn//UDz/8oKSkJJUsWVKSdOHCBTVr1kxLlizRd999p6efflp/+tOftGnTpgJ/rL5ITEzUnDlz9O677+r777/X0KFD1bdvX61atcrjcdeus95uO9988001btxY27Zt08iRI2+47ZOk2bNnq0yZMtq4caPGjx+vMWPGaPny5XnOn5GRobZt2+p///ufFi1apB07dmj48OHubaWv2/jblgXbtGrVypo4caJlWZZ16dIlq2LFitaKFSssy7KsFStWWJKsL7/80v34JUuWWJKsX3/99brLbNiwoTV58mT39erVq1tvv/22+3pkZKQ1btw49/UuXbpY/fv3d19v27at9cILL3gsM2eWs2fPWpZlWbGxsda9997r9cf5888/W5KsnTt3WpZlWQcOHLAkWdu2bbvuc3Jes0yZMrkuDofD42OSZC1YsMCyLMv68MMPrXr16lkul8t9f1ZWllW6dGkrJSXFsizLiouLs0JDQ62srKx85968ebMlyTp//rzHTAsXLnQ/Jj093XI6ndb06dPzXEbOx/r++++7b/v+++8tSdauXbssy7KsmTNnWsHBwe77W7ZsafXp0yff2byZM+frBXvExcVZXbt2tSzLsn7/+99bTz75pGVZlrVgwQIrZ9M7atQoq3Hjxh7Pe/vtt63q1at7LKd69epWdna2+7Z69epZbdq0cV+/fPmyVaZMGWvu3LmWZd3cenD1NiMlJcUqUaKEtXv3bq8/7s6dO1svvvii+3pe25RrVa9e3SpVqlSudf2OO+7w+Pxc/Tm9cOGCFRAQYK1bt85jWQMGDLBiY2Mty8p7nb2evLad3bp183jMjbZ9bdu2tVq3bu1xW4sWLayXX37Zff3q7dV7771nBQYGWqdPn77hfPnNefX28HbEHhWb7N69W5s2bVJsbKwkyc/PT71799aMGTM8HhcdHe3+d5UqVSTJvZs/IyNDw4YNU4MGDVSuXDmVLVtWu3btyre2Bw4c6N5FfOLECS1dutRjL403cv5XcT179+5VbGysatWqpaCgIPdu7OvN1bBhQ5UtW1Zly5bNdZLZmjVrtH37do9Lfn8WfMeOHdq3b58CAwPdywwJCdGFCxc8Dj9FRUWpVKlSHs/dunWrunTpomrVqikwMFBt27bNc+7mzZu7/71r1y5lZWXl+/mQ8v86XutGn19v54Q5xo0bp9mzZ2vXrl0Fen7Dhg1VosT/31yHhoYqKirKfb1kyZKqUKGC+3vqZtaDq23fvl3h4eGqW7dunvdnZ2dr7NixioqKUkhIiMqWLauUlJTrfi++/vrr7nnKli3r8biXXnop17o+aNCg6862b98+/fLLL+rQoYPHMufMmZPrUPPV66zk/bbz2ufdaN2UPNd16cr6nt+6ftdddykkJCTP+wuyjb8d2f63foqrGTNm6PLlyx4/dC3LktPp1JQpU9y33XHHHe5/55zMmrNbcNiwYVq+fLnefPNN1a5dW6VLl9ajjz6a70lf/fr10yuvvKL169dr3bp1qlmzptq0aePT7KVLl873/i5duqh69eqaPn26qlatKpfLpUaNGl13rv/85z+6dOlSnsuuWbNmrvM3/Pyu/22bkZGhZs2a6aOPPsp1X6VKldz/LlOmjMd9mZmZiomJUUxMjD766CNVqlRJhw4dUkxMTK65r37ujT4XOfL7Ol4rv2X6MifMcd999ykmJkYJCQkeh+lKlCiR63Bvzrpwtau/f6Qr30N53Xb1IYOCrAfXutH39xtvvKFJkyZp4sSJioqKUpkyZTRkyJDrfi8OGjRIvXr1cl+/evtXsWJF1a5d2+Px1/sBLl35GKUrh0rvvPNOj/uuPVn12o/T223ntc/zZn3P7+tyrRstryDb+NsRoWKDy5cva86cOXrrrbf04IMPetzXrVs3zZ07V/Xr17/hctauXav+/fu7T7TMyMjwOFkuLxUqVFC3bt00c+ZMrV+/PtdfqS5VqpTH8da8REdHKzU1VaNHj8513+nTp7V7925Nnz7dHUBff/11vsurXr16vvf7omnTppo/f74qV66soKAgr5/3448/6vTp00pKSnKfl7Nly5YbPq9OnToqXbq0UlNTNXDgwALPfbWcz29ef0G8oHPCfklJSWrSpIn7pFXpSjQcP35clmW5A7Ywfr9QQdeDa0VHR+vIkSPas2dPnntV1q5dq65du6pv376SrsT3nj17FBkZmefyQkJC8o0PX0RGRsrpdOrQoUPuvYreKsi2U8p/21cQ0dHRev/993XmzJk8Py8FnfN2w6EfGyxevFhnz57VgAED1KhRI49Lz549cx3+uZ46dero888/1/bt27Vjxw49/vjjXp2wOnDgQPdu6Li4OI/7atSooY0bN+rgwYM6depUnstLSEjQ5s2b9eyzz+rbb7/Vjz/+qGnTpunUqVMqX768KlSooH/84x/at2+fvvrqK8XHx3v3iSkEffr0UcWKFdW1a1etWbNGBw4c0MqVK/X888/nezJjtWrVVKpUKU2ePFk//fSTFi1apLFjx97w9fz9/fXyyy9r+PDh7l3OGzZs8PprmJdRo0Zp7ty5GjVqlHbt2qWdO3dq3LhxNzUn7BcVFaU+ffronXfecd/Wrl07/fzzzxo/frz279+vqVOnaunSpTf9WgVdD67Vtm1b3XffferZs6eWL1+uAwcOaOnSpUpOTpZ0ZRu0fPlyrVu3Trt27dIzzzyjEydO3PT83ggMDNSwYcM0dOhQzZ49W/v379c333yjyZMna/bs2fk+t6Dbzvy2fQURGxursLAwdevWTWvXrtVPP/2kzz77zP2uwILOebshVGwwY8YMtW/fPs9foNazZ09t2bJF33777Q2XM2HCBJUvX16tWrVSly5dFBMTo6ZNm97wee3bt1eVKlUUExOT63yPYcOGqWTJkoqMjHQfVrhW3bp1tWzZMu3YsUN33323WrZsqS+++EJ+fn4qUaKE5s2bp61bt6pRo0YaOnSo3njjjRvOVFgCAgK0evVqVatWTT169FCDBg00YMAAXbhwId//WVaqVEmzZs3SJ598osjISCUlJenNN9/06jVHjhypF198UX/961/VoEED9e7d+6beLtyuXTt98sknWrRokZo0aaI//OEP7ndR3MycsN+YMWM8ftA0aNBAf//73zV16lQ1btxYmzZt0rBhw276dQq6HuTls88+U4sWLRQbG6vIyEgNHz7cvdf1//7v/9S0aVPFxMSoXbt27h+6t8rYsWM1cuRIJSYmqkGDBnrooYe0ZMkS1axZM9/nFXTbmd+2ryBKlSqlZcuWqXLlyurUqZOioqI83lVV0DlvNw7r2gOkuO1lZGTozjvv1MyZM9WjRw+7xwEA4Lo4R6UYcblcOnXqlN566y2VK1dOjzzyiN0jAQCQL0KlGDl06JBq1qyp8PBwzZo1q8C7KwEAuFU49AMAAIzFybQAAMBYhAoAADAWoQIAAIxFqAAAAGMRKgAAwFiECgAAMBahAgAAjEWoAAAAYxEqAADAWP8P0htpdF1TWj8AAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -654,8 +684,7 @@ "ax = plt.gca()\n", "ax.set_xticks([0, 1])\n", "ax.set_xticklabels(['Analytical-Hierarchical', 'Numerical-Hierarchical'])\n", - "ax.set_ylabel('Time [s]')\n", - "plt.savefig(\"num_ana_time.png\")" + "ax.set_ylabel('Computation time [s]')" ] }, { @@ -667,26 +696,31 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "Performing parallel task execution on 3 processes.\n", - "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 2875.44it/s]2022-11-14 23:22:53 fides(WARNING) Stopping as function difference 1.62E-06 was smaller than specified tolerances (atol=1.00E-08, rtol=1.00E-08)\n", - "2022-11-14 23:22:53 fides(WARNING) Stopping as function difference 2.61E-07 was smaller than specified tolerances (atol=1.00E-08, rtol=1.00E-08)\n", - "\n", - "2022-11-14 23:23:34 fides(WARNING) Stopping as maximum number of iterations 1000.0 was exceeded.\n" + " 0%| | 0/3 [00:00" ] @@ -723,18 +757,17 @@ " order_by_id=True,\n", " colors=np.array(list(map(to_rgba, ('purple', 'orange')))),\n", " size=(15, 6),\n", - ")\n", - "plt.savefig(\"ana_ord.png\")" + ")" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { - "image/png": "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kCTpxx9/VJMmTWq9QAAAgIpUe7DvlClTNH78eIWFhalNmzbq16+fpF8vOfXs2bO26wMAAKhQtYPMfffdpyuuuEL79u3TwIEDfZ/62759e8bIAACAC6pGt1/37t1bvXv39lt244031kpBAAAAgQpojExaWppKS0sDbjQ9PV1HjhypcVEAAACBCCjIPPvss/rpp58CbvTFF1/U0aNHa1oTAABAQAK6tGRZljp16lThVwqcrTq9NwAAADUVUJBZtGhRtRuOjo6u9j4AAADVEfC3XwMAAASban8gHgAAQLAgyAAAAGMRZAAAgLEIMgAAwFg1DjK7du3SqlWr9PPPP0v69RZtAACAC6naQebw4cNKSkpSp06dNGTIEBUUFEiSJk2apAcffLDWCwQAAKhItYPM1KlTFRISon379ik0NNS3fMyYMcrKyqrV4gAAACpT7S+N/PDDD7Vq1Sq1bt3ab3nHjh313//+t9YKAwAAqEq1e2RKS0v9emJOO3LkiJxOZ60UBQAAEIhqB5lrr71Wb7zxhm/e4XCorKxMc+bMUf/+/Wu1OAAAgMpU+9LSnDlzNGDAAG3atEknTpzQQw89pK+//lpHjhzR+vXr66JGAACAclW7R6ZHjx769ttvdc0112jYsGEqLS3VyJEjtXnzZl188cV1USMAAEC5qt0jI0lut1vTp0+v7VoAAACqpUZB5vjx49q2bZsOHjyosrIyv3W///3va6UwAACAqlQ7yGRlZem2227ToUOHzlnncDh06tSpWikMAACgKtUeIzN58mTdfPPNKigoUFlZmd9EiAEAABdStYNMUVGR0tLSFB0dXRf1AAAABKzaQWbUqFFavXp1HZQCAABQPdUeI/PCCy/o5ptv1tq1a9WzZ081atTIb/0f/vCHWisOAACgMtUOMm+99ZY+/PBDNWnSRKtXr5bD4fCtczgcBBkAAHDBVPvS0vTp0zVz5kwVFxdr79692rNnj2/67rvvqtVWRkaGLrvsMoWHhysqKkrDhw9Xfn6+3zbHjx9XamqqIiMjFRYWppSUFBUVFVW3bAAAUA9VO8icOHFCY8aMUYMG1d71HDk5OUpNTdWGDRv00Ucf6eTJkxo0aJBKS0t920ydOlXvv/++li1bppycHB04cEAjR44872MDAADzOSzLsqqzw9SpU9WyZUv93//9X60X88MPPygqKko5OTnq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/fr16tevn0JDQ3XRRRcpOTnZd1LNysrSNddco+bNmysyMlI33XSTdu/eXTtPWjnO7iLev3+/Ro8erebNmysiIkLDhg3T3r17fesnTpyo4cOH6+mnn1ZsbKw6d+4sSfr73/+uPn36KDw8XDExMRo3bpwOHjzo2+/087By5Ur17t1bTqdT69atU1lZmebMmaMOHTrI6XQqPj5eTz/9tF+N3333nfr376/Q0FBdcsklft/wXt6lpffff1+XXXaZmjRpohYtWmjEiBG+dVXVifovKSlJMTExysjIqHCbt99+W927d5fT6VTbtm01d+5cv/Vt27bVn/70J91xxx0KDw9XfHy8/va3v9VajWf3nB49elR33nmnWrZsKZfLpeuvv15bt271rX/iiSd06aWX6tVXX1W7du3UpEkTSVWfT073Ei1dulTXXXedmjRpojfffFOS9Nprr/meg1atWun+++/3q/HQoUMaMWKEQkND1bFjR7333nu+dcF+3vutIMgEuX/84x/q0qWLOnfurFtvvVWvvfbaOV9pPn36dM2dO1ebNm1SSEiI7rjjDt+6kpISDRkyRNnZ2dq8ebNuuOEGDR06VPv27Sv3eHfeeaeysrJUUFDgW/bBBx/op59+0pgxY/Tss88qMTFRd911lwoKClRQUFDuN4tv2bJFAwYMULdu3ZSbm6t169Zp6NChOnXqlCSptLRUaWlp2rRpk7Kzs9WgQQONGDFCZWVltfG0VerkyZNKTk5WeHi41q5dq/Xr1yssLEw33HCD33942dnZys/P10cffaQPPvjAt+9TTz2lrVu3asWKFdq7d68mTpx4zjEeeeQRzZo1Szt27FBCQoLS09M1a9YsPfbYY/rPf/6jzMzMcz7Ucfr06Zo2bZq2bNmiTp06aezYsRX25vzrX//SiBEjNGTIEG3evFnZ2dm6/PLL/R5jIHWi/mrYsKH+9Kc/6fnnn9f3339/zvq8vDyNHj1at9xyi7Zv364nnnhCjz32mN8/S5I0d+5c9enTR5s3b9Z9992ne++91++fpdp088036+DBg1q5cqXy8vLUq1cvDRgwQEeOHPFts2vXLr399tt65513fJevAj2fPPLII3rggQe0Y8cOJScna8GCBUpNTdXdd9+t7du367333lOHDh389pk5c6ZGjx6tbdu2aciQIRo/frxfPWcK5vNevWYhqF111VXW/PnzLcuyrJMnT1otWrSwPv30U8uyLOvTTz+1JFkff/yxb/t//etfliTr559/rrDN7t27W88//7xvvk2bNtYzzzzjm+/WrZs1e/Zs3/zQoUOtiRMn+uavu+4664EHHvBr83QtP/74o2VZljV27Fjr6quvDvhx/vDDD5Yka/v27ZZlWdaePXssSdbmzZsr3Of0MZs1a3bO5HA4/B6TJGv58uWWZVnW3//+d6tz585WWVmZb73X67WaNm1qrVq1yrIsy5owYYIVHR1teb3eSuveuHGjJck6duyYX00rVqzwbePxeCyn02m98sor5bZx+rG++uqrvmVff/21JcnasWOHZVmWtWjRIsvtdvvWJyYmWuPHj6+0tkDqPP37Qv0yYcIEa9iwYZZlWdaVV15p3XHHHZZlWdby5cut06f9cePGWQMHDvTb73//93+tbt26+ebbtGlj3Xrrrb75srIyKyoqylqwYEGFxz7999y0adNzXpcNGjTwO3ecee5Zu3at5XK5rOPHj/u1d/HFF1svv/yyZVmWNWPGDKtRo0bWwYMHK338FZ1PTp9LT4uNjbWmT59eYTuSrEcffdQ3X1JSYkmyVq5caVmWPec9nIsemSCWn5+vL774QmPHjpUkhYSEaMyYMVq4cKHfdgkJCb6fW7VqJUm+ywglJSWaNm2aunbtqubNmyssLEw7duyosEdG+rVXZtGiRZJ+/abxlStX+vXyBOL0fyYV2blzp8aOHav27dvL5XKpbdu2klRhXd27d1dYWJjCwsLOGbS7du1abdmyxW+q7Gvft27dql27dik8PNzXZkREhI4fP+7XzduzZ081btzYb9+8vDwNHTpU8fHxCg8P13XXXVdu3X369PH9vGPHDnm93kqfD6ny3+PZqnp+A60T9d/s2bP1+uuva8eOHX7Ld+zYoauvvtpv2dVXX62dO3f6ehAk/79Lh8OhmJgY39/l4MGDfa+h7t27+7W1dOnSc16XZ74uzrZ161aVlJQoMjLS12ZYWJj27Nnj97ps06aNWrZs6bdvoOeTM49/8OBBHThwoFqvy2bNmsnlctX4dVnd8x4CE/TftfRbtnDhQv3yyy9+b8qWZcnpdOqFF17wLWvUqJHv59ODzk53VU6bNk0fffSR/vKXv6hDhw5q2rSpRo0aVekgudtuu02PPPKIcnNz9dlnn6ldu3a69tprq1V706ZNK10/dOhQtWnTRq+88opiY2NVVlamHj16VFjXv//9b9/gvLPbbteu3TnjR0JCKv7TLikpUe/evX3XyM905gmyWbNmfutKS0uVnJys5ORkvfnmm2rZsqX27dun5OTkc+o+c9+qnovTKvs9nq2yNqtTJ+q/vn37Kjk5Wenp6TW6vHjm36X069/m6b/LV199VT///HO528XFxZ1zmaayv9uSkhK1atVKq1evPmfdma/vs1+XUuDnk/N9XUr+j/9stX3eQ2AIMkHql19+0RtvvKG5c+dq0KBBfuuGDx+ut956S126dKmynfXr12vixIm+gaAlJSV+g1rLExkZqeHDh2vRokXKzc0955vGGzdu7PcfW3kSEhKUnZ2tmTNnnrPu8OHDys/P1yuvvOILSOvWrau0vTZt2lS6vjp69eqlpUuXKioqSi6XK+D9vvnmGx0+fFizZs3yjQvatGlTlft17NhRTZs2VXZ2tu68884a132m089ved8CX9M6UX/NmjVLl156qW/QuiR17dpV69ev99tu/fr16tSpkxo2bBhQu7/73e9qrcZevXqpsLBQISEhvp6KQNTkfCJJ4eHhatu2rbKzs9W/f/+alu2nts97CAyXloLUBx98oB9//FGTJk1Sjx49/KaUlJRzLi9VpGPHjr5BcVu3btW4ceMCGlh25513+rqjJ0yY4Leubdu2+vzzz7V3714dOnSo3PbS09O1ceNG3Xfffdq2bZu++eYbLViwQIcOHdJFF12kyMhI/e1vf9OuXbv0ySefKC0tLbAnphaMHz9eLVq00LBhw7R27Vrt2bNHq1ev1h/+8IdyB0WeFh8fr8aNG+v555/Xd999p/fee09PPfVUlcdr0qSJHn74YT300EN64403tHv3bm3YsCHg32F5ZsyYobfeekszZszQjh07tH37ds2ePfu86kT91bNnT40fP17PPfecb9mDDz6o7OxsPfXUU/r222/1+uuv64UXXtC0adNsqTEpKUmJiYkaPny4PvzwQ+3du1efffaZpk+fXmkQP5/zyRNPPKG5c+fqueee086dO/Xll1/q+eefr/FjCObzXn1GkAlSCxcuVFJSUrkftJSSkqJNmzZp27ZtVbYzb948XXTRRbrqqqs0dOhQJScnq1evXlXul5SUpFatWik5Ofmc8SbTpk1Tw4YN1a1bN99li7N16tRJH374obZu3arLL79ciYmJevfddxUSEqIGDRpoyZIlysvLU48ePTR16lT9+c9/rrKm2hIaGqo1a9YoPj5eI0eOVNeuXTVp0iQdP3680h6ali1bavHixVq2bJm6deumWbNm6S9/+UtAx3zsscf04IMP6vHHH1fXrl01ZsyY87odul+/flq2bJnee+89XXrppbr++uv1xRdfnHedqL+efPJJv386evXqpX/84x9asmSJevTooccff1xPPvmkbXe3ORwO/fvf/1bfvn11++23q1OnTrrlllv03//+95w7/M50PueTCRMmaP78+XrppZfUvXt33XTTTdq5c2eNH0Mwn/fqM4dlnXUvL6BfL0H97ne/06JFizRy5Ei7ywEAoFyMkYGfsrIyHTp0SHPnzlXz5s31+9//3u6SAACoEEEGfvbt26d27dqpdevWWrx4caV3/wAAYDcuLQEAAGMx2BcAABiLIAMAAIxFkAEAAMYiyAAAAGMRZAAAgLEIMgAAwFgEGQAAYCyCDAAAMBZBBgAAGOv/AatgglpB7vIZAAAAAElFTkSuQmCC\n", + "image/png": "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K6+8Uvfcc49effXVKh9pPmXKFM2ZM0fbtm1TWFiY7r///sCy8vJy3XbbbSooKNCOHTv0y1/+Uunp6Tp48GC1j/fggw8qPz9fhw8fDty2Zs0affPNNxo5cqReeukl9e3bVw899JAOHz6sw4cPV/vJ4jt37tTNN9+srl27asuWLfrggw+Unp6uM2fOSJIqKiqUmZmpbdu2qaCgQM2aNdOwYcPk9/sb4ttWq9OnTys1NVVRUVHatGmTNm/erFatWumXv/xl0P/wCgoKtGfPHr333ntas2ZNYN0ZM2Zo165dysvL04EDBzR27NgqjzF58mTNnDlTRUVF6tmzp7KysjRz5kxNnTpV//u//6vly5dX+aWOU6ZM0aRJk7Rz50517txZo0aNqvFozjvvvKNhw4bptttu044dO1RQUKDrrrsu6GsMZU5cvJo3b64XX3xR8+fP1//93/9VWV5YWKgRI0bo7rvv1u7du/Xss89q6tSpQf9ZkqQ5c+aoT58+2rFjhx599FE98sgjQf9Zakh33XWXSktLtXbtWhUWFqp37966+eabdfz48cB99u3bp7feektvv/124OWrUPcnkydP1uOPP66ioiKlpqZq0aJFGj9+vB5++GHt3r1bq1ev1hVXXBG0TnZ2tkaMGKFPP/1Ut912m8aMGRM0z9mcvN+7qFlwtH79+lm5ubmWZVnW6dOnrUsvvdRav369ZVmWtX79ekuS9de//jVw/3feeceSZH377bc1brNbt27W/PnzA9c7duxo/ed//mfgeteuXa1Zs2YFrqenp1tjx44NXL/pppusxx9/PGiblbOcOHHCsizLGjVqlNW/f/+Qv85//etfliRr9+7dlmVZ1v79+y1J1o4dO2pcp/IxW7ZsWeXicrmCviZJ1qpVqyzLsqw//OEP1pVXXmn5/f7Acp/PZ0VERFjr1q2zLMuyMjIyrNjYWMvn89U699atWy1J1tdffx00U15eXuA+Xq/Xcrvd1uLFi6vdRuXX+sorrwRu+8c//mFJsoqKiizLsqylS5daHo8nsLxv377WmDFjap0tlDkr/75wccnIyLCGDBliWZZl/du//Zt1//33W5ZlWatWrbIqd/ujR4+2brnllqD1nnrqKatr166B6x07drTuueeewHW/32+1b9/eWrRoUY2PXfnzHBERUeV52axZs6B9x9n7nk2bNlnR0dHWqVOngrZ3+eWXW7///e8ty7Ks6dOnW5dccolVWlpa69df0/6kcl9aKT4+3poyZUqN25Fk/frXvw5cLy8vtyRZa9eutSzLnv0equKIjIPt2bNHn3zyiUaNGiVJCgsL08iRI7VkyZKg+/Xs2TPw5w4dOkhS4GWE8vJyTZo0SV26dFHr1q3VqlUrFRUV1XhERvrhqMzSpUsl/fBJ42vXrg06yhOKyv+Z1KS4uFijRo3ST3/6U0VHRyspKUmSapyrW7duatWqlVq1alXlpN1NmzZp586dQZfaPvZ9165d2rdvn6KiogLbbNu2rU6dOhV0mLdHjx5q0aJF0LqFhYVKT09XYmKioqKidNNNN1U7d58+fQJ/Lioqks/nq/X7IdX+93iu831/Q50TF79Zs2bptddeU1FRUdDtRUVF6t+/f9Bt/fv3V3FxceAIghT8c+lyuRQXFxf4uUxLSws8h7p16xa0rZUrV1Z5Xp79vDjXrl27VF5erpiYmMA2W7Vqpf379wc9Lzt27Kh27doFrRvq/uTsxy8tLdWhQ4fq9Lxs2bKloqOj6/28rOt+D6Fx/Gct/ZgtWbJE33//fdA/ypZlye12a8GCBYHbLrnkksCfK086qzxUOWnSJL333nv67W9/qyuuuEIRERG68847az1J7r777tPkyZO1ZcsWffjhh0pOTtYNN9xQp9kjIiJqXZ6enq6OHTtq8eLFio+Pl9/vV/fu3Wuc6y9/+Uvg5Lxzt52cnFzl/JGwsJp/tMvLy3XNNdcEXiM/29k7yJYtWwYtq6ioUGpqqlJTU/XGG2+oXbt2OnjwoFJTU6vMffa65/teVKrt7/FctW2zLnPi4nfjjTcqNTVVWVlZ9Xp58eyfS+mHn83Kn8tXXnlF3377bbX3S0hIqPIyTW0/t+Xl5erQoYM2bNhQZdnZz+9zn5dS6PuTC31eSsFf/7kaer+H0BAyDvX999/r9ddf15w5c3TrrbcGLRs6dKjefPNNXXXVVefdzubNmzV27NjAiaDl5eVBJ7VWJyYmRkOHDtXSpUu1ZcuWKp803qJFi6D/sVWnZ8+eKigoUHZ2dpVlX331lfbs2aPFixcHAumDDz6odXsdO3asdXld9O7dWytXrlT79u0VHR0d8nqfffaZvvrqK82cOTNwXtC2bdvOu16nTp0UERGhgoICPfjgg/We+2yV39/qPgW+vnPi4jVz5kxdffXVgZPWJalLly7avHlz0P02b96szp07q3nz5iFt9yc/+UmDzdi7d28dOXJEYWFhgSMVoajP/kSSoqKilJSUpIKCAg0cOLC+Ywdp6P0eQsNLSw61Zs0anThxQg888IC6d+8edLnjjjuqvLxUk06dOgVOitu1a5dGjx4d0ollDz74YOBwdEZGRtCypKQkffzxxzpw4ICOHTtW7faysrK0detWPfroo/r000/12WefadGiRTp27JjatGmjmJgYvfzyy9q3b5/+9re/KTMzM7RvTAMYM2aMLr30Ug0ZMkSbNm3S/v37tWHDBk2YMKHakyIrJSYmqkWLFpo/f76++OILrV69WjNmzDjv44WHh+uZZ57R008/rddff12ff/65Pvroo5D/Dqszffp0vfnmm5o+fbqKioq0e/duzZo164LmxMWrR48eGjNmjObNmxe47cknn1RBQYFmzJihvXv36rXXXtOCBQs0adIkW2ZMSUlR3759NXToUL377rs6cOCAPvzwQ02ZMqXWEL+Q/cmzzz6rOXPmaN68eSouLtb27ds1f/78en8NTt7vXcwIGYdasmSJUlJSqv1FS3fccYe2bdumTz/99LzbmTt3rtq0aaN+/fopPT1dqamp6t2793nXS0lJUYcOHZSamlrlfJNJkyapefPm6tq1a+Bli3N17txZ7777rnbt2qXrrrtOffv21Z///GeFhYWpWbNmWrFihQoLC9W9e3c98cQT+s1vfnPemRpKZGSkNm7cqMTERA0fPlxdunTRAw88oFOnTtV6hKZdu3ZatmyZ/vSnP6lr166aOXOmfvvb34b0mFOnTtWTTz6padOmqUuXLho5cuQFvR16wIAB+tOf/qTVq1fr6quv1i9+8Qt98sknFzwnLl7PPfdc0H86evfurT/+8Y9asWKFunfvrmnTpum5556z7d1tLpdLf/nLX3TjjTdq3Lhx6ty5s+6++259+eWXVd7hd7YL2Z9kZGQoNzdX//Vf/6Vu3bpp8ODBKi4urvfX4OT93sXMZVnnvJcX0A8vQf3kJz/R0qVLNXz4cLvHAQCgWpwjgyB+v1/Hjh3TnDlz1Lp1a91+++12jwQAQI0IGQQ5ePCgkpOTddlll2nZsmW1vvsHAAC78dISAAAwFif7AgAAYxEyAADAWIQMAAAwFiEDAACMRcgAAABjETIAAMBYhAwAADAWIQMAAIxFyAAAAGP9P8voplt2CU+kAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -751,8 +784,7 @@ "ax = plt.gca()\n", "ax.set_xticks([0, 1])\n", "ax.set_xticklabels(['Analytical-Hierarchical', 'Non-Hierarchical'])\n", - "ax.set_ylabel('Time [s]')\n", - "plt.savefig(\"ana_ord_time.png\")" + "ax.set_ylabel('Computation time [s]')" ] }, { @@ -764,26 +796,32 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "Performing parallel task execution on 3 processes.\n", - "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 1088.58it/s]\n", - "2022-11-14 23:23:35 fides(WARNING) Stopping as trust region radius 6.31E-17 is smaller than machine precision.\n", - "2022-11-14 23:23:36 fides(WARNING) Stopping as trust region radius 1.13E-16 is smaller than machine precision.\n", - "2022-11-14 23:23:36 fides(WARNING) Stopping as trust region radius 1.11E-16 is smaller than machine precision.\n" + " 0%| | 0/3 [00:00" ] @@ -829,18 +867,17 @@ " colors=np.array(list(map(to_rgba, ('purple', 'blue', 'green', 'orange')))),\n", " order_by_id=True,\n", " size=(15, 6),\n", - ")\n", - "plt.savefig(\"all.png\")" + ")" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjIAAAJsCAYAAADnSEneAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAABzWUlEQVR4nO3dd1gU5/o+8HtpK71LE6SDSFNURLF3jb1rjno0yYkmJmo8sSRq1FiSk6jRGE2sMWqMGkusWFDsBRVQVAwCglKkCAsIC+zu7w9/u1+JDRSdHbw/17XXOcwuy5NMdueed97nHYlKpVKBiIiISIR0hC6AiIiI6GUxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWjpCV3A66ZUKpGeng5TU1NIJBKhyyEiIqIqUKlUKCwshKOjI3R0nj3uUuuDTHp6OpydnYUug4iIiF5CWloa6tWr98zna32QMTU1BfDoX4SZmZnA1RAREVFVyGQyODs7a47jz1Lrg4z6cpKZmRmDDBERkci8aFoIJ/sSERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFo6QldABER0SvbLBG6grfXMJWgf54jMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWloTZBYuXAiJRIIJEyZotpWWluKjjz6CtbU1TExM0L9/f2RlZQlXJBEREWkVrQgyFy9exM8//4zAwMBK2ydOnIg9e/Zg27ZtiIqKQnp6Ovr16ydQlURERKRtBA8yRUVFGD58OFatWgVLS0vN9oKCAqxZswaLFi1C+/btERISgnXr1uHMmTM4d+6cgBUTERGRthA8yHz00Ufo0aMHOnbsWGn7pUuXUF5eXmm7r68vXFxccPbs2We+n1wuh0wmq/QgIiKi2knQm0Zu2bIFly9fxsWLF594LjMzEwYGBrCwsKi03c7ODpmZmc98zwULFmD27Nk1XSoRERFpIcFGZNLS0vDpp59i06ZNqFOnTo2977Rp01BQUKB5pKWl1dh7ExERkXYRLMhcunQJ9+/fR+PGjaGnpwc9PT1ERUVh6dKl0NPTg52dHcrKypCfn1/p97KysmBvb//M95VKpTAzM6v0ICIiotpJsEtLHTp0wNWrVytt+/e//w1fX19MmTIFzs7O0NfXx9GjR9G/f38AQEJCAlJTUxEWFiZEyURERKRlBAsypqam8Pf3r7TN2NgY1tbWmu1jxozBpEmTYGVlBTMzM4wfPx5hYWFo3ry5ECUTERGRlhF0su+LLF68GDo6Oujfvz/kcjm6dOmCn376SeiyiIiISEtIVCqVSugiXieZTAZzc3MUFBRwvgwRUW21WSJ0BW+vYa8nRlT1+C34OjJEREREL4tBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiERL0CCzYsUKBAYGwszMDGZmZggLC8OBAwc0z7dt2xYSiaTS48MPPxSwYiIiItImekL+8Xr16mHhwoXw8vKCSqXCr7/+it69e+PKlSto2LAhAOD999/HnDlzNL9jZGQkVLlERESkZQQNMj179qz087x587BixQqcO3dOE2SMjIxgb28vRHlERESk5bRmjoxCocCWLVtQXFyMsLAwzfZNmzbBxsYG/v7+mDZtGh4+fPjc95HL5ZDJZJUeREREVDsJOiIDAFevXkVYWBhKS0thYmKCnTt3ws/PDwAwbNgw1K9fH46OjoiLi8OUKVOQkJCAHTt2PPP9FixYgNmzZ7+p8omIiEhAEpVKpRKygLKyMqSmpqKgoADbt2/H6tWrERUVpQkzj4uMjESHDh2QmJgIDw+Pp76fXC6HXC7X/CyTyeDs7IyCggKYmZm9tn8OIiIS0GaJ0BW8vYa9nhghk8lgbm7+wuO34CMyBgYG8PT0BACEhITg4sWL+OGHH/Dzzz8/8drQ0FAAeG6QkUqlkEqlr69gIiIi0hpaM0dGTalUVhpReVxMTAwAwMHB4Q1WRERERNpK0BGZadOmoVu3bnBxcUFhYSE2b96M48ePIyIiArdv38bmzZvRvXt3WFtbIy4uDhMnTkTr1q0RGBgoZNlERESkJQQNMvfv38eIESOQkZEBc3NzBAYGIiIiAp06dUJaWhqOHDmCJUuWoLi4GM7Ozujfvz++/PJLIUsmIiIiLSL4ZN/XraqThYiISMQ42Vc4Ak/21bo5MkRERERVxSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESiJWiQWbFiBQIDA2FmZgYzMzOEhYXhwIEDmudLS0vx0UcfwdraGiYmJujfvz+ysrIErJiIiIi0iaBBpl69eli4cCEuXbqE6OhotG/fHr1790Z8fDwAYOLEidizZw+2bduGqKgopKeno1+/fkKWTERERFpEolKpVEIX8TgrKyv873//w4ABA2Bra4vNmzdjwIABAICbN2+iQYMGOHv2LJo3b16l95PJZDA3N0dBQQHMzMxeZ+lERCSUzRKhK3h7DXs9MaKqx2+tmSOjUCiwZcsWFBcXIywsDJcuXUJ5eTk6duyoeY2vry9cXFxw9uzZZ76PXC6HTCar9CAiIqLaSfAgc/XqVZiYmEAqleLDDz/Ezp074efnh8zMTBgYGMDCwqLS6+3s7JCZmfnM91uwYAHMzc01D2dn59f8T0BERERCETzI+Pj4ICYmBufPn8fYsWMxcuRIXL9+/aXfb9q0aSgoKNA80tLSarBaIiIi0iZ6QhdgYGAAT09PAEBISAguXryIH374AYMHD0ZZWRny8/MrjcpkZWXB3t7+me8nlUohlUpfd9lERESkBQQfkfknpVIJuVyOkJAQ6Ovr4+jRo5rnEhISkJqairCwMAErJCIiIm0h6IjMtGnT0K1bN7i4uKCwsBCbN2/G8ePHERERAXNzc4wZMwaTJk2ClZUVzMzMMH78eISFhVW5Y4mIiIhqN0GDzP379zFixAhkZGTA3NwcgYGBiIiIQKdOnQAAixcvho6ODvr37w+5XI4uXbrgp59+ErJkIiIi0iJat45MTeM6MkREbwGuIyMcriNDRERE9HIYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQEDTILFixA06ZNYWpqirp166JPnz5ISEio9Jq2bdtCIpFUenz44YcCVUxERETaRNAgExUVhY8++gjnzp3D4cOHUV5ejs6dO6O4uLjS695//31kZGRoHt9++61AFRMREZE20RPyjx88eLDSz+vXr0fdunVx6dIltG7dWrPdyMgI9vb2b7o8IiIi0nJaNUemoKAAAGBlZVVp+6ZNm2BjYwN/f39MmzYNDx8+fOZ7yOVyyGSySg8iIiKqnQQdkXmcUqnEhAkT0LJlS/j7+2u2Dxs2DPXr14ejoyPi4uIwZcoUJCQkYMeOHU99nwULFmD27NlvqmwiIiISkESlUqle9KK//vqr2m/cqVMnGBoaVvn1Y8eOxYEDB3Dq1CnUq1fvma+LjIxEhw4dkJiYCA8Pjyeel8vlkMvlmp9lMhmcnZ1RUFAAMzOz6v1DEBGROGyWCF3B22vYC2PES5HJZDA3N3/h8btKIzJ9+vSp1h+XSCT4+++/4e7uXqXXf/zxx9i7dy9OnDjx3BADAKGhoQDwzCAjlUohlUqrVS8RERGJU5XnyGRmZkKpVFbpYWRkVKX3VKlU+Pjjj7Fz505ERkbCzc3thb8TExMDAHBwcKhq6URERFRLVWlEZuTIkdW6TPTuu+9W6TLORx99hM2bN2P37t0wNTVFZmYmAMDc3ByGhoa4ffs2Nm/ejO7du8Pa2hpxcXGYOHEiWrdujcDAwCrXQ0RERLVTlebIvLY/Lnn6Nc1169Zh1KhRSEtLw7vvvotr166huLgYzs7O6Nu3L7788ssqz3ep6jU2IiISMc6REY4Y5si86A9FRkbCx8cHDRo0qNbvvihDOTs7Iyoq6lXKIyIiolqs2uvIDBo0CD/++CMAoKSkBE2aNMGgQYMQGBiIP//8s8YLJCIiInqWageZEydOoFWrVgCAnTt3QqVSIT8/H0uXLsXXX39d4wUSERERPUu1g0xBQYFm5d2DBw+if//+MDIyQo8ePfD333/XeIFEREREz1LtIOPs7IyzZ8+iuLgYBw8eROfOnQEADx48QJ06dWq8QCIiIqJnqfZk3wkTJmD48OEwMTFB/fr10bZtWwCPLjkFBATUdH1EREREz1TtIDNu3DiEhoYiNTUVnTp1go7Oo0Edd3d3zpEhIiKiN+ql2q9DQkIQEhJSaVuPHj1qpCAiIiKiqqrSHJlJkyahuLi4ym86bdo05OXlvXRRRERERFVRpSDzww8/4OHDh1V+0+XLlyM/P/9layIiIiKqkipdWlKpVPD29n7mLQX+qTqjN0REREQvq0pBZt26ddV+Yzs7u2r/DhEREVF1VPnu10RERETaptoL4hERERFpCwYZIiIiEi0GGSIiIhItBhkiIiISrZcOMomJiYiIiEBJSQmARy3aRERERG9StYNMbm4uOnbsCG9vb3Tv3h0ZGRkAgDFjxuCzzz6r8QKJiIiInqXaQWbixInQ09NDamoqjIyMNNsHDx6MgwcP1mhxRERERM9T7ZtGHjp0CBEREahXr16l7V5eXrhz506NFUZERET0ItUekSkuLq40EqOWl5cHqVRaI0URERERVUW1g0yrVq2wYcMGzc8SiQRKpRLffvst2rVrV6PFERERET1PtS8tffvtt+jQoQOio6NRVlaGzz//HPHx8cjLy8Pp06dfR41ERERET1XtERl/f3/cunUL4eHh6N27N4qLi9GvXz9cuXIFHh4er6NGIiIioqeq9ogMAJibm+OLL76o6VqIiIiIquWlgkxpaSni4uJw//59KJXKSs/16tWrRgojIiIiepFqB5mDBw9ixIgRyMnJeeI5iUQChUJRI4URERERvUi158iMHz8eAwcOREZGBpRKZaUHQwwRERG9SdUOMllZWZg0aRLs7OxeRz1EREREVVbtIDNgwAAcP378NZRCREREVD3VniPz448/YuDAgTh58iQCAgKgr69f6flPPvmkxoojIiIiep5qB5nff/8dhw4dQp06dXD8+HFIJBLNcxKJhEGGiIiI3phqX1r64osvMHv2bBQUFCAlJQXJycma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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjIAAAJsCAYAAADnSEneAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAABueUlEQVR4nO3dd1RU19oG8GfovSNNkA4iCPYGir33ronmamKiiUaNiSWxR40mUaMxmtiI0cQWe8OCioINFVSsCAgKKEUYepmZ7w/XzCexgaJnDj6/tVj3MgXfdc+dOc/ZZ797SxQKhQJEREREIqQhdAFEREREr4tBhoiIiESLQYaIiIhEi0GGiIiIRItBhoiIiESLQYaIiIhEi0GGiIiIREtL6ALeNrlcjpSUFBgbG0MikQhdDhEREVWAQqFAbm4u7O3toaHx4nGXah9kUlJS4OjoKHQZRERE9BqSk5NRs2bNFz5f7YOMsbExgCf/Q5iYmAhcDREREVWEVCqFo6Oj6jz+ItU+yChvJ5mYmDDIEBERicyrpoVwsi8RERGJFoMMERERiRaDDBEREYkWgwwRERGJFoMMERERiRaDDBEREYkWgwwRERGJFoMMERERiRaDDBEREYkWgwwRERGJlqBBJjw8HN27d4e9vT0kEgl27dr1wtd+9tlnkEgkWLp06Turj4iIiNSboEEmPz8f/v7+WLFixUtft3PnTpw9exb29vbvqDIiIiISA0E3jezcuTM6d+780tc8ePAAY8eORWhoKLp27fqOKiMiIiIxUOvdr+VyOT788EN8/fXXqFOnToXeU1xcjOLiYtXvUqn0bZVHREREAlPryb4LFy6ElpYWxo0bV+H3LFiwAKampqofR0fHt1ghERERCUltR2QuXryIX375BZcuXYJEIqnw+6ZOnYqJEyeqfpdKpQwzRETV3d8VP09QFRuiEPSfV9sRmVOnTuHRo0dwcnKClpYWtLS0cO/ePXz11VdwdnZ+4ft0dXVhYmJS7oeIiIiqJ7Udkfnwww/Rrl27co917NgRH374If73v/8JVBURERGpE0GDTF5eHuLi4lS/JyQkIDo6GhYWFnBycoKlpWW512tra8PW1hZeXl7vulQiIiJSQ4IGmaioKLRu3Vr1u3Juy/DhwxESEiJQVURERCQWggaZ4OBgKBQVnySUmJj49oohIiIi0VHbyb5EREREr8IgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREosUgQ0RERKLFIENERESixSBDREREoiVokAkPD0f37t1hb28PiUSCXbt2qZ4rLS3F5MmT4efnB0NDQ9jb22PYsGFISUkRrmAiIiJSK4IGmfz8fPj7+2PFihXPPFdQUIBLly5h+vTpuHTpEnbs2IFbt26hR48eAlRKRERE6khLyH+8c+fO6Ny583OfMzU1xZEjR8o99uuvv6Jx48ZISkqCk5PTuyiRiIiI1JigQaaycnJyIJFIYGZm9sLXFBcXo7i4WPW7VCp9B5URERGREEQz2beoqAiTJ0/G4MGDYWJi8sLXLViwAKampqofR0fHd1glERERvUuiCDKlpaUYMGAAFAoFVq5c+dLXTp06FTk5Oaqf5OTkd1QlERERvWtqf2tJGWLu3buHsLCwl47GAICuri50dXXfUXVEREQkJLUOMsoQc+fOHRw/fhyWlpZCl0RERERqRNAgk5eXh7i4ONXvCQkJiI6OhoWFBezs7NCvXz9cunQJ+/btg0wmQ1paGgDAwsICOjo6QpVNREREakKiUCgUQv3jJ06cQOvWrZ95fPjw4Zg1axZcXFye+77jx48jODi4Qv+GVCqFqakpcnJyXnlbioiIROpvidAVvL+GvJ0YUdHzt6AjMsHBwXhZjhIwYxEREZEIiKJriYiIiOh5GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhItBhkiIiISLQYZIiIiEi0GGSIiIhI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JTw8PBAaGorRo0dj3Lhx+PPPP1/4ngULFsDU1FT14+jo+A4rJiIionepwrtfC0FHRwcNGzZEZGSk6rFx48bhwoULOHPmzHPfU1xcjOLiYtXvUqkUjo6O3P2aiKg64+7XwhHL7tdCsLOzg4+PT7nHateujaSkpBe+R1dXFyYmJuV+iIiIqHpS6yDTokUL3Lp1q9xjt2/fRq1atQSqiIiIiNSJWgeZCRMm4OzZs5g/fz7i4uLw999/448//sDnn38udGlERESkBtQ6yDRq1Ag7d+7EP//8A19fX8ydOxdLly7F0KFDhS6NiIiI1IBaryMDAN26dUO3bt2ELoOIiIjUkFqPyBARERG9DIMMERERiRaDDBEREYkWgwwRERGJFoMMERERiRaDDBEREYkWgwwRERGJFoMMERERiRaDDBEREYmW2q/sS0RUlSSzJUKX8N5SzFQIXQJVQxyRISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLR0hK6ADGbLZktdAnvrZmKmUKXQEREaoAjMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWgwyREREJFoMMkRERCRaDDJEREQkWqIKMj/88AMkEgnGjx8vdClUzUkk/BHqh4ioMkQTZC5cuIDff/8ddevWFboUIiIiUhOiCDJ5eXkYOnQoVq9eDXNzc6HLISIiIjUhiiDz+eefo2vXrmjXrt0rX1tcXAypVFruh4iIiKonLaELeJXNmzfj0qVLuHDhQoVev2DBAsyePfstV0VERETqQK1HZJKTk/Hll19i06ZN0NPTq9B7pk6dipycHNVPcnLyW66SiIiIhKLWIzIXL17Eo0ePUL9+fdVjMpkM4eHh+PXXX1FcXAxNTc1y79HV1YWuru67LpWIiIgEoNZBpm3btrh69Wq5x/73v//B29sbkydPfibEEBER0ftFrYOMsbExfH19yz1maGgIS0vLZx4nIiKi949az5EhIiIiehm1HpF5nhMnTghdAhEREakJjsgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaDHIEBERkWgxyBAREZFoMcgQERGRaKl1kFmwYAEaNWoEY2Nj1KhRA7169cKtW7eELouIiIjUhFoHmZMnT+Lzzz/H2bNnceTIEZSWlqJDhw7Iz88XujQiIiJSA1pCF/Ayhw4dKvd7SEgIatSogYsXL6Jly5YCVUVERETqQq2DzH/l5OQAACwsLF74muLiYhQXF6t+l0qlb70uIiIiEoZa31p6mlwux/jx49GiRQv4+vq+8HULFiyAqamp6sfR0fEdVklERETvkmiCzOeff45r165h8+bNL33d1KlTkZOTo/pJTk5+RxUSERHRuyaKW0tffPEF9u3bh/DwcNSsWfOlr9XV1YWuru47qoyIiIiEpNZBRqFQYOzYsdi5cydOnDgBFxcXoUsiIiIiNaLWQebzzz/H33//jd27d8PY2BhpaWkAAFNTU+jr6wtcHREREQlNrefIrFy5Ejk5OQgODoadnZ3qZ8uWLUKXRkRERGpArUdkFAqF0CUQERGRGlPrERkiIiKil2GQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLRYpAhIiIi0WKQISIiItFikCEiIiLREkWQWbFiBZydnaGnp4cm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", "text/plain": [ "
" ] @@ -869,8 +906,7 @@ " ]\n", ")\n", "plt.setp(ax.get_xticklabels(), fontsize=10, rotation=75)\n", - "ax.set_ylabel('Time [s]')\n", - "plt.savefig(\"all_time.png\")" + "ax.set_ylabel('Computation time [s]')" ] } ], @@ -890,7 +926,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.10.10" }, "toc": { "base_numbering": 1, diff --git a/pypesto/hierarchical/parameter.py b/pypesto/hierarchical/parameter.py index e0c341bac..fe05c4709 100644 --- a/pypesto/hierarchical/parameter.py +++ b/pypesto/hierarchical/parameter.py @@ -1,5 +1,5 @@ import logging -from typing import Any, Literal +from typing import Any, Literal, Optional import numpy as np @@ -24,8 +24,9 @@ class InnerParameter: Attributes ---------- coupled: - Whether the inner parameter is part of an observable that has both - an offset and scaling inner parameter. + If the inner parameter is part of an observable that has both + an offset and scaling inner parameter, this attribute points to + the other inner parameter. Otherwise, it is None. dummy_value: Value to be used when the optimal parameter is not yet known (in particular to simulate unscaled observables). @@ -62,7 +63,7 @@ def __init__( See class attributes. """ self.inner_parameter_id: str = inner_parameter_id - self.coupled = False + self.coupled: InnerParameter = None self.inner_parameter_type: str = inner_parameter_type if scale not in {LIN, LOG, LOG10}: @@ -82,7 +83,12 @@ def __init__( self.lb: float = lb self.ub: float = ub - self.check_bounds() + # Scaling and offset parameters can be bounded arbitrarily + if inner_parameter_type not in ( + InnerParameterType.SCALING, + InnerParameterType.OFFSET, + ): + self.check_bounds() self.ixs: Any = ixs if dummy_value is None: @@ -114,3 +120,21 @@ def check_bounds(self): f"`[{expected_lb}, {expected_ub}]`. " f"All expected parameter bounds:\n{INNER_PARAMETER_BOUNDS}" ) + + def is_within_bounds(self, value): + """Check whether a value is within the bounds.""" + if value < self.lb or value > self.ub: + return False + return True + + def get_unsatisfied_bound(self, value) -> Optional[str]: + """Get the unsatisfied bound index, if any.""" + if value < self.lb: + return LOWER_BOUND + elif value > self.ub: + return UPPER_BOUND + return None + + def get_bounds(self) -> dict: + """Get the bounds.""" + return {LOWER_BOUND: self.lb, UPPER_BOUND: self.ub} diff --git a/pypesto/hierarchical/petab.py b/pypesto/hierarchical/petab.py index 6403b2b48..d06c053f0 100644 --- a/pypesto/hierarchical/petab.py +++ b/pypesto/hierarchical/petab.py @@ -39,6 +39,11 @@ def correct_parameter_df_bounds(parameter_df: pd.DataFrame) -> pd.DataFrame: def correct_row(row: pd.Series) -> pd.Series: if pd.isna(row[PARAMETER_TYPE]): return row + if row[PARAMETER_TYPE] in [ + InnerParameterType.SCALING, + InnerParameterType.OFFSET, + ]: + return row bounds = INNER_PARAMETER_BOUNDS[row[PARAMETER_TYPE]] row[PETAB_LOWER_BOUND] = bounds[PYPESTO_LOWER_BOUND] row[PETAB_UPPER_BOUND] = bounds[PYPESTO_UPPER_BOUND] diff --git a/pypesto/hierarchical/problem.py b/pypesto/hierarchical/problem.py index d17f49710..85c2e90e1 100644 --- a/pypesto/hierarchical/problem.py +++ b/pypesto/hierarchical/problem.py @@ -224,10 +224,10 @@ def inner_problem_from_petab_problem( par.ixs = ix_matrices[par.inner_parameter_id] par_group_types = { - tuple(obs_pars.split(';')): { + tuple(obs_pars.split(';')): ( petab_problem.parameter_df.loc[obs_par, PARAMETER_TYPE] for obs_par in obs_pars.split(';') - } + ) for (obs_id, obs_pars), _ in petab_problem.measurement_df.groupby( [petab.OBSERVABLE_ID, petab.OBSERVABLE_PARAMETERS], dropna=True ) @@ -235,23 +235,38 @@ def inner_problem_from_petab_problem( } coupled_pars = { - par + group for group, types in par_group_types.items() if ( (InnerParameterType.SCALING in types) and (InnerParameterType.OFFSET in types) ) - for par in group } + # Check each group is of length 2 + for group in coupled_pars: + if len(group) != 2: + raise ValueError( + f"Expected exactly 2 parameters in group {group}: a scaling " + f"and an offset parameter." + ) + + id_to_par = {par.inner_parameter_id: par for par in inner_parameters} + + # assign coupling for par in inner_parameters: if par.inner_parameter_type not in [ InnerParameterType.SCALING, InnerParameterType.OFFSET, ]: continue - if par.inner_parameter_id in coupled_pars: - par.coupled = True + for group in coupled_pars: + if par.inner_parameter_id in group: + coupled_parameter_id = group[ + group.index(par.inner_parameter_id) - 1 + ] + par.coupled = id_to_par[coupled_parameter_id] + break return AmiciInnerProblem(xs=inner_parameters, data=data, edatas=edatas) diff --git a/pypesto/hierarchical/solver.py b/pypesto/hierarchical/solver.py index d4afcb1c0..6499dec48 100644 --- a/pypesto/hierarchical/solver.py +++ b/pypesto/hierarchical/solver.py @@ -13,6 +13,7 @@ apply_offset, apply_scaling, apply_sigma, + compute_bounded_optimal_scaling_offset_coupled, compute_nllh, compute_optimal_offset, compute_optimal_offset_coupled, @@ -91,30 +92,78 @@ def solve( ``problem``. """ x_opt = {} - data = copy.deepcopy(problem.data) # compute optimal offsets for x in problem.get_xs_for_type(InnerParameterType.OFFSET): - if x.coupled: + if x.coupled is not None: x_opt[x.inner_parameter_id] = compute_optimal_offset_coupled( data=data, sim=sim, sigma=sigma, mask=x.ixs ) + + # calculate the optimal coupled scaling + coupled_scaling = x.coupled + x_opt[ + coupled_scaling.inner_parameter_id + ] = compute_optimal_scaling( + data=data, + sim=sim, + sigma=sigma, + mask=coupled_scaling.ixs, + optimal_offset=x_opt[x.inner_parameter_id], + ) + + # check whether they both satisfy their bounds + if x.is_within_bounds( + x_opt[x.inner_parameter_id] + ) and coupled_scaling.is_within_bounds( + x_opt[coupled_scaling.inner_parameter_id] + ): + continue + else: + # if not, we need to recompute them + ( + x_opt[coupled_scaling.inner_parameter_id], + x_opt[x.inner_parameter_id], + ) = compute_bounded_optimal_scaling_offset_coupled( + data=data, + sim=sim, + sigma=sigma, + s=coupled_scaling, + b=x, + s_opt_value=x_opt[coupled_scaling.inner_parameter_id], + b_opt_value=x_opt[x.inner_parameter_id], + ) + # compute non-coupled optimal offset else: x_opt[x.inner_parameter_id] = compute_optimal_offset( data=data, sim=sim, sigma=sigma, mask=x.ixs ) + # check if the solution is within bounds + # if not, we set it to the unsatisfied bound + if not x.is_within_bounds(x_opt[x.inner_parameter_id]): + x_opt[x.inner_parameter_id] = x.get_bounds()[ + x.get_unsatisfied_bound(x_opt[x.inner_parameter_id]) + ] + # apply offsets for x in problem.get_xs_for_type(InnerParameterType.OFFSET): apply_offset( offset_value=x_opt[x.inner_parameter_id], data=data, mask=x.ixs ) - # compute optimal scalings + # compute non-coupled optimal scalings for x in problem.get_xs_for_type(InnerParameterType.SCALING): - x_opt[x.inner_parameter_id] = compute_optimal_scaling( - data=data, sim=sim, sigma=sigma, mask=x.ixs - ) + if x.coupled is None: + x_opt[x.inner_parameter_id] = compute_optimal_scaling( + data=data, sim=sim, sigma=sigma, mask=x.ixs + ) + # check if the solution is within bounds + # if not, we set it to the unsatisfied bound + if not x.is_within_bounds(x_opt[x.inner_parameter_id]): + x_opt[x.inner_parameter_id] = x.get_bounds()[ + x.get_unsatisfied_bound(x_opt[x.inner_parameter_id]) + ] # apply scalings for x in problem.get_xs_for_type(InnerParameterType.SCALING): apply_scaling( @@ -186,6 +235,8 @@ def __init__( self.x_guesses = None self.dummy_lb = -1e20 self.dummy_ub = +1e20 + self.user_specified_lb = None + self.user_specified_ub = None def initialize(self): """(Re-)initialize the solver.""" @@ -216,21 +267,19 @@ def solve( Whether to scale the results to the parameter scale specified in ``problem``. """ - pars = problem.xs.values() - # We currently cannot handle constraints on inner parameters correctly, - # and would have to assume [-inf, inf]. However, this may not be - # supported by all inner optimizers, so we go for some (arbitrary) - # large value. - lb = np.array( - [ - 0 - if x.inner_parameter_type == InnerParameterType.SIGMA - else self.dummy_lb - for x in pars + pars = list(problem.xs.values()) + + # This has to be done only once + if self.user_specified_lb is None or self.user_specified_ub is None: + self.user_specified_lb = [ + i for i in range(len(pars)) if pars[i].lb != -np.inf + ] + self.user_specified_ub = [ + i for i in range(len(pars)) if pars[i].ub != np.inf ] - ) - ub = np.full(shape=len(pars), fill_value=self.dummy_ub) + lb = [x.lb for x in pars] + ub = [x.ub for x in pars] x_guesses = self.sample_startpoints(problem, pars) @@ -265,20 +314,33 @@ def fun(x): pypesto_problem = Problem( objective, lb=lb, ub=ub, x_names=x_names, **self.problem_kwargs ) - pypesto_problem.set_x_guesses( x_guesses[:, pypesto_problem.x_free_indices] ) # perform the actual optimization result = minimize(pypesto_problem, **self.minimize_kwargs) - best_par = result.optimize_result.list[0]['x'] - if (np.isclose(best_par, lb) | np.isclose(best_par, ub)).any(): + # Check if the index of an optimized parameter on the dummy bound + # is not in the list of specified bounds. If so, raise an error. + if any( + ( + i not in self.user_specified_lb + for i, x in enumerate(best_par) + if x == self.dummy_lb + ) + ) or any( + ( + i not in self.user_specified_ub + for i, x in enumerate(best_par) + if x == self.dummy_ub + ) + ): raise RuntimeError( - "Active bounds in inner problem optimization. This can result " - "in incorrect gradient computation for the outer parameters." + f"An optimal inner parameter is on the defualt dummy bound of numerical optimization. " + f"This means the optimal inner parameter is either extremely large (>={self.dummy_ub})" + f"or extremely small (<={self.dummy_lb}). Consider changing the inner parameter bounds." ) x_opt = dict(zip(pypesto_problem.x_names, best_par)) diff --git a/pypesto/hierarchical/util.py b/pypesto/hierarchical/util.py index ceb74f27f..55835b57d 100644 --- a/pypesto/hierarchical/util.py +++ b/pypesto/hierarchical/util.py @@ -1,9 +1,11 @@ +import copy import warnings from typing import List import numpy as np -from ..C import DUMMY_INNER_VALUE, InnerParameterType +from ..C import DUMMY_INNER_VALUE, LOWER_BOUND, UPPER_BOUND, InnerParameterType +from .parameter import InnerParameter def get_finite_quotient( @@ -42,6 +44,7 @@ def compute_optimal_scaling( sim: List[np.ndarray], sigma: List[np.ndarray], mask: List[np.ndarray], + optimal_offset: float = None, ) -> float: """ Compute optimal scaling. @@ -63,7 +66,11 @@ def compute_optimal_scaling( for sim_i, data_i, sigma_i, mask_i in zip(sim, data, sigma, mask): # extract relevant values sim_x = sim_i[mask_i] # \tilde{h}_i - data_x = data_i[mask_i] # \bar{y}_i + data_x = ( + data_i[mask_i] - optimal_offset + if optimal_offset is not None + else data_i[mask_i] + ) # \bar{y}_i sigma_x = sigma_i[mask_i] # \sigma_i # update statistics num += np.nansum(sim_x * data_x / sigma_x**2) @@ -100,6 +107,7 @@ def compute_optimal_offset( sim: List[np.ndarray], sigma: List[np.ndarray], mask: List[np.ndarray], + optimal_scaling: float = None, ) -> float: """Compute optimal offset. @@ -117,13 +125,16 @@ def compute_optimal_offset( # iterate over conditions for sim_i, data_i, sigma_i, mask_i in zip(sim, data, sigma, mask): # extract relevant values - sim_x = sim_i[mask_i] # \tilde{h}_i + sim_x = ( + optimal_scaling * sim_i[mask_i] + if optimal_scaling is not None + else sim_i[mask_i] + ) # \tilde{h}_i data_x = data_i[mask_i] # \bar{y}_i sigma_x = sigma_i[mask_i] # \sigma_i # update statistics num += np.nansum((data_x - sim_x) / sigma_x**2) den += np.nansum(1 / sigma_x**2) - return get_finite_quotient( numerator=num, denominator=den, @@ -271,6 +282,141 @@ def apply_sigma( sigma[i][mask[i]] = sigma_value +def compute_bounded_optimal_scaling_offset_coupled( + data: List[np.ndarray], + sim: List[np.ndarray], + sigma: List[np.ndarray], + s: InnerParameter, + b: InnerParameter, + s_opt_value: float, + b_opt_value: float, +): + """Compute optimal scaling and offset of a constrained optimization problem. + + Computes the optimal scaling and offset of a constrained optimization in + case the unconstrained optimization yields a value outside the bounds. + We know the optimal solution then lies on the boundary of the bounds. + In the 2D offset-scaling bounded (rectangular) space, after unconstrained + optimization, if only one parameter is outside the bounds, then there is + one active edge (constraint) of the rectangle. We perform optimization on + this edge that is unconstrained in the other parameter. If this new optimum + is outside the bounds of the other parameter, the nearest vertex is chosen + as the optimum. If both parameters are outside the bounds, then there are + two active edges, which are optimized independently as above, then compared. + + Parameters + ---------- + data: + The data. + sim: + The simulation. + sigma: + The noise parameters. + s: + The scaling parameter. + b: + The offset parameter. + s_opt_value: + The optimal scaling value of the unconstrained problem. + b_opt_value: + The optimal offset value of the unconstrained problem. + + Returns + ------- + The optimal scaling and offset of the constrained problem. + """ + # Define relevant data and sim + # Make all non-masked data and sim nan's in the original one + relevant_data = copy.deepcopy(data) + relevant_sim = copy.deepcopy(sim) + for i in range(len(data)): + relevant_data[i][~s.ixs[i]] = np.nan + relevant_sim[i][~s.ixs[i]] = np.nan + + # Get bounds + s_bounds = s.get_bounds() + b_bounds = b.get_bounds() + + # Get unsatisfied bounds + s_unsatisfied = s.get_unsatisfied_bound(s_opt_value) + b_unsatisfied = b.get_unsatisfied_bound(b_opt_value) + + # If both parameters are unsatisfied, we need to check 2 + # unconstrained problems, clip the solutions to the bounds, and + # choose the one with the lowest objective value + if s_unsatisfied is not None and b_unsatisfied is not None: + # Solve the two unconstrained problems + candidate_points = [ + ( + s_bounds[s_unsatisfied], + np.clip( + compute_optimal_offset( + data, sim, sigma, s.ixs, s_bounds[s_unsatisfied] + ), + b_bounds[LOWER_BOUND], + b_bounds[UPPER_BOUND], + ), + ), + ( + np.clip( + compute_optimal_scaling( + data, sim, sigma, s.ixs, b_bounds[b_unsatisfied] + ), + s_bounds[LOWER_BOUND], + s_bounds[UPPER_BOUND], + ), + b_bounds[b_unsatisfied], + ), + ] + + # Evaluate the objective function at the candidate points + candidate_objective_values = [ + compute_nllh( + data=relevant_data, + sim=[ + sim_i * candidate_point[0] + candidate_point[1] + for sim_i in relevant_sim + ], + sigma=sigma, + ) + for candidate_point in candidate_points + ] + # The constrained solution is the candidate point with the lowest + # objective value + constrained_solution = candidate_points[ + np.argmin(candidate_objective_values) + ] + + # If only one parameter is unsatisfied, we need to solve a + # unconstrained problem, clipped to its boundary + elif s_unsatisfied is not None: + # Solve the unconstrained problem + constrained_solution = ( + s_bounds[s_unsatisfied], + np.clip( + compute_optimal_offset( + data, sim, sigma, s.ixs, s_bounds[s_unsatisfied] + ), + b_bounds[LOWER_BOUND], + b_bounds[UPPER_BOUND], + ), + ) + elif b_unsatisfied is not None: + # Solve the unconstrained problem + constrained_solution = ( + np.clip( + compute_optimal_scaling( + data, sim, sigma, s.ixs, b_bounds[b_unsatisfied] + ), + s_bounds[LOWER_BOUND], + s_bounds[UPPER_BOUND], + ), + b_bounds[b_unsatisfied], + ) + + return constrained_solution + + def compute_nllh( data: List[np.ndarray], sim: List[np.ndarray], sigma: List[np.ndarray] ) -> float: diff --git a/pypesto/visualize/parameters.py b/pypesto/visualize/parameters.py index eb69fff62..456d03091 100644 --- a/pypesto/visualize/parameters.py +++ b/pypesto/visualize/parameters.py @@ -10,7 +10,13 @@ from pypesto.util import delete_nan_inf -from ..C import INNER_PARAMETERS, RGBA, WATERFALL_MAX_VALUE +from ..C import ( + INNER_PARAMETERS, + LOWER_BOUND, + RGBA, + UPPER_BOUND, + WATERFALL_MAX_VALUE, +) from ..result import Result from .clust_color import assign_colors from .misc import ( @@ -382,19 +388,37 @@ def handle_inputs( ] if any(inner_xs): inner_xs_names = next( - list(inner_xs_idx.keys()) - for inner_xs_idx in inner_xs - if inner_xs_idx is not None + list(inner_x.keys()) for inner_x in inner_xs if inner_x is not None ) inner_xs = [ [np.nan for i in range(len(inner_xs_names))] - if inner_xs_idx is None - else list(inner_xs_idx.values()) - for inner_xs_idx in inner_xs + if inner_x is None + else list(inner_x.values()) + for inner_x in inner_xs ] # set bounds for inner parameters - inner_lb = np.full(len(inner_xs_names), -np.inf) - inner_ub = np.full(len(inner_xs_names), np.inf) + from ..hierarchical.calculator import HierarchicalAmiciCalculator + + # Check if objective has a calculator attribute + if hasattr(result.problem.objective, 'calculator') and isinstance( + inner_calculator := result.problem.objective.calculator, + HierarchicalAmiciCalculator, + ): + all_inner_bounds = np.array( + [ + inner_calculator.inner_problem.xs[inner_name].get_bounds() + for inner_name in inner_xs_names + ] + ) + inner_lb = [ + inner_bounds[LOWER_BOUND] for inner_bounds in all_inner_bounds + ] + inner_ub = [ + inner_bounds[UPPER_BOUND] for inner_bounds in all_inner_bounds + ] + else: + inner_lb = np.full(len(inner_xs_names), -np.inf) + inner_ub = np.full(len(inner_xs_names), np.inf) else: inner_xs = None # parse indices which should be plotted diff --git a/test/hierarchical/test_hierarchical.py b/test/hierarchical/test_hierarchical.py index 452d9eae3..e11cc33e2 100644 --- a/test/hierarchical/test_hierarchical.py +++ b/test/hierarchical/test_hierarchical.py @@ -1,4 +1,5 @@ """Tests for hierarchical optimization.""" +import copy import time import amici @@ -314,9 +315,9 @@ def test_analytical_computations(): assert np.isclose(sigma_value, expected_sigma_value, rtol=rtol) -def inner_problem_exp(): +def inner_problem_exp(add_scaling: bool = True, add_offset: bool = True): function = np.exp - timepoints = np.linspace(0, 10, 101) + timepoints = np.linspace(0, 3, 101) expected_values = { 'scaling_': 5, @@ -326,9 +327,13 @@ def inner_problem_exp(): simulation = function(timepoints) - data = ( - expected_values['scaling_'] * simulation + expected_values['offset_'] - ) + data = copy.deepcopy(simulation) + if add_scaling: + data *= expected_values['scaling_'] + + if add_offset: + data += expected_values['offset_'] + data[0::2] -= expected_values['sigma_'] data[1::2] += expected_values['sigma_'] @@ -344,14 +349,20 @@ def inner_problem_exp(): ixs=mask, ) for inner_parameter_id, inner_parameter_type in [ - ('offset_', InnerParameterType.OFFSET), - ('scaling_', InnerParameterType.SCALING), + ('offset_', InnerParameterType.OFFSET) + if add_offset + else (None, None), + ('scaling_', InnerParameterType.SCALING) + if add_scaling + else (None, None), ('sigma_', InnerParameterType.SIGMA), ] + if inner_parameter_id is not None ] - inner_parameters[0].coupled = True - inner_parameters[1].coupled = True + if add_scaling and add_offset: + inner_parameters[0].coupled = inner_parameters[1] + inner_parameters[1].coupled = inner_parameters[0] inner_problem = InnerProblem(xs=inner_parameters, data=[data]) @@ -405,6 +416,181 @@ def test_numerical_inner_solver(): assert np.isclose(result['sigma_'], expected_values['sigma_'], rtol=rtol) +def test_non_coupled_analytical_inner_solver(): + """Test analytically-solved non-coupled hierarchical inner parameters.""" + # Test for only offset + inner_problem, expected_values, simulation = inner_problem_exp( + add_scaling=False + ) + dummy_sigma = np.ones(simulation.shape) + + rtol = 1e-1 + + solver = AnalyticalInnerSolver() + result = solver.solve( + problem=inner_problem, + sim=[simulation], + sigma=[dummy_sigma], + scaled=False, + ) + assert np.isclose(result['offset_'], expected_values['offset_'], rtol=rtol) + assert np.isclose(result['sigma_'], expected_values['sigma_'], rtol=rtol) + + # Test for only scaling + inner_problem, expected_values, simulation = inner_problem_exp( + add_offset=False + ) + dummy_sigma = np.ones(simulation.shape) + + rtol = 1e-3 + + solver = AnalyticalInnerSolver() + result = solver.solve( + problem=inner_problem, + sim=[simulation], + sigma=[dummy_sigma], + scaled=False, + ) + + assert np.isclose( + result['scaling_'], expected_values['scaling_'], rtol=rtol + ) + assert np.isclose(result['sigma_'], expected_values['sigma_'], rtol=rtol) + + +def test_constrained_inner_solver(): + """Test numerically- and analytically-solved box-constrained hierarchical inner parameters.""" + inner_problem, expected_values, simulation = inner_problem_exp() + + dummy_sigma = np.ones(simulation.shape) + + all_lb = [(6, 3), (3, 0), (3, 1), (4, 3)] + all_ub = [(7, 4), (4, 1), (4, 3), (6, 4)] + + all_expected_values = [ + {'scaling_': 6, 'offset_': 3}, + {'scaling_': 4, 'offset_': 1}, + { + 'scaling_': 4, # all_lb[2][0], + 'offset_': np.clip( + compute_optimal_offset( + data=inner_problem.data, + sim=[simulation], + sigma=[dummy_sigma], + mask=[np.full(simulation.shape, True)], + optimal_scaling=4.0, + ), + 1, # all_lb[2][1], + 3, # all_ub[2][1], + ), + }, + { + 'scaling_': np.clip( + compute_optimal_scaling( + data=inner_problem.data, + sim=[simulation], + sigma=[dummy_sigma], + mask=[np.full(simulation.shape, True)], + optimal_offset=3.0, + ), + 4, # all_lb[3][0], + 6, # all_ub[3][0], + ), + 'offset_': 3, # all_lb[3][1], + }, + ] + + for lb, ub, expected_values in zip(all_lb, all_ub, all_expected_values): + # Set seed for reproducibility + np.random.seed(1) + inner_problem.get_for_id('scaling_').lb = lb[0] + inner_problem.get_for_id('scaling_').ub = ub[0] + inner_problem.get_for_id('offset_').lb = lb[1] + inner_problem.get_for_id('offset_').ub = ub[1] + + copied_sim = copy.deepcopy(simulation) + rtol = 1e-3 + + solver = AnalyticalInnerSolver() + ana_res = solver.solve( + problem=inner_problem, + sim=[copied_sim], + sigma=[dummy_sigma], + scaled=False, + ) + + copied_sim = copy.deepcopy(simulation) + solver = NumericalInnerSolver(minimize_kwargs={'n_starts': 10}) + num_res = solver.solve( + problem=inner_problem, + sim=[copied_sim], + sigma=[dummy_sigma], + scaled=False, + ) + + assert np.isclose(ana_res['offset_'], num_res['offset_'], rtol=rtol) + assert np.isclose(ana_res['scaling_'], num_res['scaling_'], rtol=rtol) + + assert np.isclose( + ana_res['offset_'], expected_values['offset_'], rtol=rtol + ) + assert np.isclose( + ana_res['scaling_'], expected_values['scaling_'], rtol=rtol + ) + + +def test_non_coupled_constrained_inner_solver(): + """Test non-coupled box-constrained hierarchical inner parameters.""" + for current_par, add_scaling, add_offset, lb, ub in zip( + ['scaling_', 'scaling_', 'offset_', 'offset_'], + [True, True, False, False], + [False, False, True, True], + [6, None, 3, None], + [None, 4, None, 1], + ): + # Set seed for reproducibility + np.random.seed(4) + inner_problem, expected_values, simulation = inner_problem_exp( + add_scaling=add_scaling, + add_offset=add_offset, + ) + if lb is not None: + inner_problem.get_for_id(current_par).lb = lb + expected_values = {current_par: lb} + if ub is not None: + inner_problem.get_for_id(current_par).ub = ub + expected_values = {current_par: ub} + + dummy_sigma = np.ones(simulation.shape) + copied_sim = copy.deepcopy(simulation) + rtol = 1e-3 + + solver = AnalyticalInnerSolver() + ana_res = solver.solve( + problem=inner_problem, + sim=[copied_sim], + sigma=[dummy_sigma], + scaled=False, + ) + + copied_sim = copy.deepcopy(simulation) + solver = NumericalInnerSolver(minimize_kwargs={'n_starts': 10}) + num_res = solver.solve( + problem=inner_problem, + sim=[copied_sim], + sigma=[dummy_sigma], + scaled=False, + ) + + assert np.isclose( + ana_res[current_par], num_res[current_par], rtol=rtol + ) + + assert np.isclose( + ana_res[current_par], expected_values[current_par], rtol=rtol + ) + + def at_least_as_good_as(v, v0) -> bool: """Check that the first vector of fvals is at least as good the second.