Beispiel #1
0
def rhmc_worker_beta(comm, block_width, start, y, template, theta, mu, sigmasq,
                     region_types, prop_df=5., eps=0.01, n_steps=100,
                     sigmasq_p=1., adj=2., verbose=0):
    # Compute needed data properties
    chrom_length = y.size
    w = template.size/2 + 1

    # Calculate subset of data to work on
    end = min(chrom_length, start + block_width)
    block = slice(max(start-w, 0), min(end+w, chrom_length))
    size_block = block.stop - block.start

    original = slice(start-block.start, size_block - (block.stop-end))

    subset = slice(w*(start!=0)+start-block.start,
                   size_block-w*(end!=chrom_length) - (block.stop-end))
    size_subset = subset.stop - subset.start
    
    beta_block = np.exp(theta[:size_block])
    beta_subset = beta_block[subset]

    # Setup initial return value
    ret_val = np.empty(block_width)

    # Calculate diagonal of Hessian if requested (by setting sigma.p to None)
    if sigmasq_p is None:
        result = lib.deconvolve(lib.loglik_convolve, lib.dloglik_convolve,
                                y[block], region_types[block], template,
                                mu, sigmasq,
                                subset=subset, theta0=beta_block,
                                log=False,
                                messages=0)
        sigmasq_p = lib.ddloglik_diag_convolve(theta=result[0], y=y[block],
                                               region_types=region_types[block],
                                               template=template, mu=mu,
                                               sigmasq=sigmasq,
                                               theta0=beta_block,
                                               subset=subset, log=False)
    sigma_p = np.sqrt(sigmasq_p)

    ## Repeat leapfrog process until valid result is obtained
    #leapfrog_done = False
    #
    #while not leapfrog_done:
    # Draw momentum variables
    p = np.random.randn(size_subset)*sigma_p
    p_0 = p.copy()

    # Initialize new draw of theta
    beta_draw = beta_subset.copy()
    
    # Initial gradient computation
    grad = lib.dloglik_convolve(theta=beta_draw, y=y[block],
                                region_types=region_types[block],
                                template=template, mu=mu, sigmasq=sigmasq,
                                theta0=beta_block, subset=subset, log=False)

    # Run leapfrog iterations
    for i in xrange(n_steps):
        # Half step for momentum
        p -= eps*grad/2.

        # Full step for position
        beta_draw += eps*p/sigmasq_p

        # Reflect to satisfy constraints
        p[beta_draw <= 0] *= -1.
        beta_draw[beta_draw <= 0] *= -1.

        # Update gradient
        grad = lib.dloglik_convolve(theta=beta_draw, y=y[block],
                                    region_types=region_types[block],
                                    template=template, mu=mu,
                                    sigmasq=sigmasq, theta0=beta_block,
                                    subset=subset, log=False)

        # Half step for momentum after reflection
        p -= eps*grad/2.

    # Reverse momentum at end of trajectory to make the proposal symmetric.
    p *= -1.

    # Construct complete proposal for theta
    beta_prop = beta_block.copy()
    beta_prop[subset] = beta_draw

    # Compute log target and kinetic energy differences
    log_target_ratio = -lib.loglik_convolve(theta=beta_prop, y=y[block],
                                            region_types=region_types[block],
                                            template=template, mu=mu,
                                            sigmasq=sigmasq, subset=None,
                                            theta0=beta_prop, log=False)
    log_target_ratio -= -lib.loglik_convolve(theta=beta_block, y=y[block],
                                             region_types=region_types[block],
                                             template=template, mu=mu,
                                             sigmasq=sigmasq, subset=None,
                                             theta0=beta_block, log=False)

    log_kinetic_diff = 0.5*np.sum((p**2 - p_0**2)/sigmasq_p)

    # Execute MH step
    log_accept_prob = log_target_ratio - log_kinetic_diff
    if np.log(np.random.uniform()) < log_accept_prob:
        accept = 1
        ret_val[:end-start] = np.log(beta_prop[original])
    else:
        accept = 0
        ret_val[:end-start] = np.log(beta_block[original])
    
    if verbose > 0:
        print np.mean(sigma_p), np.std(sigma_p), eps, log_accept_prob, accept, start, end

    # Transmit result
    comm.Send(ret_val, dest=MPIROOT, tag=accept)
