Skip to content

Commit 7ee87ee

Browse files
authored
Add files via upload
1 parent cebcad1 commit 7ee87ee

7 files changed

+20121
-0
lines changed

DynaMETE_Rfunctions_ToyModel.py

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
'''
2+
This file defines all of the necessary functions for DynaMETE, including the transition functions and
3+
the structure function R. This function does NOT include sums over n, since it is designed to be a
4+
more flexible version incorporating different transition functions. This will be very slow for large N or E.
5+
It also defines the METE constraint for beta, which is needed, and a function to obtain mete_lambdas.
6+
This file uses the toy model with only n and no e dependence.
7+
'''
8+
9+
# Import
10+
import numpy as np
11+
import pandas as pd
12+
from scipy.optimize import fsolve
13+
from scipy import integrate
14+
15+
# Get initial lambda
16+
def lambda_i(s):
17+
'''Initial lambda 1 given lambda 2 = 0 and state variables'''
18+
l1_guess = np.log(s['N']/(s['N']-1)) # log(no of individuals/no of individuals - 1) ? why we do that
19+
nrange = np.arange(s['N'])+1 #array of each index of the individuals
20+
l1_true = fsolve(lambda l1 : np.sum(nrange*np.exp(-l1*nrange))/np.sum(np.exp(-l1*nrange))-s['N']/s['S'],l1_guess)[0] #finding the first root of the equation using the guess
21+
li = np.array([l1_true,0])
22+
return li
23+
24+
# Transition functions
25+
# The idea here is to make everything easy to change by changing only these functions.
26+
# For f
27+
def fb0(s,p):
28+
return p['b0']
29+
def fd0(s,p):
30+
return -p['d0']*s['N']/p['Nc']
31+
def f(n,s,p):
32+
'''Transition function for dN/dt. n is the microscopic variables.
33+
s are state variables, call S, N
34+
p are parameters, call b0, d0, Nc '''
35+
return (fb0(s,p)+fd0(s,p)*n)*n
36+
37+
# Also need derivatives for lambda dynamics. Note that these have to be manually editted for alternate f,h,q
38+
def dfdt(n,s,p,ds):
39+
return fd0(s,p)/s['N']*ds['dN']*n*n
40+
41+
# R itself
42+
def R(n,l,s,p):
43+
'''Unnormalized struture function for toy model.
44+
n is microscopic variables.
45+
l are lambdas
46+
s are state variables, call S, N
47+
p are parameters, call b0, d0, Nc '''
48+
return np.exp(-l[0]*n-l[1]*f(n,s,p))
49+
50+
# For calculating a single mean with specific powers of n and e
51+
def mean_pow(npow,l,s,p,z=1):
52+
'''
53+
This function returns the mean of n^npow over the R function.
54+
It is NOT normalized, but it does take in z as an optional argument to normalize.
55+
This function sums numerically over n.
56+
Note that npow=0 corresponds to Z, so by default these are not normalized.
57+
l are lambdas
58+
s are state variables, call S, N
59+
p are parameters, call b0, d0, Nc
60+
'''
61+
nrange = np.arange(s['N'])+1
62+
return np.sum(nrange**npow*R(nrange,l,s,p))/z
63+
64+
# For calculating a covariance with specific powers of n and e for each function
65+
def cov_pow(npow,l,s,p,z):
66+
'''
67+
This function returns the covariance of two functions with the form n^npow over the R function.
68+
You have to pass in the normalization so that things are faster than calculating normalization each time.
69+
npow should be a 2d array
70+
This function sums numerically over n.
71+
z is the normalization
72+
l are lambdas
73+
s are state variables, call S, N
74+
p are parameters, call b0, d0, Nc
75+
'''
76+
nrange = np.arange(s['N'])+1
77+
# Get integral over both functions
78+
ff = np.sum(nrange**np.sum(npow)*R(nrange,l,s,p))/z
79+
# Get integral over each function
80+
f1f2 = 1
81+
for nn in npow:
82+
f1f2 *= np.sum(nrange**nn*R(nrange,l,s,p))/z
83+
return ff-f1f2
84+
85+
# For calculating a single mean over an arbitrary function
86+
# For these next two I could get clever and use *args etc to make it easier to pass in n and e
87+
# But I just don't want to bother right now.
88+
# Also, if you really want to do that, just use mean_pow since that's WAY easier
89+
def mean(func,l,s,p,*args,z=1):
90+
'''
91+
This function returns the mean of an arbitrary function over the R function.
92+
It is NOT normalized, but it does take in z as an optional argument to normalize.
93+
Because I put *args first, you have to use z=z0 if you want to put in a normalization.
94+
The arbitrary function must take arguments of the form (n,s,p) for this to work.
95+
This is the form of the f function above.
96+
You can pass additional arguments as required for the function (ie. pass ds for df/dt)
97+
To pass in n, use lambda n,e,s,p: n or similar
98+
Alternatively, use mean_pow
99+
This function sums numerically over n.
100+
z is the normalization
101+
l are lambdas
102+
s are state variables, call S, N
103+
p are parameters, call b0, d0, Nc
104+
'''
105+
nrange = np.arange(s['N'])+1
106+
# Below is to make this easier for lambda functions, but it isn't worth it. Just require s and p passed,
107+
# and let other things be passed as args if needed.
108+
# Check if we need args by looking at function passed in
109+
# funcargs = func.__code__.co_argcount
110+
# if funcargs >= 4:
111+
# args = s,p,args
112+
return np.sum(R(nrange,l,s,p)*func(nrange,s,p,*args))/z
113+
114+
# For calculating a covariance
115+
# Note if you want to do this with non-functions, use cov_pow
116+
def cov(func1,func2,l,s,p,z,*args):
117+
'''
118+
This function returns the covariance of two arbitrary functions over the R function.
119+
You have to pass in the normalization so that things are faster than calculating normalization each time.
120+
The arbitrary functions must take arguments of the form (n,s,p) for this to work.
121+
This is the form of the f function above.
122+
You can pass additional arguments as required for the function (ie. pass ds for df/dt)
123+
To pass in n use lambda n,s,p: n
124+
This function sums numerically over n.
125+
z is the normalization
126+
l are lambdas
127+
s are state variables, call S, N
128+
p are parameters, call b0, d0, Nc
129+
'''
130+
nrange = np.arange(s['N'])+1
131+
# Get integral over both functions
132+
ffeint = R(nrange,l,s,p)*func1(nrange,s,p,*args)*func2(nrange,s,p,*args)
133+
ff = np.sum(ffeint)/z
134+
# Get integral over each function
135+
f1f2 = 1
136+
for func in [func1,func2]:
137+
feint = R(nrange,l,s,p)*func(nrange,s,p,*args)
138+
f1f2 *= np.sum(feint)/z
139+
return ff-f1f2
140+
141+
def get_dXdt(l,s,p):
142+
'''
143+
Returns the time derivatives of the state variables.
144+
Inputs lambdas, state variables, and parameters.
145+
Outputs a pandas series of ds.
146+
'''
147+
# Create storage
148+
ds = pd.Series(np.zeros(2),index=['dS','dN'])
149+
# To normalize
150+
z = mean_pow(0,l,s,p)
151+
ds['dN'] = s['S']*mean(f,l,s,p,z=z)
152+
return ds

LambdaDynamicsTest.ipynb

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "cd7655a3",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"for i in np.arange()"
11+
]
12+
}
13+
],
14+
"metadata": {
15+
"kernelspec": {
16+
"display_name": "Python 3",
17+
"language": "python",
18+
"name": "python3"
19+
},
20+
"language_info": {
21+
"codemirror_mode": {
22+
"name": "ipython",
23+
"version": 3
24+
},
25+
"file_extension": ".py",
26+
"mimetype": "text/x-python",
27+
"name": "python",
28+
"nbconvert_exporter": "python",
29+
"pygments_lexer": "ipython3",
30+
"version": "3.8.8"
31+
}
32+
},
33+
"nbformat": 4,
34+
"nbformat_minor": 5
35+
}

0 commit comments

Comments
 (0)