From 3ca5312fabee4c4b3b7346b428799245bb9c38d7 Mon Sep 17 00:00:00 2001 From: youainti Date: Sat, 3 Jul 2021 20:04:39 -0700 Subject: [PATCH] got successful recursive generation for the euler equation stuff --- Code/TransitionDerivatives.ipynb | 402 ++++++++--------------------- Code/Untitled.ipynb | 80 ------ Code/composition_Exploration.ipynb | 242 +++++++++++++++++ Code/successful_recursion.ipynb | 239 +++++++++++++++++ 4 files changed, 583 insertions(+), 380 deletions(-) delete mode 100644 Code/Untitled.ipynb create mode 100644 Code/composition_Exploration.ipynb create mode 100644 Code/successful_recursion.ipynb diff --git a/Code/TransitionDerivatives.ipynb b/Code/TransitionDerivatives.ipynb index cd19f56..9cfb1c5 100644 --- a/Code/TransitionDerivatives.ipynb +++ b/Code/TransitionDerivatives.ipynb @@ -3,8 +3,10 @@ { "cell_type": "code", "execution_count": 1, - "id": "innovative-filename", - "metadata": {}, + "id": "committed-cincinnati", + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "import torch\n", @@ -14,7 +16,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "filled-question", + "id": "accepting-valentine", "metadata": {}, "outputs": [ { @@ -40,7 +42,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "middle-lease", + "id": "reserved-parallel", "metadata": {}, "outputs": [], "source": [ @@ -50,7 +52,7 @@ { "cell_type": "code", "execution_count": 4, - "id": "regular-grounds", + "id": "expected-consensus", "metadata": { "tags": [] }, @@ -62,20 +64,21 @@ { "cell_type": "code", "execution_count": 5, - "id": "satisfied-hawaiian", + "id": "cross-drain", "metadata": {}, "outputs": [], "source": [ - "scaling = torch.ones(5)\n", - "delta = 0.9 \n", - "launch_debris_rate = 0.05\n", - "collision_debris_rate = 0.07" + "#Parameters\n", + "SCALING = torch.ones(5)\n", + "DELTA = 0.9 \n", + "launch_debris_rate = 0.005\n", + "collision_debris_rate = 0.0007" ] }, { "cell_type": "code", "execution_count": 6, - "id": "saved-corporation", + "id": "charitable-frost", "metadata": {}, "outputs": [], "source": [ @@ -83,17 +86,18 @@ " #Gompertz distribution for simplicity\n", " #commonly used with saturation\n", " #TODO: ACTUALLY DERIVE A SURVIVAL FUNCTION. THIS IS JUST A PLACEHOLDER. PROBABLY SHOULD BE AN EXPONENTIAL DISTRIBUTION\n", - " eta = 1.0/(scaling@stock)\n", + " eta = 1.0/(SCALING@stock)\n", " b = 1/debris\n", " \n", " return 1 - ( b*eta*torch.exp(eta+b*stock-eta*torch.exp(b*stock)))\n", "\n", "\n", "def g(stock, debris, launches):\n", + " \n", " new_stock = stock*survival(stock,debris) + launches\n", " \n", - " #Ignoring autocatalysis\n", - " new_debris = (1-delta)*debris + launch_debris_rate * launches.sum() + collision_debris_rate*(1-survival(stock,debris)) @ stock\n", + " #TODO: Currently Ignoring autocatalysis\n", + " new_debris = (1-DELTA)*debris + launch_debris_rate * launches.sum() + collision_debris_rate*(1-survival(stock,debris)) @ stock\n", " \n", " return (new_stock, new_debris)\n" ] @@ -101,108 +105,7 @@ { "cell_type": "code", "execution_count": 7, - "id": "nominated-visitor", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([0.8600, 0.8600, 0.8600, 0.8600, 0.8802], grad_fn=)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "survival(stocks,debris)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "clean-panama", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(tensor([[-0.0142, 0.0271, 0.0271, 0.0271, 0.0271],\n", - " [ 0.0271, -0.0142, 0.0271, 0.0271, 0.0271],\n", - " [ 0.0271, 0.0271, -0.0142, 0.0271, 0.0271],\n", - " [ 0.0271, 0.0271, 0.0271, -0.0142, 0.0271],\n", - " [ 0.0251, 0.0251, 0.0251, 0.0251, -0.0142]]),\n", - " tensor([[0.0825],\n", - " [0.0825],\n", - " [0.0825],\n", - " [0.0825],\n", - " [0.0634]]))" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#Get the derivatives seperately\n", - "jacobian(survival, (stocks,debris))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "cardiovascular-music", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([[-0.0142, 0.0271, 0.0271, 0.0271, 0.0271, 0.0825],\n", - " [ 0.0271, -0.0142, 0.0271, 0.0271, 0.0271, 0.0825],\n", - " [ 0.0271, 0.0271, -0.0142, 0.0271, 0.0271, 0.0825],\n", - " [ 0.0271, 0.0271, 0.0271, -0.0142, 0.0271, 0.0825],\n", - " [ 0.0251, 0.0251, 0.0251, 0.0251, -0.0142, 0.0634]])" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#Get the derivatives as a single result\n", - "torch.cat(jacobian(survival, (stocks,debris)), axis=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "funky-illness", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(tensor([1.8600, 1.8600, 1.8600, 1.8600, 1.4401], grad_fn=),\n", - " tensor([0.5134], grad_fn=))" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#Testing state updates\n", - "g(stocks, debris, launch)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "charged-dairy", + "id": "nonprofit-vintage", "metadata": {}, "outputs": [ { @@ -223,24 +126,36 @@ " [0., 0., 1., 0., 0.],\n", " [0., 0., 0., 1., 0.],\n", " [0., 0., 0., 0., 1.]])),\n", - " (tensor([[0.0042, 0.0042, 0.0042, 0.0042, 0.0013]]),\n", - " tensor([[0.0747]]),\n", - " tensor([[0.0500, 0.0500, 0.0500, 0.0500, 0.0500]])))" + " (tensor([[4.2202e-05, 4.2202e-05, 4.2202e-05, 4.2202e-05, 1.2820e-05]]),\n", + " tensor([[0.0997]]),\n", + " tensor([[0.0050, 0.0050, 0.0050, 0.0050, 0.0050]])))" ] }, - "execution_count": 11, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "#Examples\n", + "survival(stocks,debris)\n", + "\n", + "#Get the derivatives seperately\n", + "jacobian(survival, (stocks,debris))\n", + "\n", + "#Get the derivatives as a single result\n", + "torch.cat(jacobian(survival, (stocks,debris)), axis=1)\n", + "\n", + "#Testing state updates\n", + "g(stocks, debris, launch)\n", + "\n", "#Note the two tuples of jacobians: the first is for stock evolution, the second is for debris evolution\n", "jacobian(g, (stocks,debris,launch))" ] }, { "cell_type": "markdown", - "id": "marked-flower", + "id": "future-greenhouse", "metadata": {}, "source": [ "## Next step: Construct the intertemporal-transition function(s)\n", @@ -254,102 +169,36 @@ }, { "cell_type": "code", - "execution_count": 12, - "id": "outdoor-action", + "execution_count": 8, + "id": "higher-brook", "metadata": {}, "outputs": [], "source": [ "#setup\n", "beta = torch.tensor([0.95])\n", "util_weights = torch.tensor([1.0,1.0,0,0,0])\n", - "sigma = 0.5" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "unavailable-hawaii", - "metadata": {}, - "outputs": [], - "source": [ - "#This is not a good specification of the profit function, but it will work for now.\n", - "def util(x):\n", - " return (util_weights@x)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "composite-cooperative", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor(2., grad_fn=)" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "util(stocks)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "activated-advancement", - "metadata": {}, - "outputs": [], - "source": [ + "sigma = 0.5\n", + "\n", "w = torch.zeros(5)\n", "w[0]=1" ] }, { "cell_type": "code", - "execution_count": 16, - "id": "wireless-concord", + "execution_count": 9, + "id": "approximate-motivation", "metadata": {}, "outputs": [], "source": [ + "#This is not a good specification of the profit function, but it will work for now.\n", + "def util(x):\n", + " return (util_weights@x)\n", + "\n", "def single_transition(w, g, util, stocks, debris, launch, beta):\n", " #TODO: change launch from a direct tensor, to a function.\n", " bA = beta * jacobian(g, (stocks,debris,launch))[0][0]\n", - " return bA.inverse() @ (w - jacobian(util,stocks))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "detected-cooking", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([ 0.0372, -1.2487, 0.0372, 0.0372, 0.0164])" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "single_transition(w,g,util,stocks,debris,launch,beta)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "sharp-pound", - "metadata": {}, - "outputs": [], - "source": [ + " return bA.inverse() @ (w - jacobian(util,stocks))\n", + "\n", "#need to create recursive transitions\n", "def recurse_transitions(w, g, util, stocks, debris, launch, beta, iterations):\n", " #This is of type two from the discussion above\n", @@ -359,7 +208,7 @@ " #Get recursive results\n", " curse = recurse_transitions(w,g,util,stocks,debris,launch,beta,iterations-1)\n", " \n", - " #Get updated stocks and debris\n", + " #Get updated stocks and debris \n", " stocks_iterated,debris_iterated = g(stocks, debris, launch) \n", " \n", " #Return the updated values\n", @@ -368,8 +217,8 @@ }, { "cell_type": "code", - "execution_count": 19, - "id": "radical-reason", + "execution_count": 10, + "id": "prescribed-unemployment", "metadata": {}, "outputs": [ { @@ -378,157 +227,110 @@ "tensor([ 0.0372, -1.2487, 0.0372, 0.0372, 0.0164])" ] }, - "execution_count": 19, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "recurse_transitions(w, g, util, stocks, debris, launch, beta, 1)" + "single_transition(w,g,util,stocks,debris,launch,beta)" ] }, { "cell_type": "code", - "execution_count": 20, - "id": "intelligent-angle", + "execution_count": 11, + "id": "ordinary-admission", "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "tensor([-0.4740, -1.0278, -0.0434, -0.0434, -0.0575])" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([ 0.0372, -1.2487, 0.0372, 0.0372, 0.0164])\n", + "tensor([-1.0135, -2.3671, 0.0391, 0.0391, 0.0172])\n", + "tensor([-2.1195, -3.5443, 0.0412, 0.0412, 0.0181])\n" + ] } ], "source": [ - "recurse_transitions(w, g, util, stocks, debris, launch, beta, 2)" + "r1 = recurse_transitions(w, g, util, stocks, debris, launch, beta, 1)\n", + "r2 = recurse_transitions(w, g, util, stocks, debris, launch, beta, 2)\n", + "r3 = recurse_transitions(w, g, util, stocks, debris, launch, beta, 3)\n", + "\n", + "print(r1)\n", + "print(r2)\n", + "print(r3)" ] }, { "cell_type": "code", - "execution_count": 21, - "id": "jewish-lemon", + "execution_count": 12, + "id": "committed-porcelain", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([-0.7046, -0.9430, -0.0884, -0.0884, -0.1102])" + "(tensor([1.8600, 1.8600, 1.8600, 1.8600, 1.4401], grad_fn=),\n", + " tensor([0.2454], grad_fn=),\n", + " tensor([2.8600, 2.8600, 2.8600, 2.8600, 2.4401], grad_fn=),\n", + " tensor([0.0495], grad_fn=))" ] }, - "execution_count": 21, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "recurse_transitions(w, g, util, stocks, debris, launch, beta, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "scenic-literature", - "metadata": {}, - "outputs": [], "source": [ "#TODO: manually check single_transition\n", "stocks_1,debris_1 = g(stocks, debris, launch) \n", - "stocks_2,debris_2 = g(stocks_1, debris_1, launch)" + "stocks_2,debris_2 = g(stocks_1, debris_1, launch)\n", + "stocks_1,debris_1,stocks_2,debris_2" ] }, { "cell_type": "code", - "execution_count": 28, - "id": "moving-slave", + "execution_count": 13, + "id": "touched-judge", "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "tensor([ 0.0372, -1.2487, 0.0372, 0.0372, 0.0164])" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([ 0.0372, -1.2487, 0.0372, 0.0372, 0.0164])\n", + "tensor([-1.0135, -2.3671, 0.0391, 0.0391, 0.0172])\n", + "tensor([-2.1195, -3.5443, 0.0412, 0.0412, 0.0181])\n" + ] } ], "source": [ "#Recurse 1\n", "sin1 = single_transition(w,g,util,stocks,debris,launch,beta)\n", - "sin1" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "corrected-radar", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([-0.4740, -1.0278, -0.0434, -0.0434, -0.0575])" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ "#Recurse 2\n", - "sin2 = single_transition(sin1 \n", - " ,g\n", - " ,util\n", - " ,stocks_1\n", - " ,debris_1\n", - " ,launch,beta)\n", - "sin2" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "handy-pencil", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([-1.5516, -2.1345, -0.0456, -0.0456, -0.1302])" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ + "sin2 = single_transition(sin1 ,g,util,stocks_1,debris_1,launch,beta)\n", "#recurse 3\n", - "single_transition(sin2,g,util,stocks_2,debris_2,launch,beta)" + "sin3 = single_transition(sin2,g,util,stocks_2,debris_2,launch,beta)\n", + "\n", + "print(sin1)\n", + "print(sin2)\n", + "print(sin3)" ] }, { "cell_type": "code", - "execution_count": 37, - "id": "attempted-affairs", + "execution_count": 14, + "id": "cooked-absence", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([-1.5516, -2.1345, -0.0456, -0.0456, -0.1302])" + "tensor([-2.1195, -3.5443, 0.0412, 0.0412, 0.0181])" ] }, - "execution_count": 37, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -539,17 +341,17 @@ }, { "cell_type": "code", - "execution_count": 39, - "id": "honest-diana", + "execution_count": 15, + "id": "accepting-grade", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([-0.7046, -0.9430, -0.0884, -0.0884, -0.1102])" + "tensor([-2.1195, -3.5443, 0.0412, 0.0412, 0.0181])" ] }, - "execution_count": 39, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -562,7 +364,7 @@ { "cell_type": "code", "execution_count": null, - "id": "animated-nudist", + "id": "indoor-papua", "metadata": {}, "outputs": [], "source": [] diff --git a/Code/Untitled.ipynb b/Code/Untitled.ipynb deleted file mode 100644 index 2402f0a..0000000 --- a/Code/Untitled.ipynb +++ /dev/null @@ -1,80 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "complicated-passage", - "metadata": {}, - "source": [ - "testing a recursive function builder" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "alone-individual", - "metadata": {}, - "outputs": [], - "source": [ - "def base(x,depth):\n", - " return \"y\"+base(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "sustainable-closing", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'yyyx'" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "base(\"x\",3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "systematic-actor", - "metadata": {}, - "outputs": [], - "source": [ - "def all_your(fn,depth1):\n", - " if depth1 <= 0:\n", - " return fn\n", - " else:\n", - " ifn = all_your(fn,depth-1)\n", - " return fn(ifn)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/Code/composition_Exploration.ipynb b/Code/composition_Exploration.ipynb new file mode 100644 index 0000000..a3dafa3 --- /dev/null +++ b/Code/composition_Exploration.ipynb @@ -0,0 +1,242 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 28, + "id": "taken-punch", + "metadata": {}, + "outputs": [], + "source": [ + "import copy\n", + "import itertools" + ] + }, + { + "cell_type": "markdown", + "id": "driving-booth", + "metadata": {}, + "source": [ + "testing a recursive function builder" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "permanent-training", + "metadata": {}, + "outputs": [], + "source": [ + "def compose(f,g):\n", + " return lambda *args, **kwds: f(g(*args,**kwds))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "editorial-alliance", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b'] c\n" + ] + } + ], + "source": [ + "print([\"a\",\"b\"],\"c\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "isolated-headset", + "metadata": {}, + "outputs": [], + "source": [ + "def appnd(lst,val):\n", + " lst.append(val)\n", + " return lst" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "thirty-latter", + "metadata": {}, + "outputs": [], + "source": [ + "def traverse_split_right(tuplists):\n", + " lst1,lst2 = tuplists\n", + " lst1.append(lst2.pop(0))\n", + " return (lst1,lst2)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "oriented-context", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(['a', 'b'], ['c'])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "traverse_split_right(([\"a\"],[\"b\",\"c\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "unsigned-settlement", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(['a', 'b', 'c'], ['d', 'e', 'f'])\n", + "(['a', 'b', 'c', 'd', 'e'], ['f'])\n" + ] + } + ], + "source": [ + "args = (\n", + " [\"a\",\"b\",\"c\"],\n", + " [\"d\",\"e\",\"f\"]\n", + " )\n", + "print(args)\n", + "\n", + "flist = [traverse_split_right,traverse_split_right,print]\n", + "rflist = list(reversed(flist))\n", + "\n", + "co = compose(rflist[0],compose(rflist[1],rflist[2]))\n", + "\n", + "co(args)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "satellite-sacrifice", + "metadata": {}, + "outputs": [], + "source": [ + "flist = [traverse_split_right,traverse_split_right,traverse_split_right]\n", + "\n", + "out_func = None\n", + "out_func_list =[]\n", + "\n", + "for f in itertools.repeat(traverse_split_right,3):\n", + " if out_func == None:\n", + " out_func = f\n", + " else:\n", + " out_func = compose(f,out_func)\n", + " \n", + " out_func_list.append(out_func)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "certified-track", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(['a'], ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b'], ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b', 'c'], ['d', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h', 'i', 'j'])\n" + ] + } + ], + "source": [ + "#test the list\n", + "args = (\n", + " [\"a\"],\n", + " [\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\"]\n", + " )\n", + "print(args)\n", + "\n", + "for fn in out_func_list:\n", + " #reset the data each time\n", + " a = copy.deepcopy(args)\n", + " print(fn(a))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "interesting-moral", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(['a'], ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b'], ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b'], ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b'], ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n", + "(['a', 'b'], ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n" + ] + } + ], + "source": [ + "#test a non-composed list of functions\n", + "args = (\n", + " [\"a\"],\n", + " [\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\"]\n", + " )\n", + "print(args)\n", + "for fn in itertools.repeat(traverse_split_right,4):\n", + " #Reset the data each time\n", + " a = copy.deepcopy(args)\n", + " \n", + " print(fn(a))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "incorrect-migration", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Code/successful_recursion.ipynb b/Code/successful_recursion.ipynb new file mode 100644 index 0000000..c7b92a0 --- /dev/null +++ b/Code/successful_recursion.ipynb @@ -0,0 +1,239 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "linear-harvey", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import torch\n", + "from torch.autograd.functional import jacobian\n", + "import itertools" + ] + }, + { + "cell_type": "markdown", + "id": "honey-excuse", + "metadata": {}, + "source": [ + "# Setup Functions\n", + "## General CompositionFunctions" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "helpful-radical", + "metadata": {}, + "outputs": [], + "source": [ + "### Set up functions to compose functions \n", + "# These functions will \n", + "# - compose two functions together\n", + "# - compose a function to itself n times.\n", + "\n", + "def compose(f,g):\n", + " return lambda *args: f(g(*args))\n", + "\n", + "def compose_recursive_functions(fn,n):\n", + " #Set base conditions\n", + " out_func = None\n", + " out_func_list =[]\n", + "\n", + " #build the compositions of functions\n", + " for f in itertools.repeat(fn, n):\n", + " if out_func == None:\n", + " out_func = f\n", + " else:\n", + " out_func = compose(f,out_func)\n", + "\n", + " out_func_list.append(out_func)\n", + " \n", + " return out_func_list" + ] + }, + { + "cell_type": "markdown", + "id": "fifty-southwest", + "metadata": {}, + "source": [ + "## Setup functions related to the problem" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "fancy-manual", + "metadata": {}, + "outputs": [], + "source": [ + "### Background functions\n", + "\n", + "\n", + "def survival(stock, debris):\n", + " #Gompertz distribution for simplicity\n", + " #commonly used with saturation\n", + " #TODO: ACTUALLY DERIVE A SURVIVAL FUNCTION. THIS IS JUST A PLACEHOLDER. PROBABLY SHOULD BE AN EXPONENTIAL DISTRIBUTION\n", + " eta = 1.0/(SCALING@stock)\n", + " b = 1/debris\n", + " \n", + " return 1 - ( b*eta*torch.exp(eta+b*stock-eta*torch.exp(b*stock)))\n", + "\n", + "\n", + "def laws_of_motion(stock, debris, launches):\n", + " \n", + " new_stock = stock*survival(stock,debris) + launches #TODO: Launches will become a function (neural network)\n", + " \n", + " #TODO: Currently Ignoring autocatalysis\n", + " new_debris = (1-DELTA)*debris + LAUNCH_DEBRIS_RATE * launches.sum() + COLLISION_DEBRIS_RATE*(1-survival(stock,debris)) @ stock\n", + " \n", + " return (new_stock, new_debris)\n", + "\n", + "#This is not a good specification of the profit function, but it will work for now.\n", + "def profit(x):\n", + " return UTIL_WEIGHTS @ x" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "dietary-vault", + "metadata": {}, + "outputs": [], + "source": [ + "def single_transition(item_to_iterate, laws_motion, profit,launch, stocks, debris ):\n", + " #TODO: change launch from a direct tensor, to a function.\n", + " \n", + " #Calculate the inverse\n", + " bA = BETA * jacobian(laws_motion, (stocks,debris,launch))[0][0]\n", + " #TODO: figure out some diagnostics for this section\n", + " \n", + " \n", + " return bA.inverse() @ (item_to_iterate - jacobian(profit,stocks))\n", + "\n", + "# This function wraps the single transition and handles updating dates etc.\n", + "def transition_wrapper(data_in):\n", + " #unpack states and functions\n", + " stocks, debris,profit, launch, laws_motion,item_to_transition = data_in\n", + " \n", + " #Calculate new states\n", + " new_stocks, new_debris = laws_motion(stocks,debris,launch)\n", + " \n", + " #WARNING: RECURSION: You may break your head...\n", + " #This gets the transition of the value function derivatives over time.\n", + " transitioned = single_transition(\n", + " item_to_transition, #item to iterate, i.e. the derivatives of the value function\n", + " laws_motion, profit, launch, #functions #TODO: reimplement with launch as a function\n", + " stocks, debris #states\n", + " )\n", + " \n", + " #collects the data back together for return, including the updated state variables\n", + " data_out = new_stocks, new_debris, profit, launch, laws_motion, transitioned\n", + " \n", + " return data_out" + ] + }, + { + "cell_type": "markdown", + "id": "illegal-thriller", + "metadata": {}, + "source": [ + "# Actual calculations" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "coated-dressing", + "metadata": {}, + "outputs": [], + "source": [ + "#set states\n", + "stocks = torch.ones(5)\n", + "#Last one is different\n", + "stocks[-1] = 0.5\n", + "#now add the tracking requirement in place\n", + "stocks.requires_grad_()\n", + "\n", + "#Setup Debris\n", + "debris = torch.tensor([2.2],requires_grad=True)\n", + "\n", + "#CHANGE LATER: Launch is currently a value, should be a function (i.e. neural network)\n", + "launch = torch.ones(5, requires_grad=True)\n", + "\n", + "#compose the functions together.\n", + "base_data = (stocks,debris, profit, launch, laws_of_motion, torch.ones(5, requires_grad=True))\n", + "\n", + "#Parameters\n", + "SCALING = torch.ones(5)\n", + "DELTA = 0.9 \n", + "LAUNCH_DEBRIS_RATE = 0.005\n", + "COLLISION_DEBRIS_RATE = 0.0007\n", + "UTIL_WEIGHTS = torch.tensor([1,-0.2,0,0,0])\n", + "BETA = 0.95" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "analyzed-transfer", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([-0.1543, 1.3888, 1.1316, 1.1316, 1.1553], grad_fn=)\n", + "tensor([-1.2150, 1.6724, 1.1912, 1.1912, 1.2161], grad_fn=)\n", + "tensor([-2.3316, 1.9710, 1.2539, 1.2539, 1.2801], grad_fn=)\n", + "tensor([nan, nan, nan, nan, nan], grad_fn=)\n", + "tensor([nan, nan, nan, nan, nan], grad_fn=)\n" + ] + } + ], + "source": [ + "#calculate results for first 5 iterations\n", + "for f in compose_recursive_functions(transition_wrapper,5):\n", + " result = f(base_data)\n", + " print(result[5])" + ] + }, + { + "cell_type": "markdown", + "id": "confidential-stadium", + "metadata": {}, + "source": [ + "Note how this fails on the last few iterations.\n", + "I need to get better model functions (profit, laws_of_motion, etc) together to test this out.\n", + "\n", + "Maybe with a standard RBC model?\n", + "\n", + "Also, maybe I can create a `Model` class that upon construction will capture the necesary constants, functions, etc." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}