Ejemplo n.º 1
0
def slice(initial_theta,
          step,
          lnpdf,
          pdf_params,
          create_method='step_out',
          isDomainFinite=[False, False],
          domain=[0., 0.],
          nsamples=1,
          randomize_directions=True,
          callback=None):
    """
    NAME:
       slice
    PURPOSE:
       simple slice sampling function (e.g., Neal 2003,Mackay 2003)
    INPUT:
       initial_theta - initial sample
       step - stepping out step w
       lnpdf - function evaluating the log of the pdf to be sampled
       pdf_params - parameters to pass to the pdf
       create_method - 'step_out', 'double', or 'whole' (whole only works if the domain is finite; defaults to 'double')
       nsamples - number of samples desired
       randomize_directions - (bool) pick a random coordinate to update
       isDomainFinite - is the domain finite? [bool,bool]
       domain - the domain if it is finite (has no effect if the domain is not finite)
       callback - function of current parameters to call after each new sample
    OUTPUT:
       list of samples, number if nsamples=1
    REVISION HISTORY:
       2009-10-29 - Written - Bovy (NYU)
    """
    try:
        ndim = len(initial_theta)
    except TypeError:
        ndim = 1
    if ndim == 1:  #1D
        return bovy_mcmc_oned.slice(initial_theta,
                                    step,
                                    lnpdf,
                                    pdf_params,
                                    create_method=create_method,
                                    isDomainFinite=isDomainFinite,
                                    domain=domain,
                                    nsamples=nsamples,
                                    callback=callback)
    else:  #multi-D
        return bovy_mcmc_multid.slice(initial_theta,step,lnpdf,pdf_params,
                                      create_method=create_method,
                                      isDomainFinite=isDomainFinite,
                                      domain=domain,
                                      nsamples=nsamples,
                                      randomize_directions=\
                                          randomize_directions,
                                      callback=callback)
Ejemplo n.º 2
0
def slice(initial_theta,step,lnpdf,pdf_params,create_method='step_out',
          isDomainFinite=[False,False],domain=[0.,0.],
          nsamples=1,randomize_directions=True,callback=None):
    """
    NAME:
       slice
    PURPOSE:
       simple slice sampling function (e.g., Neal 2003,Mackay 2003)
    INPUT:
       initial_theta - initial sample
       step - stepping out step w
       lnpdf - function evaluating the log of the pdf to be sampled
       pdf_params - parameters to pass to the pdf
       create_method - 'step_out', 'double', or 'whole' (whole only works if the domain is finite; defaults to 'double')
       nsamples - number of samples desired
       randomize_directions - (bool) pick a random coordinate to update
       isDomainFinite - is the domain finite? [bool,bool]
       domain - the domain if it is finite (has no effect if the domain is not finite)
       callback - function of current parameters to call after each new sample
    OUTPUT:
       list of samples, number if nsamples=1
    REVISION HISTORY:
       2009-10-29 - Written - Bovy (NYU)
    """
    try:
        ndim = len(initial_theta)
    except TypeError:
        ndim= 1
    if ndim == 1: #1D
        return bovy_mcmc_oned.slice(initial_theta,step,lnpdf,pdf_params,
                                    create_method=create_method,
                                    isDomainFinite=isDomainFinite,
                                    domain=domain,
                                    nsamples=nsamples,
                                    callback=callback)
    else: #multi-D
        return bovy_mcmc_multid.slice(initial_theta,step,lnpdf,pdf_params,
                                      create_method=create_method,
                                      isDomainFinite=isDomainFinite,
                                      domain=domain,
                                      nsamples=nsamples,
                                      randomize_directions=\
                                          randomize_directions,
                                      callback=callback)
