diff --git a/.gitignore b/.gitignore index d0b53d9..b473d13 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .ipynb_checkpoints .vscode Manifest.toml +spline_testing.jl diff --git a/Project.toml b/Project.toml index 0cf8b9f..01489e6 100644 --- a/Project.toml +++ b/Project.toml @@ -13,6 +13,7 @@ ElasticArrays = "fdbdab4c-e67f-52f5-8c3f-e7b388dad3d4" ForwardDiffPullbacks = "450a3b6d-2448-4ee1-8e34-e4eb8713b605" Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196" InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" +KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Optim = "429524aa-4258-5aef-a3af-852621145aeb" Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" diff --git a/examples/spline-flows-demo.ipynb b/examples/spline-flows-demo.ipynb new file mode 100644 index 0000000..e9967ea --- /dev/null +++ b/examples/spline-flows-demo.ipynb @@ -0,0 +1,627 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b1775d4a-d017-4b96-87fb-8f486d4969ae", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "┌ Info: Precompiling EuclidianNormalizingFlows [eb90128f-7c94-4cd6-9130-4bb7c9abac9d]\n", + "└ @ Base loading.jl:1423\n" + ] + } + ], + "source": [ + "using ChangesOfVariables, InverseFunctions, ArraysOfArrays, Statistics\n", + "using Optimisers\n", + "using PyPlot\n", + "using Distributions\n", + "using LinearAlgebra\n", + "using Test\n", + "\n", + "using ForwardDiff\n", + "# using ReverseDiff\n", + "# using FiniteDifferences\n", + "\n", + "using Revise\n", + "using EuclidianNormalizingFlows" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "93f8bdf7-9ddc-4120-935c-9cb4b292c37e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test no. 1 successfull!\n", + "Test no. 2 successfull!\n", + "Test no. 3 successfull!\n", + "Test no. 4 successfull!\n", + "Test no. 5 successfull!\n", + "Test no. 6 successfull!\n", + "Test no. 7 successfull!\n", + "Test no. 8 successfull!\n", + "Test no. 9 successfull!\n", + "Test no. 10 successfull!\n", + "Test no. 11 successfull!\n", + "Test no. 12 successfull!\n", + "Test no. 13 successfull!\n", + "Test no. 14 successfull!\n", + "Test no. 15 successfull!\n", + "Test no. 16 successfull!\n", + "Test no. 17 successfull!\n", + "Test no. 18 successfull!\n", + "Test no. 19 successfull!\n", + "Test no. 20 successfull!\n" + ] + } + ], + "source": [ + "# Compare transformation results & gradients using Finite Differences and and handwritten pullbacks.\n", + "\n", + "function run_test_suite(; nrepetitions = 20,\n", + " ndims = 10,\n", + " nparams = 10,\n", + " nsmpls = 100,\n", + " dist = Uniform(-3, 3),\n", + " )\n", + " \n", + " for i in 1:nrepetitions\n", + "\n", + " w = rand(dist, ndims, nparams)\n", + " h = rand(dist, ndims, nparams)\n", + " d = rand(dist, ndims, nparams-1)\n", + " x = rand(Normal(0, 5), ndims, nsmpls)\n", + " \n", + " try \n", + " \n", + " trafo_frwd = TrainableRQSpline(w,h,d)\n", + " trafo_bcwd = TrainableRQSplineInv(w,h,d)\n", + "\n", + " x_fwd, jac_frwd = EuclidianNormalizingFlows.with_logabsdet_jacobian(trafo_frwd, x)\n", + " x_bcwd, jac_bcwd = EuclidianNormalizingFlows.with_logabsdet_jacobian(trafo_bcwd, x_fwd) \n", + "\n", + " @test x_bcwd ≈ x\n", + " @test jac_frwd ≈ -jac_bcwd\n", + "\n", + " for j in 1:size(x, 2)\n", + " xrun = x[:,j]\n", + " \n", + "# autodiff_jac = FiniteDifferences.jacobian(algo, xtmp -> trafo_frwd(reshape(xtmp, ndims,1)), xrun )[1]\n", + " autodiff_jac = ForwardDiff.jacobian(xtmp -> trafo_frwd(reshape(xtmp, ndims,1)), xrun )\n", + " @test log(abs(det(autodiff_jac))) ≈ jac_frwd[1,j]\n", + " @test log(abs(det(autodiff_jac))) ≈ -jac_bcwd[1, j]\n", + " end\n", + "\n", + " neg_ll, gradvals = EuclidianNormalizingFlows.mvnormal_negll_trafograd(trafo_frwd, x)\n", + "\n", + "# a_run = FiniteDifferences.grad(algo, par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(par,h,d), x), w)[1]\n", + " a_run = ForwardDiff.gradient(par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(par,h,d), x), w)\n", + " @test a_run ≈ gradvals.widths\n", + "\n", + "# a_run = FiniteDifferences.grad(algo, par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(w,par,d), x), h)[1]\n", + " a_run = ForwardDiff.gradient(par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(w,par,d), x), h)\n", + " @test a_run ≈ gradvals.heights\n", + "\n", + "# a_run = FiniteDifferences.grad(algo, par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(w,h,par), x), d)[1]\n", + " a_run = ForwardDiff.gradient(par -> EuclidianNormalizingFlows.mvnormal_negll_trafo(TrainableRQSpline(w,h,par), x), d)\n", + " @test a_run ≈ gradvals.derivatives\n", + " \n", + " println(\"Test no. $i successfull!\")\n", + " catch \n", + " print(\"Test error. Parameters: \\n\")\n", + " @show w, h, d, x\n", + " end\n", + " \n", + " end\n", + "end\n", + "\n", + "run_test_suite()" + ] + }, + { + "cell_type": "markdown", + "id": "f0a3040c-30e9-4c3b-b341-303b6b56ac9b", + "metadata": {}, + "source": [ + "# 2D fit: " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "851f5c8b-c3d7-492a-9713-b521de3f5113", + "metadata": {}, + "outputs": [], + "source": [ + "nparams = 20\n", + "nsmpls = 6000\n", + "ndims = 2\n", + "K = nparams\n", + "\n", + "dist = Uniform(-1, 1)\n", + "\n", + "trafo_truth = TrainableRQSpline(rand(dist, ndims, nparams),rand(dist, ndims, nparams),rand(dist, ndims, nparams-1))\n", + "\n", + "y = rand(Normal(0, 1), ndims, nsmpls)\n", + "x = trafo_truth(y);" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "206dd995-5fbd-4610-a8bd-7e4dbd023e21", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m\n", + " Expression: x ≈ (TrainableRQSpline(trafo_truth.widths, trafo_truth.heights, trafo_truth.derivatives))((TrainableRQSplineInv(trafo_truth.widths, trafo_truth.heights, trafo_truth.derivatives))(x))\n", + " Evaluated: [0.22635793963693587 -0.513616865962038 … 1.5776729109677163 1.58459575232127; -0.23836137580693564 0.040373532197889986 … -1.0152282320188306 -0.3313487763308022] ≈ [0.22635793963693587 -0.5136168659620379 … 1.5776729109677163 1.58459575232127; -0.2383613758069356 0.040373532197889986 … -1.0152282320188304 -0.3313487763308022]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@test x ≈ TrainableRQSpline(trafo_truth.widths,trafo_truth.heights,trafo_truth.derivatives)(TrainableRQSplineInv(trafo_truth.widths,trafo_truth.heights,trafo_truth.derivatives)(x))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "bc2593eb-51b9-4f93-8a36-24842e50b843", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "([0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [-3.937466901357094, -3.857765414754657, -3.77806392815222, -3.6983624415497833, -3.6186609549473463, -3.5389594683449093, -3.4592579817424722, -3.379556495140035, -3.299855008537598, -3.2201535219351616 … 3.3153683794646684, 3.395069866067105, 3.4747713526695425, 3.554472839271979, 3.6341743258744166, 3.713875812476853, 3.7935772990792898, 3.8732787856817272, 3.952980272284164, 4.032681758886601], [-3.8911158291683163, -3.811182584444631, -3.7312493397209456, -3.65131609499726, -3.5713828502735745, -3.491449605549889, -3.411516360826204, -3.331583116102518, -3.2516498713788327, -3.1717166266551473 … 3.3828094406870592, 3.4627426854107446, 3.54267593013443, 3.6226091748581153, 3.7025424195818006, 3.782475664305486, 3.862408909029172, 3.9423421537528576, 4.022275398476543, 4.102208643200228], PyObject )" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots(1,2, figsize=(8,4))\n", + "\n", + "ax[1].hist2d(x[1,:], x[2,:], 100, cmap=\"Blues\")\n", + "# ax[1].scatter(x[1,:], x[2,:], s=0.1, alpha=0.2, color=\"C0\")\n", + "\n", + "ax[2].hist2d(y[1,:], y[2,:], 100, cmap=\"Blues\")\n", + "# ax[2].scatter(y[1,:], y[2,:], s=0.1, alpha=0.5, color=\"C0\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d0ca1bf6-660a-471e-95b9-60ebf37b651a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(result = TrainableRQSpline([1.0669729247795674 1.0665714203483638 … 1.0148028503328812 1.0148028503328812; 1.1018282807734543 1.099672516063391 … 1.137266223371498 1.137266223371498], [0.8057555127746265 0.7835876011362414 … 1.1125530413481717 1.1125530413481717; 1.0958092458413617 1.0907537606626194 … 0.8509318613772611 0.8509318613772611], [1.6318577762746813 0.4877690448802739 … 0.09869788610047461 1.0; 1.5812093924712045 0.9972067436802934 … 1.0 1.0]), optimizer_state = (widths = Leaf(AdaGrad{Float32}(0.1, 1.19209f-7), [5.51682 5.51763 … 4.15959 4.15959; 2.63382 2.62789 … 2.61411 2.61411]), heights = Leaf(AdaGrad{Float32}(0.1, 1.19209f-7), [0.134958 0.13171 … 0.13569 0.13569; 0.243399 0.241974 … 0.196538 0.196538]), derivatives = Leaf(AdaGrad{Float32}(0.1, 1.19209f-7), [3.22889e-5 2.15238e-6 … 2.52156e-6 1.19209e-7; 9.66149e-6 4.73434e-5 … 1.19209e-7 1.19209e-7])), negll_history = [2.7487459115295603, 2.864809577422111, 2.7492655146198945, 2.5652422854771997, 2.3690726294874485, 2.406935181036037, 2.305678702130055, 2.2266263995096254, 2.503263024464441, 2.2747910382172822 … 2.0860185424534383, 2.0667363390304545, 2.0833066885648144, 2.1455894188614377, 2.1393790710628338, 2.0224234006861095, 2.068832693488769, 2.172327980602589, 2.2752073562562667, 2.24966830036684])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# initial_trafo = \n", + "# EuclidianNormalizingFlows.JohnsonTrafo([10.0, 11.0], [3.5, 3.6], [10.0, 11.0], [1.0, 1.1]) ∘\n", + "# EuclidianNormalizingFlows.ScaleShiftTrafo(ones(ndims), zeros(ndims)) ∘ \n", + "# RationalQuadSpline(ones(ndims, nparams), ones(ndims, nparams), ones(ndims, nparams-1))\n", + "\n", + "# initial_trafo = ScaleShiftTrafo(ones(ndims), zeros(ndims))\n", + "\n", + "initial_trafo = TrainableRQSpline(ones(ndims, nparams), ones(ndims, nparams), ones(ndims, nparams-1))\n", + "\n", + "optimizer = ADAGrad()\n", + "smpls = nestedview(x)\n", + "nbatches = 20\n", + "nepochs = 15 \n", + "\n", + "r = EuclidianNormalizingFlows.optimize_whitening(smpls, initial_trafo, optimizer, nbatches = nbatches, nepochs = nepochs)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2a2217d7-a22c-4fb9-9af4-d1545ec434c1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2×6000 Matrix{Float64}:\n", + " 0.812807 0.185727 0.243415 1.06568 … -1.27982 1.28642 1.29557\n", + " -0.0359793 0.494229 0.67347 -0.642727 -1.40289 -1.30017 -0.184214" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "yhat = r.result(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e06830ec-de53-4d66-a9aa-6528d4918c32", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mean(yhat, dims = 2) = [-0.017523705544531882; 0.04729161847674135;;]\n", + "std(yhat, dims = 2) = [0.996418500704066; 1.0005505033466442;;]\n" + ] + }, + { + "data": { + "text/plain": [ + "2×1 Matrix{Float64}:\n", + " 0.996418500704066\n", + " 1.0005505033466442" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@show mean(yhat, dims=2)\n", + "@show std(yhat, dims=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e4871e8e-eca5-4d34-96c8-b7e760ca7347", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "([0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [-4.555581723488948, -4.473564995171166, -4.391548266853384, -4.309531538535602, -4.227514810217819, -4.145498081900038, -4.063481353582255, -3.9814646252644734, -3.8994478969466915, -3.8174311686289095 … 2.9079405534292198, 2.989957281747002, 3.0719740100647837, 3.153990738382566, 3.2360074667003476, 3.31802419501813, 3.4000409233359123, 3.4820576516536947, 3.5640743799714754, 3.6460911082892573], [-4.248609302281467, -4.1701421875685085, -4.09167507285555, -4.013207958142592, -3.9347408434296343, -3.856273728716676, -3.777806614003718, -3.6993394992907596, -3.6208723845778015, -3.5424052698648434 … 2.8918981365977228, 2.970365251310681, 3.048832366023639, 3.127299480736597, 3.205766595449555, 3.284233710162513, 3.362700824875472, 3.4411679395884303, 3.5196350543013883, 3.5981021690143464], PyObject )" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots(1,2, figsize=(8,4))\n", + "\n", + "ax[1].hist2d(x[1,:], x[2,:], 100, cmap=\"Blues\")\n", + "# ax[1].scatter(x[1,:], x[2,:], s=0.1, alpha=0.2, color=\"C0\")\n", + "\n", + "ax[2].hist2d(yhat[1,:], yhat[2,:], 100, cmap=\"Blues\")\n", + "# ax[2].scatter(y[1,:], y[2,:], s=0.1, alpha=0.5, color=\"C0\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "90fcb0eb-92e4-4b34-bc85-16662a31b105", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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UFlZiW9/+9vo6OjI7UkjiAKFBAZBEJZ54IEHMGnSJPzwhz/Evn37sG/fPtTW1mLfvn0499xzMX78eKxatQqLFy/G/v37ceWVVwrvf+KJJ+D1evHuu+/iz3/+MwDA7XbjwQcfxCeffIInnngCS5cuxc9+9jMAwOTJk3H//fejoqJCHe+2227T7ZeiKJg2bRpaWlpQX1+PJUuW4IsvvsBVV10lbPfFF1/gxRdfxKuvvopXX30V9fX1uOeee3J0tgiisKEUCUEQlqmsrITf70dJSQmGDBmivj5//nyceuqp+N3vfqe+9re//Q21tbXYunUrjj/+eADAscceiz/84Q/C3+T9HHV1dbj77rtx44034pFHHoHf70dlZSVcLpcwnsybb76J9evXY/v27aitrQUAPPnkkzj55JPx0UcfYeLEiQCAeDyOBQsWoLy8HADwve99D2+99RZ++9vfZnZiCILQQREMgiAyZvXq1Vi2bBnKysrUfyeeeCKARNSAMWHCBN17ly1bhgsvvBDDhg1DeXk5pk+fjubmZnR1dVkef/PmzaitrVXFBQCMGjUK/fr1w+bNm9XXRowYoYoLAKipqcGBAwdsHStBENagCAZBEBkTj8dx+eWX4/e//73udzU1Ner/l5aWCr/buXMnLrnkEsyYMQN33303BgwYgBUrVuD73/8+IpGI5fEVRYHL5Ur7us/nE37vcrkQj8ctj0MQhHVIYBAEYQu/349YLCa8duqpp+Jf//oXRowYAa/X+m1l1apViEajuPfee+F2JwKq//jHP9KOJzNq1Cjs2rULDQ0NahRj06ZNaGtrw0knnWR5fwiCyB6UIiEIwhYjRozABx98gB07dqCpqQnxeBwzZ85ES0sLvvOd7+DDDz/Etm3b8MYbb+D66683FQcjR45ENBrFn/70J2zbtg1PPvkkHn30Ud14nZ2deOutt9DU1ITu7m7d37ngggswduxYfPe738WaNWvw4YcfYvr06Tj33HMN0zIEQeQeEhgEQdjitttug8fjwahRozB48GDs2rULQ4cOxbvvvotYLIaLLroIo0ePxs0334zKyko1MmHE+PHjcd999+H3v/89Ro8ejaeffhrz5s0Ttpk8eTJmzJiBq666CoMHD9aZRIFEquPFF19E//79cc455+CCCy7AMcccg0WLFmX9+AmCsIZLURSlt3eCIAiCIIi+BUUwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOiQwCIIgCILIOv8fGM2/sosHHawAAAAASUVORK5CYII=", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "PyObject Text(0.5, 24.0, 'Iteration')" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots(1,1, figsize=(6,4))\n", + "\n", + "ax.plot(1:length(r.negll_history), r.negll_history)\n", + "ax.set_ylabel(\"Cost\")\n", + "ax.set_xlabel(\"Iteration\")" + ] + }, + { + "cell_type": "markdown", + "id": "11b87214-3a1b-45c5-be53-987903936783", + "metadata": {}, + "source": [ + "# 20D fit: " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "811f9aec-1564-4ff3-8c71-e9dde326b1d9", + "metadata": {}, + "outputs": [], + "source": [ + "nparams = 20 # 1180 parameters in total\n", + "nsmpls = 6000\n", + "ndims = 200\n", + "K = nparams\n", + "dist = Uniform(-1, 1)\n", + "\n", + "y = rand(Normal(0, 1), ndims, nsmpls);" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "50d5a19c-ede0-42e7-b7f7-b5d252737bbd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "200×6000 Matrix{Float64}:\n", + " -0.691889 -3.18616 -0.391503 … -0.603119 -2.09718 -0.411717\n", + " -0.281904 -2.0997 -1.33369 -0.734523 -3.77388 -1.14244\n", + " -2.97475 -1.18127 -1.87359 -2.76309 -1.05432 -1.62987\n", + " 1.3175 -0.119553 2.61351 1.90314 -0.459982 2.49269\n", + " 0.671494 -0.500254 0.927962 -1.43332 0.400622 -0.218028\n", + " -1.56722 0.694309 -1.24866 … -1.70382 -0.145199 0.367099\n", + " -1.81162 0.149531 -0.429881 -2.33556 -0.129952 0.926194\n", + " 1.70038 2.47354 1.54066 -0.139117 2.40609 2.62671\n", + " -0.662593 -1.71752 -2.13484 -1.71732 -0.0436372 -1.77626\n", + " -1.20334 -0.807311 -2.00828 -0.875717 -1.36896 -1.89271\n", + " 0.413894 1.20291 0.892127 … 0.663175 1.26332 -0.106922\n", + " -0.0204932 1.81929 -0.390894 2.03912 0.0445527 0.148286\n", + " 3.39629 0.605152 3.63561 0.856085 0.754889 -0.692226\n", + " ⋮ ⋱ \n", + " -0.797292 0.147695 -0.760741 -0.366496 0.456689 -0.235844\n", + " -1.24231 1.68847 1.67908 -0.333017 -0.843511 1.10423\n", + " 0.769666 0.209863 1.0011 … 0.401832 1.02814 0.718187\n", + " 0.751983 0.631576 -1.0655 0.868159 0.355402 1.00487\n", + " -1.44662 0.933967 -1.09779 0.142952 -0.114114 0.0301199\n", + " -1.1176 0.480633 1.41042 -0.695778 1.66772 1.40929\n", + " 2.68821 0.701662 0.741382 2.52272 -0.131076 2.74703\n", + " -0.604487 -1.09339 -0.97775 … -1.28556 -0.0575132 -0.810362\n", + " 0.651385 -0.297673 -0.576096 0.236252 -0.704701 -0.954142\n", + " 0.861886 0.836476 -1.2262 -0.256936 -0.0466302 0.526047\n", + " -2.48765 -0.685119 -1.56526 -1.35894 1.59132 1.24725\n", + " -1.37291 -1.09921 0.798149 -1.74832 -0.459981 0.814034" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bwd_true =\n", + "# EuclidianNormalizingFlows.ScaleShiftTrafo([1., 0.4], [2.5, -1.2]) ∘\n", + "# EuclidianNormalizingFlows.HouseholderTrafo([1.0, 0.3]) ∘\n", + "# EuclidianNormalizingFlows.CenterStretch([1.0, 0.1], [2.0, 2.1], [1.0, 1.1]) ∘\n", + " TrainableRQSplineInv(rand(dist, ndims, nparams),rand(dist, ndims, nparams),rand(dist, ndims, nparams-1))\n", + "\n", + "x = bwd_true(y)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d261b204-9ec3-4335-8377-27b876a163b4", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp4AAAFfCAYAAADnKswfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAABPcklEQVR4nO3df5QcVb3v/e/k12QmyXTIjCTkZMKEgIKgGBPMSQ4/EhYnJkfReB85skQkPsCzIoQl5qow8ghBYc1Bc44eowS4egmPiCAq4XgEb1gLAb2RC8EMapRggDgDk18znHQnk9iTDP38MVTVt6f3nqrq6a6q7n6/1pq1KtX1Y1f10FP0Z3/3rsvlcjkBAAAAymxM3A0AAABAbeDBEwAAAJHgwRMAAACR4METAAAAkeDBEwAAAJHgwRMAAACR4METAAAAkRgXdwNG8tZbb0lPT49MmTJF6urq4m4OgCqUy+Xk0KFDMnPmTBkzpvr+X5zPUQDlFuZzNNEPnj09PdLa2hp3MwDUgO7ubpk1a1bczSg5PkcBRCXI52iiHzynTJkiIiK7XuuWKU1NMbfG7NjgWyIiMn5s9X1TMpxzrSK1cb2oDYcyGTl1Tqv7eVNtKuFzNGnS/cfc5dSk8TG2JD7cA4QR5nM00Q+eTiw0palJmhL6gcmDJ1AdqjWGroTP0aR5a6z30NVUow9d3AMUI8jnaKIfPCtBLT2A1dK1AqhdU3nQ4h6gbHiSAAAAQCR48AQAAEAkePAEAABAJHjwBAAAQCR48AQAAEAkePAEAABAJHjwBIAE27hxo7z3ve+VprfH4Vy0aJE8/vjjcTcLZXKw/5j7Uw3nAYbjwRMAEmzWrFnyL//yL7Jt2zbZtm2bXHjhhfLRj35UduzYEXfTACA0BpAHgAS7+OKL8/59++23y8aNG+XZZ5+VM888M6ZWAUBxePAEgAoxODgoDz/8sPT398uiRYuM22SzWclms+6/M5lMVM1LHB0jFzsTTymOkURhrqWW7mOltLOSEbUDQML94Q9/kMmTJ0t9fb2sXr1aHnnkEXn3u99t3Lajo0NSqZT709raGnFrAcCOB08ASLh3vetd0tnZKc8++6x89rOflSuuuEL+9Kc/Gbdtb2+XdDrt/nR3d0fcWgCwI2oHgISbMGGCnHrqqSIismDBAnn++efl3//93+Xuu+8u2La+vl7q6+ujbmIilSIqLcUxwsS3Qc4XdfQdpk22bSsloideLz++8QSACpPL5fL6cQJApeAbTwBIsC9/+cuyYsUKaW1tlUOHDsmDDz4oTz31lPzyl7+Mu2kAEBoPnlXm2OBb7vL4scV9oV2KYwAojX379snll18ue/bskVQqJe9973vll7/8pfzjP/5j3E2LhS16rfZq5FJfn+kYo7m35brn1fhe1joePAEgwb7//e/H3QQAKBm+zgIAAEAk+MYzoDDxc5xRdSnOF+YYxPIAohR11Fusckbj5epWUIp7a5v7PWnvD+LDkwIAAAAiwYMnAAAAIkHUHlCYGDnqyDlI3F2urgKjuVbnPET0pUG3ByA5yhkt+x07SBQfdVwPOPjrBAAAgEjw4AkAAIBIELVXGFOcGiRWTWJXAeLg0uJ+AvHwi61fO9DvLs95x6SSHdfmv44M+O5nqpKv1AH5/eaJR7LwlwoAAACR4METAAAAkSBqrzCVHqf6VV5TmQ2g0vhFvGHiddtxw0TftvPZjuEslzpeD1NdP5qYvxRV/n4qqetB0pX1L/szzzwjF198scycOVPq6upk8+bN5TwdAAAAEqysD579/f1y9tlny3e+851yngYAAAAVoKxR+4oVK2TFihXlPAUqTDkHpAcAkWiqnIuNXm1zmTt0RbqOzKOY7z3IOcJcd7Exeanft1LfO4xOovp4ZrNZyWaz7r8zmUyMrQEAAEApJerrpY6ODkmlUu5Pa2tr3E0CAABAiSTqG8/29nZZu3at++9MJsPDZ8xsVebMsw4gqUoZi9qi8VLE62Fi5lJE+6ZK9iD7lZNft4goqsmpWI9Woh486+vrpb6+Pu5mAAAAoAz4ugoAAACRKOs3nocPH5Zdu3a5/37ttdeks7NTpk2bJrNnzy7nqUMzRcdJHMw8TJtK0X7bfkm5HwAwGn4xq60SPAxbpXoYYdpRbHW6XleKNgdhamvU0TfxerTK+uC5bds2Wbp0qftvp//mFVdcIZs2bSrnqQEAAJAwZX3wXLJkieRyuXKeAgAAABUiUcVFcTJFx0mMk8O0KYndBpLSDgAQiWZO8iBR9fbdB0VEZF7b1KLOYWPbVkfppnUnNE7wPbZfXB+kHaaq9nJWuFPBHj/+8gMAACASPHgCAAAgEkTtNSIpsXZS2gGgtpQ6Yi3F8V470O8uOxF7VAO36/jfaYdpnYj/HO/D14fZLwzmXK8OPAUAAAAgEjx4AgAAIBI8eAJAgnV0dMg555wjU6ZMkRNPPFFWrlwpO3fujLtZAFAU+nhWmEofjqjS2w9E7emnn5Zrr71WzjnnHDl+/LjcdNNNsmzZMvnTn/4kkyaVb0aZahNmNp9S90209dv0G7IoyPBGpRjSyDm27tdZiuGUbO2IekijJPbvrWU8eAJAgv3yl7/M+/e9994rJ554orzwwgty/vnnx9QqACgOD54AUEHS6bSIiEybNs34ejablWw26/47k8lE0i4ACIIHzwpT6njaib6DzHJUipiceB0oXi6Xk7Vr18q5554rZ511lnGbjo4OufXWWyNuWXTKOXuN6XhhInq9fZB2mqJoHa8HmfGolPfAb3ik4ds4sy2JiEw9MrTe1uYgsbvpHKWQ9OOZVHOcz1MAAFSINWvWyO9//3v50Y9+ZN2mvb1d0um0+9Pd3R1hCwFgZHzjCQAV4LrrrpP/+I//kGeeeUZmzZpl3a6+vl7q6+sjbBkABMeDZ0IFibv9Xg8Sax8fzL29bWmOF6Uktw0olVwuJ9ddd5088sgj8tRTT8mcOXPiblKsSh2vFxtp2qJj0yxANn7nC9tmvxmIdIyvjzFHJgVqz3D6PMVW1JtGEgirFMdImmq6luF48ASABLv22mvlgQcekEcffVSmTJkie/fuFRGRVColDQ0NMbcOAMLhayIASLCNGzdKOp2WJUuWyEknneT+PPTQQ3E3DQBC4xvPhLJFx36RctiYvGHC2IJ1pjg/iCDnM21jO1+Ya02KJMb/SWwTgsvlcnE3oSrYosti425b9O3Ez2EjZ4ceuN0Uow8/9rxJUwvOnVdtro6RF8GLd7xima5Ft7PU3Q3C7FcK1VxZHif+CgEAACASPHgCAAAgEkTtAZUzrjQN4h6kHY6jA4Pusik6H40oBpCvpvg3ideSxDYBSeEXpwYZ/N0vhg1yDF1x7mde29QRj2Grat/ef9BdNsXgOqLX5wgSnzvtsO1nEybC9hvgvtSxPPF6efAXCQAAAJHgwRMAAACRIGoPKExcGaQqXB8vzLGdAd9FRMaNrRMRkaaG4uMAv7baXjd1Dyg20tXn0NdX6m4D1YiKddSaMBG330DrIvnRsWkgcltcrKvPbeccaZ2IeV52HXdrtohbt8+JufOq3lX0HaRNptf1tfrdD9t+WpA54f3aVOqJBBAd/lIBAAAgEjx4AgAAIBJE7UXwizfLOde534DvfvO62+j9dJW85kT7w7c3CdImZ31+XO9/jGoX5rpr6b4AIsVXQWtBImCHXxW3iDm6t1Ws63Obqs+DVIWbBqzX2+fF1wf8r8Vhi+Vt9HWZ5okPUqlv2ibM+2M7tw3xevz4qwUAAIBI8OAJAACASBC1l1mQ6Ns0Z3mQCNWJxPP2a/D2K7ZCXG+bOepFNsdUAq/P470eLvI3Rfr63LUaI9fqdQMi5sry0R5rOB3vmiqsbVXXtrnaTXGxLV7X6x94sdtdXnHa9IJjPP6Xfe7yJxtbjee2zeHux9Q+2/62yD8vmn9H4ba2eef9Kt9t29raZ4rYSzH6AcqDv3AAAACIBA+eAAAAiARRexFMMXKQSvZSVCjreNqpMtcRuK0iXTMN2K4r1m1tsm3j104dn+tzh5mjPskqqfq+Wu45qku5ok5bZLtjf8a4fOaJTYHbYIuU//vP/ywiIl+58FRjO3TEfc3iUwrad+fWV911i2ZO8z23X7weZOD83+zuFRHv+kXyr8k2N7zp3LZuBbY2BT1ukGPYhLlHKD/++gAAACASPHgCAAAgEkTtwwSJTXWlt2me9LAxpl9crxmr01VRoI64bXO4m+Z7D/O6jW7/8UGvHbb7dXysd55KVkmxdZxtJeavPFFV+0Yx77Z+/cNnnjTi8XTc/cmzvWpyW7zuRNUi+RG7qZ02Tixtqm4fTle7z041uMt/N2lo+bc9bxpfP7etxV3W1+LsZ4vJ9bb6Prb/4s/ucseHzhAR++D2+h7pdvgNIG97X/Wc9n4DxxOlJ0skfwHuvPNOmTNnjkycOFHmz58vv/71r6M4LQAAABKk7A+eDz30kFx//fVy0003yfbt2+W8886TFStWSFdXV7lPDQAAgASpy+VyZc07Fy5cKO9///tl48aN7rozzjhDVq5cKR0dHSPum8lkJJVKyb6+tDQ1NY24bdzCVjabtvcbYD7IeUwV68PX67hbx+Detjm1rdcboxQRqakqP8wg+2FVUsV5KdXqdRcjk8nI9OaUpNPJ/5wpRpI+R0sR3dsqs03nsQ3iro+hK7ad+NZWxa2Fab+OhW3H8Bu8/o3+o+6yLap2rtEWa+v1Trzu156gnH1t86yHYXvf/Npne0/83kPb7yUDywcX5nO0rH+RBgYG5IUXXpBly5blrV+2bJls3bq1YPtsNiuZTCbvBwAAANWhrA+evb29Mjg4KNOn53eWnj59uuzdu7dg+46ODkmlUu5Pa2trwTYAAACoTJFUtdfV5VdG53K5gnUiIu3t7bJ27Vr335lMJvEPn6Ws1LUdwxY/O3RcboutdTW8jrt1rO4dw3tv+g55kUeq0YsanOONpouBO/C9JZnxux9B7pdfm4JsW4mxdaW0E7WlFHGljteLjcFtEb0TsQeZ4z3IXOx+bcu7lsahc+puADpe19G4jsz1oO8jrRvOVHFuu7f3/2GPu7z0lKnGNpna5tclQMQcd4eN6/0i8zAjHqD8yvrg2dLSImPHji34dnP//v0F34KKiNTX10t9fX05mwQAAICYlPVrkQkTJsj8+fPliSeeyFv/xBNPyOLFi8t5agAAACRM2aP2tWvXyuWXXy4LFiyQRYsWyT333CNdXV2yevXqcp8aAAAACVL2B89PfOIT0tfXJ1/96ldlz549ctZZZ8ljjz0mJ598crlPHUqYfoN+M/v0Hfb6sjRPNvdV0ccYP7bwHJpuk+6feXRgqD+L7r+p+2Q2T/HOrY+ROept0/j2vvo6dNsaVc8HvY2prbb2519r4f09buhnOqS4oZXC9G8Msm0p+ktWYj9RoNTCDE8Tdigb0zA4ul+hrf+i37BBtnPb+nuajqvP/cCL3e7yov5pBeex9T/VsxHp2ZT0uZ1j2PqZ/urVg+6y7gfqLOtrvePhXe7yDUsKZ2Ma3iZnxiVb/1LbcFZTjwydU8+C9Klz/s5d1v1I502a6u2n2uocT987fQ5bO0zvLUMolV8kfwGvueYa2b17t2SzWXnhhRfk/PPPj+K0AFDxnnnmGbn44otl5syZUldXJ5s3b467SQBQNL56AYAE6+/vl7PPPlu+853vxN0UABi1SIZTqgTh4tuRY1NbvK7peNx0LB2pj1ebHlHrnfPkRfsqXs+PsHWbvcjcOZ5ep9s2buxYtd/IMyVljh4vaNtQOwpnK9LbHzvuHaOx3jtfw4TgMUepZzzyO0/Y4xKvo1grVqyQFStWxN2Mkggys4yzTdiY0xSZhx166c6tr4qIyKKZXgSu410dk2tOzKzPo4dC0ufQMbnmxOO2iFjvlxdVGyLnIPT9uOOpoVj9/Hd61/3gqgW+x/3xVu9+XLP4lILj2iJ/3WYn+r7rkrON5wsSnzvb2Lo3aGG6VhC7lwcPngBQRbLZrGSzWfffzAAHIEn4GgYAqggzwAFIsrpcLmcrKY5dJpORVCol+/r8J50fSSkqim2RsqOpwfvyuBSxqo7abRXnvW9XsLeoeN02W5Gmj5E+MhQl6IjbxnRdpqp+27Yi+bMsmba1zbCkzxN1bG36/YmzSj2qbgW1IpPJyPTmlKTTo/uciUJdXZ088sgjsnLlSus2pm88W1tb5eWuXpnS1BR5ZFhsXGnbz7Zex7BOfGvbTzPFunq//9zhzdpjm4nH1m4THcHrCvDH/7JPRERmp7wq7q60t62O/20zCTl0JbjeVvvKhV6luinCdmZxEvG6IIjYI3+nwt3U7UDE/l4490Pf2yDdB8JUp2vFVrITu48szOcoUTsAVBFmgAOQZHxFAgAAgEjUxDeepYgg9TFMFeD69bAxrKlSWkfLOnJuavC+4p8xdehbDR2dH1PLXthiPp+IVwVvq0j3uxbb67b1ftX8SYyRTecO255SRvNE6rXl8OHDsmuXN5j3a6+9Jp2dnTJt2jSZPXt24OOkJo2XphgiwmJjybD7maqYg8StzgDmIl7Vuo6LP3zmSe7y9t0H3WUdRWvb+w8WrNPn09G3Pvbs/UOf2DpyXv3wi97rKoL/1Hu8/UwRto7z1/y99zui4+nf7O712vT8G0PHVQO33/9zr536GDr6dqrh9b5OlwERr9JdJP/e6ffKaaut60KQqnbTOWzvjwnRebRq4sETACrVtm3bZOnSpe6/165dKyIiV1xxhWzatCmmVgFAcXjwBIAEW7JkiSS4BhQAQqnaqvZyVh3rYzsxuI7Awx7D1L5iK7pNbRvePr3e2V5H4La5000xuT6WrYq+2LgeiEIlVbUXo1Sjg5RTuSqGTZXuIvmxrmn9aNqzY//QuKm6Yt02T7me69xhm4ddH0MPZK8jeOecuv062p/b7BWd6e4Ew9s+vP22gdlNA9nrY+iqfL/r0tdkattwpnboe6SFeQ9tg9fDzPndOJTJyDtntwT6HOWvPAAAACLBgycAAAAiURV9PE1V4eWMbPPO01DcefwiZ1tsbdpeR+M6lrfF/3lzsQ8WDgCvX9dtMkXitnbaInhTFwLd/vGWyyaOB6pXsfG6XyRuG2TcNpi5Lao1batjWF19/nfNQ+udSnERkRuWeIO163O/0ucN9O9Ujutj6SpzPSi8niP9qS9c4C47Vd22qnZdcf6Z+7a5y9/8uDdPumlbHed/8rv/213+7bpl7rJpRADdZr/B/nUUr2N329z2+r0wjV5gi8n9Kt/9fgdKxWlzOSvqoxj03jnumMHgx+cvOAAAACLBgycAAAAiUbVV7cUqNtJNShQcZAB2Uwyu97NF96aB3m3XGuR++B0jTkl5P1F+VLWPjl+cV+q52sPsa4vUTdXYQc6tY9ivPekNnq7nS3eqwb/zbJexbaa51UW8CnAda9vmXNfV6aa43haTX/2NJ93lP3/3n91lZzB5fT4b3Q49kL2z/oWd+911mz+72F3Wleym6nlb5b+OzG3vp7M+yNzwUf0O1pown6P8RQUAAEAkePAEAABAJIjaR8kUbZczmi1FVwDNmaM9zPzsQY7rF+3rfYmyESei9njoGNM0oHiQqDRMzG8bjF3Huk6Vs20/2wDrOlZ34mcdEetYXsfTuvrcoedq1+fWbdL76Xj88z/xKuIdX1jxTndZD+iuK+OdSFxXkz/zsje4/fnvnOYu62jfNCC9qcJcxP6+OYPohx00vpTxeZA2Y2RE7QAAAEgcHjwBAAAQiaoYQD5OpYyJg8x7Xuz5dKW6PrYTsYepQg/bjlJfSxhUpwP5klKpaxvQ3W/bYs9hE2Y+7g+f6cXkOqLXnBhcn1tXsusB2L+x6v3ushOZ22J5HaPr+Fyb/64TC9bpeF1XuO/bd9hddiJ2HaM7A+EP309H4qZB3HU79cD0tsH33Sr508T4umaLxP/7z/8sIiJfudA8UL+N3+gHKA/+EgMAACASPHgCAAAgElS1j5KpMtsW7/qtDxJxa8VGx0Ei/dEKEnE77dCD1GtB7h0wWlS1l1cc0b4pQtVzdNuiXKeKXFev66pxXU2uI+xrFp9ScG5nUPbhx7DFuk6bdNT+Rp8X5+t52/U88Ht7vW2cqF1Xm9sGpNfX8qtXDxacT1eyL5rpLeuuAtd97Ax32YnpdfcAfa36nuv3wvS6bYB/PRqBXzyuRwTQbMcwHavY39ekdGeJElXtAAAASBwePAEAABAJqtqHCRvpOtuMJgr2294WOfsNXm+bf10zHSPIXO2m/fXrtnZopog96TF6pQx6T9cExM0Ud4fZz8Y2ELwpWrWdW0e5OnJ2BoW3ReM6DtZRuo6O73hqKCrX0bhmGwjeGbxe6/jQGQXrho7tLeuB7J0uAk50LpJfqS7irX/gp79zly9Y8q6Cc3ztnt+6y//jixd6+137D8b2O3G8vl+fuW+bu/zPi1vd5U+e7S07bO+Jjd/vVbGDzZciGq+VeL1Y/EUCAABAJHjwBAAAQCSqNmovddSoK8FN8XOpB10PwplnvTGvMj14rC3ixeq6uv3ogBdLjBvrrc8c9dY729vmZLedb6Q2DC2PvuK+nPc8zNz1cUbcxOuI22jnzw57jjAVyjqi9zuuPsbjf9nnLuuB1PVc7U48rvdzB0mX/Kpv7c6trxa8rs+n3XT7z9zlH3z9MnfZidj/512/cNc9+d2r3GVdka7jcxM9gLyuotddCHTM79xTPd/7vVcsMB7bVPGvo3Hd7eA/d3j3zhafO90sbKMVRBF9h/0dLrYrSqmPEQf+OgEAACASPHgCAAAgEgwgH5COUHWk7NCxcFQxp19Fun69qcH7Kl63P0yVtin6LnawfI2B4ovH/Ro9BpCPh180aatut8Xgpmp3HfvqQd51FbopgtfH0oPJazpmNl1L+y/+7K7Tg7FveMRb/0/ne21yBn1/5uU3jee7YYk3D7mOzLWzzxyK//Wg8jNavPhZt+PHW717Y9pWn09H2Ksf9uZi17H71d94UkTyI3w9yL7umqDvqXMfg8yRHiZK11XyfnO/6/fbtq1pP9u5a1FiBpC//fbbZfHixdLY2ChTp04t56kAAACQcGV98BwYGJBLLrlEPvvZz5bzNAAAAKgAZa1qv/XWW0VEZNOmTeU8DQAAACpAooZTymazks16syxkMua+NXHz688Zpn+j7Ri2oYl0H06nHaY+p8OPa9vG1G8zzNBQzpBOIiLNk81DlNjuh9Om8QFGTar0vozlan8l3gsU584775RvfOMbsmfPHjnzzDPlW9/6lpx33nllOVcShmmxnVv3zzTN9qM5s+mI2GcM0n36nHPqPn+6L6fe1q+fqO4jmdcmNfPP53/i9ZdcuuKdIpLfP3PzZxe7y197cpe7fN3HzDMazU4NDU2k+1bqPqO6f+nBA177v/L/LCo41m97vP309b24wxviSQ+59Mn/6/0iIrL+8ZfddbbhlM5ta3GXnX64ejYj3T9Tn1v32TVtr4fJsg2ZVYr+maZ+xvT1DC5Rf7U6OjoklUq5P62thdNqAUCteeihh+T666+Xm266SbZv3y7nnXeerFixQrq6uvx3BoAECf3guW7dOqmrqxvxZ9u2bf4HMmhvb5d0Ou3+dHcXVt0BQK35t3/7N7nyyivlqquukjPOOEO+9a1vSWtrq2zcuDHupgFAKKGj9jVr1sill1464jZtbW1FNaa+vl7q6+uL2rdUbHG4FiZe99vPRkfgtjY5UbWO4nWkro9hiuhtx+477MVMTQ3mXxHnPPr1IF0MTLMfBVGKSDnOuD7q81V61wR4BgYG5IUXXpAbb7wxb/2yZctk69atBduXostSFLGh7Rx+0aVt9hrT9vMmTXWXdTSuo169n97GdD5Nx/V62ZmJR9Ox9St92YLXRbx4/J8XmyPnN/q85aWnTDWez5kh6YWd+911Lz70sLv85MO3FWwr4kXwznBMIvlDJen7rLfRbXJidx2v6/30PdCcYZZ09wbbTE86XjcNn6XZht3Ki/GPDG1je4/174OpS8bwZdP5bG2qZaEfPFtaWqSlpcV/QwDAqPX29srg4KBMnz49b/306dNl7969Bdt3dHS4hZ0AkDRl/Sqkq6tLOjs7paurSwYHB6Wzs1M6Ozvl8OHD5TwtAFSdurq6vH/ncrmCdSJ0WQKQbGWtar/55pvlvvvuc/89b948ERH51a9+JUuWLCnnqYsWpKLbb78gMWfxM/j4HFslDrZ43VQxr7fV1em2aNwUk+89+Dd3OdXoRQq6K0CYCv5SxMWljpzDzPQUp6S3D8G1tLTI2LFjC77d3L9/f8G3oCLRdFkq58wtftGlLRqfI4VxqY5jbefQ0at7LEusqtuhI269jTMrj35dzxL0zY+f7S7ryPyLm35X2FBVva6r5HUUPbf5qAy384+vu8s/2HSTsZ363CJDMyjpiF7Li75VBG+ameifvv6Uu2769Mnusq7Q1++Lc0/1Pf/Khd616vfHtJ+Id88/fKYXy//nDq/NumuFaSQEW6TuN2qCjV83kpG2qQVl/eu0adMmyeVyBT9JfegEgKSZMGGCzJ8/X5544om89U888YQsXrzYshcAJFOixvEEABRau3atXH755bJgwQJZtGiR3HPPPdLV1SWrV6+Ou2kAEEpNPHhGUeEb9hymWN1voHURcwW7LcruO/Q3436mqnb9uq2qXQ8W3/j2MfSxmqd4EX1+db0XKRwfHFTLubw2iIgcGTBH/lGzvRfOctKrxpPePoTziU98Qvr6+uSrX/2q7NmzR8466yx57LHH5OSTTy7ZOcLEgEFiQr/q9GLPp/fTsaiOZE1VyrZqeL9Bx20V0f+07hfush6AXQ9a79CV6jq21r6xamgAdj1gffsvvAHfnShbRGRus9eVQlfJu/H524O5i4jc//wb7vJdl5gLg52Ifd8+r/5CDwSvo/s131jpLpva+tt1y9x1Ohq3DQrv+M3uXndZR+P6fdMDyOv7YWIaXWA4p022SN3vd8rG9rtdy/G6VhMPngBQ6a655hq55ppr4m4GAIwKX4UAAAAgEnW5XC7nv1k8MpmMpFIp2deXlqamJv8dlGKjxiADyOsKcGd722DoYeY9DzvHe9+hoRijsX7kavPhbTZtE2TQeH0MJ5ovdhQAva8+t6bbkeS4uJyxNpF5+WUyGZnenJJ0OvznTCUYzedonGyDcNsGDjett21rq2o3xammqncRr5I6rF+9etBdXvP3s93lx/8yNAe6nltdV5DryFyvN1XD2waC19vq+d5Nc7wbI3wRufobT7rLpi4GeqB457jD6Rjcuec6Rtfn/teLvXba3ovhxxIJ//tjEiYaL7ZivVoq3cN8jvKXDAAAAJHgwRMAAACRqNriolLEkvZj6Bh5TMG2uqJbV3FrpgHdbTG5Pp42Y+pEEcmPY+2RureNafvxuqr90IDa1jvejKkjD0pta4dmqp7X1ev59847xvjg07qHUoooO0x3ilIdOwzieiSdKe4OE4kO38Y2cLzpfHo/ZyBxHXnq+FYPNG6LvnWlt4mO2nXM6sTSzpznw+kB5HWcrWP18985Le9Yw9vpVM7b2qQHbtf38DvPdrnLOl7XnHumq/o//5MX3WVd2W8afF+3WVes63v+Rr/XFUBXvpvo91hXrYeZoCDM+mJj8kqO14vFXyEAAABEggdPAAAARKJqo/Zi40VbZG6LwU3n89t2+PYmtjnSdZucZeuxVNp0RO033mfudD3PevrIMeO2foPeZ476V8k77dDHCDPPfXm7U4xeFLF2kPtFvI5SC1KJa6oqtm2r427T3N22Ad/9qtNtVdC26N4U89+59VV3+ZNne3GxE2uL5FeDOzGybr8+nq4Q15G5aUB0fVwdmetzP/3UTnf5xR1Dxz544KC7buo7vPPp/TY84g1O78T1X3tyl7Gdb/R59/FT7/HmQ9ecOF7H9Xpeek1ft7Os763tfbN1Y3Dur77POl63Vbj7xeRh1yMY/iIBAAAgEjx4AgAAIBIVMYD86/v/S5qamspa4esX3+r9TBG8aXB12zls5wkygLw+zxFLtbt3jDrjeh3dO8fTkbqO2sdZjuHsZ3vd1mXB1C0gfcSbA95WOR91XFzse4XKwwDy4ZV60GvT8WyV52EGkNdt09XRthjcL6LXg8br2NfUDts88s5A8SLmQdp11buek11Xi9/xlBeJ6yp4JxLXVfb6eJopMtdV4zraN51DJL/S3jQHvR4g38bU7UEPJq+r3T98pjnmdwSpQjchOh89BpAHAABA4vDgCQAAgEhURFX7+LFjAsWZo6nw9YtTtaYG72t5p/pcx9dhz+0X89ti/EZD9bztHuRVtavj6YjdxFbZ7zdXu67K1/dr3KDXfufYLVO8qCXIHPVR8Pt9q6R4nW4BKLUglexh4ktbdbrpdb9tbefW62wDzJsiWR2ZB6mod46xvf+gu05H4x0f8uYe35HyontnQHQdjf94q5q//F1eLO8Xca9//GV3+Qsr3lnw+vA26Wp30zrdDtvxnG4BtvnZ9b3VFee6C4TjmsWnuMt6VAG/UQr0+1rsfOlakGOEGb0BQ/grBAAAgEjw4AkAAIBIVERVeymrMW3CDEpuqjIPMmh8sWxRqWmOd9u87rZK+zDH0O3Q8bnftn5s88tHHRFXayRdrddVKlS1x88vog9brexso1+3zd1tGiDeFsXrqnY9uLuOl51qd31uXS1uqzLXFex+bNG3aYB1XUWvK+N1RO9U1Os51DVb+/Ug8w7bMS689nvu8u03/Td32Rk439aNQSt1dXqcMblz7nKNChE1qtoBAACQODx4AgAAIBJE7aNUbEQfJvLU0bdpwPYwg9Tb2mTb1nZu0/a2geJtMb5f9wRiYUSBqL28wsaATiSuq8lNr4vY51w3nU+3wxalO+e0Rbq2/TRnznLbnOa29ukY32GL821xt7Nex/Z6kHrdJttg8e62lkHobcc2DV5vm19eR/6f/O7/FhGRB679B3edfu9t72GYAeK1YqvdTRMN6G1qvZKdqB0AAACJw4MnAAAAIlERA8gnjaliO8g862GiY1tUbaqoPz5ojq/DVLjr42aOHi/YR0SkeXJhrKX308dtmDDeuI2+B86ybbB5W2V8KSJ407GJ9oHSCxtBmuJzHXmaYk4RcxSqByfXley2Nv3njsLB2HWVto6nTRXkIl70bZur/bc9b7rLTkW3iBer6xhan1sfT0fwmhOl63Y+87J3Pn0MXWX+f6/+kIjkz63udBkYvl6/P4vWbXGXzz7TuxbHXZec7S7buik4Ebt1YoAD3qJt4HlbtwzTuU0Rve33wTZxgW0bk9EMTl+t+EsLAACASPDgCQAAgEjw4AkAAIBI0MczIL++mkH6I4bp72nbT3P6c+q+nH5DL4nkzxR0dOBY3rFE8vty6nOb2h9kGKb8YZMKr8U2C1I5+1zSnxNIJtOsQ8X2r7P1B9V0/78Pn1k4BJLub6jPp/s6PvCiN5OQ00czr22qn6IeFkkPoeTsp/tnntvW4i7/Znevsf26r6lzvff/3OuresOSU43t/K9ffMFddvq26vY4wyOJ5Pf31MMpXfexM9xlZ9YnTd87fV2a04/V1o/3a0/ucpf1PdX9PR2291i/V7pNfn1DS62W+3Vq/PUFAABAJHjwBIAEu/3222Xx4sXS2NgoU6dOjbs5ADAqNRG1FzukkWbbzxkKyBYXBzmGiWnYJJH8+Nw0XJJtdiFb9D1usK7wWGo0Ez20ko7gne1t5/OblUjEu8b8GY+8a21q8H49/e5dKd7jUhwDlcN5v21dWZJiYGBALrnkElm0aJF8//vfL+mxw84qVMyxgxzX1I7RzFjjrNcxuo5bbW0ytdk2LJLexhQz37n1VXfZNuuQjrOdSFy/rumhlbTH/7LPXV4hQ0Ma6RmK/mndL9zlx9Z9yF3W9850bD0DkY78bcMi5Q2BZKDPYXoPdXSu2/aVC72uArZz+81c5DcsUpD/Dor9b4V4vVBNPHgCQKW69dZbRURk06ZN8TYEAEqAB08AqCLZbFayWW8O7UymcA5wAIhL2R48d+/eLV/72tfkySeflL1798rMmTPlU5/6lNx0000yYULhzBTlVIrY1DYLkKmy3FZN7tcm+ww/5m2c8+go3hava6aZgo6KeVsdd9tmU/Kj9zPF6qYIP6xSvMfE67XFb2SGStXR0eF+S+qnnDFgKePIILG75sS+tqplHQubZkqybauPp2fOMbVPz0Ck99NV6Kb4X1d/6xmKbFG7ZuoqoON1PWuSKX7W91a3U0fcuvJdt09fr8MWn5tmmdJskbrtvQozEoIplg/yuxr2d9Dv3LUcwZftE/ell16St956S+6++27ZsWOHfPOb35S77rpLvvzlL5frlABQEdatWyd1dXUj/mzbtq2oY7e3t0s6nXZ/uru7/XcCgIiU7RvP5cuXy/Lly91/n3LKKbJz507ZuHGjrF+/vlynBYDEW7NmjVx66aUjbtPW1lbUsevr66W+vt5/QwCIQaR9PNPptEybVvh1vCPJfZN0tGyKxI8PDhasC8ocL5srbXWsfuTt/caraN+pUh+pzePGeuudc+tq8iOHvJhjxtSJ7rKO6Mc3FF6jrbvB8bxKdS9eMFUVB+mmEEaxleqVWOFuH7QfSdPS0iItLS3+G1YxHVWbBgO3CRJ5hhkYXEfpTjv0On2Og43mQc51NOxE5baoWg/GvvSUqe6yE6Xr/Wzxum1geSdKX3HadHfdHU95A7DfdcnZ7rK+Rmc/XZ2vB5vXVfm6TXrZdN22bgqmKN02gLwtojdF1WHj62Lj7qj3qzaR/UV95ZVXZMOGDbJ69WrrNh0dHZJKpdyf1tbCISoAoJZ0dXVJZ2endHV1yeDgoHR2dkpnZ6ccPnw47qYBQGihHzyL6ZvU09Mjy5cvl0suuUSuuuoq67HpmwQA+W6++WaZN2+e3HLLLXL48GGZN2+ezJs3r+g+oAAQp7pcLpfz38zT29srvb3mOWMdbW1tMnHiUETb09MjS5culYULF8qmTZtkzJjgz7qZTEZSqZTs60tLU1OT/w4lEDZidbYvdk72IOfWEeoRtdxoiFNtEWvfYS+i0FXkznp9rCBx91E35vfaGTYmNx3Ddg9M1zWaONz0vqE2ZTIZmd6cknQ6us+ZKMXxOVoKQebUtkXtzr5+VdDDj+FH72frKmA6nm0ge32N9/9haL50PRe6jsz1frbjObG7af52EW9Odts2tmp/Hefr/TTnuvX5gtxnZxvdtg+f6Q2Abxs9wDSwvy2iN3WnsO2H4oT5HA3dxzNM36Q33nhDli5dKvPnz5d777031EMnAAAAqkvZiot6enpkyZIlMnv2bFm/fr0cOHDAfW3GjBnlOi0AAAASKnTUHtSmTZvkM5/5jPG1oKdMUkTkF+va5nu2Rbmm7W2Rs64K15xo2zbX+fgA86g759Hn0Oc2VaHb2hykqjqvMv7tff1GDAirEivSK7HNNlFfy2jPR9SefGEH3jYNpO4X9eptbAOY26JczbSvjq11tbiO0k3barZ54k376mhcs0XYTkW6ft1W2W+rTnfW68hcV9+bukLoNoet+DZ1xQjzHuv2mwbyRzhhPkfL9ldh1apVksvljD8AAACoPZX91QoAAAAqRqQDyFeyMJF5kNdtsbrDNme5X5QYtjrdidh1tbyO6Pce/Ju7nGr0IgjTHPV5c7mLOT7X0b3p9SDrnXtgn9ve/71Kcpxd6YPeR33uJL+XCM8UkweZd9tv7nHNFqU7bHOyvyb9hq3zOXOZ22Lmaxaf4i6bKrmt13TEW378L/vcZT3ou0OfW1+rddD+3YXXYWuH7iqgz+1sr89tY6rsnyP+1fB6vT5GsV0riNXjwSc2AAAAIsGDJwAAACJRc1F7qWNMJ6oOMjd2fnxeeDz9uo6k/eZAD3JuXbWu55V3mAajFxFpnuKtN1XX553bkl7p+6UHsm9qGGc9bsGxfY4bRJIrrEvRNiJnJIkp/gwizPZ+29pe94tyg1Rx2wZ0N0XmOuLWx7MNxu64c+ur7rKOtRfNnGa8Fie2tsXMpkHXRby52vXrzjqR/O4BK6SwEl+3w3atmt+c67b22+ZtN52nnDF62FEWkI+/VAAAAIgED54AAACIRM1F7cXGkXo/PQi6qbp7XICB201sr+v15ipy8zXZqtr94mC9ny3+L/Z8OtL3zu1f1V4pMXJS2lmJ9w7VpVwRZLExp20ecr9tdYxrG2hcx76meeJtc7nb5m136AHm9aDwunLcNGC7U1k/fFvbnOuzUw0F16HPHWQ+eydit8Xrtvtv6t5gu/82flXtpf5dJF4fHf4iAQAAIBI8eAIAACASVRG1+80hXmqmwcrH+xeW5zHNxR5kwPf0ES8+mDF1oojkV4o3T/YiDFMFuYhIw4TCinndnmOq6D3MXO2abfD3Iz7zuccZC1dTPF3p7UflK7aq3U+YQcJtA6b7xbBh4l0Rc3QfpJ2mKnm9TkfmOhrXUbRpwHbbnOu2wd2d9baB9W3vYZjKcr2taTlI1wTNL66PKnZHePx1AgAAQCR48AQAAEAkqiJqjzpW1BFxsTF//jYjH0NXluv50p1zj7dWoXtvr20AeSf6PnZcR+3etrodpq4AQeLpo5Z54M3z0ccXd1d6PF1NXQVQ+UoZadqqnP3OkTcfuRIkBg+zn98g6KZB3odz1uttbQPMv9F/1Hhs597YugH4DYCvo31bXF8s24gApvsfZAQC0z2PKl73m3SAOH9k/HUCAABAJHjwBAAAQCSqImpPsqOWKm5TLGqrBPeL9m3bajpe19s4UXvzFC/O8JsbXq/Pn2e9sFJ/+DHGjS0cQF4PyK//XyjsSAHVIkxkTryOWhCkylwzVdTb5hD3i32DzPduOrffuuGcNulB3nXcrY9hi8FNg7gHGYzdWR/kPoeJzLVi4+cw+0UVd/vF/BgZf6kAAAAQCR48AQAAEImqjdqDzJ1uYosu/SJu23H95mfXxz6eV03uvW6u/jZXmdu21e3Q0fZ4Q2Sut7VF5qaB88N0KxjeDtN+tSpMZE68jjiUItL0G+x7NNGlqdI4SDW8aT8tyHWb1tvibr3eqSzXleymediH76ejb9O9myPm+Nw093uYwfmHb1PsnOthqtNtA9b7zdXud2xi8mjxVwsAAACR4METAAAAkeDBEwAAAJGo2j6etn6dfsPPBOkzZ+r3GLZvqPnc5vPpfo+6H6WzrI+lt+077PWH0Y5k1UxC4wr7amq9h7xjzJhaX/C6vr5xllmJ9Hq/vrK636e+FtP9qqShhCqprYCfUvSJC9NHstg+pWGGPNLbh50Bx9TnUm+r+2HaZgFy+izq13V/zyD3a+qRkfuo6m31kExOX1J9Pt1mU39Kkfw+l8b2hLj/ga4vxO9MkN8T+nbGg7+AAJBQu3fvliuvvFLmzJkjDQ0NMnfuXLnllltkYMD8P5UAkHRV+40nAFS6l156Sd566y25++675dRTT5U//vGPcvXVV0t/f7+sX78+7uYBQGgV9eAZJq60vV7scEr5yyPvFzZW9YufdbSvt00fOS4iIqlG9TaqL0KOHfe2bZjsxSY6wt578G9D26o4vPfQcXe5sV4Pw+Stb2oYOqf9+vyHUHLWH1GxfLNqp41zDyopsi5FWyvxujE6y5cvl+XLl7v/PuWUU2Tnzp2ycePGmnrwLPWQTX7Hs+1nGx7IFkX7ndsUu+tj6dmW5B0jNllEzDG/LXbX53Zi97DXraN2Z3vd5nltU32PEUYpjoH4VdSDJwDUunQ6LdOmTbO+ns1mJZvNuv/OZDJRNAsAAuGrEwCoEK+88ops2LBBVq9ebd2mo6NDUqmU+9Pa2hphCwFgZHW5XC7nv1k8MpmMpFIp2deXlqamJv8dyihM1XrYKNQ0c1GQ+NmJyVONXiRia+cRy4xG3ra68txrR6NlBiInrtdt1mwzEO143fv25ZQTC6OSIDMemWZnCjM7lU2lV55XevvjkslkZHpzStLp6D5n1q1bJ7feeuuI2zz//POyYMEC9989PT1ywQUXyAUXXCDf+973rPuZvvFsbW1NxOdoqZViBqUwxw2yvtj2+M2iE6RS3SRIPO1sY3s9yH0OMwuQ34xHpb53KL8wn6NE7QAQsTVr1sill1464jZtbW3uck9PjyxdulQWLVok99xzz4j71dfXS3194dBnAJAEPHgCQMRaWlqkpaXFf0MReeONN2Tp0qUyf/58uffee2XMGL7NBlC5qurBs9RRoz6ejpSPDxYOjq4rvnU8bYuOTYPQNwTYT5/HGfxdb3vk8KDazxyv62r35ilDMb6Or/XrvWqw+bzqedNxdWX/UXOl/jtPmuwuO/dAx+R60Huncn4453pH836bKsTDjEBg2zbOuLvU5yO6j19PT48sWbJEZs+eLevXr5cDBw64r82YMSPGliVDuaLVIFXho9m+GLqCXA/u7sdWcf+b3b3u8rltwf4naPgxNOcehK08L0XMT8ReWarqwRMAqsmWLVtk165dsmvXLpk1a1beawnung8AVnyNAQAJtWrVKsnlcsYfAKhEZf3G8yMf+Yh0dnbK/v375YQTTpCLLrpI7rjjDpk5c2ZZzlds3GrbN3+dOTp24mIdC9sqvTUdL/u1Lb9NhfvpbY9YonFnsPnh+g4VTr3nRPgiIn2H/2Y8nok+txPhiwzrHmAYDD99xNtPD1iv76Np0P7RxL9h9i1F5BxFbF3qcxCvo1bZ5iMfTRzst63fHPV+g9Tb2AZ013O1mwayL3auc1s7bcczdRso9WgF5Rr9AMUp61+WpUuXyo9//GPZuXOn/PSnP5VXXnlFPv7xj5fzlAAAAEiosn7j+fnPf95dPvnkk+XGG2+UlStXyrFjx2T8eP6vAwAAoJZEVlz05ptvyg9/+ENZvHix9aFztFO9BRlwXFeA+w0Er6NevV9331F1jKHoWw/iHpZ3HnO8/tr+I+5ya3ODu5w+Ejxu0RG2juudCN40KLtI/n3R1+1Up+v7orsP5Mfk3no9kL0T88+Yah5z0K87gk0SI+coYmuicaA0bBG4LYIPU2Uehj6HFmRQe0eQ+dJNXQhKEU8npQqdeD1Zyv6X6oYbbpBJkyZJc3OzdHV1yaOPPmrdlqneAAAAqlfoB89169ZJXV3diD/btm1zt//iF78o27dvly1btsjYsWPl05/+tLUis729XdLptPvT3d1d/JUBAAAgUULP1d7b2yu9vb0jbtPW1iYTJ04sWP/6669La2urbN26VRYtWuR7rijnajcNDG6L6DNHCyPu/Ne9Km49z7qtUt2hz63PoY9tqpjvNVSmi+RH2Dqu1xX4zjXqKnRdnZ5X4a7O40Tt+h7Zona9Xt8bZ6B6fQ5T1f5Qm4uLSsLE7gyYXhqVMgqAI4652qMU5edosZJSdWya8zvsvO1RnDspwsxRH2Zg+WKvO+n3q5qVda72MFO9Dec84+p+nAAAAKgNZSsueu655+S5556Tc889V0444QR59dVX5eabb5a5c+cG+rYTAAAA1aVsD54NDQ3ys5/9TG655Rbp7++Xk046SZYvXy4PPvig1Nebq5hLyTYvum0OdCfO0+vyI+JjBdvaNFrO4Vddnzdfuo7U1Xo9ELyzvY7ObdG4jXMeva0+98Gj3vq5J3rzrDvnzhu8fsDbr9Gne4CIF+/vPeh9A94ypbjqUFs0GyamrZR43T65QDLmaq+UUQCQHEmJRU3tiKoyO8y5bUxxvY64dfV9Kdof5hh+g+/7DaZv209vn5TfI4ysbA+e73nPe+TJJ58s1+EBAABQYfhaAQAAAJGIbAD5OOlYWzNVkevqaR2v6zhYV143vT1wvK4E13FxXpW8mAdp7zs8UHDcvEHX1bFfe/Owu3wwO9S+Z7u8gfb/frZXTTbvpBO8bVVk/t3/81d3efYJhd0eWlPmrhDvmOytd6J0231xKtZFRF4+cMhdPnrcu5bpjUMjH2QGvPvcd9i7/yn1XsxSA+c70X2QyQCCrDfxO0ZUUbCpHbZrKvb6tGK7KQDVwIml/aquhzPFvmGquEfDVFkex7lLPcg8qhd/WQAAABAJHjwBAAAQiaqI2k0xebHRq47Xj1mqsZvUvOx7D/5NRERmTC0cMH842+D0mbfnXNfHcI4rkj+/+e60NxD8A8++ISIiAwNepXvDeO8cU+u9dj7fk3aX0/1e7P693+wWEZFl57YZj/FvD/7eXf6f1/1DwTUdUedunOD9Oh1TA8VPHOtF4nv7vet6bGefiIjMn+VVy0+d6LV53mSvq4BpLvlxg+aB6XWVf7F0JX5GdVPwqvWLH+DcFHMHOYZzD3QXgyCTHJi6mgQ5n2lkCL9RIYBKVmwsbYqL9bGiGoTer7rbrx1h2xBnTG6q3C911T7Kg78WAAAAiAQPngAAAIhE6LnaozTSHMN+MV/YymZnvW2wc72fKbq0DVJvmtd96HiFg63rOdd1hbiO4F/e41W1myqs9ZzrToQ//Hw6Ht/6xpsiIvLf3j3TXffc628a2zx3qheJO90aGuvNIwbouPv1vqPusmlOe72trXuDaWD5cXmjAJj/H6rU84abIueomKJ2W3W6Fua6azE+Z652JEGxcfdozxfknFF1FUDlCvM5Wht/WQAAABA7HjwBAAAQiYqtaveLAW3xuo7Ex/ukpXnzkGfNg787sact/tSV9vmV2YURaasaJD2v6l3F9TqWdudqV1X2O/Z41etnnpTyjqFidz0w+0VzThQRbxB7EZEPzJpW0DaR/FjduV59P3Ulvqa7CnSr2N3pTqCvtdkyV7vp/gaJgouNi3WbdKTvtKPUkXSQriG6HaU8dzmPV4vRPZKDKNguzP2Iar561Ab+EgAAACASPHgCAAAgEjx4AgAAIBIV28dT8xtmJsgQSU7/s+ODgwXrRERSjd6ynkkofTD79uverdT9QXWfRd2+3j41G87bfSf1cccb+vOJiIwf57XD6ZeZVn1AmxvqvdfV8Ez63L/t7nWX/3Z86B6cPm2Kt9+BrLusZ0r60OknucvOdeu+kLqPqr63epioGVO99v1299DMRbOmNLrrDuw55C6ffpLXJtMMPbahhGx9CW2z/JhEPVySrc1+/SKD9KEsdqakUqBfJ+KUxD6Itn6nxbbVrx9rEvu5JrFNiA5/FQAAABAJHjwBAAAQiaqI2p1hZmzRq20moYYJI3/Fb4u+82cVqn/7uN5sQCk1vFF+zO+1T0fO5m3N7WhU19I8eSjG37Jrn7vu7/+u2V3WQy/tTZuHOpo+aagduzP97rpFrS3ucmvKi8G7+7zY/ZQTJ4lIfhcDPZySHuJJ0/H/2SdNLWjbpAne8fT7Zopsw8a4fvF5mKF/Sj1TUpDhlEyvl3NIKSTDRz7yEens7JT9+/fLCSecIBdddJHccccdMnPmTP+dkQjFRstB9vM7XhJnGiJer238RQKABFu6dKn8+Mc/lp07d8pPf/pTeeWVV+TjH/943M0CgKJUxTeeAFCtPv/5z7vLJ598stx4442ycuVKOXbsmIwfzzdHACpLVT14lqKaWdOxtt5Pz77jrNexti0q9Y9vvWVbtwFdIe5E/p9ecLK77pm/HHCXmxq8qnAnGhfJn7nIifHf2eyd/LieeUlF5rpC36nc1+tssw7pOP6YoTuBblv6iNdlQb9v4xvGFKwPW3me5Fl0gvzO2H4n/PbzE3Z0AMTnzTfflB/+8IeyePFi60NnNpuVbNYbmSKTyUTVPFgUGy2XOpIm4kYS8JcFABLuhhtukEmTJklzc7N0dXXJo48+at22o6NDUqmU+9Pa2hphSwFgZDx4AkDE1q1bJ3V1dSP+bNu2zd3+i1/8omzfvl22bNkiY8eOlU9/+tOSy5mLEdvb2yWdTrs/3d3dUV0WAPiqy9k+vRIgk8lIKpWSfX1paWpqKskx/WLFIDGnrfrcMS6vAr4wIh6+jel4+nW9nx6c3kRvq2NyvZ+O0p143HZcfTwdpZvul47RGy2D+Wt73x6EPi+un2yO60tdLV4tkhiTl+KeR/m+ZTIZmd6cknS6dJ8zfnp7e6W3t3fEbdra2mTixIkF619//XVpbW2VrVu3yqJFi3zPVY7PUQDQwnyOVlUfTwCoBC0tLdLS0uK/oYHzXYHuxwkAlYIHTwBIqOeee06ee+45Offcc+WEE06QV199VW6++WaZO3duoG87ASBpKvbB0xTF6VjYtq2tEtrZVw/WrgdEtx1v4O3lCSoObJ7sDQ7vzMM+/Hi6kts5px6gfUCdY9veg+7yzv1eRf2W3+weOu5f97jrZpzszad+1cXvcpe/9/Od7vJkFW0fVlXybjtf3uX9o+91d/GzN13pLq88/UQREXnpTTW3uprv/X+94sWIr+z3Bqff+19e+3//wlD7j/5xq7vuwf/v/3WXT6j32qnnbdcV7g5bVwhblwXT74GtK0Redf3b77N+3abY0Q1s7XSOYbs+23HzJ00YO6q2mY41fL9SROPV2C2iGA0NDfKzn/1MbrnlFunv75eTTjpJli9fLg8++KDU1xdOQoHakJSB4IFiVOyDJwBUu/e85z3y5JNPxt0MACgZvlYAAABAJKq2qt0WCfrFlLa4Pn3EO55p3vNGNce4rUq773Dh4O8iXjW4rgTXsbyO/3Us+vOX9w+1+Zi3bvlp3lztNnv7vWP3vn1dff3ewO0fmGW+11l17tObmwrak1/J7t1nPbj+ywe8aN6ZB7477XUxaJrgxUYzUl5Fr76nznvU1OAfMfnF1kHmXC9WKeJi2++jI0jUblLt1f5hxFHVHiWq2gGUW5jP0dr+iwMAAIDI8OAJAACASFRVcZGOD20x7Hif6b1tVe96vWlO8iDzwdvmfjfFurOaG9xlHYXqCP4LF8wVkfy4tU9VqacaC+dkFxE5Z8I0d9npQqCr73VMrgeW190DZkydaG37SM4cl3KXnQhe3wvdDlsXCb+IPcgoBn7xclLi57Dz0QPwqr6TUvFNFTrgScZfVwAAAFQ9HjwBAAAQiUii9mw2KwsXLpQXX3xRtm/fLu973/uiOG1RbIOIZ456Vd86cvaLQoNE8H7b2uZLd+Y61/G0bqfteL2G+FzH6xlVwa+lGgu7GNjmrbdF8PmV+4Xt110FTHPDB1HO6m5TNXwlVoiHudag2wNJkbQ4O2ntAeIUyV+TL33pSzJz5swoTgUAAICEKvuD5+OPPy5btmyR9evX+26bzWYlk8nk/QAAAKA6lDVq37dvn1x99dWyefNmaWxs9N2+o6NDbr311qLPZ4s/bduYomh7FbQXr+dXeo95+3yq6jpv3mrvGH5tMs1BPsTbr88wt7ptjnc9v7ner0lVuzuxuo7og1SCm+a21wPF2/6fRt+DVOO4guPqe6uVq7q7FJF5JcbQQa61Eq8LAJBsZfvLksvlZNWqVbJ69WpZsGBBoH3a29slnU67P93d3eVqHgAAACIW+sFz3bp1UldXN+LPtm3bZMOGDZLJZKS9vT3wsevr66WpqSnvBwAAANUhdNS+Zs0aufTSS0fcpq2tTW677TZ59tlnpb6+Pu+1BQsWyGWXXSb33Xdf2FNbmSqNg8SEYebu1tvqbZz1OroMMqi66Tx6P1tFuq70duLxVOMkd136iK6+986h43XNWa9jch3LH7PMbe/Nl+7tlx/Fmyvj9fEaDfeuVQ2cnzlqPoZ3rNJWXRd7jKirv0txPmJ0AEAcQj94trS0SEtLi+923/72t+W2225z/93T0yMf/OAH5aGHHpKFCxeGPS0AAAAqXNmKi2bPnp3378mTJ4uIyNy5c2XWrFnlOi0AAAASqirmai9XzGqLNE3zvdti/jCxqH79+Niccb3mxNx6EPcZU72uDfnzm5sjcad9etvx47zXU43manJnvnTdJUBX39u6JpgG6D8yYB6E3q+SPY5B3L1RDOIbXJ2YHABQqSJ78Gxra5NczvyAAQAAgOrHVycAAACIRFVE7eUSJtLUFd9BqtpNUa1eF2TAdHfgeeumwavrdRV682RdOe+tHze28ET6uosdSUB3A6iUQdyJuwEACI+/ngAAAIgED54AAACIRNVG7VFVHZsGng977mKPYYr0j1sGfPc7tikCF/Gq122CtM12bqet+ty66t3ehaA84qxUBwCgFvDXFQAAAJHgwRMAAACR4METAAAAkajaPp5R9dFz+inq/ohBzh2mfbbhmUzHCNIvUvcDzRwdEBH/mY1s5wvLNANUkGGkTPeg1O8x/ToBACgv/tICAAAgEjx4AkAFyGaz8r73vU/q6uqks7Mz7uYAQFGqNmqPSpAZhooRZgilsHG4HmbJmaUoTJwfRKlnHTJtE2TIpmK7NBC7I2m+9KUvycyZM+XFF1+MuymoAQf7vVnrpk4aeVg9IAz+ugJAwj3++OOyZcsWWb9+fdxNAYBR4RtPAEiwffv2ydVXXy2bN2+WxsZG3+2z2axks1n335lMppzNA4BQePAMKCkxrD63nuXHU1w7daW77Rhh7kG5ttVs20bRPQCIQi6Xk1WrVsnq1atlwYIFsnv3bt99Ojo65NZbby1/41DViNdRLvylBYCIrVu3Turq6kb82bZtm2zYsEEymYy0t7cHPnZ7e7uk02n3p7u7u4xXAgDh8I0nAERszZo1cumll464TVtbm9x2223y7LPPSn19fd5rCxYskMsuu0zuu+++gv3q6+sLtgeApODBM6AkxrBhKur94uwgxyp1pXox2wLVoKWlRVpaWny3+/a3vy233Xab+++enh754Ac/KA899JAsXLiwnE0EgLLgwRMAEmr27Nl5/548ebKIiMydO1dmzZoVR5MAYFT4qgkAAACR4BvPgJJS1V7qCnAAlaOtrU1yuZz/hgCQUDyNAAAAIBI8eAIAACASRO0BJSWqTko7AAAAwuIpBgAAAJHgwRMAAACR4METAAAAkeDBEwAAAJHgwRMAAACR4METAAAAkeDBEwAAAJHgwRMAAACRYAB5FLDNB5+U+eoBAKNzsP+Yuzx10vgYW4Jaw9MDAAAAIpHobzxzuZyIiBzKZGJuSW3hG0/UEufzxfm8qTZ8jsLkkPrGc8wg33hidMJ8jib6wfPQoUMiInLqnNaYWwKg2h06dEhSqVTczSg5PkcBRCXI52hdLsH/m//WW29JT0+PTJkyRerq6kREJJPJSGtrq3R3d0tTU1PMLYxOrV63SO1eO9cdzXXncjk5dOiQzJw5U8aMqb5v8k2fo9WkVv878cN9KcQ9KVSqexLmczTR33iOGTNGZs2aZXytqampJn9xavW6RWr32rnu8qvGbzodI32OVpNa/e/ED/elEPekUCnuSdDP0er733sAAAAkEg+eAAAAiETFPXjW19fLLbfcIvX19XE3JVK1et0itXvtXHdtXTeKw++LGfelEPekUBz3JNHFRQAAAKgeFfeNJwAAACoTD54AAACIBA+eAAAAiAQPngAAAIgED54AAACIRFU8eGazWXnf+94ndXV10tnZGXdzymr37t1y5ZVXypw5c6ShoUHmzp0rt9xyiwwMDMTdtLK48847Zc6cOTJx4kSZP3++/PrXv467SWXX0dEh55xzjkyZMkVOPPFEWblypezcuTPuZkWuo6ND6urq5Prrr4+7KagQtfb5aFOLn5s2fJ76i/qztioePL/0pS/JzJkz425GJF566SV566235O6775YdO3bIN7/5Tbnrrrvky1/+ctxNK7mHHnpIrr/+ernppptk+/btct5558mKFSukq6sr7qaV1dNPPy3XXnutPPvss/LEE0/I8ePHZdmyZdLf3x930yLz/PPPyz333CPvfe97424KKkgtfT7a1Ornpg2fpyOL5bM2V+Eee+yx3Omnn57bsWNHTkRy27dvj7tJkfv617+emzNnTtzNKLkPfOADudWrV+etO/3003M33nhjTC2Kx/79+3Miknv66afjbkokDh06lDvttNNyTzzxRO6CCy7Ife5zn4u7Sahg1fr5aMPn5shq7fN0JHF91lb0N5779u2Tq6++Wn7wgx9IY2Nj3M2JTTqdlmnTpsXdjJIaGBiQF154QZYtW5a3ftmyZbJ169aYWhWPdDotIlJ177HNtddeKx/60IfkoosuirspqALV+Plow+emv1r7PB1JXJ+14yI9WwnlcjlZtWqVrF69WhYsWCC7d++Ou0mxeOWVV2TDhg3yr//6r3E3paR6e3tlcHBQpk+fnrd++vTpsnfv3phaFb1cLidr166Vc889V84666y4m1N2Dz74oPzud7+T559/Pu6moApU6+ejDZ+bI6u1z9ORxPlZm7hvPNetWyd1dXUj/mzbtk02bNggmUxG2tvb425ySQS9bq2np0eWL18ul1xyiVx11VUxtby86urq8v6dy+UK1lWzNWvWyO9//3v50Y9+FHdTyq67u1s+97nPyf333y8TJ06MuzlIED4fw6n1z02bWvo8HUncn7WJm6u9t7dXent7R9ymra1NLr30Uvn5z3+e9x/T4OCgjB07Vi677DK57777yt3Ukgp63c4vSU9PjyxdulQWLlwomzZtkjFjEvf/EKMyMDAgjY2N8vDDD8vHPvYxd/3nPvc56ezslKeffjrG1kXjuuuuk82bN8szzzwjc+bMibs5Zbd582b52Mc+JmPHjnXXDQ4OSl1dnYwZM0ay2Wzea6gdfD4Gw+emXa19no4k7s/axD14BtXV1SWZTMb9d09Pj3zwgx+Un/zkJ7Jw4UKZNWtWjK0rrzfeeEOWLl0q8+fPl/vvv79q/xgvXLhQ5s+fL3feeae77t3vfrd89KMflY6OjhhbVl65XE6uu+46eeSRR+Spp56S0047Le4mReLQoUPy17/+NW/dZz7zGTn99NPlhhtuqPloDMHUyuejTa1+btrU6ufpSOL+rK3YPp6zZ8/O+/fkyZNFRGTu3LlV/dDZ09MjS5YskdmzZ8v69evlwIED7mszZsyIsWWlt3btWrn88stlwYIFsmjRIrnnnnukq6tLVq9eHXfTyuraa6+VBx54QB599FGZMmWK2zcrlUpJQ0NDzK0rnylTphR84E2aNEmam5t56EQgtfT5aFOrn5s2tfp5OpK4P2sr9sGzVm3ZskV27dolu3btKnjArtAvr60+8YlPSF9fn3z1q1+VPXv2yFlnnSWPPfaYnHzyyXE3raw2btwoIiJLlizJW3/vvffKqlWrom8QUCFq6fPRplY/N234PE2eio3aAQAAUFlqo8c1AAAAYseDJwAAACLBgycAAAAiwYMnAAAAIsGDJwAAACLBgycAAAAiwYMnAAAAIsGDJwAAACLBgycAAAAiwYMnAAAAIsGDJwAAACLx/wPzg+eukgHiIQAAAABJRU5ErkJggg==", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(1,2, figsize=(8,4))\n", + "\n", + "ax[1].hist2d(x[1,:], x[2,:], 100, cmap=\"Blues\")\n", + "# ax[1].scatter(x[1,:], x[2,:], s=0.1, alpha=0.2, color=\"C0\")\n", + "\n", + "ax[2].hist2d(y[1,:], y[2,:], 100, cmap=\"Blues\");\n", + "# ax[2].scatter(y[1,:], y[2,:], s=0.1, alpha=0.5, color=\"C0\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "c89d305a-fbe1-47c0-8a56-d95e38db5fea", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 13.845783 seconds (396.81 M allocations: 29.229 GiB, 35.13% gc time)\n" + ] + } + ], + "source": [ + "initial_trafo = \n", + " TrainableRQSpline(ones(ndims, 40), ones(ndims, 40), ones(ndims, 40-1)) #∘\n", + "# EuclidianNormalizingFlows.ScaleShiftTrafo([1., 1], [2., 2]) \n", + "\n", + "optimizer = ADAGrad(0.1)\n", + "smpls = nestedview(x)\n", + "nbatches = 50\n", + "nepochs = 10 \n", + "\n", + "@time r = EuclidianNormalizingFlows.optimize_whitening(smpls, initial_trafo, optimizer, nbatches = nbatches, nepochs = nepochs);" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "1c9d73f4-c63d-4fd5-a23f-22ac21598878", + "metadata": {}, + "outputs": [], + "source": [ + "yhat = r.result(x);" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "09eb20f8-3b24-4807-bd1f-2888270ffd11", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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LpP/+I//kPnz58vUqVMT7F15vfnmm7J48WKZO3eufPvb307NL1PU5s+fL3PnzpV7773X3fee97xHPvKRj0h7e3uCPSuvfD4vN9xwg/zgBz+Qn/zkJ/Lud7876S7F4tChQ/LGG28U7PuLv/gLmTNnjtxyyy01GZ3BX628Hw5Uq++PA9Xq++VAlfT+WbFjPKdNm1bw7zFjxoiIyKxZs6r6obO7u1sWLVok06ZNk7vuukvefvtt93uTJ09OsGfRW7t2rVx99dUyb948WbBggdx///3S2dkpq1atSrprZbV69Wr57ne/K4899piMHTvWHbOVyWSkoaEh4d6Vz9ixY4veHE877TSZMGFCqt40kR619H44UK2+Pw5Uq++XA1XS+2fFPnjWqqeeekp27dolu3btKnrArtA/XltdeeWVsn//fvniF78ob731lpxzzjny+OOPy/Tp05PuWllt2LBBREQWLVpUsP+BBx6QlStXxt8hIKVq6f1woFp9fxyI98vKU7FROwAAACpLdY/ABgAAQGrw4AkAAIBY8OAJAACAWPDgCQAAgFjw4AkAAIBY8OAJAACAWPDgCQAAgFjw4AkAAIBY8OAJAACAWPDgCQAAgFjw4AkAAIBY/P+PCxMjh0VQPgAAAABJRU5ErkJggg==", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "([0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [-3.5760123271603077, -3.491559357275769, -3.4071063873912304, -3.322653417506692, -3.2382004476221535, -3.153747477737615, -3.0692945078530762, -2.9848415379685376, -2.900388568083999, -2.8159355981994603 … 4.109207932332703, 4.193660902217243, 4.27811387210178, 4.36256684198632, 4.447019811870858, 4.5314727817553955, 4.615925751639935, 4.700378721524473, 4.784831691409012, 4.86928466129355], [-4.765852938591611, -4.6864187406969435, -4.606984542802277, -4.527550344907609, -4.448116147012941, -4.368681949118274, -4.2892477512236065, -4.20981355332894, -4.130379355434272, -4.050945157539604 … 2.4626590698231254, 2.542093267717793, 2.62152746561246, 2.700961663507128, 2.7803958614017947, 2.8598300592964625, 2.9392642571911303, 3.018698455085797, 3.098132652980465, 3.1775668508751327], PyObject )" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots(1,2, figsize=(8,4))\n", + "\n", + "ax[1].hist2d(x[1,:], x[2,:], 100, cmap=\"Blues\")\n", + "# ax[1].scatter(x[1,:], x[2,:], s=0.1, alpha=0.2, color=\"C0\")\n", + "\n", + "ax[2].hist2d(yhat[1,:], yhat[2,:], 100, cmap=\"Blues\")\n", + "# ax[2].scatter(y[1,:], y[2,:], s=0.1, alpha=0.5, color=\"C0\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f98cec70-507f-47be-b4c7-1dd730924b44", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "Figure(PyObject
)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "PyObject Text(0.5, 24.0, 'Iteration')" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots(1,1, figsize=(6,4))\n", + "\n", + "ax.plot(1:length(r.negll_history), r.negll_history)\n", + "ax.set_ylabel(\"Cost\")\n", + "ax.set_xlabel(\"Iteration\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e1556a7-7b19-4c6b-b30c-6f5926ca9024", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1eb56f0b-5d29-407e-8cc9-9f71413a929f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.7.2", + "language": "julia", + "name": "julia-1.7" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notes.jl b/notes.jl new file mode 100644 index 0000000..fcfd080 --- /dev/null +++ b/notes.jl @@ -0,0 +1,5 @@ + # think about storage, so memory coalescence can be used?, also shared memory caching for older hardware + # keep data on gpu + # use profiling to really get in there with the optimization + #use NVIDIAs compute sanitizer to look at emory issues: cuda/compute-sanitizer + # instpection tools : @macroexpand use in front of @kernel in kernel definition; @ka_code_typed, @ka_code_llvm use in front of call to kernel \ No newline at end of file diff --git a/src/EuclidianNormalizingFlows.jl b/src/EuclidianNormalizingFlows.jl index c370990..699280d 100644 --- a/src/EuclidianNormalizingFlows.jl +++ b/src/EuclidianNormalizingFlows.jl @@ -29,6 +29,8 @@ using Parameters using SpecialFunctions using StatsBase using ValueShapes +using KernelAbstractions +using KernelAbstractions: @atomic import Zygote import ZygoteRules @@ -46,5 +48,6 @@ include("householder_trafo.jl") include("scale_shift_trafo.jl") include("center_stretch.jl") include("johnson_trafo.jl") +include("spline_trafo.jl") end # module diff --git a/src/optimize_whitening.jl b/src/optimize_whitening.jl index 31b9d9a..76e6aee 100644 --- a/src/optimize_whitening.jl +++ b/src/optimize_whitening.jl @@ -6,6 +6,7 @@ std_normal_logpdf(x::Real) = -(abs2(x) + log2π)/2 function mvnormal_negll_trafo(trafo::Function, X::AbstractMatrix{<:Real}) nsamples = size(X, 2) # normalize by number of samples to be independent of batch size: + Y, ladj = with_logabsdet_jacobian(trafo, X) #ref_ll = sum(sum(std_normal_logpdf.(Y), dims = 1) .+ ladj) / nsamples # Faster: @@ -26,7 +27,8 @@ function optimize_whitening( smpls::VectorOfSimilarVectors{<:Real}, initial_trafo::Function, optimizer; nbatches::Integer = 100, nepochs::Integer = 100, optstate = Optimisers.setup(optimizer, deepcopy(initial_trafo)), - negll_history = Vector{Float64}() + negll_history = Vector{Float64}(), + shuffle_samples::Bool = false ) batchsize = round(Int, length(smpls) / nbatches) batches = collect(Iterators.partition(smpls, batchsize)) @@ -40,6 +42,10 @@ function optimize_whitening( state, trafo = Optimisers.update(state, trafo, d_trafo) push!(negll_hist, negll) end + if shuffle_samples + shuffled_smpls = shuffle(smpls) + batches = collect(Iterators.partition(shuffled_smpls, batchsize)) + end end (result = trafo, optimizer_state = state, negll_history = vcat(negll_history, negll_hist)) end diff --git a/src/spline_trafo.jl b/src/spline_trafo.jl new file mode 100644 index 0000000..aeabe0a --- /dev/null +++ b/src/spline_trafo.jl @@ -0,0 +1,546 @@ +# This file is a part of EuclidianNormalizingFlows.jl, licensed under the MIT License (MIT). +# The algorithm implemented here is described in https://arxiv.org/abs/1906.04032 + +struct TrainableRQSpline <: Function + widths::AbstractMatrix{<:Real} + heights::AbstractMatrix{<:Real} + derivatives::AbstractMatrix{<:Real} +end + +export TrainableRQSpline +@functor TrainableRQSpline + +struct RQSpline <: Function + widths::AbstractMatrix{<:Real} + heights::AbstractMatrix{<:Real} + derivatives::AbstractMatrix{<:Real} +end + +export RQSpline +@functor RQSpline + +struct TrainableRQSplineInv <: Function + widths::AbstractMatrix{<:Real} + heights::AbstractMatrix{<:Real} + derivatives::AbstractMatrix{<:Real} +end + +@functor TrainableRQSplineInv +export TrainableRQSplineInv + +struct RQSplineInv <: Function + widths::AbstractMatrix{<:Real} + heights::AbstractMatrix{<:Real} + derivatives::AbstractMatrix{<:Real} +end + +@functor RQSplineInv +export RQSplineInv + + +Base.:(==)(a::TrainableRQSpline, b::TrainableRQSpline) = a.widths == b.widths && a.heights == b.heights && a.derivatives == b.derivatives + +Base.isequal(a::TrainableRQSpline, b::TrainableRQSpline) = isequal(a.widths, b.widths) && isequal(a.heights, b.heights) && isequal(a.derivatives, b.derivatives) + +Base.hash(x::TrainableRQSpline, h::UInt) = hash(x.widths, hash(x.heights, hash(x.derivatives, hash(:TrainableRQSpline, hash(:EuclidianNormalizingFlows, h))))) + +(f::TrainableRQSpline)(x::AbstractMatrix{<:Real}) = spline_forward(f, x)[1] + +function ChangesOfVariables.with_logabsdet_jacobian( + f::TrainableRQSpline, + x::AbstractMatrix{<:Real} +) + return spline_forward(f, x) +end + +function InverseFunctions.inverse(f::TrainableRQSpline) + return TrainableRQSplineInv(f.widths, f.heights, f.derivatives) +end + +Base.:(==)(a::TrainableRQSplineInv, b::TrainableRQSplineInv) = a.widths == b.widths && a.heights == b.heights && a.derivatives == b.derivatives + +Base.isequal(a::TrainableRQSplineInv, b::TrainableRQSplineInv) = isequal(a.widths, b.widths) && isequal(a.heights, b.heights) && isequal(a.derivatives, b.derivatives) + +Base.hash(x::TrainableRQSplineInv, h::UInt) = hash(x.widths, hash(x.heights, hash(x.derivatives, hash(:TrainableRQSplineInv, hash(:EuclidianNormalizingFlows, h))))) + +(f::TrainableRQSplineInv)(x::AbstractMatrix{<:Real}) = spline_backward(f, x)[1] + +function ChangesOfVariables.with_logabsdet_jacobian( + f::TrainableRQSplineInv, + x::AbstractMatrix{<:Real} +) + return spline_backward(f, x) +end + +function InverseFunctions.inverse(f::TrainableRQSplineInv) + return TrainableRQSpline(f.widths, f.heights, f.derivatives) +end + +# Transformation forward: + +function spline_forward(trafo::TrainableRQSpline, x::AbstractMatrix{<:Real}; B=5.) + + @assert size(trafo.widths, 1) == size(trafo.heights, 1) == size(trafo.derivatives, 1) == size(x, 1) >= 1 + @assert size(trafo.widths, 2) == size(trafo.heights, 2) == (size(trafo.derivatives, 2) + 1) >= 2 + + ndims = size(x, 1) + + w = _cumsum(_softmax(trafo.widths)) + h = _cumsum(_softmax(trafo.heights)) + d = _softplus(trafo.derivatives) + + w = hcat(repeat([-B,], ndims,1), w) + h = hcat(repeat([-B,], ndims,1), h) + d = hcat(repeat([1,], ndims,1), d) + d = hcat(d, repeat([1,], ndims,1)) + + return spline_forward(RQSpline(w,h,d), x) +end + +function spline_forward(trafo::RQSpline, x::AbstractMatrix{<:Real}) + return spline_forward(x, trafo.widths, trafo.heights, trafo.derivatives, trafo.widths, trafo.heights, trafo.derivatives) +end + +function spline_forward( + x::AbstractArray{M0}, + w::AbstractArray{M1}, + h::AbstractArray{M2}, + d::AbstractArray{M3}, + w_logJac::AbstractArray{M4}, + h_logJac::AbstractArray{M5}, + d_logJac::AbstractArray{M6} +) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real, M4<:Real, M5<:Real, M6<:Real} + + T = promote_type(M0, M1, M2, M3, M4, M5, M6) + + ndims = size(x, 1) + nsmpls = size(x, 2) + + y = zeros(T, ndims, nsmpls) + logJac = zeros(T, ndims, nsmpls) + + device = KernelAbstractions.get_device(x) + n = device isa GPU ? 256 : 4 + kernel! = spline_forward_kernel!(device, n) + + ev = kernel!(x, y, logJac, w, h, d, ndrange=size(x)) + + wait(ev) + + return y, sum(logJac, dims=1) +end + + +function spline_forward_pullback( + x::AbstractArray{M0}, + w::AbstractArray{M1}, + h::AbstractArray{M2}, + d::AbstractArray{M3}, + w_logJac::AbstractArray{M4}, + h_logJac::AbstractArray{M5}, + d_logJac::AbstractArray{M6}, + tangent::ChainRulesCore.Tangent; + ) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real, M4<:Real, M5<:Real, M6<:Real} + + T = promote_type(M0, M1, M2, M3, M4, M5, M6) + + ndims = size(x, 1) + nsmpls = size(x, 2) + nparams = size(w, 2) + + y = zeros(T, ndims, nsmpls) + logJac = zeros(T, ndims, nsmpls) + + ∂y∂w = zeros(T, ndims, nparams) + ∂y∂h = zeros(T, ndims, nparams) + ∂y∂d = zeros(T, ndims, nparams+1) + + ∂LogJac∂w = zeros(T, ndims, nparams) + ∂LogJac∂h = zeros(T, ndims, nparams) + ∂LogJac∂d = zeros(T, ndims, nparams+1) + + device = KernelAbstractions.get_device(x) + n = device isa GPU ? 256 : 4 + kernel! = spline_forward_pullback_kernel!(device, n) + + ev = kernel!( + x, y, logJac, + w, h, d, + ∂y∂w, ∂y∂h, ∂y∂d, + ∂LogJac∂w, ∂LogJac∂h, ∂LogJac∂d, + tangent, + ndrange=size(x) + ) + + wait(ev) + logJac = sum(logJac, dims=1) + + return NoTangent(), @thunk(tangent[1] .* exp.(logJac)), ∂y∂w, ∂y∂h, ∂y∂d, ∂LogJac∂w, ∂LogJac∂h, ∂LogJac∂d +end + +@kernel function spline_forward_kernel!( + x::AbstractArray, + y::AbstractArray, + logJac::AbstractArray, + w::AbstractArray, + h::AbstractArray, + d::AbstractArray +) + i, j = @index(Global, NTuple) + + K = size(w, 2) + + # Find the bin index + k1 = searchsortedfirst_impl(w[i,:], x[i,j]) - 1 + k2 = one(typeof(k1)) + + # Is inside of range + isinside = (k1 < K) && (k1 > 0) + k = Base.ifelse(isinside, k1, k2) + + x_tmp = Base.ifelse(isinside, x[i,j], w[i,k]) # Simplifies calculations + (yᵢⱼ, LogJacᵢⱼ) = eval_forward_spline_params(w[i,k], w[i,k+1], h[i,k], h[i,k+1], d[i,k], d[i,k+1], x_tmp) + + y[i,j] = Base.ifelse(isinside, yᵢⱼ, x[i,j]) + logJac[i, j] += Base.ifelse(isinside, LogJacᵢⱼ, zero(typeof(LogJacᵢⱼ))) +end + + +@kernel function spline_forward_pullback_kernel!( + x::AbstractArray, + y::AbstractArray, + logJac::AbstractArray, + w::AbstractArray, + h::AbstractArray, + d::AbstractArray, + ∂y∂w_tangent::AbstractArray, + ∂y∂h_tangent::AbstractArray, + ∂y∂d_tangent::AbstractArray, + ∂LogJac∂w_tangent::AbstractArray, + ∂LogJac∂h_tangent::AbstractArray, + ∂LogJac∂d_tangent::AbstractArray, + tangent::ChainRulesCore.Tangent + ) + + i, j = @index(Global, NTuple) + + K = size(w, 2) + + # Find the bin index + k1 = searchsortedfirst_impl(w[i,:], x[i,j]) - 1 + k2 = one(typeof(k1)) + + # Is inside of range + isinside = (k1 < K) && (k1 > 0) + k = Base.ifelse(isinside, k1, k2) + + x_tmp = Base.ifelse(isinside, x[i,j], w[i,k]) # Simplifies calculations + (yᵢⱼ, LogJacᵢⱼ, ∂y∂wₖ, ∂y∂hₖ, ∂y∂dₖ, ∂LogJac∂wₖ, ∂LogJac∂hₖ, ∂LogJac∂dₖ) = eval_forward_spline_params_with_grad(w[i,k], w[i,k+1], h[i,k], h[i,k+1], d[i,k], d[i,k+1], x_tmp) + + y[i,j] = Base.ifelse(isinside, yᵢⱼ, x[i,j]) + logJac[i, j] += Base.ifelse(isinside, LogJacᵢⱼ, zero(typeof(LogJacᵢⱼ))) + + left_edge_istrue = (1 < k < K) + left_edge_ind = Base.ifelse(left_edge_istrue, k-1, one(typeof(k))) + + @atomic ∂y∂w_tangent[i, left_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * left_edge_istrue, ∂y∂wₖ[1], zero(eltype(∂y∂wₖ))) + @atomic ∂y∂h_tangent[i, left_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * left_edge_istrue, ∂y∂hₖ[1], zero(eltype(∂y∂hₖ))) + @atomic ∂y∂d_tangent[i, left_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * left_edge_istrue, ∂y∂dₖ[1], zero(eltype(∂y∂dₖ))) + @atomic ∂LogJac∂w_tangent[i, left_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * left_edge_istrue, ∂LogJac∂wₖ[1], zero(eltype(∂LogJac∂wₖ))) + @atomic ∂LogJac∂h_tangent[i, left_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * left_edge_istrue, ∂LogJac∂hₖ[1], zero(eltype(∂LogJac∂hₖ))) + @atomic ∂LogJac∂d_tangent[i, left_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * left_edge_istrue, ∂LogJac∂dₖ[1], zero(eltype(∂LogJac∂dₖ))) + + right_edge_istrue = (k < K - 1) + right_edge_ind = Base.ifelse(right_edge_istrue, k, one(typeof(k))) + + @atomic ∂y∂w_tangent[i, right_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * right_edge_istrue, ∂y∂wₖ[2], zero(eltype(∂y∂wₖ))) + @atomic ∂y∂h_tangent[i, right_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * right_edge_istrue, ∂y∂hₖ[2], zero(eltype(∂y∂hₖ))) + @atomic ∂y∂d_tangent[i, right_edge_ind+1] += tangent[1][i,j] * Base.ifelse(isinside * right_edge_istrue, ∂y∂dₖ[2], zero(eltype(∂y∂dₖ))) + @atomic ∂LogJac∂w_tangent[i, right_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * right_edge_istrue, ∂LogJac∂wₖ[2], zero(eltype(∂LogJac∂wₖ))) + @atomic ∂LogJac∂h_tangent[i, right_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * right_edge_istrue, ∂LogJac∂hₖ[2], zero(eltype(∂LogJac∂hₖ))) + @atomic ∂LogJac∂d_tangent[i, right_edge_ind+1] += tangent[2][1,j] * Base.ifelse(isinside * right_edge_istrue, ∂LogJac∂dₖ[2], zero(eltype(∂LogJac∂dₖ))) + +end + +function ChainRulesCore.rrule( + ::typeof(spline_forward), + x::AbstractArray{M0}, + w::AbstractArray{M1}, + h::AbstractArray{M2}, + d::AbstractArray{M3}, + w_logJac::AbstractArray{M4}, + h_logJac::AbstractArray{M5}, + d_logJac::AbstractArray{M6}; +) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real, M4<:Real, M5<:Real, M6<:Real} + + # To do: Rewrite to avoid repeating calculation. + y, logJac = spline_forward(x, w, h, d, w_logJac, h_logJac, d_logJac) + pullback(tangent) = spline_forward_pullback(x, w, h, d, w_logJac, h_logJac, d_logJac, tangent) + return (y, logJac), pullback +end + +function eval_forward_spline_params( + wₖ::Real, wₖ₊₁::Real, + hₖ::Real, hₖ₊₁::Real, + dₖ::Real, dₖ₊₁::Real, + x::Real) + + Δy = hₖ₊₁ - hₖ + Δx = wₖ₊₁ - wₖ + sk = Δy / Δx + ξ = (x - wₖ) / Δx + + denom = (sk + (dₖ₊₁ + dₖ - 2*sk)*ξ*(1-ξ)) + nom_1 = sk*ξ*ξ + dₖ*ξ*(1-ξ) + nom_2 = Δy * nom_1 + nom_3 = dₖ₊₁*ξ*ξ + 2*sk*ξ*(1-ξ) + dₖ*(1-ξ)^2 + nom_4 = sk*sk*nom_3 + + y = hₖ + nom_2/denom + + # LogJacobian + logJac = log(abs(nom_4))-2*log(abs(denom)) + + return y, logJac +end + +function eval_forward_spline_params_with_grad( + wₖ::M0, wₖ₊₁::M0, + hₖ::M1, hₖ₊₁::M1, + dₖ::M2, dₖ₊₁::M2, + x::M3) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real} + + Δy = hₖ₊₁ - hₖ + Δx = wₖ₊₁ - wₖ + sk = Δy / Δx + ξ = (x - wₖ) / Δx + + denom = (sk + (dₖ₊₁ + dₖ - 2*sk)*ξ*(1-ξ)) + nom_1 = sk*ξ*ξ + dₖ*ξ*(1-ξ) + nom_2 = Δy * nom_1 + nom_3 = dₖ₊₁*ξ*ξ + 2*sk*ξ*(1-ξ) + dₖ*(1-ξ)^2 + nom_4 = sk*sk*nom_3 + + y = hₖ + nom_2/denom + + # LogJacobian + logJac = log(abs(nom_4))-2*log(abs(denom)) + + # Gradient of parameters: + + # dy / dw_k + ∂s∂wₖ = Δy/Δx^2 + ∂ξ∂wₖ = (-Δx + x - wₖ)/Δx^2 + ∂y∂wₖ = (Δy / denom^2) * ((∂s∂wₖ*ξ^2 + 2*sk*ξ*∂ξ∂wₖ + dₖ*(∂ξ∂wₖ - + 2*ξ*∂ξ∂wₖ))*denom - nom_1*(∂s∂wₖ - 2*∂s∂wₖ*ξ*(1-ξ) + (dₖ₊₁ + dₖ - 2*sk)*(∂ξ∂wₖ - 2*ξ*∂ξ∂wₖ)) ) + ∂LogJac∂wₖ = (1/nom_4)*(2*sk*∂s∂wₖ*nom_3 + sk*sk*(2*dₖ₊₁*ξ*∂ξ∂wₖ + 2*∂s∂wₖ*ξ*(1-ξ)+2*sk*(∂ξ∂wₖ - 2*ξ*∂ξ∂wₖ)-dₖ*2*(1-ξ)*∂ξ∂wₖ)) - (2/denom)*(∂s∂wₖ - 2*∂s∂wₖ*ξ*(1-ξ) + (dₖ₊₁ + dₖ - 2*sk)*(∂ξ∂wₖ - 2*ξ*∂ξ∂wₖ)) + + # dy / dw_k+1 + ∂s∂wₖ₊₁ = -Δy/Δx^2 + ∂ξ∂wₖ₊₁ = -(x - wₖ) / Δx^2 + ∂y∂wₖ₊₁ = (Δy / denom^2) * ((∂s∂wₖ₊₁*ξ^2 + 2*sk*ξ*∂ξ∂wₖ₊₁ + dₖ*(∂ξ∂wₖ₊₁ - + 2*ξ*∂ξ∂wₖ₊₁))*denom - nom_1*(∂s∂wₖ₊₁ - 2*∂s∂wₖ₊₁*ξ*(1-ξ) + (dₖ₊₁ + dₖ - 2*sk)*(∂ξ∂wₖ₊₁ - 2*ξ*∂ξ∂wₖ₊₁)) ) + ∂LogJac∂wₖ₊₁ = (1/nom_4)*(2*sk*∂s∂wₖ₊₁*nom_3 + sk*sk*(2*dₖ₊₁*ξ*∂ξ∂wₖ₊₁ + 2*∂s∂wₖ₊₁*ξ*(1-ξ)+2*sk*(∂ξ∂wₖ₊₁ - 2*ξ*∂ξ∂wₖ₊₁)-dₖ*2*(1-ξ)*∂ξ∂wₖ₊₁)) - (2/denom)*(∂s∂wₖ₊₁ - 2*∂s∂wₖ₊₁*ξ*(1-ξ) + (dₖ₊₁ + dₖ - 2*sk)*(∂ξ∂wₖ₊₁ - 2*ξ*∂ξ∂wₖ₊₁)) + + # dy / dh_k + ∂s∂hₖ = -1/Δx + ∂y∂hₖ = 1 + (1/denom^2)*((-nom_1+Δy*ξ*ξ*∂s∂hₖ)*denom - nom_2 * (∂s∂hₖ - 2*∂s∂hₖ*ξ*(1-ξ)) ) + ∂LogJac∂hₖ = (1/nom_4)*(2*sk*∂s∂hₖ*nom_3 + sk*sk*2*∂s∂hₖ*ξ*(1-ξ)) - (2/denom)*(∂s∂hₖ - 2*∂s∂hₖ*ξ*(1-ξ)) + + # dy / dh_k+1 + ∂s∂hₖ₊₁ = 1/Δx + ∂y∂hₖ₊₁ = (1/denom^2)*((nom_1+Δy*ξ*ξ*∂s∂hₖ₊₁)*denom - nom_2 * (∂s∂hₖ₊₁ - 2*∂s∂hₖ₊₁*ξ*(1-ξ)) ) + ∂LogJac∂hₖ₊₁ = (1/nom_4)*(2*sk*∂s∂hₖ₊₁*nom_3 + sk*sk*2*∂s∂hₖ₊₁*ξ*(1-ξ)) - (2/denom)*(∂s∂hₖ₊₁ - 2*∂s∂hₖ₊₁*ξ*(1-ξ)) + + # dy / dd_k + ∂y∂dₖ = (1/denom^2) * ((Δy*ξ*(1-ξ))*denom - nom_2*ξ*(1-ξ) ) + ∂LogJac∂dₖ = (1/nom_4)*sk^2*(1-ξ)^2 - (2/denom)*ξ*(1-ξ) + + # dy / dδ_k+1 + ∂y∂dₖ₊₁ = -(nom_2/denom^2) * ξ*(1-ξ) + ∂LogJac∂dₖ₊₁ = (1/nom_4)*sk^2*ξ^2 - (2/denom)*ξ*(1-ξ) + + ∂y∂w = (∂y∂wₖ, ∂y∂wₖ₊₁) + ∂y∂h = (∂y∂hₖ, ∂y∂hₖ₊₁) + ∂y∂d = (∂y∂dₖ, ∂y∂dₖ₊₁) + + ∂LogJac∂w = (∂LogJac∂wₖ, ∂LogJac∂wₖ₊₁) + ∂LogJac∂h = (∂LogJac∂hₖ, ∂LogJac∂hₖ₊₁) + ∂LogJac∂d = (∂LogJac∂dₖ, ∂LogJac∂dₖ₊₁) + + return y, logJac, ∂y∂w, ∂y∂h, ∂y∂d, ∂LogJac∂w, ∂LogJac∂h, ∂LogJac∂d +end + +# Transformation backward: + +function spline_backward(trafo::TrainableRQSplineInv, x::AbstractMatrix{<:Real}; B = 5.) + + @assert size(trafo.widths, 1) == size(trafo.heights, 1) == size(trafo.derivatives, 1) == size(x, 1) >= 1 + @assert size(trafo.widths, 2) == size(trafo.heights, 2) == (size(trafo.derivatives, 2) + 1) >= 2 + + ndims = size(x, 1) + + w = _cumsum(_softmax(trafo.widths)) + h = _cumsum(_softmax(trafo.heights)) + d = _softplus(trafo.derivatives) + + w = hcat(repeat([-B,], ndims,1), w) + h = hcat(repeat([-B,], ndims,1), h) + d = hcat(repeat([1,], ndims,1), d) + d = hcat(d, repeat([1,], ndims,1)) + + return spline_backward(RQSplineInv(w, h, d), x) +end + +function spline_backward(trafo::RQSplineInv, x::AbstractMatrix{<:Real}) + return spline_backward(x, trafo.widths, trafo.heights, trafo.derivatives) +end + + +function spline_backward( + x::AbstractArray{M0}, + w::AbstractArray{M1}, + h::AbstractArray{M2}, + d::AbstractArray{M3}, + ) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real} + + T = promote_type(M0, M1, M2, M3) + + ndims = size(x, 1) + nsmpls = size(x, 2) + + y = zeros(T, ndims, nsmpls) + logJac = zeros(T, ndims, nsmpls) + + device = KernelAbstractions.get_device(x) + n = device isa GPU ? 256 : 4 + kernel! = spline_backward_kernel!(device, n) + + ev = kernel!(x, y, logJac, w, h, d, ndrange=size(x)) + + wait(ev) + + return y, sum(logJac, dims=1) +end + +@kernel function spline_backward_kernel!( + x::AbstractMatrix{M0}, + y::AbstractMatrix{M1}, + logJac::AbstractMatrix{M2}, + w::AbstractMatrix{M3}, + h::AbstractMatrix{M4}, + d::AbstractMatrix{M5} + ) where {M0<:Real, M1<:Real, M2<:Real, M3<:Real, M4<:Real, M5<:Real,} + + i, j = @index(Global, NTuple) + + K = size(w, 2) + + # Find the bin index + k1 = searchsortedfirst_impl(h[i,:], x[i,j]) - 1 + k2 = one(typeof(k1)) + + # Is inside of range + isinside = (k1 < K) && (k1 > 0) + k = Base.ifelse(isinside, k1, k2) + + x_tmp = Base.ifelse(isinside, x[i,j], h[i,k]) # Simplifies unnecessary calculations + (yᵢⱼ, LogJacᵢⱼ) = eval_backward_spline_params(w[i,k], w[i,k+1], h[i,k], h[i,k+1], d[i,k], d[i,k+1], x_tmp) + + y[i,j] = Base.ifelse(isinside, yᵢⱼ, x[i,j]) + logJac[i, j] += Base.ifelse(isinside, LogJacᵢⱼ, zero(typeof(LogJacᵢⱼ))) +end + +function eval_backward_spline_params( + wₖ::M0, wₖ₊₁::M0, + hₖ::M1, hₖ₊₁::M1, + dₖ::M2, dₖ₊₁::M2, + x::M3) where {M0<:Real,M1<:Real, M2<:Real, M3<:Real} + + Δy = hₖ₊₁ - hₖ + Δy2 = x - hₖ # use y instead of X, because of inverse + Δx = wₖ₊₁ - wₖ + sk = Δy / Δx + + a = Δy * (sk - dₖ) + Δy2 * (dₖ₊₁ + dₖ - 2*sk) + b = Δy * dₖ - Δy2 * (dₖ₊₁ + dₖ - 2*sk) + c = - sk * Δy2 + + denom = -b - sqrt(b*b - 4*a*c) + + y = (2 * c / denom) * Δx + wₖ + + # Gradient computation: + da = (dₖ₊₁ + dₖ - 2*sk) + db = -(dₖ₊₁ + dₖ - 2*sk) + dc = - sk + + temp2 = 1 / (2*sqrt(b*b - 4*a*c)) + + grad = 2 * dc * denom - 2 * c * (-db - temp2 * (2 * b * db - 4 * a * dc - 4 * c * da)) + LogJac = log(abs(Δx * grad)) - 2*log(abs(denom)) + + return y, LogJac +end + +# Utils: + +function _softmax(x::AbstractVector) + + exp_x = exp.(x) + sum_exp_x = sum(exp_x) + + return exp_x ./ sum_exp_x +end + +function _softmax(x::AbstractMatrix) + + val = cat([_softmax(i) for i in eachrow(x)]..., dims=2)' + + return val +end + +function _cumsum(x::AbstractVector; B = 5) + return 2 .* B .* cumsum(x) .- B +end + +function _cumsum(x::AbstractMatrix) + + return cat([_cumsum(i) for i in eachrow(x)]..., dims=2)' +end + +function _softplus(x::AbstractVector) + + return log.(exp.(x) .+ 1) +end + +function _softplus(x::AbstractMatrix) + + val = cat([_softplus(i) for i in eachrow(x)]..., dims=2)' + + return val +end + +midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01) +binary_log(x::T) where {T<:Integer} = 8 * sizeof(T) - leading_zeros(x - 1) + +function searchsortedfirst_impl( + v::AbstractVector, + x::Real + ) + + u = one(Integer) + lo = one(Integer) - u + hi = length(v) + u + + n = binary_log(length(v))+1 + m = one(Integer) + + @inbounds for i in 1:n + m_1 = midpoint(lo, hi) + m = Base.ifelse(lo < hi - u, m_1, m) + lo = Base.ifelse(v[m] < x, m, lo) + hi = Base.ifelse(v[m] < x, hi, m) + end + return hi +end