将变量传递给单独的文件,然后将其变为“全局”

时间:2018-04-15 20:04:34

标签: python-2.7

我注意到以下问题是相关的:Variable Parameters Curve Fit 0Variable Parameters Curve Fit 1Hold Parameter Curve Fit 0.

它创建一个猜测参数数组和数组,规定哪些参数保持不变。然后它生成正确的名称来调用,然后使用包装器来调用它。它工作但我想将我的定义放在一个名为utilites.py的单独文件中,然后从初始文件中调用定义。如您所见,wrapper()需要找到wrapperName()。有没有办法将包装器名称传递给单独的文件,然后通过utilities.py中的所有定义使其可访问?如果您尝试传递包装器,则额外的参数curve_fit()会中断。

import numpy as np
from numpy import random
import scipy as sp
from scipy.optimize import curve_fit
import matplotlib.pyplot as pl

def exp1(t,a1,tau1):
        val=0.
        val=(a1*np.exp(-t/tau1))*np.heaviside(t,0)
        return val

def exp2(t,a1,tau1,a2,tau2):
        val=0.
        val=(a1*np.exp(-t/tau1)+a2*np.exp(-t/tau2))*np.heaviside(t,0)
        return val

def exp3(t,a1,tau1,a2,tau2,a3,tau3):
        val=0.
        val=(a1*np.exp(-t/tau1)+a2*np.exp(-t/tau2)+a3*np.exp(-t/tau3))*np.heaviside(t,0)
        return val

def exp4(t,a1,tau1,a2,tau2,a3,tau3,a4,tau4):
        val=0.
        val=(a1*np.exp(-t/tau1)+a2*np.exp(-t/tau2)+a3*np.exp(-t/tau3)+a3*np.exp(-t/tau3))*np.heaviside(t,0)
        return val

def multiexp(t,args):
        val=np.zeros(len(t))
        for i in np.arange(0,len(args),2):
            val+=args[i]*np.exp(-t/args[i+1])*np.heaviside(t,0)
        return val

def genWrapperName(hold,p0):
    counter=0
    if len(p0)==2:
        wrapperName='exp1(t,'
    elif len(p0)==4:
        wrapperName='exp2(t,'
    elif len(p0)==6:
        wrapperName='exp3(t,'
    elif len(p0)==8:
        wrapperName='exp4(t,'
    for i in range(0, len(hold)):
        if hold[i]:
            wrapperName+=str(p0[i])
        else:
            if i%2==0:
                wrapperName+='args['+str(counter)+']'
                counter+=1
            else:
                wrapperName+='args['+str(counter)+']'
                counter+=1
        if i<len(hold)-1:
            wrapperName+=','
    wrapperName+=')'
    return wrapperName

def wrapper(t,*args):
    global wrapperName
    return eval(wrapperName)

#inital guess parameters
p0=np.array([1.5,200.,2.,700.,3.,2400.])
#list of parameters to hold in the least squares fit. 1 means hold
hold=[0,1,0,1,0,0]
holdloc=[i for i, x in enumerate(hold) if x]
p1=np.delete(p0,holdloc)
timepoints = np.arange(20.,4000.,20.)
wrapperName=genWrapperName(hold,p0)
y=exp3(timepoints,1.,300.,2.,800,1.,3000.)+np.random.normal(0, .1, size=len(timepoints))

popt, pcov = curve_fit(exp3, timepoints, y, p0=p0)
print 'unheld parameters:', popt
print 'unheld covariance:', pcov

popt, pcov = curve_fit(wrapper, timepoints, y, p0=p1)

for i in range(0, len(hold)):
    if hold[i]:
        popt=np.insert(popt,i,p0[i])
print 'held parameters:', popt
print 'held covariance:', pcov
yfit=multiexp(timepoints,popt)

pl.plot(timepoints,y,timepoints,yfit)
pl.show()

1 个答案:

答案 0 :(得分:0)

在holdCurveFit.py

import numpy as np
import utilities as ut
from numpy import random
import scipy as sp
from scipy.optimize import curve_fit
import matplotlib.pyplot as pl

p0=np.array([1.5,200.,2.,700.,3.,2400.])
hold=[0,1,0,1,0,0]
holdloc=[i for i, x in enumerate(hold) if x]
p1=np.delete(p0,holdloc)
timepoints = np.arange(-200.,4000.,20.)
callFitName= ut.genCallFitName(p0,hold)

y=ut.multiexp(timepoints,p0)+np.random.normal(0, .1, size=len(timepoints))

popt, pcov = curve_fit(ut.multiexp2, timepoints, y, p0=p0)
print 'unheld parameters:', popt

popt, pcov=eval(callFitName)
for i in range(0, len(hold)):
    if hold[i]:
        popt=np.insert(popt,i,p0[i])
print 'held parameters:', popt

yfit=ut.multiexp(timepoints,popt)

pl.plot(timepoints,y,timepoints,yfit)
pl.show()

并在utilities.py

import numpy as np

def multiexp2(t,*args):
    val=np.zeros(len(t))
    for i in np.arange(0,len(args),2):
        val+=args[i]*np.exp(-t/args[i+1])*np.heaviside(t,0)
    return val

def multiexp(t,args):
    val=np.zeros(len(t))
    for i in np.arange(0,len(args),2):
        val+=args[i]*np.exp(-t/args[i+1])*np.heaviside(t,0)
    return val

def genCallFitName(p0,hold):
    counter=0
    callFitName='curve_fit(lambda timepoints, *p: ('
    for i in range(0, len(hold)):
        if hold[i] and i%2==0:
            callFitName+=str(p0[i])
        elif hold[i] and i%2==1:
            callFitName+='*np.exp(-timepoints/'+str(p0[i])+')'
        elif i%2==0 and not hold[i]: 
            callFitName+='p['+str(counter)+']'
            counter+=1
        else:
            callFitName+='*np.exp(-timepoints/p['+str(counter)+'])'
            counter+=1
        if i<len(hold)-1 and i%2==1:
            callFitName+='+'
    callFitName+=')*np.heaviside(timepoints,0), timepoints, y, p0=p1)'
    return callFitName