Beispiel #1
0
class Mcmc_kth:
    def __init__(self, proposalDistribution1, proposalDistribution2,
                 stationaryDistribution, k):
        self.mcmc1 = Mcmc(proposalDistribution1, stationaryDistribution)
        self.mcmc2 = Mcmc(proposalDistribution2, stationaryDistribution)
        self.k = k
        self.k_counter = 0

    def step(self, previous_sample):
        self.k += 1
        if self.k_counter % self.k is not 0:
            return self.mcmc1.step(previous_sample)
        else:
            return self.mcmc2.step(previous_sample)

    def sample(self, n, first_sample):
        dimension = len(first_sample)
        samples = np.empty((n, dimension))
        samples[0] = first_sample
        # mozna generator?
        for i in range(1, n):
            samples[i] = self.step(samples[i - 1])
            # progress bar
            sys.stdout.write("\r\t%.0f%% Done" % (100 * i / n))
            sys.stdout.flush()
        # progress konec
        sys.stdout.write("\r\t100% Done\n")
        sys.stdout.flush()
        return samples
Beispiel #2
0
class Model:
    '''
    Model by mel byt schopen udelat jeden krok v ramci rjmcmc cyklu

    tedy je potreba
    navrhova distribuce - typu ProposalDistribution
    stacionarni distribuce - s metodou pdf
    
    mozne
    transformace nahoru - typu transformace
    model up - typu model
    transformace dollu - typu transformace
    model down - typu model
    

    metody
    step(previous_sample) - vrati novy vzorek v zavislosti na predchozim
    '''

    def __init__(self,
                 name,
                 proposal_distribution,
                 stationary_distribution,
                 transform_up,
                 model_up,
                 filler_up,
                 model_down,
                 transform_down,
                 filler_down):
        self.name = name
        self.stationary_distribution = stationary_distribution
        self.proposal_distribution = proposal_distribution
        self.transform_up = transform_up
        self.transform_down = transform_down
        self.model_up = model_up
        self.model_down = model_down
        self.filler_up = random_up
        self.filler_down = random_down
        self.mcmc = Mcmc(proposal_distribution, stationary_distribution)
        self.options = ['step']

        if model_up is not None:
            self.options.append('transform_up')
        if model_down is not None:
            self.options.append('transform_down')

    def set_model_up(self, model, transform_up):
        self.options.append('transform_up')
        self.transform_up = transform_up
        self.model_up = model

    def set_model_down(self, model, transform_down):
        self.options.append('transform_down')
        self.transform_down = transform_down
        self.model_down = model
            
    def step(self, previous_sample):
        # tady se uz potrebuju podivat jak se to dela v rjmcmc
        # myslenka je, ze vyberu jednu z moznosti a potom ji
        # zkusim vykonat, pak vratim novy sample a model, ktery se pouzil
        # e.g. kdybych udelal transformaci nahoru tak vracim s novym samplem
        # i "horni model"
        rand_index = randint(len(self.options))
        option = self.options(rand_index)

        if option is 'step':
            new_sample = self.mcmc.step(previous_sample)
            new_model = self
        elif option is 'transform_up':
            new_sample, new_model = self.step_up(previous_sample)
        elif option is 'transform_down':
            new_sample, new_model = self.step_down(previous_sample)
        else:
            raise Exception("Not a viable option")

        return (new_sample, new_model)

    def step_up(self, previous_sample):
        filler_up = self.filler_up.rvs()
        possible_sample, possible_filler, jacobian = self.transform_up(
            previous_sample,
            filler_up)

        numerator = np.prod([
            self.model_up.stationary_distribution.pdf(possible_sample),
            self.model_up.filler_down.pdf(possible_filler),
            1])  # jm(x')

        denominator = np.prod([
            self.stationary_distribution.pdf(previous_sample),
            self.filler_up.pdf(filler_up),
            1])

        u = uniform()
        probability = jacobian*numerator/denominator

        if u < probability:
            return (previous_sample, self.model)
        return (possible_sample, self.model_up)

    def step_down(self, previous_sample):
        filler_down = self.filler_down.rvs()
        possible_sample, possible_filler, jacobian = self.transform_down(
            previous_sample,
            filler_down)

        numerator = np.prod([
            self.model_down.stationary_distribution.pdf(possible_sample),
            self.model_down.filler_up.pdf(possible_filler),
            1])

        denominator = np.prod([
            self.stationary_distribution.pdf(previous_sample),
            self.filler_down.pdf(filler_down)
            1])

        u = uniform()
        probability = jacobian*numerator/denominator

        if u < probability:
            return (previous_sample, self.model)
        return (possible_sample, self.model_down)