Beispiel #2
0
def rhmc_worker_beta(comm,
                     block_width,
                     start,
                     y,
                     template,
                     theta,
                     mu,
                     sigmasq,
                     region_types,
                     prop_df=5.,
                     eps=0.01,
                     n_steps=100,
                     sigmasq_p=1.,
                     adj=2.,
                     verbose=0):
    # Compute needed data properties
    chrom_length = y.size
    w = template.size / 2 + 1

    # Calculate subset of data to work on
    end = min(chrom_length, start + block_width)
    block = slice(max(start - w, 0), min(end + w, chrom_length))
    size_block = block.stop - block.start

    original = slice(start - block.start, size_block - (block.stop - end))

    subset = slice(w * (start != 0) + start - block.start,
                   size_block - w * (end != chrom_length) - (block.stop - end))
    size_subset = subset.stop - subset.start

    beta_block = np.exp(theta[:size_block])
    beta_subset = beta_block[subset]

    # Setup initial return value
    ret_val = np.empty(block_width)

    # Calculate diagonal of Hessian if requested (by setting sigma.p to None)
    if sigmasq_p is None:
        result = lib.deconvolve(lib.loglik_convolve,
                                lib.dloglik_convolve,
                                y[block],
                                region_types[block],
                                template,
                                mu,
                                sigmasq,
                                subset=subset,
                                theta0=beta_block,
                                log=False,
                                messages=0)
        sigmasq_p = lib.ddloglik_diag_convolve(
            theta=result[0],
            y=y[block],
            region_types=region_types[block],
            template=template,
            mu=mu,
            sigmasq=sigmasq,
            theta0=beta_block,
            subset=subset,
            log=False)
    sigma_p = np.sqrt(sigmasq_p)

    ## Repeat leapfrog process until valid result is obtained
    #leapfrog_done = False
    #
    #while not leapfrog_done:
    # Draw momentum variables
    p = np.random.randn(size_subset) * sigma_p
    p_0 = p.copy()

    # Initialize new draw of theta
    beta_draw = beta_subset.copy()

    # Initial gradient computation
    grad = lib.dloglik_convolve(theta=beta_draw,
                                y=y[block],
                                region_types=region_types[block],
                                template=template,
                                mu=mu,
                                sigmasq=sigmasq,
                                theta0=beta_block,
                                subset=subset,
                                log=False)

    # Run leapfrog iterations
    for i in xrange(n_steps):
        # Half step for momentum
        p -= eps * grad / 2.

        # Full step for position
        beta_draw += eps * p / sigmasq_p

        # Reflect to satisfy constraints
        p[beta_draw <= 0] *= -1.
        beta_draw[beta_draw <= 0] *= -1.

        # Update gradient
        grad = lib.dloglik_convolve(theta=beta_draw,
                                    y=y[block],
                                    region_types=region_types[block],
                                    template=template,
                                    mu=mu,
                                    sigmasq=sigmasq,
                                    theta0=beta_block,
                                    subset=subset,
                                    log=False)

        # Half step for momentum after reflection
        p -= eps * grad / 2.

    # Reverse momentum at end of trajectory to make the proposal symmetric.
    p *= -1.

    # Construct complete proposal for theta
    beta_prop = beta_block.copy()
    beta_prop[subset] = beta_draw

    # Compute log target and kinetic energy differences
    log_target_ratio = -lib.loglik_convolve(theta=beta_prop,
                                            y=y[block],
                                            region_types=region_types[block],
                                            template=template,
                                            mu=mu,
                                            sigmasq=sigmasq,
                                            subset=None,
                                            theta0=beta_prop,
                                            log=False)
    log_target_ratio -= -lib.loglik_convolve(theta=beta_block,
                                             y=y[block],
                                             region_types=region_types[block],
                                             template=template,
                                             mu=mu,
                                             sigmasq=sigmasq,
                                             subset=None,
                                             theta0=beta_block,
                                             log=False)

    log_kinetic_diff = 0.5 * np.sum((p**2 - p_0**2) / sigmasq_p)

    # Execute MH step
    log_accept_prob = log_target_ratio - log_kinetic_diff
    if np.log(np.random.uniform()) < log_accept_prob:
        accept = 1
        ret_val[:end - start] = np.log(beta_prop[original])
    else:
        accept = 0
        ret_val[:end - start] = np.log(beta_block[original])

    if verbose > 0:
        print np.mean(sigma_p), np.std(
            sigma_p), eps, log_accept_prob, accept, start, end

    # Transmit result
    comm.Send(ret_val, dest=MPIROOT, tag=accept)
