Skip to content

Commit 8a85ce6

Browse files
a
1 parent 60aad03 commit 8a85ce6

31 files changed

Lines changed: 10169 additions & 451 deletions

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ Imports:
2323
ggplot2,
2424
cowplot(>= 1.1.3),
2525
smashr,
26-
Rcpp
26+
Rcpp,
27+
ebnm,
2728
Suggests:
2829
susieR,
2930
knitr,

NAMESPACE

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ export(L_mixsq)
8282
export(L_mixsq.mixture_normal)
8383
export(L_mixsq.mixture_normal_per_scale)
8484
export(Pois_fSuSiE)
85-
export(Pois_fSuSiE2)
8685
export(TI_regression)
8786
export(TI_regression.susiF)
8887
export(affected_reg)
@@ -152,6 +151,7 @@ export(plot_susiF)
152151
export(plot_susiF_effect)
153152
export(plot_susiF_pip)
154153
export(pois_mean_GP)
154+
export(pois_smooth_split)
155155
export(post_mat_mean)
156156
export(post_mat_mean.mixture_normal)
157157
export(post_mat_mean.mixture_normal_per_scale)
@@ -161,6 +161,7 @@ export(post_mat_sd.mixture_normal_per_scale)
161161
export(remap_data)
162162
export(simu_IBSS_ash_vanilla)
163163
export(simu_IBSS_per_level)
164+
export(smash_dwt)
164165
export(smash_regression)
165166
export(smash_regression.susiF)
166167
export(susiF)
@@ -204,6 +205,11 @@ export(vga_pois_solver_newton_1iter)
204205
export(which_dummy_cs)
205206
export(which_dummy_cs.susiF)
206207
export(which_lowcount)
208+
<<<<<<< Updated upstream
209+
=======
210+
import(ebnm)
211+
import(wavethresh)
212+
>>>>>>> Stashed changes
207213
importFrom(ashr,ash)
208214
importFrom(ashr,calc_loglik)
209215
importFrom(ashr,cdf_post)

