嘿,我目前正在使用Python的模块进行热力学液相平衡。为此,我需要编写活动系数模型(如NRTL),其中涉及多个求和。为了增强模块的性能,我尝试使用numba来实现该功能:
AppDomain
我正在尝试新的选择,例如cython,但是我的表现不如numbas的jit好。
@jit(cache=True)
def NRTL(X,T,g, alpha, g1):
'''
NRTL activity coefficient model.
input
X: array like, vector of molar fractions
T: float, absolute temperature in K.
g: array like, matrix of energy interactions in K.
g1: array_like, matrix of energy interactions in K^2
alpha: float, aleatory factor.
tau = ((g + g1/T)/T)
output
lngama: array_like, natural logarithm of activify coefficient
'''
tau = g + g1*T
tau /= T
nc=len(X)
G=np.exp(-alpha*tau)
lngama=np.zeros_like(X)
for i in range(nc):
SumC=SumD=SumE=0
for j in range(nc):
A=X[j]*G[i,j]
SumA=SumB=0
for k in range(nc):
SumA +=X[k]*G[k,j]
SumB +=X[k]*G[k,j]*tau[k,j]
SumC +=A/SumA*(tau[i,j]-SumB/SumA)
SumD+=X[j]*G[j,i]*tau[j,i]
SumE+=X[j]*G[j,i]
lngama[i]=SumD/SumE+SumC
return lngama
我使用以下参数评估该功能:
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cdef double[:] nrtlaux(double [:] X, double [:,::1] G, double [:,::1] tau, int nc):
cdef int i, j, k
cdef double A, SumA, SumB, SumC, SumD, SumE, aux1, aux2
cdef double [:] lngama = np.zeros(nc)
for i in range(nc):
SumC = SumD = SumE = 0.
for j in range(nc):
A = X[j]*G[i,j]
SumA = SumB = 0.
for k in range(nc):
aux1 = X[k]*G[k,j]
SumA += aux1
SumB += aux1*tau[k,j]
SumC += A/SumA*(tau[i,j]-SumB/SumA)
aux2 = X[j]*G[j,i]
SumD += aux2*tau[j,i]
SumE += aux2
lngama[i] = SumD/SumE+SumC
return lngama
def NRTL(np.ndarray[double, ndim=1] X, double T, np.ndarray[double, ndim=2] g,
np.ndarray[double, ndim=2] alpha, np.ndarray[double, ndim=2] g1):
cdef int nc = len(X)
cdef:
double[:,::1] tau = (g/T + g1)
double[:,::1] G = np.exp( -alpha * tau )
lngama = nrtlaux(X, G, tau, nc)
return np.asarray(lngama)
我得到了以下结果:
X = np.array([0.5,0.4,0.1])
g = np.array([[0,35.00002657,463.719316],[341.00001923,0,96.02154497],[1194.42262, 534.77089478,0]])
alpha = np.array([[0,0.3456916919878884,0.242020522],[0.3456916919878884,0,0.54 ],[0.242020522,0.54 ,0]])
g1 = np.zeros_like(g)
T = 350.
我对jitted函数的良好结果感到惊讶,我还是cython的初学者,所以我希望对提高性能有什么建议?