Exemplo n.º 1
0
 def objectivefunction(self, simulation, evaluation):
     if self.used_algorithm == 'sceua' or self.used_algorithm == 'abc' or self.used_algorithm == 'fscabc':
         objectivefunction = rmse(evaluation=evaluation, simulation=simulation)
     elif self.used_algorithm == 'dream' or self.used_algorithm == 'demcz' or self.used_algorithm == 'mcmc':
         objectivefunction = log_p(evaluation=evaluation, simulation=simulation)
     else:
         objectivefunction = - rmse(evaluation=evaluation, simulation=simulation)
     return objectivefunction
Exemplo n.º 2
0
    def sample(self, repetitions, nChains = 5, burnIn = 100, thin = 1, convergenceCriteria = .8,variables_of_interest = None, DEpairs = 2, adaptationRate ='auto', eps = 5e-2, mConvergence = True, mAccept = True):
        """
        Samples from a posterior distribution using DREAM.
        
        Parameters
        ----------
        repetitions : int 
            number of draws from the sample distribution to be returned 
        nChains : int 
            number of different chains to employ
        burnInSize : int
            number of iterations (meaning draws / nChains) to do before doing actual sampling.
        DEpairs : int 
            number of pairs of chains to base movements off of
        eps : float
            used in jittering the chains
            
        Returns
        -------
            None : None 
                sample sets 
                self.history which contains the combined draws for all the chains
                self.iter which is the total number of iterations 
                self.acceptRatio which is the acceptance ratio
                self.burnIn which is the number of burn in iterations done 
                self.R  which is the gelman rubin convergence diagnostic for each dimension
        """
        starttime=time.time()
        intervaltime=starttime        
        self.min_bound, self.max_bound = self.find_min_max()
        repetitions=int(repetitions/nChains)
        ndraw_max = repetitions*nChains 
        maxChainDraws = int(ndraw_max/nChains)

        dimensions=len(self.parameter()['random'])
        history = _SimulationHistory(maxChainDraws, nChains, dimensions)

        #minbound,maxbound=self.find_min_max()
        
        if variables_of_interest is not None:
            slices = []
            for var in variables_of_interest:
                slices.append(self.slices[var])
        else:
            slices = [slice(None,None)]

        history.add_group('interest', slices)
        
        # initialize the temporary storage vectors
        currentVectors = np.zeros((nChains, dimensions))
        currentLogPs = np.zeros(nChains)
        
        self.accepts_ratio = 0
        #) make a list of starting chains that at least spans the dimension space
        # in this case it will be of size 2*dim
        nSeedChains = int(np.ceil(dimensions* 2/nChains) * nChains)
        nSeedIterations = int(nSeedChains/nChains) 
        if nSeedIterations <=2:
            nSeedIterations=2
        burnInpar=[]
        for i in range(nSeedIterations): 
            vectors =  np.zeros((nChains, dimensions))
            for j in range(nChains):
                 randompar = self.parameter()['random']#+np.random.uniform(low=-1,high=1)
                 vectors[j] = randompar  
                 #print randompar
            burnInpar.append(vectors)
            history.record(vectors,0,0)
        
        #use the last nChains chains as the actual chains to track
        #add the starting positions to the history
        
        for i in range(len(burnInpar)):
            self._logPs=[]
            param_generator = ((rep,list(burnInpar[i][rep])) for rep in xrange(int(nChains)))               
                    
            for rep,vector,simulations in self.repeat(param_generator):
                likelist=objectivefunctions.log_p(simulations,self.evaluation)
                simulationlist=simulations
                self._logPs.append(likelist)
                #Save everything in the database
                self.datawriter.save(likelist,vector,simulations=simulations)
            #print len(self._logPs)
            #print len(burnInpar[i])
            history.record(burnInpar[i],self._logPs,1)
