⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linmix_err.pro

📁 basic median filter simulation
💻 PRO
📖 第 1 页 / 共 4 页
字号:
                    logpost[i] = logpost_new
                    
                endif
                
            endfor
                                ;get pi|G, can do exact Gibbs sampler
                                ;for this
            if ngauss eq 1 then pi[*,i] = 1d else $
              pi[*,i] = randomdir(seed, nk + 1)

        endelse
        
;finally, update parameters for prior distribution, only do this if
;more than one gaussian
        
        if ngauss gt 1 then begin

            if gibbs then begin
                
                repeat mu0[i] = mean(mu[*,i]) + sqrt(usqr[i] / ngauss) * randomn(seed) $
                  until (mu0[i] gt mu0min) and (mu0[i] lt mu0max)

            endif else begin
                
                loglik = loglik_mixerr( x, ygibbs, xvar, yvar, xycov, delta, theta, $
                                        pi[*,i], mu[*,i], tausqr[*,i], Glabel[*,i] )
                
                muprop = mu0[i] + sqrt(jvar_mu0) * randomn(seed)

                if muprop gt mu0min and muprop lt mu0max then begin

                    logprior_old = logprior_mixerr(mu[*,i], mu0[i], tausqr[*,i], usqr[i], wsqr[i])
                    logprior_new = logprior_mixerr(mu[*,i], muprop, tausqr[*,i], usqr[i], wsqr[i])
                    
                    logpost_new = loglik + logprior_new
                    logpost_old = loglik + logprior_old
                    
                    accept = linmix_metro_update( logpost_new, logpost_old, seed )
                    
                    if accept then begin
                        
                        naccept[2 + 2 * ngauss] = naccept[2 + 2 * ngauss] + 1L
                        mu0[i] = muprop
                        logpost[i] = loglik + logprior_new
                        
                    endif
                
                endif

            endelse

            if gibbs then begin
                
                nu = ngauss + nuu
                usqr0 = (nuu * wsqr[i] + total( (mu[*,i] - mu0[i])^2 )) / nu
                
                repeat usqr[i] = usqr0 * nu / randomchi(seed, nu) $
                  until usqr[i] le umax
                
            endif else begin
                                ;do metropolis update

                log_usqr = alog(usqr[i]) + sqrt(jvar_usqr) * randomn(seed)
                usqr0 = exp(log_usqr)
                
                if usqr0 le umax then begin

                    logprior_old = logprior_mixerr(mu[*,i], mu0[i], tausqr[*,i], usqr[i], wsqr[i])
                    
                    logpost[i] = loglik + logprior_old ;update posterior after gibbs step for mu0
                    
                    logprior_new = logprior_mixerr(mu[*,i], mu0[i], tausqr[*,i], usqr0, wsqr[i])
                    
                    logpost_new = loglik + logprior_new
                    logpost_old = loglik + logprior_old
                    
                    log_jrat = log_usqr - alog(usqr[i])
                    
                    accept = linmix_metro_update( logpost_new, logpost_old, seed, log_jrat )
                    
                    if accept then begin
                        
                        naccept[3 + 2 * ngauss] = naccept[3 + 2 * ngauss] + 1L
                        usqr[i] = usqr0
                        logpost[i] = loglik + logprior_new
                        
                    endif

                endif
                
            endelse
            
            if gibbs then begin
                
                alphaw = ngauss * nut / 2d + 1
                betaw = 0.5 * nut * total(1d / tausqr[*,i])
                
                wsqr[i] = randomgam(seed, alphaw, betaw)
                
            endif else begin
                
                log_wsqr = alog(wsqr[i]) + sqrt(jvar_wsqr) * randomn(seed)
                wsqr0 = exp(log_wsqr)
                
                logprior_old = logprior_mixerr(mu[*,i], mu0[i], tausqr[*,i], usqr[i], wsqr[i])
                logprior_new = logprior_mixerr(mu[*,i], mu0[i], tausqr[*,i], usqr[i], wsqr0)
                
                logpost_new = loglik + logprior_new + log_wsqr
                logpost_old = loglik + logprior_old + alog(wsqr[i])
                
                accept = linmix_metro_update( logpost_new, logpost_old, seed )
                
                if accept then begin
                    
                    naccept[4 + 2 * ngauss] = naccept[4 + 2 * ngauss] + 1L
                    wsqr[i] = wsqr0
                    logpost[i] = loglik + logprior_new
                    
                endif
                
            endelse

        endif

    endfor

                                ;save Markov Chains
    if iter eq 0 then begin
        
        alphag = alpha
        betag = beta
        sigsqrg = sigsqr
        
        pig = pi
        mug = mu
        tausqrg = tausqr

        if ngauss gt 1 then begin

            mu0g = mu0
            usqrg = usqr
            wsqrg = wsqr
        
        endif

        if metro then logpostg = logpost

    endif else begin
        
        alphag = [alphag, alpha]
        betag = [betag, beta]
        sigsqrg = [sigsqrg, sigsqr]

        pig = [[pig], [pi]]
        mug = [[mug], [mu]]
        tausqrg = [[tausqrg], [tausqr]]
        
        if ngauss gt 1 then begin
        
            mu0g = [mu0g, mu0]
            usqrg = [usqrg, usqr]
            wsqrg = [wsqrg, wsqr]

        endif
        
        if metro then logpostg = [logpostg, logpost]

    endelse
        
    iter = iter + 1L
    