Ejemplo n.º 3
0
def slice(initial_theta,step,lnpdf,pdf_params,create_method='step_out',randomize_directions=True,isDomainFinite=[False,False],domain=[0.,0.],
          nsamples=1,callback=None):
    """
    NAME:
       slice
    PURPOSE:
       simple slice sampling function (e.g., Neal 2003,Mackay 2003)
       performs random, coordinate aligned updates
    INPUT:
       initial_theta - ([k]) initial sample
       step - (1 or [k]) stepping out step w
       lnpdf - function evaluating the log of the pdf to be sampled, 
               arguments are initial_theta + pdf_params
       pdf_params - parameters to pass to the pdf
       create_method - 'step_out', 'double', or whole (string or array of D strings)
       randomize_directions - (bool) pick a random coordinate to update
       isDomainFinite - is the domain finite? [[bool,bool],...]
       domain - the domain if it is finite (has no effect if the domain is not finite) [[0.,0.],...]
       nsamples - number of samples desired
       callback - function of parameter to call after new sample
    OUTPUT:
       list of samples, number if nsamples=1
    REVISION HISTORY:
       2009-10-30 - Written - Bovy (NYU)
    DOCTEST:
    >>> import numpy as nu
    >>> import scipy as sc
    >>> from scipy import linalg
    >>> nu.random.seed(1)
    >>> def lngaussian(x,params):
    ...        return -sc.log(2.*sc.pi)+.5*sc.log(linalg.det(params[1]))-0.5*sc.dot(x-params[0],sc.dot(params[1],x-params[0]))
    >>> lnpdf= lngaussian
    >>> mean= nu.array([0.,0.])
    >>> variance= nu.array([[1.,1],[1,4.]])
    >>> invvar= linalg.inv(variance)
    >>> pdf_params= ([mean,invvar],)
    >>> isDomainFinite= [False,False]
    >>> domain= [0.,0.]
    >>> create_method= 'double'
    >>> nsamples= 10000
    >>> samples= slice(nu.array([0.1,0.1]),1.,lnpdf,pdf_params,create_method,
    ...        True,isDomainFinite,domain,
    ...        nsamples=nsamples)
    >>> samples= nu.array(samples)
    >>> logprecision= -1.5
    >>> assert (nu.mean(samples[:,0])-0.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.mean(samples[:,1])-0.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.std(samples[:,0])-1.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.std(samples[:,1])-2.)**2. < 10.**(logprecision*2.)
    >>> from scipy import stats
    >>> assert (stats.moment(samples[:,0],3)-0.)**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,1],3)-0.)**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,0],4)-stats.norm.moment(4))**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,1]/2.,4)-stats.norm.moment(4))**2. < 10.**(logprecision)
    >>> assert (nu.corrcoef(samples.T)[0,1]-0.5)**2. < 10.**(logprecision)
    """
    out= []
    d= len(initial_theta)
    if not isinstance(isDomainFinite,sc.ndarray):
        isDomainFinite= sc.array(isDomainFinite)
    if not isinstance(domain,sc.ndarray):
        domain= sc.array(domain)
    if isinstance(step,list): step= sc.array(step)
    if isinstance(step,(int,float)) or len(step) == 1:
        step= sc.ones(d)*step
    if len(isDomainFinite.shape) == 1:
        dFinite= []
        for ii in range(d):
            dFinite.append(isDomainFinite)
        isDomainFinite= dFinite
    if len(domain.shape) == 1:
        dDomain= []
        for ii in range(d):
            dDomain.append(domain)
        domain= dDomain
    if not isinstance(create_method,list) or len(create_method) == 1:
        tmp_method= []
        for ii in range(d):
            if isinstance(create_method,list): 
                tmp_method.append(create_method[0])
            else:
                tmp_method.append(create_method)
        create_method= tmp_method
    current_sample= initial_theta.copy()
    params= []
    params.append(lnpdf)
    params.append(pdf_params)
    for ii in range(nsamples):
        if randomize_directions:
            permuterange= sc.random.permutation(d)
        else:
            permuterange= range(d)
        for dd in permuterange:
            thisparams= copy.copy(params)
            thisparams.append(dd)
            thisparams.append([current_sample[jj] for jj in range(d) if jj != dd])#list comprehensions are supposedly faster than numpy slicing
            new_up_sample= oned_mcmc.slice(current_sample[dd],step[dd],oned_lnpdf,(thisparams,),create_method[dd],
                                           isDomainFinite[dd],domain[dd],nsamples=1)
            current_sample= current_sample.copy()
            current_sample[dd]= new_up_sample
        if not callback is None: callback(current_sample)
        out.append(current_sample)
    if nsamples == 1:
        return out[0]
    else:
        return out
