diff --git a/.gitignore b/.gitignore index 710c7fc..b07e4d4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ source/ /.Rhistory /.Rproj.user/* LoopDetectR.Rproj +/LoopDetectR.Rcheck # Compiled source # diff --git a/examples/model_1_POSm4_R.ipynb b/examples/model_1_POSm4_R.ipynb new file mode 100644 index 0000000..2a3862c --- /dev/null +++ b/examples/model_1_POSm4_R.ipynb @@ -0,0 +1,1498 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "846fd1a6", + "metadata": {}, + "source": [ + "## **0. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "fc391249", + "metadata": {}, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a4619679", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4ea4fa08", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "adf81c8c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16dc790d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")\n", + "library(deSolve)\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b677961f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "colors <- c('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB')" + ] + }, + { + "cell_type": "markdown", + "id": "bc602c8d", + "metadata": {}, + "source": [ + "## **1. Model definition**" + ] + }, + { + "cell_type": "markdown", + "id": "2b148688", + "metadata": {}, + "source": [ + "Model POSm4 with 4 positive feedbacks can be loaded from the library" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "12108b07", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Load example ODE system with function func_POSm4, 4 variables\n", + "data(\"func_POSm4\")" + ] + }, + { + "cell_type": "markdown", + "id": "1903c5dc", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "## **2. Result reproduction**" + ] + }, + { + "cell_type": "markdown", + "id": "5fc586ee", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **2.1. Loop structures**" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "5ab687a9", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Parameters from supplementary material\n", + "klin <- c(150, 0.04, 0.3, 500, 5000, 80, 4, 5)\n", + "knonlin <- c(0.3,2)\n", + "s_star <- c(1,2,3,4) # Dummy steady state for initialization\n", + "\n", + "# Parameters not yet in supplement data\n", + "perturbation_point <- 8.6" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "81b11f06", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
4, 41-1
3, 4, 1,....4-1
3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 6 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 3, 4, 1,.... & 4 & -1\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 3, 4, 1,.... | 4 | -1 |\n", + "| 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 4, 4 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(func_POSm4,vset=list(s_star),t=1,klin=klin,\n", + " knonlin=knonlin,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "b1bccacc", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 4
len_1len_2len_3len_4
<dbl><dbl><dbl><dbl>
all4011
pos0010
neg4001
\n" + ], + "text/latex": [ + "A data.frame: 3 × 4\n", + "\\begin{tabular}{r|llll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4\\\\\n", + " & & & & \\\\\n", + "\\hline\n", + "\tall & 4 & 0 & 1 & 1\\\\\n", + "\tpos & 0 & 0 & 1 & 0\\\\\n", + "\tneg & 4 & 0 & 0 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 4\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> |\n", + "|---|---|---|---|---|\n", + "| all | 4 | 0 | 1 | 1 |\n", + "| pos | 0 | 0 | 1 | 0 |\n", + "| neg | 4 | 0 | 0 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4\n", + "all 4 0 1 1 \n", + "pos 0 0 1 0 \n", + "neg 4 0 0 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "f1f8c98c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
53, 4, 1,....4-1
6 3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 3 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t5 & 3, 4, 1,.... & 4 & -1\\\\\n", + "\t6 & 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 5 | 3, 4, 1,.... | 4 | -1 |\n", + "| 6 | 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2\n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "c3a1aa95", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **2.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "9e3795b8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1 0 0-1
1-1 0 1
0 1-1 0
0 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & 0 & 0 & -1\\\\\n", + "\t 1 & -1 & 0 & 1\\\\\n", + "\t 0 & 1 & -1 & 0\\\\\n", + "\t 0 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | 0 | 0 | -1 |\n", + "| 1 | -1 | 0 | 1 |\n", + "| 0 | 1 | -1 | 0 |\n", + "| 0 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 0 0 -1 \n", + "[2,] 1 -1 0 1 \n", + "[3,] 0 1 -1 0 \n", + "[4,] 0 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "52610797", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003].\n", + "\n", + "The input function, in the example `func_POSm4` (positive feedback chain model from [Baum et al., 2016]) defines the time derivatives of the modelled variables as a vector: \n", + "$f_i(s)=dS_i/dt$. Note that only those input arguments to the function that encode the modelled variables (and hence in whose direction the partial derivatives are taken) are allowed to be called `x`." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "c261caec", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
1
259.243116830199
2
0.00371448194657896
3
0.0218301587733568
4
0.295548075392272
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[1] 259.243116830199\n", + "\\item[2] 0.00371448194657896\n", + "\\item[3] 0.0218301587733568\n", + "\\item[4] 0.295548075392272\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "1\n", + ": 259.2431168301992\n", + ": 0.003714481946578963\n", + ": 0.02183015877335684\n", + ": 0.295548075392272\n", + "\n" + ], + "text/plain": [ + " 1 2 3 4 \n", + "2.592431e+02 3.714482e-03 2.183016e-02 2.955481e-01 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_POSm4_list <- function(t,x,klin,knonlin){list(func_POSm4(t,x,klin,knonlin))}\n", + "sol <- deSolve::ode(y = rep(1,4), times = seq(0,11,0.1), func = func_POSm4_list, \n", + " parms=klin, knonlin=knonlin)\n", + "\n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "8b4155db", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-0.37882163 0 0-68.1056
0.07882163-5500 0 68.1056
0.00000000 500-84 0.0000
0.00000000 0 80 -5.0000
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -0.37882163 & 0 & 0 & -68.1056\\\\\n", + "\t 0.07882163 & -5500 & 0 & 68.1056\\\\\n", + "\t 0.00000000 & 500 & -84 & 0.0000\\\\\n", + "\t 0.00000000 & 0 & 80 & -5.0000\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -0.37882163 | 0 | 0 | -68.1056 |\n", + "| 0.07882163 | -5500 | 0 | 68.1056 |\n", + "| 0.00000000 | 500 | -84 | 0.0000 |\n", + "| 0.00000000 | 0 | 80 | -5.0000 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] \n", + "[1,] -0.37882163 0 0 -68.1056\n", + "[2,] 0.07882163 -5500 0 68.1056\n", + "[3,] 0.00000000 500 -84 0.0000\n", + "[4,] 0.00000000 0 80 -5.0000" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(func_POSm4,s_star,method=\"complex\",\n", + " t=1,klin=klin,knonlin=knonlin,)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "71c0bc77", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1 0 0-1
1-1 0 1
0 1-1 0
0 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & 0 & 0 & -1\\\\\n", + "\t 1 & -1 & 0 & 1\\\\\n", + "\t 0 & 1 & -1 & 0\\\\\n", + "\t 0 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | 0 | 0 | -1 |\n", + "| 1 | -1 | 0 | 1 |\n", + "| 0 | 1 | -1 | 0 |\n", + "| 0 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 0 0 -1 \n", + "[2,] 1 -1 0 1 \n", + "[3,] 0 1 -1 0 \n", + "[4,] 0 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "e6ed3518", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **2.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "bee71136", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAMAAABoqemGAAAAOVBMVEUAAAAil+ZNTU1h0E9oaGh8fHyMjIyampqnp6eysrK9vb3Hx8fQ0NDZ2dnfU2vh4eHp6enw8PD///+VWJnmAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2di5aiOhBF04zatm1flf//2Cv4Ak0gkEqlqnL2Wneu3TOScKjNM0bXAgDU4kp3AACwHggMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAaBHQAgihV20QtboAlQIQbrCgKDejBYVxAY1IPBuoLAoB4M1hUEBvVgsK4gMKgHg3UFgUE9GKwrCAzqwWBdQWBQDwbrCgKDejBYVxAY1IPBuoLAoB4M1hUEBvVgsK4gMKgHg3UFgUE9ZKurP7d5vt64o6dlF/ox+IHAQ1RvITCoh3x11bi/+6uza3wtLxb4FPdRXwgM6iFfXf24/f3V/vlqqiOzAp8aCKyMtGkWzEORTL5cL8/jbuPOER2ZE/jgthBYPsG5USqXeGLqmKRkMma6vV/5/rnt9c/jzrmmPxI7d9m43U3T4W+vR+rnyyuHjWsOw57uwxfHIyAwLwvmM6pR4bjD7OpkMiZ6dN/9/787kX9uq9EJ6tzO3W18/63rXe9Xpv+p//HOKXYtITATK84ADabwyboZ2lZG439bxMxxEV1s3H1h/R+/bft7f7m93H89+m1z6i5zf29/c+z+0WU7vn0NgWWwwtznW6n7IomEXNq10eQMdN/ZePXzdQvrrurf8/Xwt52rx+u5df/zznWSX7of2/HbZ4HAGVh1UPEth6xHokjO5baQNW9KbHSKU38GvHWn/qfz8Wd7V/XWsgv99vafp1ggMD/pzo4XR7UgIdDGI610N9fD6OU+oGP7XNOhwN7fQmAZkJr7WCbx8opBvGO7L5TlLfEc3E/74/pbyd9uczie31X1//bx32dnITAXGdy9LzjLUhnJYu5j2Sxviac7+m76i9mbe15Vn7/trowH18Dzoy8DSEuBrQki8tVnv/RsS85NTnMfTbC8ZQHf7vEsqfPz5LnaHfz2dhf6ePub3+7H6yEcN7EYyV+hOnL4gCGXWzssb1nA0bn7kXR/33/9jQQe/fa7e7VrR1fHzWgMlzyBL9dOb+/nCtO9E164XCUqPohPuIJpBQrcNs/xlF2l/z3PkNv7/0a/3bvm5/k33Ugs9z0egylO4EvjHnsdxQKzuXtrja+pZPh2a/f2WN4iHcYU9t0dusuh6QeMaRSYu0JbqUF8UCAZCHyDMYX7WLNzszmrE7hIhbYCg/ikUDIQ+AZjCo/tfNluVQlcrEL7xou1HIWyaISnuQbGFO7PyLpXWzUCl6zQvv2irU9SdMfWQuAbjCkc7g/JuofZM59WlhF06Qrt+1C6A15KXVGMO8Hyljjo58TqPiC8v3j/arykuA4mvuXG/tnX48z2L18cEiq0R0YvXqhOJl/HqefEuj0zbuYNZk3h9Bxpcv6WK7CYCu0R1BX9yeTrPfGcWCf3fRmes04sKa5/iW8R2ESwaUEl2iGmO6Lk7Vnen3xrQDwn1s6F/+5tSRGdS3+LwCYCDUsrUikGCwxGlMDUc2Ld+ytM4L+f29w/u/3f9D8s9GBRYpWKEFhkMLIEJp4Tq+fy8ZtPOIdSbtyL6Z7x14usy7sh5btlJxn/O/5bRGjZ5HNiddfAnvvZUatE/Zae6znD72O+kWb6Sp97wKLUEu0o/BxacDaijsD0c2K152b8sxfWoZSn5+uT9157chOrkFuhNwqOdZIdjSyByefEujTzJ9BFhlJ+/kDWxApk12hHqQ6KT0aWwORzYm03bQR1H4GFH2JulLqjV6TZJQgTmHZOrPNmG/E4ivsa+Hjrk5BrYAU12lGglyp2bNIEJp0T6xhxA/q24OUdXZ3CdnAXejM5SIyjfFTUaAd7P7UkI0xgyjmxzrH+Mj8H3vfPu5rdT+nnwDoOMTfYb8nztrceaQITzon17bso9sIqsJQm9NRoB2dnNe3YxAlMOCeW966WlwoF1lSjHXzdVZaMOIFLwC9wTJVkDFpZkbact+SZGqICArfVCayuSFvckg8CgdvaBFa5AXFLPgAEbusSWGWV6r/nkA0I3HIL7CLvrmUJWuvWY3imlruFPEDgVpLAbsj6JsJN0y+Th9wdryiYbKtKPqld9zVE3yff37wvOK6DiW8Zvb3EKbRefVs8VAshSGDySe1uX0MUYXAVAisu0o6cvdecjCSBiSe123djMvdO1ueBH29nF1hzkXbkfCqeb9H5kSQw8aR2jbuE/up9STG9S37L6O3MAis//LZ4Kh5CksBZJrWb/szt/d8s76quxxq6a7QHT8X9iBI4w6R2e/c5T+UH1gXWXqQdeCruh0rgf4sILZt6UrtfF3MxzS9wdxpx3eNMXydQ1Zb+Iu3AU3E/oo7A5JPaHXaN+5lvllvg7e0p7+Cjj+RNkC+mNDlWw0I0sgQmn9SuOx2fP4dmFvhwPVfoujnzrS80QVso0g769aj1zCTralNPaje8tR2GWeDu9vhwDTI0QbsQCdAPa6FeYCEWr0fWFaed1O759zMwC/zsbXaBbRxkejCsJYAsgSkntbs9Bz67+ZllmQXe3I/Ap+mupQdtpkhbDGsJIktgyknt+pFYl53Ya+BjM9215KANVSnxylhKRpjAhJPa3cdCR0xNyX0XendfibxfbmapSknXxs7pc4cwgQkntbva3lyvmCPaLPIc2O1+czZhzF8MawkhTeASsAvM0IS1zUS2PtUHYy2A1qTA5rYS1QohGHMJWBTY3kYiWiMEYzACCKwAjEsLAIENCoxtlHEhwoDArAK7MTmaMLmJSNbJYi6CBCaf1O620IiWGQU+MAiMOs22CIHIEZh8Ursrl0aYwO2pyfilp0nvkw0GlgYQJDDxpHYdu6hRN6zXwKeoOQYSmrBZqBhYGkCQwMST2rX9jBziBL6eRcfMVb26CaOFioGlAQQJTD6p3dltBQqctwkUaoZ3S0aSwNST2m3duTaBUaj0b5YNkcBfiwgtm3ZSu5/rX0FgK2Bcix9JR2DaSe1Ogw8yTWNHYMOVinEtfkQJTDqp3aa51Caw5UrFuBY/ogSmnNSuv5CGwGbAuBY/sgQmnNQubrjT7Z8u76hIgU2XKgT2I0tgwkntILAt1q6c6VBaaQJTTmr3fM8sRgS2Xaor1852KK24MqGc1O7xnlkgsALWrZ3tTDqklQnlpHZtVQIbr1UI7EeawCWAwArAuJYAqBMbAhvcLiMwriUABIbAGoDAASAwBNaAzI0kAAgstDaWNWFws4zBY/EAEBgCawB3WwNAYAsCG9wqb0DgABAYAmsAdRoAwRgQ2OBGeQf39AJAYAisAQgcAAJDYA3gnl6AxQIbJH9qK1jQRA3lilsCAXAE1n8ENrhNPoDAAXBtAYE1gCuKALi2UC+wyY3yAXZofiAwBFYB8vCDawsIrILotawjjie4toDAKoDAfiCwdoGNbpV3Ylezkjie4N4ABFYBBPYDgSGwCiJXs5I0XuBSS7nAZjfLGxDYDwTmFHjBGE4IPCZuPWtJ4wXO1DgFPkDgtUStZy1hDOhWOfiN2+//0Cacp9CnZkvbhN3N8gYE9hMrsOFoWK+BT4OvL6dowvB2GROzotWEMaAXOMJgw9nw3sQ63L+/nKgJw9tlDAT2Eymw5WhU34W2vGFGRKxoNVkMuZ1CzxpsORvNAlveLmMirvXqCWOI62KZE9h0NBBYA/MC15PFiF7gqvdtrAL//ez6J0i7/R9FE6Y3zAg3e6ZYTxYjYgS2HQ2jwJfN4Cnw9AMlPDYZMytwRVmMuAlc876NUeC9a35vN6HPx2b6gRIEHtMLPFWmFWUxIkJg49EwCtwMniGdXJPchPEtM2RO4IqiGHMXuOJ9G+tY6NAP65owvmWGzB1oKopizLzA1qPBEVgDMwJXlMQbD4Hr3bfxXgMfz/0rXAMvZOZAU1ESb8wKbD4azsdI28Fd6M0luQnz2+aFmy7TipJ44ylwtdHwPgfe98+Bm90PxXNg89vmhZss04qCeOcZTEBg+9HoHYllf9sMgMB+XgLXGg0E1sDXc2U9ZVpTEO/MCFxBNPwCx3whIgQeA4EDDASuNBoIrIGXwJ4yrSmId6YFriEZCKyBKYFryuGDocB1RgOBFfDVQmA/EJhX4Lg5KSHwG0OB38u0ohg8TApcRTRyBI6ecza9G9qAwCFGAlcZDU6h5fM1XtlRmdaTgpeviZ/qyAYCywcCB/ma+LGOaCCwfN4EHpVpPSl4gcAQWD4TAtcTgp/3+1b1RYOhlOLpihIC+4HAEFg8HwK/yrSaDEJ8PPp9/aKSbNgFPu66c+jdObWJSrZPC4GnCAtcSzTcAm9vT3ldM2kwBB7wKfCzTOsJIcDn+OfaomEW+OC2l07gg/tObKKWDTQlcD0ZhIDAzAI37nK7DZ08K2UtG8gr8L1M68kgwJcngsqiYRa4P32GwEvoCxICe4HA3AJv7kfgk9skNlHNFvIK7D0s14dP4MqiKXMNfGzcIbGJajYRBA4DgdnvQu+ovtysmk3kF/hjeFaVeAWuK5oiz4Hd7je5iWo2UVDgahIIExK4omjUjsSqZhsFBB5Os1MtAVVrigYCSyd0V3Xma+mrAAJDYPGEBHYwOCRwTdFAYOkEBcYxOChwRdFAYOGERk06nEQHbzdDYOq33N7nouetm2+iFn+nBK6oTP0EBK4qGkaBDxB4BRA4DATmPYU+NdPDN5Y0UbvAbviXtTIhcDXRsF4Dn9yeqgkIPPzbSvELXNe+jfcm1sGdiJqAwMO/rZQpgWuJRutd6MoFdm9/XSeTAlcSDQQWDgQO4xW4smggsHBmBK6kTP1MC1xHNBBYNv4pntznP6gQ/wd/IXCGt9A3AYHf/0V9zAlcRTQQWDbzAldRpl68AtcWDQSWDQQOA4FbCCwdr8DO/29qY17gCqKBwLKBwGF8Ar//bD4bpQLX4m+UwPar1A8EbiGwdKIEtl+mXmIENh8NBBaN98v2PlfeepX68Uz356kL49lAYNF01fevezEtsPUq9RMnsPFsILBoYgU2XqVefJOF1RcNBBYNBA4TK7DtbCCwaHwC+9fddJV68QgcKAvL2UBg0TwFHqxxhVXqBQJ3QGDRLBDYdJn6iBfYcjQQWDQQOMwCgQ1nA4FFcy28f28Ch1fdbpV6+RS4xmggsGRuB+DxXayJVbdbph48U5XUGA0ElgwEDrNMYLPZQGDJLBTYbJX6WCiw1Wx0ClyJvz6Bp1fdaJX6+BS4ymggsGQgcJilAhvNBgJLZrHARqvUg+dzlnNVYTIbCCyZ5QLbrFIPEPgGBJbMp8Dza26yTD/5FLjOaCCwZCBwkDUCW8wGAgumr7elAlusUg8Q+AYEFsw6gS2W6SerBDYYDavAfz8717Hb/6U1Ua3AcStur0w/+JwsrNJoGAW+bNyLbVITFQn8r4XAHtYKbC4bRoH3rvk99a/Ox8btU5qAwPNvtA0EvsMocONOz9cn16Q0AYEj3mma1QJbi4ZRYOdCPyxuolaB49fbWJl+8CFwrdHgCCyYx3wc3X8QeMhr9SAwx1t6rtfAx3P/KvUauBJ/UwQ2VqbvpAhsKxrOx0jbwV3ozSWhiUoEvj9FWiewrTJ9J0lgU9HwPgfe98+Bm91P2nPgWgVett6WyvSdwbotu7v3/m71qByJBYGj326UNIEtRQOB5TISuFvphettqEzfGK7Z4muL9wXoRuVQSgi8YAEWgcBPVA6lrFTgxattp0zfeBd4eUGYiSZV4MOmbc8bt5k5pHbQDaWsQ+BbjaUIbKdM30gX2Ew0iQIfuxFVTXdInTeYbiAHBF62DHO8CbyqHoxEkyjw1v1eZdy0vzPnxP37yIZSViTwv+cfEPgFBH6SKHDn4ak7HZ4WsgdH4EW8DsB3gWsu0zGjlVq1Y/tYiloIBN65Y1R5UQ+ltLEBgtAIbDIlGoFtRJN8Cn06dgfTmFNo4qGUXybyD0MksI0yHTMWeP35mIVo0m9iOffTpXiMeCfpUMovE/mHoRLYYEwQ+EXyY6TbyfDml6g/nib8f/tlI/8g95Ub3sRKW5Ih3k6hiRakE41DKbu/7aM3kH+QocCvjyOlLMoM4/VJKkf90fALHHPKMyvwLXj98YchFNhaTpSroz6aZIGPu/5O9Dn+7XQC648/yGPN/g3+TF+aDUjXRns0qQL3d5avv2uiDaYQ+JG69vTD0ApsKygIPCBR4IPbXjojD+47+u3pAr9C1x5/EGKBLQVFvCrKk0kUuHGXm5FxN/Nfz4FTelWBwM/1gsAfUK+K7mgIRmIRCeyGTC7lK/DaEOQC2wmKfkVUR5Mo8OZ+BO4+0BD79uRT6GE5qw4/zPgMmkJgM0lB4BE018DHxh2i304qsO70g0DgIBnWQ3M0qXehd1EzbIzeDoFneTuDJhHYSFJZ1kJxNCTPgd1uwUhKYoE1hx8ki8A2knpfiX+V79w0DqWEwKmL1ctoFf5dqX3nBoEF8lolCPzGYBX+kd2hbxVHkyCwc/FPfl5EDb1cIrDe7IPkElh/VMMVwM6tg1vguKGXdQs8PMpc//uPTmD1WeUTWGs0zKfQkUMvFwmsNfogGQXWnpVH4MoNZhY4cuhl1QK/F+l/LQ7Bd8a3sN7+T7pwNSQL/Ns/RoqZUKd/b9zQy2UCK40+RFaBdWflOwBXvnMj+Thhp3DceyOHXk736j/Th+CPowytwJrD8h6AK9+5JQrcTRV7/d+x6Wa2iyBy6OVCgVUmH2C8KhkEVhxWboE1RpP8ccLbZO0zE7W/iBt6CYFv9CsKge987tvGL8ib0ADBxwnHL+aIGnq5VGCFwQfwHICpBVYbFgT2kHwK/TgCT37TQkoTHiAwZSNaeOt1FoH1RZP8aaT+GviviZ5RZ3kTn3g2mbrg/XiKNIPAKtP6+BTDx4sszUiHfSglRa/qEph2JIevGQ18dDmTwNqygcCS8B1lcgisMK6wwHUfgjV+Gsm7xZTl7sVbpFkEVhfXhL91H4IZBV5wxK5T4M9VgMB3/NF8vszUmGCoBP6bH4p1yCqwrti9cAqsLC5WgVVlkyrwfsE18KmJnTmrSoE9K5BRYFV5BaL5fJmtObEkPwd+EPNxhuinxWsEVhW7B1/3cwqsKK9QNJ8vMzYolOShlL/t1p3PWzfzld03DvdxH4m9siiwt/dPgas+BAej+XyZs0WZEAyl/LkefU8L5pVd2ISHwBZTFPsn/AJrycvfzawCa4mmJRH42H2yqPRz4A49qX8SrtJ8AisJrITASqJpkwXeXU+hz27T/kkQWE/qH0wUaUaBVQQW6OO/wOu8rcojUeBjJ27/oX7SwdC1CTxRpP/Rf55wtl1JRPhb9SE49THST/fTt6P9MNJagdWkPuYr1O3sAssPbCoa/w+ZG5aGmaGUPVpSHxHudH6BhScW3LXlF1h4Mk9sCawl9SETXWYQWHRiM9H4f+BoXRBJn0YajW9m7NXEBtOR+oCpDlcu8Fw0/h942heDSoE9c+o8UBH6i/A5YgeHwGITm4/G/wNhD/IslhaVp9ATAutI/cFMZ1kEFppYRDT+H/j6IILU58C0d599TXiwIvBcXx+TymYaDB3bjQJMH35bJoElJvMO1ayUtCQIrCH0G7NFWq3AccmEfiLtSbYlU5EocPdNCxmoQeCIfjIJLCyyeX0/4qj4EJwo8GW3jfoYUkITHiYFVhB6G1elbAKLiiyqL1wCi0rGS/IptLC70K2CzCP1rVLgBcmEf6RETjR+DAosPvPIIn19sUrm29CtmMhik2EUWEo0Icw9RmqlRx5dpJwCi8gsPhlOgUVEE8aiwJIjX1CkzzPoOgRekgwEfsI4K2VqEy/UCryoSFkFLp3ZsmRYBS4dzTScs1KubOKTOYFlRv61sEh5BS6a2dJkeAUuW04z2bDOSrmqCQ+zAgs0eHGNcgtcLLPFO7bPMOyensxmwzsr5ZomPOgTeIW+lQi8OpnpX9BSbt82+09UzkoZsb0kGbziENPDLHCJzBKSmf4FMSXKKa5sVM5KqUrglTXa8gvMHdraHVsBgfnrKTYblbNSxmwvIQav1/f1GJhNYNbQEpIpIDBzPcWHo3JWSjUCpxSpbYGTkikhMGs2C9pSOStl1PYqb3BakZYQmCu0xGSKCMyUzdLrigSBSR8c+ZsIEbW9dA1N+KSEwCyhJSdjVuAVdwVS5sRq9ufl717URAjxAq+/P/PiJXD+jyO9yJ4aQTJlBM4ezapkEgTeXK98t3kOwyQClzOYokZLCZw3NYodmy8LAxcYK5NJuQY+75urw/u4bwxd10QA0QLT6HtfR36Bs8X2RWNv681CucHro0m8ifX3fVV4c6CeV2euV/NDsXqKjEyganRwAOa8CG7zxEaXS1tQ4FzRJCw2/dNIv91TpG/aU2kigdkf3pFXaRGB6WOjzKUtKTB5NMklQ/FxwsvP9XK4SevHTBNvCBSYVN6OggIT50adTEmBaaMhSIbo88BH3pFYsQKzGUxeo2UFJsyNfMfWlhWYcFOTLMn2EZjJ4Aw1OrqHxS8wzSrRXlO8GGUz/BUPJOtEFY3ta2AOgTmKlF/g9OQy5dJRWGCKaMiySR0LveAutBuT0qt4gTMbnK9KiwucklyuQ++d0gInFRVxNCkC/3XPgZvo58CHIgJnNDhrlZYXeO1pdF5522cSBQVOiIY6G86RWKcm9lP/lALnMjhzmX4IXMDgFeuY3d5WhMByokkaC/2zcADHKfZDS/IF5j3K/Df8HSuL1pPD3va1bytrsJBoEgReMQvWwcWdb5MKnGNcQvZC9QlcxODYOs182TtEiMDxhZUzGpUTuy8UmNRgpkL1ClzG4Nn6+2KUt0OMwDE7t9zZVCEwmcHcR5l3gQsZHF5xbnd75Ag8rTBLOHUITPXsnWIpcQQELmawpxxLuNvxjGYscMF923sOX198OzZWgf9+dv0TpN1+5vpZosC81Tp+1Pnf+1+U4mtAqT74Be4ULrx3K5IMo8CXzeAp8PQDJXKBUw3mrtf3JyVDg8sqXJ6QwG2V2TAKvHfN7+0m9PnYTD9Qohc4weByl3legass0yETAleYDaPAzeAZ0mn6ww8ZBF5pcOnrvPbtxf2vayvTAY9V9wtcXTaMAo9GT/INpXyyZuhMqQu9GYGrK9MBL4EDBteVTT1H4IUGF7xL00YIXPpuVjkG0QQEriob3mvg420e2hLXwB3xSha1d3SUeXvh+UeVESNwRdlwPkbaDu5CbyaHUWcSOH5Y4LrFkxElcF2nig+G0YQFrsdg3ufA+/45cLP74X4O/CRCzeL6xgpcUZm+iBS4mr2bzpFYKQZP6llygMKAWIGrKdMXsQLXsnerTuCgpEVHF70RLXAtZfoiXuA6oikh8PwMllkF7hjaWnhkoI8FAtdRpk+eaxshcBXRVCpwj0Bzb4yqdPzC969rqNMH42hgsCCBoyfM6iARWCzLBK6iTh8sE7iCZOQIvKiJOgR+1Seu9u6Mo5kV2P7pCQQWyGKBqzH47dxkXmDz0UBgeXyeQUecK1oO5MUKgY0bXOFjJPGsEdh6nd5ZI7DtZNgFPu66A/DunNYEBJ54m2FWCWw6GW6Bt7d7zK6ZNLhqgV+rNqhPGNzxHk2kwJaTYRb44LaXTuCD+05qAgJPv9MoawU2fIuAWeDGXW73sNI+0G9Z4MGaLRXYvMEf+7Zog81Gwyxwf/oMgadIEdhsmd5JENhqNMwCb+5H4JPbJDUBgWffbJDPaBYIbDSbMtfAx8YdkpqwK/BwxZYLbLRK73zeHVgisM1suO9C70jmhYbAUe+3RqLAJrMp8hzY7X4Tm4DAUQuwhefiYpnAFrPBSCxZjNZrlcAWq/QGBPYAgWUROADjbo0/moUCG4wGAosidADG3Roage1FA4FFQSOwvTJtQ9FUb7BWgc1tiBtEAltMh0hga9GwfjdS9Kw5tQo8XqkEge3FE4hmucDGomEU+ACB56AT2Fw+ENgP5yn0qZkevrGgCZsCv61TksDGAgrt2lYIbCsZ1mvg0/RXmi1oAgIvXppuKAU2lQzvTazD4BtGk5owKfD7KkHgJ8Fd2yqBLUWDu9BymBK4coMhcAgILIZJf+u+2JuIpnaDIbAYIHAQcoHtRAOBpfCxQukCWwlpKpqVAluJRqvABsdS5hDYSJnmENhINBBYCp/rA4HvTEYDgTneQt8EBF67WH1MnpusFthENBBYCnP+VnytNx3NeoENRNNCYClkE1h9mXr6TySw+mg6ILAIZqr088ekRasCAk8CgSXgWxkqgZWX6Ww0lRsMgSWQVWDdZZpVYN3R9EBgAXjXhU5gzWU6H02SwJqjuQGByxPjb6UC+3sOgV9A4OJEFKnnZ4Im5BPoN6HAaqN5AIGLwyCw0jIN9ZpkiMtcI0qAwKWJOcp4fqZpRTRx/taYzAC1AmsP/kFklVZYpsEuI5oBELgs0VVaXZmGO0wssL5ohkDgosT7W1uZTnSXet+mLZoRELgg/+KPMrVV6VRvIfAACFyORUWaXKWqApvsa+07txEQuBjMRaqoTCfOTDoq39CN9g8AABCJSURBVLmNgcClYC9SNWU6001fEPUegiFwGWYOMjULPNfLHAIricYDBC7CiiIlEFhFZrN99AZRrcEQuARrivS/KgyeOzNpIfAYCMzP6iL9L1li6aFF9C8QQa0GQ2B2YjoeLMdUhWWnlhKN+Z2bHwjMTMTht508niQWquDYUqOxvXMLAIFZiavRmRNCox8NJogmTWG50UwAgRmJ1XdO0aQ6FZobya7NZDTTvYLAfMT3eLYKrU1xF71ri4jGVjZzyUBgLuJrNMbPhDKVFxxtNAnZiItmPhkIzMOSGo07wJopU/porMyCH5OMVoF1zamzrEZjC3CtwqKSWxhN5Cqv3rsJyiYuGU6BL9/ObY/3hUwuxZbAS/WNP4KoN3hxNNFrrD2a2GQYBb40rmN3W0g1Ai/Xd0HxqS7Tf4gmRHwyjALv3eFq8aHZ9gupROAVNbqo9taVqYTsViWzKJpV2QiIZtGOjVHg5vbGc7M5UwgsIeo51hXpIiuVlilDMiv3bqWjWZgMo8APZy/bbR0CryzSCsqUKRmF0SxOhlHgjbs8Xm0rEHh1kS4uuzVlWjK89clYj2ZFMowCH9z3/dXZbY0LvOb+zJPFVaeqTFOSWRHNimxKRbMqGc7HSPuntUdnWuCkGl3joxqDk3Zs69ZTi8Erk2EdyHHaPV6dv+0KnKgvV5UWyC81mXXXtMvfVCKZtW3qHYklU+DEQ0zHuiqVX6bpyax8aCY+mpRkIDAd/wjsbVePQJBdpogm3FZSY6wC//3sboOx9n/JTUgTmKZC24SB+GLLlGjHxhkNW20lR8M5lHLjXmxTm5AlMJW9bcpHfUUaTLZja1mj4Sgukh0b61DK5vfUvzofG7dPbEKSwIQ1mjRfjrwypUwmKRtx0VDt2FiHUp6er0+uSWziP+LiWA3lIaZNnPBKWJlSbyHOnZuWZAoMpfz8YU0T3QYprzCxvW3q/MaCDNYeTcbaokxG8RG4o6jC9CWaPj+5DIPJbluNSMxGiMHE0fBeAx/P/Suaa+AbxRTO03DyFwyUL9Ms8rZWoqFeKOdjpO3gLvTmMvUvFwisa+DbLOlfgFS2THPZ2yIaP7zPgff9c+Bm90PxHPiBpoFvc1B8gVm5Ms1ob0uSzcJFEK5NtmgUj8R6wmpwnsu7BxQClzI488WM4n1bzpKxILCicTNzkAhcpE6z34tQu2/Lm0wJgacfIUU2UUDg/PfLaPzlr9PsOzayaNgNzp2MCYGZBr7lb0OjwHmvKZ5ojIZjxyZHYDdkfiHjDaFl4NsMVFXKVqZMuRAmszyalWvItGOTI/DCJvgEZtoSLWWVchjMl0tbNJqV2Sx/0yqMCJzNYM4ipazS3Aaz5tKWFXhhNqw7NjMC5xoSmGOpISj9zXmqyFuhPaTRrDB4STaLl56EicdIHRly494WtAKvOFWMWV9+eTvK7tvauGwK7NgKCHzcdQfg3Tm1iY+NQJyd8qPMuuXNrHORCu0QEM10Nv+KRcMt8PZ2j9k1kwavEVjFwLcpqKuUtEzLVWiHBIFD2ZRNhlvgg9teOoFfk7yvbiLbIbjQ9iD3d+Ui3+vxX+EKbXNEs3KJH1GUToZd4MZdbvewkj/Qn+sQXGyLSBG4498Ayg6tRFI00sJhFrg/fc4lMIHB5TZJhiLNtFB2EM0EzAJv7kfgk9ukNuHbAmn6Fd2j5ikoE2WKaCYocw18bLov+05rglrgsudDmcrJQpUimim470LvqOaF9m+A1RKWvpzJVU76yzTbGuiPpqPIc2C3+01vwp//Kg/L343IV0zqyxTRTKJ2JFYo/uUqFrc3bykpL1NEM405gZePyl/277OAKg2CaKapW+Dy5849eQtJdZkimhnsCRxrsIzn8B25y0hxmSKaOQwKHGOwGHlbjiJSW6aIZhbW70aKnjUnTeBZgwXZ26JKwzD0W2s0TxgFPrAJPG2wLH1ZSkhnmbL0Wmc0LzhPoU/N9PCNZU1MJh+UVNK5cw9PAaksU0QTAes18Gn6K82WNTETvE9UcfbylY/CMmXqssJkhvDexDoMvmE0tYnZ4N9sFWgvY/XoK1NEE4XFu9BPnk+K5DwyGvEfY+1oK1NEE4dpgTuEfO7aB2/hqCpTzl2bsmjeMC+wXJhXQFNeiCYaCFwK9v7rCQzRxAOBy8B7jnhrkr3FdRSIRk02n0DgIhTpvI7EEM0iIHAJCvVdQWQlDr99u2WaTQcC81OqSBVEVq6H8rPxA4HZKdhx6ZkhmsVAYGaKHX5vrZdsfA5EswIIzErZGpUdWum+lW5/HRCYkdL6toJTQzbrgMB8iOixiE58IEBfqdHMdAsCcyGiRmXGJiQaldlAYB6k1KjA3OREozEbvQLLSzuMoBqVlhuiCROTDQTOj6gabUUFh2jCxGUDgXMjrUYFBScvGn3ZQOC8CKxRKckhmjDx2UDgnIis0VZGdBL64EFAt/5bUjYQOB9S9ZUQndhsivdrYTIQOBdiS7Sj9IhOwdmU7driZCBwFhadBZWgZPeEZ1PyI1HL24bAGRBeoR0FP3grPZxi/VuVDAQmR3yF9pTppPgzk45S0ax6GwSmRUWF9vBP/agmmwITDq6OBgJToqVCe1j7qkbeDt6upu3YIDAdmmq0Zc1PWTKM0STv2CAwEaoOMTe4OqwvGbZvRkxvBwIToOfqbgxHp3VGw9JnkmQgcCo6K/RG5p5r3bG1DMVFFY1igUWcmknow3pydl6vvD2ZoyFbvGaByx+EdddomzFAJBNcMG00ugUua7D6Im1zBYhkgkulXqxygct9l47yM8Qn9GuBZMKLpF+mdoGLHIStlGgH8ZogmvDiskRTQOBD4zYHwia4K8ZQiXYQro0lezs0RMMp8GnnmkP74zq2dE1wD3xjbY4BmhUyc00xgGqFckbDKPCpN3fvvi/teecmj8HLmlA08E0k6etkMxeSysq9Y2MU+Nvt23bvmu71xW3omuApHouHmDtJ62U4l+TSYoiGUWDXv9HtBj8QNZG/gCwXaZsQoPFcUkqLacfGLvDv7dz5diCmaiL7kMC8yy/PuhW0n8v6ZLiiYT2Fvl793rj0p9N0TWRNq4YyXZNgFbmsWE3eawpGgS/N87zZTR+AlzehZeCbXBauZjW5tMuiYc+F9Tnw/qFtM3n8lSKw6dszH8Sva125tNHVVSQX/SOxbpAnV1uRtlEK/1edvD1xyTB05BMrAhMbXGOVttOrXam7dyZXvWQyrAL//ez6wRy7/R99E6Tj3uiWpYzAqtfs7h2/pcV3a5w3sTbuBeFQyjtkMVZeq+8VWbxEBTHM4j8ZwTAKvHfN76l/dT42tI+ReqjG9JIsRjf/DSjdF3HIyoVR4Madnq9PtAM5bpCMXE1fBgB8sI/E8v1A1YT8kasA0GLpCJwisKCTIgDi4b0GPp77V3mugdvVBkNeoBXOx0jbwV3ozWXqX65uYo2IsBfohfc58L5/DtzsfjI8B76xWEboCzRjZiTWg0U+4twZKMecwAsMhr1APSUEnn6ElNpErJXQFxjAnsBRBuPcGdhAjsBuSNLyZ92EvcAKcgQmbGLaT+gL7GBS4AlHce4MTGFT4IDCsBdYw95jpAfvssJeYBB2gY+77gC8O2ds4sHrY5v4qAIwCrfA29s9ZtdMGkx4kJf04WsAqGEW+OC2l07gg/vO1QQAFcEscOMut3tYWT7QD0BtMAvcnz5DYACIYBZ4cz8Cnyi/XhSAailzDXxsKL/gG4Bq4b4Lvcs2LzQAFVLkObDb/eZsAoBqsDsSC4AKgMAAKAYCA6AYCAyAYiAwAIph/W6k6FlzIDAAUTAKfIDAABDDeQp9aqaHbxA0AUBdsF4Dn6a/0oyiCQCqgvcm1mHwDaOZmgCgJoTehQYARLHCLnphlXXggZSOSOmHmI5I6Yecjgwp3qniHXggpSNS+iGmI1L6IacjQ4p3qngHHkjpiJR+iOmIlH7I6ciQ4p0q3oEHUjoipR9iOiKlH3I6MqR4p4p34IGUjkjph5iOSOmHnI4MKd6p4h14IKUjUvohpiNS+iGnI0OKd6p4Bx5I6YiUfojpiJR+yOnIkOKdKt6BB1I6IqUfYjoipR9yOjKkeKeKd+CBlI5I6YeYjkjph5yODCneqeIdeCClI1L6IaYjUvohpyNDineqeAceSOmIlH6I6YiUfsjpyJDinSregQdSOiKlH2I6IqUfcjoyRGSnAABxQGAAFAOBAVAMBAZAMRAYAMVAYAAUA4EBUAwEBkAxEBgAxUBgABQDgQFQDAQGQDEQGADFQGAAFAOBAVAMBAZAMWUF3jeu2V+KduHGYSOkI237J2Kfevp27vtcuhftRUaFHB7bREZ3hhStlm3/jWybkl24se870kjYMpdGgsBHGYGcm1s/Cu9JTo+vDRRTsC9KVsufa07tqXF/BfvQc3Lfl243+126I1d2a75jkpzmumUuu9ivcM/Gd9+DfeENcy3R2zYRU7ADSlbL3h2vf/66n4J96NndUpCgzu+qL4ml70UnzsU1hfvhJGyYg9veOyCmYAeUjGbnulOjk9sV7MMQAeqcn8VSlG93Kt2FnvvlRNkdyXVndt8m0gq2o2S1iNi/vri4bekuXC+yzhLi2Lj2p+mvK8rycz+FLnrIO71XqoQt9AQCPzn0J0hF+XG/IuJwbtffPCrdj/bQ3cVqDqW7AYH9bYvK49wUPzPqT84kxOG6uzWX7/IXez/9bd/i3YDA/rYl5XFpyp9Ab7rnNhLicP018Ln4A5NDdwp93ZGUPgRDYC+NpDy2pYu1u3XUncNLiENKpW5cdxl+Kb4juQchqmDvlL8LfZZwU++82ZYfduSelO6JlOdqUnYko7vQIgr2SclofvojzrH4cIGuD+XPnyUJfNsy5+Kp3A55Yp5HyynYFxiJ1Uqo1AHl9e2vfi/dtedv4X7sXTfweF/cGIzE8rPpDzfl5fmWcuTrENGLHyFbZiujH49tIqVgBxStlttnTUr24IaYU9cOGb04bkVsmVZGhTy2iZSCHSCiWgAA64DAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwAAoBgIDoBgIDIBiIDAAioHAACgGAgOgGAgMgGIgMACKgcAAKAYCA6AYCAyAYiAwAIqBwNZxA55fNQ+sgA1qHQhsGmzQKoC4VsGGrQIIbBVs2Cp4CNz9//rfj2t+2nbv3L7/7WHjmkPB3oH1QOAqGAv8010PH7fdn53Bu/76eFu0g2AlELgKxgJvL+3h/mfTtsfu1WXrjmW7CFYBgatgLPBf/+p8/3nnLtdXF7cr2D+wFghcBW/XwO3wz9dDJqAPbLUqgMBWwVargmmBy/ULpIKNVwVTAu9w+0oxELgKpgT+dc2pbQ+4iaUSCFwFUwK3/QNh15yL9Q6sBwJXwaTA3Ugs9w1/VQKBAVAMBAZAMRAYAMVAYAAUA4EBUAwEBkAxEBgAxUBgABQDgQFQDAQGQDEQGADFQGAAFAOBAVAMBAZAMRAYAMVAYAAUA4EBUAwEBkAxEBgAxUBgABQDgQFQDAQGQDEQGADFQGAAFAOBAVAMBAZAMRAYAMVAYAAUA4EBUAwEBkAxEBgAxfwPY5ThLHQstGMAAAAASUVORK5CYII=", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:5],\n", + " type = \"l\",\n", + " lty = 1,\n", + " log = \"y\",\n", + " xlab = \"Time\",\n", + " ylab = \"Variables\"\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = paste(\"Variable\", 1:4),\n", + " col = 1:4,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "b014adcb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Continue simulation to observe stability\n", + "sol <- deSolve::ode(y = as.numeric(sol[95,2:5]), times = seq(0,11,0.01), func = func_POSm4_list, \n", + " parms=klin, knonlin=knonlin)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "21bbad0e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol)\n", + "\n", + "# rename columns for clarity\n", + "colnames(sol_for_plot) <- c(\"time\", \"S1\", \"S2\", \"S3\", \"S4\")\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = S1:S4, names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b596080", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAMAAABoqemGAAAAZlBMVEUAAAAAd7szu+5NTU1oaGh8fHyDg4OMjIyVlZWampqjo6Onp6evr6+ysrK5ubm9vb3BwcHHx8fJycnQ0NDR0dHY2NjZ2dne3t7h4eHk5OTp6enq6uruM3fudzPv7+/w8PD19fX///+zdwo+AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2daWObvBKFSeQlLnHdxKnj6yT1y///k9fsi0agXSMx50ObODAMh/OwG7KCRCJFqyx0AyQSSV8EMIkUsQhgEiliEcAkUsQigEmkiEUAk0gRiwAmkSIWAUwiRSwCmESKWAQwiRSxCGASKWIRwCRSxCKASaSIRQCTSBFLGeCs12Z/urvoaTAlS6VuB5Zl23zyaW4ynS0/VvnRefD75fH7drnSzPShP8m0O1hI+8N1uQVB9Rz6UKXSUMoF+unqJmFhvGu+L1N8OMuOoDSUJ5kAXOrooql+SnYqXetexzDdtpnBdE7AWG+Pjw6D3/PH72/LpdwCPOlJoZnOoDQBvm671thFZgS5sr5lCrDMJkZT9nw61K2OtsBnlhkAfAMzOfmMyRV2DnA23fWQaqY3KEmAz5BDawQ427toy67KNh+bwvv0s+lP8tqCmSxXFP3+WLkHrbLxA2QJ4ExpL1phOio9GLTgAODzpLu3pRGwSgvg+qf79VhuY0aHfTg1z4HGUjvBmRwjW+5BX6aDqMkE4Pqna9mF1nrEBsAm4xcuAa73oPJyxXYpD4QztjACWhkA/NC93BJtrDbkQrYBvok2KqOdZtbGQl/mANdH5jp9JA1wCS27Nb9UW+OTyYQCygzg4s7qzcyA4009QD3c+eEU68+D3o/V6m6bX4fFTo/VwLY08Jo/yu3PwJSu+WY4HvDBQPdjuV7ZH+99nSlvw8/q/y6P/d9NfuuGOJcnrjdg/XIWj+CyPg52SMrN8RGe7XqSj/2XzXE8nwJ/HtPbtnMzskXU5Ki5wT7T2JgCsHHITDb8pZmj9nC6372Q6qEXPzj3SdXm5jQFeGwDbyo/N10L2yGv5bjlX/rf8za+YBTgpdf/MMm4ZxkCXEX2WB/91XNcbp0OzXC39kRfs9gHBx55V+zG6k+2Va3B0IMp7SfjtfuwGXQa/Nj97dTVWQQ4b35v8eumCBziH8vFDeaznflSeWcJN9vVyNUsvI3mc9YfdhbbMm1y1Fz3y9QYyMZ24JFp7f+DfYruR7keOvGDc5+c2xm+Dac/tYE3lU9JO/4hG/NbzffgzN59k5/v3QiTKMBLr/thmnHfMgX4WjtfzmV9HuCtmfXK7G7Wq/XTJRvoXEwH6oe+TKbEBuMdppWmh5nbwd/ytk42aXv4WTXguNNhEe40+7UaalKw0ab/lLWj8rPdzfd+NJ8L/nC2iJscNleGdQMaA9nYjjkyrf2/Xyfd2hpyPXTiB+c+6Ztiw+lPbABM5VLStlAdRAz5rVCHTk9U1nRFBKEdAzzJuHeZAlz+zur/6jXofpiA7aVZoVaGbpv1Z3UFrstudrjXx9L9T/vxlKrL7edyX6Y1sRzoCB+CV8OcHoVO5XRP40rgfFST3j86vZRj5O0Uy96v+4xftW6qsmA+u9VXveDrVRo/2/Uk20vEXSWBP5uytU3GnWiZabJvrj6JlcPGADaObZmUu3SOlmuF23IPAwla5j9hw1keZGlsA+8Vn5Km73KFO+a3Ws9C9yABURAsvX7wcca9ywbA5e+HwUwd2s/rVeq5Nf123NRrqftwyVSmXLufLlxSr328jk3R9k/dvk+nwdFNtQd2H1aC56Pv9NJM6dp9UsViPIXjuIWx7t2CzLu/87NdtFCNO4H9aWadjVM53+QEnvKPkDGAjbMA93sV22WjAID5wflPurQ0m1SBDZxXQErqvqvTNGN+hSer+CiIlt5k8EHXnmUL4HIOyp2SyzBn9V7KnbdruGT6HcPJLmL7Q551xyNt0rJMdPXqmI1PtByhnsef9ZNuPxxcAOo3Oo2uTRwEGehWZAxYJY9m7cJ9yg84mM/uNq+hLaImJ/CcBMYANs4DfBzMwFGtB7hl/pPSwLd+loU2TDsGUlL/aXqD62TeuM8vokFggIUZ9yRbABdNPvLhzHFr9VL3S3UuNBv/pR+c82mbcfs7VYHNETjqKP/Sftyt3pcBHnc6vM85m5yeYfNXHM5NXLoVGTTb1cjciV9gwEFr5WZzMxx8rskROuxNZAxg4zzAt2auzk1f0j2IWuY/Gezdjk5iTW2YegWkpDuk5U50zgG8GNpxQsHBPcoawIfa2M3kBML4x9upP1M4/gvwEz9Qp+7MwmF23TpTYTapk+wN940O7U7TePxujtotbz4cbTrbcJez/vAzM9Pk4G/b/dt9OpXuF8DGOVuKavE2q+luzTjXQzEWPzj8iWiWRz9PvAIm11Xn7lQo96pFx8Dcj+KlBw7uWaYAN2eh65XyrVtFgzPXnXHvvIDiwtkDeXPuz12PER4NPFcBmrQA4Gwy2uRP48GaXRDW77Dysy0AeM6fRYDBteqSMbyNc7YU1T40q+fuTbOH8eDwJ6JZHvzMeQVMrq9+mvxhchZ6vM89nvbc0gMt8ixTgPtDq8qn08zyr6/ksf3pMjpJMx2cswf25q0zdnQ9YDTwXAVo0jYArldh5batOXECzDbc5aw/bgDmbZyzpZm7S/WvyI2lHsaDw5+IZrn/mfcKmFxdvTpxPdncDk8IFIMrbfw8zy490CLPMgWYdYu+2rncdqcY+JkrT09sb6M/QnHh7BkevY10rm68GV9/3Gdax8DjD4Hv+g5Hm0R2Et/qICLv99uA2YZpEvjTzM1tOjMzTUIzDBpTaWTjnC3NVA9l/g/tbyo98IPDn7SrPrENvFdQSurZKoednE+sKvdnpssQT892ikObFMDdTWjNiY2sO3XDz1z/idoWePC12mZf5/7IXL1OvUyN0zwLPf5w5msIAMATledJu31MeLaX9hNG/hz7svlwsLnvSgCdAcZANi4BXLZRbpXOXSGFHvjB4U8a605iG3iv+JTUQ91qPidsj+6FrnZCBLvQs0svdoCvb9Wqe3Dv8h6co4EXdV5yJYCrC/FFN+KmPlN55CZTabBu7X9UBXi8hVr0YazqUnDWnyQBZlsMMOBPk7NNJr4OLNMcYAxk4xLA5dxtuuWh2AM/OP9Jf0X1zsQ28F7xKelaeMu481jVfQesPP9+P1ch7m9dHbc/u/SiBXik7tpB/bX5w2C48Y/lim57bb+/JQ8wf49NdXtqeVv77ZBNbwCquuhuOOLOiHeqV8v3AlwM7RSLW87dKsLP30RjH6DZhgEW+FOdX7r0N0txtgBNQs3xxkA29mP2Bo3K1cfMw9uPFXrgB+c/KXnatDdDiWwAvBLeiVX/afJolP4u8Lo417M4tIkBPDiWyjrnCmjmJt+hHt8NAfzU/XAf3uXa3TbXeQ9dIx43B7nbYwYshtEU4dvUxUts7AM02zDAAn/YeFSBLeMmweZ4YwAb+zEH66Fhueruim63V7EHfnD+k1t/ZrwtwdsAeMWnZLQ4p/dJjQhu96YHPTc/zi49fnD/MgX4OP3T8JfJj923YQ6le+dCFuDizn3PpL/jfDO5S274pZvpV2yGqq+BTm6K7H4cXjyAH/s1s8TKJA3yws82DLDAn+5rONwtQuIm4eZ4Y3gb+zF7g/h2+x1SxR74wYFP5r+NdBGZyqeka2Hy7aNK1003+B74qmb749zSAwb3LhOAN+1NAo1Gp/ugmbu23/wsF82+kAa4/Ipmaff+2NF6zau9Ke5GjlL1FzgHXx0F3S13xza5oNPHn6tzs9NZHPsA/6XCYhgXbrYFAIv8qb4ee+QHFzcpaI4zhrdx6EBr0LjcYYKqYg/84Pwnx+abv0OApzbwpvIp6VsAr2RcqpkffqFYKrSRAzyjwe2oJBLJhywCHO6GbhJprbJHXPWt0kCPJSCRVipbADeHxdwZJRKJ5FB2AaYjYBLJq2wBvAn5ZD4Saa2is04kUsQigEmkiEUAk0gRiwAmkSIWAUwiRSwCmESKWAQwiRSxCGASKWIRwCRSxCKASaSIRQCTSBGLACaRIhYBTCJFLMcAZyRSzHKLhwURwCSSWG7xsCDnALutT0pBaFOCtrFeBDApuNCmBG1jvQhgUnChTQnaxnoRwKTgQpsStI31IoBJwYU2JWgb60UAk4ILbUrQNtaLACYFF9qUoG2sFwFMCi60KUHbWC8CmEQSKYL4EsAkkkgRxJcAJpFEiiC+BDCJJFIE8SWASSSRIogvAUwiiRRBfAlgEkmkCOJLAJNIIkUQXwKYFFxoU4K2sV4EMCm40KYEbWO9CGBScKFNCdrGehHApOBCmxK0jfUigEnBhTYlaBvrRQCTggttStA21it9gH96hW4lsNAa4Tsl0kYgiO+SkgT4Z04hGgqlSIzwkBI9Iwhgrw7MxhVlch2JjOhkZgQB7McB2cAmH1wyopGqEQInCGDHDigvp1SDS0Y00jUCdoIAduWAxsJJM7hkRCt1Iwr+k4kIYAcOqCwh4djWu/IvpagKR/fZsStZMQL8OwFs1QGDpTStYrGrALJoRNxOuDaCALblgIXFNC5lpy3/smhE3KsyG+SOakF/IIAtOGAvsMOCxm35l3UjYnXCXyIIYDMHrCd2UNakL+9K3Aj5lHg2ggDWd8DJghqUNi3iS24SO6hto0lDyaUkgBEEsJYD7hbUoL6dUo61EiOWU+I4EqJSBLCyA44j20/DYj038mUEAifmU+LBCFEkCGAlB3wsqX46tqvalCcjsKzKxCkJbAQBbHp6wk1XSHILa4VGCFLi0QkCWFTe4PSEu66Q5BbQOo0AUoLDCAJYwgG/S6qfpONpqMtzZvtJup2GhKYpCWTEcmMIFRjgAPQWKAEOYwRCJ1AlggCedSBMZgt8sQ1mBDYnsCWCAFY6v+i2FW7a3iY3r4A+4AI4eCL4jwlg6fOLbtsAp+93kgKREbUCJ0IwSQIYciA0vQWW3Ib3AYkRCJwggAXlufrBF1XXRJApT3ogIzDQWxDAwvLj+hgWVddHqIl3DSBwIrgRWCJBAAvKD+sjWVZF8Nyi8YGMGHXCfUoA9w7gWVZF4NxicgKHEVmG1AgCuHUAU2iLkLklI0aT7gAO08OkG+5TArh2AFdoi3C5JSOG0x0AHKAFoCHuUwSNLckDwOhSGyq3ZMRwqgMjEHBCAAvKZ/hCW4TJLRkxnObICQycgE5gaGxBPgF2OykV+W8HJb5YjMDACQEMl88QptZ/bpHii8UIDJwQwHD5DF9oC9+5RYsvFiMwcEIAw+XDX+GD5DO3eOktPAMcnxMEcAmw2yloyV+GUIfWK8AxOkEAI3XAW4pwh7bw50ScRiCN71BWO2QPTcrjdMBTkNCnNoAT7qelJwL4wW/3T18epwN+ooQ/tZ6ciNYIpPEdigB2Og3kqfXiRAT7IQUB3IkAHkwCe2o9OBEHvgRwJwK4mwD+1Lp3Im4jkMZ3KNsd0kmsIqLUInECQ0oI4FoEcFT8+nJifjAMKSGAK034ReuAy9xGhK8nI5YmgCElqwP4T8vqxwtjvz7qn6f8onXAXW5j2vwWSIzAkJK1Afy3vWXjlVV6LX/m+EXrgLPcRsavByMkhsWQkpUB/Lu95+qL7T6L4nPH/tU3YrEozkI7y21k+CIxAkNKVgXwx479bkh9Z3/L/z7ZB1weqQOOchsbvs6NkCuNISWrApi9fBYNwK/sq/7oFS6P1AEnuY1u81sgMQJDSlYF8GOnuQV41+wysx1cHqkDLnIbI79kRKtVAVyqAbg95p1+Daktj9QBB/mKMrYujbBb1bUIYLg8UgfsJyzO2JIRrQhguDxSB6xHLNLYkhGt1gowHQP39SKMLRnRaq0AN2ehv9Z9FjrW1LoyIkIn1grwe30B+IO9w+WROmA3ZfHGloxotVaA/7V3Yn3B5ZE6YDNmcZ5+bmS18Yh9WC3Ao3uhgfJIHbAYtJjxdbImUx8RQ0pWC3Dx93XHXuAbKfE6YC+3cfPrYE2mMSaGlKwOYMnySB2wltvI+bW/JtMZFUNKCGC4PFIHbANso1QQoTACQ0oIYLg8Ugds5TZ2fnEYgSElBDBcHqkDlnIbPb84jMCQEgIYLo/UATu5jZ9fHEZgSAkBDJdH6oCV3CbALw4jMKSEAIbLI3XARm5T4JeMaEUAw+WROmAhcUnElgBuRQDD5ZE6YJ64JFJLa7JOBDBcHqkDBHAjMqIRAQyXx+qAaegSia05wEkbgTa+vQhg/dETiC2tyFoRwHB5rA6YxS6Z2FoC2Fo74UQAw+WxOkAA17KyJ2KvnYCC5gRtfHsRwLojp5FbFCsyFCkhgMHyWB0wCV5C/OJYkaFICQEMlsfqgEHyUuLXBsDmTaBICQEMlsfqgH70kuLXwp6IhSZQpIQABstjdYAAroViTwRFSghgsDxWB7Szlxa/OFZkKFJCAIPlsTqgG77E+MWxIkOREgIYLI/VATOArbcTTARwKwIYLI/VAc30pcYv7Yl0IoDB8lgdIIBrGfmQkhEEMFweqwN6+VtHbGVHS8oIAhguj9UBrQCuZLsjOVZSPhDAgvJYHTAA2EU7wUQAtyKAwfJYHdBJ4FpiKzdSYkYQwHB5rA5oRDDBHWiTFVliRhDAcHmsDmgD7KadYKI9kVYEMFgeqwPqGUwzttprMps9oEgJAQyWx+qAcgjT3G/UXpNZ7QFFSghgsDxWBzQBdtVOOGEwAkVKCGCwPFYHVFOYKr+aANvtAUVKCGCwPFYHCOBGGIxAkRICGCyP1QGt3DrrJqAUZ8zJqQAUKSGAwfJYHdDKrbt2wgmDEShSQgCD5bE6oJbDVE9BF3pG2O4BRUoIYLA8Vgcw5BaFyIhGBDBYHqsDSkFMOLY6ADvsJqAIYLA8VgcI4EZkRCMCGCyP1QGVJKYcWw0jEnWCAAbLY3VAObdOuwkoWpM1IoDB8lgdUIhi0rGlNVkrAhgsj9UB+Swmvd+oviZz201AEcBgeawOqALsuJ1wIiMaEcBgeawOKObWcTcBhcEIFCkhgMHyWB2QTmPi2x0CuBUBDJbH6gAB3EjNCDc9oEgJAQyWx+oAhtyikOz8uVyRoUgJAQyWx+qAUm6ddxNQGIxAkRICGCyP1QHJPKa+A00AdyKAwfJYHVAB2H03AYXBCBQpIYDB8lgdwJBbFJKbQ7d7IihSQgCD5bE6gCG3KKRghIduQgqYR7Tx7UUALw6VdnAJ4FYEMFQeqwNSiVwBv2REJwIYKo/VgZ+f74cWB1pDbGWNSN6Jb84JtPHttVqAv/nFxQ+0mtiSEUXxzTuBNr694A7v53zPsixj+/x8NyqP1YEfYHFxw6whttJGJO9EOgCft9lQ+7NBeawOSOR2HbElgFulAvDpsend5Odr9cv1LX/8yk7a5bE68C0JsLeGQonWZK3SAPiyyVh+G310zR9EXzTLY3WAAG4kC7DLHnCkBIgEjsZmNe0wy478QPeT7pygdeB7meB1AIzBCBwpSQPgPXzO6n7QLI/Vge/F4K6DXwmA3e9B40hJGgDbLo/VgUWAV3LgJ7smWxHAAyNwNDYrAlgwwEr4RbEmQ5GSb8AJFI3NS9ThNd9U3e+vZuWxOkAAN8JgBIqUpAXwoboCXP49M7gKjNgBDLlFodqDGSdWBfBPIgDvs8257v6cZSa3YqF1YCm3a+FXzggCGK3ADs/Zpmi7z6HrSvLlsTpAANf6xgAwCqUE8L7ab667v2Vbk/JYHWgWlDC464rtgg9rMAJ0Am18e4Ed1n033RvNBFoHFgBeW2zJCAIYLo/VAQK4FgHcCnICbXx7gR2yAcD3jJmUx+rAEGA+uOuLrYjg9TmRAsCHwTHwKdO8i7Iuj9WBdjHBBK8vtgKA12ZEIgBfM3YvustIml9EqssjdWCcWwKYAB4D3DiBNb4DwR3mGauuA5ffJMyNyiN1oMstHNwV5paMAIzAGt+BBB0eu+dxqPE7PV7G6sA8wOuJLQ6AMaSkN2LgBIbGFiTq8H4sn6uzzdVuhWYEcGQCc9vJkxEYUpIawFpiEW6BgdyuiF8CuBUBXIkAjkyzAPsyAkNKCOBKBHBkmuZ25MRKAe4jgaGxBfHPxOKlUC5WgIPkFoO43A6dIIARNLYgApjbBK+JXwK4VSoAS+tPy+rHC2O/PppfYgR4SvBqAQ5mBIaUgEZgaGxBuh3+ba8YvbJKr/VvCQC8Kn5xAIxBKwP4N2sA/mK7z6L43LF/1a+RADxaWgTwKLedEys2oo0E0vgOtdjh7bLnPvvYsd8NwO/sb/nfJ6t3ouMFmHJbTJxYvRFo4zsU3OHtMHsSi718tjddvbKv+qNXuDxOB8ZLqyCAh78RwNEDfGcDfIHXIj12mluAd802l+3g8jgdmAA8JHhdsZ1bla3LCXBNhjS+Q4EdHrPNvfpW//2NiR4r2wDcnsvi7oJuyuN0gABuJQaYjIgX4G1J7T4rv8hwYwx+rCwBnIQI4EZgJJDGdyjxM7FOWfVW4JPgsbLpAVwHd125bYwAVmXr8iFFgK9Zdfr5LnisbFLHwKvNLQ6AMaQkPYAXnko5Pgv9FfVZ6KIPLgEcwAgMKQHX6RgaW5DgGLg87mXZrRpiFuD3+gLwB3uHy+N0QAjwyvjlAe4IJoAjBjivTj0fqoPgS/WaFV4NwP/aO7G+4PI4HRAA/E0ABzECQ0rASGBobEGip1JeywdSPv69bgRPxYLvhebK43SAAG7EA1ysE2DYCASNLUn0VMqs/vchwXPdu9POf1937OUDHgjDooHEAxwitwgkAviHAI4a4OJc7TefNhkzeqoshkUDiQBuJAL426sPCFICGFHEDLC18jgdEAHsN7cIBOcW+NCpEKSEABaUx+mAMLcEcAiAEQic54gBvufVPjQ7CO6Eli6P0wF4cfGb5eQ1Z8SqnIDnGWl8h4I7PGftvRxGr/dG6wAB3IiMaJQWwLcsO9RfYThvzQhG6oA4t9+UWzKiE9L4DiW4kaM/97ytv9OgWx6nA/DiqoMbpqNAmjGCAEYb36HADlnWf4XwJrgTS7I8TgcI4EaCw10yohbS+A4182UG6Bfl8jgdgBfXD+V2+HGQhkKJABaUx+kAAdyIjGiUFsCHwXN0zhn/VEqF8jgdABfXz8/69qEFAHsmOHxKWh8SAficsVv780b0UCy58igdgBfXj+/cIpBgTUYA1wrf2KLgDvcZO5UI304sxctIQoBXR/AswN6MCJ+S1AB+ENzKZAcaqwMEcCsRwH4JDp+S5AAurvm2vA0rvxqWR+nAAsArIpgAriVIRPjGFrXKLzOAi6v+CuzKCBYC7HVfJHxKCGBReZQOiAFe2c0c1cw+B1+ThU9JogCfNtnmzaw8Sgfq3D5DAK/rHoZFI/w4ET4loBExA3wq7588VWexjB7JgdOBZnE9DxdX+ywOAtg/wOEFJeJhBM74jgR3uK06Ly8hXVlmch4LpwNzAK+KYAjgnzWuyhID+JxtbuUDZbNL+fPBpDxKBwjgRkKAuz+uxAlBInDGdySww31JbvNoykL0WEq58hgdaJfWDMDrzu3QiHU4kRjAdd+b+iaO9L7MMA/wmgieBZiMiBvge1Z/lX8dAP9Qbhv1RqzoaCJFgM9Z/YLg9L7QLwR4+PcgnfkWkNufKcCrcCIxgKt3ezeHwAej60goHZACeA25/RYBPPr7apxIB+C3bFs92K58vGyW3aBBZMtjdGAJ4NUQjMWI8CnpnOg/+okY4PI6cFZ9J/jxn9GToVE6gCW3wQUY8TMywtPRRPiUpAZwkbNsX255WX6HB5Atj9GBRYDXchQsAngyhHMnwqeEB/gnboCtlcfoAJbcBhcWI4Kn5JsAFpXH6MBybleyCcZiRPCUdEYQwNPyGB3gc/szze06CJYF2LURwVNCAAvLY3RAADA/TOoEi3LLDeO4j+ApIYCF5TE6QAA34nPLG+GD4OApIYCF5TE6IAPwKvah5QFO3AmBEQRw7ACvM7fAQIk7ITICZXzHIoBLUW4bAUasYVVmB+DzYVM+h/moceuiPicrBPibA5g/CV2sOrfQYH4786tvzogfdYBvm+5Z6urfHiCAFdQvrRHA8HB+W/MsUW6hwVJ2ovdhZIRSfO8s21/K2xavR2b4NgQlEcDFLMAp51YAMDxYyk7YADjvt7s3ZvYFAiUJvg88FNsftW+IjgJgeLuzgk2wJMDJr8psAMwGg5q90VNNEgA3X0zSK48a4GZxCWKbPMHcoZ9oTZY6wTYA5t+p/fjnus2y7an99HpgWbbvNs7nwwOs/DYaezzIW/mKsv381hzu8C3bnsut7v2SP/YG7kftB9slAPCKchvKiNApsQHwhjt1lWXnevPXvN8zH78usH1/4LkeFhhkm43GhwV2eB88SvZUsnvITtBwywq9aCCp5jZZguWNcLwvEjolsBFqAJ+4bWWJ3rUoLs05rcdWsPz7eVPDta9+LR+YcS/aCY0HyavRi8tmFj6ww3zwFI57OfpV9y3BoRcNoG/V3BLAro0InRKhESqNVdvL7eF0aU8YZc3T5O7VuxHuGWv+sCl/vbaHpfUjq5rHSI4GaY+q559KB3a4Ge3PbxTnZFQeKcDPcrlN+yhYGWBXToROiRWAH/uq7S5vvSXOsua9YqeS0WN3Zvpc/pq3m9V7z9dkELmHWc08F3r4S8oAC0/dFIlvghUAdmtE6JRMjfjRAvixWT0dNv2dHB2At3L/dduXKpHdjumsJjQZ5HGQnJ8Xr/+AHW6rNzPUupRTvycP8OzQ3nrzK2FuhQM7ciJ0SkAjyh90GrvkrD4z1Y9c/jS6qsNVbraSo0Fu1RZ9k1+KOQmeSsk68jfljsBJ98JW6EUDSA3ghAnmTgYsr8kcORE6JVYBLsr9431hDnBxOzQXcZVPYj02wexUbuJvp/INhQ+gdW8tCb1oAE0Bnt3upLwTrbMmI4AFGg15nxx2ioid/ApM7XqqrjbNECzo8NCtCY7VmkH3zpLQiwYQCPDC4ARwkfC+iHhXRD6+29EmruGxOcy91sfA1/Hw7TFwdY9FcwwMvsn3sp07DS3q8HYs0d9WX43KNppXgVMAOF2CFXdF1mOEDsCn4YXW+qrr+Cx0Pr7RozsLXb++t5rQZBCW9RekxBNe31E0chMAACAASURBVJcZ9ABOMLiqRiRLsHhNpnQvdE/ftkI3a+5fvLH6wm+7ja7ulL62Nzdu+xNek0E6nq86W2BLSgDgdeV2cYRVGaEQ30t5sqncBb7W542qI8/N5QFjcydW/jiUfWxSb3n90sB9tnnQetu2w/KDPI6kD+UO8KPAm3i6og6veXlFa5uDe+XySgHgVINLRjQaGlEaoAVwce2/0H9oRj6z4c3P7Y3OzWZ2O7zReXIvdD3Iuf1t7gEBgg7zSTO6Sgjg5IJLRjSyA3D7SJ1t8wWjcuT74QFQd3brUn7VaNt9N/e8z7qzS+2ExoPcyq0oO8xuROEOH/weq92BoyHB+AD+nuR26dRNP46X9jxKHeAVGGEC8ER+sg9O5Nx/AfhxBD5/J8hCeZwAP08AlhrJQ3NepbEmS5Pg9AAefnvwZLQJTgngxHIL7orIjWS7lcApSQ/gLOvvob5rf5m/rmQwshMZAJwWwVpGuCEYF8A/KQBsq49EAE5xEzwxQmoP2tGqLGxKviGALTSGZguMfyZUpAdwggRDAMuOlh7Az/YB9qO1HwNLbngI4PF4dltBBfBPAgCPz0KbPOMWnwNGuU2I4G9ERuADGEVjUoI7PCR+HVg7t+kQPPJBxQgHBBPA+lr8OmFid2JNNjyye9BFcptgArjRd5IAF9d8m+S90JPcysc2NYL1AU7aiGQAtlUemwPGAKcSXMgIJYDTNIIAnpTH5oABwGlteciIRmMjnn8I4FF5ZA58m+Q2qVuiJxseDSMScQICuP0btvgCmnaYATIpj8yBydLSATjJ3BLABDBcHpkDZgAntAn+BgBWHt1Zdz6VGMC2yyNzYO6AR3p8Z915VD0jhgCn4wQBLCqPzIG5pSU9fgq5NQQ4MSMmkej+iC2+gAjgVeb22xRgq06ETMnEiOgB3sNvU7pr3pCFzQFTgFMhGIqtjhF2nCCA9cWfxAIe4n4/JfJys9n9JYUK0RNsDrDNVVnAlEx3RaIH+LLJWD5+L+k1rx9wq1UelwOzS0uhBAFc2DyhFxrgIiGA6/cUb/JzfRP09a18WeLs69EGYg9NyuNywALAaRCMywgCWF9Qh+ft6DLwXvYLwaz7py+PyoH5/SWlIpETbMMIe5vgtQF8KgHb969byA0mA496P+f78qnybC/xjvBOcQAsXFpKVQjgwh7ByAB23Vi7fWxfh/ZmMhmbHa4E4AQIHhpR8LlVKmPBiOAAi4xw0liebcszSpdt88qUg9HNjgSwZpmoCbYKcPRGeAa4fWRk/cDmE8sOBLCk5veXFOtEn1tzgNM0YvBnlfj+wOIHHBctX1JIAEvKFsDR3xJtC+DoCQ4BcLML3ah7O7CmtEf905L68cLYr4/yJ+wAt2GzBHC6uVUsFK8Ro0T4ArjYl+egT4OHVYUA+G97xfeVVXot4gTYsFScWsqtaqlonQgDcHHJq0s83XY4AMC/21s2vtjusyg+d+wfeoC/LQIcN8FQbk1KRetEIICL6kJt1r330zvAHzv2uwH4nf0t//tk5U407juxuqRZAzjS3H5bBDhqIxbXZE7je+0uBHsHmL18Fg2qr+yr/ugVLk8A49PYCEOAk3CisuDJD8D9i8e66t4Bfuw0twDvmk0u28HlUwU45tyOjQByq17NzIlQKYGMGA3gorHuxWO37sW9Qc5CNwC3+8zTfee2PHKADavFSfBibjXKEcCyumbZoTwDfd5039wlgGXUx6wH2LgeAVxYOKG3KoCLc/ctIRuTEYx63Cw9lXL1AEdL8MQISwCbGBEa4NoHXwAX9+q1RYf+S372AWbLj5WN7Rh4GltbuY2PYEcAGxgRKCWTDbA3gK0K7PCYscXvAI/PQn+hPwttH+BIN8GDpi0BbGwEAawvsMONxEu9u+vA1V2UH+wdLo/GAQcAx3k3hwOATQkOkxIuEbwTeOIrFNihTN8NwP/aO7G+4PJYHPh2BnBsBBPAjQjgSoN7oTUreZETgGPcBH+7ADjKVVnCAB+y5fd6d6ed/77u2MuHqDwWB7jYWslthAS7BDgqJ/hEpAPwpb9EZVoeiwMuAY4ptzy/KzUiaYCLPNtrPgh6Wh6JA8N4rTq3royIbl8EMCIdgJN7vei329xGFFwyohEBLFcehwOjcDnIbTTBdWdEZARDq/R0ALZYHocDlNtGZEQjAliyPAoH5JaWSXELdbzIIcBREfwNGUEAA+UxOPDtHuCYctv95gRgHSf8pwQ0IimAr3n5faRtvnxBeL48BgckV7dG5W0Ucq5vpwDrr8q8pwQ2IiWA8+4MluabvdvyGByQXFqW6iPWpFE3qzINJ9YG8OjlZuUvm6N2LdF14OxYbnuvR0OCMQDsOrbR7ERP+1wtwNJGeHi52Xb8ojNlgR2eM9a+4/vGMpNbOhAA7Dy2sVxKmrbZGhF+XyQIwIPf/QI8ernZ45cHahfWvOhMXYJ7ofs3ep+MNsFYAB78bh/gSDbBojVZ+H0RzynhuvQL8OjlZqyewjWDn2gjUW1uEt1ktBUeYPmlZToRS7VcSWhE+H2RJAB+gsUPCBbVtmD564SR34nlD2DcBPNsOQBY0wi/KeF79Avw+OVmtW7aB8ESW+CoAVZYWsaTsVXMicRGrGxVJliT+QOYf7lZedCqe6Yp8WNgYJ/OCcDoCQbAcghwXE6IjXADMPdys+KsfQ5L5iz08vOxZsqHBRiKk0OA8eZ2zggH+yJ4jVBbkzkCuJi83MyAXxjgxyY4ievA4OZgxQCPP3MDMPJ9EbU1mZ+Xmx0N+BUAXBKcwJ1YHgHGTTDYnEuAcRshvSbz8nKz4QGrRjnB59fq6fFx3wsNH485zS3O4Ho1AjPBqkZ4eLnZjTGjh98k/G0kAVLryy0Z0UrVCPcvN7uz7nSTntIFWLRJdJVbtAd/354BxkuwciLcv9ysP1bVrJYswMJd2rXlVsSvayMUnPCUEnUj3L/czPjBVdPxqkIJPBNLGFt3ucVJcAxG+EmJhhGhb2OQUKIAL8QWR259SGyEQ4BVjya8pETHiAgBtl0+4HvnFpaWq9ziInhmd3ZdAGsZQQAHfG3V0tJyBjAmguc6cgiwIsEeUqJnBAEcxIE5fp0CjG4TPLtGcQ6wtBHOUzKbiAQBHvYd3/eBJZeWi9ziIljCCLcAyxrhOiXzRiQOcHTfB5ZdWskDHI8RjlOyYETiAJ8jA1h6aTnJLaK7OTAYgcKJJSPSAviUcYrq+8DySyvt3H7jMAKRE+IhkgK4e+ZlKxbT1wmXY7uS3IY3AsuqTNKIdACuPrTWd4inHc3HZhW5xWAEjqMJMyMIYJ8OfMvE1lNuwwZXxodVGaGbiFgBtljenwNSC8tbbgMGV86IZ+dGBCdYbo2eOsC3y96kvDcHJPl1D3Dg3EqmduBDokbYSES0AN8Ow/NYJuU9OSAbWx8ABw2utBEeAI7DiAAAj15udtxkLL/PjzAjsMM7G+C7wf9uJPmF5RHgEMFVMAITwA5SYicR3l5upv9YDrDDY7a5V29tub+ZPVXW5/dM5JDxcOgXbsujtyILb4T1lCgb4RPg0cvNTuXLze6HTPs4FexwW1K7z8on99wY09+8+/yeiSQxXnIb5grKt5ITHgFebMd2SqwZ4f7lZpv6F/0JiS8jneqn550y/ZcPe/yeiSwwHgH2S3DMRthNib4RnBMqjT3D4geEiup/Y0gM8LXerN/13z1cOAdYNbW+cuufYGUnMBlhMyUmifADMP9ys9tW/9HQMzdyNN3jPQv9rZxaXLm1PTm8Rix0ZS8lZkb4AZh7udnjV/29XMExcLljzrJbXV67uFOAdfD1lluvBEdvhK2UmBrhCeDJy82u270BwWCHeXXquX6E/CXb6NYuXAKsxy+q3NqckvLkfBkh44SdlJgnwhfAxeTlZsVdfx8a7PCasWv1jsJrcd2YvHnJGcCaC2t4zSB8bu1NRmNano1w7oRuIqwBrKzr4OyS/nNv4A7zqvO8vsasWbku78QB7YU1u7Tsyktu9Y3wB7CXVZkdI7wAzL3czGxKgvHO1X7zqbzLS7NwU96BAwYLyyPAHgg2McK/E+7quzPC/cvNWI3zVftANbpvIxktLJ+xdU2wBSPSWJWZGeEd4PHLzY7Z9l6ex7J7DJznZm9MG5R3do+N/aVlW05za+jDyAhPTrisbTAF78fAo5ebtTdGa+/oCq4Dm9w+Oa5kqVAlU3z9AuyQYLtG+HLCWWGj8v5PYg1fblYdp2Zb/S8cxPNEDvPQFp4BdkWwDSdCAIzXiCBnoe1IcB34zVZ5F/fYGATBL8AutjzfNlLrG2AnBHswIlaAi0N2vIJ/UC5vxwE7y6rwnlv7BNtyAhXAGimxtB5LFGBkrxe1hm8ogG0RbM+IZ1RGqKfEshMEsLC8uQMW8fUPsE2CbRpRzzoWIxRT4i8RsQJssbxpfasLKxzA5q3bNcI/wHMEK6XEgREEsLi8Uf1vuwsrwJ6jJYLdGDEGOCDB8inxYYRWY8GEGGDby6oIsuGxsBNtPbVTI0JvgmVT4sqIyoMiIYARvB/YwbIqlhaXI5nNg0MjPAMsNkIqJd9OnEgfYNMv9Gs57Sa1gQA22Yt2aoRvgIUES0QsTCJSANj0/cDqbrtZ1VYCFhdigl0b4R1g7VVZqERECLD19wOrOu5uWY3OYRU+c6u1F+3SiFAAaxHscD02BXhqRIQAW38/sJLpTpfVKLZ+AVYOrmMjggGM04ikAK4+tPhlBnnjXS+rkAAXKrP17dyJ52AAKxnhKxK+AR69G6nUWX86ngBeNN99aIugAEsHl4yYDufeCc8Aj96NVOpmMB3n14FlFoCfZRU2t1JPHCcjuGE8GDEAeOKE+3cjVdpgBnjpe4DconL48CQwt/43PfAshjTC3wn5SngTMTHC/buRSu2ZfYCPG3tfZhAuDH5JOX54oWBxeT/8kzHCqROBjRDfZIcsESrZBxeizG0rp8zkUi08JhudiNYu3jYrmDfPC2tmcYVBOJgP2IwYHmihSoQTgCfvRro89qRtA3zMmNFbgQflm/oIQlsAi6t4DpvcUE4gM0IEsPsuFoxwAvD43Uh3tjXaVQfH3Ji91XtYvqsfOrPF+IxFs7jQEeynCT63/o0YOAEC7KOF5wUj3AA8ejfStnwDmW2A3TzULmxmi3Fs2/+GC8xXH4HpLUCAh8H17QQHsK/pNzM7NmLghCOAi/7dSPXj5+IAuPB3dQAWDHCAbU/h6XKvSNCGpwhohNzFRgeCAe6dcP9uJOMzTeB4h8zOI+2Q3YsmADjERjisRLkNZUSwlAiNKNwBPH43khuAL/VD4y0IE8DPQoAHyQ3WnU+JcxsGYYQA139z0dj43Ui1rF9GyrP9BfyDcnlsABcwwH1yAzXnVXO5DbEuQwlw4Qjg8buRatk/Bta9Djx9ekc8AK9oIzy3K1KsyYh5gAtHx8DjdyNVQgMwixjg9WyEyYhW8wD7eTeS4XSsdshi3gIXqwkuGdHoOQzAVmW5w7gBXklwyYhG7SwSwJ0iB3gdwSUjGi0agSm+Aok6vOb1lxT3aleEEQP8LJPbVQSXjGiUMMCH9uxVpnZbNHaAi6XcriG4UgCTEQWq+IoEd7jPNue6+3N/48iMGGvOP8cPcPrBldsVWYER6QJ8zjZF232eHad//tNi+vHC2K+P4Z8SADj54OIzIlBKltdkiOIrEtjhvtpvrru/9c/eavS3vdr7yiq9Dv6GF+Bn6dymTjA+I0ICXKQIcN130/10Jn63u8tfbPdZFJ879q//I3KAyx+Wc5s2wQprsoIADtCWmlQB/tix3w3A7+xv+d8n+yiEwuOACsC+ghtECI0IkxKJNRme+AoFdsgGAE/eTshePtsbJl/ZV/3RayEUHgeUcpsywQiNCAhw+UN6AB8Gx8Cn8buRHjvNLcC7hmy2mymPxgG13CZMMEIjCGB9gR1eM3YvustI3BcL20tGbPQrXB6LA+P9pafF3KZLsCLAPowggPUFd5iXj6V8dH/Ns+7x8b2iBbj8oV1MCHIbRqoAe3CCANaXoMNj911Cnt91AJwqwc/KACftRPlDigAX92P5ncVtDt0KHeMxsDrAiea2n6eVAyyzJkMTX7F0Ohyfhf6K4iy0BsBpBndsxBMZsV6A3+sLwB/sfaY8Fgd0AE4xuFxs12pE4gDf8/Ju6IIdoO8iNQD/a+/E+popj8QBvdwW6eXWyIiUnBjMT4IAn7P2ZizuTuiiP2sF3AvNlUfigGZu0yOYAG6UNMC3LDvUXyI8bwGCu9POf1937GXmRko0DjybAZxQcMmIRkkDnA8uHm37p9fqlMfhAL+0JHObXHB1AU7diKekAGaDL/Hfqu8Ga5fH4YA+wIntROM0IkRKpNZkSOI7J7DDUd9GM4HEAYPcpkUwTiMCpETOCCTxnRMBLDVuKgTjNIIA1hfY4WHwJLuz0YvOcDgwDJ5ybpPaBPNHfspGOHDCf0okE4EjvrMCOzxn7Nb+vFF7LOW0PAoHzABOiGBgu6NuhH0ncAAMOIEjvrOCO9xn7FQifDsx6EKwQnkMDoxSpw1wCgQbAuxqVUYA60vQ4b77NpLZm4JROGAKcDKbYMnYLlWw7gQBrC9Rh9dc/G0klfIYHDAGOBWCCeBGnBFP3U+j4VDEd16OO0ThALi4NHIbPcHmACeyKgONIICh8ggcADfAWrmNPbjWAI7cCDgRBDBUHoEDNgBOYstDRjRaAcDHTdbLpHx4B8aB081tAsF9tgJwAkasAGCWZQQwUCbq4JIRjQRGJATwsXwopZ3y4R2wlNv4tzxkRKP0ATa7+2pUPrgDk7Tp5zb64NoCOFUjEgLYXt/hHQCW1lP3k3qleINre00WtxEEsGT54A7ILy25UrHmdtq8AcDWjfCbkhUAfMgMb8Dqy4d2QBRbndxOi0Wlae8mANsm2GtKhGuyhAC+GN4BPSgf2AGVpaVeLSZBRjx1P+kUixngwe8pAlzk2Z57pZleeQwAD343AzjiTbDYCAQE+0wJ13mKAGdZKteBLQMcLcEzsTUA2JYTBLC+0gZYaWlpFYxEXNuGANs1wmNK4EQ89T+GakxXSd8LzW8nCOBGpgBbdcI3wMMPZo0ggDEAPPzEFOBICeabtgSwHSf8pWQuEQQwVD6kA0DELAEcG8FwbJ8GP2vWjMwIYOmlCvA138T+RA6INWOAI87t8JPh3Bs5YdqaX80mIimA8+4M1sGsfHCAx5+ZAxwhwfPbnRWtyuYTkRLAD36P5bb3ejQkODjAk8+sARxTcOe3O4YAp2DE0+Dn0V9jBXjwXOgby0xu6QjogHB1+9T/aK0wZi1sd9azL6JuRKwAHwZvJDwZbYLDOQBuH8xP3XSlTXrzqiUjVrMq0zAiVoCzwdsJ7xmDBpEtH8oBeP9uvbmdfGjTiFicWBXAol+Uy4cFePqpndxGRTAZ0Wh5lc47ES/Awy1wjAALtg3ry61bIywdTfhIiYQR6QAc/THw3NJ6Gv5iVF+3O58SdLpWgLmP0wR4fBY6wrcTai0t5foRECzq0xbAdgj2kBIZI9IB+LEJjvo6sN7SsjEFZBKtaKztitgxwn1KhGvcRAEuCY73TizNpaU+De2xPcmDEVb2RZynRNxlqgDH/HZC3aWlPhHtsf1IxYgnYCiFieiOXct1SmbWMskCbKu8fwe0l5bGZPRH9yBZI8KvysIB/EQAL5T37sDcPp11gDET/OwTYDMjHKdE34g4Ab7nefPT8WD6eFnvDswek9kHGC/Bc/xaBRj9voiBEVECfGHdzZObzPT5sr4dmI2tzUM/7JtgBSNMAcZNsJERMQJ8y7Jtu929Hx+/mJX368D80lpRbv0bgdQJMyNiBHiT5YPfbiym68AyS+tJ9Kvm1PTHd6gFI6DcPomGlZ6afgF30klE/3uMAJ+zzej3xwbZ5DjYqwNqsW0X15NocMnpaY/uTktGgAAbOBGtEYJEdB9FCPAhext/kI+2yMrlPTqgGNt+caX2nQY5I54mv5ogHLUR098HH0YI8Ca7jT+4GB0Fe3RgcWnNLC7N5OLMbSgj0DlhbkSEAPMtG82EPwckl9YT/4l+cDHm9nnZCC63IyOe4HEkJqoxokuZGlEQwP4ckFhY/NIqjBHGl1sZfiEnghrhJCU2jCCAPTkgs7BAgE0PALERLM/vE/ypphFmm2AHKZEyAo7EwIgIAd5PTzrfIjgGllpYAoD5MxfqU1Yfz5ECG6E+Wi37KZHjd9GJCAE+ZsfxB/ifyCG5sIRLyyS5qAAOaYQRwbZT8qzC79PMnyIEmHsI5Qb7EzlkYzuTW4NLoYgARmCEphOWU2LPiAgBLg7j67755MYO1fKuHZBd2RZLdwxqBhfNJtiWEboEy04ckt2UWExEjADf2ZDgPJteF1Ys79gB+YW1eMtv3ARHbYTNlCisyJaNiBHg8vZnVj0Qq7geHz+a7EC7BlhlYc0d8AwHUA0uDoBVjFjKrRHBiuPUspeSZ/VIzA0QJcDFfd89ECvb3/m/K5V36YDSwlpeWpp7jwgAVjNi2YloV2W2jYgT4MdG+FgyzPZvhvg6dUBxYUkArJfc4LnVMuJJZhgdIwI6oWpEugBbLO+qvtq+UimpQMa3CVb2QcmIxeH4VlTGsCnNRDzNDUEAu3JAM7ZPkoMtD8c1ozSGPakbIQewPsEqI1iUEyMIYDcOaCwsydhqERxuy6O+1ZFek+kQHA5gHSMIYJnyDuprLSxpgDUIDnXwh86IUATrGUEAy5R3d5erYlLkw6hLsFI75iIjRhPV5PdpdhAC2N1drqoxUchiFPuO2k64NCLAvoguvlJGEMCObpLTCIlKFDWDq9qSvhIzQj8ljo0ggN3cJKfBiloSVYPrd8tjZIQSwJoEq7aknRLzSMwPQgA7uUlOBxS1HGLeBNsw4klxcPnhtfrSTIn7SBDAthwwXFaqAOMlGLsRWq1ppcSHEwSwHQeMl5Vybv1seZT1bO4ERiPUU+LJCALYhgMW8FXPrV5wFZtSlA0jVPcsvBCsmhIL+BLAkuWN61vBVwNg1eA63wTbMULdBz0jlFpUS4kVfOXWZASwoQPPdhaWVm4Vg2veo0x542m4N0JjVaaSEq+JIICNHLCGL9LcSiuwEar73Q7XZJ6NIIANHLC3rHSO/PqxpEdzRbBFfDUBVvQvHSMIYCuX6M2zoBdbFDvRVlNrBrD0eMkYQQDrOWB5WWkDrEWwxmSWSpIRgSKxNoDZQ5PyGvWtLyv93IYNLj4jZIe2TXAoI1YGMOv+6cubXaK3lQGvAFtqGpcRagRb7TmgEQRwkEv0nPRjG2wT7CS15gDLjovdCMl5WRnAlQwAdhRaI4CD7DsiNkJybFutu3KCABZKG2BnqVVk0GhsG827M8IIYB2CJSsLUhLeiBUCrHsSy+HCMout733HNRoBpsSlEQSwUFoAO11WprnV2QTrzsOzWyesGCFZQGUWgJTgMGI1AHfXjyb8SjngGF/j3HojOBIjJCsozMY0JY7XY6sH+E+L6ccLY78+Bn+Z8rvsgPNlZXoIXOjtO6rPiXsjjAF2tSobp8RTImQGTBPgv+3dGq+s0mv3F47fJQc8hNYCwO72HacjuXXC2AdXZ/QGKcFlRJIA/253l7/Y7rMoPnfsX/OXmudx+Zn6XpaVDX6dE+zHCO8ASxPcpcRnJGQGTBDgjx373UD6zv6W/32yD/HgYgc8LSsrsdXbd5Scp/SNWByuTok3I1YNMHv5LBqAX9lX/dGreHCpK3xun0RjJbfOCPbohEWAZcvIz9YzSiMSBPix09wCvGv2ltlupjxQ3+eyKoIALLnpWY8Rik6YdbioVQNcqr1kxEa/wuWn9T2H1lZsHQTXtxM2zgWo11E3wrzDJRHAugBPM+vjSeh2AZautDCLoYx4slVHutD8LAZLxJPUoARw7wC3qHwsq8IewKoAiOczjBG2+I3eCAJY/RiYh9fTsrLIr0Fw+7kFjPDlBA4jnqHPAhjxJDds2gA3Z6G/5s9CQ4vKG74WtzvK+45gSIMZYR9ghWLRGpE2wO/1BeAP9j5THgBYp01dWYytxtoATWjJiF4EcAvwv/ZOrK+Z8lnARVVYzq16NSyhtbonolVu1gifnCh1njbA/L3QQPlsvKg8K3hugx7tDWTXB9tGeORErfPEAS7+vu7Yy8yNlD3AGlOxIOWDNamCymOFZbeSZR9014wCJ3wDLD10ogCrlA/qgG1+7YPgSdaNsLtq9JcSxbYJYAQA269ot6QPOVqT2apIAOsrZYAd0BYnwC66tlnTW0pUmyaAQzpg/Qi4L2q3pms5NMJOUb8AKwxPAIcH2ElR21Xdyk3LEQKs3DIBHNABR6TFCnA0ZR2KAFYvH8wBZ5vK6AgmIxqpN0wAhwbYWWEXld3I8ZrMQWFH0uiXAA7mgMNwxZVbh5jFZYROuwRwigBHdfDndDMZFcE6zRLAoRxwGq2YcusBYEfFLUurVwI4kANukxVRbh23Go8Req0SwGEccE1YPLl13WniRhDAQRxwv4WMhWA/RhhXcZ8SzUgQwEkD7HIKVuShTSsTcJ4SXSMI4BAO+KArCoCjMcJ1SrSNIIADOOBn6xgBwF6MsDIRxynR75EA9u+Ap71b/JvgJ49rMsOJuE2JgQ8EsHcHfB2dogfYE79W9kWcpsTECALYtwO+UoueYG/82jDCZUqMjCCAPTvgL7YeVxU68miEBYIdpsTMCALYrwM+Y4t6E0xGNDI0ggD26oDX2GI+EU1GNDI1ggD26YDn2OLd8pARjYyNIIA9OuA7tmiPgr0bgXUTbG4EAezPAf+xRbrlCWAEToItGEEA+3LgKURsUeY2nBF+J7koG0YQwJ4cCMMvxtySEbXsJIIA9uNAmNQW+IIb1gjvUxXL0hqdAPbhQKDNbz9p/9OFFa0R1lNiywkC2IMDAWOLi+B4jbCdEmtGEMC+vqodiiJEAEdshN2UWDSCAPb0Ve1wDGEBamjC1wAACmpJREFUOPCKzMwImymxagQB7Oer2gERQrIJjtsIiymxuyIjgL180zMkQMEbGDQRtg8MANs2ggD28EWxwPhg6SB0FyYE20qJdScIYHcOYImtyZbH2uTxGKHVhJ2UODCCAHblAJrUht4E4+G3CNuGEyMIYDcOIEptEZRgMmI8bdvTJ4BdOIArtQFz+4TSiWATdmAEAezAAWypDZVbdPgGW5W5M4IAdneXK5rUBsotGTGaqJspE8CWHcCY2iLEJhjh5reU/4bc+kAAW3UAaWoL7wSjNcJ3T66NIICd3CSHLLWF5y0PGTGamMtJEsAObpLDl1qvWx7cRujti2ilxIcRBLDte2xwptbflidNIzRS4scIAtiGA/jxLTwdBUdghFZ3yinxZQQBbMGBCFJb+AA4ivWY3iZYMSX+nCCAjR2II7WFe4LjMuJJaRSVlIzoVZuMughgMwci2ehUcttkdEY8qYwinxKv+BLAZg7EhK/TE9FxGaGxKpNOiW8jCGB9ByJLrbtNcHRGFI4ADmAEAazrQHypdUQwGTEq6tkIAtj4En00qXWyE01GjEv6NoIANrxE/2S/I4ey3HKk67HC/iY4mBEEsNEl+rhSW9gNbsw+uDPCUk1ZEcBqDkRNb2Fz3zEJI6wVCmYEAYz2Er0b2WmdjBiXCWcEAax5id5hR25lof0E8LWzL4LACAJY0oEnBAvLioz7T8QHY4JxJIIAlnIAxbKyJKN5SM+IJ6lhuZRgMYIAlnAAybKyJP35wLHNsSYDgPEYQQAvOZBYagttgpPzQcWIYUpQJYIAnnUA1bKyJo25WbsRfUqQGUEAzziAbFnZk+ocpYlvoWBEkxJ8RhDAIgfwLSuLUpkpMqJoUoLRCAIYdiDp1PazJz9kokbIEpxlSI0ggAEHkC4rm5KbNzKiHSrLkDpBAE8dmIT2ye3Ug2l5/siI6RAYjSCAZy4QIFtWdjU/k2QE91ecThDArQPckkK3rGxLNKNrM0I4ozEYQQA/HADYxbisrGs6w6APT6G79CBuhuNxggDOpucXsS4qB4JzSkZEZAQBnHEAu50eKsUZWheK1QgCOMN6gcCPYgytE0VqBAGcZZEsKmeKLbPOFKMRBHCWRbGgHCuexLoWbARaTtA21stqh+yhSXn8DpCCC21K0DbWy2aHrPunL4/fAVJwoU0J2sZ6EcCk4EKbErSN9bLeIQFMUhXalKBtrBcBTAoutClB21gvux3SSSyShtCmBG1jvWgLTAoutClB21gvnQ7/tJB+vDD266MYXT8igEnJKIL4anT4t4X1lVV6bf9AZ6FJaSmC+Kp3+Lvd2n6x3WdRfO7Yv+YvBDApLUUQX9UOP3bsdwPwO/tb/vfJPto/0p1YpKQUQXxVO2Qvn0VD6Sv7qj96FQ8egQMkkkgRxFe1w8dOcwvwrtnast1MefwOkEgiRRBfnQ4bgNvd5elu86g8fgdIJJEiiC8BTCKJFEF8CWBScKFNCdrGehkATMfAJDtCmxK0jfUyALg5C/1FZ6FJZkKbErSN9TIA+L2+APzB3mfK43eAFFxoU4K2sV4GAP9r78T6mimP3wFScKFNCdrGehkAzN0LDZXH7wApuNCmBG1jvUwALv6+7tjLx9ygEThACi60KUHbWC/nj5UlkSKWWzwsiAAmkcRyi4cF4e+QRCIJRQCTSBGLACaRIhYBTCJFLAKYRIpYBDCJFLEIYBIpYhHAJFLEIoBJpIhFAJNIEYsAJpEiFgFMIkUsAphEilguAe5eXqivPzNPvFye/i/GXmae97Ok9xe2+/OfQQNF+eIZ7VH/q5+XYFDgz+4xA7pjs066Fb5eGfv9b3k4kcr8/J553Mus+Fdoao5fGKbQsRwCLPHAjiX9NYhv8aue/i+z8XcGCSwfO6Q/A5+G/Pzb1TOgOXrHr26Br3p0bf/+1ON/ao0sfIWm6viFYQpdyx3A3MsL1fXbIL6P5f/rMeX/7ZjmNuijHP+/30YroOLFaAb+mkz6Me3H+P9+6c5/o1/ay++1fOjhh7Z/n2z3v6p/nX0g8Ss0FccvDFPoXO4A5l9eqKjBixB1tOuWoN74L3VyjBbe685g9BeDVV9RGl+h85/2FrTSh/5apJ51bQN+sf+V//1v7qGnAs2+QlNtfNMUOpc7gGVeXjirwYsQTWRYwiT/H+xTf+qG5D02HP8zGr/SP4MdkHoNarAL3/yv3oHiKzTnxreVQmdyB7DMixtmNXgRooH+6R8EF9UenP5ZuP899l71Z+CxBf14WXhm4Jx+sfL8zc7gJF5R5l//JN57vQut24DMm3sEUnyF5tz4llLoTu4ANlgAfBF9GW2IHkc/+gD8t/tlMgPNORzt9Q9jf8xO4hXlSsTkAPp9Z+LfS73t1N2HUXiB19z4eiN7VOoAG0Xw69erQQKr0z/6M/BSrXn0dwFYdfrGaBeiPQ+gp/+9VOsP3etA1UnE8vQTATynxAE224Q89J82APVJZONl/4+96I3YXID50h2/MHTvfxWA/35p7wHVl/H+EMCzQnwMXI1sZt27Kb8G55LMb4Ro65iNZzB9/UtIRbf1/k9/H/6jem2A5vgmx8CD8bmfscn5WejZlxcuysy63ya7j6YthAb41Rjg/ww23pb2wMoN+W+TyWunkACWeXnhokys+7fbmVxI2dVbEJNd0MJkBprp6wa49f9/+ivQv0aLrtn2ae/BNPP/rnkrlsIrNOfG537GJncAy7y8cFEmdwLvzO6CfGe//ivPY5ltxU3OQr/+Z3IM+V97J5MeAIXpleQ/1X3M+neC/Sn9/+9zp30KoPpPO4UEsI17oU2s+226C9vcS212FG10BGo2/U/T/g1vBWv632meyP5vZ3QvuuG90ARwIfPywkUZWGd+DFp9j0V7+9V2oT9uOf1Xg43g12MdZuK/aW7fH/3v/mivBOovU+lex1J4heb8+MV6ASaRSI5FAJNIEYsAJpEiFgFMIkUsAphEilgEMIkUsQhgEiliEcAkUsQigEmkiEUAk0gRiwDGrmyk6oPQLZHwiMKAXQQwaUYUhjhE1JJAUS7iEAFMAkW5iEMEMAkU5SIODQCuf3z8e91m2fZaFOfH/4db89frgWXZ/hyiR1IAEcBxCAD4XJ/WuubVf6wmOG9Odu3DtEnyLQI4DgEAZ4d7cd9mmyy/lxvjvPz0mLFy43veZIcwfZI8iwCOQwDA1Ub2ktWoXrLN4997xu71QJvs6rtFUggRwHEIAPjS/HbtPz1m7cHvud4ik1IXARyHoJNYBff/djDUxltvpIAigOOQHMDTm7ZIyYsWcxwigEmgaDHHIVmAffdFCixa4nFI9hiYzj2vTARwHJIDOKdzz2sTARyH5AC+Zu11pDPdi7UOEcBxSA7g8k7K070obnlGO9PrEAEchyQB7u6FzujrDOsQARyHZAEuLuW3kbbHu9fuSMFEAJNIEYsAJpEiFgFMIkUsAphEilgEMIkUsQhgEiliEcAkUsQigEmkiEUAk0gRiwAmkSIWAUwiRSwCmESKWAQwiRSxCGASKWIRwCRSxCKASaSIRQCTSBGLACaRItb/Adff9me80LdDAAAAAElFTkSuQmCC", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "colors <- c(\n", + " S1 = \"#EE7733\",\n", + " S2 = \"#0077BB\",\n", + " S3 = \"#33BBEE\",\n", + " S4 = \"#EE3377\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(size = 1.5) +\n", + " ## vertical dashed line\n", + " geom_vline(\n", + " xintercept = perturbation_point,\n", + " linetype = \"dashed\",\n", + " colour = \"black\",\n", + " linewidth = 0.7\n", + " ) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = 0:11,\n", + " minor_breaks = seq(0, 11, 0.5),\n", + " limits = c(0, 11),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 11), clip = \"on\") +\n", + " scale_y_log10(\n", + " breaks = scales::trans_breaks(\"log10\", function(x) 10^x),\n", + " labels = scales::trans_format(\"log10\", scales::math_format(10^.x))\n", + " ) + # log10 transformation\n", + " labs(\n", + " title = \"Dynamics of the 4-Variable Positive Feedback Chain\",\n", + " x = \"Time\",\n", + " y = \"Concentration (log scale)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "markdown", + "id": "24c09faa", + "metadata": {}, + "source": [ + "### **2.4. Pertubation Analysis**" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "70a2312f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "t0 <- 8.6 # perturbation time in original time axis\n", + "idx0 <- 86\n", + "cap <- 0.05 # window half-width (before/after), like Python cap_range\n", + "dt <- 0.0001" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "07e45a5a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "s_star_pertubation_1 <- as.numeric(sol[855,2:5])\n", + "tpre = seq(-cap, 0, by = dt)\n", + "sol_pertubation_1_pre <- deSolve::ode(y = s_star_pertubation_1, times = tpre, func = func_POSm4_list, \n", + " parms=klin, knonlin=knonlin)\n", + "\n", + "s_star_pertubation_1 <- as.numeric(sol[860,2:5])\n", + "# Change the 4th position to 0.75\n", + "s_star_pertubation_1[4] <- 0.75\n", + "\n", + "tpost <- seq(0, cap, by = dt)\n", + "sol_pertubation_1_post <- deSolve::ode(y = s_star_pertubation_1, times = tpost, func = func_POSm4_list, \n", + " parms=klin, knonlin=knonlin)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "b89c6113", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "t_all <- c(tpre, tpost)\n", + "y_all <- rbind(sol_pertubation_1_pre, sol_pertubation_1_post[, , drop = FALSE])" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "ef4f5f4b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "Plot with title \"Perturbation Analysis: S4 when S4 is perturbed\"" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "t_all <- c(tpre, tpost)\n", + "y_all <- rbind(sol_pertubation_1_pre, sol_pertubation_1_post[, , drop = FALSE])\n", + "\n", + "# Plot: 4 stacked panels (base graphics)\n", + "\n", + "# To save as PNG file, uncomment the following lines, and the dev.off() line at the end\n", + "\n", + "# png(\n", + "# filename = \"model_1_perturbation.png\",\n", + "# width = 8, height = 8, units = \"in\",\n", + "# res = 300 # DPI\n", + "# )\n", + "\n", + "op <- par(mfrow = c(4,1), mar = c(4,5,3,1))\n", + "for (j in 2:5) {\n", + " if (j==3) {\n", + " xlim_vals <- c(-0.005, 0.005)\n", + " ticks_seq <- seq(-0.005, 0.005, by = 0.001)\n", + " } else {\n", + " xlim_vals <- c(-0.05, 0.05)\n", + " ticks_seq <- seq(-0.05, 0.05, by = 0.01)\n", + " }\n", + " plot(t_all, y_all[,j], type = \"l\", lwd = 4, col = colors[j-1],\n", + " xlab = \"Time\", ylab = paste(\"Concentration of S\", j, sep=\"\"),\n", + " xlim = xlim_vals, xaxt = \"n\", xaxs = \"i\",\n", + " main = paste(\"Perturbation Analysis: S\", j-1, \" when S4 is perturbed\", sep=\"\"))\n", + " axis(\n", + " 1,\n", + " at = ticks_seq\n", + " )\n", + " abline(v = 0, lty = 2, lwd = 2)\n", + " box(lwd = 2) # black outer box\n", + "}\n", + "\n", + "# dev.off()\n", + "par(op)" + ] + }, + { + "cell_type": "markdown", + "id": "dc7729e7", + "metadata": {}, + "source": [ + "## **3. Additional features**" + ] + }, + { + "cell_type": "markdown", + "id": "6aa20302", + "metadata": {}, + "source": [ + "### **3.1. Add subject ID to make the loop result more comprehensible**" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "id": "b8a59f66", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "id_to_subject <- c(\n", + " \"S1\", \"S2\", \"S3\", \"S4\"\n", + ")\n", + "names(id_to_subject) <- 1:4" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "id": "a9a0ae03", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "df <- res_tab$loop_rep[[1]]" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "id": "2cce91f7", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "df$loop_subject <- lapply(\n", + " df$loop,\n", + " function(t) unname(id_to_subject[as.character(t)])\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "id": "44a698ce", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 4
looplengthsignloop_subject
<I<list>><dbl><dbl><list>
1, 11-1S1, S1
2, 21-1S2, S2
3, 31-1S3, S3
4, 41-1S4, S4
3, 4, 1,....4-1S3, S4, S1, S2, S3
3, 4, 2, 33 1S3, S4, S2, S3
\n" + ], + "text/latex": [ + "A data.frame: 6 × 4\n", + "\\begin{tabular}{llll}\n", + " loop & length & sign & loop\\_subject\\\\\n", + " > & & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1 & S1, S1\\\\\n", + "\t 2, 2 & 1 & -1 & S2, S2\\\\\n", + "\t 3, 3 & 1 & -1 & S3, S3\\\\\n", + "\t 4, 4 & 1 & -1 & S4, S4\\\\\n", + "\t 3, 4, 1,.... & 4 & -1 & S3, S4, S1, S2, S3\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1 & S3, S4, S2, S3\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 4\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> | loop_subject <list> |\n", + "|---|---|---|---|\n", + "| 1, 1 | 1 | -1 | S1, S1 |\n", + "| 2, 2 | 1 | -1 | S2, S2 |\n", + "| 3, 3 | 1 | -1 | S3, S3 |\n", + "| 4, 4 | 1 | -1 | S4, S4 |\n", + "| 3, 4, 1,.... | 4 | -1 | S3, S4, S1, S2, S3 |\n", + "| 3, 4, 2, 3 | 3 | 1 | S3, S4, S2, S3 |\n", + "\n" + ], + "text/plain": [ + " loop length sign loop_subject \n", + "1 1, 1 1 -1 S1, S1 \n", + "2 2, 2 1 -1 S2, S2 \n", + "3 3, 3 1 -1 S3, S3 \n", + "4 4, 4 1 -1 S4, S4 \n", + "5 3, 4, 1,.... 4 -1 S3, S4, S1, S2, S3\n", + "6 3, 4, 2, 3 3 1 S3, S4, S2, S3 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "markdown", + "id": "14c9f240", + "metadata": {}, + "source": [ + "### **3.2. Represent regulation relationship from Jacobian matrix**" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "id": "080c0f16", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A tibble: 9 × 4
fromtoregulationregulation_words
<chr><chr><dbl><chr>
S1S1-1inhibition (negative)
S1S4-1inhibition (negative)
S2S1 1activation (positive)
S2S2-1inhibition (negative)
S2S4 1activation (positive)
S3S2 1activation (positive)
S3S3-1inhibition (negative)
S4S3 1activation (positive)
S4S4-1inhibition (negative)
\n" + ], + "text/latex": [ + "A tibble: 9 × 4\n", + "\\begin{tabular}{llll}\n", + " from & to & regulation & regulation\\_words\\\\\n", + " & & & \\\\\n", + "\\hline\n", + "\t S1 & S1 & -1 & inhibition (negative)\\\\\n", + "\t S1 & S4 & -1 & inhibition (negative)\\\\\n", + "\t S2 & S1 & 1 & activation (positive)\\\\\n", + "\t S2 & S2 & -1 & inhibition (negative)\\\\\n", + "\t S2 & S4 & 1 & activation (positive)\\\\\n", + "\t S3 & S2 & 1 & activation (positive)\\\\\n", + "\t S3 & S3 & -1 & inhibition (negative)\\\\\n", + "\t S4 & S3 & 1 & activation (positive)\\\\\n", + "\t S4 & S4 & -1 & inhibition (negative)\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A tibble: 9 × 4\n", + "\n", + "| from <chr> | to <chr> | regulation <dbl> | regulation_words <chr> |\n", + "|---|---|---|---|\n", + "| S1 | S1 | -1 | inhibition (negative) |\n", + "| S1 | S4 | -1 | inhibition (negative) |\n", + "| S2 | S1 | 1 | activation (positive) |\n", + "| S2 | S2 | -1 | inhibition (negative) |\n", + "| S2 | S4 | 1 | activation (positive) |\n", + "| S3 | S2 | 1 | activation (positive) |\n", + "| S3 | S3 | -1 | inhibition (negative) |\n", + "| S4 | S3 | 1 | activation (positive) |\n", + "| S4 | S4 | -1 | inhibition (negative) |\n", + "\n" + ], + "text/plain": [ + " from to regulation regulation_words \n", + "1 S1 S1 -1 inhibition (negative)\n", + "2 S1 S4 -1 inhibition (negative)\n", + "3 S2 S1 1 activation (positive)\n", + "4 S2 S2 -1 inhibition (negative)\n", + "5 S2 S4 1 activation (positive)\n", + "6 S3 S2 1 activation (positive)\n", + "7 S3 S3 -1 inhibition (negative)\n", + "8 S4 S3 1 activation (positive)\n", + "9 S4 S4 -1 inhibition (negative)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sign_J <- sign(j_matrix)\n", + "labs <- paste0(\"S\", 1:nrow(sign_J))\n", + "rownames(sign_J) <- labs\n", + "colnames(sign_J) <- labs\n", + "\n", + "regulation_info <- sign_J %>%\n", + " as.data.frame() %>%\n", + " mutate(from = rownames(.)) %>%\n", + " pivot_longer(\n", + " -from,\n", + " names_to = \"to\",\n", + " values_to = \"regulation\"\n", + " ) %>%\n", + " mutate(\n", + " regulation_words = case_when(\n", + " regulation == -1 ~ \"inhibition (negative)\",\n", + " regulation == 1 ~ \"activation (positive)\",\n", + " TRUE ~ \"no regulation\"\n", + " )\n", + " )\n", + "regulation_info[regulation_info$regulation != 0, ]" + ] + }, + { + "cell_type": "markdown", + "id": "066927c1", + "metadata": {}, + "source": [ + "### **3.3. Loop Summary in more detail**" + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "id": "e3dddce3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 4
looplengthsignloop_subject
<I<list>><dbl><dbl><list>
1, 11-1S1, S1
2, 21-1S2, S2
3, 31-1S3, S3
4, 41-1S4, S4
3, 4, 1,....4-1S3, S4, S1, S2, S3
3, 4, 2, 33 1S3, S4, S2, S3
\n" + ], + "text/latex": [ + "A data.frame: 6 × 4\n", + "\\begin{tabular}{llll}\n", + " loop & length & sign & loop\\_subject\\\\\n", + " > & & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1 & S1, S1\\\\\n", + "\t 2, 2 & 1 & -1 & S2, S2\\\\\n", + "\t 3, 3 & 1 & -1 & S3, S3\\\\\n", + "\t 4, 4 & 1 & -1 & S4, S4\\\\\n", + "\t 3, 4, 1,.... & 4 & -1 & S3, S4, S1, S2, S3\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1 & S3, S4, S2, S3\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 4\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> | loop_subject <list> |\n", + "|---|---|---|---|\n", + "| 1, 1 | 1 | -1 | S1, S1 |\n", + "| 2, 2 | 1 | -1 | S2, S2 |\n", + "| 3, 3 | 1 | -1 | S3, S3 |\n", + "| 4, 4 | 1 | -1 | S4, S4 |\n", + "| 3, 4, 1,.... | 4 | -1 | S3, S4, S1, S2, S3 |\n", + "| 3, 4, 2, 3 | 3 | 1 | S3, S4, S2, S3 |\n", + "\n" + ], + "text/plain": [ + " loop length sign loop_subject \n", + "1 1, 1 1 -1 S1, S1 \n", + "2 2, 2 1 -1 S2, S2 \n", + "3 3, 3 1 -1 S3, S3 \n", + "4 4, 4 1 -1 S4, S4 \n", + "5 3, 4, 1,.... 4 -1 S3, S4, S1, S2, S3\n", + "6 3, 4, 2, 3 3 1 S3, S4, S2, S3 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "id": "9733249d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 7
lengthnum_loopsnum_loops_positivenum_loops_negativeloopsloops_positiveloops_negative
<dbl><int><int><int><I<named list>><I<named list>><I<named list>>
11404c(\"S1\", .... c(\"S1\", ....
33110c(\"S3\", ....c(\"S3\", ....
44101c(\"S3\", .... c(\"S3\", ....
\n" + ], + "text/latex": [ + "A data.frame: 3 × 7\n", + "\\begin{tabular}{r|lllllll}\n", + " & length & num\\_loops & num\\_loops\\_positive & num\\_loops\\_negative & loops & loops\\_positive & loops\\_negative\\\\\n", + " & & & & & > & > & >\\\\\n", + "\\hline\n", + "\t1 & 1 & 4 & 0 & 4 & c(\"S1\", .... & & c(\"S1\", ....\\\\\n", + "\t3 & 3 & 1 & 1 & 0 & c(\"S3\", .... & c(\"S3\", .... & \\\\\n", + "\t4 & 4 & 1 & 0 & 1 & c(\"S3\", .... & & c(\"S3\", ....\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 7\n", + "\n", + "| | length <dbl> | num_loops <int> | num_loops_positive <int> | num_loops_negative <int> | loops <I<named list>> | loops_positive <I<named list>> | loops_negative <I<named list>> |\n", + "|---|---|---|---|---|---|---|---|\n", + "| 1 | 1 | 4 | 0 | 4 | c(\"S1\", .... | | c(\"S1\", .... |\n", + "| 3 | 3 | 1 | 1 | 0 | c(\"S3\", .... | c(\"S3\", .... | |\n", + "| 4 | 4 | 1 | 0 | 1 | c(\"S3\", .... | | c(\"S3\", .... |\n", + "\n" + ], + "text/plain": [ + " length num_loops num_loops_positive num_loops_negative loops \n", + "1 1 4 0 4 c(\"S1\", ....\n", + "3 3 1 1 0 c(\"S3\", ....\n", + "4 4 1 0 1 c(\"S3\", ....\n", + " loops_positive loops_negative\n", + "1 c(\"S1\", .... \n", + "3 c(\"S3\", .... \n", + "4 c(\"S3\", .... " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "split_by_len <- split(df, df$length)\n", + "\n", + "loop_summary_extended <- data.frame(\n", + " length = as.numeric(names(split_by_len)),\n", + " num_loops = vapply(split_by_len, nrow, integer(1)),\n", + " loops = I(lapply(split_by_len, function(x) x$loop_subject)),\n", + " stringsAsFactors = FALSE\n", + ")\n", + "\n", + "loop_summary_extended$num_loops_positive <- vapply(\n", + " split_by_len,\n", + " function(x) sum(x$sign > 0),\n", + " integer(1)\n", + ")\n", + "\n", + "loop_summary_extended$num_loops_negative <- vapply(\n", + " split_by_len,\n", + " function(x) sum(x$sign < 0),\n", + " integer(1)\n", + ")\n", + "\n", + "loop_summary_extended$loops_positive <- I(lapply(\n", + " split_by_len,\n", + " function(x) x$loop_subject[x$sign > 0]\n", + "))\n", + "\n", + "loop_summary_extended$loops_negative <- I(lapply(\n", + " split_by_len,\n", + " function(x) x$loop_subject[x$sign < 0]\n", + "))\n", + "\n", + "loop_summary_extended <- loop_summary_extended[\n", + " order(loop_summary_extended$length),\n", + " c(\"length\",\"num_loops\",\"num_loops_positive\",\"num_loops_negative\",\n", + " \"loops\",\"loops_positive\",\"loops_negative\")\n", + "]\n", + "\n", + "loop_summary_extended\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb0f25f8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/model_1_perturbation.png b/examples/model_1_perturbation.png new file mode 100644 index 0000000..4db2982 Binary files /dev/null and b/examples/model_1_perturbation.png differ diff --git a/examples/model_2_complex_formation_R.ipynb b/examples/model_2_complex_formation_R.ipynb new file mode 100644 index 0000000..4892932 --- /dev/null +++ b/examples/model_2_complex_formation_R.ipynb @@ -0,0 +1,1830 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c1123f2d", + "metadata": {}, + "source": [ + "## **0. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "3aa06e65", + "metadata": {}, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5aaaa97", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "357901cd", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbf8efe3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5bc2137e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")\n", + "library(deSolve)\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9dd37926", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "colors <- c('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB')" + ] + }, + { + "cell_type": "markdown", + "id": "ef9fc41b", + "metadata": {}, + "source": [ + "## **1. Model definition**" + ] + }, + { + "cell_type": "markdown", + "id": "b1adc5c3", + "metadata": {}, + "source": [ + "Model 2: Model for Complex Formation \n", + "\n", + "Varusai TM, Kolch W, Kholodenko BN, Nguyen LK (2015) Protein-protein interactions\n", + "generate hidden feedback and feed-forward loops to trigger bistable switches, oscillations\n", + "and biphasic dose-responses. Molecular bioSystems 11: 2750-2762.\n", + "\n", + "Supplement Data Table S4 is for Model 3.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "cf9c4c03", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "func_varusai15_simple <- function(t,x,params){\n", + " # function: Complex Formation [Varusai et al., 2015]\n", + " #\n", + " # Varusai TM, Kolch W, Kholodenko BN, Nguyen LK (2015) Protein-protein interactions\n", + " # generate hidden feedback and feed-forward loops to trigger bistable switches, oscillations\n", + " # and biphasic dose-responses. Molecular bioSystems 11: 2750-2762.\n", + " #\n", + " dx <- rep(0,3)\n", + " dx[1] <- -params[1] * x[1] * x[2] + params[2]* x[3];\n", + " dx[2] <- -params[1] * x[1] * x[2] + params[2]* x[3];\n", + " dx[3] <- params[1] * x[1] * x[2] - params[2]* x[3];\n", + " return(dx)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "dae5e300", + "metadata": {}, + "source": [ + "## **2. Result reproduction**" + ] + }, + { + "cell_type": "markdown", + "id": "58ea4a5b", + "metadata": {}, + "source": [ + "### **2.1. Loop structures**" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "d9f19514", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Parameters from supplementary material\n", + "params <- c(1.0, 2.0)\n", + "s_star <- c(10.0, 5.0, 2.0) # Dummy steady state for initialization\n", + "\n", + "# Parameters not yet in supplement data\n", + "perturbation_point <- 0.2" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "4f929c59", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 8 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
1, 2, 12 1
1, 3, 12 1
1, 3, 2, 13-1
2, 3, 1, 23-1
2, 3, 22 1
\n" + ], + "text/latex": [ + "A data.frame: 8 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\t 1, 3, 1 & 2 & 1\\\\\n", + "\t 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t 2, 3, 2 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 8 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "| 1, 3, 1 | 2 | 1 |\n", + "| 1, 3, 2, 1 | 3 | -1 |\n", + "| 2, 3, 1, 2 | 3 | -1 |\n", + "| 2, 3, 2 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 1, 2, 1 2 1 \n", + "5 1, 3, 1 2 1 \n", + "6 1, 3, 2, 1 3 -1 \n", + "7 2, 3, 1, 2 3 -1 \n", + "8 2, 3, 2 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(func_varusai15_simple,vset=list(s_star),t=1,params=params,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "54b7b1a3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 3
len_1len_2len_3
<dbl><dbl><dbl>
all332
pos030
neg302
\n" + ], + "text/latex": [ + "A data.frame: 3 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & len\\_1 & len\\_2 & len\\_3\\\\\n", + " & & & \\\\\n", + "\\hline\n", + "\tall & 3 & 3 & 2\\\\\n", + "\tpos & 0 & 3 & 0\\\\\n", + "\tneg & 3 & 0 & 2\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 3\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> |\n", + "|---|---|---|---|\n", + "| all | 3 | 3 | 2 |\n", + "| pos | 0 | 3 | 0 |\n", + "| neg | 3 | 0 | 2 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3\n", + "all 3 3 2 \n", + "pos 0 3 0 \n", + "neg 3 0 2 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2631d303", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 5 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
4 1, 2, 12 1
61, 3, 2, 13-1
72, 3, 1, 23-1
8 2, 3, 22 1
\n" + ], + "text/latex": [ + "A data.frame: 5 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t4 & 1, 2, 1 & 2 & 1\\\\\n", + "\t6 & 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t7 & 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t8 & 2, 3, 2 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 5 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 4 | 1, 2, 1 | 2 | 1 |\n", + "| 6 | 1, 3, 2, 1 | 3 | -1 |\n", + "| 7 | 2, 3, 1, 2 | 3 | -1 |\n", + "| 8 | 2, 3, 2 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "4 1, 2, 1 2 1 \n", + "6 1, 3, 2, 1 3 -1 \n", + "7 2, 3, 1, 2 3 -1 \n", + "8 2, 3, 2 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2 \n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "adee57fb", + "metadata": {}, + "source": [ + "### **2.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a3bf2b5d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\t
$loop_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A data.frame: 8 × 3
    looplengthsign
    <I<list>><dbl><dbl>
    1, 11-1
    2, 21-1
    3, 31-1
    1, 2, 12 1
    1, 3, 12 1
    1, 3, 2, 13-1
    2, 3, 1, 23-1
    2, 3, 22 1
    \n", + "
  2. \n", + "
\n", + "
\n", + "\t
$loop_rep_index
\n", + "\t\t
1
\n", + "\t
$jac_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 3 × 3 of type dbl
    -1-1 1
    -1-1 1
    1 1-1
    \n", + "
  2. \n", + "
\n", + "
\n", + "\t
$jac_rep_index
\n", + "\t\t
1
\n", + "
\n" + ], + "text/latex": [ + "\\begin{description}\n", + "\\item[\\$loop\\_rep] \\begin{enumerate}\n", + "\\item A data.frame: 8 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\t 1, 3, 1 & 2 & 1\\\\\n", + "\t 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t 2, 3, 2 & 2 & 1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$loop\\_rep\\_index] 1\n", + "\\item[\\$jac\\_rep] \\begin{enumerate}\n", + "\\item A matrix: 3 × 3 of type dbl\n", + "\\begin{tabular}{lll}\n", + "\t -1 & -1 & 1\\\\\n", + "\t -1 & -1 & 1\\\\\n", + "\t 1 & 1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$jac\\_rep\\_index] 1\n", + "\\end{description}\n" + ], + "text/markdown": [ + "$loop_rep\n", + ": 1. \n", + "A data.frame: 8 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "| 1, 3, 1 | 2 | 1 |\n", + "| 1, 3, 2, 1 | 3 | -1 |\n", + "| 2, 3, 1, 2 | 3 | -1 |\n", + "| 2, 3, 2 | 2 | 1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$loop_rep_index\n", + ": 1\n", + "$jac_rep\n", + ": 1. \n", + "A matrix: 3 × 3 of type dbl\n", + "\n", + "| -1 | -1 | 1 |\n", + "| -1 | -1 | 1 |\n", + "| 1 | 1 | -1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$jac_rep_index\n", + ": 1\n", + "\n", + "\n" + ], + "text/plain": [ + "$loop_rep\n", + "$loop_rep[[1]]\n", + " loop length sign\n", + "1 1, 1 1 -1\n", + "2 2, 2 1 -1\n", + "3 3, 3 1 -1\n", + "4 1, 2, 1 2 1\n", + "5 1, 3, 1 2 1\n", + "6 1, 3, 2, 1 3 -1\n", + "7 2, 3, 1, 2 3 -1\n", + "8 2, 3, 2 2 1\n", + "\n", + "\n", + "$loop_rep_index\n", + "[1] 1\n", + "\n", + "$jac_rep\n", + "$jac_rep[[1]]\n", + " [,1] [,2] [,3]\n", + "[1,] -1 -1 1\n", + "[2,] -1 -1 1\n", + "[3,] 1 1 -1\n", + "\n", + "\n", + "$jac_rep_index\n", + "[1] 1\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f43813a7", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 3 × 3 of type dbl
-1-1 1
-1-1 1
1 1-1
\n" + ], + "text/latex": [ + "A matrix: 3 × 3 of type dbl\n", + "\\begin{tabular}{lll}\n", + "\t -1 & -1 & 1\\\\\n", + "\t -1 & -1 & 1\\\\\n", + "\t 1 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 3 × 3 of type dbl\n", + "\n", + "| -1 | -1 | 1 |\n", + "| -1 | -1 | 1 |\n", + "| 1 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3]\n", + "[1,] -1 -1 1 \n", + "[2,] -1 -1 1 \n", + "[3,] 1 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "f9454da1", + "metadata": {}, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003]." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "dbd42fd2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
1
6.62356545421023
2
1.62356545421025
3
5.37643454578977
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[1] 6.62356545421023\n", + "\\item[2] 1.62356545421025\n", + "\\item[3] 5.37643454578977\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "1\n", + ": 6.623565454210232\n", + ": 1.623565454210253\n", + ": 5.37643454578977\n", + "\n" + ], + "text/plain": [ + " 1 2 3 \n", + "6.623565 1.623565 5.376435 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_list <- function(t,x,params){list(func_varusai15_simple(t,x,params))}\n", + "sol <- deSolve::ode(y = s_star, times = seq(0,1,0.001), func = func_list, \n", + " parms=params)\n", + "\n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star_end" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "2f3d21ac", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 3 × 3 of type dbl
-5-10 2
-5-10 2
5 10-2
\n" + ], + "text/latex": [ + "A matrix: 3 × 3 of type dbl\n", + "\\begin{tabular}{lll}\n", + "\t -5 & -10 & 2\\\\\n", + "\t -5 & -10 & 2\\\\\n", + "\t 5 & 10 & -2\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 3 × 3 of type dbl\n", + "\n", + "| -5 | -10 | 2 |\n", + "| -5 | -10 | 2 |\n", + "| 5 | 10 | -2 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3]\n", + "[1,] -5 -10 2 \n", + "[2,] -5 -10 2 \n", + "[3,] 5 10 -2 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(func_varusai15_simple,s_star,method=\"complex\",\n", + " t=1,params=params)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "67868589", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 3 × 3 of type dbl
-1-1 1
-1-1 1
1 1-1
\n" + ], + "text/latex": [ + "A matrix: 3 × 3 of type dbl\n", + "\\begin{tabular}{lll}\n", + "\t -1 & -1 & 1\\\\\n", + "\t -1 & -1 & 1\\\\\n", + "\t 1 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 3 × 3 of type dbl\n", + "\n", + "| -1 | -1 | 1 |\n", + "| -1 | -1 | 1 |\n", + "| 1 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3]\n", + "[1,] -1 -1 1 \n", + "[2,] -1 -1 1 \n", + "[3,] 1 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "fb34cf9c", + "metadata": {}, + "source": [ + "### **2.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "e8883776", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 420, + "width": 420 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:4],\n", + " type = \"l\",\n", + " lty = 1,\n", + " xlab = \"Time\",\n", + " ylab = \"Concentration\",\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = c(\"A\", \"B\", \"AB\"),\n", + " col = 1:3,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "3beedbcf", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol)\n", + "\n", + "# rename columns for clarity\n", + "colnames(sol_for_plot) <- c(\"time\", \"A\", \"B\", \"AB\")\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = A:AB, names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "26027184", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "colors <- c(\n", + " A = \"#EE7733\",\n", + " B = \"#0077BB\",\n", + " AB = \"#33BBEE\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(size = 3) +\n", + " ## vertical dashed line\n", + " geom_vline(\n", + " xintercept = perturbation_point,\n", + " linetype = \"dashed\",\n", + " colour = \"black\",\n", + " linewidth = 0.7\n", + " ) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 1, 0.2),\n", + " minor_breaks = seq(0, 1, 0.1),\n", + " limits = c(0, 1),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 1), clip = \"on\") +\n", + " scale_y_continuous(\n", + " minor_breaks = seq(0, 11, 2),\n", + " ) +\n", + " labs(\n", + " title = \"Dynamics of the 3-Variable Complex Formation Model\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "markdown", + "id": "d005f29c", + "metadata": {}, + "source": [ + "### **2.4. Pertubation Analysis**" + ] + }, + { + "cell_type": "markdown", + "id": "688d7e9a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **2.4.1. Partubation in A**" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "1c922b3c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
  1. 1001
  2. 4
\n" + ], + "text/latex": [ + "\\begin{enumerate*}\n", + "\\item 1001\n", + "\\item 4\n", + "\\end{enumerate*}\n" + ], + "text/markdown": [ + "1. 1001\n", + "2. 4\n", + "\n", + "\n" + ], + "text/plain": [ + "[1] 1001 4" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "33904 bytes" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Size of variable sol (how many rows and columns)\n", + "dim(sol)\n", + "object.size(sol)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "6539db9a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "t0 <- 0.2 # perturbation time in original time axis\n", + "idx0 <- 200\n", + "cap <- 0.05 # window half-width (before/after), like Python cap_range\n", + "dt <- 0.001" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "55b33b49", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# pre-perturbation window from the already-simulated sol\n", + "k <- round(cap / dt)\n", + "pre <- sol[(idx0 - k):idx0, 2:4, drop = FALSE]\n", + "tpre <- seq(-cap, 0, by = dt)\n", + "\n", + "# perturbed IC and forward simulation on local time [0, cap]\n", + "y0 <- as.numeric(sol[idx0, 2:4])\n", + "y0[1] <- 40.0" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "1ced98df", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "150" + ], + "text/latex": [ + "150" + ], + "text/markdown": [ + "150" + ], + "text/plain": [ + "[1] 150" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "200-cap/dt" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "55b3ff5e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "s_star_pertubation_1 <- as.numeric(sol[(200-cap/dt),2:4])\n", + "tpre = seq(-cap, 0, by = dt)\n", + "sol_pertubation_1_pre <- deSolve::ode(y = s_star_pertubation_1, times = tpre, func = func_list, \n", + " parms=params)\n", + "\n", + "s_star_pertubation_1 <- as.numeric(sol[200,2:4])\n", + "# Change the 1st position to 40.0\n", + "s_star_pertubation_1[1] <- 40.0\n", + "\n", + "tpost <- seq(0, cap, by = dt)\n", + "sol_pertubation_1_post <- deSolve::ode(y = s_star_pertubation_1, times = tpost, func = func_list, \n", + " parms=params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "382eba5f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "agg_record_1372292667: 2" + ], + "text/latex": [ + "\\textbf{agg\\textbackslash{}\\_record\\textbackslash{}\\_1372292667:} 2" + ], + "text/markdown": [ + "**agg_record_1372292667:** 2" + ], + "text/plain": [ + "agg_record_1372292667 \n", + " 2 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "t_all <- c(tpre, tpost)\n", + "y_all <- rbind(sol_pertubation_1_pre, sol_pertubation_1_post) # avoid duplicating t=0 row\n", + "labels <- c(\"A\", \"B\", \"AB\")\n", + "\n", + "# Plot: 4 stacked panels (base graphics)\n", + "\n", + "# To save as PNG file, uncomment the following lines, and the dev.off() line at the end\n", + "\n", + "# png(\n", + "# filename = \"model_2_perturbation_A.png\",\n", + "# width = 8, height = 6, units = \"in\",\n", + "# res = 300 # DPI\n", + "# )\n", + "\n", + "op <- par(mfrow = c(3,1), mar = c(4,5,3,1))\n", + "for (j in 2:4) {\n", + " plot(t_all, y_all[,j], type = \"l\", lwd = 4, col = colors[j-1],\n", + " xlab = \"Time\", ylab = paste(\"Concentration of\", labels[j-1], sep=\"\"),\n", + " xlim = c(-0.05, 0.05), xaxt = \"n\", xaxs = \"i\",\n", + " main = paste(\"Perturbation Analysis: \", labels[j-1], \" when A is perturbed\", sep=\"\"))\n", + " axis(\n", + " 1,\n", + " at = seq(-0.05, 0.05, by = 0.01)\n", + " )\n", + " abline(v = 0, lty = 2, lwd = 2)\n", + " box(lwd = 2) # black outer box\n", + "}\n", + "\n", + "# dev.off()\n", + "par(op)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "dd297c4b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "s_star_pertubation_1 <- as.numeric(sol[(200-cap/dt),2:4])\n", + "tpre = seq(-cap, 0, by = dt)\n", + "sol_pertubation_1_pre <- deSolve::ode(y = s_star_pertubation_1, times = tpre, func = func_list, \n", + " parms=params)\n", + "\n", + "s_star_pertubation_1 <- as.numeric(sol[200,2:4])\n", + "# Change the 2nd position to 10.0\n", + "s_star_pertubation_1[2] <- 10.0\n", + "\n", + "tpost <- seq(0, cap, by = dt)\n", + "sol_pertubation_1_post <- deSolve::ode(y = s_star_pertubation_1, times = tpost, func = func_list, \n", + " parms=params)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "b4a463ad", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "Plot with title \"Perturbation Analysis: AB when A is perturbed\"" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "t_all <- c(tpre, tpost)\n", + "y_all <- rbind(sol_pertubation_1_pre, sol_pertubation_1_post) # avoid duplicating t=0 row\n", + "labels <- c(\"A\", \"B\", \"AB\")\n", + "\n", + "# Plot: 4 stacked panels (base graphics)\n", + "\n", + "# To save as PNG file, uncomment the following lines, and the dev.off() line at the end\n", + "\n", + "# png(\n", + "# filename = \"model_2_perturbation_B.png\",\n", + "# width = 8, height = 6, units = \"in\",\n", + "# res = 300 # DPI\n", + "# )\n", + "\n", + "op <- par(mfrow = c(3,1), mar = c(4,5,3,1))\n", + "for (j in 2:4) {\n", + " plot(t_all, y_all[,j], type = \"l\", lwd = 4, col = colors[j-1],\n", + " xlab = \"Time\", ylab = paste(\"Concentration of\", labels[j-1], sep=\"\"),\n", + " xlim = c(-0.05, 0.05), xaxt = \"n\", xaxs = \"i\",\n", + " main = paste(\"Perturbation Analysis: \", labels[j-1], \" when A is perturbed\", sep=\"\"))\n", + " axis(\n", + " 1,\n", + " at = seq(-0.05, 0.05, by = 0.01)\n", + " )\n", + " abline(v = 0, lty = 2, lwd = 2)\n", + " box(lwd = 2) # black outer box\n", + "}\n", + "\n", + "# dev.off()\n", + "par(op)" + ] + }, + { + "cell_type": "markdown", + "id": "ea05a483", + "metadata": {}, + "source": [ + "## **3. Additional features**" + ] + }, + { + "cell_type": "markdown", + "id": "14073aff", + "metadata": {}, + "source": [ + "### **3.1. Add subject ID to make the loop result more comprehensible**" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "5d29bc2a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "id_to_subject <- c(\n", + " \"A\", \"B\", \"AB\"\n", + ")\n", + "names(id_to_subject) <- 1:3" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "796b8fb4", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "df <- res_tab$loop_rep[[1]]" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "cab114e7", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "df$loop_subject <- lapply(\n", + " df$loop,\n", + " function(t) unname(id_to_subject[as.character(t)])\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "fe72c366", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 8 × 4
looplengthsignloop_subject
<I<list>><dbl><dbl><list>
1, 11-1A, A
2, 21-1B, B
3, 31-1AB, AB
1, 2, 12 1A, B, A
1, 3, 12 1A , AB, A
1, 3, 2, 13-1A , AB, B , A
2, 3, 1, 23-1B , AB, A , B
2, 3, 22 1B , AB, B
\n" + ], + "text/latex": [ + "A data.frame: 8 × 4\n", + "\\begin{tabular}{llll}\n", + " loop & length & sign & loop\\_subject\\\\\n", + " > & & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1 & A, A\\\\\n", + "\t 2, 2 & 1 & -1 & B, B\\\\\n", + "\t 3, 3 & 1 & -1 & AB, AB\\\\\n", + "\t 1, 2, 1 & 2 & 1 & A, B, A\\\\\n", + "\t 1, 3, 1 & 2 & 1 & A , AB, A \\\\\n", + "\t 1, 3, 2, 1 & 3 & -1 & A , AB, B , A \\\\\n", + "\t 2, 3, 1, 2 & 3 & -1 & B , AB, A , B \\\\\n", + "\t 2, 3, 2 & 2 & 1 & B , AB, B \\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 8 × 4\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> | loop_subject <list> |\n", + "|---|---|---|---|\n", + "| 1, 1 | 1 | -1 | A, A |\n", + "| 2, 2 | 1 | -1 | B, B |\n", + "| 3, 3 | 1 | -1 | AB, AB |\n", + "| 1, 2, 1 | 2 | 1 | A, B, A |\n", + "| 1, 3, 1 | 2 | 1 | A , AB, A |\n", + "| 1, 3, 2, 1 | 3 | -1 | A , AB, B , A |\n", + "| 2, 3, 1, 2 | 3 | -1 | B , AB, A , B |\n", + "| 2, 3, 2 | 2 | 1 | B , AB, B |\n", + "\n" + ], + "text/plain": [ + " loop length sign loop_subject \n", + "1 1, 1 1 -1 A, A \n", + "2 2, 2 1 -1 B, B \n", + "3 3, 3 1 -1 AB, AB \n", + "4 1, 2, 1 2 1 A, B, A \n", + "5 1, 3, 1 2 1 A , AB, A \n", + "6 1, 3, 2, 1 3 -1 A , AB, B , A \n", + "7 2, 3, 1, 2 3 -1 B , AB, A , B \n", + "8 2, 3, 2 2 1 B , AB, B " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "markdown", + "id": "a2beb7e7", + "metadata": {}, + "source": [ + "### **3.2. Represent regulation relationship from Jacobian matrix**" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "8703ce8b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A tibble: 9 × 4
fromtoregulationregulation_words
<chr><chr><dbl><chr>
A A -1inhibition (negative)
A B -1inhibition (negative)
A AB 1activation (positive)
B A -1inhibition (negative)
B B -1inhibition (negative)
B AB 1activation (positive)
ABA 1activation (positive)
ABB 1activation (positive)
ABAB-1inhibition (negative)
\n" + ], + "text/latex": [ + "A tibble: 9 × 4\n", + "\\begin{tabular}{llll}\n", + " from & to & regulation & regulation\\_words\\\\\n", + " & & & \\\\\n", + "\\hline\n", + "\t A & A & -1 & inhibition (negative)\\\\\n", + "\t A & B & -1 & inhibition (negative)\\\\\n", + "\t A & AB & 1 & activation (positive)\\\\\n", + "\t B & A & -1 & inhibition (negative)\\\\\n", + "\t B & B & -1 & inhibition (negative)\\\\\n", + "\t B & AB & 1 & activation (positive)\\\\\n", + "\t AB & A & 1 & activation (positive)\\\\\n", + "\t AB & B & 1 & activation (positive)\\\\\n", + "\t AB & AB & -1 & inhibition (negative)\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A tibble: 9 × 4\n", + "\n", + "| from <chr> | to <chr> | regulation <dbl> | regulation_words <chr> |\n", + "|---|---|---|---|\n", + "| A | A | -1 | inhibition (negative) |\n", + "| A | B | -1 | inhibition (negative) |\n", + "| A | AB | 1 | activation (positive) |\n", + "| B | A | -1 | inhibition (negative) |\n", + "| B | B | -1 | inhibition (negative) |\n", + "| B | AB | 1 | activation (positive) |\n", + "| AB | A | 1 | activation (positive) |\n", + "| AB | B | 1 | activation (positive) |\n", + "| AB | AB | -1 | inhibition (negative) |\n", + "\n" + ], + "text/plain": [ + " from to regulation regulation_words \n", + "1 A A -1 inhibition (negative)\n", + "2 A B -1 inhibition (negative)\n", + "3 A AB 1 activation (positive)\n", + "4 B A -1 inhibition (negative)\n", + "5 B B -1 inhibition (negative)\n", + "6 B AB 1 activation (positive)\n", + "7 AB A 1 activation (positive)\n", + "8 AB B 1 activation (positive)\n", + "9 AB AB -1 inhibition (negative)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sign_J <- sign(j_matrix)\n", + "labs <- paste0(c(\"A\", \"B\", \"AB\"))\n", + "rownames(sign_J) <- labs\n", + "colnames(sign_J) <- labs\n", + "\n", + "regulation_info <- sign_J %>%\n", + " as.data.frame() %>%\n", + " mutate(from = rownames(.)) %>%\n", + " pivot_longer(\n", + " -from,\n", + " names_to = \"to\",\n", + " values_to = \"regulation\"\n", + " ) %>%\n", + " mutate(\n", + " regulation_words = case_when(\n", + " regulation == -1 ~ \"inhibition (negative)\",\n", + " regulation == 1 ~ \"activation (positive)\",\n", + " TRUE ~ \"no regulation\"\n", + " )\n", + " )\n", + "regulation_info[regulation_info$regulation != 0, ]" + ] + }, + { + "cell_type": "markdown", + "id": "fbe99d74", + "metadata": {}, + "source": [ + "### **3.3. Loop Summary in more detail**" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "d57b2e96", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 8 × 4
looplengthsignloop_subject
<I<list>><dbl><dbl><list>
1, 11-1A, A
2, 21-1B, B
3, 31-1AB, AB
1, 2, 12 1A, B, A
1, 3, 12 1A , AB, A
1, 3, 2, 13-1A , AB, B , A
2, 3, 1, 23-1B , AB, A , B
2, 3, 22 1B , AB, B
\n" + ], + "text/latex": [ + "A data.frame: 8 × 4\n", + "\\begin{tabular}{llll}\n", + " loop & length & sign & loop\\_subject\\\\\n", + " > & & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1 & A, A\\\\\n", + "\t 2, 2 & 1 & -1 & B, B\\\\\n", + "\t 3, 3 & 1 & -1 & AB, AB\\\\\n", + "\t 1, 2, 1 & 2 & 1 & A, B, A\\\\\n", + "\t 1, 3, 1 & 2 & 1 & A , AB, A \\\\\n", + "\t 1, 3, 2, 1 & 3 & -1 & A , AB, B , A \\\\\n", + "\t 2, 3, 1, 2 & 3 & -1 & B , AB, A , B \\\\\n", + "\t 2, 3, 2 & 2 & 1 & B , AB, B \\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 8 × 4\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> | loop_subject <list> |\n", + "|---|---|---|---|\n", + "| 1, 1 | 1 | -1 | A, A |\n", + "| 2, 2 | 1 | -1 | B, B |\n", + "| 3, 3 | 1 | -1 | AB, AB |\n", + "| 1, 2, 1 | 2 | 1 | A, B, A |\n", + "| 1, 3, 1 | 2 | 1 | A , AB, A |\n", + "| 1, 3, 2, 1 | 3 | -1 | A , AB, B , A |\n", + "| 2, 3, 1, 2 | 3 | -1 | B , AB, A , B |\n", + "| 2, 3, 2 | 2 | 1 | B , AB, B |\n", + "\n" + ], + "text/plain": [ + " loop length sign loop_subject \n", + "1 1, 1 1 -1 A, A \n", + "2 2, 2 1 -1 B, B \n", + "3 3, 3 1 -1 AB, AB \n", + "4 1, 2, 1 2 1 A, B, A \n", + "5 1, 3, 1 2 1 A , AB, A \n", + "6 1, 3, 2, 1 3 -1 A , AB, B , A \n", + "7 2, 3, 1, 2 3 -1 B , AB, A , B \n", + "8 2, 3, 2 2 1 B , AB, B " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "ec36d7d7", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 7
lengthnum_loopsnum_loops_positivenum_loops_negativeloopsloops_positiveloops_negative
<dbl><int><int><int><I<named list>><I<named list>><I<named list>>
11303c(\"A\", \".... c(\"A\", \"....
22330c(\"A\", \"....c(\"A\", \"....
33202c(\"A\", \".... c(\"A\", \"....
\n" + ], + "text/latex": [ + "A data.frame: 3 × 7\n", + "\\begin{tabular}{r|lllllll}\n", + " & length & num\\_loops & num\\_loops\\_positive & num\\_loops\\_negative & loops & loops\\_positive & loops\\_negative\\\\\n", + " & & & & & > & > & >\\\\\n", + "\\hline\n", + "\t1 & 1 & 3 & 0 & 3 & c(\"A\", \".... & & c(\"A\", \"....\\\\\n", + "\t2 & 2 & 3 & 3 & 0 & c(\"A\", \".... & c(\"A\", \".... & \\\\\n", + "\t3 & 3 & 2 & 0 & 2 & c(\"A\", \".... & & c(\"A\", \"....\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 7\n", + "\n", + "| | length <dbl> | num_loops <int> | num_loops_positive <int> | num_loops_negative <int> | loops <I<named list>> | loops_positive <I<named list>> | loops_negative <I<named list>> |\n", + "|---|---|---|---|---|---|---|---|\n", + "| 1 | 1 | 3 | 0 | 3 | c(\"A\", \".... | | c(\"A\", \".... |\n", + "| 2 | 2 | 3 | 3 | 0 | c(\"A\", \".... | c(\"A\", \".... | |\n", + "| 3 | 3 | 2 | 0 | 2 | c(\"A\", \".... | | c(\"A\", \".... |\n", + "\n" + ], + "text/plain": [ + " length num_loops num_loops_positive num_loops_negative loops \n", + "1 1 3 0 3 c(\"A\", \"....\n", + "2 2 3 3 0 c(\"A\", \"....\n", + "3 3 2 0 2 c(\"A\", \"....\n", + " loops_positive loops_negative\n", + "1 c(\"A\", \".... \n", + "2 c(\"A\", \".... \n", + "3 c(\"A\", \".... " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "split_by_len <- split(df, df$length)\n", + "\n", + "loop_summary_extended <- data.frame(\n", + " length = as.numeric(names(split_by_len)),\n", + " num_loops = vapply(split_by_len, nrow, integer(1)),\n", + " loops = I(lapply(split_by_len, function(x) x$loop_subject)),\n", + " stringsAsFactors = FALSE\n", + ")\n", + "\n", + "loop_summary_extended$num_loops_positive <- vapply(\n", + " split_by_len,\n", + " function(x) sum(x$sign > 0),\n", + " integer(1)\n", + ")\n", + "\n", + "loop_summary_extended$num_loops_negative <- vapply(\n", + " split_by_len,\n", + " function(x) sum(x$sign < 0),\n", + " integer(1)\n", + ")\n", + "\n", + "loop_summary_extended$loops_positive <- I(lapply(\n", + " split_by_len,\n", + " function(x) x$loop_subject[x$sign > 0]\n", + "))\n", + "\n", + "loop_summary_extended$loops_negative <- I(lapply(\n", + " split_by_len,\n", + " function(x) x$loop_subject[x$sign < 0]\n", + "))\n", + "\n", + "loop_summary_extended <- loop_summary_extended[\n", + " order(loop_summary_extended$length),\n", + " c(\"length\",\"num_loops\",\"num_loops_positive\",\"num_loops_negative\",\n", + " \"loops\",\"loops_positive\",\"loops_negative\")\n", + "]\n", + "\n", + "loop_summary_extended\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/model_2_perturbation_A.png b/examples/model_2_perturbation_A.png new file mode 100644 index 0000000..7923386 Binary files /dev/null and b/examples/model_2_perturbation_A.png differ diff --git a/examples/model_3_complex_formation_extend_R.ipynb b/examples/model_3_complex_formation_extend_R.ipynb new file mode 100644 index 0000000..00b7299 --- /dev/null +++ b/examples/model_3_complex_formation_extend_R.ipynb @@ -0,0 +1,1667 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5c5107a0", + "metadata": {}, + "source": [ + "## **0. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "0aa853b2", + "metadata": {}, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad430870", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2d7c70f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c741284", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1d32152b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")\n", + "library(deSolve)\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3eb6dbbb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "colors <- c('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB')" + ] + }, + { + "cell_type": "markdown", + "id": "de63ff1e", + "metadata": {}, + "source": [ + "## **1. Model definition**" + ] + }, + { + "cell_type": "markdown", + "id": "39347b82", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **Example 3: Model of complex formation with activation-deactivation cycle**\n", + "\n", + "The model of complex formation with activation-deactivation cycle has also been investigated in [4]. It is composed of the basic model of complex formation in that A\n", + "and B bind to form complex AB as described in section 1.2, together with an activation and deactivation of one of the complex-forming species, B and B∗. In addition\n", + "to the two reactions of complex formation and complex decomposition, the activating\n", + "reaction and the deactivation reaction are modelled using Michaelis-Menten reaction\n", + "kinetics. Thereby, the activation of B to B∗\n", + "is in addition stimulus-dependent (the\n", + "stimulus is modelled as a parameter, kn3), while the deactivation of B∗\n", + "to B depends\n", + "linearly on species A. The model contains four species, A, B, AB, B∗\n", + ", four rate coefficients, k1 . . . , k4, two activation constants, kn1, kn2, and a stimulus parameter, kn3." + ] + }, + { + "cell_type": "markdown", + "id": "480bf021", + "metadata": {}, + "source": [ + "$$\n", + "\\begin{aligned}\n", + "\\frac{dA}{dt} &= -k_1\\,A\\,B + k_2\\,AB ,\\\\[6pt]\n", + "\\frac{dB}{dt} &= -k_1\\,A\\,B + k_2\\,AB + k_3\\,A\\,\\frac{B^*}{B^* + kn_1} - k_4\\,kn_3\\,\\frac{B}{B + kn_2} ,\\\\[6pt]\n", + "\\frac{d(AB)}{dt} &= k_1\\,A\\,B - k_2\\,AB ,\\\\[6pt]\n", + "\\frac{dB^*}{dt} &= -k_3\\,A\\,\\frac{B^*}{B^* + kn_1} + k_4\\,kn_3\\,\\frac{B}{B + kn_2} .\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "We employed the following parameter set for the analyses: k1 = 0.021458, k2 =\n", + "0.000227335, k3 = 663.297, k4 = 0.000139797, kn1 = 55.5913, kn2 = 10.2194, and\n", + "values for the stimulus of kn3 = 1 (unstimulated) or kn3 = 20 (stimulated). The initial\n", + "conditions were set as A = 5, B = 300, AB = 0.0001, B∗ = 0.01.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "dc85fe5e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "func_varusai15 <- function(t, y, params) {\n", + " A <- y[1]\n", + " B <- y[2]\n", + " AB <- y[3]\n", + " B_star <- y[4]\n", + "\n", + " k1 <- params[1]\n", + " k2 <- params[2]\n", + " k3 <- params[3]\n", + " k4 <- params[4]\n", + " kn1 <- params[5]\n", + " kn2 <- params[6]\n", + " kn3 <- params[7]\n", + "\n", + " dx <- rep(0,4)\n", + "\n", + " dAdt <- -k1 * A * B + k2 * AB\n", + " dBdt <- -k1 * A * B + k2 * AB + k3 * A * (B_star / (B_star + kn1)) - k4 * kn3 * (B / (B + kn2))\n", + " dABdt <- k1 * A * B - k2 * AB\n", + " dB_stardt <- -k3 * A * (B_star / (B_star + kn1)) + k4 * kn3 * (B / (B + kn2))\n", + "\n", + " # list(c(dAdt, dBdt, dABdt, dB_stardt))\n", + " dx[1] <- dAdt\n", + " dx[2] <- dBdt\n", + " dx[3] <- dABdt\n", + " dx[4] <- dB_stardt\n", + " return(dx)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "44e7e155", + "metadata": {}, + "source": [ + "## **2. Result reproduction**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4e5b9062", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Parameters from supplementary material\n", + "initial_conditions_act_deact <- c(5, 300, 0.0001, 0.01)\n", + "\n", + "k1 <- 0.021458\n", + "k2 <- 0.000227335\n", + "k3 <- 663.297\n", + "k4 <- 0.000139797\n", + "kn1 <- 55.5913\n", + "kn2 <- 10.2194\n", + "kn3_unstimulated <- 1.0\n", + "kn3_stimulated <- 20.0\n", + "\n", + "params_act_deact_unstimulated <- c(k1, k2, k3, k4, kn1, kn2, kn3_unstimulated)\n", + "params_act_deact_stimulated <- c(k1, k2, k3, k4, kn1, kn2, kn3_stimulated)" + ] + }, + { + "cell_type": "markdown", + "id": "b927c538", + "metadata": {}, + "source": [ + "### **2.1. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "b9c9522a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **2.1.1. Loop structure**" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6c2540e5", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 10 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
4, 41-1
1, 2, 12 1
1, 3, 12 1
1, 3, 2, 13-1
2, 3, 1, 23-1
2, 3, 22 1
1, 4, 2, 13 1
\n" + ], + "text/latex": [ + "A data.frame: 10 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\t 1, 3, 1 & 2 & 1\\\\\n", + "\t 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t 2, 3, 2 & 2 & 1\\\\\n", + "\t 1, 4, 2, 1 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 10 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "| 1, 3, 1 | 2 | 1 |\n", + "| 1, 3, 2, 1 | 3 | -1 |\n", + "| 2, 3, 1, 2 | 3 | -1 |\n", + "| 2, 3, 2 | 2 | 1 |\n", + "| 1, 4, 2, 1 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 4, 4 1 -1 \n", + "5 1, 2, 1 2 1 \n", + "6 1, 3, 1 2 1 \n", + "7 1, 3, 2, 1 3 -1 \n", + "8 2, 3, 1, 2 3 -1 \n", + "9 2, 3, 2 2 1 \n", + "10 1, 4, 2, 1 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(func_varusai15,vset=list(initial_conditions_act_deact),t=1,params=params_act_deact_unstimulated,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3d056cc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 3
len_1len_2len_3
<dbl><dbl><dbl>
all433
pos031
neg402
\n" + ], + "text/latex": [ + "A data.frame: 3 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & len\\_1 & len\\_2 & len\\_3\\\\\n", + " & & & \\\\\n", + "\\hline\n", + "\tall & 4 & 3 & 3\\\\\n", + "\tpos & 0 & 3 & 1\\\\\n", + "\tneg & 4 & 0 & 2\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 3\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> |\n", + "|---|---|---|---|\n", + "| all | 4 | 3 | 3 |\n", + "| pos | 0 | 3 | 1 |\n", + "| neg | 4 | 0 | 2 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3\n", + "all 4 3 3 \n", + "pos 0 3 1 \n", + "neg 4 0 2 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "e9a5ecf2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
5 1, 2, 12 1
71, 3, 2, 13-1
82, 3, 1, 23-1
9 2, 3, 22 1
101, 4, 2, 13 1
\n" + ], + "text/latex": [ + "A data.frame: 6 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t5 & 1, 2, 1 & 2 & 1\\\\\n", + "\t7 & 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t8 & 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t9 & 2, 3, 2 & 2 & 1\\\\\n", + "\t10 & 1, 4, 2, 1 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 5 | 1, 2, 1 | 2 | 1 |\n", + "| 7 | 1, 3, 2, 1 | 3 | -1 |\n", + "| 8 | 2, 3, 1, 2 | 3 | -1 |\n", + "| 9 | 2, 3, 2 | 2 | 1 |\n", + "| 10 | 1, 4, 2, 1 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "5 1, 2, 1 2 1 \n", + "7 1, 3, 2, 1 3 -1 \n", + "8 2, 3, 1, 2 3 -1 \n", + "9 2, 3, 2 2 1 \n", + "10 1, 4, 2, 1 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2 \n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "9f0fc026", + "metadata": {}, + "source": [ + "#### **2.1.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "eefb6816", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\t
$loop_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A data.frame: 10 × 3
    looplengthsign
    <I<list>><dbl><dbl>
    1, 11-1
    2, 21-1
    3, 31-1
    4, 41-1
    1, 2, 12 1
    1, 3, 12 1
    1, 3, 2, 13-1
    2, 3, 1, 23-1
    2, 3, 22 1
    1, 4, 2, 13 1
    \n", + "
  2. \n", + "
\n", + "
\n", + "\t
$loop_rep_index
\n", + "\t\t
1
\n", + "\t
$jac_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 4 × 4 of type dbl
    -1-1 1 0
    -1-1 1 1
    1 1-1 0
    -1 1 0-1
    \n", + "
  2. \n", + "
\n", + "
\n", + "\t
$jac_rep_index
\n", + "\t\t
1
\n", + "
\n" + ], + "text/latex": [ + "\\begin{description}\n", + "\\item[\\$loop\\_rep] \\begin{enumerate}\n", + "\\item A data.frame: 10 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\t 1, 3, 1 & 2 & 1\\\\\n", + "\t 1, 3, 2, 1 & 3 & -1\\\\\n", + "\t 2, 3, 1, 2 & 3 & -1\\\\\n", + "\t 2, 3, 2 & 2 & 1\\\\\n", + "\t 1, 4, 2, 1 & 3 & 1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$loop\\_rep\\_index] 1\n", + "\\item[\\$jac\\_rep] \\begin{enumerate}\n", + "\\item A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & -1 & 1 & 0\\\\\n", + "\t -1 & -1 & 1 & 1\\\\\n", + "\t 1 & 1 & -1 & 0\\\\\n", + "\t -1 & 1 & 0 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$jac\\_rep\\_index] 1\n", + "\\end{description}\n" + ], + "text/markdown": [ + "$loop_rep\n", + ": 1. \n", + "A data.frame: 10 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "| 1, 3, 1 | 2 | 1 |\n", + "| 1, 3, 2, 1 | 3 | -1 |\n", + "| 2, 3, 1, 2 | 3 | -1 |\n", + "| 2, 3, 2 | 2 | 1 |\n", + "| 1, 4, 2, 1 | 3 | 1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$loop_rep_index\n", + ": 1\n", + "$jac_rep\n", + ": 1. \n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | -1 | 1 | 0 |\n", + "| -1 | -1 | 1 | 1 |\n", + "| 1 | 1 | -1 | 0 |\n", + "| -1 | 1 | 0 | -1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$jac_rep_index\n", + ": 1\n", + "\n", + "\n" + ], + "text/plain": [ + "$loop_rep\n", + "$loop_rep[[1]]\n", + " loop length sign\n", + "1 1, 1 1 -1\n", + "2 2, 2 1 -1\n", + "3 3, 3 1 -1\n", + "4 4, 4 1 -1\n", + "5 1, 2, 1 2 1\n", + "6 1, 3, 1 2 1\n", + "7 1, 3, 2, 1 3 -1\n", + "8 2, 3, 1, 2 3 -1\n", + "9 2, 3, 2 2 1\n", + "10 1, 4, 2, 1 3 1\n", + "\n", + "\n", + "$loop_rep_index\n", + "[1] 1\n", + "\n", + "$jac_rep\n", + "$jac_rep[[1]]\n", + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 -1 1 0\n", + "[2,] -1 -1 1 1\n", + "[3,] 1 1 -1 0\n", + "[4,] -1 1 0 -1\n", + "\n", + "\n", + "$jac_rep_index\n", + "[1] 1\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "05e68bc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1-1 1 0
-1-1 1 1
1 1-1 0
-1 1 0-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & -1 & 1 & 0\\\\\n", + "\t -1 & -1 & 1 & 1\\\\\n", + "\t 1 & 1 & -1 & 0\\\\\n", + "\t -1 & 1 & 0 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | -1 | 1 | 0 |\n", + "| -1 | -1 | 1 | 1 |\n", + "| 1 | 1 | -1 | 0 |\n", + "| -1 | 1 | 0 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 -1 1 0 \n", + "[2,] -1 -1 1 1 \n", + "[3,] 1 1 -1 0 \n", + "[4,] -1 1 0 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "b4802333", + "metadata": {}, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003]." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "adbc93e2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
1
0.000179595763481961
2
294.947056130261
3
4.99992040423706
4
0.0631234655454742
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[1] 0.000179595763481961\n", + "\\item[2] 294.947056130261\n", + "\\item[3] 4.99992040423706\n", + "\\item[4] 0.0631234655454742\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "1\n", + ": 0.0001795957634819612\n", + ": 294.9470561302613\n", + ": 4.999920404237064\n", + ": 0.0631234655454742\n", + "\n" + ], + "text/plain": [ + " 1 2 3 4 \n", + "1.795958e-04 2.949471e+02 4.999920e+00 6.312347e-02 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_list <- function(t,x,params){list(func_varusai15(t,x,params))}\n", + "sol <- deSolve::ode(y = initial_conditions_act_deact, times = seq(0,5000,0.1), func = func_list, \n", + " parms=params_act_deact_unstimulated)\n", + "\n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star_end" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "1d134ecb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-6.4374000-1.072900e-01 0.000227335 0.00000
-6.3181048-1.072903e-01 0.000227335 59.63689
6.4374000 1.072900e-01-0.000227335 0.00000
-0.1192952 2.969035e-07 0.000000000-59.63689
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -6.4374000 & -1.072900e-01 & 0.000227335 & 0.00000\\\\\n", + "\t -6.3181048 & -1.072903e-01 & 0.000227335 & 59.63689\\\\\n", + "\t 6.4374000 & 1.072900e-01 & -0.000227335 & 0.00000\\\\\n", + "\t -0.1192952 & 2.969035e-07 & 0.000000000 & -59.63689\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -6.4374000 | -1.072900e-01 | 0.000227335 | 0.00000 |\n", + "| -6.3181048 | -1.072903e-01 | 0.000227335 | 59.63689 |\n", + "| 6.4374000 | 1.072900e-01 | -0.000227335 | 0.00000 |\n", + "| -0.1192952 | 2.969035e-07 | 0.000000000 | -59.63689 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] \n", + "[1,] -6.4374000 -1.072900e-01 0.000227335 0.00000\n", + "[2,] -6.3181048 -1.072903e-01 0.000227335 59.63689\n", + "[3,] 6.4374000 1.072900e-01 -0.000227335 0.00000\n", + "[4,] -0.1192952 2.969035e-07 0.000000000 -59.63689" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(func_varusai15, initial_conditions_act_deact,method=\"complex\",\n", + " t=1,params=params_act_deact_stimulated)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "d9a4b8c8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1-1 1 0
-1-1 1 1
1 1-1 0
-1 1 0-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & -1 & 1 & 0\\\\\n", + "\t -1 & -1 & 1 & 1\\\\\n", + "\t 1 & 1 & -1 & 0\\\\\n", + "\t -1 & 1 & 0 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | -1 | 1 | 0 |\n", + "| -1 | -1 | 1 | 1 |\n", + "| 1 | 1 | -1 | 0 |\n", + "| -1 | 1 | 0 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 -1 1 0 \n", + "[2,] -1 -1 1 1 \n", + "[3,] 1 1 -1 0 \n", + "[4,] -1 1 0 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "9fb5ce0e", + "metadata": {}, + "source": [ + "#### **2.1.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "cf1a9580", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:5],\n", + " type = \"l\",\n", + " lty = 1,\n", + " log = \"y\",\n", + " xlab = \"Time\",\n", + " ylab = \"Concentration\",\n", + "\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = c(\"A\", \"B\", \"AB\", \"B*\"),\n", + " col = 1:4,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "1f18ff68", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol)\n", + "\n", + "# rename columns for clarity\n", + "colnames(sol_for_plot) <- c(\"time\", \"A\", \"B\", \"AB\", \"B*\")\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = A:`B*`, names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "273651c0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "colors <- c(\n", + " A = \"#EE7733\",\n", + " B = \"#0077BB\",\n", + " AB = \"#33BBEE\",\n", + " `B*` = \"#EE3377\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(linewidth = 3) +\n", + " ## vertical dashed line\n", + " # geom_vline(\n", + " # xintercept = perturbation_point,\n", + " # linetype = \"dashed\",\n", + " # colour = \"black\",\n", + " # linewidth = 0.7\n", + " # ) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 5000, 1000),\n", + " minor_breaks = seq(0, 5000, 500),\n", + " limits = c(0, 5000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 5000), clip = \"on\") +\n", + " scale_y_log10(\n", + " breaks = scales::trans_breaks(\"log10\", function(x) 10^x),\n", + " labels = scales::trans_format(\"log10\", scales::math_format(10^.x))\n", + " ) + # log10 transformation\n", + " labs(\n", + " title = \"Dynamics of the 4-Variable Complex Formation Model\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "markdown", + "id": "6f592bea", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **2.2. Stimulated Condition**\n", + "\n", + "When introducing a stimulus at t=0 which increases kn3 from 1 to 20" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "743969e4", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Now, draw temporal dynamics for unstimulated conditions from t=[-1000, 0], and then stimulated conditions from t=[0, 2000]\n", + "time_1 <- seq(-1000, 0, 0.1)\n", + "time_2 <- seq(0, 2000, 0.1)\n", + "sol_unstimulated <- deSolve::ode(y = as.numeric(s_star_end), times = time_1, func = func_list, \n", + " parms=params_act_deact_unstimulated)\n", + "sol_stimulated <- deSolve::ode(y = sol_unstimulated[nrow(sol_unstimulated),2:5], times = time_2, func = function(t,x,params){list(func_varusai15(t,x,params_act_deact_stimulated))}, \n", + " parms=params_act_deact_stimulated)\n", + "\n", + "time_full <- c(time_1, time_2)\n", + "sol_full <- rbind(sol_unstimulated, sol_stimulated) " + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "id": "b0e64f58", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting\n", + "sol_for_plot_2 <- as.data.frame(sol_full)\n", + "# rename columns for clarity\n", + "colnames(sol_for_plot_2) <- c(\"time\", \"A\", \"B\", \"AB\", \"B*\")\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot_2 %>%\n", + " pivot_longer(cols = A:`B*`, names_to = \"species\", values_to = \"value\")\n", + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "colors <- c(\n", + " A = \"#EE7733\",\n", + " B = \"#0077BB\",\n", + " AB = \"#33BBEE\",\n", + " `B*` = \"#EE3377\"\n", + ")\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(linewidth = 3) +\n", + " ## vertical dashed line\n", + " geom_vline(\n", + " xintercept = 0,\n", + " linetype = \"dashed\",\n", + " colour = \"black\",\n", + " linewidth = 0.7\n", + " ) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(-1000, 2000, 500),\n", + " minor_breaks = seq(-1000, 2000, 250),\n", + " limits = c(-1000, 2000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(-1000, 2000), clip = \"on\"\n", + " ) +\n", + " scale_y_log10(\n", + " breaks = scales::trans_breaks(\"log10\", function(x) 10^x),\n", + " labels = scales::trans_format(\"log10\", scales::math_format(10^.x))\n", + " ) + # log10 transformation\n", + " labs(\n", + " title = \"Model 3: Varusai 4 Variables\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + " \n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "d1ea7751", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1] \"Jacobian matrix changed at index 12332 and time 233\"\n", + "[1] \"Unstimulated Jacobian:\"\n", + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 -1 1 0\n", + "[2,] -1 -1 1 1\n", + "[3,] 1 1 -1 0\n", + "[4,] -1 1 0 -1\n", + "[1] \"Stimulated Jacobian:\"\n", + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 -1 1 0\n", + "[2,] 1 -1 1 1\n", + "[3,] 1 1 -1 0\n", + "[4,] -1 1 0 -1\n" + ] + } + ], + "source": [ + "# Search for changes in loops upon stimulation over time_full\n", + "res_tab_0 <- find_loops_vset(func_varusai15,vset=list(initial_conditions_act_deact),t=1,params=params_act_deact_unstimulated,max_num_loops=10)\n", + "j_0 <- res_tab_0$jac_rep[[1]]\n", + "\n", + "for (idx in 1:(nrow(sol_full))) {\n", + " # compute loopsl\n", + " res_tab <- find_loops_vset(func_varusai15,vset=list(sol_full[idx,2:5]),t=idx,params=params_act_deact_stimulated,max_num_loops=10)\n", + " j_1 <- res_tab$jac_rep[[1]]\n", + " if (!identical(j_0, j_1)) {\n", + " print(paste(\"Jacobian matrix changed at index\", idx, \"and time\", time_full[idx], sep=\" \"))\n", + " print(\"Unstimulated Jacobian:\")\n", + " print(j_0)\n", + " print(\"Stimulated Jacobian:\")\n", + " print(j_1)\n", + " break\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "id": "243d080c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1] \"Loop summary unstimulated conditions:\"\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 4
len_1len_2len_3len_4
<dbl><dbl><dbl><dbl>
all4431
pos0410
neg4021
\n" + ], + "text/latex": [ + "A data.frame: 3 × 4\n", + "\\begin{tabular}{r|llll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4\\\\\n", + " & & & & \\\\\n", + "\\hline\n", + "\tall & 4 & 4 & 3 & 1\\\\\n", + "\tpos & 0 & 4 & 1 & 0\\\\\n", + "\tneg & 4 & 0 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 4\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> |\n", + "|---|---|---|---|---|\n", + "| all | 4 | 4 | 3 | 1 |\n", + "| pos | 0 | 4 | 1 | 0 |\n", + "| neg | 4 | 0 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4\n", + "all 4 4 3 1 \n", + "pos 0 4 1 0 \n", + "neg 4 0 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab_0 <- find_loops_vset(func_varusai15,vset=list(initial_conditions_act_deact),t=1,params=params_act_deact_unstimulated)\n", + "print(\"Loop summary unstimulated conditions:\")\n", + "loop_summary(res_tab_0$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "id": "75fdb42d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1] \"Loop summary stimulated conditions:\"\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 4
len_1len_2len_3len_4
<dbl><dbl><dbl><dbl>
all4431
pos0320
neg4111
\n" + ], + "text/latex": [ + "A data.frame: 3 × 4\n", + "\\begin{tabular}{r|llll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4\\\\\n", + " & & & & \\\\\n", + "\\hline\n", + "\tall & 4 & 4 & 3 & 1\\\\\n", + "\tpos & 0 & 3 & 2 & 0\\\\\n", + "\tneg & 4 & 1 & 1 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 4\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> |\n", + "|---|---|---|---|---|\n", + "| all | 4 | 4 | 3 | 1 |\n", + "| pos | 0 | 3 | 2 | 0 |\n", + "| neg | 4 | 1 | 1 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4\n", + "all 4 4 3 1 \n", + "pos 0 3 2 0 \n", + "neg 4 1 1 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab <- find_loops_vset(func_varusai15,vset=list(sol_full[idx,2:5]),t=idx,params=params_act_deact_stimulated)\n", + "print(\"Loop summary stimulated conditions:\")\n", + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "d703b6e6", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAMAAABoqemGAAAAb1BMVEUAAAAAAP8Ad7szu+5NTU1oaGh8fHyDg4OMjIyVlZWampqjo6Onp6evr6+ysrK5ubm9vb3BwcHHx8fJycnQ0NDR0dHY2NjZ2dne3t7h4eHk5OTp6enp/Onq6uruM3fudzPv7+/v9/rw8PD19fX////0ErZ1AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2di5qiurZG2ftEy3ZRtl1tteXy9D69Xb7/Mx5BQECcU27OBMb4vu7ygiFY/yggCSQ6A0CwRNYVAIDuIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwMxD4ChlVTxfXV947oMt3jrFyyhy693D8i5vR+V395fnS70aHXlc+2X9nY4Va/n9PPelQwvm8X1GNWHrz8UPPv/WNiu39KeixsflzXXpeXx5/qFXoyMPa7+9e6djxRDYmnl8n5lX++zpfhyBC3+FnVftU27URD+q/bFh67tVDIGtmcf3mWm1yZ5uRhH4FJXYPvjUunKouq/t917EsmHrB68YAr+EeXyfmVWL7OliFIE3mbiHpbALrpoRlw4LXse2aesHrxgCv4R5fJ/pUe3l3yl9dsqeDSzwMt/xnqSyK8emlydOr8TAHJv/fA1dMQR+CfP4PtPj5yhvlvnInuXbftok7q02p2L59JXFtpK43fqS6kV8KJdZWcnHZuXqb90ndlM6VN3fDutPm7RlfFmUn35y46LFplLK7eEhXlQ+8KiMOxbVre9TsfIa6gte39pe1rYsvtnyauvfZ8MGgc58BN6u82PE5EGpHTY/I76duO7c9bk73pZa5QutSmU2r213Oxq9X+hYOlRNDlSPxUcy4lKVo+sfnSaBby1m+Zl9cxl3tdskpxIN73SpWKmcuwWTR8f8i9zdVeju+7zfIHiCGQm8yw8LL6na3QRe3pKXRW9fPHdNSy1vZTat65gWfXy40OL2kssLu60xyneD+epX50aBy5/YS2XUq3e4vHZofKdDxW7l3C9YfH+lOt5We/d93m8QPMN8BN6d0uheI3za5Vm6Nj2dzqdtkrZ0H5w8WFxCtL82diUvJfuL5eWlQ/Lgtoe5X9O2nPXGhT6Kt5PMXg/ql9lOKm3/WhWfzHtiGwROFrzsqU7Jz4VURr2Ci3Qjm97pULFbOfcLpssVX6OrLn7/fd5vEDzDfAQ+JBlJBN0mf/QPWZbSBqfr7jI9Xj5dDwbd9XP5HvhQ7CjS6J3yMu/XtE5zKx0EJmu8HqrGRQnHzeJQvBkVVY5L1a89zH+eFvHuJJVRW/vmuiFNle9QsVs59wtGNxNdVNorJz8bvs/7DYJnmJPA22tqUo9zgTelOMZX9da3PcxHtlSpV2Wf76ebBc56qBbHx5VZ5x90DX2tFU/29RerAj8asSkIfMj+XDVWvn3FmsppqGExzCt/r+H7lDYIHjMngY/X+KQZzgVeRtfj6oRsv7DI97HZTvlcHToc1U//KhyS5thI7ITZZVHd1yN72m9uvVtRqWINAqcLLjZ3LbZ3ZVTfdtJfn/YVq5dTXjCqfo2Leu1LRayEDQKZOQmcqLlLYro4FwJXEnh9ElXTlS9Vwp3rn6yyjcSj6GwHF5c1P26LZtl7+RoELtp8SldOiGWkrPMj1+bKt65Y+Ul9waYNKP+sfZ9NGwQ6sxI4Tg6X0//6CXwX0BrJeaDQEJOdYrrbwftxWS9dE7jo6ir6aJQyihfulupRsdI58N2CLQSOGjcInmFWAu8Trxbp6deoAovvXY8od+kuJztTvnaXutV239wA1STw5cyycGb/RBnFC4LArStWPGlYsK3A9Q2Cp5iVwGkP8PWILRd4Fd2dAy9LAc6Wurt89txgx2a1Ko3VlL7YRXKoGt/20knr0fJYLbVZ4FrJu3TwUnpYrJVRvCAI3LpixZOGBfPv/Hz9Gpfl95q+z/oGwVPMS+BLzhbX8zyhFbp0KWw+3KNpbP+dAMVY6LRQKYNJq2zyx+SuN/VBF1Dy+PqnYZ+9fLokvfqKVkbxgiRw24rd7Vpr3UibW7FxebH77/N+g+Ap5vFV5QZcx/slp1h5ztJ9bKkf+FjuBz65bKlSv2WlzMoLqe2b07UV+uH1hOds5etCyrKgcaMniyhvFl5lLy9udpQElspQKt+tYhWBawsmP92xWv/8vfvv836D4Cnm8VVV0lfNYTryohiJlfZWJmFKhxC5YvFEnEWSwWOcDzS4z1nRClP8BXgUxutwj6KvNb3+MDlHX93XLyGRImnZ2RcX8u6yPxbn4zrbu2llPPhC+lWsckxcW/D6NeS1XlQ/e/d93m8QPMXMBL5dqlt5Kef61rEwMd8DZ/vinMrh4I3SeH73eCz0bcldwwcTjvVPHm7l5i+vSsu70xNlPPhC+lWseNKwYFHd20dvn73/Pu82CJ5iZgInZ2Mf1ZdKVyPlfbfFRTS3q5HK3SSbWgEFRU9IMRDrkSjJgu72tKhCepXU7u6T+ZU6pQrFRXWylWllNH8hPStWPLlfMNU2/yL39dXef593GwTPMDOBEwFqO4P8StZl6Xrg8ya7jLW01D5tIF2sPk7negE30sEMq9vd4B6JkqS1fJx4yC+OTSrYMNArfX9VubLwEKeHprdxD1oZjV9Iz4qVqlNf8PpWemH15n7x++/zfoPgCeYhMMBEQWCAgEFggIBBYICAQWCAgEFggIBBYICAQWCAgEFggIBBYICAQWCAgEFggIBBYICAQWCAgEFggIBBYICAQWCAgEFggIBBYICAGVngCCBkxtVjABAY4DHj6jEAowv835nQdUv/F/wFgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAJrWGcUBBAYgTWsMwoCCIzACv/6l3VI4TEIjMAKCOwzCDwfgbtinVEQQGAE1rDOKAggMAJrWGcUBBAYgTWsMwoCCIzAGtYZBQEERmAN64yCAAIjsALdSD6DwAisgMA+g8DzEZihlBMEgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAJrWGcUBBAYgTWsMwoCCIzACnQj+QwCI7ACAvsMAs9H4K5YZxQEEBiBNawzCgIIjMAa1hkFAQRGYA3rjIIAAiOwhnVGQQCBEVjDOqMggMAIrEA3ks8gMAIrILDPIPB8BGYo5QRBYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAa1hkFAQRGYA3rjIIAAiOwAt1IPoPACKyAwD6DwPMRuCvWGQUBBEZgDeuMggACI7CGdUZBAIERWMM6oyCAwAisYZ1REEBgBNawzigIIHAU/RsgVBAYgSFgEBiBIWAQGIEhYBAYgSFgEBiBIWAQGIEhYBAYgSFgEBiBIWAQGIEhYBCYoZQa1qMFQQCBEVjDOqMggMAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAK3FbWZxAYgRUQ2GcQeD4CM7XKBEFgBNawzigIIDACa1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgDeuMggACI7AC3Ug+g8AIrIDAPoPA8xG4K9YZBQEERmAN64yCAAIjsIZ1RkEAgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAIr0I3kMwiMwAoI7DNzE9hdqBU/G4EZSjlBZiawK/67FY/ACtYZBQEERmAN64yCwMwETnHV4hFYwTqjIIDACKxhnVEQmKHArlY8AitYZxQEEBiBFehG8pkpC/zDZQ8+vzn312f2xNWWQmAFBPaZCQv8K+/xfXcp7+kTd1f8bATuinVGQWC6An/Ph2z8dm9f5/PXm/tzbvAXgVWsMwoCUxX48819zwT+6X4lP77c53UgVm0oFgJrWGcUBKYqsPv2dc5MfXe/ry+9NxePwArWGQWBqQp8OWjOBX67/ji7t+biEVjBOqMgMFWBEzKB80Pm+lUMefEIrGCdURBAYARWoBvJZxAYgRUQ2GdmIDDnwBkMpZwgMxA4a4X+PftWaASeIDMQ+KdLR1F+up/NxSOwgnVGQWAGAv/JR2L9bi4egRWsMwoCMxC4Ohb6vngEVrDOKAjMQeDzr/c39+3zwVIIrGGdURCYssBPFo/AMnQj+QwCI7ACAvsMAs9H4K5YZxQEEBiBNawzCgIIjMAa1hkFAQRGYA3rjIIAAiOwhnVGQQCBEVjDOqMggMAIrEA3ks8gMAIrILDPIPB8BGYo5QRBYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAa1hkFAQRGYA3rjIIAAiOwAt1IPoPACKyAwD6DwPMRuCvWGQUBBEZgDeuMggACI7CGdUZBAIERWMM6oyCAwAisYZ1REEBgBNawzigIIDACK9CN5DMIjMAKCOwzCDwfgRlKOUEQGIE1rDMKAgiMwBrWGQUBBEZgDeuMggACI7CGdUZBAIERWMM6oyCAwAisQDeSzyAwAisgsM8g8HwE7op1RkEAgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAJrWGcUBBAYgTWsMwoCCIzACnQj+QwCI7ACAvsMAs9HYIZSThAERmAN64yCAAIjsIZ1RkEAgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAIr0I3kMwiMwAoI7DMIPB+Bu2KdURBAYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAa1hkFAQRGYA3rjIIAAiOwAt1IPoPACKyAwD6DwPMRmKGUEwSBEVjDOqMggMAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAKdCP5DAIjsAIC+wwCz0fgrlhnFAQQGIE1rDMKAgiMwBrWGQUBBEZgDeuMgkCwAp928cpFUeRW8e7Uq3gEVrDOKAgEKvBuGZVZ7XoUj8AK1hkFgSAF3l52vYt4d0ifHD7iy1O37Vw8AsvQjeQzAQq8X0QuPlZeOsQXo/cdi0dgGQT2mQAFjqLN/UKnbdctmY/ADKWcIAEKvGpuszqtOxaPwArWGQWBAAUeungEVrDOKAggMAJrWGcUBBAYgTWsMwoCCIzAGtYZBQEERmAFupF8ZhIC99oIBFZAYJ9B4PkI3BXrjILAJATuVzwCK1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgDeuMgkCoAkdV+hSPwArWGQUBBEZgBbqRfCZUgW/sl67H/TgQWAWBfSZ8gc/nZXTUFpGKj/4HIFSmIPA+6ngp8LV4BIZwmYLA58j1KR6BIVymIXC/Rizr3wFAZ6Yg8C5a9CkegSFcJiDwzkWd7yl7RmAImlAFrvQCL3sVj8AQLhMQeNln/4vAEDShCjxg8QgM4YLACAwBg8AMpdSwHi0IAgiMwBrWGQUBBEZgDeuMggACI7CGdUZBYBICcz3wmHA5oc8gMAIrILDPTELgfsXPRmCmVpkgCIzAGtYZBQEERmAN64yCwBQEPu5XfYpHYAXrjIJAsAIf19yVsiUIPEFCFfjkSvou9n2KR2AF64yCQKgCb6LF6ewub50+XMRtZZ+C6UUnSKgCLxNrV9Hh8vDo3KlP8Qgsg8A+E6rAab2313vpbKNNn+JnI3BXrDMKAkELfIjS5udTr3vqILCGdUZBIGiB8zGUtEKPinVGQaBd9nfrRRRFq02HqUy6S/bgHDg573XXSVUQeFSsMwoCbbJ/XBQdN3EHT1p/JP9k04tx2vS8Tk+C9z3vC20tiO9YZxQEWnh1ctFqn+z3DhsX9Rn71JLGGh4id0hu6X75/7Do8PekVDwCK1hnFARaCBzfPDn27HttRXMN47TmcXo84HoVj8AydCP5TAuBXWnR3Qt3wQ9quEuPm7eLyPXZ/yKwCgL7TAuBK4umTy7/HZblO6sf1i6KVsXOebe+7B3jY+XT1UU+VlH5A83rfbqGnZiPwAylnCAtBL4/1YyiXWVukzhr4sr2zqvs6e66bMMiy2fmRkHggUDgCdJC4O3dvjJR73A+77M2rU3kkvd3i+uE26v06emi7OmcC1xdJE4/ft4vxNnJ6jVcNQ+cPHWc5RuBNawzCgJtenfS/eVyvd3nBkVZ/83JJYOST1E+JnmRPD1E7nrwvE733OmKaovkZ9VHsR+oXsOoSffTtms/FQJrWGcUBFrFfptfw7fcZdn/yN5IHN0ULdO75Gmce3ZK9UxXVFskip4ZEVKv4X5RnFjnHOLu1xQisIZ1RkGg5X7rsF0vbiM5CgGPyVns8lZUouyyame6otoil5PkeKdeSXRfw+QPySLeHa5V+ogvT13nKQoRWMM6oyDQ5cBznxizO5fbpZNHlSl774ZeZc3WlUWO6R59Ecv7zqYa7paVopR2bLl4BJahG8lnOp45xmmzVV+Bi/viiPvP5hqedvEq8d+tntiJSyCwAgL7zPMCV5Y85f3ApTebjK09bVjbYZv2NgkG041kjHVGQeB5gZeV0ZOZj9lp7uF6DnyoLp+fA6dDHbNz4MoiOful1AyNwMZYZxQEnhd4Wx5ukRpba4WOqwM9ilboXdrnmw1drizioluHlGDYszXsBgJrWGcUBFqNhb7Zt0zVzS8jOLprx2++j05HSh/yawyWtwav2iKFzwf2wB5jnVEQaCHwPmlsSg6BD1t33Rtnd3TdZSOx4sup7GWXerz8TBZbRYuLrcdlvuz9Ipcz6XVynH0p4EMwrKuaz4HAGtYZBYE2rdCH2wX96yz7O1ce/JwPdM52s8vyQOfaWOjrIrv8mXRBEQIbY51REOhyS51lPg7q8uHT+mJz0bq1Ty41Wm7yM9vd6rKL3hbLNixyjC8FunVj01ZhWJsatgeBFehG8pmet5MaTCNpLSMXj8AyCOwzCDwfgRlKOUEQGIE1rDM6Pf4zHAiMwBrWcfeGAb0bDARGYA1rb0bFWsC+hDozw/m8uXVqcWP3p5ipwNaKjUuwApfnB24znOxCrXgEVrA28FmsXTIhVIGzm2u1xRX/3YpHYBk/u5GsxfGFUAVedLuzvCv+uxWPwDJ+CGwtiq+EKnDHerviv1JJA3syOXDWYxAYgTWQ1mNCFXjdfGsADVf8dysegRXQ1mNCFXjfbXImV/x3Kx6BFdB2BIb6EkMVOLmtnnYj6B8ue/D5zbm/PpNHrvjvVjwCKwyVtRxrd/ow9HfRm1AFjiK1H/hX3uP77lLezwjcicHCZm3fAwbbPgumK/D3fMjGb/f2dT5/vbk/CNyFAbqRUHQ0QhVY4/PNfc8E/ul+JT++XHIQPeeRWB3pIzCmjs1UBXbfvs6Zqu/u9/Wl9+biZyPwa4dSYutLmKrAl4PmXOC364+ze2suHoEV2mYKYV9IwAIf4usNuh52CGcC58fM9WPnvHgEVmgRJ5x9NeEKXNzfMno0szcCVxlZYKS1IFiBL/5u0ptUbx4ajMBVxhMYbc0IVeBd5PKpl44uah7SwTlwlXEERltTxhLY5ROr9OfBWOjbfIbbB7vgaiv0b1qhB7+cEHHNaSPw/zXTtOiumJ6hPw8GctwmBT49+GNR9AOnoyg/3c/m4hFY5pHAmOsDIwm8juKHbUtt0S8nfLARmcB/8pFYv5uLn43AXWmIDeb6wkgCX/aJbqiD8yf2wKLA5bHQjSVZC+I79cxgrkeMI/BHFJ9jacbBNvQ9Bz6ff72/uW+fj4pHYIVKYHDXL8YReBntz/vyhOB9eKIVus/pNgJr3NKCut4xisDXViVXOsrtQ3MN13o/8JPFI7BCnhXc9ZBRBP5I5/sd6hj6QQ3X6kisJ4tHYIU0KMjrJ6MInM+ZsOhlVmHYg9cP8VIeC/1k8Qgsk3Qj4a6vjCHwsdg3HhtKaW/YEIUIxSOwzL+Q12PGEHiTDW3cR5tBDBuiEKH42QjcbUuR12vGGEq5cNkDN8gxNAIPRJctxV7PGUHgQ9qElRB3u3lzjXoN0yo/cVO7Z4tH4Icgr/eMIHBcXBy0L1TuAwIPRNstxd0AGEHg0nW3Dy7BbQeH0APRbkvZ9wZBqNcDD1g8AjeAvYGAwAh8D/oGQ6gCl+v96HrgJ4tH4DrYGw5TELjrXKP5h0e1JjzQNySmIPAOgQcEe4MiQIG30R19LmdA4DLoGxgBCnxe1vR1XE44FE36vmCCb+hMiAKnLw5WbwQuaNR3vAm+YQAQGIFzmvVFYK8JVeABi0fgKw/0HWJ+YBiNKQh83K/6FI/AKQ/0RWC/CVbg47rcjtWn+NkILG3po91vgnVGQSBUgU+upO+ieW6kJ4tHYGH3m2CdURAIVeBNtDil944/ffS7qywC/1fxF4F9ZvzJzfK+2s73x2qs4TKxdpXeMODoXJ/71yLwnb+1t60zCgJtBP6fZpoWLU1u1vsOd4+7kbbX6Rm2ve69hcCKvwjsMyMJXJrc7LqGUxx1bSp+LPDhWuap1xwQsxdY0ReBvWYkgUuTm0W1n+0Na3wxKpVJK/RTNG+p6i/dSD4zjsDlyc0KgV1Xw5peXKbztrjrcTkCP0Xjlqr+IrDXjCNweXKz4hB627DgU4Y1vRinp9jXOQr3vaaAmI/ATaj6/pdDaK8ZReDK5GZ5G1bnhqbGGh4id0jnKDycD4teN7+ctcDP+IvAPjOKwJXJzXKBl13vEd1cwziteXzto+pY8rX4GQv8lL8I7DOjCFyZ3Cxbw4eLOo6XelDDXVr6dhG5fjefRmDFXwT2mTEErk5ulq/h0LWzh6uRxuI5fxHYZ8YQuDq5WbGGrm3FzY1Y8SAzH57nLPCT/iKwz4w/uVm+hmPXU9UH/cB9hk9WS3qZMX7xrL90I/nM+JObZWs4LLu2FXNHjlF41l8E9prxJze73XuuY3kP+oE/OhZ3V/xsBK5u6dMCcwjtM+NPbpb3Ig3bD3xeR5sh5i6drcDP+4vAPhPq9cBML9qe8pa28BeBfQaBEVj7nHVGQSBUgQcsfo4Ct/EXgX0GgRFYwzqjIIDAcxS4lb90I/lMqAIzP3B7ii1t5S8Ce80UBOaC/pa0E5hDaJ+ZgsDMD9yOlv4isM8EKDDzA/cEgSdEgAIzP3A/2vqLwD4TosDpi1zM0JW2/iKwzyDw3ARuvQNGYJ8JVeABi5+vwM99gG4kn0HgmQncfgeMwD4zisC95zOrltb88mZRasfqU/xsBE63tLW/HEJ7TZvs/7uZJid6zmdWLa3xVVdpiO5TPAIrWGcUBEYSOPm/x3xm1dKaXtxErteswKXiZyVwB38R2GdGFHiopuLGQhb9ZvUuF4/ACtYZBYFxBXaDGNb4It1IrblsafsmrP8isNeMewjddT6zammNLyJwa6oCP/8564yCwKiNWJ3vY1ctrenFdTTMLe0QWIVuJJ8ZVeDO85lVS2t6cT9MA9l5XgJ32gEjsM+MeQ7cfT6zammNr8bRaojC5yRwtyYsDqG9ZtRGrM7zmVVLa3yRu1J2AIEnx6gCD9PUhMBD0c1fBPaZkYZSXn92ns+sWtoAZUjFI7CCdUZBYEyBu89nVi1tgDKk4hFYwTqjIDDixQxR9/nMqqUNUYhQ/GwE7ugvAvvMmAJ3n8+sWtqD1w/xIq39ql9nFQIr0I3kM+FeD7zOW6+ifsOiEVgBgX0mWIFX0WJ3PdneRdGpT/EzFLjd56wzCgKhCryLFue8tSzuNWZzNgJ3PQVGYJ8JVeBVetx8rf2x13gRBNawzigIhCrwtd5Z7RnI8Qxd/UVgn0HguQjceQeMwD4TqsCuJDCzEz4DAk+SUAVel86Bt8yN9ASdBaYbyWdCFfgQudO56Ebqc2Hh/ARu+UEE9plQBT7HyW0pL7U/xFG/EdcIrGGdURAIVuDzphhx3e+KiZkI3P0UGIF9JlyBz6dNMs/oMu553x4E1rDOKAgELPBQxSOwgnVGQeAVcyP1XMfoAv9nXrR23zqjINBGrgeBaHLiNjfS8XReLM+nHrMkPajhKU5GQ5/duucUDQiMwAEzksBXw5Jbvy6j5WKx7DNaubmGuygfjNXzznkIrEA3ks+MKPD15+mwjqL1vscFf401PF4KvZa56/XXAYEROGjGFdglgkVx3OuS+8YaxqXOo2WvKVwQWMM6oyAw7iF0Itbmchy96nXBbtOLrnQR/zG9Nrhz8TMTuLW/COwzozZijXhPrEq9e16N9FJ/zEHgSTGqwCPOjYTAXUHgSTHmOfCYcyOtS6fVu14Tnc1M4Pb+IrDPjNqINeLcSLvIFV3Li35tZLMSuIO/COwzowo84txI51XktonCx63r243UJdQh0nFL6UbymXDnRloV4736zRSMwAoI7DMBz410iLka6SVYZxQEmBsJgTWsMwoCAc+NNBAIrGGdURDgemAE1rDOKAiEK/BmEd3oUzwCK1hnFASCFdhFEQK/BuuMgkCoAm+Sm1IOUzwCy9CN5DOhCtxv9FWleASWQWCfCVXg4eo9H4G7bql1RkEAgRFYwzqjIBCqwOtokEsVzwisY51REAhV4H3PEdCl4hFYwTqjIBCqwOc4Wg1xsTEC61hnFARCFTiK6AduCwJPEARGYAW6kXwmVIEHLB6BZRDYZxB4PgJ3xTqjIIDACKxhnVEQCFjgQ7zgjhyvwDqjIBCuwHHRgrXuVzwCK1hnFASCFfji7ybZ9x42PQ1GYA3rjIJAqAKX7gt97Hf/eATWsM4oCIQq8Lo0I+G21y4YgRXoRvKZUAWOSrMTnnrd/RKBFRDYZ8IV+NGT1sXPRmCGUk6QcAUu74ER+BkQeIKEKjDnwO1B4AkSqsDVVuh+sxMOq4m/IPAECVXgyy6YfuCWIPAECVbgxGBGYrUCgSdIuAIzO2FbuJxwggQs8FDFI7AMAvsMAs9H4K5YZxQEwhT4FOczh2/WfW8vi8Aa1hkFgSAF3rti8OQi6nt/WQTWsM4oCIQo8DGKlvl+97S5POlXPAIrWGcUBEIUeBHFpWdHRz/wuFhnFAQCFHgXLSrPLzvkPufBCKxhnVEQCFDgdfRRfSGu7JFbF4/AMnQj+UyAAi+iY/WFfa+zYARWQGCfCVDg+ypzOeFTMJRygiAwAmtYZxQEEBiBNawzCgIBCryqNzofOQd+CgSeIAEKvIk21Re4I8dzIPAECVDgu5tQLrgjx1Mg8AQJUODzutrvG9cGdrQtHoFl6EbymRAFPrmywXFU7xduWTwCyyCwz4QocDL82aU3xDofNpeHfQ6g5yRwV6wzCgJBCnw+rYobYkWr0/37rYpHYAXrjIJAmAJfdtx7s58AAAv/SURBVMKbxGG3+mipr7tQKx6BFawzCgKhCtwRV/x3Kx6BFawzCgIIjMAa1hkFgZkJnOKqxSOwgnVGQQCBEViBbiSfmaHArlY8AssgsM8g8HwEZijlBJmowD9c9uDzm3N/fZ5L/UeutigCa1hnFASmKfCvvLP33aW8395yd8UjsIJ1RkFgkgJ/z/e2v93b1/n89eb+5G+5++IRWME6oyAwQYE/39z3TOCf7lfy48t9Zu9dd8jV4hFYwTqjIDBBgd23r3Mm6bv7fX3p/fHiCKxhnVEQmKDAl4PmXOC364+zexOKR2AZupF8ZoICJ+Qtzq7ytLl4BJZBYJ9B4PkI3BXrjIIAAiOwhnVGQWDaAnMOPATWGQWBaQuctUL/phW6D9YZBYFpC/zz2gH86X4KxSOwgnVGQWDaAv/JR2L9FopHYAXrjILAtAVuGAt9XzwCy9CN5DMTF/j86/3NffuUFkVgBQT2mYkK3Kb42QjMUMoJgsAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAa1hkFAQRGYAW6kXwGgRFYAYF9BoHnI3BXrDMKAgiMwBrWGQUBBEZgDeuMggACI7CGdUZBAIERWMM6oyCAwAisYZ1REEBgBFagG8lnEBiBFRDYZxB4PgIzlHKCIDACa1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgDeuMggACI7CGdUZBAIERWIFuJJ9BYARWQGCfQeD5CNwV64yCAAIjsIZ1RkEAgRFYwzqjIIDACKxhnVEQQGAE1rDOKAggMAJrWGcUBBAYgRXoRvIZBEZgBQT2GQSej8AMpZwgCIzAGtYZBQEERmAN64yCAAIjsIZ1RkEAgRFYwzqjIIDACKxhnVEQQGAEVqAbyWcQGIEVENhnEHg+AnfFOqMggMAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBNawzCgIIjMAa1hkFAQRGYAW6kXwGgRFYAYF9BoHnIzBDKScIAiOwhnVGQQCBEVjDOqMggMAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBFehG8hkERmAFBPYZBJ6PwF2xzigIIDACa1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgDeuMggACI7CGdUZBAIERWIFuJJ9BYARWQGCfQeD5CMxQygmCwAisYZ1REEBgBNawzigIIDACa1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgBbqRfAaBEVgBgX0GgecjcFesMwoCCIzAGtYZBQEERmAN64yCAAIjsIZ1RkEAgRFYwzqjIIDACKxhnVEQQGAEVqAbyWcQGIEVENhnEHg+AjOUcoIgMAJrWGcUBBAYgTWsMwoCCIzAGtYZBQEERmAN64yCAAIjsIZ1RkEAgRFYgW4kn0FgBFZAYJ9B4PkI3BXrjIIAAiOwhnVGQQCBEVjDOqMggMAIrGGdURBAYATWsM4oCCAwAmtYZxQEEBiBFehG8hkERmAFBPYZBJ6PwAylnCAIjMAa1hkFAQRGYA3rjIIAAiOwhnVGQQCBEVjDOqMggMAIrGGdURBAYARWoBvJZxAYgRUQ2GcQeD4Cd8U6oyCAwAisYZ1REEBgBNawzigIIDACa1hnFAQQGIE1rDMKAgiMwBrWGQUBBEZgBbqRfAaBEVgBgX0GgecjMEMpJwgCI7CGdUZBAIERWMM6oyCAwAisYZ1REEBgBNawzigIIDACa1hnFAQQGIEV6EbyGQRGYAUE9hkEno/AXbHOKAggMAJrWGcUBBAYgTWsMwoCCIzAGtYZBQEERmAN64yCAAIjsIZ1RkEAgaPo/wBCBYERGAIGgREYAgaBERgCBoERGAIGgREYAgaBERgCBoERGAIGgREYAgaBERgCBoEZSqlhPVoQBBAYgTWsMwoCCIzAGtYZBQEERmAN64yCAAIjsIZ1RkEAgRFYwzqjIIDACKzAbWV9ZoYCu1rxCCyDwD4zP4GdqxU/G4GZWmWCzE5gN989MAJPkLkJ7GZ8CI3AEwSBEVjDOqMgMDOB3RmBW2OdURCYl8Cu+K9UPAIrWGcUBCYq8A+XPfj85txfn+ek8dm59D9Xa4ZGYAW6kXxmmgL/yiV9vxr7Xn7T1YoHCJluVr2Q9jX8nu9lf7u3r/P56839Kb3rasUDhExnsV5F2xp+vrnvmcA/3a/kx5f7LL3vBqkVADxFW4Hdt698uNW7+3196V1YHgBGpK3Al4PmXOC364+zexuwPgDQgi4H+ZnAeVtWffwzALwKBAYIGAQGCJgeAnMODGBND4GzVujftEIDWNFD4J/XDuBP93PA+gBAC3oI/CcfifV70BoBwNP0ELhxLDQAvJA+Ap9/vb+5b5/SogAwJv6P1gaAhwwt8P21wsLjAfmnfDXyC9ZX4zVrsdlMk19pvtLXbfDnX859+3lf+OvD1IqBBW68VvjR4yH5Kv2iX7G+Ki9rDTDYTJNfabHSl23wX9cC/5JW5GOjz7ACN14r/OjxoPy4XtsorXs8XrOWhNdvpsmvtFjpyzb4h/vrUtTfb+6HQXj7MKTAD64VfvR4UL7dvtWXrK/Ca9aS8OrNNPmVllb6sg3OhhX+ToYVvjy8fRj0rpTN1wo/ejwk/5TGc75ifVVedmX0yzfT5FdaWunrN9i9Pry9GFLgB9cKP3o8JF/u/fNb1qX1ivVVedmo8JdvpsmvtLTSV2/wn+Qk+NXh7cXgk5u58o/056PHQ/LD3dogXrG+Ki+7LstkM01+pVlpr97g7+7v14e3FxMR+FvyxZ///JWcnkxYYJPNtBT4xRv8lbRhzU7gWzv/+eW/7cq6kyOgb5MWOOO1m2kpcMaLNvjqLwKfX3caURM4Xf2Ez4FzXrqZJs0aNUlessE/r/5yDnyuXiv86PEYlBoRX7K+Ky+/Mvqlm2nyK20QeOyVfs+7h6zC24mRBC5fK/zo8ZC8uX+SH3+7769ZX5WXXRltspkmv9Jit/+qDf7z9vZ39vDV4e3FSAKXrxV+9HhIfrj3f9LGjr9fs74qL7sy2mQzTX6lRSv0izb4n7e3YsTIq8Pbi5EEfvlw0mwo649Xra/KywbJWmymya80X+mrNvi7yxFWNP2x0KVzl/K1wo8eD0lyocj7369bX5WXXRltsJkmv9JipS/aYFcW+OXh7QHXAwMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAJbElVIX+hSzD5atf3IKtp3WRP4BgJbMpDAi+jU9iOnaNFlTeAbCGxPN2tvbKNt+w9tunwIvAOB7ekrcLd7NHl1ZyfoCgLb01PgXRR3+Vgc7XqtFrwAge0pCXx9ePn/sIyi5eFi5+Xn+pi9e1i7KFrVvVtG2fuH+LJwtNxUT4iL0mt/J47RcqgNADsQ2J4GgXfXZq1DnP5wV0PjrLGr2uRcNEflb+eL10uv7+g7NH2BdyCwPQ0CR+vT+bSMFlF8SnbG6THyJnLJzne3iNblT+dH0LvL26eG9x8KzDH0FEBgexoETney++iq4j7dx54il+0xF9Gh9Oncw+LVU9XUhwJ3PHcGr0BgexoE3mfPDrdXN8UOs2reqqJzrbyzIPCh/fAP8A4EtqepEet893NZWqo8CMNVfoWH7co9KfA5cp2rDL6AwPY8J3B90Nb9p3dJI3X9bUlgfvnhw+/QnoEETluhV9vDs4fQCDwF+B3a86zA8qe3kdse6+WdEXji8Du059lz4Hpj1ZX8HLh1KzTnwFMAge15TuD4Qa/PqtxUnfDRLPCeVugpgsD2PCfwIcr7kXYV8+LoI/3pMpGPtVboZfaxZV3gD/qBJwAC2/OcwEkj1fZ0ETSOKgfTea9wHC32l+PnbdISXR5LuU0HcO2Xri4wI7GmAALb86TAt8HOFfFO+als1ofkdot0HEhR6jL7ULXsZHnGQocPAtvzrMDnfdLRW7/a6DYUK15c373eYedW6nYRufWxVjanwNMAgYOH64HnDAKHT6dj4ROdSJMAgcOn0z2xOn0IvAOBJwB3pZwvCDwB9tVL+J9hzX2hpwECAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwQMAgMEDAIDBAwCAwTM/wOmFO6eh/jBngAAAABJRU5ErkJggg==", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot again including the color area in the background to indicate unstimulated and stimulated loop structures changes (at idx, t)\n", + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "colors <- c(\n", + " A = \"#EE7733\",\n", + " B = \"#0077BB\",\n", + " AB = \"#33BBEE\",\n", + " `B*` = \"#EE3377\"\n", + ")\n", + "\n", + "t_change <- time_full[idx]\n", + "yr <- range(sol_long$value, na.rm = TRUE)\n", + "\n", + "plot2 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " # Add background colored areas \n", + " annotate(\"rect\",\n", + " xmin = -1000, xmax = t_change,\n", + " ymin = 10**-4, ymax = yr[2]+1000,\n", + " alpha = 0.2, fill = \"lightblue\") +\n", + " annotate(\"rect\",\n", + " xmin = t_change, xmax = 2000,\n", + " ymin = 10**-4, ymax = yr[2]+1000,\n", + " alpha = 0.2, fill = \"lightgreen\") +\n", + " ## vertical dashed line\n", + " geom_vline(\n", + " xintercept = 0,\n", + " linetype = \"dashed\",\n", + " colour = \"black\",\n", + " linewidth = 0.7\n", + " ) +\n", + " ## Another vertical line at the time of loop structure change\n", + " geom_vline(\n", + " xintercept = t_change,\n", + " linetype = \"dotted\",\n", + " colour = \"blue\",\n", + " linewidth = 0.7\n", + " ) +\n", + " ## Trajectory lines\n", + " geom_line(linewidth = 3) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(-1000, 2000, 500),\n", + " minor_breaks = seq(-1000, 2000, 250),\n", + " limits = c(-1000, 2000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(-1000, 2000), clip = \"on\", ylim = c(10**-4, yr[2]+1000)\n", + " ) +\n", + " scale_y_log10(\n", + " breaks = scales::trans_breaks(\"log10\", function(x) 10^x),\n", + " labels = scales::trans_format(\"log10\", scales::math_format(10^.x)),\n", + " limits = c(10**-4, yr[2]+1000),\n", + " expand = c(0, 0)\n", + " ) + # log10 transformation\n", + " labs(\n", + " title = \"Model 3: Varusai 4 Variables\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + " \n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "plot2\n", + "# ggsave(\"POSm4_plot_stimulated_loops.png\", plot2, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "id": "1a104392", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Zoom in around the perturbation point to see the dynamics more clearly (of only B)\n", + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "\n", + "plot3 <- ggplot(sol_long %>% filter(species == \"B\"), aes(x = time, y = value, colour = species)) +\n", + " ## vertical dashed line\n", + " geom_vline(\n", + " xintercept = 0,\n", + " linetype = \"dashed\",\n", + " colour = \"black\",\n", + " linewidth = 0.7\n", + " ) +\n", + " ## Another vertical line at the time of loop structure change\n", + " geom_vline(\n", + " xintercept = t_change,\n", + " linetype = \"dotted\",\n", + " colour = \"blue\",\n", + " linewidth = 0.7\n", + " ) +\n", + " ## Trajectory lines\n", + " geom_line(linewidth = 3) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(-1000, 2000, 500),\n", + " minor_breaks = seq(-1000, 2000, 250),\n", + " limits = c(-1000, 2000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(-1000, 2000), clip = \"on\"\n", + " ) +\n", + " scale_y_continuous(\n", + " minor_breaks = seq(-293, 295, 0.2),\n", + " breaks = seq(-293, 295, 1),\n", + " # limits = c(10**-2, yr[2]+1000),\n", + " # expand = c(0, 0)\n", + " ) + \n", + " labs(\n", + " title = \"Dynamics of B\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + " \n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "plot3\n", + "# ggsave(\"POSm4_plot_stimulated_loops_zoomed.png\", plot" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/model_5_MAPK_reduced_R.ipynb b/examples/model_5_MAPK_reduced_R.ipynb new file mode 100644 index 0000000..9a18c09 --- /dev/null +++ b/examples/model_5_MAPK_reduced_R.ipynb @@ -0,0 +1,2386 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5c5107a0", + "metadata": {}, + "source": [ + "## **0. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "0aa853b2", + "metadata": {}, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad430870", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2d7c70f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c741284", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1d32152b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")\n", + "library(deSolve)\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3eb6dbbb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "colors <- c('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB')" + ] + }, + { + "cell_type": "markdown", + "id": "de63ff1e", + "metadata": {}, + "source": [ + "## **1. Model definition**" + ] + }, + { + "cell_type": "markdown", + "id": "39347b82", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **Example 5: Reduced MAPK Model (with and without explicit feedback)**" + ] + }, + { + "cell_type": "markdown", + "id": "21903465", + "metadata": {}, + "source": [ + "The model for the mitogen-activated phosphorylation kinase (MAPK) cascade proposed in [7] captures the first, second and third level of a phosphorylation cascade which occurs for example in epidermal growth factor (EGF) signaling. The kinase on the first level can be reversibly phosphorylated once, the kinases on levels two andthree can be reversibly phosphorylated twice. The phosphorylated kinase of the first level acts positively on the phosphorylations on the second level, the double phosphorylated kinase of the second level acts positively on the phosphorylations on the third level. The model contains an explicit negative feedback regulation: The double phosphorylated kinase of the third level acts negatively on the phosphorylation on the first level. All phosphorylations are governed by Michaelis-Menten kinetics. The model contains eight variables, ten rate coefficients, eleven inhibition or activation constants, and one Hill coefficient." + ] + }, + { + "cell_type": "markdown", + "id": "8f5f1511", + "metadata": {}, + "source": [ + "$$\n", + "\\begin{aligned}\n", + "\\frac{dS_1}{dt} &=\n", + "- k_1 \\, \\frac{S_1}{kn_2 + S_1} \\, \\frac{kn_1^{n_1}}{kn_1^{n_1} + S_8^{n_1}}\n", + "+ k_2 \\, \\frac{S_2}{S_2 + kn_3}, \\\\[8pt]\n", + "\n", + "\\frac{dS_2}{dt} &=\n", + "\\phantom{-}\\, k_1 \\, \\frac{S_1}{kn_2 + S_1} \\, \\frac{kn_1^{n_1}}{kn_1^{n_1} + S_8^{n_1}}\n", + "- k_2 \\, \\frac{S_2}{S_2 + kn_3}, \\\\[10pt]\n", + "\n", + "\\frac{dS_3}{dt} &=\n", + "\\phantom{-}\\, k_6 \\, \\frac{S_4}{kn_7 + S_4}\n", + "- k_3 \\, \\frac{S_2 \\, S_3}{kn_4 + S_3}, \\\\[10pt]\n", + "\n", + "\\frac{dS_4}{dt} &=\n", + "\\phantom{-}\\, k_3 \\, \\frac{S_2 \\, S_3}{kn_4 + S_3}\n", + "- k_6 \\, \\frac{S_4}{kn_7 + S_4}\n", + "+ k_5 \\, \\frac{S_5}{kn_6 + S_5}\n", + "- k_4 \\, \\frac{S_2 \\, S_4}{kn_5 + S_4}, \\\\[10pt]\n", + "\n", + "\\frac{dS_5}{dt} &=\n", + "\\phantom{-}\\, k_4 \\, \\frac{S_2 \\, S_4}{kn_5 + S_4}\n", + "- k_5 \\, \\frac{S_5}{kn_6 + S_5}, \\\\[10pt]\n", + "\n", + "\\frac{dS_6}{dt} &=\n", + "\\phantom{-}\\, k_{10} \\, \\frac{S_7}{kn_{11} + S_7}\n", + "- k_7 \\, \\frac{S_5 \\, S_6}{kn_8 + S_6}, \\\\[10pt]\n", + "\n", + "\\frac{dS_7}{dt} &=\n", + "\\phantom{-}\\, k_7 \\, \\frac{S_5 \\, S_6}{kn_8 + S_6}\n", + "- k_{10} \\, \\frac{S_7}{kn_{11} + S_7}\n", + "- k_8 \\, \\frac{S_5 \\, S_7}{kn_9 + S_7}\n", + "+ k_9 \\, \\frac{S_8}{kn_{10} + S_8}, \\\\[10pt]\n", + "\n", + "\\frac{dS_8}{dt} &=\n", + "\\phantom{-}\\, k_8 \\, \\frac{S_5 \\, S_7}{kn_9 + S_7}\n", + "- k_9 \\, \\frac{S_8}{kn_{10} + S_8}.\n", + "\\end{aligned}\n", + "$$\n" + ] + }, + { + "cell_type": "markdown", + "id": "d486b5d6", + "metadata": {}, + "source": [ + "In the table below, the notation we used is given together with the notation used in the original publication [7], and we provide the initial conditions and reference parameter set published together with the model." + ] + }, + { + "cell_type": "markdown", + "id": "9340d377", + "metadata": {}, + "source": [ + "**Initial conditions**\n", + "\n", + "| Var | Name (short) | Name (long) | Initial value |\n", + "|------:|-------------|-------------|---------------|\n", + "| S₁ | MKKK | MAPKKK | 100 nM |\n", + "| S₂ | MKKK-P | MAPKKK* | 0 |\n", + "| S₃ | MKK | MAPKK | 300 nM |\n", + "| S₄ | MKK-P | MAPKK* | 0 |\n", + "| S₅ | MKK-PP | MAPKK** | 0 |\n", + "| S₆ | MAPK | MAPK | 300 nM |\n", + "| S₇ | MAPK-P | MAPK* | 0 |\n", + "| S₈ | MAPK-PP | MAPK** | 0 |\n" + ] + }, + { + "cell_type": "markdown", + "id": "201db642", + "metadata": {}, + "source": [ + "**Parameters**\n", + "| Parameter | Symbol | Value | Units |\n", + "|----------:|--------|-------|-------|\n", + "| k₁ | V₁ | 2.5 | nM·s⁻¹ |\n", + "| k₂ | V₂ | 0.25 | nM·s⁻¹ |\n", + "| k₃ | k₃ | 0.025 | s⁻¹ |\n", + "| k₄ | k₄ | 0.025 | s⁻¹ |\n", + "| k₅ | V₅ | 0.75 | nM·s⁻¹ |\n", + "| k₆ | V₆ | 0.75 | nM·s⁻¹ |\n", + "| k₇ | k₇ | 0.025 | s⁻¹ |\n", + "| k₈ | k₈ | 0.025 | s⁻¹ |\n", + "| k₉ | V₉ | 0.5 | nM·s⁻¹ |\n", + "| k₁₀ | V₁₀ | 0.5 | nM·s⁻¹ |\n" + ] + }, + { + "cell_type": "markdown", + "id": "9fb78a52", + "metadata": {}, + "source": [ + "The MAPK cascade model without explicit feedback regulation is exactly the same as the one described above, but for the corresponding regulation term omitted from the ODE system. Therefore, only the first two equations of the ODE model are altered to:" + ] + }, + { + "cell_type": "markdown", + "id": "cb1f8ad9", + "metadata": {}, + "source": [ + "$$\n", + "\\begin{aligned}\n", + "\\frac{dS_1}{dt} &=\n", + "- k_1 \\, \\frac{S_1}{kn_2 + S_1}\n", + "+ k_2 \\, \\frac{S_2}{S_2 + kn_3}, \\\\[8pt]\n", + "\n", + "\\frac{dS_2}{dt} &=\n", + "\\phantom{-}\\, k_1 \\, \\frac{S_1}{kn_2 + S_1}\n", + "- k_2 \\, \\frac{S_2}{S_2 + kn_3}.\n", + "\\end{aligned}\n", + "$$\n" + ] + }, + { + "cell_type": "markdown", + "id": "f038b36a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **1.1. Reduced MAPK Model with aexplicit feedback**" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "id": "9edacb63", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "model_mapk_simple_w_feedback <- function(t, y, klin, kn, n1) {\n", + " # Unpack state\n", + " S1 <- y[1]; S2 <- y[2]; S3 <- y[3]; S4 <- y[4]\n", + " S5 <- y[5]; S6 <- y[6]; S7 <- y[7]; S8 <- y[8]\n", + "\n", + " # Kinetic parameters\n", + " k1 <- klin[1]; k2 <- klin[2]; k3 <- klin[3]; k4 <- klin[4]; k5 <- klin[5]\n", + " k6 <- klin[6]; k7 <- klin[7]; k8 <- klin[8]; k9 <- klin[9]; k10 <- klin[10]\n", + "\n", + " # Saturation constants\n", + " kn1 <- kn[1]; kn2 <- kn[2]; kn3 <- kn[3]; kn4 <- kn[4]; kn5 <- kn[5]\n", + " kn6 <- kn[6]; kn7 <- kn[7]; kn8 <- kn[8]; kn9 <- kn[9]; kn10 <- kn[10]\n", + " kn11 <- kn[11]\n", + "\n", + " # dS1/dt\n", + " term_inhibit <- (kn1^n1) / (kn1^n1 + S8^n1)\n", + " dS1 <- -k1 * (S1/(kn2 + S1)) * term_inhibit +\n", + " k2 * (S2/(S2 + kn3))\n", + "\n", + " # dS2/dt\n", + " dS2 <- k1 * (S1/(kn2 + S1)) * term_inhibit -\n", + " k2 * (S2/(S2 + kn3))\n", + "\n", + " # dS3/dt\n", + " dS3 <- k6 * (S4/(kn7 + S4)) -\n", + " k3 * (S2*S3/(kn4 + S3))\n", + "\n", + " # dS4/dt\n", + " dS4 <- k3 * (S2*S3/(kn4 + S3)) -\n", + " k6 * (S4/(kn7 + S4)) +\n", + " k5 * (S5/(kn6 + S5)) -\n", + " k4 * (S2*S4/(kn5 + S4))\n", + "\n", + " # dS5/dt\n", + " dS5 <- k4 * (S2*S4/(kn5 + S4)) -\n", + " k5 * (S5/(kn6 + S5))\n", + "\n", + " # dS6/dt\n", + " dS6 <- k10 * (S7/(kn11 + S7)) -\n", + " k7 * (S5*S6/(kn8 + S6))\n", + "\n", + " # dS7/dt\n", + " dS7 <- k7 * (S5*S6/(kn8 + S6)) -\n", + " k10 * (S7/(kn11 + S7)) -\n", + " k8 * (S5*S7/(kn9 + S7)) +\n", + " k9 * (S8/(kn10 + S8))\n", + "\n", + " # dS8/dt\n", + " dS8 <- k8 * (S5*S7/(kn9 + S7)) -\n", + " k9 * (S8/(kn10 + S8))\n", + " \n", + " dx <- rep(0,8)\n", + " dx[1] <- dS1\n", + " dx[2] <- dS2\n", + " dx[3] <- dS3\n", + " dx[4] <- dS4\n", + " dx[5] <- dS5\n", + " dx[6] <- dS6\n", + " dx[7] <- dS7\n", + " dx[8] <- dS8\n", + " \n", + " return(dx)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "51df3daa", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **1.2. Reduced MAPK Model without explicit feedback**" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "id": "64a3f6ca", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "model_mapk_simple_wo_feedback <- function(t, y, klin, kn, n1) {\n", + " # Unpack state\n", + " S1 <- y[1]; S2 <- y[2]; S3 <- y[3]; S4 <- y[4]\n", + " S5 <- y[5]; S6 <- y[6]; S7 <- y[7]; S8 <- y[8]\n", + "\n", + " # Kinetic parameters\n", + " k1 <- klin[1]; k2 <- klin[2]; k3 <- klin[3]; k4 <- klin[4]; k5 <- klin[5]\n", + " k6 <- klin[6]; k7 <- klin[7]; k8 <- klin[8]; k9 <- klin[9]; k10 <- klin[10]\n", + "\n", + " # Saturation constants\n", + " kn1 <- kn[1]; kn2 <- kn[2]; kn3 <- kn[3]; kn4 <- kn[4]; kn5 <- kn[5]\n", + " kn6 <- kn[6]; kn7 <- kn[7]; kn8 <- kn[8]; kn9 <- kn[9]; kn10 <- kn[10]\n", + " kn11 <- kn[11]\n", + "\n", + " # dS1/dt\n", + " dS1 <- -k1 * (S1/(kn2 + S1)) +\n", + " k2 * (S2/(S2 + kn3))\n", + "\n", + " # dS2/dt\n", + " dS2 <- k1 * (S1/(kn2 + S1)) -\n", + " k2 * (S2/(S2 + kn3))\n", + "\n", + " # dS3/dt\n", + " dS3 <- k6 * (S4/(kn7 + S4)) -\n", + " k3 * (S2*S3/(kn4 + S3))\n", + "\n", + " # dS4/dt\n", + " dS4 <- k3 * (S2*S3/(kn4 + S3)) -\n", + " k6 * (S4/(kn7 + S4)) +\n", + " k5 * (S5/(kn6 + S5)) -\n", + " k4 * (S2*S4/(kn5 + S4))\n", + "\n", + " # dS5/dt\n", + " dS5 <- k4 * (S2*S4/(kn5 + S4)) -\n", + " k5 * (S5/(kn6 + S5))\n", + "\n", + " # dS6/dt\n", + " dS6 <- k10 * (S7/(kn11 + S7)) -\n", + " k7 * (S5*S6/(kn8 + S6))\n", + "\n", + " # dS7/dt\n", + " dS7 <- k7 * (S5*S6/(kn8 + S6)) -\n", + " k10 * (S7/(kn11 + S7)) -\n", + " k8 * (S5*S7/(kn9 + S7)) +\n", + " k9 * (S8/(kn10 + S8))\n", + "\n", + " # dS8/dt\n", + " dS8 <- k8 * (S5*S7/(kn9 + S7)) -\n", + " k9 * (S8/(kn10 + S8))\n", + " \n", + " dx <- rep(0,8)\n", + " dx[1] <- dS1\n", + " dx[2] <- dS2\n", + " dx[3] <- dS3\n", + " dx[4] <- dS4\n", + " dx[5] <- dS5\n", + " dx[6] <- dS6\n", + " dx[7] <- dS7\n", + " dx[8] <- dS8\n", + " \n", + " return(dx)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "44e7e155", + "metadata": {}, + "source": [ + "## **2. Result reproduction**" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "4e5b9062", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Parameters from supplementary material\n", + "klin <- c(\n", + " 2.5, # k1\n", + " 0.25, # k2\n", + " 0.025, # k3\n", + " 0.025, # k4\n", + " 0.75, # k5\n", + " 0.75, # k6\n", + " 0.025, # k7\n", + " 0.025, # k8\n", + " 0.5, # k9\n", + " 0.5 # k10\n", + ")\n", + "\n", + "kn <- c(\n", + " 9, # kn1 = KI\n", + " 10, # kn2 = K1\n", + " 8, # kn3 = K2\n", + " 15, # kn4\n", + " 15, # kn5\n", + " 15, # kn6\n", + " 15, # kn7\n", + " 15, # kn8\n", + " 15, # kn9\n", + " 15, # kn10\n", + " 15 # kn11\n", + ")\n", + "\n", + "n1 <- 1\n", + "\n", + "# Initial conditions\n", + "initial_conditions <- c(\n", + " S1 = 100, # S1: MKKK, MAPKKK\n", + " S2 = 0, # S2: MKKK-P, MKKK*\n", + " S3 = 300, # S3: MKK, MAPKK\n", + " S4 = 0, # S4: MKK-P, MAPKK*,\n", + " S5 = 0, # S5: MKK-PP, MAPKK**\n", + " S6 = 300, # S6: MAPK, MAPK\n", + " S7 = 0, # S7: MAPK-P, MAPK*\n", + " S8 = 0 # S8: MAPK-PP, MAPK** \n", + ")\n", + "\n", + "all_labels <- c('MAPKKK (S1)', 'MAPKKK* (S2)', 'MAPKK (S3)', 'MAPKK* (S4)', \n", + " 'MAPKK** (S5)', 'MAPK (S6)', 'MAPK* (S7)', 'MAPK** (S8)')\n" + ] + }, + { + "cell_type": "markdown", + "id": "b927c538", + "metadata": {}, + "source": [ + "### **2.1. Reduced MAPK Model with explicit feedback**" + ] + }, + { + "cell_type": "markdown", + "id": "b9c9522a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **2.1.1. Loop structure (at first)**" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "6c2540e5", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 7 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
4, 41-1
5, 51-1
7, 71-1
8, 81-1
1, 2, 12 1
\n" + ], + "text/latex": [ + "A data.frame: 7 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 5, 5 & 1 & -1\\\\\n", + "\t 7, 7 & 1 & -1\\\\\n", + "\t 8, 8 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 7 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 5, 5 | 1 | -1 |\n", + "| 7, 7 | 1 | -1 |\n", + "| 8, 8 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 4, 4 1 -1 \n", + "4 5, 5 1 -1 \n", + "5 7, 7 1 -1 \n", + "6 8, 8 1 -1 \n", + "7 1, 2, 1 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(model_mapk_simple_w_feedback,vset=list(initial_conditions),t=1,klin=klin,kn=kn,n1=n1,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3d056cc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all61
pos01
neg60
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 6 & 1\\\\\n", + "\tpos & 0 & 1\\\\\n", + "\tneg & 6 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 6 | 1 |\n", + "| pos | 0 | 1 |\n", + "| neg | 6 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 6 1 \n", + "pos 0 1 \n", + "neg 6 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e9a5ecf2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 2 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
71, 2, 12 1
\n" + ], + "text/latex": [ + "A data.frame: 2 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t7 & 1, 2, 1 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 2 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 7 | 1, 2, 1 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "7 1, 2, 1 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2 \n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "9f0fc026", + "metadata": {}, + "source": [ + "#### **2.1.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "05e68bc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-1 10 0 00 0 1
1-10 0 00 0-1
0-10 1 00 0 0
0 10-1 10 0 0
0 00 0-10 0 0
0 00 0-10 1 0
0 00 0 10-1 1
0 00 0 00 0-1
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -1 & 1 & 0 & 0 & 0 & 0 & 0 & 1\\\\\n", + "\t 1 & -1 & 0 & 0 & 0 & 0 & 0 & -1\\\\\n", + "\t 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0\\\\\n", + "\t 0 & 1 & 0 & -1 & 1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 0 & 1 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & 1 & 0 & -1 & 1\\\\\n", + "\t 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |\n", + "| 1 | -1 | 0 | 0 | 0 | 0 | 0 | -1 |\n", + "| 0 | -1 | 0 | 1 | 0 | 0 | 0 | 0 |\n", + "| 0 | 1 | 0 | -1 | 1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 0 | 1 | 0 |\n", + "| 0 | 0 | 0 | 0 | 1 | 0 | -1 | 1 |\n", + "| 0 | 0 | 0 | 0 | 0 | 0 | 0 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]\n", + "[1,] -1 1 0 0 0 0 0 1 \n", + "[2,] 1 -1 0 0 0 0 0 -1 \n", + "[3,] 0 -1 0 1 0 0 0 0 \n", + "[4,] 0 1 0 -1 1 0 0 0 \n", + "[5,] 0 0 0 0 -1 0 0 0 \n", + "[6,] 0 0 0 0 -1 0 1 0 \n", + "[7,] 0 0 0 0 1 0 -1 1 \n", + "[8,] 0 0 0 0 0 0 0 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix (at initialization point)\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "b4802333", + "metadata": {}, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003]." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "adbc93e2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
S1
95.6517023027939
S2
4.34829769720574
S3
208.414606568695
S4
74.5151466422457
S5
17.0702467890569
S6
6.84331427771254
S7
15.1917577910863
S8
277.9649279312
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[S1] 95.6517023027939\n", + "\\item[S2] 4.34829769720574\n", + "\\item[S3] 208.414606568695\n", + "\\item[S4] 74.5151466422457\n", + "\\item[S5] 17.0702467890569\n", + "\\item[S6] 6.84331427771254\n", + "\\item[S7] 15.1917577910863\n", + "\\item[S8] 277.9649279312\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "S1\n", + ": 95.6517023027939S2\n", + ": 4.34829769720574S3\n", + ": 208.414606568695S4\n", + ": 74.5151466422457S5\n", + ": 17.0702467890569S6\n", + ": 6.84331427771254S7\n", + ": 15.1917577910863S8\n", + ": 277.9649279312\n", + "\n" + ], + "text/plain": [ + " S1 S2 S3 S4 S5 S6 S7 \n", + " 95.651702 4.348298 208.414607 74.515147 17.070247 6.843314 15.191758 \n", + " S8 \n", + "277.964928 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_list <- function(t,x,klin,kn,n1){list(model_mapk_simple_w_feedback(t,x,klin,kn,n1))}\n", + "sol <- deSolve::ode(y = initial_conditions, times = seq(0,3650,1), func = func_list, \n", + " parms=klin, kn=kn, n1=n1)\n", + "\n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star_end" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "1d134ecb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-7.024262e-05 0.013116435 0.000000e+00 0.0000000000 0.000000000 0.00000000 0.000000000 2.473666e-04
7.024262e-05-0.013116435 0.000000e+00 0.0000000000 0.000000000 0.00000000 0.000000000-2.473666e-04
0.000000e+00-0.023321506-3.266837e-05 0.0014039753 0.000000000 0.00000000 0.000000000 0.000000e+00
0.000000e+00 0.002510742 3.266837e-05-0.0016074721 0.010938252 0.00000000 0.000000000 0.000000e+00
0.000000e+00 0.020810765 0.000000e+00 0.0002034968-0.010938252 0.00000000 0.000000000 0.000000e+00
0.000000e+00 0.000000000 0.000000e+00 0.0000000000-0.007832276-0.01341634 0.008227814 0.000000e+00
0.000000e+00 0.000000000 0.000000e+00 0.0000000000-0.004747116 0.01341634-0.015250355 8.738361e-05
0.000000e+00 0.000000000 0.000000e+00 0.0000000000 0.012579392 0.00000000 0.007022541-8.738361e-05
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -7.024262e-05 & 0.013116435 & 0.000000e+00 & 0.0000000000 & 0.000000000 & 0.00000000 & 0.000000000 & 2.473666e-04\\\\\n", + "\t 7.024262e-05 & -0.013116435 & 0.000000e+00 & 0.0000000000 & 0.000000000 & 0.00000000 & 0.000000000 & -2.473666e-04\\\\\n", + "\t 0.000000e+00 & -0.023321506 & -3.266837e-05 & 0.0014039753 & 0.000000000 & 0.00000000 & 0.000000000 & 0.000000e+00\\\\\n", + "\t 0.000000e+00 & 0.002510742 & 3.266837e-05 & -0.0016074721 & 0.010938252 & 0.00000000 & 0.000000000 & 0.000000e+00\\\\\n", + "\t 0.000000e+00 & 0.020810765 & 0.000000e+00 & 0.0002034968 & -0.010938252 & 0.00000000 & 0.000000000 & 0.000000e+00\\\\\n", + "\t 0.000000e+00 & 0.000000000 & 0.000000e+00 & 0.0000000000 & -0.007832276 & -0.01341634 & 0.008227814 & 0.000000e+00\\\\\n", + "\t 0.000000e+00 & 0.000000000 & 0.000000e+00 & 0.0000000000 & -0.004747116 & 0.01341634 & -0.015250355 & 8.738361e-05\\\\\n", + "\t 0.000000e+00 & 0.000000000 & 0.000000e+00 & 0.0000000000 & 0.012579392 & 0.00000000 & 0.007022541 & -8.738361e-05\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -7.024262e-05 | 0.013116435 | 0.000000e+00 | 0.0000000000 | 0.000000000 | 0.00000000 | 0.000000000 | 2.473666e-04 |\n", + "| 7.024262e-05 | -0.013116435 | 0.000000e+00 | 0.0000000000 | 0.000000000 | 0.00000000 | 0.000000000 | -2.473666e-04 |\n", + "| 0.000000e+00 | -0.023321506 | -3.266837e-05 | 0.0014039753 | 0.000000000 | 0.00000000 | 0.000000000 | 0.000000e+00 |\n", + "| 0.000000e+00 | 0.002510742 | 3.266837e-05 | -0.0016074721 | 0.010938252 | 0.00000000 | 0.000000000 | 0.000000e+00 |\n", + "| 0.000000e+00 | 0.020810765 | 0.000000e+00 | 0.0002034968 | -0.010938252 | 0.00000000 | 0.000000000 | 0.000000e+00 |\n", + "| 0.000000e+00 | 0.000000000 | 0.000000e+00 | 0.0000000000 | -0.007832276 | -0.01341634 | 0.008227814 | 0.000000e+00 |\n", + "| 0.000000e+00 | 0.000000000 | 0.000000e+00 | 0.0000000000 | -0.004747116 | 0.01341634 | -0.015250355 | 8.738361e-05 |\n", + "| 0.000000e+00 | 0.000000000 | 0.000000e+00 | 0.0000000000 | 0.012579392 | 0.00000000 | 0.007022541 | -8.738361e-05 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] \n", + "[1,] -7.024262e-05 0.013116435 0.000000e+00 0.0000000000 0.000000000\n", + "[2,] 7.024262e-05 -0.013116435 0.000000e+00 0.0000000000 0.000000000\n", + "[3,] 0.000000e+00 -0.023321506 -3.266837e-05 0.0014039753 0.000000000\n", + "[4,] 0.000000e+00 0.002510742 3.266837e-05 -0.0016074721 0.010938252\n", + "[5,] 0.000000e+00 0.020810765 0.000000e+00 0.0002034968 -0.010938252\n", + "[6,] 0.000000e+00 0.000000000 0.000000e+00 0.0000000000 -0.007832276\n", + "[7,] 0.000000e+00 0.000000000 0.000000e+00 0.0000000000 -0.004747116\n", + "[8,] 0.000000e+00 0.000000000 0.000000e+00 0.0000000000 0.012579392\n", + " [,6] [,7] [,8] \n", + "[1,] 0.00000000 0.000000000 2.473666e-04\n", + "[2,] 0.00000000 0.000000000 -2.473666e-04\n", + "[3,] 0.00000000 0.000000000 0.000000e+00\n", + "[4,] 0.00000000 0.000000000 0.000000e+00\n", + "[5,] 0.00000000 0.000000000 0.000000e+00\n", + "[6,] -0.01341634 0.008227814 0.000000e+00\n", + "[7,] 0.01341634 -0.015250355 8.738361e-05\n", + "[8,] 0.00000000 0.007022541 -8.738361e-05" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(model_mapk_simple_w_feedback, s_star_end,method=\"complex\",\n", + " t=3650,klin=klin, kn=kn, n1=n1)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "d9a4b8c8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-1 1 0 0 0 0 0 1
1-1 0 0 0 0 0-1
0-1-1 1 0 0 0 0
0 1 1-1 1 0 0 0
0 1 0 1-1 0 0 0
0 0 0 0-1-1 1 0
0 0 0 0-1 1-1 1
0 0 0 0 1 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -1 & 1 & 0 & 0 & 0 & 0 & 0 & 1\\\\\n", + "\t 1 & -1 & 0 & 0 & 0 & 0 & 0 & -1\\\\\n", + "\t 0 & -1 & -1 & 1 & 0 & 0 & 0 & 0\\\\\n", + "\t 0 & 1 & 1 & -1 & 1 & 0 & 0 & 0\\\\\n", + "\t 0 & 1 & 0 & 1 & -1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & -1 & 1 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 1 & -1 & 1\\\\\n", + "\t 0 & 0 & 0 & 0 & 1 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |\n", + "| 1 | -1 | 0 | 0 | 0 | 0 | 0 | -1 |\n", + "| 0 | -1 | -1 | 1 | 0 | 0 | 0 | 0 |\n", + "| 0 | 1 | 1 | -1 | 1 | 0 | 0 | 0 |\n", + "| 0 | 1 | 0 | 1 | -1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | -1 | 1 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 1 | -1 | 1 |\n", + "| 0 | 0 | 0 | 0 | 1 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]\n", + "[1,] -1 1 0 0 0 0 0 1 \n", + "[2,] 1 -1 0 0 0 0 0 -1 \n", + "[3,] 0 -1 -1 1 0 0 0 0 \n", + "[4,] 0 1 1 -1 1 0 0 0 \n", + "[5,] 0 1 0 1 -1 0 0 0 \n", + "[6,] 0 0 0 0 -1 -1 1 0 \n", + "[7,] 0 0 0 0 -1 1 -1 1 \n", + "[8,] 0 0 0 0 1 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "9fb5ce0e", + "metadata": {}, + "source": [ + "#### **2.1.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "b6906e49", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol <- deSolve::ode(y = s_star_end, times = seq(0,5000,1), func = func_list, \n", + " parms=klin, kn=kn, n1=n1)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "a9e0a20b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "296.620110566778" + ], + "text/latex": [ + "296.620110566778" + ], + "text/markdown": [ + "296.620110566778" + ], + "text/plain": [ + "[1] 296.6201" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "max(sol[,9])" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "6e020cf1", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
  1. 5001
  2. 9
\n" + ], + "text/latex": [ + "\\begin{enumerate*}\n", + "\\item 5001\n", + "\\item 9\n", + "\\end{enumerate*}\n" + ], + "text/markdown": [ + "1. 5001\n", + "2. 9\n", + "\n", + "\n" + ], + "text/plain": [ + "[1] 5001 9" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dim(sol)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "cf1a9580", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 420, + "width": 420 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:dim(sol)[2]],\n", + " type = \"l\",\n", + " lty = 1,\n", + " xlab = \"Time\",\n", + " ylab = \"Concentration\",\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = all_labels,\n", + " col = 1:8,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "9a37d5b5", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "investigate_label <- c('MAPKK** (S5)', 'MAPK (S6)', 'MAPK* (S7)')\n", + "investigate_index <- c(6, 7, 8)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "1f18ff68", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol[, c(1, investigate_index)])\n", + "\n", + "# rename columns for clarity (use time + investigate_label)\n", + "colnames(sol_for_plot) <- c(\"time\", investigate_label)\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = `MAPKK** (S5)`:`MAPK* (S7)`, names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "273651c0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 840 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 14, repr.plot.height = 6)\n", + "colors <- c(\n", + " `MAPKK** (S5)` = \"#EE7733\",\n", + " `MAPK (S6)` = \"#0077BB\",\n", + " `MAPK* (S7)` = \"#33BBEE\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(linewidth = 2) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 5000, 1000),\n", + " minor_breaks = seq(0, 5000, 500),\n", + " limits = c(0, 5000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 5000), clip = \"on\") +\n", + " labs(\n", + " title = \"Dynamics of the Reduced MAPK Model with Explicit Feedback\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "a506b026", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_list <- lapply(1:nrow(sol), function(i) as.numeric(sol[i, 2:9]))\n", + "res_tab_all <- find_loops_vset(model_mapk_simple_w_feedback,vset=sol_list,t=1,klin=klin,kn=kn,n1=n1)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "id": "a1881f7e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Draw background in the plot corresponding to the time points where\n", + "# certain loop structures are present\n", + "\n", + "# 1-to-1 time vector (must match loop_rep_index length)\n", + "time_vec <- sort(unique(sol_long$time))\n", + "\n", + "stopifnot(length(res_tab_all$loop_rep_index) == length(time_vec))\n", + "\n", + "# Run-length encode to get contiguous segments of the same loop structure\n", + "r <- rle(res_tab_all$loop_rep_index)\n", + "\n", + "end_idx <- cumsum(r$lengths)\n", + "start_idx <- c(1, head(end_idx + 1, -1))\n", + "\n", + "bands <- tibble(\n", + " loop_type = factor(r$values),\n", + " t_start = time_vec[start_idx],\n", + " t_end = time_vec[end_idx]\n", + ")\n", + "transition_times <- bands$t_end[-nrow(bands)]" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "8725b19d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 840 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "plot2 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " # background bands (behind lines)\n", + " geom_rect(\n", + " data = bands,\n", + " aes(xmin = t_start, xmax = t_end, ymin = -Inf, ymax = Inf, fill = loop_type),\n", + " inherit.aes = FALSE,\n", + " alpha = 0.1\n", + " ) +\n", + " geom_vline(\n", + " xintercept = transition_times,\n", + " colour = \"grey40\",\n", + " linewidth = 0.7,\n", + " alpha = 0.35\n", + " ) +\n", + " geom_line(linewidth = 2) +\n", + " scale_colour_manual(values = colors) +\n", + " scale_fill_brewer(palette = \"Set2\", name = \"Loop structure\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 5000, 1000),\n", + " minor_breaks = seq(0, 5000, 500),\n", + " limits = c(0, 5000),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 5000), clip = \"on\") +\n", + " labs(\n", + " title = \"Dynamics of the Reduced MAPK Model with Explicit Feedback\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " panel.grid = element_blank(),\n", + " panel.border = element_rect(colour = \"black\", fill = NA, linewidth = 1.1)\n", + " )\n", + "\n", + "plot2\n" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "id": "3bc28d1d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 8
len_1len_2len_3len_4len_5len_6len_7len_8
<dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
all85135531
pos05024111
neg80111420
\n" + ], + "text/latex": [ + "A data.frame: 3 × 8\n", + "\\begin{tabular}{r|llllllll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4 & len\\_5 & len\\_6 & len\\_7 & len\\_8\\\\\n", + " & & & & & & & & \\\\\n", + "\\hline\n", + "\tall & 8 & 5 & 1 & 3 & 5 & 5 & 3 & 1\\\\\n", + "\tpos & 0 & 5 & 0 & 2 & 4 & 1 & 1 & 1\\\\\n", + "\tneg & 8 & 0 & 1 & 1 & 1 & 4 & 2 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 8\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> | len_5 <dbl> | len_6 <dbl> | len_7 <dbl> | len_8 <dbl> |\n", + "|---|---|---|---|---|---|---|---|---|\n", + "| all | 8 | 5 | 1 | 3 | 5 | 5 | 3 | 1 |\n", + "| pos | 0 | 5 | 0 | 2 | 4 | 1 | 1 | 1 |\n", + "| neg | 8 | 0 | 1 | 1 | 1 | 4 | 2 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4 len_5 len_6 len_7 len_8\n", + "all 8 5 1 3 5 5 3 1 \n", + "pos 0 5 0 2 4 1 1 1 \n", + "neg 8 0 1 1 1 4 2 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab_all$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "id": "0a868f1a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 8
len_1len_2len_3len_4len_5len_6len_7len_8
<dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
all85135531
pos05014301
neg80121230
\n" + ], + "text/latex": [ + "A data.frame: 3 × 8\n", + "\\begin{tabular}{r|llllllll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4 & len\\_5 & len\\_6 & len\\_7 & len\\_8\\\\\n", + " & & & & & & & & \\\\\n", + "\\hline\n", + "\tall & 8 & 5 & 1 & 3 & 5 & 5 & 3 & 1\\\\\n", + "\tpos & 0 & 5 & 0 & 1 & 4 & 3 & 0 & 1\\\\\n", + "\tneg & 8 & 0 & 1 & 2 & 1 & 2 & 3 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 8\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> | len_5 <dbl> | len_6 <dbl> | len_7 <dbl> | len_8 <dbl> |\n", + "|---|---|---|---|---|---|---|---|---|\n", + "| all | 8 | 5 | 1 | 3 | 5 | 5 | 3 | 1 |\n", + "| pos | 0 | 5 | 0 | 1 | 4 | 3 | 0 | 1 |\n", + "| neg | 8 | 0 | 1 | 2 | 1 | 2 | 3 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4 len_5 len_6 len_7 len_8\n", + "all 8 5 1 3 5 5 3 1 \n", + "pos 0 5 0 1 4 3 0 1 \n", + "neg 8 0 1 2 1 2 3 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab_all$loop_rep[[2]])" + ] + }, + { + "cell_type": "markdown", + "id": "6f592bea", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **2.2. Reduced MAPK Model without explicit feedback**" + ] + }, + { + "cell_type": "markdown", + "id": "f59d6720", + "metadata": {}, + "source": [ + "#### **2.1.1. Loop structure (at first)**" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "id": "f152e382", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 7 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
4, 41-1
5, 51-1
7, 71-1
8, 81-1
1, 2, 12 1
\n" + ], + "text/latex": [ + "A data.frame: 7 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 5, 5 & 1 & -1\\\\\n", + "\t 7, 7 & 1 & -1\\\\\n", + "\t 8, 8 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 7 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 5, 5 | 1 | -1 |\n", + "| 7, 7 | 1 | -1 |\n", + "| 8, 8 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 4, 4 1 -1 \n", + "4 5, 5 1 -1 \n", + "5 7, 7 1 -1 \n", + "6 8, 8 1 -1 \n", + "7 1, 2, 1 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(model_mapk_simple_wo_feedback,vset=list(initial_conditions),t=1,klin=klin,kn=kn,n1=n1,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "id": "8f02f293", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all61
pos01
neg60
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 6 & 1\\\\\n", + "\tpos & 0 & 1\\\\\n", + "\tneg & 6 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 6 | 1 |\n", + "| pos | 0 | 1 |\n", + "| neg | 6 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 6 1 \n", + "pos 0 1 \n", + "neg 6 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "id": "b5415ec2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 2 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
71, 2, 12 1
\n" + ], + "text/latex": [ + "A data.frame: 2 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t7 & 1, 2, 1 & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 2 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 7 | 1, 2, 1 | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "7 1, 2, 1 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2 \n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "f5fbad0b", + "metadata": {}, + "source": [ + "#### **2.1.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "id": "b058ca06", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-1 10 0 00 0 0
1-10 0 00 0 0
0-10 1 00 0 0
0 10-1 10 0 0
0 00 0-10 0 0
0 00 0-10 1 0
0 00 0 10-1 1
0 00 0 00 0-1
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -1 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\\\\n", + "\t 1 & -1 & 0 & 0 & 0 & 0 & 0 & 0\\\\\n", + "\t 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0\\\\\n", + "\t 0 & 1 & 0 & -1 & 1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 0 & 1 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & 1 & 0 & -1 & 1\\\\\n", + "\t 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |\n", + "| 1 | -1 | 0 | 0 | 0 | 0 | 0 | 0 |\n", + "| 0 | -1 | 0 | 1 | 0 | 0 | 0 | 0 |\n", + "| 0 | 1 | 0 | -1 | 1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 0 | 1 | 0 |\n", + "| 0 | 0 | 0 | 0 | 1 | 0 | -1 | 1 |\n", + "| 0 | 0 | 0 | 0 | 0 | 0 | 0 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]\n", + "[1,] -1 1 0 0 0 0 0 0 \n", + "[2,] 1 -1 0 0 0 0 0 0 \n", + "[3,] 0 -1 0 1 0 0 0 0 \n", + "[4,] 0 1 0 -1 1 0 0 0 \n", + "[5,] 0 0 0 0 -1 0 0 0 \n", + "[6,] 0 0 0 0 -1 0 1 0 \n", + "[7,] 0 0 0 0 1 0 -1 1 \n", + "[8,] 0 0 0 0 0 0 0 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix (at initialization point)\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "34b4f161", + "metadata": {}, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003]." + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "id": "299e548b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
S1
1.01955086432784
S2
98.9804491356722
S3
1.43623788843733
S4
6.07643921148842
S5
292.487322900074
S6
0.0670824395339598
S7
1.04469160783373
S8
298.888225952632
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[S1] 1.01955086432784\n", + "\\item[S2] 98.9804491356722\n", + "\\item[S3] 1.43623788843733\n", + "\\item[S4] 6.07643921148842\n", + "\\item[S5] 292.487322900074\n", + "\\item[S6] 0.0670824395339598\n", + "\\item[S7] 1.04469160783373\n", + "\\item[S8] 298.888225952632\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "S1\n", + ": 1.01955086432784S2\n", + ": 98.9804491356722S3\n", + ": 1.43623788843733S4\n", + ": 6.07643921148842S5\n", + ": 292.487322900074S6\n", + ": 0.0670824395339598S7\n", + ": 1.04469160783373S8\n", + ": 298.888225952632\n", + "\n" + ], + "text/plain": [ + " S1 S2 S3 S4 S5 S6 \n", + " 1.01955086 98.98044914 1.43623789 6.07643921 292.48732290 0.06708244 \n", + " S7 S8 \n", + " 1.04469161 298.88822595 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_list <- function(t,x,klin,kn,n1){list(model_mapk_simple_wo_feedback(t,x,klin,kn,n1))}\n", + "sol <- deSolve::ode(y = initial_conditions, times = seq(0,500,1), func = func_list, \n", + " parms=klin, kn=kn, n1=n1)\n", + "\n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star_end" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "id": "99caeba0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-0.006018131 0.0001747516 0.0000000 0.00000000 0.0000000000 0.0000000 0.00000000 2.196046e-05
0.006018131-0.0001747516 0.0000000 0.00000000 0.0000000000 0.0000000 0.00000000-2.196046e-05
0.000000000-0.0021845600-0.1373966 0.02532550 0.0000000000 0.0000000 0.00000000 0.000000e+00
0.000000000-0.0050230608 0.1373966-0.10888315 0.0001189866 0.0000000 0.00000000 0.000000e+00
0.000000000 0.0072076207 0.0000000 0.08355765-0.0001189866 0.0000000 0.00000000 0.000000e+00
0.000000000 0.0000000000 0.0000000 0.00000000-0.0001113063-0.4831478 0.02913389 0.000000e+00
0.000000000 0.0000000000 0.0000000 0.00000000-0.0015164776 0.4831478-0.45519861 7.612218e-05
0.000000000 0.0000000000 0.0000000 0.00000000 0.0016277839 0.0000000 0.42606471-7.612218e-05
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -0.006018131 & 0.0001747516 & 0.0000000 & 0.00000000 & 0.0000000000 & 0.0000000 & 0.00000000 & 2.196046e-05\\\\\n", + "\t 0.006018131 & -0.0001747516 & 0.0000000 & 0.00000000 & 0.0000000000 & 0.0000000 & 0.00000000 & -2.196046e-05\\\\\n", + "\t 0.000000000 & -0.0021845600 & -0.1373966 & 0.02532550 & 0.0000000000 & 0.0000000 & 0.00000000 & 0.000000e+00\\\\\n", + "\t 0.000000000 & -0.0050230608 & 0.1373966 & -0.10888315 & 0.0001189866 & 0.0000000 & 0.00000000 & 0.000000e+00\\\\\n", + "\t 0.000000000 & 0.0072076207 & 0.0000000 & 0.08355765 & -0.0001189866 & 0.0000000 & 0.00000000 & 0.000000e+00\\\\\n", + "\t 0.000000000 & 0.0000000000 & 0.0000000 & 0.00000000 & -0.0001113063 & -0.4831478 & 0.02913389 & 0.000000e+00\\\\\n", + "\t 0.000000000 & 0.0000000000 & 0.0000000 & 0.00000000 & -0.0015164776 & 0.4831478 & -0.45519861 & 7.612218e-05\\\\\n", + "\t 0.000000000 & 0.0000000000 & 0.0000000 & 0.00000000 & 0.0016277839 & 0.0000000 & 0.42606471 & -7.612218e-05\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -0.006018131 | 0.0001747516 | 0.0000000 | 0.00000000 | 0.0000000000 | 0.0000000 | 0.00000000 | 2.196046e-05 |\n", + "| 0.006018131 | -0.0001747516 | 0.0000000 | 0.00000000 | 0.0000000000 | 0.0000000 | 0.00000000 | -2.196046e-05 |\n", + "| 0.000000000 | -0.0021845600 | -0.1373966 | 0.02532550 | 0.0000000000 | 0.0000000 | 0.00000000 | 0.000000e+00 |\n", + "| 0.000000000 | -0.0050230608 | 0.1373966 | -0.10888315 | 0.0001189866 | 0.0000000 | 0.00000000 | 0.000000e+00 |\n", + "| 0.000000000 | 0.0072076207 | 0.0000000 | 0.08355765 | -0.0001189866 | 0.0000000 | 0.00000000 | 0.000000e+00 |\n", + "| 0.000000000 | 0.0000000000 | 0.0000000 | 0.00000000 | -0.0001113063 | -0.4831478 | 0.02913389 | 0.000000e+00 |\n", + "| 0.000000000 | 0.0000000000 | 0.0000000 | 0.00000000 | -0.0015164776 | 0.4831478 | -0.45519861 | 7.612218e-05 |\n", + "| 0.000000000 | 0.0000000000 | 0.0000000 | 0.00000000 | 0.0016277839 | 0.0000000 | 0.42606471 | -7.612218e-05 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] [,6] \n", + "[1,] -0.006018131 0.0001747516 0.0000000 0.00000000 0.0000000000 0.0000000\n", + "[2,] 0.006018131 -0.0001747516 0.0000000 0.00000000 0.0000000000 0.0000000\n", + "[3,] 0.000000000 -0.0021845600 -0.1373966 0.02532550 0.0000000000 0.0000000\n", + "[4,] 0.000000000 -0.0050230608 0.1373966 -0.10888315 0.0001189866 0.0000000\n", + "[5,] 0.000000000 0.0072076207 0.0000000 0.08355765 -0.0001189866 0.0000000\n", + "[6,] 0.000000000 0.0000000000 0.0000000 0.00000000 -0.0001113063 -0.4831478\n", + "[7,] 0.000000000 0.0000000000 0.0000000 0.00000000 -0.0015164776 0.4831478\n", + "[8,] 0.000000000 0.0000000000 0.0000000 0.00000000 0.0016277839 0.0000000\n", + " [,7] [,8] \n", + "[1,] 0.00000000 2.196046e-05\n", + "[2,] 0.00000000 -2.196046e-05\n", + "[3,] 0.00000000 0.000000e+00\n", + "[4,] 0.00000000 0.000000e+00\n", + "[5,] 0.00000000 0.000000e+00\n", + "[6,] 0.02913389 0.000000e+00\n", + "[7,] -0.45519861 7.612218e-05\n", + "[8,] 0.42606471 -7.612218e-05" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(model_mapk_simple_w_feedback, s_star_end,method=\"complex\",\n", + " t=3650,klin=klin, kn=kn, n1=n1)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "id": "d1b442c8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 8 × 8 of type dbl
-1 1 0 0 0 0 0 1
1-1 0 0 0 0 0-1
0-1-1 1 0 0 0 0
0-1 1-1 1 0 0 0
0 1 0 1-1 0 0 0
0 0 0 0-1-1 1 0
0 0 0 0-1 1-1 1
0 0 0 0 1 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 8 × 8 of type dbl\n", + "\\begin{tabular}{llllllll}\n", + "\t -1 & 1 & 0 & 0 & 0 & 0 & 0 & 1\\\\\n", + "\t 1 & -1 & 0 & 0 & 0 & 0 & 0 & -1\\\\\n", + "\t 0 & -1 & -1 & 1 & 0 & 0 & 0 & 0\\\\\n", + "\t 0 & -1 & 1 & -1 & 1 & 0 & 0 & 0\\\\\n", + "\t 0 & 1 & 0 & 1 & -1 & 0 & 0 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & -1 & 1 & 0\\\\\n", + "\t 0 & 0 & 0 & 0 & -1 & 1 & -1 & 1\\\\\n", + "\t 0 & 0 & 0 & 0 & 1 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 8 × 8 of type dbl\n", + "\n", + "| -1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |\n", + "| 1 | -1 | 0 | 0 | 0 | 0 | 0 | -1 |\n", + "| 0 | -1 | -1 | 1 | 0 | 0 | 0 | 0 |\n", + "| 0 | -1 | 1 | -1 | 1 | 0 | 0 | 0 |\n", + "| 0 | 1 | 0 | 1 | -1 | 0 | 0 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | -1 | 1 | 0 |\n", + "| 0 | 0 | 0 | 0 | -1 | 1 | -1 | 1 |\n", + "| 0 | 0 | 0 | 0 | 1 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]\n", + "[1,] -1 1 0 0 0 0 0 1 \n", + "[2,] 1 -1 0 0 0 0 0 -1 \n", + "[3,] 0 -1 -1 1 0 0 0 0 \n", + "[4,] 0 -1 1 -1 1 0 0 0 \n", + "[5,] 0 1 0 1 -1 0 0 0 \n", + "[6,] 0 0 0 0 -1 -1 1 0 \n", + "[7,] 0 0 0 0 -1 1 -1 1 \n", + "[8,] 0 0 0 0 1 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "b007c715", + "metadata": {}, + "source": [ + "#### **2.1.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "id": "1d8fa1ab", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 840 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:dim(sol)[2]],\n", + " type = \"l\",\n", + " lty = 1,\n", + " xlab = \"Time\",\n", + " ylab = \"Concentration\",\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = all_labels,\n", + " col = 1:8,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "id": "5cc9b71e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "investigate_label <- c('MAPKK** (S5)', 'MAPK** (S8)')\n", + "investigate_index <- c(6, 9)" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "id": "cf8c7b52", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol[, c(1, investigate_index)])\n", + "\n", + "# rename columns for clarity (use time + investigate_label)\n", + "colnames(sol_for_plot) <- c(\"time\", investigate_label)\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = `MAPKK** (S5)`:`MAPK** (S8)`, names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "id": "e0fc16f0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA8AAAAJYCAMAAACaSn8zAAAAYFBMVEUAAAAAd7tNTU1oaGh8fHyDg4OMjIyVlZWampqjo6Onp6evr6+ysrK5ubm9vb3BwcHHx8fJycnQ0NDR0dHY2NjZ2dne3t7h4eHk5OTp6enq6urudzPv7+/w8PD19fX///9MeKiJAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2d62KjKhRGGTRpajOZjp00J506vv9bngBeQNF4AeXyrR+tSXQLZK+geCMlAMBbyN4FAAAsBwID4DEQGACPgcAAeAwEBsBjIDAAHgOBAfAYCAyAx0BgADwGAgPgMRAYAI+BwAB4DAQGwGMgMAAes1hg0pIcL4XJMmnWZCjU/UQJSbNOcEKOzeujeGNVqeYUWJk3m798j6zzmnSZHqqde2w5XQ0G1z595b34S1vFYPq4iAmBGWeTheqvyUykmyhr2gkux5+caOYFvqcTdHlCE0NZwVYCP1/79JX34kNgLaYEVqwwi7lv4CSK2u+BybV6ed1P4JxO0WWcNoaygo0EnrD26SvvxYfAWowJLG2GOgsr5ntZFp23SLsBcd5aYN1Sy1NOs6QRgY2tfU64TlQIrGWVwGKquJ0pe5WbKpM1hjMsqV4mQQq8LJgpgReuvRsCAmsxIPCDIpUkcJeBDGOFF71yUb2CwEsWhcA7YEbgsmB98JW/K3dmzXz5kRB6ujWzn/lob5rd5GCXhzvp5fHylj3CHXPNmm5ZIi+neUOiODMZj+eijdPrXtlrtt38zl+9V6+IPkL9TnJRSpWzse2kLUJ3HayEFz7Fap02a0pKNT3rwol/1xMLeh+qjbwWaTltBbsNc2+/Jla2ez2bqJxmDWNfga4Go2vXtJjmnV5DVznyWHnafh/dRBopX8maj7btGQiGBOY7j2cxTCTaiCXJqZrvnlbfbTV8lDdfdvUOn4mKd9JmR7R/VOXYWa68NG/0h8HPzWeXJo42wy4nUVRe/NOlnaUbQYzTEJ4I7VxNoY5SzG5Bjm0RmoXO5YjAWfU6l4IoZZHWIi2nrWCvaS51C57qePI3QK/dRce+Al0Nxtfeb7H+O/2GVkpYtUovkUbKdyIh+mtM4JtofNaibWeWV/PRplH5z+KVSORld6Z27mtnTVRa7tSNdC1VUumzrI6jzbDLo9S0XkHeCtyLIK2P6uZKtU1TNjl4awvKJu7lsMBZ88ZtoCzSWqTltBXsf3upKMd7U2i14W+dRUe+ggUC91us946modUSXtW5SP1LN1g+VtUA/TUmMHtNxT/xI3qUv9f0Wv2m8jZNq5/QW1rPLdq7EPvS7dRRXRMLmeRsu6n+wthMZ/0uOJ/n8gh0Yeu9qJHUauRFlbNMsCKv59JEYBPJoy7XpEnVY1W9G5voqSVIqowT2wus473WBW7nVafIka2G1jE1ZZHW0kwOVFBGvMt+U2jBf1nu7WxN1RJNiQa+gvF9d93K+y3Wf0fT0GoJ+Q9uP5EGy8e+2hD9NSowe32SculUvy9+VfO63e/nRPzEF/KXw7+AWzN1redu1nRrLT1XQeuPiiTL1ZPBijY3eZoWujJXb91YJjApLizqrZpLE6GpQfVLXxWq6kaOg6s5V3kpNu/Y7BmRNgu6Ddo2We25rjbSWprJ5wrVH7MO6dj+tIn+ra3agJqar2C2wP0W67+jaWgeKlFL2EukwfLxMZoQ/TUuMGt61tlc5SwQW7dFdxF186vdXu5sOdcTGWn2CGthCRk6elU7Uy941pW5rAW+iC+be1wLrInAfp3EDgIXgFSfVBvvV9LvG9tP6hEr8VndJw8KrO6G6mqzTuB6XzGVZquqxrYTTmq0ka9gtsD9Fuu/o2lo+bt+r0uorGesfOlgoviOaYHLKtUyOacK3SLF9ZzKX07Zmb2Xle3RngYeIDlrhqBTUu/JSb/wgwLfSb0TeW8E1kRI2hLcpbmkWM0OgboW8fvPsvPIk5VvwXbaRNcG5XBZ1gpciL3FuzTbva3awOa95iuYLXC/xfrvaBpabhVpFL1UEmmofM1PeHgYF/gk2jbpjnEok/fLUflSh9JYmdDkRzOKcer+vCozj0QgQo2E/UDnvOi1wJoI8lvSXBJUvxqWQO+8H73xVGJdSHd/WSvCcFnmCFzq4F3bRTfb8LeiC6Yt98ja+y2mf2e4NNJ0J5GGysdw/zSFRZgSuBqFFtvQd/4bmXfnqyfv8pDqKoGbow3tkQVd8UYisLdu3LBM/Fkn8MBqeN/L+oeE/VSkfPu12zxaEYbLslpgXs933WzD38qQIIOrGnhLbTH9O8OlaaZ7iTRUPs6l+0kQmBK43UvjTXUZyUZxMI8eL1dlEKs7ey8r9an43nyJynEkXcqPCHyt3LraEVhs//EmOldTI9r2m0xXm/5c8wQW38JdM9vwtzIkyOCqBt5SW0z/znBp6ul+Ig2Vj/CBa5vXvO6GKYFpY9CJdTFpM8rQzzM2QpHelQ9H07iekHcEFXJ+7o16PdSRzNkHFkeAxRZwLbAmAiuBtKNISnX/baBpqkYhYoTlWk31mmdMYF1t2rna34MZAmsGsW5t1QbGl3VfwVyB+y2mf6fT0JoS9hNpqHwpn/dUBoghgVlKVjsZbBu6IM2gXz8bNZk3SWCxIykWFEOMxUNd8bN67WbKvFFosesuvuKRUWipBPXpHtII6kDTNI0iVV/XPGMCD41Cdys/XWBWfnYGWj22Q9rJZge9X6L+VzBf4H6L6d/pNLSmhP1EGirfXfQw2p9/zzEh8O09kVKSfXIk3RSUJtvMy2YJzI/Fl82CiRisPPdWw5HOUWgnBzKMFSZvrKqTQROhPTxZaI4D65pGea85VtVvk4GpcrgsvPKiyY/zBa76sITIZ11V29Mjh7j6X8F8gfst1n9H09DdEua6RBopX33yeWisElihOa9VXDZ/kuZTJ1kGp2y/89hk8iSB+6fZcOvYme13vomqlI+Xojl3qTciLlejrY/yliYCP0upPkVKzFUXqrxn/T6pRdSV/dpcGpXVeUUXMXCKhqYsLEPZyN01bYvexhj+nsqqImyXUD2c1YZLlZWPfQX6GvSbt9MUaov139E0tFpC5qImkUbKxz5675bFf4wJ3P6Etp1ZPZ86masL3supAhfyia7NmXM13TEKeYRy4CRl+S1N3vYj3NtB73oupVDdTc8WftCGd2zihOg6ldp529+9fpPpynJra97Mpf52NhEU6vmudbGakzbayqkjFKNfgbYG/eaV6LdY/x1NQysl5FmjSaSR8rGPaLcs/mNK4HP3I/lFZ7K5sIZf+ZOXUwUui96lJu05/0nvRLn2+p26cJp0at5iqfzemasfobkcpr0aST6WcR5ajdgwl/r6/iV74pj20CkamrLUV2JJZWljKBVUKKW93PacJ/bJPakDdlc+9hXoatBvXpl+i2neGb8a6aq2SZNIY+W7kO5WWgiYEDg5viu9nzLip8vGW33xJ/t2juVkgdlFsizJjufG1lvGN6h6J3IwxMWi0tWjmnRq3mJF6XY8/QiPpKkuSJXmuvJR8LYVtFnb9vDtRcHqvGzTMMkGmkxXFt6Mx3fFoTqGUkEFIUezO5gIYcUnzRXZnZWPfQW6GpT9EArdFtO9021o8V9csay0gJxIo+UbPIzhM4sFHkE6IxV4woBpwHUsfGuaixaA6+A78xTz3xq/ODe8fY3AgcCeYvpbq3a0grz0MmQgsKfYERh7wL4BgT3F9LeWKHefBL4AgT0F3xoAHgOBAfAYCAyAx0BgADwGAgPgMRAYAI+BwAB4DAQGwGMgMAAeA4EB8BgIDIDHQGAAPAYCA+AxdgXu3ZAJAGtYTWVXgcAgFKymsqvYFthqeAAaIs01CAzCINJcg8AgDCLNNQgMwiDSXIPAIAwizTUIDMIg0lyDwCAMIs01CAzCINJcg8AgDCLNNQgMwiDSXIPAIAwizbXZtf79Qg+//onpjxdKXz/60230OBsV7ECkuTa31q+Ucfhm0298mr51p6XocTYq2IFIc21mrT/o63f57ycX9YsePsvy80C/1Wk5epyNCnYg0lybWesXyreeKX38+U3/sOlP+qFOy9HjbFSwA5Hm2rJa00PJtpq/xIs3dVqOHmejgh2INNeW1Pr7lXe0BypeMpvlaTl6nI06gR/AMJHm2oJaU0p/i//1a3Vajh5now6zd5YHTKS5Nr/WX69vwmAIPJe9czxoIs21RbX+x7ehIfAs9k7w0Ik015bV+l93vxf7wE/YO73DJ9JcW1hr1tNWI89f0ij0F0ah9eyd3REQaa7NrPVBHAf+oi/s2C8/6PvBdojlaTl6nI3aY+/kjoFIc21mrX/T139sHIv5+l2fffWlTsvR42zULtqE27tQoRFpri07F5r+YtM4F3oa8HYLIs212bXmVx19iuk/bwf68tGfbqPH2agdHNP3b5hEmmu4Htg6u9m7t1LbEmmuQWDrbOvv3h7tRqS5BoFts5m/exu0M5HmGgS2zQb+7u2OE0SaaxDYMrY74L29cYZIcw0CW8amv3s74xSR5hoEtou9DnhFrpsvjANEmmsQ2C6W/I3Z1AEizTUIbBU7HTCs1RBprkFgq1jwF+rqiTTXILBNzPsLdYeINNcgsE2MCwx5B4k01yCwRQz7C3nHiDTXILBFjAoMeceJNNcgsEVs+msmakBEmmsQ2CLmBIa9T4k01yCwPYxtQUPfCUSaaxDYHqYEhr9TiDTXILA9bPhroFiBEmmuQWBrmOmAoe9EIs01CGwNIwLD36lEmmsQ2BbG/TVTrGCJNNcgsC1MCAx9pxNprkFgSxi4kBDd7xwizTUIbAmj/horVcBEmmsQ2BKrBYa/84g01yCwJeDvxkSaaxDYDis7YOz+zibSXIPAdlgnMPSdT6S5BoHtAH+3JtJcg8B2WCMw/F1CpLkGga2wZgsa/i4i0lyDwFZYITD0XUakuQaBrQB/NyfSXIPAVlgsMPxdSqS5BoFtsHgLGv4uJtJcg8A2WCow/F1OpLkGgS0Af3cg0lyDwBZYKDD8XUOkuQaBLbBMYPi7ikhzDQKbZ20HbKNM4RNnrkFgC6zsgK2UKXzizDUIbIFFAsPflcSZaxDYAgv8xf7vauLMNQhsniUdMPxdTZS5BoEtsEBgdMDriTLXILAF4O8uRJlrENgCswWGvyaIMtcgsAXmCgx9jRBlrkFgC8wUGP2vGaLMNQhsnrljWPDXDDHmWgmBzQN/9yHGXCshsHnmCQx/TRFjrpUQ2DyzBIa/xogx10oIbJxZu8Dw1xwR5hoDAhtmjsAYgDZIhLnGgMBmQQe8F/HlGgcCm2VRB2y5THEQX65xILBZlghsuUiREF+ucSCwUeDvbkSXawIIbJQZAsNfs0SXawIIbJTpAmMH2DDR5ZoAAhsF/u5GdLkmgMAmmdwB4wiwcWLLtQoIbJL5AtsvUyzElmsVENgk8Hc/Ysu1CghskokCw18LxJZrFRDYJNMEhr82iC3XKiCwSSYJDH+tEFuuVUBgg0wbw4LAVogs12ogsEHg745Elms1ENggswTepEQREVmu1UBgg0wRGP5aIrJcq4HA5piyCwx/bRFXrjVAYHNMEBg7wNaIK9caILAx4O+uRJVrLRDYGBB4V6LKtRYIbIznAsNfi0SVay0Q2BQzOuCtihQVMeWaBAQ2xfQOeLMiRUVMuSYBgU3xVGD4a5WYck0CAptiqr8Q2A4x5ZoEBDbFE4Hhr2ViyjUJCGwKCLwvMeWaBAQ2xJNdYPhrm4hyTQYCG2JiB7xhiSIjolyT0de6yLMjJYTQY5YXa6LH06jTOuAtSxQZEeWajK7WeUpkjvny6PE06qjA8Nc+EeWaTL/Wl0fXm2T5jb+4vWePl/SyNHo8jTomMHaANyCiXJPp1vqaEJrdlbdu2cPo67Lo0TTq2BgW/N2CeHJNoVtrQs79mYrLwtaJp1HRAe9NPLmm0K31UT9mVZyWRY+mUdEB7008uaaAw0hmmCDwxiWKjXhyTQECm2FYYPi7DfHkmgIENsLIGBb83YZock0FAhsBHfDuRJNrKhDYCIMCw9+tiCbXVJ7Xek3DRNOoQwJjBHozosk1FQhsgqFdYPi7HbHkWgdsQpsAAu9PLLnWAQIbAP46QCS51gUCG+CZwDsUKT4iybUuENgAAwLD3y2JJNe6aGtNVFZEj6JR4a8LxJFrPSDwevQCYwd4W+LItR5Pan1N6fL7ccTSqFqB4e/GxJFrPZ7WOiX3Z7OMRI+iUdEBu0Acudbjaa2vZNmlwCJ6DI2KDtgJosi1PhPOxKIrosfQqKMC71OkGIki1/rgVMrVwF8niCLX+jytdU6SFdFjaFSNwPB3e6LItT7Pap1TsvSesmUkjdoXGDvAOxBFrvV5fhw4XRM9hkYdFnivEkVJFLnW55nA6Yr+N45G7Y9hoQPegxhyTQPOhV4LOmA3iCHXNEDgtQx2wLuVKE5iyDUNEHgtXYHh7z7EkGsaIPBKurvA2AHeiQhyTQcEXklHYPi7FxHkmg4IvA50wK4Qfq5pwamU60AH7Arh55oWCLyOAYH3LFKkhJ9rWrAJvQr46wzB55oeCLwKvcB7lihags81PRB4FarA6IB3JPhc0/O01vfrcUX00BsV/jpD8LmmR1/r+wl3pZyELDBGoHcl+FzTo611QSV9k6vy2ccrpS+/q+kXSl8/+tNt9NAbVSfwviWKluBzTY+21meSFCV9fFS8U6LeVvahL+OVTb+J6bfutBQ98EaVd4HRAe9L6Lk2gLbWKbP2SG6PyTulhfTJL/r6XZb/Heivsvyih8+y/DzQb3Vajh54o6IDdofQc22AgQv6H38u4l46F3KWPjmIW1Q+fC3L3/QPm/6kH+p0N1DAaDrgnUsUL6Hn2gDDAt8IH34utPfUoZRtNX+J6Td1uhsoXKQtaPi7N4Hn2hDDAtctomuYb7YTXPXGJeuN5eleoGCBwA4ReK4NMbAPzPZ7qXioiq5hftL/RC/MYP/laTl62I0Kfx0i8FwbQlvrjA89n/hO8FVzX+hPNoYFgVuBMQK9P4Hn2hDaWt8IvbFbuj/+3hKSdT8W/kLgRmD46wCB59oQ+lpnvDUyfiJH79FIv4W/2Af+0RV47wJFTdi5NshArXO+3XxJCO31vz/rQ0XVyPOXNAr9FdUodC0wOmAXCDvXBplb6+/D4b9q8rcw+YP+Vqfl6CE3Kjpgpwg614aZWet/h0NzrtV3ffbVlzotRw+5Ubsd8N7liZygc22Ybq2PhXa2onrK909aU0Z/LnRH4L2LEztB59ow3VoT3cMIi0vdOlQWuPzzdqAv1R6xPC1FM1tal0AH7BYh59oI3Vpf2bjVXXnrlvWuKZwcPeBGrQSGv44Qcq6N0K/1hT58zfIbf3F7zx4v6dJHFIbcqKq/EHhvQs61EXS1zlPlAcHHXDPPxOgBNyo6YLcIOddG0Ne6yLMjuysHPWa5flRrYvRwGxUdsGMEnGtj4K6UC4G/jhFwro0BgReCDWjHCDjXxoDAC4G/jhFwro0BgReCDWjHCDjXxoDAC4G/jhFwro0BgZeBDWjXCDfXRoHAy0AH7Brh5tooEHgZ6IBdI9xcGwUCLwP+uka4uTYKBF5E0wHvXRBQE2yujQOBF4EO2DmCzbVxIPAS4K97hJprTxio9TnB84FHwAi0e4Saa0/Q15oq1xOuiB5mo6IDdpBAc+0ZA88HpsuvAVaih9mo6IAdJNBce4a21gkx42+ojQp/HWRWruUnto94PN+fz7pqPfYZeTqhiehuVdYQ8NdFZuTavR3h6T23wOR6tgACzwf+usj0XCsoOV7ZjWZuZyoegu0x2lqfyM1Q9BAFRgfsJNNzLWv73Ts1tbe4F9paX039LoUocO3vj70LAhSm5xqV5sx974KHnk54XHYj6G708ATGCLSjTM81ZU7+4vHnlhKSNrdPvp2ofDvW/ESa26XXS6uzvB/X3b91MQP7wDgOPMBfdMCOMj3X+o+8JiQXqZ6K11l9R2Xx8li9zKX1qLPUN2JOV1ZiPhB4HhDYVabn2qXXVzL1bo9dx2pMqzoPIk8IfyTYkb8sHsoWzXrUWTK+OHusydJHICwG50LPovUXAjvGjFzj/WV6ulzre54Twp+HzcanHyIWhFYfJOzljVCx8XziPTdfT2eWeq/6XsXZEAg8C/jrLHNy7VKfK5zm1bLv1QfM0XMzMp2zl1ndrRZcT76eziyELDgjxAwQeA6tvxDYNebl2u1yStozORoB72wvNm0jMWVT1U6+ns4sj53kdY8wWc5QrW8Zq1+arTsgHJjAkr8Q2DUW5NqVPbkvV5ZlU50BoE7gathameXOe/QkM3LoZh4Dtc6a0p1WRQ9K4L8Q2GGW5VrGh63WClzeT2Jy8XM8FzN0HJicWd97O68zOEyB4a+LTM41ZcaiPg4sfagztvNSs7LbhR9t2tpgba3zetyNbxys2C4ISmB0wE4zOddS5ezJyscq329iH/imzl/LQGi9QKo/2fiabj4MPXAudPs7clnTBQcp8A8I7CKTc+0in27Bje2MQmfqiR7NKHTOVeDr6cxCSXtAanbB1zFwIkc7olbwn52l0QMSGP66zZxzoVv7Uq4uqZL8TsWB37qP5mdK32oD0nbAqzNL4/PNjR64f7Lo0ujhCfwDArvJ9Fy7ssEmPsRzoaI3ZkPIjz3FvDoTK3vsyj66sPvjP5vtSJKHrfe0nrc/y2NP+sS2sx8B3o1XbJwJPTAEZvyFwG4zI9du7QX9p2rZnMonPzcHYUQ3m8onOnfOhRaz5PWr+TcIWAn2gacBf11nwS110uoCI7ZscXrY3IxuXdmlRum57sfy46OLvqjrUWe5s/Mm6MnQdfQzmDAKveIaqWAE/guBXSfSLUV9yU84Dqyi+guBHQQCy5xwJpYMOmD3gcAKtyzFudA17V04ILCzQGAb0f1tGJmOvxDYRSCwjej+NoxEexcsCOwuYeTabCDwc7oC710eoCOMXJtNt9b9i6Ui3TRpaf2FwA4TRK7NBwI/Q/IXAjtMCLm2AGxCP+FvrwOGwE4SQK4tAQI/od8BQ2AnCSDXlgCBx0EH7Av+59oinl5OGPn1wOiAfcH/XFsErgceReMvBHYT73NtGU8FziFw9SAz+Os03ufaMrq1vpAeEV8P/BcCe4PvubaQXq3Tjr404ssJFX9xENhtPM+1pTzfB14V3etG/YsO2CP8zrXFQOBhdB0wBHYVv3NtMTgOPMhfbEH7hNe5tpyntb5fjyui+9yoqr8Q2HG8zrXl6Gt9P8njWCuie9yoWn8hsLP4nGsr0Na6oJK+SZzPRur4C4Fdx+NcW4O21meSFCV9fFS8r7qrrMeN+lcv8J5FAqNYyDV6vDS3V74cq1OKaXNucd3DZYW0/vfmmeHaYuVih/TCjtYeq6c43I7Vgx3K43zZtLXmD4E58sdK3Cld8eRxbwXu+QuBXcdCrklPWsjqXcm8eV5De9k8V0R8fuOL3IsyScviXv9vIt7FM0/qky3SahEGm6kg7axTy6gveMnOyeK3or+Q89yYnUA+MtABQ2B3sSJwWve2NK3in0hWn5tYvXNPuebiQd/i6UopSZPk8af+30RM+Q9CRlK2X3oVCx6ZaJfqqUzSgxMnllFf8JL9MPCQBZkdsxPIQ4Y6YAjsLjNy7YceTcj36unY18eUiP/YgKadreNCfm4wt6W4sQe1XIv6fx3wnVRb20V3wepvMfvhaCMnctQljnAUGv76hxWBi2obOiPVQ/7eH29klWXNGqv7UPHnGIp3cpJlbEu7/l+RpOqCHPF7UO1Zp3MfTzqwD1zwwPf+2mZG91Pgnr8Q2H2sCFxW29A0reKnjy75qj6n8LFjm4hX5+aZYufH1uvx3P4XXKuHBlab0BVnsQkt5rqQmQd9tLUWPxriGYXXNY8s9lvg9o3Brxg4gx2B37kK+aPP5fHFRi8l8rjztd4Hzp9duZeR6kEnRzYGfamfenJmR20ry29zH1CqrfWN0Bt/RuGNPUp1xSNP/RQYHbCP2BG44E6eHsby+O/chmobuh2Fbl+N7sKmzXO3rxmTlvLe9sqfVpwKnWcPOelrnfHSZm3pFuKlwH1/IbAH2BH4IR2bSKv49ZPBE/GxOBZ0rmYm+YmMHgdSiljkD7+ubBM3vfOh7Ovcaoj59W/nvISXhNBVjxz3UeD+CDQOAvuAJYHZNjTbguYv7k2ne++tkR8eTkd3OLtFvLEfhkR0ywXRDXA9B1cjdUEH7CdWjgOXfBuabUHzF+fmqNK5t8b6OPDIbnBzXKeQ3uicsmVE4CybfULIQHT/BB7ugCGw01gSmO248s6RvUia8zqS3hrFq+vYbnC1D3yqBqMfHTqtjyLVd381sw/c/kSsxGOB5ffgrwfYEvidHLmTjxc36czKm17g8tIcSuqTiQ78RsiJDVnlCTM54y+q07kePwAmRqEjviOHzl8I7AO2BC6I6M8eL7LmIC33TCvwo38d7EOv1cGivN6T5uc6ptIJ1c1G+vQy6t7MZp/QNRTdV4GV97AF7QO2BK5Pj3y8oO0RGTapF7gcOfBanYlVFhmz9lSdonVOHvpWe61mzsR6/Iqcb9oP5kb3TeCRDhgCu40PuZY/u9roPvvq3YFNaIWZIZVAy5fdA62/2IL2Ai9yLX2yh2vsaqQ4BdaNQJcQ2A+8yLX7+PCwqeuBjeFFozaM+guBHcePXMtHz5Y+GbojhzH8aNQaCOwzfuWaMSBww4C/2IL2A69yzRxPjwPH83zgAX8hsB94lWvmeH4iRyyDWOP+QmDX8SnXDPJU4FieDzzkLwT2BI9yzSTdWsf6fOChHWD46wv+5JpRerWO9PnA6IB9x59cMwouZuA864AhsPN4k2tmgcAcdMDe402umQXHgRmD/kJgb/Al1wwDgRmD/uIgsDdYyLUVDzdTX3Xvm1OjedRZ0V6AMOlRZwO1PifSONaEMEPR/RAYHXAAWLkeeOHDzdRXsx51lrfSTbq0QV9r+fnA4Qs87C8E9gcrAi98uJn6atajzuSbaUy5uFBb6zOha54KLEX3QeDBEegSW9AeMSPX/urRhFz4cDP11axHnSVStzvlUWfaWiernuotR/dJYN1nENgbrAi89OFm6qsZjzpTLz2YcIMdHEZ63gFDYB+wIvDSh+qlZ8MAABHMSURBVJupr2Y86iwnx0tCkuq+sxMedRa9wGP+QmCPsCPw0oebLX3UWSYPaE151Jm21idi5JZ2Xgms/RD++oMdgZc+3Ex9pUX7qLOE97n3VPTOE27zrq31tRpKW437Ak/wFwJ7gR2Blz7cjCx81FnFvdp9fl4p/QwZOc68v/RAdAgMNsKSwAsfbrb0UWedDxcK3Lkg6VmM6WV0DvgbDJZu7L7w4Wbqq7ECq4866334tIz60JEIPOovBPYKW09mWPZwM/WVloFHnRViQW7+0n1gYzgu8OgINK4k9AtbAi97uJn6SsvAo86ORfu47wmPOoPA6IDDwJbAyx5upr7SMvqoMyHuhEedxSzweAcMgf3ClsDLHm6mvtKjf9TZJSHNEPLSM7Ee3LJEXNK06oiwHwIPfAx/vcLtXNNh5FFnA7U+1aNXZNVp0U436iR/IbAvOJ1rekw86kxf6yNJctEiORl/HNOT6C436ri/ENgznM41PSYedaatdU7aUfKMnHWzTMPlRn3SAWML2jNczrUhDDzqTFvrI99uFi1yf34oaiS6u406zV8I7A0O55pNRq5GmnwyyEh0Zxv1yQg0BPYOd3PNKpEK/NRfbEH7hrO5ZhdtrakkcJhPJ4TAweFsrtll4Hrgdh/4EuKzkab6C4H9wdVcs4y21jd+o8z6MNKKCwtdbdSn/kJg73A11ywzdD0w5ceBbxl5fjr1WHQ3GxX+BoijuWabgVqfm2sJ1/jraKM+9xcC+4ebuWadoVoXZ3aCdZqtuzmWk436fAcY/nqIk7lmnwivRkIHHCRO5pp94hN4QgeMY0ge4mKubcBArYuMX4lIJ52OORLdwUZFBxwmLubaBuhrnZP6ZKw1Z0I72agT/IXAPuJgrm2BttZ3Qk7iQqc8XWWwg406wV9sQfuIg7m2BdpaZ9LBo7S+ad6i6M41KjrgUHEv1zZh4Fzo9kLj++jNqZ9Fd61Rp/gLgb3EuVzbhpGrkXQv5kZ3rFGnjEBjC9pPXMu1jVgi8K/6+qSPF0pfP/rTI8vuyjR/IbCXOJZrWzFyNZIg7z3o7E99d803ynnrTkvR3WrUOR0wBPYMx3JtKwbuidXeTz7p3pbyJ60E/qKHz7L8PNBvdVqO7lSjzuqAIbBnuJVrmzF0V0p6YQrfL7RzGOnjQH9WAv+mf9i/T/qhTsvRnWpU+BsybuXaZgzU+kiU5z200JfP+gb1b/RLvPWmTsvRXWrUaf5CYE9xKte2Y/jJDPqrkR4byrXAh2pXmB7UaTm6Q40Kf8PGpVzbkCW1rgSux7LYf3laju5Oo07cAYbAvuJQrm1JdAI/mQ3++opDubYlsQiMDjh03Mm1TRm6pU5CWrof+rgPPNFfnMThLe7k2qboa00JeS5wNfL8JY1Cf7k6Cj3PXwjsIc7k2rZoa31mN6UcpjkOzA/6ftDf6rQc3ZVGnegvBPYXZ3JtW7S17p19pVIJ/F2fffWlTsvRHWnUqR0wtqD9xZVc25jnFzP08e5c6Mn+QmB/cSTXtmaNwOWftwN9+ehPTw20EVNHoLEF7TNu5NrmDFyNtO520G10Fxp1ur8Q2GOcyLXt0db62ruEcGl0FxoVHXAUOJFr2zP0bKTjikeaSdEdaFR0wHHgQq7twMA+8Ohx4BnRHWhU+BsHLuTaDgQv8HR/IbDXOJBrexD6o1Xgbyzsn2u7ELjAM3aAIbDf7J5r+xCJwFPmhb9es3uu7cPwHTmSAJ4PjA44HvbOtZ0YqHXWjGCdVkXft1Hn+AuBPQcCSzz8PbO+93ZeZ7AjAk+aGf76DQRuke4LfadkxSkd+zbqAn8hsLdA4JaT9ETCy5ouGAKDrYDA0pvS0wkLQnWzTIy+Z6PC36iAwNKbITydcJa/ENh7ILD0ptID+ynwrBFo+Os/ELglhH1gdMCRAYFb1FHo0ftjPYm+W6OiA44NCCxx8v44MDrg2IDAMifPz8Sa5y9O4ggACKww9HTCmdF3atRF/kJgr4HANqLv06jzdoAhcBBAYBvRd2nUuf5iCzoEIHBNkWXV1Pm08vayfgiMDjgEIHDFlTYnTyZk5f1ld2nUhR0wBPYbCCy4E5LW/W5xfrxYFX1PgafOD3+DAAILEpJJr+7Uu+PAC/2FwJ4DgTk5SZTXjw55xX7wjgJPnh/+hgEE5pzIu/pGpvTIc6Nv36jogCMFAnMSclffuK7ZC96+Uef6iw44FCCweN1rBq8uJ5w9Ag2BQwECi9deCwx/4wUCi9cQGHgJBOYcu4POd4/2gef7i7MogwECc87krL7h0x05lvoLgQMAAnN6N6FM/Lkjx3x/IXA4QGDBST3um3VO7JgZfctGhb9RA4EFBZUNzkj3uPC86Bs26oIdYAgcEBC44k4J5TfEKm/nx+SKDeh9BJ6xCM7CCggIXFMcmxtikWPR/3xO9O0aFR1w5EDglvuZOUyP7+v03bJR4W/sQGAb0TcXeM4yEDgkILCN6Fs1KvyNHghsI/pGjbpkAxoChwUEthF9m0aFvwACW4m+rcCzFoLAYQGBbUTfpFHXdMAQOBQgsI3oWzQq/AUlBLYTfUuBZy0EgUMDAtuIvkGjwl/AgMA2ottv1EUb0BA4PCCwjejWGxX+AgEEthF9M4HnLQV/wwMC24huu1GXdcAQOEAgsI3oWwk8byn4GyAQ2EZ0y426yl8IHBQQ2EZ0u+HhL2iAwDaiWw2/bgcYAocFBLYR3Wb4lf5C4LCAwDaiOyywnUKBvYDANqJbDL/QXwxBBwoEthF9A4FnLgZ/AwUC24huL/xCfyFwqEBgG9GthYe/QAUC24jumsAYwQoWCGwjuq3wK/2FwOEBgW1EtxR+5Qg0/A0QCGwjup3wa/2FwAECgW1Etyvw3OXgb8BAYBvRrYTHBjToA4FtRLcRfqm/OIQUNBDYRnSbAs9dDh1w0EBgG9EthIe/QAcEthHdfHiMQAMtENhGdOPh1+4Aw99QgcA2opsOv9pfCBwqENhGdOcENlwe4AwQ2EZ0w+HhLxgCAtuIbkng2QvC3+CBwDaimw2/1l8IHDAQ2EZ0o+HhLxgGAtuIbjI8RqDBCBDYRnSD4eEvGAMC24gOgcFGQGAb0c2Fh79gFAhsI7qx8Iv9xQhWJEBgG9FNhYe/4AkQ2EZ0Q+HhL3gGBLYRfW+BsQMcDRDYRnQz4eEveAoEthHdSPj1/kLg8IHANqIbFXj2gvA3IiCwjegmwsNfMAEIbCO6gfDYAQZTgMA2oq8PD3/BJCCwjeirw8NfMA0IbCP62vB/lwqMAejYgMA2ohsTeO6C8Dc2ILCN6CvDw18wFQhsI/q68PAXTAYC24i+Kjz8BdOBwDairwkPf8EMILCN6CvCYwAazAEC24i+PDz8BbOAwDaiGxB45nLwN1IgsI3oi8PDXzAPCGwj+tLwC/39AX+jBQLbiL4s/NL9X/gbMRDYRvSVAs9bDP7GDAS2EX1R+IUdMPyNGghsI/qS8Mv8/QF/4wYC24i+IPxqf+evEgQABLYRfXZ4bD6DZUBgG9Hnhv+L/hcsAwLbiD4z/DJ/sfsLILCd6PPCr/Z3XulASEBgG9HnhP8Lf8FyILCN6DPCY/MZrAEC24g+Pfwif3/AX1ABgW1Enxx+ib/QF7RAYBvRJ4Zfsvv7A/4CCQhsI/q08Ku7X/gLILCN6FPCL+h+f/yAv0AFAtuI/jz83/n+Ql/QBwLbiP4s/N/Z/nbthb6AA4FtRB8Pb0Bf+AsEENhG9LHwf2f625cX9oIGCLyOjxdKXz+60QfD/+0yGlzjLvwFChB4FW+U89aJrgvfc3fM3gF1oS/oAIHX8EUPn2X5eaDfavROeI27Wn9HtIW9QAsEXsNv+of9+6TqRjQhA8rKPLcV+oKnQOA1vNEv/r+zDT1BYNgLjACB13Cg4j89qNGfCQx9gSEg8BooVf/X0UcFhrzAHBB4DQsEhrvAJBB4DfMEhrrAOBB4DZP3gaEtsAMEXkM1Cv3VG4U2Ex6AZ0Saa8aOA/MDwB/0txo9zkYFOxBprhmq9Xd9JtaXGj3ORgU7EGmu7XAuNAAWiDTXjNX6z9uBvky/GgkAs0Saa7vfUgcAI0SaaxAYhEGkuQaBQRhEmmsQGIRBpLkGgUEYRJprEBiEQaS5BoFBGESaaxAYhEGkuQaBQRhEmmsQGIRBpLkGgUEYRJprtgUGYCusprKrQGAQClZT2VXirDUAgQCBAfAYCAyAx0BgADwGAgPgMRAYAI+BwAB4DAQGwGMgMAAeA4EB8BgIDIDHQGAAPAYCA+AxFgX+eKH0tfuwFbv8qp8vLq97i3J8vFL68nufdf9+oYdf//ZZN+OT7rPuf+JxXHSXlTuDPYH1jzuzyp/q21TWvUU5XsU6Xvdb9+F7j3UzvqtG33zdn5LAe1TcDawJ/FU/cPTb1hp6/Kx/juV1b1GOX/T1Ef2/A/21/bo/2Lr//eT5uvW6OS+i0bdf9y/6p57cpeJuYE3g36J5P+lW2zIfB/qzElhe9xblODS/G9uv+4XyrWde863XzXg7iEbfft0vraJ7VNwRrAn8Vj3re7NNGfryWTZbc+26tywHW/1O62a/HXus+4N+1huxG6/7H6+yYK8v3AGsCVz1SqXUzHb5LMtaYHndG5bjm+0E77Lu71fe32y/7v8eew2i0Tdf9yd9+3ipHkm90xfuAtYErseT6v+bUK1MXveG5fhJ/9tn3Y99/9/yejZb97/Da72Gzdf9i7Yjhzt94S4AgY3xycaw9lj31+ubMHjzdb+y3dCdBH5hP5fVtgcENk90Agt/d8qlf7vksRgH3kngim/6AoFtsMuuyI77wL+Fv3vtjv3rrm+LddOGHXdDd135/tgehf7adDBQHYX+kgYlbZfjZ33UYod1c6QR8M3WLQu8V713qbhDWDwOzDP6g/62tQYNzXHgdt2blOP7cPivmtx63QdxHPiLbUluXm9OfRx443VXFf+P/tyr4k5gTeDv+oSYL1tr0FAJLK97i3L8Oxyacwq2Xvdv+vqPjWOxtN163QLR6Juv+xd9+8cHsf7bq+JOENS50M3Axcanxv6UNiX3Og/7V3d9m7X/XudC715xJ7B4NdKft0N1nH0zmpFHed32yyHvC2697urim8/++rZq/7rRN183q/jbfzut3BVwPTAAHgOBAfAYCAyAx0BgADwGAgPgMRAYAI+BwAB4DAQGwGMgMAAeA4EB8BgIbByiwN9YEuZKjnMXOZLrkjUBj4HAxjEkcEKKuYsUJFmyJuAxENgSy6xtuZDL/IXOSxYCPgOBLbFW4GW3dIrkRlCgAQJbYqXAOcmWLJaRfNVqgW9AYEtIAovJx99bSkh6e9j5+H+6V5/eTpSQY9e7lFSf37LHzCQ9qzvETfTO78SdpKYqALwAAltCI3AuhrVuGf9HhaFZNdilDjk3w1H1x/Xs3ejdjn7B0BfwGQhsCY3A5FSURUoSkhWsM+bbyGdCWeebJ+QkL11vQeePjwvN54MCYxs6MiCwJTQC8072SoSKV97HFoRWPWZCbtLStYfNu4Vq6qDAC/edga9AYEtoBL5Wr27tu+emw1TNOyo6d+KVIwLf5p/+AXwGAltCN4hV9v6n0lzySRhU+V5ulyOdKHBJcCApKiCwJaYJ3D1pq790zgapux+PCYxvNCrwdVvCkMB8FPp4uU3dhIbAkYGv2xJTBR5f+kLo5d6NV0JgUIOv2xJT94G7g1WCeh949ig09oEjAwJbYprA2cBRn6M8VM141wt8xSh05EBgS0wT+Ebq40i5Yl5G3vl/Wol874xCp9ViaVfgdxwHjgsIbIlpArNBqkvxEDQjysZ0fVQ4I8n1sf18YSPR8rmUF34C1zWlXYFxJlZkQGBLTBS4PdlZEa+od2WrY0g0T/h5IE3UtFpIjc3mx7nQUQGBLTFV4PLKDvR2rzZqT8XKEvGpuMNOG/WSEHq6d2JjFzg6ILCb4HpgMAkI7CiLtoULHESKDQjsKIvuibVoIeAzENhVcFdKMAEI7CpX9RL+KZxwX+jogMAAeAwEBsBjIDAAHgOBAfAYCAyAx0BgADwGAgPgMRAYAI+BwAB4DAQGwGMgMAAeA4EB8BgIDIDH/A8qHSmKSGvfMwAAAABJRU5ErkJggg==", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 300, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 8, repr.plot.height = 5)\n", + "colors <- c(\n", + " `MAPKK** (S5)` = \"#EE7733\",\n", + " `MAPK** (S8)` = \"#0077BB\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(linewidth = 2) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 500, 100),\n", + " minor_breaks = seq(0, 500, 50),\n", + " limits = c(0, 500),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 500), clip = \"on\") +\n", + " labs(\n", + " title = \"Dynamics of Model without Explicit Feedback\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "id": "7334152c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all85
pos05
neg80
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 8 & 5\\\\\n", + "\tpos & 0 & 5\\\\\n", + "\tneg & 8 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 8 | 5 |\n", + "| pos | 0 | 5 |\n", + "| neg | 8 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 8 5 \n", + "pos 0 5 \n", + "neg 8 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab <- find_loops_vset(model_mapk_simple_wo_feedback,vset=list(sol[dim(sol)[1],2:9]),t=1,klin=klin,kn=kn,n1=n1)\n", + "loop_summary(res_tab$loop_rep[[1]])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/model_6_calcium_oscillations_R.ipynb b/examples/model_6_calcium_oscillations_R.ipynb new file mode 100644 index 0000000..aad6932 --- /dev/null +++ b/examples/model_6_calcium_oscillations_R.ipynb @@ -0,0 +1,3491 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5c5107a0", + "metadata": {}, + "source": [ + "## **0. Initialization**" + ] + }, + { + "cell_type": "markdown", + "id": "0aa853b2", + "metadata": {}, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad430870", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2d7c70f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c741284", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\Rtmpk1kCL5\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1d32152b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")\n", + "library(deSolve)\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3eb6dbbb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "colors <- c('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB')" + ] + }, + { + "cell_type": "markdown", + "id": "de63ff1e", + "metadata": {}, + "source": [ + "## **1. Model definition**" + ] + }, + { + "cell_type": "markdown", + "id": "8ebe4f73", + "metadata": {}, + "source": [ + "#### **Example 6: Calcium oscillations model**" + ] + }, + { + "cell_type": "markdown", + "id": "ed0a97ed", + "metadata": {}, + "source": [ + "The reactions (flows) constituting the model are given by\n", + "$$\n", + "\\begin{aligned}\n", + "\\nu_1 &= k_1,\\\\[6pt]\n", + "\\nu_2 &= k_2,\\\\[6pt]\n", + "\\nu_3 &= k_3 \\cdot \\frac{S_1^{n_1}}{kn_1^{\\,n_1} + S_1^{n_1}},\\\\[10pt]\n", + "\\nu_4 &= k_4 \\cdot \n", + " \\frac{S_2^{n_2}}{kn_2^{\\,n_2} + S_2^{n_2}} \\cdot\n", + " \\frac{S_1^{n_3}}{kn_3^{\\,n_3} + S_1^{n_3}},\\\\[10pt]\n", + "\\nu_5 &= k_5 \\cdot S_2,\\\\[6pt]\n", + "\\nu_6 &= k_6 \\cdot S_1.\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "The model is composed from these six reactions by\n", + "$$\n", + "\\begin{aligned}\n", + "\\frac{dS_1}{dt} &= \\nu_1 + \\nu_2 - \\nu_3 + \\nu_4 + \\nu_5 - \\nu_6,\\\\[6pt]\n", + "\\frac{dS_2}{dt} &= \\nu_3 - \\nu_4 - \\nu_5.\n", + "\\end{aligned}\n", + "$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0a5aff3a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "model_calcium_oscillation <- function(t, y, klin, kn, n0) {\n", + " # Unpack state variables\n", + " S1 <- y[1]\n", + " S2 <- y[2]\n", + "\n", + " # Kinetic parameters\n", + " k1 <- klin[1]; k2 <- klin[2]; k3 <- klin[3]\n", + " k4 <- klin[4]; k5 <- klin[5]; k6 <- klin[6]\n", + "\n", + " # Saturation constants\n", + " kn1 <- kn[1]; kn2 <- kn[2]; kn3 <- kn[3]\n", + "\n", + " # Hill exponents\n", + " n1 <- n0[1]; n2 <- n0[2]; n3 <- n0[3]\n", + "\n", + " # Reaction rates\n", + " v1 <- k1\n", + " v2 <- k2\n", + " v3 <- k3 * (S1^n1) / (kn1^n1 + S1^n1)\n", + " v4 <- k4 *\n", + " (S2^n2) / (kn2^n2 + S2^n2) *\n", + " (S1^n3) / (kn3^n3 + S1^n3)\n", + " v5 <- k5 * S2\n", + " v6 <- k6 * S1\n", + "\n", + " # ODEs\n", + " dS1 <- v1 + v2 - v3 + v4 + v5 - v6\n", + " dS2 <- v3 - v4 - v5\n", + "\n", + " dx = rep(0, 2)\n", + " dx[1] = dS1\n", + " dx[2] = dS2\n", + " return(dx)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "44e7e155", + "metadata": {}, + "source": [ + "## **2. Result reproduction**" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4e5b9062", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Parameters from supplementary material\n", + "initial_conditions_calcium <- c(0.3920, 1.6456)\n", + "klin_calcium <- c(1, 7.3 * 0.4, 65, 500, 1, 10) # Fix k2 to 40% of original value as the new params from Prof. Baum\n", + "kn_calcium <- c(1, 2, 0.9)\n", + "n_calcium <- c(2, 2, 4)\n", + "time_points <- seq(0, 3, length.out = 301)\n", + "\n", + "# Additional variables \n", + "all_labels <- c(\"S1\", \"S2\")" + ] + }, + { + "cell_type": "markdown", + "id": "b927c538", + "metadata": {}, + "source": [ + "### **2.1. Reduced Calcium Oscillations Model**" + ] + }, + { + "cell_type": "markdown", + "id": "b9c9522a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "#### **2.1.1. Loop structure (at first)**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "6c2540e5", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11 1
2, 21-1
1, 2, 12-1
\n" + ], + "text/latex": [ + "A data.frame: 3 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & 1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | 1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | -1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 1 \n", + "2 2, 2 1 -1 \n", + "3 1, 2, 1 2 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# compute loops\n", + "res_tab <- find_loops_vset(model_calcium_oscillation,vset=list(initial_conditions_calcium),t=1,klin=klin_calcium,kn=kn_calcium,n0=n_calcium)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]] \n", + "# To access a specific loop representation: e.g., the sixth loop, add [6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "3d056cc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all21
pos10
neg11
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 2 & 1\\\\\n", + "\tpos & 1 & 0\\\\\n", + "\tneg & 1 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 2 | 1 |\n", + "| pos | 1 | 0 |\n", + "| neg | 1 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 2 1 \n", + "pos 1 0 \n", + "neg 1 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e9a5ecf2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 2 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
31, 2, 12-1
\n" + ], + "text/latex": [ + "A data.frame: 2 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t3 & 1, 2, 1 & 2 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 2 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 3 | 1, 2, 1 | 2 | -1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "3 1, 2, 1 2 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2 \n", + "# Return all loops from loop_list containing node 2\n", + "loop_list <- res_tab$loop_rep[[1]]\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "9f0fc026", + "metadata": {}, + "source": [ + "#### **2.1.2. Calculating the Jacobian matrix**\n", + "\n", + "Sign jacobian matrix can be access via `res_tab` variable that we have calculated above, or derived from a jacobian matrix at a specific state" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "05e68bc3", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 2 × 2 of type dbl
1 1
-1-1
\n" + ], + "text/latex": [ + "A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t 1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| 1 | 1 |\n", + "| -1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2]\n", + "[1,] 1 1 \n", + "[2,] -1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix (at initialization point)\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "markdown", + "id": "b4802333", + "metadata": {}, + "source": [ + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003]." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "adbc93e2", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
1
0.310611331644207
2
1.87644941000528
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[1] 0.310611331644207\n", + "\\item[2] 1.87644941000528\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "1\n", + ": 0.3106113316442072\n", + ": 1.87644941000528\n", + "\n" + ], + "text/plain": [ + " 1 2 \n", + "0.3106113 1.8764494 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "func_list <- function(t,x,klin,kn,n0){list(model_calcium_oscillation(t,x,klin,kn,n0))}\n", + "sol <- deSolve::ode(y = initial_conditions_calcium, times = time_points, func = func_list, \n", + " parms=klin_calcium, kn=kn_calcium, n0=n_calcium)\n", + " \n", + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star_end" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "1d134ecb", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 2 × 2 of type dbl
-2.007491 2.856177
-7.992509-2.856177
\n" + ], + "text/latex": [ + "A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -2.007491 & 2.856177\\\\\n", + "\t -7.992509 & -2.856177\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -2.007491 | 2.856177 |\n", + "| -7.992509 | -2.856177 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] \n", + "[1,] -2.007491 2.856177\n", + "[2,] -7.992509 -2.856177" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "j_matrix <- numDeriv::jacobian(model_calcium_oscillation, s_star_end,method=\"complex\",\n", + " t=3650,klin=klin_calcium, kn=kn_calcium, n0=n_calcium)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d9a4b8c8", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 2 × 2 of type dbl
-1 1
-1-1
\n" + ], + "text/latex": [ + "A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -1 | 1 |\n", + "| -1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2]\n", + "[1,] -1 1 \n", + "[2,] -1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "9fb5ce0e", + "metadata": {}, + "source": [ + "#### **2.1.3. Temporal dynamics**" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "b6906e49", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol <- deSolve::ode(y = initial_conditions_calcium, times = seq(0,2.64,0.01), func = func_list, \n", + " parms=klin_calcium, kn=kn_calcium, n0=n_calcium)\n", + "\n", + "s_star_end <- sol[dim(sol)[1],2:dim(sol)[2]]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "20cd5293", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol <- deSolve::ode(y = s_star_end, times = seq(0,3,0.001), func = func_list, \n", + " parms=klin_calcium, kn=kn_calcium, n0=n_calcium)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "cf1a9580", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 420, + "width": 420 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "matplot(\n", + " sol[,1], sol[,2:dim(sol)[2]],\n", + " type = \"l\",\n", + " lty = 1,\n", + " xlab = \"Time\",\n", + " ylab = \"Concentration\",\n", + ")\n", + "\n", + "legend(\n", + " \"topright\",\n", + " legend = all_labels,\n", + " col = 1:8,\n", + " lty = 1\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "76f56970", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
  1. 'time'
  2. 'S1'
  3. 'S2'
\n" + ], + "text/latex": [ + "\\begin{enumerate*}\n", + "\\item 'time'\n", + "\\item 'S1'\n", + "\\item 'S2'\n", + "\\end{enumerate*}\n" + ], + "text/markdown": [ + "1. 'time'\n", + "2. 'S1'\n", + "3. 'S2'\n", + "\n", + "\n" + ], + "text/plain": [ + "[1] \"time\" \"S1\" \"S2\" " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "c(\"time\", all_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "01a98770", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
  1. 'S1'
  2. 'S2'
\n" + ], + "text/latex": [ + "\\begin{enumerate*}\n", + "\\item 'S1'\n", + "\\item 'S2'\n", + "\\end{enumerate*}\n" + ], + "text/markdown": [ + "1. 'S1'\n", + "2. 'S2'\n", + "\n", + "\n" + ], + "text/plain": [ + "[1] \"S1\" \"S2\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "all_of(all_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "1f18ff68", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_for_plot <- as.data.frame(sol)\n", + "\n", + "# rename columns for clarity (use time + investigate_label)\n", + "colnames(sol_for_plot) <- c(\"time\", all_labels)\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = all_of(all_labels), names_to = \"species\", values_to = \"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "273651c0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 840 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "options(repr.plot.width = 14, repr.plot.height = 6)\n", + "colors <- c(\n", + " `S1` = \"#EE7733\",\n", + " `S2` = \"#0077BB\"\n", + ")\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(linewidth = 2) +\n", + " scale_colour_manual(values = colors) + # scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 3, 0.5),\n", + " minor_breaks = seq(0, 3, 0.1),\n", + " limits = c(0, 3),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 3), clip = \"on\") +\n", + " labs(\n", + " title = \"Dynamics of the Calcium Oscillation Model\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " # panel.grid.minor = element_blank(),\n", + " panel.grid = element_blank(),\n", + "\n", + " ## black outer box\n", + " panel.border = element_rect(\n", + " colour = \"black\",\n", + " fill = NA,\n", + " linewidth = 1.1\n", + " )\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "a506b026", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "sol_list <- lapply(1:nrow(sol), function(i) as.numeric(sol[i, 2:3]))\n", + "res_tab_all <- find_loops_vset(model_calcium_oscillation,vset=sol_list,t=1,klin=klin_calcium,kn=kn_calcium,n0=n_calcium)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "ec8b3250", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\t
$loop_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A data.frame: 3 × 3
    looplengthsign
    <I<list>><dbl><dbl>
    1, 11-1
    2, 21-1
    1, 2, 12 1
    \n", + "
  2. \n", + "\t
  3. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A data.frame: 3 × 3
    looplengthsign
    <I<list>><dbl><dbl>
    1, 11-1
    2, 21-1
    1, 2, 12-1
    \n", + "
  4. \n", + "\t
  5. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
    A data.frame: 3 × 3
    looplengthsign
    <I<list>><dbl><dbl>
    1, 11 1
    2, 21-1
    1, 2, 12-1
    \n", + "
  6. \n", + "
\n", + "
\n", + "\t
$loop_rep_index
\n", + "\t\t
\n", + "
  1. 1
  2. 1
  3. 1
  4. 1
  5. 1
  6. 1
  7. 1
  8. 1
  9. 1
  10. 1
  11. 1
  12. 1
  13. 1
  14. 1
  15. 1
  16. 1
  17. 1
  18. 1
  19. 1
  20. 1
  21. 1
  22. 1
  23. 1
  24. 1
  25. 1
  26. 1
  27. 1
  28. 1
  29. 1
  30. 1
  31. 1
  32. 1
  33. 1
  34. 1
  35. 1
  36. 1
  37. 1
  38. 1
  39. 1
  40. 1
  41. 1
  42. 1
  43. 1
  44. 1
  45. 1
  46. 1
  47. 1
  48. 1
  49. 1
  50. 1
  51. 1
  52. 1
  53. 1
  54. 1
  55. 1
  56. 1
  57. 1
  58. 1
  59. 1
  60. 1
  61. 1
  62. 1
  63. 1
  64. 1
  65. 1
  66. 1
  67. 1
  68. 1
  69. 1
  70. 1
  71. 1
  72. 1
  73. 1
  74. 1
  75. 1
  76. 1
  77. 1
  78. 1
  79. 1
  80. 1
  81. 1
  82. 1
  83. 1
  84. 1
  85. 1
  86. 1
  87. 1
  88. 1
  89. 1
  90. 1
  91. 1
  92. 1
  93. 1
  94. 1
  95. 1
  96. 1
  97. 1
  98. 1
  99. 1
  100. 1
  101. 1
  102. 1
  103. 1
  104. 1
  105. 1
  106. 1
  107. 1
  108. 1
  109. 1
  110. 1
  111. 1
  112. 1
  113. 1
  114. 1
  115. 1
  116. 1
  117. 1
  118. 1
  119. 1
  120. 1
  121. 1
  122. 1
  123. 1
  124. 1
  125. 1
  126. 1
  127. 1
  128. 1
  129. 1
  130. 1
  131. 1
  132. 1
  133. 1
  134. 1
  135. 1
  136. 1
  137. 1
  138. 1
  139. 1
  140. 1
  141. 1
  142. 1
  143. 1
  144. 1
  145. 1
  146. 1
  147. 1
  148. 1
  149. 1
  150. 1
  151. 1
  152. 1
  153. 1
  154. 1
  155. 1
  156. 1
  157. 1
  158. 1
  159. 1
  160. 1
  161. 1
  162. 1
  163. 1
  164. 1
  165. 1
  166. 1
  167. 1
  168. 1
  169. 1
  170. 1
  171. 1
  172. 1
  173. 1
  174. 1
  175. 1
  176. 1
  177. 1
  178. 1
  179. 1
  180. 1
  181. 1
  182. 1
  183. 1
  184. 1
  185. 1
  186. 1
  187. 1
  188. 1
  189. 1
  190. 1
  191. 1
  192. 1
  193. 1
  194. 1
  195. 1
  196. 1
  197. 1
  198. 1
  199. 1
  200. 1
  201. 3
  202. 2
  203. 2
  204. 2
  205. 2
  206. 2
  207. 2
  208. 2
  209. 2
  210. 2
  211. 2
  212. 2
  213. 2
  214. 1
  215. 1
  216. 1
  217. 1
  218. 1
  219. 1
  220. 1
  221. 1
  222. 1
  223. 1
  224. 1
  225. 1
  226. 1
  227. 1
  228. 1
  229. 1
  230. 1
  231. 1
  232. 1
  233. 1
  234. 1
  235. 1
  236. 1
  237. 1
  238. 1
  239. 1
  240. 1
  241. 1
  242. 1
  243. 1
  244. 1
  245. 1
  246. 1
  247. 1
  248. 1
  249. 1
  250. 1
  251. 1
  252. 1
  253. 1
  254. 1
  255. 1
  256. 1
  257. 1
  258. 1
  259. 1
  260. 1
  261. 1
  262. 1
  263. 1
  264. 1
  265. 1
  266. 1
  267. 1
  268. 1
  269. 1
  270. 1
  271. 1
  272. 1
  273. 1
  274. 1
  275. 1
  276. 1
  277. 1
  278. 1
  279. 1
  280. 1
  281. 1
  282. 1
  283. 1
  284. 1
  285. 1
  286. 1
  287. 1
  288. 1
  289. 1
  290. 1
  291. 1
  292. 1
  293. 1
  294. 1
  295. 1
  296. 1
  297. 1
  298. 1
  299. 1
  300. 1
  301. 1
  302. 1
  303. 1
  304. 1
  305. 1
  306. 1
  307. 1
  308. 1
  309. 1
  310. 1
  311. 1
  312. 1
  313. 1
  314. 1
  315. 1
  316. 1
  317. 1
  318. 1
  319. 1
  320. 1
  321. 1
  322. 1
  323. 1
  324. 1
  325. 1
  326. 1
  327. 1
  328. 1
  329. 1
  330. 1
  331. 1
  332. 1
  333. 1
  334. 1
  335. 1
  336. 1
  337. 1
  338. 1
  339. 1
  340. 1
  341. 1
  342. 1
  343. 1
  344. 1
  345. 1
  346. 1
  347. 1
  348. 1
  349. 1
  350. 1
  351. 1
  352. 1
  353. 1
  354. 1
  355. 1
  356. 1
  357. 1
  358. 1
  359. 1
  360. 1
  361. 1
  362. 1
  363. 1
  364. 1
  365. 1
  366. 1
  367. 1
  368. 1
  369. 1
  370. 1
  371. 1
  372. 1
  373. 1
  374. 1
  375. 1
  376. 1
  377. 1
  378. 1
  379. 1
  380. 1
  381. 1
  382. 1
  383. 1
  384. 1
  385. 1
  386. 1
  387. 1
  388. 1
  389. 1
  390. 1
  391. 1
  392. 1
  393. 1
  394. 1
  395. 1
  396. 1
  397. 1
  398. 1
  399. 1
  400. 1
\n", + "
\n", + "\t
$jac_rep
\n", + "\t\t
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    -1 1
    1-1
    \n", + "
  2. \n", + "\t
  3. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    -1 1
    -1-1
    \n", + "
  4. \n", + "\t
  5. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    1 1
    -1-1
    \n", + "
  6. \n", + "
\n", + "
\n", + "\t
$jac_rep_index
\n", + "\t\t
\n", + "
  1. 1
  2. 1
  3. 1
  4. 1
  5. 1
  6. 1
  7. 1
  8. 1
  9. 1
  10. 1
  11. 1
  12. 1
  13. 1
  14. 1
  15. 1
  16. 1
  17. 1
  18. 1
  19. 1
  20. 1
  21. 1
  22. 1
  23. 1
  24. 1
  25. 1
  26. 1
  27. 1
  28. 1
  29. 1
  30. 1
  31. 1
  32. 1
  33. 1
  34. 1
  35. 1
  36. 1
  37. 1
  38. 1
  39. 1
  40. 1
  41. 1
  42. 1
  43. 1
  44. 1
  45. 1
  46. 1
  47. 1
  48. 1
  49. 1
  50. 1
  51. 1
  52. 1
  53. 1
  54. 1
  55. 1
  56. 1
  57. 1
  58. 1
  59. 1
  60. 1
  61. 1
  62. 1
  63. 1
  64. 1
  65. 1
  66. 1
  67. 1
  68. 1
  69. 1
  70. 1
  71. 1
  72. 1
  73. 1
  74. 1
  75. 1
  76. 1
  77. 1
  78. 1
  79. 1
  80. 1
  81. 1
  82. 1
  83. 1
  84. 1
  85. 1
  86. 1
  87. 1
  88. 1
  89. 1
  90. 1
  91. 1
  92. 1
  93. 1
  94. 1
  95. 1
  96. 1
  97. 1
  98. 1
  99. 1
  100. 1
  101. 1
  102. 1
  103. 1
  104. 1
  105. 1
  106. 1
  107. 1
  108. 1
  109. 1
  110. 1
  111. 1
  112. 1
  113. 1
  114. 1
  115. 1
  116. 1
  117. 1
  118. 1
  119. 1
  120. 1
  121. 1
  122. 1
  123. 1
  124. 1
  125. 1
  126. 1
  127. 1
  128. 1
  129. 1
  130. 1
  131. 1
  132. 1
  133. 1
  134. 1
  135. 1
  136. 1
  137. 1
  138. 1
  139. 1
  140. 1
  141. 1
  142. 1
  143. 1
  144. 1
  145. 1
  146. 1
  147. 1
  148. 1
  149. 1
  150. 1
  151. 1
  152. 1
  153. 1
  154. 1
  155. 1
  156. 1
  157. 1
  158. 1
  159. 1
  160. 1
  161. 1
  162. 1
  163. 1
  164. 1
  165. 1
  166. 1
  167. 1
  168. 1
  169. 1
  170. 1
  171. 1
  172. 1
  173. 1
  174. 1
  175. 1
  176. 1
  177. 1
  178. 1
  179. 1
  180. 1
  181. 1
  182. 1
  183. 1
  184. 1
  185. 1
  186. 1
  187. 1
  188. 1
  189. 1
  190. 1
  191. 1
  192. 1
  193. 1
  194. 1
  195. 1
  196. 1
  197. 1
  198. 1
  199. 1
  200. 1
  201. 3
  202. 2
  203. 2
  204. 2
  205. 2
  206. 2
  207. 2
  208. 2
  209. 2
  210. 2
  211. 2
  212. 2
  213. 2
  214. 1
  215. 1
  216. 1
  217. 1
  218. 1
  219. 1
  220. 1
  221. 1
  222. 1
  223. 1
  224. 1
  225. 1
  226. 1
  227. 1
  228. 1
  229. 1
  230. 1
  231. 1
  232. 1
  233. 1
  234. 1
  235. 1
  236. 1
  237. 1
  238. 1
  239. 1
  240. 1
  241. 1
  242. 1
  243. 1
  244. 1
  245. 1
  246. 1
  247. 1
  248. 1
  249. 1
  250. 1
  251. 1
  252. 1
  253. 1
  254. 1
  255. 1
  256. 1
  257. 1
  258. 1
  259. 1
  260. 1
  261. 1
  262. 1
  263. 1
  264. 1
  265. 1
  266. 1
  267. 1
  268. 1
  269. 1
  270. 1
  271. 1
  272. 1
  273. 1
  274. 1
  275. 1
  276. 1
  277. 1
  278. 1
  279. 1
  280. 1
  281. 1
  282. 1
  283. 1
  284. 1
  285. 1
  286. 1
  287. 1
  288. 1
  289. 1
  290. 1
  291. 1
  292. 1
  293. 1
  294. 1
  295. 1
  296. 1
  297. 1
  298. 1
  299. 1
  300. 1
  301. 1
  302. 1
  303. 1
  304. 1
  305. 1
  306. 1
  307. 1
  308. 1
  309. 1
  310. 1
  311. 1
  312. 1
  313. 1
  314. 1
  315. 1
  316. 1
  317. 1
  318. 1
  319. 1
  320. 1
  321. 1
  322. 1
  323. 1
  324. 1
  325. 1
  326. 1
  327. 1
  328. 1
  329. 1
  330. 1
  331. 1
  332. 1
  333. 1
  334. 1
  335. 1
  336. 1
  337. 1
  338. 1
  339. 1
  340. 1
  341. 1
  342. 1
  343. 1
  344. 1
  345. 1
  346. 1
  347. 1
  348. 1
  349. 1
  350. 1
  351. 1
  352. 1
  353. 1
  354. 1
  355. 1
  356. 1
  357. 1
  358. 1
  359. 1
  360. 1
  361. 1
  362. 1
  363. 1
  364. 1
  365. 1
  366. 1
  367. 1
  368. 1
  369. 1
  370. 1
  371. 1
  372. 1
  373. 1
  374. 1
  375. 1
  376. 1
  377. 1
  378. 1
  379. 1
  380. 1
  381. 1
  382. 1
  383. 1
  384. 1
  385. 1
  386. 1
  387. 1
  388. 1
  389. 1
  390. 1
  391. 1
  392. 1
  393. 1
  394. 1
  395. 1
  396. 1
  397. 1
  398. 1
  399. 1
  400. 1
\n", + "
\n", + "
\n" + ], + "text/latex": [ + "\\begin{description}\n", + "\\item[\\$loop\\_rep] \\begin{enumerate}\n", + "\\item A data.frame: 3 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & 1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A data.frame: 3 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A data.frame: 3 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & 1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 1, 2, 1 & 2 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$loop\\_rep\\_index] \\begin{enumerate*}\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item ⋯\n", + "\\item 3\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\end{enumerate*}\n", + "\n", + "\\item[\\$jac\\_rep] \\begin{enumerate}\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -1 & 1\\\\\n", + "\t 1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t 1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n", + "\n", + "\\item[\\$jac\\_rep\\_index] \\begin{enumerate*}\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item ⋯\n", + "\\item 3\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 2\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\item 1\n", + "\\end{enumerate*}\n", + "\n", + "\\end{description}\n" + ], + "text/markdown": [ + "$loop_rep\n", + ": 1. \n", + "A data.frame: 3 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | 1 |\n", + "\n", + "\n", + "2. \n", + "A data.frame: 3 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | -1 |\n", + "\n", + "\n", + "3. \n", + "A data.frame: 3 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | 1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 1, 2, 1 | 2 | -1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$loop_rep_index\n", + ": 1. 1\n", + "2. 1\n", + "3. 1\n", + "4. 1\n", + "5. 1\n", + "6. 1\n", + "7. 1\n", + "8. 1\n", + "9. 1\n", + "10. 1\n", + "11. 1\n", + "12. 1\n", + "13. 1\n", + "14. 1\n", + "15. 1\n", + "16. 1\n", + "17. 1\n", + "18. 1\n", + "19. 1\n", + "20. 1\n", + "21. 1\n", + "22. 1\n", + "23. 1\n", + "24. 1\n", + "25. 1\n", + "26. 1\n", + "27. 1\n", + "28. 1\n", + "29. 1\n", + "30. 1\n", + "31. 1\n", + "32. 1\n", + "33. 1\n", + "34. 1\n", + "35. 1\n", + "36. 1\n", + "37. 1\n", + "38. 1\n", + "39. 1\n", + "40. 1\n", + "41. 1\n", + "42. 1\n", + "43. 1\n", + "44. 1\n", + "45. 1\n", + "46. 1\n", + "47. 1\n", + "48. 1\n", + "49. 1\n", + "50. 1\n", + "51. 1\n", + "52. 1\n", + "53. 1\n", + "54. 1\n", + "55. 1\n", + "56. 1\n", + "57. 1\n", + "58. 1\n", + "59. 1\n", + "60. 1\n", + "61. 1\n", + "62. 1\n", + "63. 1\n", + "64. 1\n", + "65. 1\n", + "66. 1\n", + "67. 1\n", + "68. 1\n", + "69. 1\n", + "70. 1\n", + "71. 1\n", + "72. 1\n", + "73. 1\n", + "74. 1\n", + "75. 1\n", + "76. 1\n", + "77. 1\n", + "78. 1\n", + "79. 1\n", + "80. 1\n", + "81. 1\n", + "82. 1\n", + "83. 1\n", + "84. 1\n", + "85. 1\n", + "86. 1\n", + "87. 1\n", + "88. 1\n", + "89. 1\n", + "90. 1\n", + "91. 1\n", + "92. 1\n", + "93. 1\n", + "94. 1\n", + "95. 1\n", + "96. 1\n", + "97. 1\n", + "98. 1\n", + "99. 1\n", + "100. 1\n", + "101. 1\n", + "102. 1\n", + "103. 1\n", + "104. 1\n", + "105. 1\n", + "106. 1\n", + "107. 1\n", + "108. 1\n", + "109. 1\n", + "110. 1\n", + "111. 1\n", + "112. 1\n", + "113. 1\n", + "114. 1\n", + "115. 1\n", + "116. 1\n", + "117. 1\n", + "118. 1\n", + "119. 1\n", + "120. 1\n", + "121. 1\n", + "122. 1\n", + "123. 1\n", + "124. 1\n", + "125. 1\n", + "126. 1\n", + "127. 1\n", + "128. 1\n", + "129. 1\n", + "130. 1\n", + "131. 1\n", + "132. 1\n", + "133. 1\n", + "134. 1\n", + "135. 1\n", + "136. 1\n", + "137. 1\n", + "138. 1\n", + "139. 1\n", + "140. 1\n", + "141. 1\n", + "142. 1\n", + "143. 1\n", + "144. 1\n", + "145. 1\n", + "146. 1\n", + "147. 1\n", + "148. 1\n", + "149. 1\n", + "150. 1\n", + "151. 1\n", + "152. 1\n", + "153. 1\n", + "154. 1\n", + "155. 1\n", + "156. 1\n", + "157. 1\n", + "158. 1\n", + "159. 1\n", + "160. 1\n", + "161. 1\n", + "162. 1\n", + "163. 1\n", + "164. 1\n", + "165. 1\n", + "166. 1\n", + "167. 1\n", + "168. 1\n", + "169. 1\n", + "170. 1\n", + "171. 1\n", + "172. 1\n", + "173. 1\n", + "174. 1\n", + "175. 1\n", + "176. 1\n", + "177. 1\n", + "178. 1\n", + "179. 1\n", + "180. 1\n", + "181. 1\n", + "182. 1\n", + "183. 1\n", + "184. 1\n", + "185. 1\n", + "186. 1\n", + "187. 1\n", + "188. 1\n", + "189. 1\n", + "190. 1\n", + "191. 1\n", + "192. 1\n", + "193. 1\n", + "194. 1\n", + "195. 1\n", + "196. 1\n", + "197. 1\n", + "198. 1\n", + "199. 1\n", + "200. 1\n", + "201. ⋯\n", + "202. 3\n", + "203. 2\n", + "204. 2\n", + "205. 2\n", + "206. 2\n", + "207. 2\n", + "208. 2\n", + "209. 2\n", + "210. 2\n", + "211. 2\n", + "212. 2\n", + "213. 2\n", + "214. 2\n", + "215. 1\n", + "216. 1\n", + "217. 1\n", + "218. 1\n", + "219. 1\n", + "220. 1\n", + "221. 1\n", + "222. 1\n", + "223. 1\n", + "224. 1\n", + "225. 1\n", + "226. 1\n", + "227. 1\n", + "228. 1\n", + "229. 1\n", + "230. 1\n", + "231. 1\n", + "232. 1\n", + "233. 1\n", + "234. 1\n", + "235. 1\n", + "236. 1\n", + "237. 1\n", + "238. 1\n", + "239. 1\n", + "240. 1\n", + "241. 1\n", + "242. 1\n", + "243. 1\n", + "244. 1\n", + "245. 1\n", + "246. 1\n", + "247. 1\n", + "248. 1\n", + "249. 1\n", + "250. 1\n", + "251. 1\n", + "252. 1\n", + "253. 1\n", + "254. 1\n", + "255. 1\n", + "256. 1\n", + "257. 1\n", + "258. 1\n", + "259. 1\n", + "260. 1\n", + "261. 1\n", + "262. 1\n", + "263. 1\n", + "264. 1\n", + "265. 1\n", + "266. 1\n", + "267. 1\n", + "268. 1\n", + "269. 1\n", + "270. 1\n", + "271. 1\n", + "272. 1\n", + "273. 1\n", + "274. 1\n", + "275. 1\n", + "276. 1\n", + "277. 1\n", + "278. 1\n", + "279. 1\n", + "280. 1\n", + "281. 1\n", + "282. 1\n", + "283. 1\n", + "284. 1\n", + "285. 1\n", + "286. 1\n", + "287. 1\n", + "288. 1\n", + "289. 1\n", + "290. 1\n", + "291. 1\n", + "292. 1\n", + "293. 1\n", + "294. 1\n", + "295. 1\n", + "296. 1\n", + "297. 1\n", + "298. 1\n", + "299. 1\n", + "300. 1\n", + "301. 1\n", + "302. 1\n", + "303. 1\n", + "304. 1\n", + "305. 1\n", + "306. 1\n", + "307. 1\n", + "308. 1\n", + "309. 1\n", + "310. 1\n", + "311. 1\n", + "312. 1\n", + "313. 1\n", + "314. 1\n", + "315. 1\n", + "316. 1\n", + "317. 1\n", + "318. 1\n", + "319. 1\n", + "320. 1\n", + "321. 1\n", + "322. 1\n", + "323. 1\n", + "324. 1\n", + "325. 1\n", + "326. 1\n", + "327. 1\n", + "328. 1\n", + "329. 1\n", + "330. 1\n", + "331. 1\n", + "332. 1\n", + "333. 1\n", + "334. 1\n", + "335. 1\n", + "336. 1\n", + "337. 1\n", + "338. 1\n", + "339. 1\n", + "340. 1\n", + "341. 1\n", + "342. 1\n", + "343. 1\n", + "344. 1\n", + "345. 1\n", + "346. 1\n", + "347. 1\n", + "348. 1\n", + "349. 1\n", + "350. 1\n", + "351. 1\n", + "352. 1\n", + "353. 1\n", + "354. 1\n", + "355. 1\n", + "356. 1\n", + "357. 1\n", + "358. 1\n", + "359. 1\n", + "360. 1\n", + "361. 1\n", + "362. 1\n", + "363. 1\n", + "364. 1\n", + "365. 1\n", + "366. 1\n", + "367. 1\n", + "368. 1\n", + "369. 1\n", + "370. 1\n", + "371. 1\n", + "372. 1\n", + "373. 1\n", + "374. 1\n", + "375. 1\n", + "376. 1\n", + "377. 1\n", + "378. 1\n", + "379. 1\n", + "380. 1\n", + "381. 1\n", + "382. 1\n", + "383. 1\n", + "384. 1\n", + "385. 1\n", + "386. 1\n", + "387. 1\n", + "388. 1\n", + "389. 1\n", + "390. 1\n", + "391. 1\n", + "392. 1\n", + "393. 1\n", + "394. 1\n", + "395. 1\n", + "396. 1\n", + "397. 1\n", + "398. 1\n", + "399. 1\n", + "400. 1\n", + "401. 1\n", + "\n", + "\n", + "\n", + "$jac_rep\n", + ": 1. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -1 | 1 |\n", + "| 1 | -1 |\n", + "\n", + "\n", + "2. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -1 | 1 |\n", + "| -1 | -1 |\n", + "\n", + "\n", + "3. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| 1 | 1 |\n", + "| -1 | -1 |\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "$jac_rep_index\n", + ": 1. 1\n", + "2. 1\n", + "3. 1\n", + "4. 1\n", + "5. 1\n", + "6. 1\n", + "7. 1\n", + "8. 1\n", + "9. 1\n", + "10. 1\n", + "11. 1\n", + "12. 1\n", + "13. 1\n", + "14. 1\n", + "15. 1\n", + "16. 1\n", + "17. 1\n", + "18. 1\n", + "19. 1\n", + "20. 1\n", + "21. 1\n", + "22. 1\n", + "23. 1\n", + "24. 1\n", + "25. 1\n", + "26. 1\n", + "27. 1\n", + "28. 1\n", + "29. 1\n", + "30. 1\n", + "31. 1\n", + "32. 1\n", + "33. 1\n", + "34. 1\n", + "35. 1\n", + "36. 1\n", + "37. 1\n", + "38. 1\n", + "39. 1\n", + "40. 1\n", + "41. 1\n", + "42. 1\n", + "43. 1\n", + "44. 1\n", + "45. 1\n", + "46. 1\n", + "47. 1\n", + "48. 1\n", + "49. 1\n", + "50. 1\n", + "51. 1\n", + "52. 1\n", + "53. 1\n", + "54. 1\n", + "55. 1\n", + "56. 1\n", + "57. 1\n", + "58. 1\n", + "59. 1\n", + "60. 1\n", + "61. 1\n", + "62. 1\n", + "63. 1\n", + "64. 1\n", + "65. 1\n", + "66. 1\n", + "67. 1\n", + "68. 1\n", + "69. 1\n", + "70. 1\n", + "71. 1\n", + "72. 1\n", + "73. 1\n", + "74. 1\n", + "75. 1\n", + "76. 1\n", + "77. 1\n", + "78. 1\n", + "79. 1\n", + "80. 1\n", + "81. 1\n", + "82. 1\n", + "83. 1\n", + "84. 1\n", + "85. 1\n", + "86. 1\n", + "87. 1\n", + "88. 1\n", + "89. 1\n", + "90. 1\n", + "91. 1\n", + "92. 1\n", + "93. 1\n", + "94. 1\n", + "95. 1\n", + "96. 1\n", + "97. 1\n", + "98. 1\n", + "99. 1\n", + "100. 1\n", + "101. 1\n", + "102. 1\n", + "103. 1\n", + "104. 1\n", + "105. 1\n", + "106. 1\n", + "107. 1\n", + "108. 1\n", + "109. 1\n", + "110. 1\n", + "111. 1\n", + "112. 1\n", + "113. 1\n", + "114. 1\n", + "115. 1\n", + "116. 1\n", + "117. 1\n", + "118. 1\n", + "119. 1\n", + "120. 1\n", + "121. 1\n", + "122. 1\n", + "123. 1\n", + "124. 1\n", + "125. 1\n", + "126. 1\n", + "127. 1\n", + "128. 1\n", + "129. 1\n", + "130. 1\n", + "131. 1\n", + "132. 1\n", + "133. 1\n", + "134. 1\n", + "135. 1\n", + "136. 1\n", + "137. 1\n", + "138. 1\n", + "139. 1\n", + "140. 1\n", + "141. 1\n", + "142. 1\n", + "143. 1\n", + "144. 1\n", + "145. 1\n", + "146. 1\n", + "147. 1\n", + "148. 1\n", + "149. 1\n", + "150. 1\n", + "151. 1\n", + "152. 1\n", + "153. 1\n", + "154. 1\n", + "155. 1\n", + "156. 1\n", + "157. 1\n", + "158. 1\n", + "159. 1\n", + "160. 1\n", + "161. 1\n", + "162. 1\n", + "163. 1\n", + "164. 1\n", + "165. 1\n", + "166. 1\n", + "167. 1\n", + "168. 1\n", + "169. 1\n", + "170. 1\n", + "171. 1\n", + "172. 1\n", + "173. 1\n", + "174. 1\n", + "175. 1\n", + "176. 1\n", + "177. 1\n", + "178. 1\n", + "179. 1\n", + "180. 1\n", + "181. 1\n", + "182. 1\n", + "183. 1\n", + "184. 1\n", + "185. 1\n", + "186. 1\n", + "187. 1\n", + "188. 1\n", + "189. 1\n", + "190. 1\n", + "191. 1\n", + "192. 1\n", + "193. 1\n", + "194. 1\n", + "195. 1\n", + "196. 1\n", + "197. 1\n", + "198. 1\n", + "199. 1\n", + "200. 1\n", + "201. ⋯\n", + "202. 3\n", + "203. 2\n", + "204. 2\n", + "205. 2\n", + "206. 2\n", + "207. 2\n", + "208. 2\n", + "209. 2\n", + "210. 2\n", + "211. 2\n", + "212. 2\n", + "213. 2\n", + "214. 2\n", + "215. 1\n", + "216. 1\n", + "217. 1\n", + "218. 1\n", + "219. 1\n", + "220. 1\n", + "221. 1\n", + "222. 1\n", + "223. 1\n", + "224. 1\n", + "225. 1\n", + "226. 1\n", + "227. 1\n", + "228. 1\n", + "229. 1\n", + "230. 1\n", + "231. 1\n", + "232. 1\n", + "233. 1\n", + "234. 1\n", + "235. 1\n", + "236. 1\n", + "237. 1\n", + "238. 1\n", + "239. 1\n", + "240. 1\n", + "241. 1\n", + "242. 1\n", + "243. 1\n", + "244. 1\n", + "245. 1\n", + "246. 1\n", + "247. 1\n", + "248. 1\n", + "249. 1\n", + "250. 1\n", + "251. 1\n", + "252. 1\n", + "253. 1\n", + "254. 1\n", + "255. 1\n", + "256. 1\n", + "257. 1\n", + "258. 1\n", + "259. 1\n", + "260. 1\n", + "261. 1\n", + "262. 1\n", + "263. 1\n", + "264. 1\n", + "265. 1\n", + "266. 1\n", + "267. 1\n", + "268. 1\n", + "269. 1\n", + "270. 1\n", + "271. 1\n", + "272. 1\n", + "273. 1\n", + "274. 1\n", + "275. 1\n", + "276. 1\n", + "277. 1\n", + "278. 1\n", + "279. 1\n", + "280. 1\n", + "281. 1\n", + "282. 1\n", + "283. 1\n", + "284. 1\n", + "285. 1\n", + "286. 1\n", + "287. 1\n", + "288. 1\n", + "289. 1\n", + "290. 1\n", + "291. 1\n", + "292. 1\n", + "293. 1\n", + "294. 1\n", + "295. 1\n", + "296. 1\n", + "297. 1\n", + "298. 1\n", + "299. 1\n", + "300. 1\n", + "301. 1\n", + "302. 1\n", + "303. 1\n", + "304. 1\n", + "305. 1\n", + "306. 1\n", + "307. 1\n", + "308. 1\n", + "309. 1\n", + "310. 1\n", + "311. 1\n", + "312. 1\n", + "313. 1\n", + "314. 1\n", + "315. 1\n", + "316. 1\n", + "317. 1\n", + "318. 1\n", + "319. 1\n", + "320. 1\n", + "321. 1\n", + "322. 1\n", + "323. 1\n", + "324. 1\n", + "325. 1\n", + "326. 1\n", + "327. 1\n", + "328. 1\n", + "329. 1\n", + "330. 1\n", + "331. 1\n", + "332. 1\n", + "333. 1\n", + "334. 1\n", + "335. 1\n", + "336. 1\n", + "337. 1\n", + "338. 1\n", + "339. 1\n", + "340. 1\n", + "341. 1\n", + "342. 1\n", + "343. 1\n", + "344. 1\n", + "345. 1\n", + "346. 1\n", + "347. 1\n", + "348. 1\n", + "349. 1\n", + "350. 1\n", + "351. 1\n", + "352. 1\n", + "353. 1\n", + "354. 1\n", + "355. 1\n", + "356. 1\n", + "357. 1\n", + "358. 1\n", + "359. 1\n", + "360. 1\n", + "361. 1\n", + "362. 1\n", + "363. 1\n", + "364. 1\n", + "365. 1\n", + "366. 1\n", + "367. 1\n", + "368. 1\n", + "369. 1\n", + "370. 1\n", + "371. 1\n", + "372. 1\n", + "373. 1\n", + "374. 1\n", + "375. 1\n", + "376. 1\n", + "377. 1\n", + "378. 1\n", + "379. 1\n", + "380. 1\n", + "381. 1\n", + "382. 1\n", + "383. 1\n", + "384. 1\n", + "385. 1\n", + "386. 1\n", + "387. 1\n", + "388. 1\n", + "389. 1\n", + "390. 1\n", + "391. 1\n", + "392. 1\n", + "393. 1\n", + "394. 1\n", + "395. 1\n", + "396. 1\n", + "397. 1\n", + "398. 1\n", + "399. 1\n", + "400. 1\n", + "401. 1\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "$loop_rep\n", + "$loop_rep[[1]]\n", + " loop length sign\n", + "1 1, 1 1 -1\n", + "2 2, 2 1 -1\n", + "3 1, 2, 1 2 1\n", + "\n", + "$loop_rep[[2]]\n", + " loop length sign\n", + "1 1, 1 1 -1\n", + "2 2, 2 1 -1\n", + "3 1, 2, 1 2 -1\n", + "\n", + "$loop_rep[[3]]\n", + " loop length sign\n", + "1 1, 1 1 1\n", + "2 2, 2 1 -1\n", + "3 1, 2, 1 2 -1\n", + "\n", + "\n", + "$loop_rep_index\n", + " [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [75] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [112] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [149] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [186] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [223] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2\n", + " [260] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [297] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [334] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [371] 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [408] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [445] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [482] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [519] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [556] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [593] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [630] 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [667] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [704] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1\n", + " [741] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [778] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [815] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [852] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [889] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [926] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [963] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1000] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1037] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1074] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1111] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1148] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1185] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1222] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1259] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2\n", + "[1296] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1333] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1370] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1407] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1444] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1481] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1518] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1555] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1592] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1629] 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1666] 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1703] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1740] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1777] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1814] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1851] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1888] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1925] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1962] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1999] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2036] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2073] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2110] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2147] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2184] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2221] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2258] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2295] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2\n", + "[2332] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2369] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2406] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2443] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2480] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2517] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2554] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2591] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2628] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2665] 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2702] 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2739] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2776] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2\n", + "[2813] 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2850] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2887] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2924] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2961] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2998] 1 1 1 1\n", + "\n", + "$jac_rep\n", + "$jac_rep[[1]]\n", + " [,1] [,2]\n", + "[1,] -1 1\n", + "[2,] 1 -1\n", + "\n", + "$jac_rep[[2]]\n", + " [,1] [,2]\n", + "[1,] -1 1\n", + "[2,] -1 -1\n", + "\n", + "$jac_rep[[3]]\n", + " [,1] [,2]\n", + "[1,] 1 1\n", + "[2,] -1 -1\n", + "\n", + "\n", + "$jac_rep_index\n", + " [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [75] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [112] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [149] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [186] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [223] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2\n", + " [260] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [297] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [334] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [371] 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [408] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [445] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [482] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [519] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [556] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [593] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + " [630] 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [667] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + " [704] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1\n", + " [741] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [778] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [815] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [852] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [889] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [926] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + " [963] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1000] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1037] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1074] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1111] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1148] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1185] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1222] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1259] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2\n", + "[1296] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1333] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1370] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1407] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1444] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1481] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1518] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1555] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1592] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1629] 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1666] 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1703] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[1740] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[1777] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1814] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1851] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1888] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1925] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1962] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[1999] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2036] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2073] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2110] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2147] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2184] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2221] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2258] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2295] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2\n", + "[2332] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2369] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2406] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2443] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2480] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2517] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2554] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2591] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2628] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2665] 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n", + "[2702] 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2739] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n", + "[2776] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2\n", + "[2813] 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2850] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2887] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2924] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2961] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n", + "[2998] 1 1 1 1\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res_tab_all" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "a1881f7e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Draw background in the plot corresponding to the time points where\n", + "# certain loop structures are present\n", + "\n", + "# 1-to-1 time vector (must match loop_rep_index length)\n", + "time_vec <- sort(unique(sol_long$time))\n", + "\n", + "stopifnot(length(res_tab_all$loop_rep_index) == length(time_vec))\n", + "\n", + "# Run-length encode to get contiguous segments of the same loop structure\n", + "r <- rle(res_tab_all$loop_rep_index)\n", + "\n", + "end_idx <- cumsum(r$lengths)\n", + "start_idx <- c(1, head(end_idx + 1, -1))\n", + "\n", + "bands <- tibble(\n", + " loop_type = factor(r$values),\n", + " t_start = time_vec[start_idx],\n", + " t_end = time_vec[end_idx]\n", + ")\n", + "transition_times <- bands$t_end[-nrow(bands)]" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "8725b19d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 840 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "plot2 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " # background bands (behind lines)\n", + " geom_rect(\n", + " data = bands,\n", + " aes(xmin = t_start, xmax = t_end, ymin = -Inf, ymax = Inf, fill = loop_type),\n", + " inherit.aes = FALSE,\n", + " alpha = 0.1\n", + " ) +\n", + " geom_vline(\n", + " xintercept = transition_times,\n", + " colour = \"grey40\",\n", + " linewidth = 0.7,\n", + " alpha = 0.35\n", + " ) +\n", + " geom_line(linewidth = 2) +\n", + " scale_colour_manual(values = colors) +\n", + " scale_fill_brewer(palette = \"Set2\", name = \"Loop structure\") +\n", + " scale_x_continuous(\n", + " breaks = seq(0, 3, 0.5),\n", + " minor_breaks = seq(0, 3, 0.1),\n", + " limits = c(0, 3),\n", + " expand = c(0, 0)\n", + " ) +\n", + " coord_cartesian(xlim = c(0, 3), clip = \"on\") +\n", + " labs(\n", + " title = \"Dynamics of Calcium Oscillation Model\",\n", + " x = \"Time (a.u.)\",\n", + " y = \"Concentration (a.u.)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " panel.grid = element_blank(),\n", + " panel.border = element_rect(colour = \"black\", fill = NA, linewidth = 1.1)\n", + " )\n", + "\n", + "plot2\n" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "2f90ae6b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1] \"Loop structure 1:\"\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\t
  1. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    -1 1
    1-1
    \n", + "
  2. \n", + "\t
  3. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    -1 1
    -1-1
    \n", + "
  4. \n", + "\t
  5. \n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
    A matrix: 2 × 2 of type dbl
    1 1
    -1-1
    \n", + "
  6. \n", + "
\n" + ], + "text/latex": [ + "\\begin{enumerate}\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -1 & 1\\\\\n", + "\t 1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t -1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\item A matrix: 2 × 2 of type dbl\n", + "\\begin{tabular}{ll}\n", + "\t 1 & 1\\\\\n", + "\t -1 & -1\\\\\n", + "\\end{tabular}\n", + "\n", + "\\end{enumerate}\n" + ], + "text/markdown": [ + "1. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -1 | 1 |\n", + "| 1 | -1 |\n", + "\n", + "\n", + "2. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| -1 | 1 |\n", + "| -1 | -1 |\n", + "\n", + "\n", + "3. \n", + "A matrix: 2 × 2 of type dbl\n", + "\n", + "| 1 | 1 |\n", + "| -1 | -1 |\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "[[1]]\n", + " [,1] [,2]\n", + "[1,] -1 1\n", + "[2,] 1 -1\n", + "\n", + "[[2]]\n", + " [,1] [,2]\n", + "[1,] -1 1\n", + "[2,] -1 -1\n", + "\n", + "[[3]]\n", + " [,1] [,2]\n", + "[1,] 1 1\n", + "[2,] -1 -1\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(\"Loop structure 1:\")\n", + "res_tab_all$jac_rep" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "3bc28d1d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all21
pos01
neg20
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 2 & 1\\\\\n", + "\tpos & 0 & 1\\\\\n", + "\tneg & 2 & 0\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 2 | 1 |\n", + "| pos | 0 | 1 |\n", + "| neg | 2 | 0 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 2 1 \n", + "pos 0 1 \n", + "neg 2 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab_all$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "0a868f1a", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all21
pos00
neg21
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 2 & 1\\\\\n", + "\tpos & 0 & 0\\\\\n", + "\tneg & 2 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 2 | 1 |\n", + "| pos | 0 | 0 |\n", + "| neg | 2 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 2 1 \n", + "pos 0 0 \n", + "neg 2 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab_all$loop_rep[[2]])" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "cee49cc0", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 2
len_1len_2
<dbl><dbl>
all21
pos10
neg11
\n" + ], + "text/latex": [ + "A data.frame: 3 × 2\n", + "\\begin{tabular}{r|ll}\n", + " & len\\_1 & len\\_2\\\\\n", + " & & \\\\\n", + "\\hline\n", + "\tall & 2 & 1\\\\\n", + "\tpos & 1 & 0\\\\\n", + "\tneg & 1 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 2\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> |\n", + "|---|---|---|\n", + "| all | 2 | 1 |\n", + "| pos | 1 | 0 |\n", + "| neg | 1 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2\n", + "all 2 1 \n", + "pos 1 0 \n", + "neg 1 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(res_tab_all$loop_rep[[3]])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/test_r.ipynb b/examples/test_r.ipynb new file mode 100644 index 0000000..6172825 --- /dev/null +++ b/examples/test_r.ipynb @@ -0,0 +1,1469 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8443073c", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **Installation**\n", + "LoopDetectR is on CRAN and can be installed within R by" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f4527cc", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Before running the R code cells in jupyter notebook,\n", + "# initialize the R kernel by this line of code:\n", + "# IRkernel::installspec()" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e4b77c16", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n", + "also installing the dependencies 'igraph', 'numDeriv'\n", + "\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'igraph' successfully unpacked and MD5 sums checked\n", + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "package 'LoopDetectR' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\RtmpaOiKF4\\downloaded_packages\n" + ] + } + ], + "source": [ + "# Download and install\n", + "install.packages(\"LoopDetectR\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "37148f24", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'deSolve' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\RtmpaOiKF4\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'numDeriv' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\RtmpaOiKF4\\downloaded_packages\n" + ] + } + ], + "source": [ + "install.packages(\"deSolve\") # if not already installed\n", + "install.packages(\"numDeriv\") # if not already installed" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5af1f007", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Load package\n", + "library(\"LoopDetectR\")" + ] + }, + { + "cell_type": "markdown", + "id": "7821beca", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **In brief and quick start**\n", + "The package LoopDetectR enables determining all feedback loops of an ordinary differential equation (ODE) system at user-defined values of the model parameters and of the modelled variables.\n", + "\n", + "The following call reports (up to 10) feedback loops for an ODE system determined by a function, here the example function `func_POSm4`, at variable values s_star (here, these are all equal to 1). Additional arguments to the example function are supplied." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "452aaf33", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
4, 41-1
3, 4, 1,....4-1
3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 6 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 3, 4, 1,.... & 4 & -1\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 3, 4, 1,.... | 4 | -1 |\n", + "| 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 4, 4 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Load example ODE system with function func_POSm4, 4 variables\n", + "data(\"func_POSm4\")\n", + "# Example variable values\n", + "s_star <- rep(1,4)\n", + "# Further arguments of func_POSm4, in addition: time t as argument\n", + "klin <- rep(1,8)\n", + "knonlin <- c(2.5,3)\n", + "\n", + "# compute loops\n", + "res_tab <- find_loops_vset(func_POSm4,vset=list(s_star),t=1,klin=klin,\n", + " knonlin=knonlin,max_num_loops=10)\n", + "# The loop list is reported\n", + "res_tab$loop_rep[[1]]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1ad58566", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " loop length sign\n", + "1 1, 1 1 -1\n", + "2 2, 2 1 -1\n", + "3 3, 3 1 -1\n", + "4 4, 4 1 -1\n", + "5 3, 4, 1,.... 4 -1\n", + "6 3, 4, 2, 3 3 1\n" + ] + } + ], + "source": [ + "print(res_tab$loop_rep[[1]])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "eedcc059", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\n", + "
A data.frame: 1 × 3
looplengthsign
<I<list>><dbl><dbl>
63, 4, 2, 331
\n" + ], + "text/latex": [ + "A data.frame: 1 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t6 & 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 1 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 6 | 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# This is the sixth loop of the list. It is a positive feedback loop (sign in \n", + "# the loop list equals +1) of length 3 in that variable 3 regulates variable 4, \n", + "# variable 4 regulates variable 2, and variable 2 regulates variable 3. \n", + "res_tab$loop_rep[[1]][6,]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "441d7e21", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1 0 0-1
1-1 0 1
0 1-1 0
0 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & 0 & 0 & -1\\\\\n", + "\t 1 & -1 & 0 & 1\\\\\n", + "\t 0 & 1 & -1 & 0\\\\\n", + "\t 0 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | 0 | 0 | -1 |\n", + "| 1 | -1 | 0 | 1 |\n", + "| 0 | 1 | -1 | 0 |\n", + "| 0 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 0 0 -1 \n", + "[2,] 1 -1 0 1 \n", + "[3,] 0 1 -1 0 \n", + "[4,] 0 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# The corresponding signed Jacobian matrix\n", + "res_tab$jac_rep[[1]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69850e68", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "aaa76790", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 420, + "width": 420 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Load example ODE system with function func_POSm4, \n", + "# Positive feedback chain model from [Baum et al., 2016], 4 variables\n", + "data(func_POSm4)\n", + "# The function func_POSm4 returns a vector, but deSolve needs the vector within\n", + "# a list as output. Therefore, we define a function that simply puts the output \n", + "# of func_POSm4 into a list:\n", + "func_POSm4_list <- function(t,x,klin,knonlin){list(func_POSm4(t,x,klin,knonlin))}\n", + "# Kinetic parameters of the model, supplied as arguments to func_POSm4\n", + "# klin <- c(165,0.044,0.27,550,5000,78,4.4,5.1)\n", + "klin <- c(150, 0.04, 0.3, 500, 5000, 80, 4, 5)\n", + "knonlin <- c(0.3,2)\n", + "# Solve the system using deSolve\n", + "sol <- deSolve::ode(y = rep(1,4), times = seq(0,11,0.1), func = func_POSm4_list, \n", + " parms=klin, knonlin=knonlin)\n", + "# The solution of the 4-variable system is oscillatory, showing only the first \n", + "# variable here\n", + "plot(sol[,1],sol[,2],type='l',xlab='Time',ylab ='Variable 1')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e363256e", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'\n", + "(as 'lib' is unspecified)\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "package 'tidyverse' successfully unpacked and MD5 sums checked\n", + "\n", + "The downloaded binary packages are in\n", + "\tC:\\Users\\Admin\\AppData\\Local\\Temp\\RtmpcZaHJz\\downloaded_packages\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "── \u001b[1mAttaching core tidyverse packages\u001b[22m ──────────────────────── tidyverse 2.0.0 ──\n", + "\u001b[32m✔\u001b[39m \u001b[34mdplyr \u001b[39m 1.1.4 \u001b[32m✔\u001b[39m \u001b[34mreadr \u001b[39m 2.1.6\n", + "\u001b[32m✔\u001b[39m \u001b[34mforcats \u001b[39m 1.0.1 \u001b[32m✔\u001b[39m \u001b[34mstringr \u001b[39m 1.6.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mggplot2 \u001b[39m 4.0.1 \u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.3.0\n", + "\u001b[32m✔\u001b[39m \u001b[34mlubridate\u001b[39m 1.9.4 \u001b[32m✔\u001b[39m \u001b[34mtidyr \u001b[39m 1.3.1\n", + "\u001b[32m✔\u001b[39m \u001b[34mpurrr \u001b[39m 1.2.0 \n", + "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n", + "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m masks \u001b[34mstats\u001b[39m::lag()\n", + "\u001b[36mℹ\u001b[39m Use the conflicted package (\u001b[3m\u001b[34m\u001b[39m\u001b[23m) to force all conflicts to become errors\n" + ] + } + ], + "source": [ + "# Make beautiful plot using ggplot2 / tidyverse\n", + "# install.packages(\"tidyverse\") # if not already installed\n", + "library(tidyverse)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "e7722a33", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "library(deSolve)\n", + "library(tidyverse)\n", + "\n", + "# solve system\n", + "sol_for_plot <- as.data.frame(\n", + " ode(\n", + " y = rep(1,4),\n", + " times = seq(0, 11, 0.1),\n", + " func = func_POSm4_list,\n", + " parms = klin,\n", + " knonlin = knonlin\n", + " )\n", + ")\n", + "\n", + "# rename columns for clarity\n", + "colnames(sol_for_plot) <- c(\"time\", \"X1\", \"X2\", \"X3\", \"X4\")\n", + "\n", + "# reshape to long format\n", + "sol_long <- sol_for_plot %>%\n", + " pivot_longer(cols = X1:X4, names_to = \"species\", values_to = \"value\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "079c187f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Warning message:\n", + "\"\u001b[1m\u001b[22mUsing `size` aesthetic for lines was deprecated in ggplot2 3.4.0.\n", + "\u001b[36mℹ\u001b[39m Please use `linewidth` instead.\"\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "plot without title" + ] + }, + "metadata": { + "image/png": { + "height": 360, + "width": 480 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + "# geom_line(size = 1.1) +\n", + "# scale_colour_brewer(palette = \"Dark2\") +\n", + "# labs(\n", + "# title = \"Dynamics of the 4-Variable Positive Feedback Chain\",\n", + "# x = \"Time\",\n", + "# y = \"Concentration\",\n", + "# colour = \"Species\"\n", + "# ) +\n", + "# theme_minimal(base_size = 16) +\n", + "# theme(\n", + "# plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + "# legend.position = \"right\",\n", + "# panel.grid.minor = element_blank()\n", + "# )\n", + "\n", + "options(repr.plot.width = 8, repr.plot.height = 6)\n", + "\n", + "plot1 <- ggplot(sol_long, aes(x = time, y = value, colour = species)) +\n", + " geom_line(size = 1.1) +\n", + " scale_colour_brewer(palette = \"Dark2\") +\n", + " scale_y_log10(\n", + " breaks = scales::trans_breaks(\"log10\", function(x) 10^x),\n", + " labels = scales::trans_format(\"log10\", scales::math_format(10^.x))\n", + " ) + # ← log₁₀ transformation\n", + " labs(\n", + " title = \"Dynamics of the 4-Variable Positive Feedback Chain\",\n", + " x = \"Time\",\n", + " y = \"Concentration (log scale)\",\n", + " colour = \"Species\"\n", + " ) +\n", + " theme_minimal(base_size = 16) +\n", + " theme(\n", + " plot.title = element_text(face = \"bold\", hjust = 0.5),\n", + " panel.grid.minor = element_blank()\n", + " )\n", + "\n", + "plot1\n", + "# ggsave(\"POSm4_plot.png\", plot1, width = 10, height = 8, units = \"in\", dpi = 300)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "90aac4e1", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "dir.create(\"results\", showWarnings = FALSE)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "5da4476d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "agg_record_757164869: 2" + ], + "text/latex": [ + "\\textbf{agg\\textbackslash{}\\_record\\textbackslash{}\\_757164869:} 2" + ], + "text/markdown": [ + "**agg_record_757164869:** 2" + ], + "text/plain": [ + "agg_record_757164869 \n", + " 2 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "svg(\"results/posm4.svg\", width = 10, height = 8)\n", + "print(plot1)\n", + "dev.off()" + ] + }, + { + "cell_type": "markdown", + "id": "834f11c6", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **Calculating the Jacobian matrix**\n", + "The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, `s_star`. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003].\n", + "\n", + "The input function, in the example `func_POSm4` (positive feedback chain model from [Baum et al., 2016]) defines the time derivatives of the modelled variables as a vector: \n", + "$f_i(s)=dS_i/dt$. Note that only those input arguments to the function that encode the modelled variables (and hence in whose direction the partial derivatives are taken) are allowed to be called `x`." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "7a7e6226", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
1
63.9008547597954
2
0.0111646237998349
3
0.0748170189314118
4
1.37597224802616
\n" + ], + "text/latex": [ + "\\begin{description*}\n", + "\\item[1] 63.9008547597954\n", + "\\item[2] 0.0111646237998349\n", + "\\item[3] 0.0748170189314118\n", + "\\item[4] 1.37597224802616\n", + "\\end{description*}\n" + ], + "text/markdown": [ + "1\n", + ": 63.90085475979542\n", + ": 0.01116462379983493\n", + ": 0.07481701893141184\n", + ": 1.37597224802616\n", + "\n" + ], + "text/plain": [ + " 1 2 3 4 \n", + "63.90085476 0.01116462 0.07481702 1.37597225 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Set the last point of the numeric solution as point of interest, omit the \n", + "# first column (it contains the time)\n", + "s_star <- sol[dim(sol)[1],2:dim(sol)[2]]\n", + "s_star" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "bdad5d8b", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1.2396132 0 0.0-85.9719
0.9696132-5550 0.0 85.9719
0.0000000 550-82.4 0.0000
0.0000000 0 78.0 -5.1000
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1.2396132 & 0 & 0.0 & -85.9719\\\\\n", + "\t 0.9696132 & -5550 & 0.0 & 85.9719\\\\\n", + "\t 0.0000000 & 550 & -82.4 & 0.0000\\\\\n", + "\t 0.0000000 & 0 & 78.0 & -5.1000\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1.2396132 | 0 | 0.0 | -85.9719 |\n", + "| 0.9696132 | -5550 | 0.0 | 85.9719 |\n", + "| 0.0000000 | 550 | -82.4 | 0.0000 |\n", + "| 0.0000000 | 0 | 78.0 | -5.1000 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4] \n", + "[1,] -1.2396132 0 0.0 -85.9719\n", + "[2,] 0.9696132 -5550 0.0 85.9719\n", + "[3,] 0.0000000 550 -82.4 0.0000\n", + "[4,] 0.0000000 0 78.0 -5.1000" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "klin <- c(165,0.044,0.27,550,5000,78,4.4,5.1)\n", + "knonlin <- c(0.3,2)\n", + "j_matrix <- numDeriv::jacobian(func_POSm4,s_star,method=\"complex\",\n", + " t=1,klin=klin,knonlin=knonlin,)\n", + "j_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "39c1a233", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A matrix: 4 × 4 of type dbl
-1 0 0-1
1-1 0 1
0 1-1 0
0 0 1-1
\n" + ], + "text/latex": [ + "A matrix: 4 × 4 of type dbl\n", + "\\begin{tabular}{llll}\n", + "\t -1 & 0 & 0 & -1\\\\\n", + "\t 1 & -1 & 0 & 1\\\\\n", + "\t 0 & 1 & -1 & 0\\\\\n", + "\t 0 & 0 & 1 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A matrix: 4 × 4 of type dbl\n", + "\n", + "| -1 | 0 | 0 | -1 |\n", + "| 1 | -1 | 0 | 1 |\n", + "| 0 | 1 | -1 | 0 |\n", + "| 0 | 0 | 1 | -1 |\n", + "\n" + ], + "text/plain": [ + " [,1] [,2] [,3] [,4]\n", + "[1,] -1 0 0 -1 \n", + "[2,] 1 -1 0 1 \n", + "[3,] 0 1 -1 0 \n", + "[4,] 0 0 1 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "signed_jacobian <- sign(j_matrix)\n", + "signed_jacobian" + ] + }, + { + "cell_type": "markdown", + "id": "f50e0305", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "### **Computing all feedback loops and useful functions for loop search**\n", + "The Jacobian matrix is used to compute feedback loops in the generated interaction graph. The default function for this is `find_loops`, in that strongly connected components are determined to reduce runtime. For smaller systems, the function `find_loops_noscc` skips this step and thus can be faster. The optional second input argument, `max_num_loops`, sets an upper limit to the number of detected and reported loops and thus can prevent overly long runtime (but also potentially not all loops are returned)." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "cfc29fc4", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
4, 41-1
3, 4, 1,....4-1
3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 6 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 3, 4, 1,.... & 4 & -1\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 3, 4, 1,.... | 4 | -1 |\n", + "| 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 4, 4 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Determine the loop_list from Jacobian matrix j_matrix\n", + "loop_list <- find_loops(j_matrix)\n", + "loop_list" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "54d49c90", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 6 × 3
looplengthsign
<I<list>><dbl><dbl>
1, 11-1
2, 21-1
3, 31-1
4, 41-1
3, 4, 1,....4-1
3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 6 × 3\n", + "\\begin{tabular}{lll}\n", + " loop & length & sign\\\\\n", + " > & & \\\\\n", + "\\hline\n", + "\t 1, 1 & 1 & -1\\\\\n", + "\t 2, 2 & 1 & -1\\\\\n", + "\t 3, 3 & 1 & -1\\\\\n", + "\t 4, 4 & 1 & -1\\\\\n", + "\t 3, 4, 1,.... & 4 & -1\\\\\n", + "\t 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 6 × 3\n", + "\n", + "| loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|\n", + "| 1, 1 | 1 | -1 |\n", + "| 2, 2 | 1 | -1 |\n", + "| 3, 3 | 1 | -1 |\n", + "| 4, 4 | 1 | -1 |\n", + "| 3, 4, 1,.... | 4 | -1 |\n", + "| 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "1 1, 1 1 -1 \n", + "2 2, 2 1 -1 \n", + "3 3, 3 1 -1 \n", + "4 4, 4 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Use the signed Jacobian matrix to determine the loop_list give the same result\n", + "loop_list <- find_loops(signed_jacobian)\n", + "loop_list" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "a4336c7f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[1]]\n", + "[1] 3 4 1 2 3\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Retrieve fifth loop\n", + "loop_list[5,1] " + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "3b862f3d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
  1. 3
  2. 4
  3. 1
  4. 2
  5. 3
\n" + ], + "text/latex": [ + "\\begin{enumerate*}\n", + "\\item 3\n", + "\\item 4\n", + "\\item 1\n", + "\\item 2\n", + "\\item 3\n", + "\\end{enumerate*}\n" + ], + "text/markdown": [ + "1. 3\n", + "2. 4\n", + "3. 1\n", + "4. 2\n", + "5. 3\n", + "\n", + "\n" + ], + "text/plain": [ + "[1] 3 4 1 2 3" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# In order to obtain the vector of the order of variables of a loop, you have to \n", + "# call the list element\n", + "loop_list[5,1][[1]]" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "e28abdc5", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\n", + "
A data.frame: 1 × 3
looplengthsign
<I<list>><dbl><dbl>
53, 4, 1,....4-1
\n" + ], + "text/latex": [ + "A data.frame: 1 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t5 & 3, 4, 1,.... & 4 & -1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 1 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 5 | 3, 4, 1,.... | 4 | -1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "5 3, 4, 1,.... 4 -1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Retrieve all loops of length 4\n", + "loop_list[loop_list$length==4,]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "e3dc787d", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 4
len_1len_2len_3len_4
<dbl><dbl><dbl><dbl>
all4011
pos0010
neg4001
\n" + ], + "text/latex": [ + "A data.frame: 3 × 4\n", + "\\begin{tabular}{r|llll}\n", + " & len\\_1 & len\\_2 & len\\_3 & len\\_4\\\\\n", + " & & & & \\\\\n", + "\\hline\n", + "\tall & 4 & 0 & 1 & 1\\\\\n", + "\tpos & 0 & 0 & 1 & 0\\\\\n", + "\tneg & 4 & 0 & 0 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 4\n", + "\n", + "| | len_1 <dbl> | len_2 <dbl> | len_3 <dbl> | len_4 <dbl> |\n", + "|---|---|---|---|---|\n", + "| all | 4 | 0 | 1 | 1 |\n", + "| pos | 0 | 0 | 1 | 0 |\n", + "| neg | 4 | 0 | 0 | 1 |\n", + "\n" + ], + "text/plain": [ + " len_1 len_2 len_3 len_4\n", + "all 4 0 1 1 \n", + "pos 0 0 1 0 \n", + "neg 4 0 0 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loop_summary(loop_list)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "9cb66750", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 3 × 3
looplengthsign
<I<list>><dbl><dbl>
2 2, 21-1
53, 4, 1,....4-1
6 3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 3 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t2 & 2, 2 & 1 & -1\\\\\n", + "\t5 & 3, 4, 1,.... & 4 & -1\\\\\n", + "\t6 & 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 3 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 2 | 2, 2 | 1 | -1 |\n", + "| 5 | 3, 4, 1,.... | 4 | -1 |\n", + "| 6 | 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "2 2, 2 1 -1 \n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Index of node of interest\n", + "noi <- 2\n", + "# Return all loops from loop_list containing node 2\n", + "loop_list[vapply(loop_list$loop,function(x){noi %in% x},logical(1)),]" + ] + }, + { + "cell_type": "markdown", + "id": "3291b3cc", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "source": [ + "The `LoopDetectR` function `find_edge` can be used to search a loop list for loops containing specific edges defined by the indices of the ingoing and outgoing nodes. This example returns the indices of all loops with a regulation of node 3 by node 2. These are only two here." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "d736f376", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "\n", + "\t\n", + "\t\n", + "\n", + "
A data.frame: 2 × 3
looplengthsign
<I<list>><dbl><dbl>
53, 4, 1,....4-1
6 3, 4, 2, 33 1
\n" + ], + "text/latex": [ + "A data.frame: 2 × 3\n", + "\\begin{tabular}{r|lll}\n", + " & loop & length & sign\\\\\n", + " & > & & \\\\\n", + "\\hline\n", + "\t5 & 3, 4, 1,.... & 4 & -1\\\\\n", + "\t6 & 3, 4, 2, 3 & 3 & 1\\\\\n", + "\\end{tabular}\n" + ], + "text/markdown": [ + "\n", + "A data.frame: 2 × 3\n", + "\n", + "| | loop <I<list>> | length <dbl> | sign <dbl> |\n", + "|---|---|---|---|\n", + "| 5 | 3, 4, 1,.... | 4 | -1 |\n", + "| 6 | 3, 4, 2, 3 | 3 | 1 |\n", + "\n" + ], + "text/plain": [ + " loop length sign\n", + "5 3, 4, 1,.... 4 -1 \n", + "6 3, 4, 2, 3 3 1 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Obtain the indices of the loops with edge '2 regulates 3' in loop_list \n", + "loop_edge_ind <- find_edge(loop_list,source_node=2,target_node=3);\n", + "loops_with_edge_2_to_3 <- loop_list[loop_edge_ind,]\n", + "loops_with_edge_2_to_3" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "a0151df7", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "'C:\\\\Users\\\\Admin\\\\AppData\\\\Local\\\\Temp\\\\RtmpaOiKF4'" + ], + "text/latex": [ + "'C:\\textbackslash{}\\textbackslash{}Users\\textbackslash{}\\textbackslash{}Admin\\textbackslash{}\\textbackslash{}AppData\\textbackslash{}\\textbackslash{}Local\\textbackslash{}\\textbackslash{}Temp\\textbackslash{}\\textbackslash{}RtmpaOiKF4'" + ], + "text/markdown": [ + "'C:\\\\Users\\\\Admin\\\\AppData\\\\Local\\\\Temp\\\\RtmpaOiKF4'" + ], + "text/plain": [ + "[1] \"C:\\\\Users\\\\Admin\\\\AppData\\\\Local\\\\Temp\\\\RtmpaOiKF4\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "tempdir()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "ed4a5e03", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# This writes a file 'looplist_func_POSm4.RData'\n", + "save(loop_list,file=file.path(tempdir(),'looplist_func_POSm4.RData')) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb9080e6", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# This loads the object 'loop_list' into the workspace\n", + "load(file.path(tempdir(),'looplist_func_POSm4.RData'))\n", + "\n", + "# This saves the loop list into a table with separation by tab\n", + "write.table(loop_list,file=file.path(tempdir(),'looplist_func_POSm4.txt'),\n", + " sep='\\t',quote=F,row.names=F)\n", + "# This reads the loop list back into the R session, as object ll\n", + "ll <- read.table(file.path(tempdir(),'looplist_func_POSm4.txt'),\n", + " header=T,sep='\\t')\n", + "ll" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c2c967f", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# ** Example 2: Negative feedback loop model from [Novak and Tyson, 2008], 3 variables" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c994137", + "metadata": { + "vscode": { + "languageId": "r" + } + }, + "outputs": [], + "source": [ + "# Example 3: MAPK cascade model from [Huang and Ferrell, 1996], 3 variables\n", + "data(\"func_MAPK3\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "R", + "language": "R", + "name": "ir" + }, + "language_info": { + "codemirror_mode": "r", + "file_extension": ".r", + "mimetype": "text/x-r-source", + "name": "R", + "pygments_lexer": "r", + "version": "4.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/old/workflow_LoopDetectR.html b/old/workflow_LoopDetectR.html new file mode 100644 index 0000000..6f263be --- /dev/null +++ b/old/workflow_LoopDetectR.html @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + +LoopDetectR: Comprehensive Feedback Loop Detection in ODE models + + + + + + + + + + + + + + + + + + + + + + +

LoopDetectR: Comprehensive Feedback Loop Detection in ODE models

+

Katharina Baum

+

07/06/2020

+ + + +
+

Installation

+

LoopDetectR is on CRAN and can be installed within R by

+
# Download and install
+install.packages("LoopDetectR")
+

Alternatively, you can install the package from gitlab. Call the following commands in an R session.

+
# Install the package including the vignette and the manual
+remotes::install_gitlab("kabaum/LoopDetectR", build_manual=TRUE, 
+                        build_vignettes = TRUE)
+

After installation, load the package.

+
# Load package
+library("LoopDetectR")
+
+
+

In brief and quick start

+

The package LoopDetectR enables determining all feedback loops of an ordinary differential equation (ODE) system at user-defined values of the model parameters and of the modelled variables.

+

The following call reports (up to 10) feedback loops for an ODE system determined by a function, here the example function func_POSm4, at variable values s_star (here, these are all equal to 1). Additional arguments to the example function are supplied.

+
# Load example ODE system with function func_POSm4, 4 variables
+data("func_POSm4")
+# Example variable values
+s_star <- rep(1,4)
+# Further arguments of func_POSm4, in addition: time t as argument
+klin <- rep(1,8)
+knonlin <- c(2.5,3)
+
+# compute loops
+res_tab <- find_loops_vset(func_POSm4,vset=list(s_star),t=1,klin=klin,
+                           knonlin=knonlin,max_num_loops=10)
+# The loop list is reported
+res_tab$loop_rep[[1]]
+
##           loop length sign
+## 1         1, 1      1   -1
+## 2         2, 2      1   -1
+## 3         3, 3      1   -1
+## 4         4, 4      1   -1
+## 5 3, 4, 1,....      4   -1
+## 6   3, 4, 2, 3      3    1
+
# This is the sixth loop of the list. It is a positive feedback loop (sign in 
+# the loop list equals +1) of length 3 in that variable 3 regulates variable 4, 
+# variable 4 regulates variable 2, and variable 2 regulates variable 3. 
+res_tab$loop_rep[[1]][6,]
+
##         loop length sign
+## 6 3, 4, 2, 3      3    1
+
# The corresponding signed Jacobian matrix
+res_tab$jac_rep[[1]]
+
##      [,1] [,2] [,3] [,4]
+## [1,]   -1    0    0   -1
+## [2,]    1   -1    0    1
+## [3,]    0    1   -1    0
+## [4,]    0    0    1   -1
+
+
+

Introduction

+

Ordinary differential equation (ODE) models are used frequently to mathematically represent biological systems. Feedback loops are important regulatory features of biological systems and can give rise to different dynamic behavior such as multistability for positive feedback loops or oscillations for negative feedback loops.

+

The feedback loops in an ODE system can be detected with the help of its Jacobian matrix, the matrix of partial derivatives of the variables. It captures all interactions between the variables and gives rise to the interaction graph of the ODE model. In this graph, each modelled variable is a node and non-zero entries in the Jacobian matrix are (weighted) edges of the graph. Interactions can be positive or negative, according to the sign of the Jacobian matrix entry.

+

Directed path detection in this graph is used to determine all feedback loops (in graphs also called cycles or circuits) of the system. They are marked by a set of directed interactions forming a chain in which only the first and the last node (variable) is the same. Thereby, self-loops (loops of length one) can also occur.

+

LoopDetectR allows for detection of all loops of the graph and also reports the sign of each loop, i.e. whether it is a positive feedback loop (the number of negative interactions is even) or a negative feedback loop (the number of negative interactions is uneven). The output is a table that captures the order of the variables forming the loop, their length and the sign of each loop.

+

Jacobian determination in LoopDetectR relies on the package numDeriv, and path finding in graphs uses algorithms supplied in the package igraph.

+
+
+

Solving the ODE model to generate variable values of interest

+

Solving an ODE model can be performed with the package deSolve. Note: You can skip this step if you already have a point of interest in state space, or if you want to use dummy values for the variables such as s_star <- 1:4.

+
# Load example ODE system with function func_POSm4, 
+# Positive feedback chain model from [Baum et al., 2016], 4 variables
+data(func_POSm4)
+# The function func_POSm4 returns a vector, but deSolve needs the vector within
+# a list as output. Therefore, we define a function that simply puts the output 
+# of func_POSm4 into a list:
+func_POSm4_list <- function(t,x,klin,knonlin){list(func_POSm4(t,x,klin,knonlin))}
+# Kinetic parameters of the model, supplied as arguments to func_POSm4
+klin <- c(165,0.044,0.27,550,5000,78,4.4,5.1)
+knonlin <- c(0.3,2)
+# Solve the system using deSolve
+sol <-  deSolve::ode(y = rep(1,4), times = seq(0,15,0.1), func = func_POSm4_list, 
+                     parms=klin, knonlin=knonlin)
+# The solution of the 4-variable system is oscillatory, showing only the first 
+# variable here
+plot(sol[,1],sol[,2],type='l',xlab='time',ylab ='variable 1')
+

+
# Set the last point of the numeric solution as point of interest, omit the 
+# first column (it contains the time)
+s_star <- sol[dim(sol)[1],2:dim(sol)[2]]
+

State variable values of interest could be steady state values, values at a specific point in time (e.g. after a stimulus) or even a set of values (see section Determining loops over a set of variable values).

+
+
+

Calculating the Jacobian matrix

+

The function jacobian from the numDeriv package can be used to determine numerically the Jacobian matrix of an ODE system at a certain set of values for the variables, s_star. The approach is that of finite differences (with real step) or complex step approach, the latter of which is supposed to deliver more exact results [Martins et al., 2003].

+

The input function, in the example func_POSm4 (positive feedback chain model from [Baum et al., 2016]) defines the time derivatives of the modelled variables as a vector: \(f_i(s)=dS_i/dt\). Note that only those input arguments to the function that encode the modelled variables (and hence in whose direction the partial derivatives are taken) are allowed to be called x.

+
klin <- c(165,0.044,0.27,550,5000,78,4.4,5.1)
+knonlin <- c(0.3,2)
+j_matrix <- numDeriv::jacobian(func_POSm4,s_star,method="complex",
+                               t=1,klin=klin,knonlin=knonlin,)
+j_matrix
+
##            [,1]  [,2]  [,3]     [,4]
+## [1,] -1.2396132     0   0.0 -85.9719
+## [2,]  0.9696132 -5550   0.0  85.9719
+## [3,]  0.0000000   550 -82.4   0.0000
+## [4,]  0.0000000     0  78.0  -5.1000
+
signed_jacobian <- sign(j_matrix)
+

The (i,j)th entry of the Jacobian matrix denotes the partial derivative of variable \(S_i\) with respect to variable \(S_j\), \(J_{ij}=\delta S_i/\delta S_j\), which is positive if \(S_j\) has a direct positive effect on \(S_i\), negative if \(S_j\) has a direct negative effect on \(S_i\) and zero if \(S_j\) does not have a direct effect on \(S_i\). For example, the entry in row 2, column 4, \(J_{24}\), of the signed_jacobian matrix above is positive, meaning that in the underlying ODE model, variable 4 positively regulates variable 2.

+
+ +
+

Computing feedback loops over multiple sets of variable values of interest

+

In this example of a model of the bacterial cell cycle [Li et al., 2008], it is demonstrated how feedback loops can be determined over multiple sets of variable values. Here, it is focused on the solution of the ODE systems along the time axis (provided as data in the package, li08_solution.RData).

+
# Load in the example ODE model function func_li08, the kinetic parameters are
+# defined within the function, and the function returns a vector of the time
+# derivatives (in the same order as the modelled variables in the arguments)
+data("func_li08")
+# Load sets of variable values (solution to the ODE over time)
+data("li08_solution") #loads the data.frame li08_solution, columns: variables
+# Cast the solution into the correct list format and remove time (first column)
+li08_sol_list <- as.list(as.data.frame(t(li08_solution[,-1])))
+# Compute all different loop lists along the solution
+res_tab <- find_loops_vset(func_li08,vset=li08_sol_list,t=1,
+                           compute_full_list=FALSE)
+

The solutions of the example ODE model give rise to seven different loop lists that are saved as elements of the list res_tab$loop_rep. Here, two examples of resulting loop lists are given (without self-loops).

+
loop_list_2 <- res_tab$loop_rep[[2]][res_tab$loop_rep[[2]]$length>1,]
+loop_list_2
+
##          loop length sign
+## 16 6, 7, 1, 6      3   -1
+## 17    6, 7, 6      2    1
+## 18    2, 3, 2      2   -1
+
loop_list_7 <- res_tab$loop_rep[[7]][res_tab$loop_rep[[7]]$length>1,]
+loop_list_7
+
##            loop length sign
+## 15      1, 2, 1      2   -1
+## 16   1, 3, 2, 1      3    1
+## 17      2, 3, 2      2   -1
+## 18 5, 7, 1,....      4   -1
+## 19 6, 7, 1,....      5    1
+## 20   6, 7, 1, 6      3   -1
+## 21      6, 7, 6      2    1
+## 22 10, 11, ....      6    1
+## 23 10, 12, ....      3   -1
+## 24 10, 13, ....      4   -1
+## 25 10, 14, ....      8   -1
+## 26 10, 14, ....      7    1
+

The entry res_tab$loop_rep_index is a vector of the same length as the number of different states at which the loops were determined (length(li08_sol_list)), and returns which entry of res_tab$loop_rep belongs to each input state.

+
# Determine the loop list belonging to the 10th up to 20th input state. 
+# It is loop_list_2 for all of these input states.
+res_tab$loop_rep_index[10:20]
+
##  [1] 2 2 2 2 2 2 2 2 2 2 2
+

Similarly, res_tab$jac_rep and res_tab$jac_rep_index capture the different Jacobian matrices and for each input state which Jacobian belongs to it.

+

Results of this analysis could be plotted along the solution and analyzed further to discover reasons of changing loops. Please note that in order to obtain the sample solution in li08_solution.RData also event functions are required; the solution cannot be retrieved from integrating func_li08 alone. Please refer to the model’s publication [Li et al., 2008] for details.

+
+
+

Comparing two loop lists

+

LoopDetectR provides a function for comparing the loops of two systems, compare_loop_list. For a meaningful comparison, the loop indices in the compared systems should point to the same variables. This could be the case when regulations change within one system between different sets of variables of interest (along a dynamic trajectory, at different steady states of the system), or when comparing different systems in which one or more regulations are altered (as in the below example the positive feedback chain model vs. the negative feedback chain model, [Baum et al., 2016]).

+
# Load the ODE function of the positive feedback chain model
+data(func_POSm4)
+# Set kinetic parameters
+klin <- c(165,0.044,0.27,550,5000,78,4.4,5.1)
+knonlin <- c(0.3,2)
+# Compute the Jacobian matrix of the system at the state [1,1,1,1]
+j_matrix <- numDeriv::jacobian(func_POSm4,rep(1,4),method="complex",
+                               t=1, klin=klin, knonlin=knonlin)
+# Compute all loops for this Jacobian
+loop_list_pos <- find_loops(j_matrix)
+
+# Function with negative regulation. The altered regulation affects 
+# two entries of the Jacobian matrix. Parameter values and the set of 
+# variable values remain identical.
+j_matrix_neg <- sign(j_matrix)
+j_matrix_neg[1:2,4] <- -sign(j_matrix[1:2,4])
+# Compute the loop list for this Jacobian with altered regulation
+loop_list_neg <- find_loops(j_matrix_neg);
+
+# Compute comparison
+comp_inds <- compare_loop_list(loop_list_pos,loop_list_neg)
+# Only the four self-loops remain identical in both systems (the indices
+# with respect to the first input list, loop_list_pos, are saved in ind_a_id).
+loop_list_pos[comp_inds$ind_a_id,]
+
##   loop length sign
+## 1 1, 1      1   -1
+## 2 2, 2      1   -1
+## 3 3, 3      1   -1
+## 4 4, 4      1   -1
+
# ind_b_id saves the indices of the corresponding loops in the negatively 
+# regulated system, loop_list_neg.
+loop_list_neg[comp_inds$ind_b_id,]
+
##   loop length sign
+## 1 1, 1      1   -1
+## 2 2, 2      1   -1
+## 3 3, 3      1   -1
+## 4 4, 4      1   -1
+
# Two loops are the same in both systems but they have switched their signs. 
+# Their indices in the first list are saved in ind_a_switch
+loop_list_pos[comp_inds$ind_a_switch,]
+
##           loop length sign
+## 5 3, 4, 1,....      4   -1
+## 6   3, 4, 2, 3      3    1
+
# Their indices in the second list are saved in ind_b_switch 
+loop_list_neg[comp_inds$ind_b_switch,]
+
##           loop length sign
+## 5 3, 4, 1,....      4    1
+## 6   3, 4, 2, 3      3   -1
+
# All loops in the positively regulated system do also occur in the negatively
+# regulated system, i.e. ind_a_notin is empty.
+comp_inds$ind_a_notin
+
## integer(0)
+
+
+

References

+

Baum K, Politi AZ, Kofahl B, Steuer R, Wolf J. Feedback, Mass Conservation and Reaction Kinetics Impact the Robustness of Cellular Oscillations. PLoS Comput Biol. 2016;12(12):e1005298.

+

Li S, Brazhnik P, Sobral B, Tyson JJ. A Quantitative Study of the Division Cycle of Caulobacter crescentus Stalked Cells. Plos Comput Biol. 2008;4(1):e9.

+

Martins JRRA, Sturdza P, Alonso JJ. The complex-step derivative approximation. ACM Trans Math Softw. 2003;29(3):245–62.

+
+ + + + + + + + + + +