def reject(self): self.rejected += 1 if self.verbose: print_(self._id + ' rejecting') # Revert the field evaluation and the rest of the field. self.f_eval.revert() self.f.revert()
def plot_envelope(M,C,mesh): """ plot_envelope(M,C,mesh) plots the pointwise mean +/- sd envelope defined by M and C along their base mesh. :Arguments: - `M`: A Gaussian process mean. - `C`: A Gaussian process covariance - `mesh`: The mesh on which to evaluate the mean and cov. """ try: from pylab import fill, plot, clf, axis x=concatenate((mesh, mesh[::-1])) mean, var = point_eval(M,C,mesh) sig = sqrt(var) mean = M(mesh) y=concatenate((mean-sig, (mean+sig)[::-1])) # clf() fill(x,y,facecolor='.8',edgecolor='1.') plot(mesh, mean, 'k-.') except ImportError: print_("Matplotlib is not installed; plotting is disabled.")
def plot_envelope(M, C, mesh): """ plot_envelope(M,C,mesh) plots the pointwise mean +/- sd envelope defined by M and C along their base mesh. :Arguments: - `M`: A Gaussian process mean. - `C`: A Gaussian process covariance - `mesh`: The mesh on which to evaluate the mean and cov. """ try: from pylab import fill, plot, clf, axis x = concatenate((mesh, mesh[::-1])) mean, var = point_eval(M, C, mesh) sig = sqrt(var) mean = M(mesh) y = concatenate((mean - sig, (mean + sig)[::-1])) # clf() fill(x, y, facecolor='.8', edgecolor='1.') plot(mesh, mean, 'k-.') except ImportError: print_("Matplotlib is not installed; plotting is disabled.")
def wrapped_f(pymc_obj, *args, **kwargs): # Figure out what type of object it is try: values = {} # First try Model type for variable in pymc_obj._variables_to_tally: if self.all_chains: k = pymc_obj.db.chains data = [variable.trace(chain=i) for i in range(k)] else: data = variable.trace() name = variable.__name__ if kwargs.get('verbose'): print_("\nDiagnostic for %s ..." % name) values[name] = f(data, *args, **kwargs) return values except AttributeError: pass try: # Then try Node type if self.all_chains: k = pymc_obj.trace.db.chains data = [pymc_obj.trace(chain=i) for i in range(k)] else: data = pymc_obj.trace() name = pymc_obj.__name__ return f(data, *args, **kwargs) except (AttributeError, ValueError): pass # If others fail, assume that raw data is passed return f(pymc_obj, *args, **kwargs)
def wrapped_f(pymc_obj, *args, **kwargs): # Figure out what type of object it is try: values = {} # First try Model type for variable in pymc_obj._variables_to_tally: if self.all_chains: k = pymc_obj.db.chains data = [variable.trace(chain=i) for i in range(k)] else: data = variable.trace() name = variable.__name__ if kwargs.get('verbose'): print_("\nDiagnostic for %s ..." % name) values[name] = f(data, *args, **kwargs) return values except AttributeError: pass try: # Then try Node type if self.all_chains: k = pymc_obj.trace.db.chains data = [pymc_obj.trace(chain=i) for i in range(k)] else: data = pymc_obj.trace() name = pymc_obj.__name__ return f(data, *args, **kwargs) except (AttributeError,ValueError): pass # If others fail, assume that raw data is passed return f(pymc_obj, *args, **kwargs)
def discrepancy(observed, simulated, expected): """Calculates Freeman-Tukey statistics (Freeman and Tukey 1950) as a measure of discrepancy between observed and r replicates of simulated data. This is a convenient method for assessing goodness-of-fit (see Brooks et al. 2000). D(x|\theta) = \sum_j (\sqrt{x_j} - \sqrt{e_j})^2 :Parameters: observed : Iterable of observed values (length n) simulated : Iterable of simulated values (length rxn) expected : Iterable of expected values (length rxn) :Returns: D_obs : Discrepancy of observed values D_sim : Discrepancy of simulated values """ try: simulated = simulated.astype(float) except AttributeError: simulated = simulated.trace().astype(float) try: expected = expected.astype(float) except AttributeError: expected = expected.trace().astype(float) D_obs = np.sum([(np.sqrt(observed)-np.sqrt(e))**2 for e in expected], 1) D_sim = np.sum([(np.sqrt(s)-np.sqrt(e))**2 for s,e in zip(simulated, expected)], 1) # Print p-value count = sum(s>o for o,s in zip(D_obs,D_sim)) print_('Bayesian p-value: p=%.3f' % (1.*count/len(D_obs))) return D_obs, D_sim
def propose_first(self): """ This method proposes values for stochastics based on the empirical covariance of the values sampled so far. The proposal jumps are drawn from a multivariate normal distribution. """ arrayjump = np.dot( self.proposal_sd, np.random.normal(size=self.proposal_sd.shape[0]), ) # save in case needed for calculating second proposal probability self.arrayjump1 = arrayjump.copy() # is a copy needed? if self.verbose > 2: print_('First jump:', arrayjump) # Update each stochastic individually. for stochastic in self.stochastics: jump = arrayjump[self._slices[stochastic]].squeeze() if np.iterable(stochastic.value): jump = np.reshape( arrayjump[self._slices[stochastic]], np.shape(stochastic.value), ) if self.isdiscrete[stochastic]: jump = round_array(jump) stochastic.value = stochastic.value + jump
def stats(self, alpha=0.05, start=0, batches=100, chain=None, quantiles=(2.5, 25, 50, 75, 97.5)): """ Generate posterior statistics for node. :Parameters: name : string The name of the tallyable object. alpha : float The alpha level for generating posterior intervals. Defaults to 0.05. start : int The starting index from which to summarize (each) chain. Defaults to zero. batches : int Batch size for calculating standard deviation for non-independent samples. Defaults to 100. chain : int The index for which chain to summarize. Defaults to None (all chains). quantiles : tuple or list The desired quantiles to be calculated. Defaults to (2.5, 25, 50, 75, 97.5). """ try: trace = np.squeeze( np.array(self.db.trace(self.name)(chain=chain), float))[start:] n = len(trace) if not n: print_('Cannot generate statistics for zero-length trace in', self.__name__) return return { 'n': n, 'standard deviation': trace.std(0), 'mean': trace.mean(0), '%s%s HPD interval' % (int(100 * (1 - alpha)), '%'): utils.hpd(trace, alpha), 'mc error': batchsd(trace, batches), 'quantiles': utils.quantiles(trace, qlist=quantiles) } except: print_('Could not generate output statistics for', self.name) return
def plot_GP_envelopes(f, x, HPD=[ .25, .5, .95], transx=None, transy=None): """ plot_GP_envelopes(f, x[, HPD, transx, transy]) Plots centered posterior probability envelopes for f, which is a GP instance, which is a function of one variable. :Arguments: - `f`: A GaussianProcess object. - `x`: The mesh on which to plot the envelopes. - `HPD`: A list of values between 0 and 1 giving the probability mass contained in each envelope. - `transx`: Any transformation of the x-axis. - `transy`: Any transformation of the y-axis. """ try: from pymc.Matplot import centered_envelope f_trace = f.trace() x = x.ravel() N = len(f_trace) func_stacks = np.zeros((N, len(x)), dtype=float) def identity(y): return y if transy is None: transy = identity if transx is None: transx = identity # Get evaluations for i in range(N): f = copy(f_trace[i]) func_stacks[i, :] = transy(f(transx(x))) # Plot envelopes HPD = np.sort(HPD) sorted_func_stack = np.sort(func_stacks, 0) for m in HPD[::-1]: env = centered_envelope(sorted_func_stack, m) # from IPython.Debugger import Pdb # Pdb(color_scheme='LightBG').set_trace() env.display(x, alpha=1. - m * .5, new=False) centered_envelope( sorted_func_stack, 0.).display(x, alpha=1., new=False) except ImportError: six.print_('Plotter could not be imported; plotting disabled')
def savestate(self, state): """Save the sampler's state in a state.txt file.""" oldstate = np.get_printoptions() np.set_printoptions(threshold=1e6) try: with open(os.path.join(self._directory, 'state.txt'), 'w') as f: print_(state, file=f) finally: np.set_printoptions(**oldstate)
def propose(self): if self.verbose: print_(self._id + " proposing") fc = pm.gp.fast_matrix_copy eps_p_f = pm.utils.value(self.eps_p_f) f = pm.utils.value(self.f_eval) for i in xrange(len(self.scratch3)): self.scratch3[i] = np.sum(eps_p_f[self.ti[i]] - f[i]) # Compute Cholesky factor of covariance of eps_p_f, C(x,x) + V C_eval_value = pm.utils.value(self.C_eval) C_eval_shape = C_eval_value.shape # Get the Cholesky factor of C_eval, plus the nugget. # I don't think you can use S_eval for speed, unfortunately. in_chol = fc(C_eval_value, self.scratch1) v_val = pm.utils.value(self.V) for i in xrange(pm.utils.value(C_eval_shape)[0]): in_chol[i, i] += v_val[i] / np.alen(self.ti[i]) info = pm.gp.linalg_utils.dpotrf_wrap(in_chol) if info > 0: raise np.linalg.LinAlgError # Compute covariance of f conditional on eps_p_f. offdiag = fc(C_eval_value, self.scratch2) offdiag = pm.gp.trisolve(in_chol, offdiag, uplo="U", transa="T", inplace=True) C_step = offdiag.T * offdiag C_step *= -1 C_step += C_eval_value # Compute mean of f conditional on eps_p_f. for i in xrange(len(self.scratch3)): self.scratch3[i] = np.mean(eps_p_f[self.ti[i]]) m_step = ( pm.utils.value(self.M_eval) + np.dot(offdiag.T, pm.gp.trisolve(in_chol, (self.scratch3 - self.M_eval.value), uplo="U", transa="T")) .view(np.ndarray) .ravel() ) sig_step = C_step info = pm.gp.linalg_utils.dpotrf_wrap(C_step.T) if info > 0: warnings.warn("Full conditional covariance was not positive definite.") return # Update value of f. self.f_eval.value = m_step + np.dot(sig_step, np.random.normal(size=sig_step.shape[1])).view(np.ndarray).ravel() # Propose the rest of the field from its conditional prior. self.f.rand()
def plot_GP_envelopes(f, x, HPD=[.25, .5, .95], transx=None, transy=None): """ plot_GP_envelopes(f, x[, HPD, transx, transy]) Plots centered posterior probability envelopes for f, which is a GP instance, which is a function of one variable. :Arguments: - `f`: A GaussianProcess object. - `x`: The mesh on which to plot the envelopes. - `HPD`: A list of values between 0 and 1 giving the probability mass contained in each envelope. - `transx`: Any transformation of the x-axis. - `transy`: Any transformation of the y-axis. """ try: from pymc.Matplot import centered_envelope f_trace = f.trace() x = x.ravel() N = len(f_trace) func_stacks = np.zeros((N, len(x)), dtype=float) def identity(y): return y if transy is None: transy = identity if transx is None: transx = identity # Get evaluations for i in range(N): f = copy(f_trace[i]) func_stacks[i, :] = transy(f(transx(x))) # Plot envelopes HPD = np.sort(HPD) sorted_func_stack = np.sort(func_stacks, 0) for m in HPD[::-1]: env = centered_envelope(sorted_func_stack, m) # from IPython.Debugger import Pdb # Pdb(color_scheme='LightBG').set_trace() env.display(x, alpha=1. - m * .5, new=False) centered_envelope(sorted_func_stack, 0.).display(x, alpha=1., new=False) except ImportError: six.print_('Plotter could not be imported; plotting disabled')
def stats(self, alpha=0.05, start=0, batches=100, chain=None, quantiles=(2.5, 25, 50, 75, 97.5)): """ Generate posterior statistics for node. :Parameters: name : string The name of the tallyable object. alpha : float The alpha level for generating posterior intervals. Defaults to 0.05. start : int The starting index from which to summarize (each) chain. Defaults to zero. batches : int Batch size for calculating standard deviation for non-independent samples. Defaults to 100. chain : int The index for which chain to summarize. Defaults to None (all chains). quantiles : tuple or list The desired quantiles to be calculated. Defaults to (2.5, 25, 50, 75, 97.5). """ try: trace = np.squeeze( np.array( self.db.trace( self.name)( chain=chain), float))[ start:] n = len(trace) if not n: print_( 'Cannot generate statistics for zero-length trace in', self.__name__) return return { 'n': n, 'standard deviation': trace.std(0), 'mean': trace.mean(0), '%s%s HPD interval' % (int(100 * (1 - alpha)), '%'): utils.hpd(trace, alpha), 'mc error': batchsd(trace, min(n, batches)), 'quantiles': utils.quantiles(trace, qlist=quantiles) } except: print_('Could not generate output statistics for', self.name) return
def hastings_factor(self): tau = 1./(self.adaptive_scale_factor * self.proposal_sd)**2 cur_val = self.stochastic.value last_val = self.stochastic.last_value lp_for = pm.truncnorm_like(cur_val, last_val, tau, self.low_bound, self.up_bound) lp_bak = pm.truncnorm_like(last_val, cur_val, tau, self.low_bound, self.up_bound) if self.verbose > 1: six.print_(self._id + ': Hastings factor %f'%(lp_bak - lp_for)) return lp_bak - lp_for
def hastings_factor(self): tau = 1. / (self.adaptive_scale_factor * self.proposal_sd)**2 cur_val = self.stochastic.value last_val = self.stochastic.last_value lp_for = pm.truncnorm_like(cur_val, last_val, tau, self.low_bound, self.up_bound) lp_bak = pm.truncnorm_like(last_val, cur_val, tau, self.low_bound, self.up_bound) if self.verbose > 1: six.print_(self._id + ': Hastings factor %f' % (lp_bak - lp_for)) return lp_bak - lp_for
def iat(x, maxlag=None): """Calculate the integrated autocorrelation time (IAT), given the trace from a Stochastic.""" if not maxlag: # Calculate maximum lag to which autocorrelation is calculated maxlag = _find_max_lag(x) acr = [autocorr(x, lag) for lag in range(1, maxlag + 1)] # Calculate gamma values gammas = [(acr[2 * i] + acr[2 * i + 1]) for i in range(maxlag // 2)] cut = _cut_time(gammas) if cut + 1 == len(gammas): print_("Not enough lag to calculate IAT") return np.sum(2 * gammas[:cut + 1]) - 1.0
def iat(x, maxlag=None): """Calculate the integrated autocorrelation time (IAT), given the trace from a Stochastic.""" if not maxlag: # Calculate maximum lag to which autocorrelation is calculated maxlag = _find_max_lag(x) acr = [autocorr(x, lag) for lag in range(1, maxlag+1)] # Calculate gamma values gammas = [(acr[2*i]+acr[2*i+1]) for i in range(maxlag//2)] cut = _cut_time(gammas) if cut+1 == len(gammas): print_("Not enough lag to calculate IAT") return np.sum(2*gammas[:cut+1]) - 1.0
def _find_max_lag(x, rho_limit=0.05, maxmaxlag=20000, verbose=0): """Automatically find an appropriate maximum lag to calculate IAT""" # Fetch autocovariance matrix acv = autocov(x) # Calculate rho rho = acv[0,1]/acv[0,0] lam = -1./np.log(abs(rho)) # Initial guess at 1.5 times lambda (i.e. 3 times mean life) maxlag = int(np.floor(3.*lam)) + 1 # Jump forward 1% of lambda to look for rholimit threshold jump = int(np.ceil(0.01*lam)) + 1 T = len(x) while ((abs(rho) > rho_limit) & (maxlag < min(T/2, maxmaxlag))): acv = autocov(x, maxlag) rho = acv[0,1]/acv[0,0] maxlag += jump # Add 30% for good measure maxlag = int(np.floor(1.3*maxlag)) if maxlag >= min(T/2, maxmaxlag): maxlag = min(min(T/2, maxlag), maxmaxlag) "maxlag fixed to %d" % maxlag return maxlag if maxlag <= 1: print_("maxlag = %d, fixing value to 10" % maxlag) return 10 if verbose: print_("maxlag = %d" % maxlag) return maxlag
def _find_max_lag(x, rho_limit=0.05, maxmaxlag=20000, verbose=0): """Automatically find an appropriate maximum lag to calculate IAT""" # Fetch autocovariance matrix acv = autocov(x) # Calculate rho rho = acv[0, 1] / acv[0, 0] lam = -1. / np.log(abs(rho)) # Initial guess at 1.5 times lambda (i.e. 3 times mean life) maxlag = int(np.floor(3. * lam)) + 1 # Jump forward 1% of lambda to look for rholimit threshold jump = int(np.ceil(0.01 * lam)) + 1 T = len(x) while ((abs(rho) > rho_limit) & (maxlag < min(T / 2, maxmaxlag))): acv = autocov(x, maxlag) rho = acv[0, 1] / acv[0, 0] maxlag += jump # Add 30% for good measure maxlag = int(np.floor(1.3 * maxlag)) if maxlag >= min(T / 2, maxmaxlag): maxlag = min(min(T / 2, maxlag), maxmaxlag) "maxlag fixed to %d" % maxlag return maxlag if maxlag <= 1: print_("maxlag = %d, fixing value to 10" % maxlag) return 10 if verbose: print_("maxlag = %d" % maxlag) return maxlag
def propose_second(self): """ This method proposes values for stochastics based on the empirical covariance of the values sampled so far. The proposal jumps are drawn from a multivariate normal distribution. """ arrayjump = self.drscale * np.dot( self.proposal_sd, np.random.normal(size=self.proposal_sd.shape[0]), ) if self.verbose > 2: print_('Second jump:', arrayjump) # Update each stochastic individually. for stochastic in self.stochastics: jump = arrayjump[self._slices[stochastic]].squeeze() if np.iterable(stochastic.value): jump = np.reshape( arrayjump[self._slices[stochastic]], np.shape(stochastic.value), ) if self.isdiscrete[stochastic]: jump = round_array(jump) stochastic.value = stochastic.value + jump arrayjump1 = self.arrayjump1 arrayjump2 = arrayjump self.q = np.exp( -0.5 * ( np.linalg.norm(np.dot(arrayjump2 - arrayjump1, self.proposal_sd_inv), ord=2) ** 2 \ - np.linalg.norm(np.dot(-arrayjump1, self.proposal_sd_inv), ord=2) ** 2 ) )
def discrepancy(observed, simulated, expected): """Calculates Freeman-Tukey statistics (Freeman and Tukey 1950) as a measure of discrepancy between observed and r replicates of simulated data. This is a convenient method for assessing goodness-of-fit (see Brooks et al. 2000). D(x|\theta) = \sum_j (\sqrt{x_j} - \sqrt{e_j})^2 :Parameters: observed : Iterable of observed values (size=(n,)) simulated : Iterable of simulated values (size=(r,n)) expected : Iterable of expected values (size=(r,) or (r,n)) :Returns: D_obs : Discrepancy of observed values D_sim : Discrepancy of simulated values """ try: simulated = simulated.astype(float) except AttributeError: simulated = simulated.trace().astype(float) try: expected = expected.astype(float) except AttributeError: expected = expected.trace().astype(float) # Ensure expected values are rxn expected = np.resize(expected, simulated.shape) D_obs = np.sum([(np.sqrt(observed) - np.sqrt(e))**2 for e in expected], 1) D_sim = np.sum([(np.sqrt(s) - np.sqrt(e))**2 for s, e in zip(simulated, expected)], 1) # Print p-value count = sum(s > o for o, s in zip(D_obs, D_sim)) print_('Bayesian p-value: p=%.3f' % (1. * count / len(D_obs))) return D_obs, D_sim
def callback(p): try: print_('Current log-probability : %f' % self.logp) except ZeroProbability: print_('Current log-probability : %f' % -Inf)
import pymc from pymc import six from . import simple_von_mises model=pymc.MCMC(simple_von_mises) model.sample(iter=1000, burn=500, thin=2) six.print_('mu',model.mu.value) six.print_('kappa',model.kappa.value)
except: pass try: import scipy.stats from scipy import integrate, special from scipy.misc import factorial, comb from scipy.stats import genextreme, exponweib from scipy.optimize import fmin SP = True except: SP = False try: import pylab as P except: six.print_('Plotting disabled') PLOT = False # Some python densities for comparison def cauchy(x, x0, gamma): return 1/pi * gamma/((x-x0)**2 + gamma**2) def gamma(x, alpha, beta): return x**(alpha-1) * exp(-x/beta)/(special.gamma(alpha) * beta**alpha) def multinomial_beta(alpha): nom = (special.gamma(alpha)).prod(0) den = special.gamma(alpha.sum(0)) return nom/den
except: pass try: import scipy.stats from scipy import integrate, special from scipy.misc import factorial, comb from scipy.stats import genextreme, exponweib from scipy.optimize import fmin SP = True except: SP = False try: import pylab as P except: six.print_('Plotting disabled') PLOT = False # Some python densities for comparison def cauchy(x, x0, gamma): return 1 / pi * gamma / ((x - x0)**2 + gamma**2) def gamma(x, alpha, beta): return x**(alpha - 1) * exp( -x / beta) / (special.gamma(alpha) * beta**alpha) def multinomial_beta(alpha): nom = (special.gamma(alpha)).prod(0)
def propose(self): if self.verbose: print_(self._id + ' proposing') fc = pm.gp.fast_matrix_copy eps_p_f = pm.utils.value(self.eps_p_f) f = pm.utils.value(self.f_eval) for i in xrange(len(self.scratch3)): self.scratch3[i] = np.sum(eps_p_f[self.ti[i]] - f[i]) # Compute Cholesky factor of covariance of eps_p_f, C(x,x) + V C_eval_value = pm.utils.value(self.C_eval) C_eval_shape = C_eval_value.shape # Get the Cholesky factor of C_eval, plus the nugget. # I don't think you can use S_eval for speed, unfortunately. in_chol = fc(C_eval_value, self.scratch1) v_val = pm.utils.value(self.V) for i in xrange(pm.utils.value(C_eval_shape)[0]): in_chol[i, i] += v_val[i] / np.alen(self.ti[i]) info = pm.gp.linalg_utils.dpotrf_wrap(in_chol) if info > 0: raise np.linalg.LinAlgError # Compute covariance of f conditional on eps_p_f. offdiag = fc(C_eval_value, self.scratch2) offdiag = pm.gp.trisolve(in_chol, offdiag, uplo='U', transa='T', inplace=True) C_step = offdiag.T * offdiag C_step *= -1 C_step += C_eval_value # Compute mean of f conditional on eps_p_f. for i in xrange(len(self.scratch3)): self.scratch3[i] = np.mean(eps_p_f[self.ti[i]]) m_step = pm.utils.value(self.M_eval) + np.dot( offdiag.T, pm.gp.trisolve(in_chol, (self.scratch3 - self.M_eval.value), uplo='U', transa='T')).view(np.ndarray).ravel() sig_step = C_step info = pm.gp.linalg_utils.dpotrf_wrap(C_step.T) if info > 0: warnings.warn( 'Full conditional covariance was not positive definite.') return # Update value of f. self.f_eval.value = m_step + np.dot( sig_step, np.random.normal(size=sig_step.shape[1])).view( np.ndarray).ravel() # Propose the rest of the field from its conditional prior. self.f.rand()
def step(self): """ Perform the Robust Metropolis step. """ self._current_iter += 1 # Probability and likelihood for s's current value: if self.verbose > 2: print_() print_(self._id + ' getting initial logp.') logp = self.logp_plus_loglike if self.verbose > 2: print_(self._id + ' proposing.') # Sample a candidate value unit_proposal = self.unit_proposal( ) # First get unit proposal from a normal or t distribution. # Now scale this unit proposal if self._dim == 1: centered_proposal = self._cholesky_factor * unit_proposal else: centered_proposal = np.transpose( self._cholesky_factor).dot(unit_proposal) self.stochastic.value = self.stochastic.value + centered_proposal # Probability and likelihood for s's proposed value: try: logp_p = self.logp_plus_loglike except ZeroProbability: # Reject proposal if self.verbose > 2: print_(self._id + ' rejecting due to ZeroProbability.') self.reject() # Increment rejected count self._rejected += 1 if self.verbose > 2: print_(self._id + ' returning.') return if self.verbose > 2: print_('logp_p - logp: ', logp_p - logp) # Evaluate acceptance ratio alpha = min(1.0, np.exp(logp_p - logp)) unif = np.random.uniform() if unif > alpha: # Revert s if fail self.reject() # Increment rejected count self._rejected += 1 if self.verbose > 2: print_(self._id + ' rejecting') else: # Increment accepted count self._accepted += 1 if self.verbose > 2: print_(self._id + ' accepting') if (self._current_iter < self._stop_adapting) & (np.isfinite(alpha)): # Update the scale matrix of the proposals self.update_covar(alpha, unit_proposal, centered_proposal) if self.verbose > 2: print_(self._id + ' returning.')
def step(self): """ Perform the Robust Metropolis step. """ self._current_iter += 1 # Probability and likelihood for s's current value: if self.verbose > 2: print_() print_(self._id + ' getting initial logp.') logp = self.logp_plus_loglike if self.verbose > 2: print_(self._id + ' proposing.') # Sample a candidate value unit_proposal = self.unit_proposal() # First get unit proposal from a normal or t distribution. # Now scale this unit proposal if self._dim == 1: centered_proposal = self._cholesky_factor * unit_proposal else: centered_proposal = np.transpose(self._cholesky_factor).dot(unit_proposal) self.stochastic.value = self.stochastic.value + centered_proposal # Probability and likelihood for s's proposed value: try: logp_p = self.logp_plus_loglike except ZeroProbability: # Reject proposal if self.verbose > 2: print_(self._id + ' rejecting due to ZeroProbability.') self.reject() # Increment rejected count self._rejected += 1 if self.verbose > 2: print_(self._id + ' returning.') return if self.verbose > 2: print_('logp_p - logp: ', logp_p - logp) # Evaluate acceptance ratio alpha = min(1.0, np.exp(logp_p - logp)) unif = np.random.uniform() if unif > alpha: # Revert s if fail self.reject() # Increment rejected count self._rejected += 1 if self.verbose > 2: print_(self._id + ' rejecting') else: # Increment accepted count self._accepted += 1 if self.verbose > 2: print_(self._id + ' accepting') if (self._current_iter < self._stop_adapting) & (np.isfinite(alpha)): # Update the scale matrix of the proposals self.update_covar(alpha, unit_proposal, centered_proposal) if self.verbose > 2: print_(self._id + ' returning.')
def validate(sampler, replicates=20, iterations=10000, burn=5000, thin=1, deterministic=False, db='ram', plot=True, verbose=0): """ Model validation method, following Cook et al. (Journal of Computational and Graphical Statistics, 2006, DOI: 10.1198/106186006X136976). Generates posterior samples based on 'true' parameter values and data simulated from the priors. The quantiles of the parameter values are calculated, based on the samples. If the model is valid, the quantiles should be uniformly distributed over [0,1]. Since this relies on the generation of simulated data, all data stochastics must have a valid random() method for validation to proceed. Parameters ---------- sampler : Sampler An MCMC sampler object. replicates (optional) : int The number of validation replicates (i.e. number of quantiles to be simulated). Defaults to 100. iterations (optional) : int The number of MCMC iterations to be run per replicate. Defaults to 2000. burn (optional) : int The number of burn-in iterations to be run per replicate. Defaults to 1000. thin (optional) : int The thinning factor to be applied to posterior sample. Defaults to 1 (no thinning) deterministic (optional) : bool Flag for inclusion of deterministic nodes in validation procedure. Defaults to False. db (optional) : string The database backend to use for the validation runs. Defaults to 'ram'. plot (optional) : bool Flag for validation plots. Defaults to True. Returns ------- stats : dict Return a dictionary containing tuples with the chi-square statistic and associated p-value for each data stochastic. Notes ----- This function requires SciPy. """ import scipy as sp # Set verbosity for models to zero sampler.verbose = 0 # Specify parameters to be evaluated parameters = sampler.stochastics if deterministic: # Add deterministics to the mix, if requested parameters = parameters | sampler.deterministics # Assign database backend original_backend = sampler.db.__name__ sampler._assign_database_backend(db) # Empty lists for quantiles quantiles = {} if verbose: print_("\nExecuting Cook et al. (2006) validation procedure ...\n") # Loop over replicates for i in range(replicates): # Sample from priors for p in sampler.stochastics: if not p.extended_parents: p.random() # Sample "true" data values for o in sampler.observed_stochastics: # Generate simuated data for data stochastic o.set_value(o.random(), force=True) if verbose: print_("Data for %s is %s" % (o.__name__, o.value)) param_values = {} # Record data-generating parameter values for s in parameters: param_values[s] = s.value try: # Fit models given parameter values sampler.sample(iterations, burn=burn, thin=thin) for s in param_values: if not i: # Initialize dict quantiles[s.__name__] = [] trace = s.trace() q = sum(trace < param_values[s], 0) / float(len(trace)) quantiles[s.__name__].append(open01(q)) # Replace data values for o in sampler.observed_stochastics: o.revert() finally: # Replace data values for o in sampler.observed_stochastics: o.revert() # Replace backend sampler._assign_database_backend(original_backend) if not i % 10 and i and verbose: print_("\tCompleted validation replicate", i) # Replace backend sampler._assign_database_backend(original_backend) stats = {} # Calculate chi-square statistics for param in quantiles: q = quantiles[param] # Calculate chi-square statistics X2 = sum(sp.special.ndtri(q)**2) # Calculate p-value p = sp.special.chdtrc(replicates, X2) stats[param] = (X2, p) if plot: # Convert p-values to z-scores p = copy(stats) for i in p: p[i] = p[i][1] pymc.Matplot.zplot(p, verbose=verbose) return stats
def __init__( self, stochastic, cov=None, delay=1000, interval=200, greedy=True, drscale=0.1, shrink_if_necessary=False, scales=None, verbose=-1, tally=False, ): # Verbosity flag self.verbose = verbose self.accepted = 0 self.rejected = 0 # Just a dummy variable for compatibility with the superclass self.rejected_then_accepted = 0 self.rejected_twice = 0 if not np.iterable(stochastic) or isinstance(stochastic, pymc.Variable): stochastic = [stochastic] # Initialize superclass pymc.StepMethod.__init__(self, stochastic, verbose, tally) self._id = 'DelayedRejectionAdaptiveMetropolis_' + '_'.join( [p.__name__ for p in self.stochastics]) # State variables used to restore the state in a latter session. self._state += [ 'accepted', 'rejected_then_accepted', 'rejected_twice', '_trace_count', '_current_iter', 'C', 'proposal_sd', '_proposal_deviate', '_trace', 'shrink_if_necessary' ] self._tuning_info = ['C'] self.proposal_sd = None self.shrink_if_necessary = shrink_if_necessary # Number of successful steps before the empirical covariance is # computed self.delay = delay # Interval between covariance updates self.interval = interval # Flag for tallying only accepted jumps until delay reached self.greedy = greedy # Scale for second attempt self.drscale = drscale # Initialization methods self.check_type() self.dimension() # Set the initial covariance using cov, or the following fallback mechanisms: # 1. If scales is provided, use it. # 2. If a trace is present, compute the covariance matrix empirically from it. # 3. Use the stochastics value as a guess of the variance. if cov is not None: self.C = cov elif scales: self.C = self.cov_from_scales(scales) else: try: self.C = self.cov_from_trace() except AttributeError: self.C = self.cov_from_value(100.) self.updateproposal_sd() # Keep track of the internal trace length # It may be different from the iteration count since greedy # sampling can be done during warm-up period. self._trace_count = 0 self._current_iter = 0 self._proposal_deviate = np.zeros(self.dim) self.chain_mean = np.asmatrix(np.zeros(self.dim)) self._trace = [] if self.verbose >= 2: print_("Initialization...") print_('Dimension: ', self.dim) print_("C_0: ", self.C) print_("Sigma: ", self.proposal_sd)
from . import PyMCmodel import pymc as pm from pymc import six import numpy as np import matplotlib.pyplot as pl import matplotlib matplotlib.rcParams['axes.facecolor'] = 'w' import time n_iter = 10000 rej = [] times = [] mesh_sizes = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512] for mesh_size in [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]: six.print_(mesh_size) m = PyMCmodel.make_model(mesh_size, False) if mesh_size == 0: sm = pm.gp.MeshlessGPMetropolis(m['sm'].f) else: sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01) t1 = time.time() for i in xrange(n_iter): sm.step() times.append((time.time() - t1) / float(n_iter)) rej.append(sm.rejected / float(sm.rejected + sm.accepted)) m = PyMCmodel.make_model(0, True) sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01) t1 = time.time() for i in xrange(n_iter):
def raftery_lewis(x, q, r, s=.95, epsilon=.001, verbose=1): """ Return the number of iterations needed to achieve a given precision. :Parameters: x : sequence Sampled series. q : float Quantile. r : float Accuracy requested for quantile. s (optional) : float Probability of attaining the requested accuracy (defaults to 0.95). epsilon (optional) : float Half width of the tolerance interval required for the q-quantile (defaults to 0.001). verbose (optional) : int Verbosity level for output (defaults to 1). :Return: nmin : int Minimum number of independent iterates required to achieve the specified accuracy for the q-quantile. kthin : int Skip parameter sufficient to produce a first-order Markov chain. nburn : int Number of iterations to be discarded at the beginning of the simulation, i.e. the number of burn-in iterations. nprec : int Number of iterations not including the burn-in iterations which need to be obtained in order to attain the precision specified by the values of the q, r and s input parameters. kmind : int Minimum skip parameter sufficient to produce an independence chain. :Example: >>> raftery_lewis(x, q=.025, r=.005) :Reference: Raftery, A.E. and Lewis, S.M. (1995). The number of iterations, convergence diagnostics and generic Metropolis algorithms. In Practical Markov Chain Monte Carlo (W.R. Gilks, D.J. Spiegelhalter and S. Richardson, eds.). London, U.K.: Chapman and Hall. See the fortran source file `gibbsit.f` for more details and references. """ if np.rank(x) > 1: return [ raftery_lewis(y, q, r, s, epsilon, verbose) for y in np.transpose(x) ] output = nmin, kthin, nburn, nprec, kmind = pymc.flib.gibbmain( x, q, r, s, epsilon) if verbose: print_("\n========================") print_("Raftery-Lewis Diagnostic") print_("========================") print_() print_( "%s iterations required (assuming independence) to achieve %s accuracy with %i percent probability." % (nmin, r, 100 * s)) print_() print_( "Thinning factor of %i required to produce a first-order Markov chain." % kthin) print_() print_( "%i iterations to be discarded at the beginning of the simulation (burn-in)." % nburn) print_() print_("%s subsequent iterations required." % nprec) print_() print_( "Thinning factor of %i required to produce an independence chain." % kmind) return output
def raftery_lewis(x, q, r, s=.95, epsilon=.001, verbose=1): """ Return the number of iterations needed to achieve a given precision. :Parameters: x : sequence Sampled series. q : float Quantile. r : float Accuracy requested for quantile. s (optional) : float Probability of attaining the requested accuracy (defaults to 0.95). epsilon (optional) : float Half width of the tolerance interval required for the q-quantile (defaults to 0.001). verbose (optional) : int Verbosity level for output (defaults to 1). :Return: nmin : int Minimum number of independent iterates required to achieve the specified accuracy for the q-quantile. kthin : int Skip parameter sufficient to produce a first-order Markov chain. nburn : int Number of iterations to be discarded at the beginning of the simulation, i.e. the number of burn-in iterations. nprec : int Number of iterations not including the burn-in iterations which need to be obtained in order to attain the precision specified by the values of the q, r and s input parameters. kmind : int Minimum skip parameter sufficient to produce an independence chain. :Example: >>> raftery_lewis(x, q=.025, r=.005) :Reference: Raftery, A.E. and Lewis, S.M. (1995). The number of iterations, convergence diagnostics and generic Metropolis algorithms. In Practical Markov Chain Monte Carlo (W.R. Gilks, D.J. Spiegelhalter and S. Richardson, eds.). London, U.K.: Chapman and Hall. See the fortran source file `gibbsit.f` for more details and references. """ if np.rank(x)>1: return [raftery_lewis(y, q, r, s, epsilon, verbose) for y in np.transpose(x)] output = nmin, kthin, nburn, nprec, kmind = pymc.flib.gibbmain(x, q, r, s, epsilon) if verbose: print_("\n========================") print_("Raftery-Lewis Diagnostic") print_("========================") print_() print_("%s iterations required (assuming independence) to achieve %s accuracy with %i percent probability." % (nmin, r, 100*s)) print_() print_("Thinning factor of %i required to produce a first-order Markov chain." % kthin) print_() print_("%i iterations to be discarded at the beginning of the simulation (burn-in)." % nburn) print_() print_("%s subsequent iterations required." % nprec) print_() print_("Thinning factor of %i required to produce an independence chain." % kmind) return output
def __init__(self, input=None, eps=.001, diff_order = 5, verbose=-1): if not scipy_imported: raise ImportError('Scipy must be installed to use NormApprox and MAP.') Model.__init__(self, input, verbose=verbose) # Allocate memory for internal traces and get stochastic slices self._slices = {} self.len = 0 self.stochastic_len = {} self.fitted = False self.stochastic_list = list(self.stochastics) self.N_stochastics = len(self.stochastic_list) self.stochastic_indices = [] self.stochastic_types = [] self.stochastic_type_dict = {} for i in xrange(len(self.stochastic_list)): stochastic = self.stochastic_list[i] # Check types of all stochastics. type_now = check_type(stochastic)[0] self.stochastic_type_dict[stochastic] = type_now if not type_now is float: print_("Warning: Stochastic " + stochastic.__name__ + "'s value is neither numerical nor array with " + \ "floating-point dtype. Recommend fitting method fmin (default).") # Inspect shapes of all stochastics and create stochastic slices. if isinstance(stochastic.value, ndarray): self.stochastic_len[stochastic] = len(ravel(stochastic.value)) else: self.stochastic_len[stochastic] = 1 self._slices[stochastic] = slice(self.len, self.len + self.stochastic_len[stochastic]) self.len += self.stochastic_len[stochastic] # Record indices that correspond to each stochastic. for j in range(len(ravel(stochastic.value))): self.stochastic_indices.append((stochastic, j)) self.stochastic_types.append(type_now) self.data_len = 0 for datum in self.observed_stochastics: self.data_len += len(ravel(datum.value)) # Unpack step self.eps = zeros(self.len,dtype=float) if isinstance(eps,dict): for stochastic in self.stochastics: self.eps[self._slices[stochastic]] = eps[stochastic] else: self.eps[:] = eps self.diff_order = diff_order self._len_range = arange(self.len) # Initialize gradient and Hessian matrix. self.grad = zeros(self.len, dtype=float) self.hess = asmatrix(zeros((self.len, self.len), dtype=float)) self._mu = None # Initialize NormApproxMu object. self.mu = NormApproxMu(self) def func_for_diff(val, index): """ The function that gets passed to the derivatives. """ self[index] = val return self.i_logp(index) self.func_for_diff = func_for_diff
def step(self): """ Perform a Metropolis step. Stochastic parameters are block-updated using a multivariate normal distribution whose covariance is updated every self.interval once self.delay steps have been performed. The AM instance keeps a local copy of the stochastic parameter's trace. This trace is used to computed the empirical covariance, and is completely independent from the Database backend. If self.greedy is True and the number of iterations is smaller than self.delay, only accepted jumps are stored in the internal trace to avoid computing singular covariance matrices. """ # Probability and likelihood for stochastic's current value: # PROBLEM: I am using logp plus loglike everywhere... and I shouldn't be!! TODO logp = self.logp_plus_loglike if self.verbose > 1: print_('Current value: ', self.stoch2array()) print_('Current likelihood: ', logp) # Sample a candidate value self.propose_first() # Metropolis acception/rejection test accept = False try: # Probability and likelihood for stochastic's 1st proposed value: self.logp_p1 = self.logp_plus_loglike logp_p1 = float(self.logp_p1) self.logalpha01 = min(0, logp_p1 - logp) logalpha01 = self.logalpha01 if self.verbose > 2: print_('First proposed value: ', self.stoch2array()) print_('First proposed likelihood: ', logp_p1) if np.log(np.random.random()) < logalpha01: accept = True self.accepted += 1 if self.verbose > 2: print_('Accepted') logp_p = logp_p1 else: if self.verbose > 2: print_('Delaying rejection...') for stochastic in self.stochastics: stochastic.revert() self.propose_second() try: # Probability and likelihood for stochastic's 2nd proposed value: # CHECK THAT THIS IS RECALCULATED WITH PROPOSE_SECODN # CHECK THAT logp_p1 iS NOT CHANGED WHEN THIS IS RECALCD logp_p2 = self.logp_plus_loglike logalpha21 = min(0, logp_p1 - logp_p2) l = logp_p2 - logp q = self.q logalpha_02 = np.log( l * q * (1 - np.exp(logalpha21)) \ / (1 - np.exp(logalpha01)) ) if self.verbose > 2: print_('Second proposed value: ', self.stoch2array()) print_('Second proposed likelihood: ', logp_p2) if np.log(np.random.random()) < logalpha_02: accept = True self.rejected_then_accepted += 1 logp_p = logp_p2 if self.verbose > 2: print_('Accepted after one rejection') else: self.rejected_twice += 1 logp_p = None if self.verbose > 2: print_('Rejected twice') except pymc.ZeroProbability: self.rejected_twice += 1 logp_p = None if self.verbose > 2: print_('Rejected twice') except pymc.ZeroProbability: if self.verbose > 2: print_('Delaying rejection...') for stochastic in self.stochastics: stochastic.revert() self.propose_second() try: # Probability and likelihood for stochastic's proposed value: logp_p2 = self.logp_plus_loglike logp_p1 = -np.inf logalpha01 = -np.inf logalpha21 = min(0, logp_p1 - logp_p2) l = np.exp(logp_p2 - logp) q = self.q logalpha_02 = np.log( l * q * (1 - np.exp(logalpha21)) \ / (1 - np.exp(logalpha01)) ) if self.verbose > 2: print_('Second proposed value: ', self.stoch2array()) print_('Second proposed likelihood: ', logp_p2) if np.log(np.random.random()) < logalpha_02: accept = True self.rejected_then_accepted += 1 logp_p = logp_p2 if self.verbose > 2: print_( 'Accepted after one rejection with ZeroProbability' ) else: self.rejected_twice += 1 logp_p = None if self.verbose > 2: print_('Rejected twice') except pymc.ZeroProbability: self.rejected_twice += 1 logp_p = None if self.verbose > 2: print_('Rejected twice with ZeroProbability Error.') #print_('\n\nRejected then accepted number of times: ',self.rejected_then_accepted) #print_('Rejected twice number of times: ',self.rejected_twice) if (not self._current_iter % self.interval) and self.verbose > 1: print_("Step ", self._current_iter) print_("\tLogprobability (current, proposed): ", logp, logp_p) for stochastic in self.stochastics: print_( "\t", stochastic.__name__, stochastic.last_value, stochastic.value, ) if accept: print_("\tAccepted\t*******\n") else: print_("\tRejected\n") print_("\tAcceptance ratio: ", (self.accepted + self.rejected_then_accepted) / (self.accepted + 2. * self.rejected_then_accepted + 2. * self.rejected_twice)) if self._current_iter == self.delay: self.greedy = False if not accept: self.reject() if accept or not self.greedy: self.internal_tally() if self._current_iter > self.delay and self._current_iter % self.interval == 0: self.update_cov() self._current_iter += 1
from . import PyMCmodel import pymc as pm from pymc import six import numpy as np import matplotlib.pyplot as pl import matplotlib matplotlib.rcParams['axes.facecolor']='w' import time n_iter = 10000 rej = [] times = [] mesh_sizes = [0,1,2,4,8,16,32,64,128,256,512] for mesh_size in [0,1,2,4,8,16,32,64,128,256,512]: six.print_(mesh_size) m = PyMCmodel.make_model(mesh_size, False) if mesh_size==0: sm = pm.gp.MeshlessGPMetropolis(m['sm'].f) else: sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01) t1 = time.time() for i in xrange(n_iter): sm.step() times.append((time.time()-t1)/float(n_iter)) rej.append(sm.rejected/float(sm.rejected + sm.accepted)) m = PyMCmodel.make_model(0, True) sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01) t1 = time.time() for i in xrange(n_iter):
def validate(sampler, replicates=20, iterations=10000, burn=5000, thin=1, deterministic=False, db='ram', plot=True, verbose=0): """ Model validation method, following Cook et al. (Journal of Computational and Graphical Statistics, 2006, DOI: 10.1198/106186006X136976). Generates posterior samples based on 'true' parameter values and data simulated from the priors. The quantiles of the parameter values are calculated, based on the samples. If the model is valid, the quantiles should be uniformly distributed over [0,1]. Since this relies on the generation of simulated data, all data stochastics must have a valid random() method for validation to proceed. Parameters ---------- sampler : Sampler An MCMC sampler object. replicates (optional) : int The number of validation replicates (i.e. number of quantiles to be simulated). Defaults to 100. iterations (optional) : int The number of MCMC iterations to be run per replicate. Defaults to 2000. burn (optional) : int The number of burn-in iterations to be run per replicate. Defaults to 1000. thin (optional) : int The thinning factor to be applied to posterior sample. Defaults to 1 (no thinning) deterministic (optional) : bool Flag for inclusion of deterministic nodes in validation procedure. Defaults to False. db (optional) : string The database backend to use for the validation runs. Defaults to 'ram'. plot (optional) : bool Flag for validation plots. Defaults to True. Returns ------- stats : dict Return a dictionary containing tuples with the chi-square statistic and associated p-value for each data stochastic. Notes ----- This function requires SciPy. """ import scipy as sp # Set verbosity for models to zero sampler.verbose = 0 # Specify parameters to be evaluated parameters = sampler.stochastics if deterministic: # Add deterministics to the mix, if requested parameters = parameters | sampler.deterministics # Assign database backend original_backend = sampler.db.__name__ sampler._assign_database_backend(db) # Empty lists for quantiles quantiles = {} if verbose: print_("\nExecuting Cook et al. (2006) validation procedure ...\n") # Loop over replicates for i in range(replicates): # Sample from priors for p in sampler.stochastics: if not p.extended_parents: p.random() # Sample "true" data values for o in sampler.observed_stochastics: # Generate simuated data for data stochastic o.set_value(o.random(), force=True) if verbose: print_("Data for %s is %s" % (o.__name__, o.value)) param_values = {} # Record data-generating parameter values for s in parameters: param_values[s] = s.value try: # Fit models given parameter values sampler.sample(iterations, burn=burn, thin=thin) for s in param_values: if not i: # Initialize dict quantiles[s.__name__] = [] trace = s.trace() q = sum(trace<param_values[s], 0)/float(len(trace)) quantiles[s.__name__].append(open01(q)) # Replace data values for o in sampler.observed_stochastics: o.revert() finally: # Replace data values for o in sampler.observed_stochastics: o.revert() # Replace backend sampler._assign_database_backend(original_backend) if not i % 10 and i and verbose: print_("\tCompleted validation replicate", i) # Replace backend sampler._assign_database_backend(original_backend) stats = {} # Calculate chi-square statistics for param in quantiles: q = quantiles[param] # Calculate chi-square statistics X2 = sum(sp.special.ndtri(q)**2) # Calculate p-value p = sp.special.chdtrc(replicates, X2) stats[param] = (X2, p) if plot: # Convert p-values to z-scores p = copy(stats) for i in p: p[i] = p[i][1] pymc.Matplot.zplot(p, verbose=verbose) return stats
def __init__(self, input=None, eps=.001, diff_order=5, verbose=-1): if not scipy_imported: raise ImportError( 'Scipy must be installed to use NormApprox and MAP.') Model.__init__(self, input, verbose=verbose) # Allocate memory for internal traces and get stochastic slices self._slices = {} self.len = 0 self.stochastic_len = {} self.fitted = False self.stochastic_list = list(self.stochastics) self.N_stochastics = len(self.stochastic_list) self.stochastic_indices = [] self.stochastic_types = [] self.stochastic_type_dict = {} for i in xrange(len(self.stochastic_list)): stochastic = self.stochastic_list[i] # Check types of all stochastics. type_now = check_type(stochastic)[0] self.stochastic_type_dict[stochastic] = type_now if not type_now is float: print_("Warning: Stochastic " + stochastic.__name__ + "'s value is neither numerical nor array with " + \ "floating-point dtype. Recommend fitting method fmin (default).") # Inspect shapes of all stochastics and create stochastic slices. if isinstance(stochastic.value, ndarray): self.stochastic_len[stochastic] = len(ravel(stochastic.value)) else: self.stochastic_len[stochastic] = 1 self._slices[stochastic] = slice( self.len, self.len + self.stochastic_len[stochastic]) self.len += self.stochastic_len[stochastic] # Record indices that correspond to each stochastic. for j in range(len(ravel(stochastic.value))): self.stochastic_indices.append((stochastic, j)) self.stochastic_types.append(type_now) self.data_len = 0 for datum in self.observed_stochastics: self.data_len += len(ravel(datum.value)) # Unpack step self.eps = zeros(self.len, dtype=float) if isinstance(eps, dict): for stochastic in self.stochastics: self.eps[self._slices[stochastic]] = eps[stochastic] else: self.eps[:] = eps self.diff_order = diff_order self._len_range = arange(self.len) # Initialize gradient and Hessian matrix. self.grad = zeros(self.len, dtype=float) self.hess = asmatrix(zeros((self.len, self.len), dtype=float)) self._mu = None # Initialize NormApproxMu object. self.mu = NormApproxMu(self) def func_for_diff(val, index): """ The function that gets passed to the derivatives. """ self[index] = val return self.i_logp(index) self.func_for_diff = func_for_diff