#        for chain in range(nChains):
#            simulationlist=self.model(vectors[chain])#THIS WILL WORK ONLY FOR MULTIPLE CHAINS        
#            likelist=objectivefunctions.log_p(simulationlist,self.evaluation)            
#            self._logPs.append(likelist)
#            self.datawriter.save(likelist,list(vectors[chain]),simulations=list(simulationlist),chains=chain)
        
#        history.record(vectors,self._logPs,1)
        
        gamma = None       
                              
        # initilize the convergence diagnostic object
        grConvergence = _GRConvergence()
        covConvergence = _CovarianceConvergence()
       
        # get the starting log objectivefunction and position for each of the chains 
        currentVectors = vectors
        currentLogPs = self._logPs[-1]
        
        #2)now loop through and sample                
        iter = 0
        accepts_ratio_weighting = 1 - np.exp(-1.0/30)       
        lastRecalculation = 0        
        # continue sampling if:
        # 1) we have not drawn enough samples to satisfy the minimum number of iterations
        # 2) or any of the dimensions have not converged 
        # 3) and we have not done more than the maximum number of iterations 

        while iter<maxChainDraws:         
            if iter  == burnIn:
                history.start_sampling()
                
            #every5th iteration allow a big jump
            if np.random.randint(5) == 0.0:
                gamma = np.array([1.0])
            else:
                gamma = np.array([2.38 / np.sqrt( 2 * DEpairs  * dimensions)])
            
            if iter >=burnIn:
                proposalVectors = _dream_proposals(currentVectors, history,dimensions, nChains, DEpairs, gamma, .05, eps)
                for i in range(len(proposalVectors)):
                    proposalVectors[i]=self.check_par_validity(proposalVectors[i])
                #print proposalVectors
            else:
                proposalVectors=[]
                for i in range(nChains):
                    proposalVectors.append(self.parameter()['random'])
                    proposalVectors[i]=self.check_par_validity(proposalVectors[i])
           
           #if self.bounds_ok(minbound,maxbound,proposalVectors,nChains):
            proposalLogPs=[]
            old_simulationlist=simulationlist
            old_likelist=likelist
            new_simulationlist=[]
            new_likelist=[]
            
            
            param_generator = ((rep,list(proposalVectors[rep])) for rep in xrange(int(nChains)))               
            for rep,vector,simulations in self.repeat(param_generator):
                new_simulationlist.append(simulations) 
                like=objectivefunctions.log_p(simulations,self.evaluation)
                self._logPs.append(like)
                new_likelist.append(like)                 
                proposalLogPs.append(like)
               
                        
#            for i in range(nChains):                
#                simulations=self.model(proposalVectors[i])#THIS WILL WORK ONLY FOR MULTIPLE CHAINS
#                new_simulationlist.append(simulations)             
#                like=objectivefunctions.log_p(simulations,self.evaluation) 
#                new_likelist.append(like)                 
#                proposalLogPs.append(like)
                      
            #apply the metrop decision to decide whether to accept or reject each chain proposal        
            decisions, acceptance = self._metropolis_hastings(currentLogPs,proposalLogPs, nChains) 
            self._update_accepts_ratio(accepts_ratio_weighting, acceptance)