Beispiel #3
0
def rhmc_worker_theta(comm, block_width, start, y, template, theta, mu, sigmasq,
                      region_types, prop_df=5., eps_max=0.1, eps_min=0.001,
                      n_steps=100, sigmasq_p=1., adj=10, verbose=0):
    # Compute needed data properties
    chrom_length = y.size
    w = template.size/2 + 1

    # Calculate subset of data to work on
    end = min(chrom_length, start + block_width)
    block = slice(max(start-w, 0), min(end+w, chrom_length))
    size_block = block.stop - block.start

    original = slice(start-block.start, size_block - (block.stop-end))

    subset = slice(w*(start!=0)+start-block.start,
                   size_block-w*(end!=chrom_length) - (block.stop-end))
    size_subset = subset.stop - subset.start
    
    theta_block = theta[:size_block]
    theta_subset = theta_block[subset]

    # Setup initial return value
    ret_val = np.empty(block_width)

    # Calculate diagonal of Hessian if requested (by setting sigma.p to None)
    if sigmasq_p is None:
        result = lib.deconvolve(lib.loglik_convolve, lib.dloglik_convolve,
                                y[block], region_types[block], template,
                                mu, sigmasq,
                                subset=subset, theta0=theta_block,
                                log=True,
                                messages=0)
        sigmasq_p = lib.ddloglik_diag_convolve(theta=result[0], y=y[block],
                                               region_types=region_types[block],
                                               template=template, mu=mu,
                                               sigmasq=sigmasq,
                                               theta0=theta_block,
                                               subset=subset, log=True)
    sigma_p = np.sqrt(sigmasq_p)

    # Draw momentum variables
    p = np.random.randn(size_subset)*sigma_p
    p_0 = p.copy()

    # Repeat leapfrog process until valid result is obtained
    leapfrog_done = False
    eps = np.random.uniform(eps_min, eps_max)
    
    while not leapfrog_done:
        # Initialize new draw of theta
        theta_draw = theta_subset.copy()

        # Run leapfrog iterations
        grad = lib.dloglik_convolve(theta=theta_draw, y=y[block],
                                    region_types=region_types[block],
                                    template=template, mu=mu, sigmasq=sigmasq,
                                    theta0=theta_block, subset=subset, log=True)
        
        # Start with half step for momentum
        p -= eps*grad / 2.
        
        # Alternate full steps for position and momentum
        for i in xrange(n_steps):
            # Full step for position
            theta_draw += eps*p/sigmasq_p
            # Update gradient
            grad = lib.dloglik_convolve(theta=theta_draw, y=y[block],
                                        region_types=region_types[block],
                                        template=template, mu=mu,
                                        sigmasq=sigmasq, theta0=theta_block,
                                        subset=subset, log=True)
            # Full step for momentum, except at the end of the trajectory
            if i<(n_steps - 1): p -= eps*grad

        # Half step for momentum at the end
        p -= eps*grad/2.

        if np.min(np.isfinite(theta_draw)):
            leapfrog_done = True
        else:
            # Restart with smaller step size
            eps /= adj
            p[:] = p_0
            theta_draw[:] = theta_subset

    # Reverse momentum at end of trajectory to make the proposal symmetric.
    p = -p

    # Construct complete proposal for theta
    theta_prop = theta_block.copy()
    theta_prop[subset] = theta_draw

    # Compute log target and kinetic energy differences
    log_target_ratio = -lib.loglik_convolve(theta=theta_prop, y=y[block],
                                            region_types=region_types[block],
                                            template=template, mu=mu,
                                            sigmasq=sigmasq, subset=None,
                                            theta0=theta_prop, log=True)
    log_target_ratio -= -lib.loglik_convolve(theta=theta_block, y=y[block],
                                             region_types=region_types[block],
                                             template=template, mu=mu,
                                             sigmasq=sigmasq, subset=None,
                                             theta0=theta_block, log=True)

    log_kinetic_diff = 0.5*np.sum((p**2 - p_0**2)/sigmasq_p)

    # Execute MH step
    log_accept_prob = log_target_ratio - log_kinetic_diff
    if np.log(np.random.uniform()) < log_accept_prob:
        accept = 1
        ret_val[:end-start] = theta_prop[original]
    else:
        accept = 0
        ret_val[:end-start] = theta_block[original]
    
    if verbose > 0:
        print np.mean(sigma_p), np.std(sigma_p), eps, log_accept_prob, accept, start, end

    if verbose > 1 and np.isnan(log_accept_prob):
        print sigmasq_p.min(), sigmasq_p.mean(), sigmasq_p.max(), sigmasq_p.std()
        print >> sys.stderr, -lib.loglik_convolve(theta=theta_prop, y=y[block],
                                                  region_types=region_types[block],
                                                  template=template, mu=mu,
                                                  sigmasq=sigmasq, subset=None,
                                                  theta0=theta_prop, log=True)
        print >> sys.stderr, -lib.loglik_convolve(theta=theta_block, y=y[block],
                                                  region_types=region_types[block],
                                                  template=template, mu=mu,
                                                  sigmasq=sigmasq, subset=None,
                                                  theta0=theta_block, log=True)
        print >> sys.stderr, log_kinetic_diff
        print >> sys.stderr, log_target_ratio
        print >> sys.stderr, log_accept_prob, accept

    # Transmit result
    comm.Send(ret_val, dest=MPIROOT, tag=accept)
