qdsfit/libmath/functions.py

142 lines
3.6 KiB
Python

# coding=utf-8
import warnings
import numpy as np
import yafflib
__author__ = 'markusro'
class Function(object):
def __init__(self):
super(Function, self).__init__()
self._id_string = None
self._num_parameters = None
self._pretty_name = ""
self._function = None
def get_id_string(cls):
if cls._id_string is None:
raise NotImplementedError("You need to set the id_string")
return cls._id_string
def set_id_string(cls, s):
cls._id_string = s
def get_num_paramters(cls):
if cls._num_paramters is None:
raise NotImplementedError("You need to set the num_paramters")
return cls._num_paramters
def set_num_paramters(cls, s):
cls._num_paramters = s
def get_function(cls):
if cls._function is None:
raise NotImplementedError("You need to set f")
return cls._function
def set_function(cls, f):
cls._function = f
def calculate(self, x, p):
if self._function is None: raise NotImplementedError("You need to set f")
data = self._function(x, p)
return x,data[0],data[1]
class HavNegCmplx(Function):
def __init__(self):
super(HavNegCmplx, self).__init__()
self.set_function(hn)
self.set_id_string("hn")
self.set_num_paramters(4)
def hn(p, x):
om = 2*np.pi*x
#hn = om*1j
eps, t, a, b = p
h_n = eps/(1+(1j*om*t)**a)**b
cplx = np.array([h_n.real, -h_n.imag])
return cplx
class ConductivityCmplx(Function):
def __init__(self):
super(ConductivityCmplx, self).__init__()
self.set_num_paramters(3)
self.set_function(cond_cmplx)
self.set_id_string("conductivity")
def cond_cmplx(p, x ):
om = 2*np.pi*x
sgma, isgma, n = p
cond = sgma/(om**n)+isgma/(1j*om**n) # Jonscher (Universal Dielectric Response: e",e' prop sigma/omega**n
cplx = np.array([cond.real, -cond.imag])
return cplx
class PowerCmplx(Function):
def __init__(self):
super(PowerCmplx, self).__init__()
self.set_function(power_cmplx)
self.set_num_paramters(2)
self.set_id_string("power_law")
def power_cmplx( p, x ):
om = 2*np.pi*x
sgma, n = p
power = sgma/(om*1j)**n
cplx = np.array([power.real, -power.imag])
return cplx
class EpsInftyCmplx(Function):
def __init__(self):
super(EpsInftyCmplx, self).__init__()
self.set_function(static_cmplx)
self.set_id_string("e_inf")
self.set_num_paramters(1)
def static_cmplx(p, x ):
eps_inf = p[0]
static = np.ones((2, x.size))*eps_inf
static[1, :] *= 0 # set imag part zero
return static
class YaffCmplx(Function):
def __init__(self):
super(YaffCmplx, self).__init__()
self.set_function(yaff)
self.set_id_string("yaff")
self.set_num_paramters(8)
def yaff( p, x ):
#ya = self.YAFF.yaff(p[:8], x)
ya = yafflib.Yaff.yaff(p[:,0], x)
cplx = np.array([ya.imag, ya.real])
return cplx
class ModelFunction(object):
def __init__(self):
super(ModelFunction, self).__init__(self)
self.model = None
@classmethod
def select_model(self, model):
self._functions_avail = ", ".join( cls().get_id_string() for cls in Function.__subclasses__())
for cls in Function.__subclasses__():
if model == cls().get_id_string():
self.model = cls()
return True
warnings.warn("Function not found: %s \n(available functions: %s)"%(model, self._functions_avail))
return False