{ "cells": [ { "cell_type": "code", "execution_count": 124, "id": "3d049ef3-2630-4064-a2bd-ee28c7a89e9e", "metadata": {}, "outputs": [], "source": [ "using LinearAlgebra, Zygote, Tullio" ] }, { "cell_type": "markdown", "id": "cfa5d466-5354-4ef4-a4ab-2bf2ed69626e", "metadata": {}, "source": [ "### notes\n", "\n", "Notice how this approach estimates policy and the value function in a single go.\n", "While you could eliminate the value function partials, it would be much more complex.\n", "Note that in RL, both must be iterated on." ] }, { "cell_type": "code", "execution_count": 2, "id": "2bc6f9bd-8308-40a0-bee4-acbb1be4672d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#Model dimensions\n", "N_constellations = 5\n", "N_debris = 1\n", "N_states = N_constellations + N_debris" ] }, { "cell_type": "markdown", "id": "15670d3b-9651-4fc5-b98a-29ba60b4b38e", "metadata": {}, "source": [ "## Built Payoff functions" ] }, { "cell_type": "code", "execution_count": 156, "id": "1e99275a-9ab5-4c9e-921b-9587145b1fb5", "metadata": {}, "outputs": [], "source": [ "stocks = rand(1:N_constellations,N_constellations);\n", "debris = rand(1:3);\n", "payoff = 3*I + ones(5,5) .+ [1,0,0,0,0]; #TODO: move this into a struct\n", "β=0.95\n", "launches = ones(N_constellations);" ] }, { "cell_type": "code", "execution_count": 157, "id": "a4e4bbaf-61de-4860-adc2-1e91f0626ead", "metadata": {}, "outputs": [], "source": [ "#Define the market profit function\n", "F(stocks,debris,payoff,launches) = payoff*stocks + 3.0*launches .+ (debris*-0.2)\n", "\n", "#create derivative functions\n", "∂f_∂stocks(st,debris,payoff,launches) = Zygote.jacobian(s -> F(s,debris,payoff,launches),st)[1];\n", "∂f_∂debris(stocks,d,payoff,launches) = Zygote.jacobian(s -> F(stocks,s,payoff,launches),d)[1];\n", "∂f_∂launches(stocks,debris,payoff,launches) = Zygote.jacobian(l -> F(stocks,debris,payoff,l),launches)[1];\n" ] }, { "cell_type": "code", "execution_count": 158, "id": "ad73e64a-2fa5-4bdf-a4e4-22357b53002c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 5.0 2.0 2.0 2.0 2.0\n", " 1.0 4.0 1.0 1.0 1.0\n", " 1.0 1.0 4.0 1.0 1.0\n", " 1.0 1.0 1.0 4.0 1.0\n", " 1.0 1.0 1.0 1.0 4.0" ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂f_∂stocks(stocks,debris,payoff,launches) \n", "#Rows are constellations, columns are derivatives indexed by constellations" ] }, { "cell_type": "code", "execution_count": 159, "id": "a6159740-8ef2-40e0-b10f-c451cf78418d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5-element Vector{Float64}:\n", " -0.2\n", " -0.2\n", " -0.2\n", " -0.2\n", " -0.2" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂f_∂debris(stocks,debris,payoff,launches)" ] }, { "cell_type": "code", "execution_count": 160, "id": "b46da3d9-1765-4427-b3de-bf0a9fdd6576", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 3.0 0.0 0.0 0.0 0.0\n", " 0.0 3.0 0.0 0.0 0.0\n", " 0.0 0.0 3.0 0.0 0.0\n", " 0.0 0.0 0.0 3.0 0.0\n", " 0.0 0.0 0.0 0.0 3.0" ] }, "execution_count": 160, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂f_∂launches(stocks,debris,payoff,launches)" ] }, { "cell_type": "markdown", "id": "7a3a09cc-e48d-4c27-9e4f-02e45a5fc5c1", "metadata": {}, "source": [ "## Building Physical Model" ] }, { "cell_type": "code", "execution_count": 5, "id": "638ed4ac-36b0-4efb-bcb4-13d345470dd7", "metadata": {}, "outputs": [], "source": [ "struct BasicModel\n", " #rate at which debris hits satellites\n", " debris_collision_rate\n", " #rate at which satellites of different constellations collide\n", " satellite_collision_rates\n", " #rate at which debris exits orbits\n", " decay_rate\n", " #rate at which satellites\n", " autocatalysis_rate\n", " #ratio at which a collision between satellites produced debris\n", " satellite_collision_debris_ratio\n", " #Ratio at which launches produce debris\n", " launch_debris_ratio\n", "end\n", "\n", "#Getting loss parameters together.\n", "loss_param = 2e-3;\n", "loss_weights = loss_param*(ones(N_constellations,N_constellations) - I);\n", "\n", "#orbital decay rate\n", "decay_param = 0.01;\n", "\n", "#debris generation parameters\n", "autocatalysis_param = 0.001;\n", "satellite_loss_debris_rate = 5.0;\n", "launch_debris_rate = 0.05;\n", "\n", "#Todo, wrap physical model as a struct with the parameters\n", "bm = BasicModel(\n", " loss_param\n", " ,loss_weights\n", " ,decay_param\n", " ,autocatalysis_param\n", " ,satellite_loss_debris_rate\n", " ,launch_debris_rate\n", ");" ] }, { "cell_type": "code", "execution_count": 163, "id": "ae04a4f2-7401-450e-ba98-bfec375b7646", "metadata": {}, "outputs": [], "source": [ "#percentage survival function\n", "function survival(stocks,debris,physical_model) \n", " exp.(-physical_model.satellite_collision_rates*stocks .- (physical_model.debris_collision_rate*debris));\n", "end\n", "\n", "#stock update rules\n", "function G(stocks,debris,launches, physical_model)\n", " return diagm(survival(stocks,debris,physical_model) .- physical_model.decay_rate)*stocks + launches\n", "end;\n", "\n", "#stock evolution wrt various things\n", "∂G_∂launches(stocks,debris,launches,bm) = Zygote.jacobian(x -> G(stocks,debris,x,bm),launches)[1];\n", "∂G_∂debris(stocks,debris,launches,bm) = Zygote.jacobian(x -> G(stocks,x,launches,bm),debris)[1];\n", "∂G_∂stocks(stocks,debris,launches,bm) = Zygote.jacobian(x -> G(x,debris,launches,bm),stocks)[1];\n", "\n", "#debris evolution \n", "function H(stocks,debris,launches,physical_model)\n", " #get changes in debris from natural dynamics\n", " natural_debris_dynamics = (1-physical_model.decay_rate+physical_model.autocatalysis_rate) * debris \n", " \n", " #get changes in debris from satellite loss\n", " satellite_loss_debris = physical_model.satellite_collision_debris_ratio * (1 .- survival(stocks,debris,physical_model))'*stocks \n", " \n", " #get changes in debris from launches\n", " launch_debris = physical_model.launch_debris_ratio*sum(launches)\n", " \n", " #return total debris level\n", " return natural_debris_dynamics + satellite_loss_debris + launch_debris\n", "end;\n", "\n", "#get jacobians of debris dynamics\n", "∂H_∂launches(stocks,debris,launches,physical_model) = Zygote.jacobian(x -> H(stocks,debris,x,physical_model),launches)[1];\n", "∂H_∂debris(stocks,debris,launches,physical_model) = Zygote.jacobian(x -> H(stocks,x,launches,physical_model),debris)[1];\n", "∂H_∂stocks(stocks,debris,launches,physical_model) = Zygote.jacobian(x -> H(x,debris,launches,physical_model),stocks)[1];" ] }, { "cell_type": "code", "execution_count": 166, "id": "c6519b6e-f9ef-466e-a9ac-746b8f36b9e7", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 1.0 0.0 0.0 0.0 0.0\n", " 0.0 1.0 0.0 0.0 0.0\n", " 0.0 0.0 1.0 0.0 0.0\n", " 0.0 0.0 0.0 1.0 0.0\n", " 0.0 0.0 0.0 0.0 1.0" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂G_∂launches(stocks,debris,launches,bm)" ] }, { "cell_type": "code", "execution_count": 167, "id": "1d46c09d-2c91-4302-8e8d-1c0abeb010aa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5-element Vector{Float64}:\n", " -0.003843157756609293\n", " -0.009665715046375067\n", " -0.009665715046375067\n", " -0.009665715046375067\n", " -0.003843157756609293" ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂G_∂debris(stocks,debris,launches,bm)" ] }, { "cell_type": "code", "execution_count": 168, "id": "1f791c8a-5457-4ec2-bf0b-68eb6bdd578f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 0.950789 -0.00384316 -0.00384316 -0.00384316 -0.00384316\n", " -0.00966572 0.956572 -0.00966572 -0.00966572 -0.00966572\n", " -0.00966572 -0.00966572 0.956572 -0.00966572 -0.00966572\n", " -0.00966572 -0.00966572 -0.00966572 0.956572 -0.00966572\n", " -0.00384316 -0.00384316 -0.00384316 -0.00384316 0.950789" ] }, "execution_count": 168, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂G_∂stocks(stocks,debris,launches,bm)" ] }, { "cell_type": "code", "execution_count": 169, "id": "d97f9af0-d3a9-4739-b569-fa100a1590f3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1×5 Matrix{Float64}:\n", " 0.05 0.05 0.05 0.05 0.05" ] }, "execution_count": 169, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂H_∂launches(stocks,debris,launches,bm)" ] }, { "cell_type": "code", "execution_count": 170, "id": "1a7c857f-7eee-4273-b954-3a7b84a3b3e0", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1-element Vector{Float64}:\n", " 1.174417303261719" ] }, "execution_count": 170, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂H_∂debris(stocks,debris,launches,bm) " ] }, { "cell_type": "code", "execution_count": 171, "id": "9ea44146-740c-47c0-9286-846585a4db39", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1×5 Matrix{Float64}:\n", " 0.360254 0.302231 0.302231 0.302231 0.360254" ] }, "execution_count": 171, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂H_∂stocks(stocks,debris,launches,bm)\n", "#columns are derivatives" ] }, { "cell_type": "markdown", "id": "17038bfe-c7c2-484b-9aaf-6b608bbbbfab", "metadata": {}, "source": [ "## Build optimality conditions" ] }, { "cell_type": "markdown", "id": "ef3c7625-e5ee-4220-8bed-b289d0baea1e", "metadata": {}, "source": [ "## Build transition conditions\n", "\n", "I've built the transition conditions below." ] }, { "cell_type": "code", "execution_count": 172, "id": "c3ef6bcc-37ca-4f6c-b876-8ea2a068cbe1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 2.0 1.0 1.0 1.0 1.0\n", " 1.0 2.0 1.0 1.0 1.0\n", " 1.0 1.0 2.0 1.0 1.0\n", " 1.0 1.0 1.0 2.0 1.0\n", " 1.0 1.0 1.0 1.0 2.0" ] }, "execution_count": 172, "metadata": {}, "output_type": "execute_result" } ], "source": [ "W_∂stocks= ones(5,5) + I\n", "# columns are stocks\n", "# rows are derivatives" ] }, { "cell_type": "code", "execution_count": 174, "id": "5441641b-308b-4fec-a946-2568e79a1203", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×1 Matrix{Float64}:\n", " 2.0\n", " 2.0\n", " 2.0\n", " 2.0\n", " 2.0" ] }, "execution_count": 174, "metadata": {}, "output_type": "execute_result" } ], "source": [ " #temporary value partials\n", "W_∂debris = 2*ones(5,1) #temporary value partials\n", "#columns are\n", "#rows are" ] }, { "cell_type": "code", "execution_count": 106, "id": "819df0f9-e994-4461-9329-4c4607de8779", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 0.966286 -0.00195257 -0.00195257 -0.00195257 -0.00195257\n", " -0.00785729 0.972161 -0.00785729 -0.00785729 -0.00785729\n", " -0.00588119 -0.00588119 0.970199 -0.00588119 -0.00588119\n", " -0.00195257 -0.00195257 -0.00195257 0.966286 -0.00195257\n", " -0.00391296 -0.00391296 -0.00391296 -0.00391296 0.96824" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "∂G_∂stocks(stocks,debris,launches,bm)" ] }, { "cell_type": "code", "execution_count": 108, "id": "5cc19637-9727-479e-aa60-a30c71e9e8b8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×5 Matrix{Float64}:\n", " 1.91695 1.91695 1.91695 1.91695 1.91695\n", " 1.88146 1.88146 1.88146 1.88146 1.88146\n", " 1.89335 1.89335 1.89335 1.89335 1.89335\n", " 1.91695 1.91695 1.91695 1.91695 1.91695\n", " 1.90518 1.90518 1.90518 1.90518 1.90518" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = ∂f_∂stocks(stocks,debris,payoff,launches)\n", "b = ∂G_∂stocks(stocks,debris,launches,bm) * W_∂stocks #This last bit should eventually get replaced with a NN\n", "#Need to check dimensionality above. Not sure which direction is derivatives and which is functions." ] }, { "cell_type": "code", "execution_count": 119, "id": "65917e4c-bd25-4683-8553-17bc841e594a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5×1 Matrix{Float64}:\n", " -0.019525714195158184\n", " -0.07857288258866406\n", " -0.05881192039840531\n", " -0.019525714195158184\n", " -0.039129609402048404" ] }, "execution_count": 119, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = (∂G_∂debris(stocks,debris,launches,bm) .* ones(1,5)) * W_∂debris" ] }, { "cell_type": "code", "execution_count": 59, "id": "dd5ca5b4-c910-449c-a322-b24b3ef4ecf2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "49.45445380487922" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "loss(stocks,debris,payoff,launches)" ] }, { "cell_type": "code", "execution_count": 60, "id": "8ead6e86-3d03-48ff-bc3e-b3fa9808f981", "metadata": {}, "outputs": [], "source": [ "#TODO: create a launch model in flux and see if I can get it to do pullbacks" ] }, { "cell_type": "code", "execution_count": null, "id": "658ba7f0-dfbc-42da-bb20-7f8bccbb257d", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.6.2", "language": "julia", "name": "julia-1.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.6.2" } }, "nbformat": 4, "nbformat_minor": 5 }