|
@@ -4,6 +4,9 @@ import os
|
|
|
import scipy.interpolate
|
|
|
#for partial function specializations
|
|
|
import functools
|
|
|
+import function
|
|
|
+import importlib
|
|
|
+importlib.reload(function)
|
|
|
|
|
|
class model:
|
|
|
def __init__(self):
|
|
@@ -63,22 +66,30 @@ class model:
|
|
|
q=qPar['value']
|
|
|
pc=pcPar['value']
|
|
|
v=vPar['value']
|
|
|
- f=lambda t,q=q,pc=pc,v=v,s=sign:s*q(t)/v(t)/pc(t)
|
|
|
-
|
|
|
DPC=pcPar['derivatives']
|
|
|
- dfdPC=lambda t,f=f,pc=pc:-f(t)/pc(t)
|
|
|
- dPC={x:lambda t,df=dfdPC,D=DPC,x=x: df(t)*D[x](t) for x in DPC}
|
|
|
DQ=qPar['derivatives']
|
|
|
- dfdQ=lambda t,f=f,q=q: f(t)/q(t)
|
|
|
- dQ={x:lambda t,df=dfdQ,D=DQ,x=x: df(t)*D[x](t) for x in DQ}
|
|
|
-
|
|
|
DV=vPar['derivatives']
|
|
|
- dfdV=lambda t,f=f,v=v: -f(t)/v(t)
|
|
|
- dV={x:lambda t,df=dfdV,D=DV,x=x: df(t)*D[x](t) for x in DV}
|
|
|
|
|
|
+ if any(['function' in qPar,'function' in pcPar, 'function' in vPar]):
|
|
|
+ fq=function.to(q)
|
|
|
+ fpc=function.to(pc)
|
|
|
+ fv=function.to(v)
|
|
|
+ f=lambda t,q=fq,pc=fpc,v=fv,s=sign:s*q(t)/v(t)/pc(t)
|
|
|
+ dfdPC=lambda t,f=f,pc=fpc:-f(t)/pc(t)
|
|
|
+ dPC=function.generate(dfdPC,DPC)
|
|
|
+ dfdQ=lambda t,f=f,q=fq: f(t)/q(t)
|
|
|
+ dQ={x:lambda t,df=dfdQ,D=DQ,x=x: df(t)*D[x](t) for x in DQ}
|
|
|
+ dfdV=lambda t,f=f,v=fv: -f(t)/v(t)
|
|
|
+ dV={x:lambda t,df=dfdV,D=DV,x=x: df(t)*D[x](t) for x in DV}
|
|
|
+ return function.Object(f,[dPC,dQ,dV])
|
|
|
+ else:
|
|
|
+ f=sign*q/v/pc
|
|
|
+ return derivedObject(sign*q/v/pc,\
|
|
|
+ [{'df':-f/pc,'D':DPC},\
|
|
|
+ {'df':sign/v/pc,'D':DQ},\
|
|
|
+ {'df':-f/v,'D':DV}])
|
|
|
#derivatives is the combination of the above
|
|
|
|
|
|
- return derivedObject(f,[DPC,DQ,DV])
|
|
|
|
|
|
def getVolumePar(self,compartment,useVolume=1):
|
|
|
#returnis volume name, if found and useVolume is directed,
|
|
@@ -99,20 +110,28 @@ class model:
|
|
|
self.n=len(comps)
|
|
|
self.fu=[lambda t:0]*self.n
|
|
|
self.lut={c:i for (i,c) in zip(range(self.n),comps.keys())}
|
|
|
- self.fM={}
|
|
|
+ self.dM={}
|
|
|
+ self.fM=numpy.zeros((self.n,self.n))
|
|
|
for c in comps:
|
|
|
comp=comps[c]
|
|
|
if 'source' in comp:
|
|
|
self.fu[self.lut[c]]=parseFunction(comp['source'])
|
|
|
|
|
|
for t in comp['targets']:
|
|
|
- try:
|
|
|
- self.fM[self.lut[c]][self.lut[t]]=\
|
|
|
- sumFunctionArray(comp['targets'][t])
|
|
|
- except (KeyError,TypeError):
|
|
|
- self.fM[self.lut[c]]={}
|
|
|
- self.fM[self.lut[c]][self.lut[t]]=\
|
|
|
- sumFunctionArray(comp['targets'][t])
|
|
|
+ arr=comp['targets'][t]
|
|
|
+
|
|
|
+ if function.contains(arr):
|
|
|
+ try:
|
|
|
+ self.dM[self.lut[c]][self.lut[t]]=\
|
|
|
+ function.sumArray(arr)
|
|
|
+ except (KeyError,TypeError):
|
|
|
+ self.dM[self.lut[c]]={}
|
|
|
+ self.dM[self.lut[c]][self.lut[t]]=\
|
|
|
+ function.sumArray(arr)
|
|
|
+ else:
|
|
|
+#just set once
|
|
|
+ self.fM[self.lut[c],self.lut[t]]=sum(arr)
|
|
|
+
|
|
|
|
|
|
|
|
|
#build SE part
|
|
@@ -121,10 +140,11 @@ class model:
|
|
|
def buildSE(self):
|
|
|
#check which parameterst to include
|
|
|
parList=[]
|
|
|
-
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
for parName in self.seJ:
|
|
|
#print(par)
|
|
|
- par=self.mod['parameters'][parName]
|
|
|
+
|
|
|
+ par=pars[parName]
|
|
|
usePar=calculateDerivative(par)
|
|
|
#print('[{}]: {}'.format(usePar,par))
|
|
|
if not usePar:
|
|
@@ -136,6 +156,7 @@ class model:
|
|
|
self.lutSE={c:i for (i,c) in zip(range(self.m),parList)}
|
|
|
|
|
|
self.qSS={}
|
|
|
+ self.SS=numpy.zeros((self.m,self.n,self.n))
|
|
|
for parName in parList:
|
|
|
sources=self.seJ[parName]
|
|
|
for compartment in sources:
|
|
@@ -145,7 +166,11 @@ class model:
|
|
|
i=self.lut[compartment]
|
|
|
j=self.lut[t]
|
|
|
#print('[{} {} {}] {}'.format(parName,compartment,t,targets[t]))
|
|
|
- ft=sumFunctionArray(targets[t])
|
|
|
+ arr=targets[t]
|
|
|
+ if not function.contains(arr):
|
|
|
+ self.SS[k,i,j]=sum(arr)
|
|
|
+ continue
|
|
|
+ ft=function.sumArray(arr)
|
|
|
try:
|
|
|
self.qSS[k][i][j]=ft
|
|
|
except (KeyError,TypeError):
|
|
@@ -163,7 +188,8 @@ class model:
|
|
|
|
|
|
def inspect(self):
|
|
|
comps=self.compartments
|
|
|
- pars=self.mod['parameters']
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
+ #pars=self.mod['parameters']
|
|
|
|
|
|
tu=self.getTimeUnit()
|
|
|
print('Time unit: {}'.format(tu))
|
|
@@ -206,11 +232,15 @@ class model:
|
|
|
for t in targets:
|
|
|
print('\t SE bind {}/{}:{}'.format(compartment,t,targets[t]))
|
|
|
|
|
|
- def parse(self,file):
|
|
|
+ def parse(self,setupFile,parameterFile):
|
|
|
|
|
|
- with open(file,'r') as f:
|
|
|
+ with open(setupFile,'r') as f:
|
|
|
self.mod=json.load(f)
|
|
|
|
|
|
+
|
|
|
+ with open(parameterFile,'r') as f:
|
|
|
+ self.parSetup=json.load(f)
|
|
|
+
|
|
|
for m in self.mod['compartments']:
|
|
|
self.add_compartment(m)
|
|
|
|
|
@@ -220,7 +250,8 @@ class model:
|
|
|
#src=mod['sources'][s]
|
|
|
self.add_source(s,self.mod['sources'][s])
|
|
|
self.flows={}
|
|
|
- pars=self.mod['parameters']
|
|
|
+ #pars=self.mod['parameters']
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
for f in self.mod['flows']:
|
|
|
#skip comments
|
|
|
if f.find(':')<0:
|
|
@@ -274,30 +305,29 @@ class model:
|
|
|
self.build()
|
|
|
|
|
|
def add_default_parameters(self):
|
|
|
- self.mod['parameters']['one']={'value':1}
|
|
|
- self.mod['parameters']['zero']={'value':0}
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
+ pars['one']={'value':1}
|
|
|
+ pars['zero']={'value':0}
|
|
|
|
|
|
|
|
|
def M(self,t):
|
|
|
- Mb=numpy.zeros((self.n,self.n))
|
|
|
- for i in self.fM:
|
|
|
- for j in self.fM[i]:
|
|
|
- Mb[i,j]=self.fM[i][j](t)
|
|
|
+ for i in self.dM:
|
|
|
+ for j in self.dM[i]:
|
|
|
+ self.fM[i,j]=self.dM[i][j](t)
|
|
|
#create an array and fill it with outputs of function at t
|
|
|
- return Mb
|
|
|
+ return self.fM
|
|
|
|
|
|
def u(self,t):
|
|
|
ub=[f(t) for f in self.fu]
|
|
|
return numpy.array(ub)
|
|
|
|
|
|
def fSS(self,t):
|
|
|
- fSS=numpy.zeros((self.m,self.n,self.n))
|
|
|
for k in self.qSS:
|
|
|
for i in self.qSS[k]:
|
|
|
for j in self.qSS[k][i]:
|
|
|
#print('[{},{},{}] {}'.format(k,i,j,self.qSS[k][i][j]))
|
|
|
- fSS[k,i,j]=(self.qSS[k][i][j])(t)
|
|
|
- return fSS
|
|
|
+ self.SS[k,i,j]=(self.qSS[k][i][j])(t)
|
|
|
+ return self.SS
|
|
|
|
|
|
|
|
|
def fSY(self,y,t):
|
|
@@ -362,7 +392,8 @@ class model:
|
|
|
|
|
|
def calculateUncertainty(self,sol,se):
|
|
|
s2out=numpy.zeros(sol.shape)
|
|
|
- pars=self.mod['parameters']
|
|
|
+ #pars=self.mod['parameters']
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
for parName in pars:
|
|
|
par=pars[parName]
|
|
|
if not calculateDerivative(par):
|
|
@@ -379,14 +410,15 @@ class model:
|
|
|
s2=par["cv"]*par["cv"]*v*v
|
|
|
j=self.lutSE[parName]
|
|
|
fse=se[:,:,j]
|
|
|
- print('Calculating for {}/{}:{}'.format(parName,j,fse.shape))
|
|
|
+ print('Calculating for {}/{}:{} [{}]'.format(parName,j,fse.shape,s2))
|
|
|
#se2 is nt x n
|
|
|
se2=numpy.multiply(fse,fse)
|
|
|
s2out+=se2*s2
|
|
|
return numpy.sqrt(s2out)
|
|
|
|
|
|
def get(self,parName):
|
|
|
- par=self.mod['parameters'][parName]
|
|
|
+ pars=self.parSetup['parameters']
|
|
|
+ par=pars[parName]
|
|
|
par['name']=parName
|
|
|
if "value" in par:
|
|
|
return self.getValue(par)
|
|
@@ -394,6 +426,7 @@ class model:
|
|
|
return self.getFunction(par)
|
|
|
if "derived" in par:
|
|
|
return self.getDerived(par)
|
|
|
+ print('Paramter {} not found!'.format(parName))
|
|
|
|
|
|
def getValue(self,par):
|
|
|
|
|
@@ -427,16 +460,20 @@ class model:
|
|
|
def getFunction(self,par):
|
|
|
fName=par['function']
|
|
|
#print('[{}]: getFunction({})'.format(par['name'],par['function']))
|
|
|
- df=self.mod['functions'][fName]
|
|
|
+ df=self.parSetup['functions'][fName]
|
|
|
+ skip=['type']
|
|
|
+ par1={x:self.get(df[x]) for x in df if x not in skip}
|
|
|
if df['type']=='linearGrowth':
|
|
|
- skip=['type']
|
|
|
- par1={x:self.get(df[x]) for x in df if x not in skip}
|
|
|
#print(par1)
|
|
|
- return linearGrowth(par1)
|
|
|
+ return function.linearGrowth(par1)
|
|
|
+ if df['type']=='linearGrowthFixedSlope':
|
|
|
+ return function.linearGrowthFixedSlope(par1)
|
|
|
+
|
|
|
+ print('Function {} not found!'.format(fName))
|
|
|
|
|
|
def getDerived(self,par):
|
|
|
dName=par['derived']
|
|
|
- d=self.mod['derivedParameters'][dName]
|
|
|
+ d=self.parSetup['derivedParameters'][dName]
|
|
|
#print('Derived [{}]: type {}'.format(dName,d['type']))
|
|
|
if d['type']=='product':
|
|
|
#print('{}*{}'.format(d['a'],d['b']))
|
|
@@ -447,12 +484,17 @@ class model:
|
|
|
b=pB['value']
|
|
|
DB=pB['derivatives']
|
|
|
#even more generic -> df/dp=[df/dA*dA/dp+df/dB*dB/dp]
|
|
|
- f=lambda t,a=a,b=b,:a(t)*b(t)
|
|
|
- dfdA=lambda t,b=b: b(t)
|
|
|
- dfdB=lambda t,a=a: a(t)
|
|
|
- dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
- dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
- return derivedObject(f,[dA,dB])
|
|
|
+ if any(['function' in pA,'function' in pB]):
|
|
|
+ fa=function.to(a)
|
|
|
+ fb=function.to(b)
|
|
|
+ f=lambda t,a=fa,b=fb:a(t)*b(t)
|
|
|
+ dfdA=lambda t,b=fb: b(t)
|
|
|
+ dfdB=lambda t,a=fa: a(t)
|
|
|
+ dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
+ dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
+ return function.Object(f,[dA,dB])
|
|
|
+ else:
|
|
|
+ return derivedObject(a*b,[{'df':b,'D':DA},{'df':a,'D':DB}])
|
|
|
|
|
|
if d['type']=='power':
|
|
|
#print('{}^{}'.format(d['a'],d['n']))
|
|
@@ -462,12 +504,19 @@ class model:
|
|
|
pN=self.get(d['n'])
|
|
|
n=pN['value']
|
|
|
DN=pN['derivatives']
|
|
|
- f=lambda t,a=a,n=n:numpy.power(a(t),n(t))
|
|
|
- dfdA=lambda t,n=n,f=f,a=a:n(t)*f(t)/a(t)
|
|
|
- dfdN=lambda t,a=a,f=f:numpy.log(a(t))*f(t)
|
|
|
- dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
- dN={x:lambda t,df=dfdN,D=DN,x=x: df(t)*D[x](t) for x in DN}
|
|
|
- return derivedObject(f,[dA,dN])
|
|
|
+ if any(['function' in pA,'function' in pB]):
|
|
|
+ fa=function.to(a)
|
|
|
+ fn=function.to(n)
|
|
|
+ f=lambda t,a=fa,n=fn:numpy.power(a(t),n(t))
|
|
|
+ dfdA=lambda t,n=fn,f=f,a=fa:n(t)*f(t)/a(t)
|
|
|
+ dfdN=lambda t,a=fa,f=f:numpy.log(a(t))*f(t)
|
|
|
+ dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
+ dN={x:lambda t,df=dfdN,D=DN,x=x: df(t)*D[x](t) for x in DN}
|
|
|
+ return function.Object(f,[dA,dN])
|
|
|
+ else:
|
|
|
+ f=numpy.power(a,n)
|
|
|
+ return derivedObject(f,{'df':n*f/a,'D':DA},{'df':f*numpy.log(a),'D':DN})
|
|
|
+
|
|
|
if d['type']=='ratio':
|
|
|
#print('{}/{}'.format(d['a'],d['b']))
|
|
|
pA=self.get(d['a'])
|
|
@@ -477,12 +526,17 @@ class model:
|
|
|
b=pB['value']
|
|
|
DB=pB['derivatives']
|
|
|
#even more generic -> df/dp=[df/dA*dA/dp+df/dB*dB/dp]
|
|
|
- f=lambda t,a=a,b=b,:a(t)/b(t)
|
|
|
- dfdA=lambda t,f=f,a=a: f(t)/a(t)
|
|
|
- dfdB=lambda t,f=f,b=b: -f(t)/b(t)
|
|
|
- dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
- dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
- return derivedObject(f,[dA,dB])
|
|
|
+ if any(['function' in pA,'function' in pB]):
|
|
|
+ fa=function.to(a)
|
|
|
+ fb=function.to(b)
|
|
|
+ f=lambda t,a=fa,b=fb,:a(t)/b(t)
|
|
|
+ dfdA=lambda t,f=f,a=fa: f(t)/a(t)
|
|
|
+ dfdB=lambda t,f=f,b=fb: -f(t)/b(t)
|
|
|
+ dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
+ dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
+ return function.Object(f,[dA,dB])
|
|
|
+ else:
|
|
|
+ return derivedObject(a/b,[{'df':1/b,'D':DA},{'df':-a/b/b,'D':DB}])
|
|
|
if d['type']=='sum':
|
|
|
#print('{}+{}'.format(d['a'],d['b']))
|
|
|
pA=self.get(d['a'])
|
|
@@ -492,24 +546,23 @@ class model:
|
|
|
b=pB['value']
|
|
|
DB=pB['derivatives']
|
|
|
#even more generic -> df/dp=[df/dA*dA/dp+df/dB*dB/dp]
|
|
|
- f=lambda t,a=a,b=b,:a(t)+b(t)
|
|
|
- dfdA=lambda t: 1
|
|
|
- dfdB=lambda t: 1
|
|
|
- dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
- dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
- return derivedObject(f,[dA,dB])
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ if any(['function' in pA,'function' in pB]):
|
|
|
+ fa=function.to(a)
|
|
|
+ fb=function.to(b)
|
|
|
+ f=lambda t,a=fa,b=fb,:a(t)+b(t)
|
|
|
+ dfdA=lambda t: 1
|
|
|
+ dfdB=lambda t: 1
|
|
|
+ dA={x:lambda t,df=dfdA,D=DA,x=x: df(t)*D[x](t) for x in DA}
|
|
|
+ dB={x:lambda t,df=dfdB,D=DB,x=x: df(t)*D[x](t) for x in DB}
|
|
|
+ return function.Object(f,[dA,dB])
|
|
|
+ else:
|
|
|
+ return derivedObject(a+b,[{'df':1,'D':DA},{'df':1,'D':DB}])
|
|
|
|
|
|
|
|
|
def calculateDerivative(par):
|
|
|
#add derivatives if dist(short for distribution) is specified
|
|
|
return "dist" in par
|
|
|
|
|
|
-
|
|
|
-
|
|
|
def sumValues(dArray,x):
|
|
|
s=0
|
|
|
for a in dArray:
|
|
@@ -518,49 +571,25 @@ def sumValues(dArray,x):
|
|
|
except KeyError:
|
|
|
continue
|
|
|
return s
|
|
|
-
|
|
|
-def sumFunctions(dArray,x):
|
|
|
- #print('sumFunctions for {}'.format(x))
|
|
|
- fs=[]
|
|
|
- for a in dArray:
|
|
|
- #print('\tChecking {}'.format(a))
|
|
|
- try:
|
|
|
- #check if a[x] is a function with a dummy parameter
|
|
|
- v=a[x](1e7)
|
|
|
- fs.append(a[x])
|
|
|
- #print('\tAdding [{}]'.format(v))
|
|
|
- except KeyError:
|
|
|
- #print('\t{} not in table'.format(x))
|
|
|
- continue
|
|
|
- except TypeError:
|
|
|
- #print('\tConstructing lambda for {}'.format(x))
|
|
|
- fs.append(lambda t,a=a,x=x:a[x])
|
|
|
- return sumFunctionArray(fs)
|
|
|
|
|
|
-def sumFunctionArray(fs):
|
|
|
- return lambda t,fs=fs: sum([f(t) for f in fs])
|
|
|
|
|
|
def valueObject(v,parName):
|
|
|
#convert everything to functions
|
|
|
- d0={parName:lambda t:1}
|
|
|
- try:
|
|
|
- v(3)
|
|
|
- return {'value':v,'derivatives':d0}
|
|
|
- except TypeError:
|
|
|
- pass
|
|
|
- return {'value':lambda t,v=v:v,'derivatives':d0}
|
|
|
-
|
|
|
-def derivedObject(v,dArray):
|
|
|
- try:
|
|
|
- v(3)
|
|
|
- o={'value':v}
|
|
|
- except TypeError:
|
|
|
- o={'value':lambda t,v=v:v}
|
|
|
+ d0={parName:1}
|
|
|
+ return {'value':v,'derivatives':{parName:1}}
|
|
|
+
|
|
|
+def derivedObject(f,ders):
|
|
|
+ o={'value':f}
|
|
|
+ DD=[]
|
|
|
+ for d in ders:
|
|
|
+ df=d['df']
|
|
|
+ D=d['D']
|
|
|
+ DD.append({x:df*D[x] for x in D})
|
|
|
allKeys=[]
|
|
|
- for x in dArray:
|
|
|
+ for x in DD:
|
|
|
allKeys.extend(x.keys())
|
|
|
allKeys=list(set(allKeys))
|
|
|
- o['derivatives']={x:sumFunctions(dArray,x) for x in allKeys}
|
|
|
+ o['derivatives']={x:sumValues(DD,x) for x in allKeys}
|
|
|
return o
|
|
|
|
|
|
|
|
@@ -625,60 +654,4 @@ def get(timeUnit,par):
|
|
|
|
|
|
#no idea what to do
|
|
|
return v
|
|
|
-
|
|
|
-def logistic(par):
|
|
|
- t0=par['t0']['value']
|
|
|
- W=par['W']['value']
|
|
|
- L=lambda t,t0=t0,W=W:1/(1+numpy.exp(-(t-t0(t))/W(t)))
|
|
|
- #D1[x] could be a function !!!
|
|
|
- Dt0=par['t0']['derivatives']
|
|
|
- dt0={x:lambda t,L=L,W=W,D=Dt0,x=x: L(t)*(1-L(t))/W(t)*D[x](t) for x in Dt0}
|
|
|
- #D2[x] could be a function !!!
|
|
|
- DW=par['W']['derivatives']
|
|
|
- dW={x:lambda t,L=L,t0=t0,W=W,D=DW,x=x: L(t)*(1-L(t))*(t-t0(t))/W(t)/W(t)*D[x](t) for x in DW}
|
|
|
- #merge
|
|
|
- return derivedObject(L,[dt0,dW])
|
|
|
-
|
|
|
-def linearGrowth(par):
|
|
|
- #make sure we never return zero or negative
|
|
|
- C=par['C']['value']
|
|
|
- t1=par['t1']['value']
|
|
|
- t2=par['t2']['value']
|
|
|
- eps=1e-8*C(0)
|
|
|
- pL1=logistic({'t0':par['t1'],'W':par['W1']})
|
|
|
- pL2=logistic({'t0':par['t2'],'W':par['W2']})
|
|
|
- L1=pL1['value']
|
|
|
- L2=pL2['value']
|
|
|
-
|
|
|
- deltaW=lambda t,t1=t1,t2=t2:t2(t)-t1(t)
|
|
|
- deltaT=lambda t,t1=t1:t-t1(t)
|
|
|
- fq=lambda t,dt=deltaT,w=deltaW:dt(t)/w(t)
|
|
|
- f1=lambda t,eps=eps,q=fq,L1=L1,L2=L2,C=C:C(t)*q(t)*L1(t)*(1-L2(t))
|
|
|
- f2=lambda t,L1=L1,L2=L2,C=C: C(t)*L1(t)*L2(t)
|
|
|
-
|
|
|
- f=lambda t,eps=eps,f1=f1,f2=f2:eps+f1(t)+f2(t)
|
|
|
-
|
|
|
- Dt1=par['t1']['derivatives']
|
|
|
- dfdt1=lambda t,q=fq,C=C,w=deltaW,L1=L1,L2=L2:\
|
|
|
- -C(t)*L1(t)*(1-L2(t))*(1+q(t))/w(t)
|
|
|
- dt1={x:lambda t,df=dfdt1,D=Dt1,x=x:df(t)*D[x](t) for x in Dt1}
|
|
|
-
|
|
|
- Dt2=par['t2']['derivatives']
|
|
|
- dfdt2=lambda t,f1=f1,w=deltaW:-f1(t)/w(t)
|
|
|
- dt2={x:lambda t,df=dfdt2,D=Dt2,x=x:df(t)*D[x](t) for x in Dt2}
|
|
|
-
|
|
|
- DL1=pL1['derivatives']
|
|
|
- dfdL1=lambda t,C=C,L2=L2,q=fq:C(t)*(q(t)*(1-L2(t))+L2(t))
|
|
|
- dL1={x:lambda t,df=dfdL1,D=DL1,x=x:df(t)*D[x](t) for x in DL1}
|
|
|
-
|
|
|
- DL2=pL2['derivatives']
|
|
|
- dfdL2=lambda t,C=C,L1=L1,q=fq:C(t)*L1(t)*(1-q(t))
|
|
|
- dL2={x:lambda t,df=dfdL2,D=DL2,x=x: df(t)*D[x](t) for x in DL2}
|
|
|
-
|
|
|
- DC=par['C']['derivatives']
|
|
|
- dfdC=lambda t,L1=L1,L2=L2,q=fq:L1(t)*(q(t)*(1-L2(t))+L2(t))
|
|
|
- dC={x:lambda t,df=dfdC,D=DC,x=x:df(t)*D[x](t) for x in DC}
|
|
|
-
|
|
|
- return derivedObject(f,[dt1,dt2,dL1,dL2,dC])
|
|
|
-
|
|
|
|