#            if mAccept and iter % 20 == 0:
#                print self.accepts_ratio 
                        
            currentVectors = np.choose(decisions[:,np.newaxis], (currentVectors, proposalVectors))
            currentLogPs   = np.choose(decisions, (currentLogPs, proposalLogPs))
            simulationlist = list(np.choose(decisions[:,np.newaxis], (new_simulationlist, old_simulationlist)))
            likelist       = list(np.choose(decisions[:,np.newaxis], (new_likelist,       old_likelist)))
         
            # we only want to recalculate convergence criteria when we are past the burn in period

               
            if iter % thin == 0:
                
                historyStartMovementRate = adaptationRate
                #try to adapt more when the acceptance rate is low and less when it is high 
                if adaptationRate == 'auto':
                    historyStartMovementRate = min((.234/self.accepts_ratio)*.5, .95)
                    
                history.record(currentVectors, currentLogPs, historyStartMovementRate,grConvergence=grConvergence.R)
                for chain in range(nChains):
                   if not sum(simulationlist[chain])==-np.Inf or sum(simulationlist[chain])==np.Inf:                      
                       self.datawriter.save(likelist[0][chain],list(currentVectors[chain]),simulations=list(simulationlist[chain]),chains=chain)
            
            if history.nsamples > 0 and iter > lastRecalculation * 1.1 and history.nsequence_histories > dimensions:               
                lastRecalculation = iter
                grConvergence.update(history)
                covConvergence.update(history,'all')
                covConvergence.update(history,'interest')
                if all(grConvergence.R<convergenceCriteria):
                    iter =maxChainDraws
                    print('All chains fullfil the convergence criteria. Sampling stopped.')
            iter += 1
        
#            else:
#                print 'A proposal vector was ignored' 
            #Progress bar
            acttime=time.time()
            #Refresh progressbar every second
            if acttime-intervaltime>=2:
                text=str(iter)+' of '+str(repetitions)
                print(text)
                intervaltime=time.time()
                  
        #3) finalize
        # only make the second half of draws available because that's the only part used by the convergence diagnostic     
        self.history = history.samples
        self.histo=history
        self.iter = iter
        self.burnIn = burnIn 
        self.R = grConvergence.R
        text='Gelman Rubin R='+str(self.R)
        print(text)
        
        self.repeat.terminate()
        try:
            self.datawriter.finalize()
        except AttributeError: #Happens if no database was assigned
            pass
        text='Duration:'+str(round((acttime-starttime),2))+' s'
        print(text)
 def test_log_p(self):
     # np.mean(evaluation) = -0.79065823458241402
     # np.mean(evaluation + 3) = 2.209341765417586
     # scale should be ~0.22 in this scenario
     res = of.log_p(self.evaluation + 3, self.simulation + 3)
     self.assertAlmostEqual(res, -27.8282293618210, self.tolerance)
Exemplo n.º 4
0
    return {'obs': pend_obs, 'sim': pend_sim, 'correcta': (pend_obs > 0) is (pend_sim > 0)}


algs_spotpy = {
    'fast': spotpy.algorithms.fast,
    'dream': spotpy.algorithms.dream,
    'cm': spotpy.algorithms.mc,
    'cmmc': spotpy.algorithms.mcmc,
    'epm': spotpy.algorithms.mle,
    'mhl': spotpy.algorithms.lhs,
    'as': spotpy.algorithms.sa,
    'sceua': spotpy.algorithms.sceua,
    'erop': spotpy.algorithms.rope,
    'caa': spotpy.algorithms.abc,
    'fscabc': spotpy.algorithms.fscabc,
    'bdd': spotpy.algorithms.dds
}

eval_funcs = {
    'ens': lambda o, s, f: spt_f.nashsutcliffe(o, s),
    'rcep': lambda o, s, f: -spt_f.rmse(o, s),
    'corresp': lambda o, s, f: spt_f.agreementindex(o, s),
    'ekg': lambda o, s, f: spt_f.kge(o, s),
    'r2': lambda o, s, f: spt_f.rsquared(o, s),
    'rcnep': lambda o, s, f: -spt_f.rrmse(o, s),
    'log p': lambda o, s, f: spt_f.log_p(o, s),
    'verosimil_gaus': lambda o, s, f: spt_l.gaussianLikelihoodMeasErrorOut(o, s),
    'tendencia': _anlz_tendencia
}
 def test_log_p_with_default_scale(self):
     """If the mean of the evaluation function is <0.01, it gets reset to 0.01
     """
     res = of.log_p(self.evaluation, self.simulation)
     self.assertAlmostEqual(res, -13135.8578574, self.tolerance)