Beispiel #4
0
def rhmc_worker_theta(comm,
                      block_width,
                      start,
                      y,
                      template,
                      theta,
                      mu,
                      sigmasq,
                      region_types,
                      prop_df=5.,
                      eps_max=0.1,
                      eps_min=0.001,
                      n_steps=100,
                      sigmasq_p=1.,
                      adj=10,
                      verbose=0):
    # Compute needed data properties
    chrom_length = y.size
    w = template.size / 2 + 1

    # Calculate subset of data to work on
    end = min(chrom_length, start + block_width)
    block = slice(max(start - w, 0), min(end + w, chrom_length))
    size_block = block.stop - block.start

    original = slice(start - block.start, size_block - (block.stop - end))

    subset = slice(w * (start != 0) + start - block.start,
                   size_block - w * (end != chrom_length) - (block.stop - end))
    size_subset = subset.stop - subset.start

    theta_block = theta[:size_block]
    theta_subset = theta_block[subset]

    # Setup initial return value
    ret_val = np.empty(block_width)

    # Calculate diagonal of Hessian if requested (by setting sigma.p to None)
    if sigmasq_p is None:
        result = lib.deconvolve(lib.loglik_convolve,
                                lib.dloglik_convolve,
                                y[block],
                                region_types[block],
                                template,
                                mu,
                                sigmasq,
                                subset=subset,
                                theta0=theta_block,
                                log=True,
                                messages=0)
        sigmasq_p = lib.ddloglik_diag_convolve(
            theta=result[0],
            y=y[block],
            region_types=region_types[block],
            template=template,
            mu=mu,
            sigmasq=sigmasq,
            theta0=theta_block,
            subset=subset,
            log=True)
    sigma_p = np.sqrt(sigmasq_p)

    # Draw momentum variables
    p = np.random.randn(size_subset) * sigma_p
    p_0 = p.copy()

    # Repeat leapfrog process until valid result is obtained
    leapfrog_done = False
    eps = np.random.uniform(eps_min, eps_max)

    while not leapfrog_done:
        # Initialize new draw of theta
        theta_draw = theta_subset.copy()

        # Run leapfrog iterations
        grad = lib.dloglik_convolve(theta=theta_draw,
                                    y=y[block],
                                    region_types=region_types[block],
                                    template=template,
                                    mu=mu,
                                    sigmasq=sigmasq,
                                    theta0=theta_block,
                                    subset=subset,
                                    log=True)

        # Start with half step for momentum
        p -= eps * grad / 2.

        # Alternate full steps for position and momentum
        for i in xrange(n_steps):
            # Full step for position
            theta_draw += eps * p / sigmasq_p
            # Update gradient
            grad = lib.dloglik_convolve(theta=theta_draw,
                                        y=y[block],
                                        region_types=region_types[block],
                                        template=template,
                                        mu=mu,
                                        sigmasq=sigmasq,
                                        theta0=theta_block,
                                        subset=subset,
                                        log=True)
            # Full step for momentum, except at the end of the trajectory
            if i < (n_steps - 1): p -= eps * grad

        # Half step for momentum at the end
        p -= eps * grad / 2.

        if np.min(np.isfinite(theta_draw)):
            leapfrog_done = True
        else:
            # Restart with smaller step size
            eps /= adj
            p[:] = p_0
            theta_draw[:] = theta_subset

    # Reverse momentum at end of trajectory to make the proposal symmetric.
    p = -p

    # Construct complete proposal for theta
    theta_prop = theta_block.copy()
    theta_prop[subset] = theta_draw

    # Compute log target and kinetic energy differences
    log_target_ratio = -lib.loglik_convolve(theta=theta_prop,
                                            y=y[block],
                                            region_types=region_types[block],
                                            template=template,
                                            mu=mu,
                                            sigmasq=sigmasq,
                                            subset=None,
                                            theta0=theta_prop,
                                            log=True)
    log_target_ratio -= -lib.loglik_convolve(theta=theta_block,
                                             y=y[block],
                                             region_types=region_types[block],
                                             template=template,
                                             mu=mu,
                                             sigmasq=sigmasq,
                                             subset=None,
                                             theta0=theta_block,
                                             log=True)

    log_kinetic_diff = 0.5 * np.sum((p**2 - p_0**2) / sigmasq_p)

    # Execute MH step
    log_accept_prob = log_target_ratio - log_kinetic_diff
    if np.log(np.random.uniform()) < log_accept_prob:
        accept = 1
        ret_val[:end - start] = theta_prop[original]
    else:
        accept = 0
        ret_val[:end - start] = theta_block[original]

    if verbose > 0:
        print np.mean(sigma_p), np.std(
            sigma_p), eps, log_accept_prob, accept, start, end

    if verbose > 1 and np.isnan(log_accept_prob):
        print sigmasq_p.min(), sigmasq_p.mean(), sigmasq_p.max(
        ), sigmasq_p.std()
        print >> sys.stderr, -lib.loglik_convolve(
            theta=theta_prop,
            y=y[block],
            region_types=region_types[block],
            template=template,
            mu=mu,
            sigmasq=sigmasq,
            subset=None,
            theta0=theta_prop,
            log=True)
        print >> sys.stderr, -lib.loglik_convolve(
            theta=theta_block,
            y=y[block],
            region_types=region_types[block],
            template=template,
            mu=mu,
            sigmasq=sigmasq,
            subset=None,
            theta0=theta_block,
            log=True)
        print >> sys.stderr, log_kinetic_diff
        print >> sys.stderr, log_target_ratio
        print >> sys.stderr, log_accept_prob, accept

    # Transmit result
    comm.Send(ret_val, dest=MPIROOT, tag=accept)