def form_data(self): ''' Form time series data used in lm model. ''' assert self.t is not None, "t is not defined." assert self.y is not None, "y is not defined." globalenv['t'] = FloatVector(self.t) globalenv['y'] = FloatVector(self.y) if self.ysd is None: globalenv['ysd'] = FloatVector(ones_like(self.y)) else: globalenv['ysd'] = FloatVector(self.ysd) _r('the_data <- data.frame(t=t,y=y,ysd=ysd)')
def predict(self, t, level=0.95, interval='none'): ''' Interface of R predict function. ''' globalenv['t_pred'] = FloatVector(t) y=array(_r('predict(fit,data.frame(t=t_pred),level=%f,interval="%s")'%\ (level,interval))) return y
def get_res(self): ''' Return residual of the part of time series that is used in linear regression. Nan is there is no residula available. ''' tp = asarray(_r('resid(fit)')) res = zeros_like(self.t) + nan res[self.subset] = tp return res
def __init__(self): # initialize the r process _r(''' # define a heaviside function: hvsd <- function(x, a = 0){ result = (sign(x-a) + 1.)/2. result } T<-365. Omega<-2*pi/T ''') ## @var if_sea # If consider seasonal signal? self.if_sea = None ## @var if_semi # if consider semisesonal signal? self.if_semi = None ## jumps list self.jumps = None ## data_par : t self.t = None ## y self.y = None ## ysd self.y = None ## linear sections used for linear regression. self.linsecs = None ## record the outliers self.if_outlier = None ## outlier criteri (times of st): self.outlier_cri = 3.0
def lm(self, verbose=True): ''' Do linear regression. ''' self.form_model() self.form_data() self.form_subset() _r('fit <- lm(fml,the_data,subset)') nth = 1 if verbose: print('%dth iter: std(mm)=%.3f vel(mm/yr)=%.3f outliers #:%d'%\ (nth,self.get_res_std()*1000.,self.get_vel()*365.*1000., sum(self.if_outlier))) nth += 1 while self.mark_outliers() > 0: self.form_subset() #_r('fit <- lm(fml,the_data,subset,weights=1/ysd^2)') _r('fit <- update(fit,.~.,subset=subset,weights=1/ysd^2)') if verbose: print('%dth iter: std(mm)=%.3f vel(mm/yr)=%.3f outliers #:%d'%\ (nth,self.get_res_std()*1000.,self.get_vel()*365.*1000., sum(self.if_outlier))) nth += 1
def get_magnitude_semiseasonal(self): S = _r("fit$coe[['sin(2 * Omega * t)']]")[0] C = _r("fit$coe[['cos(2 * Omega * t)']]")[0] return sqrt(S**2 + C**2)
def get_jumps(self): ''' Reture jumps and their value. ''' for jump in self.jumps: yield (jump, _r("fit$coe[['hvsd(t, %d)']]" % jump)[0])
def get_vel_sd(self): ''' ''' return _r("summary(fit)$coef['t','Std. Error']")[0]
def get_vel(self): ''' ''' return _r("fit$coe[['t']]")[0]
def get_res_time_series(self): res = asarray(_r('resid(fit)')) return res, self.t[self.subset]
def get_res_std(self): ''' Return standard error of residuls. ''' return float(_r("summary(fit)$sigma")[0])
if __name__ == '__main__': # local testing code mod = PreRModel() # model: mod.if_sea = True mod.if_semi = True mod.jumps = [] # data: tp = loadtxt('../J550.IGS08') t = tp[:, 0] e = tp[:, 1] * 1000. t_eq = 55631 mod.t = t mod.y = e mod.linsecs = [[-inf, 55631]] mod.lm() print(_r('summary(fit)')) print(_r('coef(summary(fit))')) plot(mod.t, mod.get_res(), 'x') res = mod.predict_res(mod.t[mod.if_outlier], mod.y[mod.if_outlier]) plot(mod.t[mod.if_outlier], res, 'r.') show()