Numba jitclass:父 class 键入 class 成员
Numba jitclass: parent class type as a class member
考虑 class 自由度及其子粒子组:
class dof():
def getVar(self):
return self.var
spec = [
('var', float64[:]),
('C_s', float64[:]),
]
@jitclass(spec)
class particleGroup(dof):
def __init__(self, partRelease):
self.var = np.array([partRelease.Q, partRelease.M[0], partRelease.M[1], partRelease.M[2], partRelease.B, partRelease.x[0], partRelease.x[1], partRelease.x[2], 0])
self.C_s = np.copy(partRelease.C_s)
def getC(self):
return self.C_s
partRelease 对象的细节并不重要。
class dof 是一个 python class 因为 numba 不支持继承 jitclass。因此,不能在其上使用deferred_type。
dof 可以是不同子 class 的父。我希望 dof class 在另一个 class 中使用,在那里我可以调用父函数 getVar()。
我的问题:如何在另一个class中存储此class(自由度类型或任何子类型)的实例?在 jitclass 规范中指定哪种类型?
Then:即使我可以指定父class类型,我怀疑对python class的调用将是昂贵的。有没有另一种方法可以有效地进行多态性,例如使用模板而不是继承?
我找到了答案(至少是第二个问题)。
解决方案的灵感来自于模板。它包括不使用继承,而是在其接口中具有所需通用功能的不同 classes(这里 getVar)。
spec = [
('var', float64[:]),
('C_s', float64[:]),
]
@jitclass(spec)
class particleGroup():
def __init__(self, val, valCs):
self.var = np.array([val, val, val, val])
self.C_s = np.array([valCs, valCs*2, valCs*3, valCs*4])
def getC(self):
return self.C_s
def getVar(self):
return self.var
spec = [
('var', float64[:]),
]
@jitclass(spec)
class otherDofType():
def __init__(self):
self.var = np.array([1.0, 0.0])
def getVar(self):
return self.var
如果class想使用任意类型对象的通用函数,可以将其定义封装在一个函数中:
def createUserClass(dofType, dofObject):
dof_t = deferred_type()
dof_t.define(dofType)
spec = [
('dof', dof_t),
]
@jitclass(spec)
class UserClass():
def ___init__(self, dof):
self.dof = dof
def resetVar(self):
a = dof.getVar()
a[:] = 0
return UserClass(dofObject)
然后我可以获取和使用 UserClass 的实例,例如:
particleGroupInstance = particleGroup(6.0, 2.0)
userObjectParticleGroup = createUserClass(particleGroup.class_type.instance_type, particleGroupInstance)
userObjectParticleGroup.resetVar()
otherDofTypeInstance = otherDofType()
userObjectOtherDofType = createUserClass(otherDofType.class_type.instance_type, otherDofTypeInstance)
userObjectOtherDofType.resetVar()
它有点笨重但有效并且应该比任何基于继承的解决方案都快...
考虑 class 自由度及其子粒子组:
class dof():
def getVar(self):
return self.var
spec = [
('var', float64[:]),
('C_s', float64[:]),
]
@jitclass(spec)
class particleGroup(dof):
def __init__(self, partRelease):
self.var = np.array([partRelease.Q, partRelease.M[0], partRelease.M[1], partRelease.M[2], partRelease.B, partRelease.x[0], partRelease.x[1], partRelease.x[2], 0])
self.C_s = np.copy(partRelease.C_s)
def getC(self):
return self.C_s
partRelease 对象的细节并不重要。
class dof 是一个 python class 因为 numba 不支持继承 jitclass。因此,不能在其上使用deferred_type。
dof 可以是不同子 class 的父。我希望 dof class 在另一个 class 中使用,在那里我可以调用父函数 getVar()。
我的问题:如何在另一个class中存储此class(自由度类型或任何子类型)的实例?在 jitclass 规范中指定哪种类型?
Then:即使我可以指定父class类型,我怀疑对python class的调用将是昂贵的。有没有另一种方法可以有效地进行多态性,例如使用模板而不是继承?
我找到了答案(至少是第二个问题)。
解决方案的灵感来自于模板。它包括不使用继承,而是在其接口中具有所需通用功能的不同 classes(这里 getVar)。
spec = [
('var', float64[:]),
('C_s', float64[:]),
]
@jitclass(spec)
class particleGroup():
def __init__(self, val, valCs):
self.var = np.array([val, val, val, val])
self.C_s = np.array([valCs, valCs*2, valCs*3, valCs*4])
def getC(self):
return self.C_s
def getVar(self):
return self.var
spec = [
('var', float64[:]),
]
@jitclass(spec)
class otherDofType():
def __init__(self):
self.var = np.array([1.0, 0.0])
def getVar(self):
return self.var
如果class想使用任意类型对象的通用函数,可以将其定义封装在一个函数中:
def createUserClass(dofType, dofObject):
dof_t = deferred_type()
dof_t.define(dofType)
spec = [
('dof', dof_t),
]
@jitclass(spec)
class UserClass():
def ___init__(self, dof):
self.dof = dof
def resetVar(self):
a = dof.getVar()
a[:] = 0
return UserClass(dofObject)
然后我可以获取和使用 UserClass 的实例,例如:
particleGroupInstance = particleGroup(6.0, 2.0)
userObjectParticleGroup = createUserClass(particleGroup.class_type.instance_type, particleGroupInstance)
userObjectParticleGroup.resetVar()
otherDofTypeInstance = otherDofType()
userObjectOtherDofType = createUserClass(otherDofType.class_type.instance_type, otherDofTypeInstance)
userObjectOtherDofType.resetVar()
它有点笨重但有效并且应该比任何基于继承的解决方案都快...