Ejemplo n.º 4
0
def slice(initial_theta,
          step,
          lnpdf,
          pdf_params,
          create_method='step_out',
          randomize_directions=True,
          isDomainFinite=[False, False],
          domain=[0., 0.],
          nsamples=1,
          callback=None):
    """
    NAME:
       slice
    PURPOSE:
       simple slice sampling function (e.g., Neal 2003,Mackay 2003)
       performs random, coordinate aligned updates
    INPUT:
       initial_theta - ([k]) initial sample
       step - (1 or [k]) stepping out step w
       lnpdf - function evaluating the log of the pdf to be sampled, 
               arguments are initial_theta + pdf_params
       pdf_params - parameters to pass to the pdf
       create_method - 'step_out', 'double', or whole (string or array of D strings)
       randomize_directions - (bool) pick a random coordinate to update
       isDomainFinite - is the domain finite? [[bool,bool],...]
       domain - the domain if it is finite (has no effect if the domain is not finite) [[0.,0.],...]
       nsamples - number of samples desired
       callback - function of parameter to call after new sample
    OUTPUT:
       list of samples, number if nsamples=1
    REVISION HISTORY:
       2009-10-30 - Written - Bovy (NYU)
    DOCTEST:
    >>> import numpy as nu
    >>> import scipy as sc
    >>> from scipy import linalg
    >>> nu.random.seed(1)
    >>> def lngaussian(x,params):
    ...        return -sc.log(2.*sc.pi)+.5*sc.log(linalg.det(params[1]))-0.5*sc.dot(x-params[0],sc.dot(params[1],x-params[0]))
    >>> lnpdf= lngaussian
    >>> mean= nu.array([0.,0.])
    >>> variance= nu.array([[1.,1],[1,4.]])
    >>> invvar= linalg.inv(variance)
    >>> pdf_params= ([mean,invvar],)
    >>> isDomainFinite= [False,False]
    >>> domain= [0.,0.]
    >>> create_method= 'double'
    >>> nsamples= 10000
    >>> samples= slice(nu.array([0.1,0.1]),1.,lnpdf,pdf_params,create_method,
    ...        True,isDomainFinite,domain,
    ...        nsamples=nsamples)
    >>> samples= nu.array(samples)
    >>> logprecision= -1.5
    >>> assert (nu.mean(samples[:,0])-0.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.mean(samples[:,1])-0.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.std(samples[:,0])-1.)**2. < 10.**(logprecision*2.)
    >>> assert (nu.std(samples[:,1])-2.)**2. < 10.**(logprecision*2.)
    >>> from scipy import stats
    >>> assert (stats.moment(samples[:,0],3)-0.)**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,1],3)-0.)**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,0],4)-stats.norm.moment(4))**2. < 10.**(logprecision)
    >>> assert (stats.moment(samples[:,1]/2.,4)-stats.norm.moment(4))**2. < 10.**(logprecision)
    >>> assert (nu.corrcoef(samples.T)[0,1]-0.5)**2. < 10.**(logprecision)
    """
    out = []
    d = len(initial_theta)
    if not isinstance(isDomainFinite, sc.ndarray):
        isDomainFinite = sc.array(isDomainFinite)
    if not isinstance(domain, sc.ndarray):
        domain = sc.array(domain)
    if isinstance(step, list): step = sc.array(step)
    if isinstance(step, (int, float)) or len(step) == 1:
        step = sc.ones(d) * step
    if len(isDomainFinite.shape) == 1:
        dFinite = []
        for ii in range(d):
            dFinite.append(isDomainFinite)
        isDomainFinite = dFinite
    if len(domain.shape) == 1:
        dDomain = []
        for ii in range(d):
            dDomain.append(domain)
        domain = dDomain
    if not isinstance(create_method, list) or len(create_method) == 1:
        tmp_method = []
        for ii in range(d):
            if isinstance(create_method, list):
                tmp_method.append(create_method[0])
            else:
                tmp_method.append(create_method)
        create_method = tmp_method
    current_sample = initial_theta.copy()
    params = []
    params.append(lnpdf)
    params.append(pdf_params)
    for ii in range(nsamples):
        if randomize_directions:
            permuterange = sc.random.permutation(d)
        else:
            permuterange = range(d)
        for dd in permuterange:
            thisparams = copy.copy(params)
            thisparams.append(dd)
            thisparams.append([
                current_sample[jj] for jj in range(d) if jj != dd
            ])  #list comprehensions are supposedly faster than numpy slicing
            new_up_sample = oned_mcmc.slice(current_sample[dd],
                                            step[dd],
                                            oned_lnpdf, (thisparams, ),
                                            create_method[dd],
                                            isDomainFinite[dd],
                                            domain[dd],
                                            nsamples=1)
            current_sample = current_sample.copy()
            current_sample[dd] = new_up_sample
        if not callback is None: callback(current_sample)
        out.append(current_sample)
    if nsamples == 1:
        return out[0]
    else:
        return out