R/EB_poisson_mean_routines.R

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,231 @@ pois_mean_GP_opt_obj_gradient = function(theta,x,s,beta,sigma2,n){
469469
pois_mean_GP_obj = function(x,s,beta,sigma2,m,v){
470470
return(sum(x*m-s*exp(m+v/2)-log(sigma2)/2-(m^2+v-2*m*beta+beta^2)/2/sigma2+log(v)/2))
471471
}
472+
473+
474+
475+
476+
477+
478+
479+
#'@title Smooth over-dispersed Poisson sequence
480+
#'@param x data vector
481+
#'@param maxiter,tol max iteration and tolerance for stopping it.
482+
#'@param Eb_init,sigma2_init initial values of smooth mean and nugget effect.
483+
#'@examples
484+
#' set.seed(12345)
485+
#' n=2^9
486+
#' sigma=0.5
487+
#' mu=c(rep(0.3,n/4), rep(3, n/4), rep(10, n/4), rep(0.3, n/4))
488+
#' x = rpois(n,exp(log(mu)+rnorm(n,sd=sigma)))
489+
#' fit = pois_smooth_split(x,maxiter=30)
490+
#' plot(x,col='grey80')
491+
#' lines(exp(fit$Eb))
492+
#' fit$sigma2
493+
#' plot(fit$obj)
494+
#'@details The problem is
495+
#'\deqn{x_i\sim Poisson(\exp(\mu_i)),}
496+
#'\deqn{\mu_i\sim N(b_i,\sigma^2),}
497+
#'\deqn{\b_i\sim g(.).}
498+
#'@export
499+
500+
pois_smooth_split = function(x,
501+
s = NULL,
502+
Eb_init = NULL,
503+
sigma2_init = NULL,
504+
est_sigma2 = TRUE,
505+
maxiter = 100,
506+
tol=1e-5,
507+
filter.number = 1,
508+
family = 'DaubExPhase',
509+
verbose=FALSE,
510+
printevery = 10,
511+
ebnm_params=list(mode=0),
512+
optim_method='L-BFGS-B'){
513+
514+
n = length(x)
515+
if(is.null(s)){
516+
s = 1
517+
}
518+
if(length(s)==1){
519+
s = rep(s,n)
520+
}
521+
if(is.null(Eb_init)){
522+
Eb = log(runmed(x/s,1 + 2 * min((n-1)%/% 2, ceiling(0.1*n)))+0.01)
523+
}else{
524+
Eb = Eb_init
525+
}
526+
if(is.null(sigma2_init)){
527+
sigma2 = var(log(x/s+0.01)-Eb)
528+
}else{
529+
sigma2 = sigma2_init
530+
}
531+
532+
W = (t(wavethresh::GenW(n,filter.number,family)))[-1,]
533+
534+
mu_pm = rep(0,n)
535+
mu_pv = rep(1/n,n)
536+
obj = -Inf
537+
538+
for(iter in 1:maxiter){
539+
# get m, s^2
540+
opt = optim(c(mu_pm,log(mu_pv)),
541+
fn = pois_mean_GP_opt_obj,
542+
gr = pois_mean_GP_opt_obj_gradient,
543+
x=x,
544+
s=s,
545+
beta=Eb,
546+
sigma2=sigma2,
547+
n=n,
548+
method = optim_method)
549+
mu_pm = opt$par[1:n]
550+
mu_pv = exp(opt$par[(n+1):(2*n)])
551+
qb = smash_dwt(x=mu_pm,
552+
sigma=sqrt(sigma2),
553+
filter.number=filter.number,
554+
family=family,
555+
ebnm_params=ebnm_params,W=W)
556+
Eb = qb$mu.est
557+
Eb2 = qb$mu.est.var + Eb^2
558+
# get sigma2
559+
if(est_sigma2){
560+
sigma2 = mean(mu_pm^2+mu_pv+Eb2-2*mu_pm*Eb)
561+
}
562+
563+
564+
# calc obj
565+
obj[iter+1] = pois_smooth_split_obj(x,s,mu_pm,mu_pv,Eb,Eb2,sigma2,qb$dKL)
566+
567+
if(verbose){
568+
if(iter%%printevery==0){
569+
print(paste("Done iter",iter,"obj =",obj[iter+1]))
570+
}
571+
572+
}
573+
574+
if((obj[iter+1]-obj[iter])<tol){
575+
break
576+
}
577+
578+
}
579+
return(list(Emean = exp(mu_pm+mu_pv/2),
580+
Vmean = exp(mu_pv-1)*exp(2*mu_pm+mu_pv),
581+
Emu=mu_pm,
582+
Vmu=mu_pv,
583+
Eb=Eb,
584+
Eb2=Eb2,
585+
sigma2=sigma2,
586+
obj=obj,
587+
H = qb$dKL + sum(log(2*pi*mu_pv)/2-log(2*pi*sigma2)/2-(mu_pm^2+mu_pv-2*mu_pm*Eb+Eb2)/2/sigma2)))
588+
}
589+
590+
pois_smooth_split_obj = function(x,s,m,s2,Eb,Eb2,sigma2,KLb){
591+
return(sum(x*m-s*exp(m+s2/2)+log(s2)/2-log(sigma2)/2-(m^2+s2-2*m*Eb+Eb2)/2/sigma2)+KLb)
592+
}
593+
594+
595+
596+
#'@title Empirical Bayes wavelet smoothing via DWT
597+
#'@description Smooth homogeneous Gaussian data.
598+
#'@param x data
599+
#'@param sigma known standard error
600+
#'@param filter.number,family wavelet family and filter number as in wavethresh package
601+
#'@param ebnm_params a list of `ebnm` parameters
602+
#'@param W the dwt matrix for calc posterior variance. Remove the first row which is all 1/sqrt(n)
603+
#'@return a list of
604+
#' \item{mu.est:}{posterior mean}
605+
#' \item{mu.est.var:}{posterior variance}
606+
#' \item{loglik:}{log likelihood}
607+
#' \item{dKL:}{KL divergence between g(the prior) and q(the posterior)}
608+
#'@import wavethresh
609+
#'@import ebnm
610+
#'@export
611+
smash_dwt = function(x,sigma,filter.number=1,
612+
family="DaubExPhase",
613+
ebnm_params=list(mode=0),W=NULL){
614+
615+
n = length(x)
616+
J = log(n,2)
617+
if(ceiling(J)!=floor(J)){
618+
stop('Length of x must be power of 2')
619+
}
620+
if(is.null(ebnm_params)){
621+
ebnm_params = ebnm_params_default()
622+
}else{
623+
temp = ebnm_params_default()
624+
for(i in 1:length(ebnm_params)){
625+
temp[[names(ebnm_params)[i]]] = ebnm_params[[i]]
626+
}
627+
ebnm_params = temp
628+
}
629+
tsum = sum(x)/sqrt(n)
630+
x.w = wd(x, filter.number = filter.number,
631+
family = family, type = "wavelet")
632+
633+
data.var = sigma^2
634+
if(length(data.var==1)){
635+
data.var = rep(data.var,n)
636+
}
637+
638+
if(is.null(W)){
639+
W = (t(GenW(n,filter.number,family)))[-1,]
640+
}
641+
642+
if(length(sigma)==1){
643+
x.w.v = rep(sigma^2,n-1)
644+
tsum.var = sigma^2
645+
}else{
646+
x.w.v = data.var
647+
tsum.var = x.w.v[1]
648+
x.w.v = x.w.v[-1]
649+
}
650+
651+
dKL = 0
652+
loglik.scale = c()
653+
x.w.v.s = rep(0, 2^J-1)
654+
for (j in 0:(J - 1)) {
655+
x.pm = rep(0, 2^j)
656+
#index = (((J - 1) - j) * n + 1):((J - j) * n)
657+
index = (n-2^(j+1)+1):(n-2^j)
658+
x.w.j = accessD(x.w, j)
659+
x.w.v.j = x.w.v[index]
660+
ind.nnull = (x.w.v.j != 0)
661+
662+
a = ebnm(x.w.j[ind.nnull],sqrt(x.w.v.j[ind.nnull]),
663+
mode=ebnm_params$mode,
664+
prior_family=ebnm_params$prior_family,
665+
scale = ebnm_params$scale,
666+
g_init = ebnm_params$g_init,
667+
fix_g = ebnm_params$fix_g,
668+
output = ebnm_params$output,
669+
optmethod = ebnm_params$optmethod)
670+
671+
dKL = dKL + a$log_likelihood - Eloglik_GP(x.w.j[ind.nnull], sqrt(x.w.v.j[ind.nnull]),a$posterior$mean, a$posterior$mean^2+a$posterior$sd^2)
672+
x.pm[ind.nnull] = a$posterior$mean
673+
x.pm[!ind.nnull] = 0
674+
x.w = putD(x.w, j, x.pm)
675+
loglik.scale[j + 1] = a$log_likelihood
676+
x.w.v.s[index[ind.nnull]] = a$posterior$sd^2
677+
x.w.v.s[index[!ind.nnull]] = 0
678+
}
679+
mu.est = wr(x.w)
680+
loglik = sum(loglik.scale)
681+
#x.w.v.s = c(tsum.var,x.w.v.s)
682+
mu.est.var = colSums(W^2*x.w.v.s)
683+
return(list(mu.est=mu.est,mu.est.var=mu.est.var,loglik = loglik,dKL = dKL))
684+
}
685+
686+
687+
688+
Eloglik_GP = function(x, s, Et, Et2) {
689+
# Deal with infinite SEs:
690+
idx = is.finite(s)
691+
x = x[idx]
692+
s = s[idx]
693+
Et = Et[idx]
694+
Et2 = Et2[idx]
695+
return(-0.5 * sum(log(2*pi*s^2) + (1/s^2) * (Et2 - 2*x*Et + x^2)))
696+
}
697+
698+
699+

0 commit comments

Comments
 (0)