{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import boolean2\n", "import pylab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Define a model with its initial condition" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# This initial condition leads to a cycle of period 4.\n", "# If A is set to False, a steady state is obtained.\n", "text = \"\"\"\n", "A = D = True\n", "B = C = False\n", "\n", "B *= A or C\n", "C *= A and not D\n", "D *= B and C\n", "\"\"\"\n", "\n", "model = boolean2.Model( text=text, mode='sync')\n", "model.initialize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Simulations" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "model.iterate( steps=15 )" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]\n", "B [False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]\n", "C [False, False, True, True, False, False, True, True, False, False, True, True, False, False, True, True]\n", "D [True, False, False, True, True, False, False, True, True, False, False, True, True, False, False, True]\n" ] } ], "source": [ "# the model data attribute holds the states keyed by nodes\n", "for node in model.data:\n", " print(node, model.data[node])" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True False False True\n", "True True False False\n", "True True True False\n", "True True True True\n", "True True False True\n", "True True False False\n", "True True True False\n", "True True True True\n", "True True False True\n", "True True False False\n", "True True True False\n", "True True True True\n", "True True False True\n", "True True False False\n", "True True True False\n", "True True True True\n" ] } ], "source": [ "# Successive states are also available\n", "for state in model.states:\n", " print(state.A, state.B, state.C, state.D)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cycle detection" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Cycle of length 4 starting at index 1\n" ] } ], "source": [ "# this is a helper function that reports the cycle lengths \n", "# and the index at wich the cycle started\n", "model.report_cycles()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 4)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the same thing as above but\n", "# will not print only return the two parameters\n", "model.detect_cycles()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot of a trajectory" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO2de5DcV5XfP0ejtyzrrZFmuu1RvDaLzdpaWzGGDRsCIdiwhchuttaOg70EyqVavMHZpBZTVLbY2trYKfIwKcw6ghDYQoXLZePgELNeLw9TFHiRTOQXxqxiYrqlkTSSrYf1fpz8cfvardE8uud3f7/7+N1P1ZQ03T33d/r073fuuef3PbdFVclkMplM/MzybUAmk8lk3JADeiaTySRCDuiZTCaTCDmgZzKZTCLkgJ7JZDKJMNvXgVeuXKkjIyO+Dp/JZDJR8tRTT+1T1VUTPectoI+MjLBt2zZfh89kMpkoEZGXJ3sul1wymUwmEXJAz2QymUTIAT2TyWQSIQf0TCaTSYQc0DOZTCYRckDPZDKZRMgBPZPJZBIhB/RMJpNJhBzQM5lMJhFyQM9kMplEyAE9k8lkEiEH9Ewmk0mEHNAzmUwmEaYN6CLyJRHZKyLPTfK8iMh/FZEdIvKMiFzt3szy2LIFRkZg1izz75YtBQZbswZEzv9ZsyaM8To4fc+ux8s+DM+HJY2ZfejmXDwHVZ3yB/hN4GrguUmefx/wLUCA64C/nW5MVeWaa65R33z1q6oLF6rCGz8LF5rHZ0T3QON/QhhP3b/n7MMa+LCEMbMPZz4msE0niavT7oeuqt8XkZEpXrIR+MvOgZ4UkaUislZVR4tMNFXwqU/B0aPnPnb0KPzRH8Hq1f2P954pnnvq7sf7Hu+aKZ57vP/hAPPeXL5n1+NlHxYfz7UPwb0fsw/LQUwcnuZFJqB/U1XfMsFz3wTuVtUfdH7/NvAJVT3v2ytE5DbgNoCLLrrompdfnnSf9kqYNctMj65QxN1g0yA4NDwgsg+LU6UPIU0/Vu3DfgKRiDylqhsmes7FNxZN9M4ntE5VNwObATZs2OD9LLjoIphoThkchIcemsGA/2Dyp575/A/6Hu7KP5h8wB/0PxwAv/M7sGfP+Y/P9D27Hi/7sPh4rn0I7v2YfVgSk9Viun+AESavof834Kau318E1k43Zig19HnzAq675fpv9uFMCLj+a8k+LKeG7iKgv59zb4r+uJcxQwjoqqof/ajxgojqxRcXOAFUVQcHJ/6wBgfDGK/DV79q3quT9+x6vOzD8HxY0pjZhzMbs1BAB74GjAKngDbwEWATsKnzvAD3Av8XeBbYMN2YGlBA//SnzQlw8qSjAX/8Y+PWb3zD0YCqeuKEMfJP/9TdmCFz+LDx4V13uR330ktVf+/33I4ZMhddpHrLLW7H3LhR9dd+ze2YIXP99aobNvi24hymCui9qFxumuZ5BT7WS3knRFotIwOdM8fhgADNpqMBgblzTTHQjp067bb516UP7Xh18eGZM7BzZzk+fOIJt2OGTKsFl13m24qeqX2naKsFjYbjAcHxoJ3x6hKMsg+Ls3u3Cepl+PDAAXjtNbfjhorzAFEutQ/o7bbjJKbdhvnzYeVKh4NijLSZa+qUmaHv2mUCXeqU6cPu8VPm0CHz49qHJVL7gN5qOf687IwujnWsdSoX2Pc5POx23GbTBPPdu92OGyJllP66x6vDuVjWpFgitQ7oBw/C4cMllFzKWKI1Gm9kDKnTapn2vnnz3I5rP5c6BKMyy1bd46dMWT4skVoH9FImYOc1nA51WupmHxan3YaFC2HZMrfjDg+b1WddfAg5Q48F56vSspQFUK+lrvM6WIc6+tB16a9OiqtWy/hvaMi3JT2TAzoOV1RlKQugfkvdMny4dKnJWrMPi1EXtZBzTXP51Dqgt9tmgy5nE3CZS7ShoXosdctUFojURy1UVtkKsg8DptYBvdWCtWthtostyuyAUM5JMGeOMTb1zKjsumUd1EKnTxt5ZvZhMcoq/ZVI7QN6FE1FljosdbMPizM6CmfPluvD1BVXqtE1FUHNA3opTUULFsDy5Q4H7aIOS90qMvTRUZPFpkoVPuw+ToocOmS6YXOGHgd2AnbeVFSGssBil7pmU7Q0KVtZ0Gya7HU0+C/Umjlllv66x015pVO2D0uitgH9wAE4ciSSpiJLo2GyhoMHyzuGb1otI4ubO7ec8eugFqqibNV9nBSJsKkIahzQo2oqstRhqZt9WJx2Gy64AJYsKWf8OiiuImwqghoHdOcrqrKVBVCfpW72YTHKLv3VQXHVahlN89q1vi3pi9oHdGcrqrKVBZD+UrcKZcGFF5rsNVUfQjXqjNTVQs41zdVQ24DebsPAgMMJuIol2tq1JmtI9UKqQllgm4tS9SFU0xCTuuIqwqYiqHFAb7VMKXBgwOGAUO5JMHu2MTrVC6kqZUHKwejUKbNarMKHKSuuImwqgpoH9KiaiiwpL3WzD4uza5cJslX4MFXFVaRNRVDjgF5KU9GiRWYDqDJJuVxQlbKg2TQbqZ08We5xfFClD7uPlxIHDsDRozlDj4Uom4ostlyQ4lK3KmVBs2n8l2JzUZVlq+7jpUSkTUVQ04D+yitw7FhkTUWWRsNkD6++Wv6xqqaq7UpTVgtVWbbqPl5KRNpUBDUN6FE2FVlSzoyyD4vTbhtp5oUXlnscq7hKseQSaVMR1DSgO19RVaUsgLRrl1UpC7IPi2MVVylOiq2Wkb+tWePbkr6pdUB3tqKqSlkA6S51q1QWLF5sMtjUfAjVqjNSVQs51zRXRy0DerttEozBQYcDQjWZ0Zo1xvjULqSqlQWpqoWqbIhJVc8faVMR1DSgt1rmy8ujaiqyDAyk2VxUtbIgxWB08iTs2VP9pJia4irSpiKocUCPsqnIkuJSN/uwODt3Vlf6gzQVVxE3FUGPAV1ErheRF0Vkh4jcOcHzS0Tkf4nI0yLyvIh82L2p7iilqWjx4vK2Kx1PiuWCqpUFzabJZk+cqOZ4VeDDh93HTYFXXoHjx9PN0EVkALgXuAG4HLhJRC4f97KPAT9V1auAdwL/SURK+oaCYqiWENCrXqKl2FxklQVVbVdqP69du6o5XhX4KFt1HzcFIm4qgt4y9GuBHar6kqqeBO4HNo57jQKLRUSAC4BXgCC/tHHfPjMBR9lUZGk0zJvYv7+6Y5aN3a60KmVBimohH2Wr7uOmQMRNRdBbQB8Guj+xduexbj4HvBnYBTwLfFxVz44fSERuE5FtIrJtbGxshiYXI+qmIkuKmVH2YXHabbOX0AUXVHM8q7hKqeQScVMR9BbQJ9qcZPxa/73AdmAIWA98TkTOa1VT1c2qukFVN6xatapvY13gfEVVtbIA0qxdVl22shlY9uHMsYqrlCbFVsuxprlaegnobaD7LGlgMvFuPgx8XQ07gF8Av+rGRLc4X1FVrSyA9Ja6PpQFF1xgstlUfAh+1BmpqYWspnlWnALAXqzeClwqIus6NzpvBB4Z95pfAu8GEJFB4E3ASy4NdUW7bfZ+Wr3a4YBQbWY0OGjeRCoXki9lQWpqIR8NManp+SNuKoIeArqqngZuBx4DXgAeUNXnRWSTiGzqvOzPgLeLyLPAt4FPqOq+sowugk1inE3APu6Kz5plsohULiRfyoKUgtGJE7B3r79JMRXFVcRNRQA9fQOqqj4KPDrusfu6/r8L+CduTSuH6JuKLCktdX36cOvWao9ZFnZi8uFDq7haubLaY7vGapp/+7d9WzJj4iwUFaCUpqIlS0xjUZWkVC7wpSxoNmFszASk2PHpw+7jx8y+fWalE3GGXquAfvZsAk1FlpSai3wpC+zntnNntcctA59lq+7jx0zkTUVQs4A+NmZUhlE3FVkaDfNmPOn5neJru9KU1EI+y1bdx4+ZyJuKoGYBPYmmIktKmVH2YXHabVi+HBYurPa4VnGVQskl8qYiqFlAd76i8qUsgLRql77KVik1F/nyoVVcpTAptlowdy54anp0QS0DurMVlS9lQfcxY7+QrLLAhw8XLjRZbew+BL9bvqaiuIq8qQhqFtDbbZg3z+EE7HOJtmqVySZiv5B8KwtSUQv5bIhJRc8feVMR1Cyg2yRGJtqdZqYDgt+lbuwXkm9lQaMRvw+PHTMTo88MPQXFVcRfbGGpZUB3OiD4OwlSyC6zD4vj+2Zes2lWWTErrkrRNFdPrQJ6KU1Fy5bBokUOB+2DHIyK02yaLsejR/0c3wUh+LDbjhgZG4NTp3JAj4WzZ03/SBJNRZZGw7yps+dtPR8PrZbj3dL6xK4MYm4u8r3KSeEGvW8fOqI2AX3PHjMBJ9FUZGk2zZvau9efDUXxrSxIQYvuOxil5MOcocdBUk1FlhQupOzD4rTbZmOsBQv8HN8qrmIuufguWzmiNgHd+QRslQW+Sy4Q94Xku2w13Pk2xdh96HOlmEJzUatlNM2R7xhZu4CeRFORJfbs0ioLfPpwwQJzEcfqQ/A/KUL8N+ida5r9UJuA3m7D/PmwYoXDAcHvhbRypckqYr2QQlEWxB6MfJetIP7mohB86IDaBHSbxCTRVGQRibsxJgQfQtw+PHrUfIWfb3WG9WGsiivfZStH1Cqgl9JUZGuwvog5u/StzrCk4EPfk2LMiqszZ0rQNPuhNgG9lKaiFSuq3650PDEHoxDKVvb4r74KR474tWMmhORDiHOls3cvnD7t34cOqEVAL2UCDuFGFJjsdtcu8yZjI5TtSmNWC4Wyyom5uSgUHzqgFgF9924T75JqKrI0mya72LPHtyX9E4qyIGa1UCjBKAUfhpCgFaQWAT3JpiJLzBdS9mFx2m2zbcK8eX7tsIqrGFc5oZStHFCLgO58ArbKghBOgNjLBSH4MObmolBWilZxFeOk2GoZTfPy5b4tKUytArqz8z6kJVqs2WVIyoJ580yWG5sPIZxJEeK9Qe9c0+yPWgT0dtuIUZYtczgghJEZLV9uuh1ju5CssiAEH0K8wSiUshXE21wUkg8LUouAnmRTkSXW5qKQfAhx+vC11+DAgXAmRbudc2yKq1DKVg6oTUBPsqnIEmN2GVpAzz4sToyKqzNnjOw3FB8WpKeALiLXi8iLIrJDRO6c5DXvFJHtIvK8iDzh1sxiOC8ztttGOz1/vsNBCxBjMAqpbAXGhwcPwuHDvi3pndDUGTE2F1lNcyg+LMi0AV1EBoB7gRuAy4GbROTyca9ZCnwe+ICqXgH8bgm2zojTp2F0NNGmIkujYd7k6dO+LekdqyxwtltaQWJUC4WiQbfE2FwUmg8L0kuGfi2wQ1VfUtWTwP3AxnGv+efA11X1lwCqGsyGDqOjZr8g5yWXkAJ6s2myjN27fVvSO6EpC2JUC7Vaxn8hlf4gPh9CWNdzAXoJ6MNA9yfU7jzWzWXAMhH5nog8JSK3TDSQiNwmIttEZNtYRd8QXsrn5XsP7/HEeCFlHxan3YbBQbN9QghYxVVMq5zQylYF6SWgT5RC6bjfZwPXAO8H3gv8OxG57Lw/Ut2sqhtUdcOqivbvcP55WWVBSCdArOWCkHw4NGSy3dh8GNKkGGNzUatlNM1Ll/q2xAmze3hNG+i+8hrArgles09VjwBHROT7wFXAz51YWYCkm4ossWWXISoL5s412W4sPgRj65ve5NuKc4ntBn1opb+C9JKhbwUuFZF1IjIXuBF4ZNxrvgG8Q0Rmi8hC4K3AC25NnRmtFlxwASxZ4mjA0NQZYLKLRYviuZBK2S3NAbEFoxAbYmJrLgrRhwWYNqCr6mngduAxTJB+QFWfF5FNIrKp85oXgL8CngF+DHxRVZ8rz+zesZ9Xkk1Fltiai0L0IcTlw0OHzE9ok2Js2zmHVrYqSC8lF1T1UeDRcY/dN+73zwCfcWeaG5JvKrLElF2GGtCbTfibv/FtRW+E7MMzZ4y8LPRAWYqm2S/Jd4qW0lQUkrLAElNAD7FsBcaHhw+bBqPQCVWdEVNzkdU0h+bDAiQd0E+dMuXapJuKLLa56NQp35ZMj1UWONstzRExqYVCbYiJqbkoVB8WIOmAvmsXqCbeVGRpNs2bHR31bcn0hKosiEktZJuKhoZ8W3IusfkQwryeZ0jSAb0WTUWWmC6k7MPitNuwdi3MmePbknOxiqsYVjmhlq0KkHRAd/55WWVBiCdAbOWCEH24dm08zUWhqjNiai6ymuYLL/RtiTOSDui1aCqyxJJdhqwsmDPHBPXQfQjhTooQzw36UEt/BUg+oF94ocMJOFR1BpjOqcWLw7+QStktzSExBCPV8AN6DKucxJqKIPGA7vzzCjlDhzgaY7IPi3PwIBw5Eu6kGMt2zqGWrQqQdEAvpakoRGWBJYbsMvSAbn2o4/efC4gYfHj2rJGZhcrJkyVomv2TfEB3rnBZsyY8ZYElhoAectkKjA+PHDE7aoZK6OqMGJqLRkfNpB2qD2dIsgH95Enz1Ya1aCqyNBrmTZ886duSyXG+W5pjYlALhd4QE0NzUeg+nCHJBvSdO82/tWgqstjmopCXuqErC2JQC7VaMGuWUeSESCw+hLCv5xmQbEB3/nlZZUHIM3oMF1KoTUWWWHw4NASze9pbr3qs4irkVU7oZasZkmxAd/55WWVByCdALOWCkH24Zo3JfkP3YciTIoTfXGQ1zYsX+7bEKckG9Fo1FVlCzy5jUBbMnm2y31B9COFPihD+DfoYfDgDkg7oS5ea+29OCF2dASbbWLIk3AvJKgtC9iGEHYxU42iICb25KAYfzoBkA3rtmoosITfGZB8W59VX4ejR8CfFRsOsxkJVXMVQtpoByQb0UpqKQlYWWELOLmMJ6CE3F8Xkw1AVVydOlKBpDoOkA7rzpqK1a8NVFlhCDugxlK3A+PDYMXjlFd+WnE8s6oyQm4vsJBO6D2dAkgH9+HEYG6tZU5Gl0YC9e00WEhrOd0sriZDVQrE0xITcXBSLD2dAkgG9lk1FFmujdUJIxObDUIPR7NlGXhkyofsQ4jgX+yTJgF5KU1HoDTGWkC+k7MPi2KaigQHflkyNVVyFuMqJpfQ3A5IM6M7LjFZZEMOMHvpSNwYfDg6aLDhUH8YSiEJtLnKuaQ6HJAN6LZuKLKHejIpJWTAwYLLg0HwI8UyKEO4N+ph82CfJBvTly2HhQkcDxrREW7QIli0L70KyyoIYfAhhBqNYmoosoTYXxeTDPkkyoNe2qcgS4lI3+7A4+/cbCVcsk6Ldzjk0xVVMZas+STKgl9JUNDAQvrLAEmJmFFtAtz4MqbkoRh9CWIqrUjTN4dBTQBeR60XkRRHZISJ3TvG6vy8iZ0Tkn7kzsX9KaSqKQVlgCbFcEFPZCowPT5yAfft8W/IGsTQVWUK8n2Mnl1h82CfTBnQRGQDuBW4ALgduEpHLJ3ndfwAec21kPxw7ZlamtWwqsjQaJhAdO+bbkjeITVkQolootoaY7MPK6SVDvxbYoaovqepJ4H5g4wSv+0PgIWCvQ/v6ppREMLaAHuJSN1YfhpRdtlrm+2wHB31b0hsh6vljK1v1SS8BfRjo/kTancdeR0SGgX8K3DfVQCJym4hsE5FtY2Nj/draE7VuKrKEeCFlHxan3YbhYbNJXAxYxVVIk2Jspb8+6eXMmOjLH8ffKboH+ISqnplqIFXdrKobVHXDqlWrerWxL5yXGa2yIKYZPdSlbkw+XL3aZMOh+TC2QBSaWsi5pjksetk6sA10X4kNYPyemBuA+8V88e9K4H0iclpV/6cTK/vAnjvDw1O/ru8BYwpGoW0uFaOyYNYscxKF4kMw5+Jb3+rbiv4I7QZ9bIlFn/SSoW8FLhWRdSIyF7gReKT7Baq6TlVHVHUEeBD4Ax/BHMzntXIlLFjgaMAYl2gLF8KKFeFcSKXsllYBIQWj2JqKLKFJaGP0YR9MG9BV9TRwO0a98gLwgKo+LyKbRGRT2Qb2S+2biiwhLXWzD4szNma+/Se2SbHRMLYfP+7bEkOMZas+6OnbGlT1UeDRcY9NeANUVX+/uFkzp9WCiy92PODs2fEoCywhZZexBvRmEx56CM6e9X8jMmYfgsm0fuVX/Npy9GgJmuawiOR2ee+U0lQUk7LAElJAj7FsBcaHJ0+aDNM3sTUVWUKSfybeVASJBfQjR8xOt7VuKrI0GuYr1I4e9W1JvMqCkNRCsTbEZB9WSlIBPTcVdRFSZpR9WJxWC+bOhZLkvqURYkCP8VzskaQCem4q6iKkxpjsw+JYH8ZW+rOKqxAmxVhLf30Q2dkxNc7LjFZZEOOMHlpmFKMPV640WXEoPow1EIWiFrKa5vnzfVtSGkkF9NxU1EUozUUxKwtmzTJ+9O1DiHdShHBu0Mfswx5JLqCvXg3z5jkaMOYl2vz5pt7q+0KKtanIEkIwOnvW+DHWYBRKc1HiTUWQWEDPTUXjCGGpm31YnL174dSpeCfFRsOs0nwrrmIuW/VIUgG9lG8qilFZYAkhM4o9oDebJjs+e9afDSn4EPyei6VomsMjuYCem4q6CKFcYC9iZzc2KqbZhNOnzXdj+iLWpiJLCAE9dh/2SKSR6nwOH4aDB3NT0Tk0GnDgALz2mj8bnO+WVjEhqIVib4jJPqyMZAJ6biqagBAyo+zD4rRa5ib3ypX+bChCSAE95nOxB5IJ6M4/L6ssiHlGD6ExJtamIktIPpSJvmsmAqziKoSSS6ylvx5JJqA7L5FZZUHMM3oomVHMPlyxwgQk3z6MeVIE/2oh55rmMEkmoLdaJoEZGnI4IMQdjGw24iszSkFZIOK/uSj2SRH836BPwYc9kFRAHxw0KkMnxNxUZJk3zzjF14WUgg/BbzA6cwZ27Yo/GPmW0NagqQgSCui5qWgSfC51sw+Ls2ePkU3GPik2Gma1duSIn+OnULbqgWQCuvMVVatlMtxYlQUWn5lRKgG92TRZ8pkz1R87JR+Cn4mxFE1zmCQV0J1OwLErCyw+ywWpKAuaTRPMd++u/tipNMT4lH+m4sMeSCKgHzpkJuHcVDQBjYZx0KFD1R87FWWBT7VQKg0x2YeVkERAL2VVmkpA95kZZR8Wp9UyXbbLl1d/bJfYVZrPgJ7CuTgNSQV0ZxOwVRakMKP7rF3G3lRk8e3DZjP+0p9VXPkquTjVNIdLEgHdeYnMKgtSmNF9L3VT8OGyZSZL9uXDFCZF8KcWcq5pDpckAnqrZTZEXLvW4YCQRjAaHjbZSdWZUUrKAhF/aqFUJkXwd4M+JR9OQzIBfc0amDPH0YCpNMSAccqaNdVfSCn5EPwEo9OnYXQ0nWDka1KsSVMRJBLQc1PRNPhY6mYfFmf3bnM/J5VJsdEwq7bDh6s9bkplq2lIIqCX0lSUgrLA4iMzSi2gN5smWz59urpjpuhDqHZitBNIKj6chp4CuohcLyIvisgOEblzgudvFpFnOj8/FJGr3Js6Maq5qWhabLlAtbpjpqYsaDbNlsqjo9UdM7WGGB/yz9R8OA3TBnQRGQDuBW4ALgduEpHLx73sF8A/VNUrgT8DNrs2dDIOHjTbQ2QN+hQ0GuZbiw4erO6YqSkLfKiFUmuIyT4snV4y9GuBHar6kqqeBO4HNna/QFV/qKqvdn59EqjMe7mpqAd8ZEbZh8VptWDRIli6tLpjlolVXPkI6Cmdi1PQS0AfBro/gXbnscn4CPCtiZ4QkdtEZJuIbBsbG+vdyilwPgGnpiwAP7XL1JQFPn2YSunPKq6qLrk41TSHTS8BfaKzacJirIj8I0xA/8REz6vqZlXdoKobVq1a1buVU+C8RJaasgD8LXVT8uGSJSZbzj4sRtVqIeea5rDpJaC3ge5w2QB2jX+RiFwJfBHYqKr73Zg3Pa0WDAzkpqIpGRoyWUpVmVGKygIfzUWpla2gej1/ij6cgl4C+lbgUhFZJyJzgRuBR7pfICIXAV8HPqSqP3dv5uS0WiaYDww4GjDFu+KzZxsnVXUhpehDqDYYnTqVXukPqp8UUyv9TcO0AV1VTwO3A48BLwAPqOrzIrJJRDZ1XvYnwArg8yKyXUS2lWbxOEprKspL3ZmTfVic0VEjM03Rh3ZbiLIpRdMcNrN7eZGqPgo8Ou6x+7r+/1Hgo25N641WC9avdzxgSsoCS7MJzz5bzbFSLFuBeT+7d5vsueyabMo+BPP+liwp91gHDpSgaQ6bqDtFS2sqSklZYKmyuShVZUGzafy367xbSO5JuWwF1ZRdUvXhFEQd0F99FY4dK6HkkuISrdGAo0eN08omVWVBlWqhlMtWkH1YElEH9NxU1AdVZkbZh8VptWDx4vLLElVjFVdVBvQUz8VJSCKgO5uAU1UWQLWNMakqC7IPi2MVV1WVXJxqmsMn6oDuvESWqrIAqlvqpqwsuPBCkzVXlV2m6EOoTi3kXNMcPlEH9FbLTPiDgw4HhDQzI3til50Zpa4sqEpHnWrZCqrT86fsw0mIPqAPDeWmop4YGDDOKvtCStmHUE0wOnnSfK9tyj5st8tXXKVatpqCqAN6birqkyqWutmHxdm1K93SH5j3deSIWc2VRcqlvymIOqCX8k1FKSoLLFWUC1IuW4F5X3v2mCy6LOrgQyh3YnzllRI0zeETbUBXfeOLhZyR+hKtiuai1JUF9vzYubO8Y9ShbAXlJhep+3ASog3o+/fD8eO5qagvGg3jtP0lboaZurKgCrVQHcpWkH1YAj3t5RIipTUVXXmlwwEDozszWrmynGOkriyoIru0+5wsXlzeMXxiJ/wqAvoE5+KpU6dot9scP368vOM7YP78+TQaDeb00XEdfUB3NgGnriyAc2uXTnc066LdLm/sEKgiu0y99GcVV2WXXCbRNLfbbRYvXszIyAgS6J5Nqsr+/ftpt9usW7eu57+LtuTivESWurIAyg9GdVAW2JvmZWeXKfsQylcLTaFpPn78OCtWrAg2mAOICCtWrOh7FRFtQG+1zN5Pq1c7HBDSzowGB03WUlZmVBdlQdlqodTLVlC+nn8aH4YczC0zsTHqgD48bPb5cUId7ooPDBinlXUh1cGHUG4wOnEC9u6thw/LbC5KvWw1CdEG9NxUNEPKXOpmHxbHyiHr4MNjx8yqzjWONc1btsDIiEkeR0bM70UZGBhg/fr1XHXVVVx99dX88Ic/LD4oEdyIubsAAAo2SURBVAf0UpqKUlYWWMosF9ShbAXm/Y2NGQmoa+rkQyhnYty3z5mmecsWuO02ePllM0+8/LL5vWhQX7BgAdu3b+fpp5/mrrvu4pOf/GRhWyFSlcvZs7mpaMY0m/Dww+bsdF1HnEJZkBTdzUWXXOJ27DqVraAcVVQfPrzjDti+ffLnn3zSVMG6OXoUPvIR+MIXJv6b9evhnnt6tBU4dOgQy5Yt6/0PpiDKgL5vn1EZ5qaiGdBomDN0bMzhHeUOzndLC5RutZDrgF6nshWUk6E79OH4YD7d471y7Ngx1q9fz/HjxxkdHeU73/lOsQE7RBnQS2squvpqhwMGSndmVEZATz2zhHKbi1otWLbMfFF5yljFVZkBvYdzcbpMemTElFnGc/HF8L3v9W3Z69iSC8CPfvQjbrnlFp577rnC6psoa+jOk5i6KAug3NplXcpWZWaXdfGhVVyVMSm22840zX/+57Bw4bmPLVxoHnfF2972Nvbt28fY2FjhsaIM6M7LjHVRFkB5waiU3dICZdEik0WXlV3WwYdQnlrIoab55pth82aTkYuYfzdvNo+74mc/+xlnzpxhxYoVhceKtuQydy6sWuVwQKhHZrR6tcleXGdGDpUFUVCWWqjVgmuvdT9uiDSbsHWr+3Edl/5uvtltAIc3auhg2vy/8pWvMODg3lO0Ab3RcCjSqIuyAEzWUkZmVCcfQjnNRcePm4mxTj4sQ3HVbsN117kbrwTOnDlTyrjRllxyU1EBygjo2YfFsZNinXx44oSZxFxRiqY5HqIM6KU0FdVBWWApI7usU9kKzPvcv9+Ikl1RRx+C23NxbKwETXM8RBfQz5419zBzU1EBmk3jxLNn3Y3pUFkQBWV8c1Edy1bg9l5E3Xw4jp5q6CJyPfBZYAD4oqrePe556Tz/PuAo8Puq+hOnlq5ZA3v2MAs4CXB352dwEHbvLjTm69g6XpExQ6f7PXffhJnpex7vQztmXXx42WVvPO7Kh3bMuvhw48Y3Hnflww9+sNh4kTJtQBeRAeBe4D1AG9gqIo+o6k+7XnYDcGnn563AX3T+dUf3hzX+8Zlu8DPVmKni2o/Zh+c+nn3YG9mHpdBLhn4tsENVXwIQkfuBjUB3QN8I/KWqKvCkiCwVkbWqOurc4olwoN/MkP3oguzD4mQfzpheAvow0H3Xos352fdErxkGzgnoInIbcBvARRdd1K+tk/PZz87s7z7+cXc2pMBM/Jh9eC7Zh8UJyYfjSzkWB6Wc3bt3c8cdd7B161bmzZvHyMgI99xzD5d1l/H6RHSaDeZF5HeB96rqRzu/fwi4VlX/sOs1/xu4S1V/0Pn928Afq+pTk427YcMG3bZtWx+WTqFTnekm+WWMGTqu33P24blkH/aGRx++8MILvPnNb3Y+bj+oKm9/+9u59dZb2bRpEwDbt2/n8OHDvOMd75jSVhF5SlU3TDRuLxl6G+i+ZdwAds3gNZlMJhMW0+2fOxXvfOfEj/ewf+53v/td5syZ83owN39WfBvhXmSLW4FLRWSdiMwFbgQeGfeaR4BbxHAdcNB5/XyyPbaL7L1dxpih4/o9Zx9O/3jV48VAzX343HPPcc011zgfd9oMXVVPi8jtwGMY2eKXVPV5EdnUef4+4FGMZHEHRrb4YeeWliE9qpGc6XVcv+fsw/DGi4FQfDjd/rlTlVyK7J9bEj3p0FX1UUzQ7n7svq7/K/Axt6ZlMplMmlxxxRU8+OCDzseNrlM0k8lkKqOkUs673vUuTpw4wRe6vsdu69atPPHEE4XGzQE9k8lkJmP3bqNmGf9TsGQkIjz88MM8/vjjXHLJJVxxxRV8+tOfZmhoqNC4UW6fm8lkMrEzNDTEAw884HTMnKFnMplMIuSAnslkMomQA3omk6kd03XIh8BMbMwBPZPJ1Ir58+ezf//+oIO6qrJ//37mz5/f19/lm6KZTKZWNBoN2u02Y2Njvk2Zkvnz59Po85t8ckDPZDK1Ys6cOaxbt863GaWQSy6ZTCaTCDmgZzKZTCLkgJ7JZDKJMO0XXJR2YJEx4OUZ/vlKYJ9Dc8og21ic0O2D8G0M3T4I38bQ7LtYVVdN9IS3gF4EEdk22Td2hEK2sTih2wfh2xi6fRC+jaHb100uuWQymUwi5ICeyWQyiRBrQN/s24AeyDYWJ3T7IHwbQ7cPwrcxdPteJ8oaeiaTyWTOJ9YMPZPJZDLjyAE9k8lkEiG6gC4i14vIiyKyQ0Tu9G3PeESkKSLfFZEXROR5Efm4b5smQkQGROT/iMg3fdsyESKyVEQeFJGfdXz5Nt82dSMi/7rz+T4nIl8Tkf62xSvHpi+JyF4Rea7rseUi8riI/F3n32UB2viZzuf8jIg8LCJLQ7Kv67l/KyIqIit92NYLUQV0ERkA7gVuAC4HbhKRy/1adR6ngX+jqm8GrgM+FqCNAB8HXvBtxBR8FvgrVf1V4CoCslVEhoF/BWxQ1bcAA8CNfq0C4MvA9eMeuxP4tqpeCny787tPvsz5Nj4OvEVVrwR+DnyyaqO6+DLn24eINIH3AL+s2qB+iCqgA9cCO1T1JVU9CdwPbPRs0zmo6qiq/qTz/8OYQDTs16pzEZEG8H7gi75tmQgRuRD4TeC/A6jqSVU94Neq85gNLBCR2cBCYJdne1DV7wOvjHt4I/CVzv+/AnywUqPGMZGNqvrXqnq68+uTQH97xjpkEh8C/Bfgj4GgVSSxBfRhoNX1e5vAgmU3IjIC/Drwt34tOY97MCfnWd+GTMLfA8aA/9EpC31RRBb5NsqiqjuB/4jJ1kaBg6r6136tmpRBVR0Fk2wAqz3bMx3/EviWbyO6EZEPADtV9WnftkxHbAFdJngsyBlTRC4AHgLuUNVDvu2xiMhvAXtV9SnftkzBbOBq4C9U9deBI/gvFbxOpw69EVgHDAGLRORf+LUqfkTkU5iS5RbftlhEZCHwKeBPfNvSC7EF9DbQ7Pq9QQBL3fGIyBxMMN+iql/3bc84fgP4gIj8P0zJ6l0i8lW/Jp1HG2irql3ZPIgJ8KHwj4FfqOqYqp4Cvg683bNNk7FHRNYCdP7d69meCRGRW4HfAm7WsJpjLsFM3E93rpkG8BMRWePVqkmILaBvBS4VkXUiMhdzI+oRzzadg4gIpvb7gqr+Z9/2jEdVP6mqDVUdwfjvO6oaVHapqruBloi8qfPQu4GfejRpPL8ErhORhZ3P+90EdNN2HI8At3b+fyvwDY+2TIiIXA98AviAqh71bU83qvqsqq5W1ZHONdMGru6co8ERVUDv3Di5HXgMcwE9oKrP+7XqPH4D+BAm893e+Xmfb6Mi5A+BLSLyDLAe+Pee7XmdzsrhQeAnwLOY68h7e7iIfA34EfAmEWmLyEeAu4H3iMjfYVQadwdo4+eAxcDjnevlvsDsi4bc+p/JZDKJEFWGnslkMpnJyQE9k8lkEiEH9Ewmk0mEHNAzmUwmEXJAz2QymUTIAT2TyWQSIQf0TCaTSYT/D2nYayfjBXHiAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "p1 = pylab.plot( model.data[\"B\"] , 'ob-', label=\"B\" )\n", "p2 = pylab.plot( model.data[\"C\"] , 'sr-', label=\"C\" )\n", "pylab.legend()\n", "\n", "pylab.ylim((-0.1,1.1))\n", "pylab.show() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Random sampling of the initial condition" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start: 1 -> (4, 0, [1, 2, 3, 4, 1, 2, 3, 4, 1, 2])\n", "Start: 3 -> (4, 0, [3, 4, 1, 2, 3, 4, 1, 2, 3, 4])\n", "Start: 2 -> (4, 0, [2, 3, 4, 1, 2, 3, 4, 1, 2, 3])\n", "Start: 5 -> (4, 1, [5, 2, 3, 4, 1, 2, 3, 4, 1, 2])\n", "Start: 6 -> (4, 1, [6, 2, 3, 4, 1, 2, 3, 4, 1, 2])\n", "Start: 7 -> (4, 1, [7, 1, 2, 3, 4, 1, 2, 3, 4, 1])\n", "Start: 0 -> (4, 1, [0, 1, 2, 3, 4, 1, 2, 3, 4, 1])\n" ] } ], "source": [ "text = \"\"\"\n", "A = True\n", "B = Random\n", "C = Random\n", "D = Random\n", "\n", "B *= A or C\n", "C *= A and not D\n", "D *= B and C\n", "\"\"\"\n", "\n", "seen = {}\n", "\n", " \n", "# the key will be the fingerprint of the first state \n", "#(some random inital conditions may be the same), it is fine to overwrite in this case\n", "# as the 'sync' update rule is completely deterministic\n", "for i in range(10):\n", " model = boolean2.Model( text=text, mode='sync')\n", " model.initialize()\n", " model.iterate( steps=20 )\n", "\n", " # detect the cycles in the states\n", " size, index = model.detect_cycles() \n", " \n", " # fingerprint of the first state\n", " key = model.first.fp()\n", "\n", " # keep only the first 10 states out of the 20\n", " values = [ x.fp() for x in model.states[:10] ]\n", "\n", " # store the fingerprinted values for each initial state\n", " seen [ key ] = (index, size, values )\n", "\n", "# print out the observed states\n", "for first, values in list(seen.items()):\n", " print('Start: %s -> %s' % (first, values))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Perturbation (KO, KI) of the model" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start: 5 -> (1, 1, [5, 6, 6, 6, 6, 6, 6, 6, 6, 6])\n", "Start: 0 -> (1, 2, [0, 5, 6, 6, 6, 6, 6, 6, 6, 6])\n", "Start: 6 -> (1, 0, [6, 6, 6, 6, 6, 6, 6, 6, 6, 6])\n" ] } ], "source": [ "# Knocking node B out.\n", "#\n", "# Instead of a cycle, now a steady state is observed.\n", "# \n", "# Code is identical to tutorial 3 after the state modification steps\n", "\n", "text = \"\"\"\n", "A = True\n", "B = Random\n", "C = Random\n", "D = Random\n", "\n", "B *= A or C\n", "C *= A and not D\n", "D *= B and C\n", "\"\"\"\n", "\n", "\n", "# Fix the value and initial states of some components (here we perform a KO of B)\n", "text = boolean2.modify_states(text, turnon=[], turnoff=[ \"B\" ])\n", "\n", "\n", "seen = {}\n", "for i in range(10):\n", " model = boolean2.Model( text, mode='sync')\n", " model.initialize()\n", " model.iterate( steps=20 )\n", "\n", " size, index = model.detect_cycles() \n", " \n", " # fingerprint of the first state\n", " key = model.first.fp()\n", "\n", " # keep only the first 10 states out of the 20\n", " values = [ x.fp() for x in model.states[:10] ]\n", "\n", " # store the fingerprinted values for each initial state\n", " seen [ key ] = (index, size, values ) \n", "\n", "# print out the observed states\n", "for first, values in list(seen.items()):\n", " print('Start: %s -> %s' % (first, values))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Random sampling of asynchronous trajectories" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Asynchronous updating rules are non deterministic and\n", "# need to be averaged over many runs\n", "#\n", "# The collector class makes this averaging very easy. It takes\n", "# a list of states and nodes to build a data structure that \n", "# can compute the average the state of each node over all simulation and each timestep.\n", "#\n", "# The output of averaging (in the normalized mode) is a value between\n", "# 0 and 1 representing the fraction of simulation (multiply by 100 to get percent) \n", "# that had the node in state True. \n", "\n", "\n", "text = \"\"\"\n", "A = True\n", "B = Random\n", "C = Random\n", "D = Random\n", "B* = A or C\n", "C* = A and not D\n", "D* = B and C\n", "\"\"\"\n", "\n", "coll = boolean2.util.Collector()\n", "for i in range(50):\n", " model = boolean2.Model( text, mode='async')\n", " model.initialize()\n", " model.iterate( steps=15 ) \n", "\n", " # in this case we take all nodes\n", " # one could just list a few nodes such as [ 'A', 'B', 'C' ]\n", " nodes = model.nodes\n", "\n", " # this collects states for each run\n", " coll.collect( states=model.states, nodes=nodes )\n", "\n", "# this step averages the values for each node\n", "# returns a dictionary keyed by nodes and a list of values\n", "# with the average state for in each timestep\n", "avgs = coll.get_averages( normalize=True )\n", "\n", "# make some shortcut to data to for easier plotting\n", "valueB = avgs[\"B\"]\n", "valueC = avgs[\"C\"]\n", "valueD = avgs[\"D\"]\n", "\n", "# plot the state of the nodes\n", "p1 = pylab.plot( valueB , 'ob-', label=\"B\" )\n", "p2 = pylab.plot( valueC , 'sr-', label=\"C\" )\n", "p3 = pylab.plot( valueD , '^g-', label=\"D\" )\n", "pylab.legend()\n", "\n", "pylab.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# PLDE mode (broken with newer versions of pylab)\n", "\n", "In addition to sync and async modes, booleannet supports a PLDE mode.\n", "Unfortunately, it relies on the RK integrator which used to be part of pylab but has been removed." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "# Using Piecewise linear differential equations\n", "#\n", "# This initial condition leads to damped oscillations\n", "# If A is set to False, a steady state is obtained.\n", "\n", "text = \"\"\"\n", "A = True\n", "B = False\n", "C = False\n", "D = True\n", "1: B* = A or C\n", "1: C* = A and not D\n", "1: D* = B and C\n", "\"\"\"\n", "\n", "if False:\n", " model = boolean2.Model( text, mode='plde')\n", " model.initialize()\n", " model.iterate( fullt=7, steps=150 )\n", "\n", " #\n", " # generate the plot\n", " #\n", " p1 = pylab.plot( model.data[\"B\"] , 'ob-' )\n", " p2 = pylab.plot( model.data[\"C\"] , 'sr-' )\n", " p3 = pylab.plot( model.data[\"D\"] , '^g-' )\n", "\n", "\n", " pylab.legend( [p1,p2,p3], [\"B\",\"C\",\"D\"])\n", "\n", " pylab.show()" ] } ], "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.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }