got successful recursive generation for the euler equation stuff

temporaryWork
youainti 5 years ago
parent 58f10e54ea
commit 3ca5312fab

@ -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=<RsubBackward1>)"
]
},
"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=<AddBackward0>),\n",
" tensor([0.5134], grad_fn=<AddBackward0>))"
]
},
"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=<DotBackward>)"
]
},
"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",
@ -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])"
"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"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"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=<AddBackward0>),\n",
" tensor([0.2454], grad_fn=<AddBackward0>),\n",
" tensor([2.8600, 2.8600, 2.8600, 2.8600, 2.4401], grad_fn=<AddBackward0>),\n",
" tensor([0.0495], grad_fn=<AddBackward0>))"
]
},
"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])"
"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"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"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": []

@ -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
}

@ -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
}

@ -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=<MvBackward>)\n",
"tensor([-1.2150, 1.6724, 1.1912, 1.1912, 1.2161], grad_fn=<MvBackward>)\n",
"tensor([-2.3316, 1.9710, 1.2539, 1.2539, 1.2801], grad_fn=<MvBackward>)\n",
"tensor([nan, nan, nan, nan, nan], grad_fn=<MvBackward>)\n",
"tensor([nan, nan, nan, nan, nan], grad_fn=<MvBackward>)\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
}
Loading…
Cancel
Save