Source code for Taweret.mix.gaussian

# SAMBA methods included here: Multivariate BMM
# Written by: Alexandra Semposki
# Authors of SAMBA: Alexandra Semposki, Dick Furnstahl, and Daniel Phillips

# necessary imports
from Taweret.core.base_mixer import BaseMixer
import numpy as np
import sys
sys.path.append('../Taweret')


[docs] class Multivariate(BaseMixer): r''' The multivariate BMM class originally introduced in the BAND SAMBA package. Combines individual models using a Gaussian form. .. math:: f_{\dagger} = \mathcal{N} \left( \sum_i \frac{f_i/v_i}{1/v_i}, \sum_i \frac{1}{v_i} \right) Example: -------- .. code-block:: python m = Multivariate(x=np.linspace(), models=dict(), n_models=0) m.predict(ci=68) m.evaluate_weights() ''' def __init__(self, x, models, n_models=0): ''' Parameters: ----------- x : numpy.linspace Input space variable in which mixing is occurring. models : dict Dict of models with BaseModel methods. n_models : int Number of free parameters per model. Returns: -------- None. ''' # set up the class variables self.model_dict = models self.x = x self.n_models = n_models # convert models dict() to list self.models = [i for i in self.model_dict.values()] # set up weights variable self.var_weights = np.zeros(len(self.models)) return None
[docs] def evaluate(self): ''' Evaluate the mixed model at one set of parameters. Not needed for this mixing method. ''' return None
[docs] def evaluate_weights(self): ''' Calculate the weights for each model in the mixed model over the input space. Returns: -------- weights : numpy.ndarray Array of model weights calculated in the Multivariate.predict function. ''' # check predict() has been called if self.var_weights is np.zeros(len(self.models)): raise Exception('Please run the predict function before\ calling this function.') # return the weights calculated in the predict method return self.var_weights
@property def map(self): ''' Return the MAP values of the parameters. Not needed for this method. ''' return None @property def posterior(self): ''' Return the posterior of the parameters. Not needed for this mixing method. ''' return None
[docs] def predict(self, ci=68): ''' The f_dagger function responsible for mixing the models together in a Gaussian way. Based on the first two moments of the distribution: mean and variance. Parameters: ----------- ci : int, list The desired credibility interval(s) (1-sigma, 2-sigma) Returns: -------- mean, intervals, std_dev : numpy.ndarray The mean, credible intervals, and std_dev of the predicted mixed model ''' # credibility interval(s) self.ci = ci # predict for the two models self.prediction = [] for i in range(len(self.models)): self.prediction.append(self.models[i].evaluate(self.x)) # calculate the models from the class variables f = [] v = [] for i in range(len(self.models)): f.append(self.prediction[i][0].flatten()) v.append(np.square(self.prediction[i][1]).flatten()) # initialise arrays num = np.zeros(len(self.x)) denom = np.zeros(len(self.x)) var = np.zeros(len(self.x)) # sum over the models in the same input space for i in range(len(self.x)): num[i] = np.sum([f[j][i] / v[j][i] for j in range(len(f))]) denom[i] = np.sum([1 / v[j][i] for j in range(len(f))]) # combine everything via input space tracking mean = num / denom var = 1 / denom # variances for each model v = np.asarray(v) weights = 1.0 / v self.var_weights = weights / np.sum(weights, axis=0) # std_dev calculation std_dev = np.sqrt(var) # credibility interval check if self.ci == 68: val = [1.0] elif self.ci == 95: val = [1.96] elif self.ci == [68, 95]: val = [1.0, 1.96] else: raise ValueError('Choose 1 and/or 2 sigma band.') # calculate interval(s) interval_low = [] interval_high = [] for i in range(len(val)): interval_low.append(mean - val[i] * std_dev) interval_high.append(mean + val[i] * std_dev) # combine interval(s) into one list to return interval = [interval_low, interval_high] return 0.0, mean, interval, std_dev
[docs] def predict_weights(self): ''' Predict the weights of the mixed model. Returns mean and intervals from the posterior of the weights. Not needed for this mixing method. ''' return None
@property # @prior.setter def prior(self): ''' Return the prior of the parameters in the mixing. Not needed for this method. ''' return None
[docs] def prior_predict(self): ''' Find the predicted prior distribution. Not needed for this mixing method. ''' return None
[docs] def sample_prior(self): ''' Returns samples from the prior distributions for the various weight parameters. Not needed for this mixing method. ''' return None
[docs] def set_prior(self): ''' Set the priors on the parameters. Not needed for this mixing method. ''' return None
[docs] def train(self): ''' Train the mixed model by optimizing the weights. Not needed in this mixing method. ''' return None