;check for convergence
    
    if iter ge 4 and iter eq checkiter and not burnin then begin

        if not silent and metro then linmix_metro_results, $
          float(naccept) / (nchains * iter), ngauss

        Bvar = dblarr(npar)     ;between-chain variance
        Wvar = dblarr(npar)     ;within-chain variance
        
        psi = dblarr(iter, nchains, npar)
        
        psi[*,*,0] = transpose(reform(alphag, nchains, iter))
        psi[*,*,1] = transpose(reform(betag, nchains, iter))
        psi[*,*,2] = transpose(reform(sigsqrg, nchains, iter))

        pig2 = reform(pig, ngauss, nchains, iter)
        mug2 = reform(mug, ngauss, nchains, iter)
        tausqrg2 = reform(tausqrg, ngauss, nchains, iter)

        psi[*,*,3] = transpose( total(pig2 * mug2, 1) ) ;mean of xi
                                ;variance of xi
        psi[*,*,4] = transpose( total(pig2 * (tausqrg2 + mug2^2), 1) ) - psi[*,*,3]^2
                                ;linear correlation coefficient
                                ;between xi and eta
        psi[*,*,5] = psi[*,*,1] * sqrt(psi[*,*,4] / (psi[*,*,1]^2 * psi[*,*,4] + psi[*,*,2]))
                                ;do normalizing transforms before
                                ;monitering convergence
        psi[*,*,2] = alog(psi[*,*,2])
        psi[*,*,4] = alog(psi[*,*,4])
        psi[*,*,5] = linmix_atanh(psi[*,*,5])

        psi = psi[iter/2:*,*,*] ;discard first half of MCMC

        ndraw = iter / 2
                                ;calculate between- and within-sequence
                                ;                  variances
        for j = 0, npar - 1 do begin
            
            psibarj = total( psi[*,*,j], 1 ) / ndraw
            psibar = mean(psibarj)
            
            sjsqr = 0d
            for i = 0, nchains - 1 do $
              sjsqr = sjsqr + total( (psi[*, i, j] - psibarj[i])^2 ) / (ndraw - 1.0)
            
            Bvar[j] = ndraw / (nchains - 1.0) * total( (psibarj - psibar)^2 )
            Wvar[j] = sjsqr / nchains
            
        endfor
        
        varplus = (1.0 - 1d / ndraw) * Wvar + Bvar / ndraw
        Rhat = sqrt( varplus / Wvar ) ;potential variance scale reduction factor
        
        if total( (Rhat le 1.1) ) eq npar and iter ge miniter then convergence = 1 $
        else if iter ge maxiter then convergence = 1 else begin
            
            if not silent then begin
                print, 'Iteration: ', iter
                print, 'Rhat Values for ALPHA, BETA, log(SIGMA^2), mean(XI), ' + $
                  'log(variance(XI), atanh(corr(XI,ETA)) ): '
                print, Rhat
            endif
            
            checkiter = checkiter + 100L
            
        endelse

    endif
    
    if (burnin) and (iter eq burniter) then begin
;still doing burn-in stage, get new estimates for jumping kernel
;parameters
        
        jvar_ssqr = linmix_robsig( alog(sigsqrg) )^2

                                ;now modify covariance matrix for
                                ;coefficient jumping kernel
        coefg = [[alphag], [betag]]
        
        jvar_coef = correlate( transpose(coefg), /covar)

        if ngauss gt 1 then begin

            jvar_mu0 = linmix_robsig(mu0g)^2 * 2.4^2

            jvar_usqr = linmix_robsig( alog(usqrg) )^2 * 2.4^2
    
            jvar_wsqr = linmix_robsig( alog(wsqrg) )^2 * 2.4^2

        endif
        
        if iter eq burnstop then burnin = 0
        
        if not silent and not burnin then begin
            
            print, 'Burn-in Complete'
            iter = 0L
            
        endif
        
        naccept = lonarr(5 + 2 * ngauss)
        burniter = burniter + 250L
        
    endif
    
endrep until convergence

ndraw = iter * nchains / 2

;save posterior draws in a structure

if ngauss gt 1 then begin

    post = {alpha:0d, beta:0d, sigsqr:0d, pi:dblarr(ngauss), mu:dblarr(ngauss), $
            tausqr:dblarr(ngauss), mu0:0d, usqr:0d, wsqr:0d, ximean:0d, xisig:0d, $
            corr:0d}

endif else begin
    
    post = {alpha:0d, beta:0d, sigsqr:0d, pi:dblarr(ngauss), mu:dblarr(ngauss), $
            tausqr:dblarr(ngauss), ximean:0d, xisig:0d, corr:0d}

endelse

post = replicate(post, ndraw)

post.alpha = alphag[(iter*nchains+1)/2:*]
post.beta = betag[(iter*nchains+1)/2:*]
post.sigsqr = sigsqrg[(iter*nchains+1)/2:*]
post.pi = pig[*,(iter*nchains+1)/2:*]
post.mu = mug[*,(iter*nchains+1)/2:*]
post.tausqr = tausqrg[*,(iter*nchains+1)/2:*]

if ngauss gt 1 then begin

    post.mu0 = mu0g[(iter*nchains+1)/2:*]
    post.usqr = usqrg[(iter*nchains+1)/2:*]
    post.wsqr = wsqrg[(iter*nchains+1)/2:*]

endif

post.ximean = total(post.pi * post.mu, 1) ;mean of xi   
post.xisig = total(post.pi * (post.tausqr + post.mu^2), 1) - post.ximean^2
post.xisig = sqrt(post.xisig)   ;standard deviation of xi

                                ;get linear correlation coefficient
                                ;between xi and eta
post.corr = post.beta * post.xisig / sqrt(post.beta^2 * post.xisig^2 + post.sigsqr)

return
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -