def get_confidence_bounds(self, confidence_level=0.68, cache=False ): """ Computes the marginal 1D confidence bounds on the Fisher parameters :param confidence_level: (optional) C.L. of the bounds. Default 68%. :type confidence_level: :class:`float` in [0,1] :param cache: (optional) wether to use cached results or compute everything again :type cache: bool """ # check input: if confidence_level<0.0 or confidence_level>1.0: raise ValueError('Invalid confidence level. Legal input is between 0 and 1.') # invert the Fisher matrix: if cache: fisher_matrix_inv_temp = self.fisher_matrix_inv else: fisher_matrix_inv_temp = self.inverse_fisher_matrix() # compute the coefficient that correspond to the desired confidence level: coefficient = fu.confidence_coefficient( confidence_level ) # compute the result: return coefficient*np.sqrt( np.diagonal( fisher_matrix_inv_temp ) )
def compute_ellipse(self, params1=None, params2=None, confidence_level=0.68, names=None, num_points=100): """ Function that computes the (2D) ellipses for a given parameters combination. Returns a dictionary with all the meaningul information about the ellipses. :param params1: name of the first parameter or list of names of parameters. :type params1: a :class:`string` or a :class:`list` of :class:`string` :param params2: name of the second parameter or list of names of parameters. :type params3: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param num_points: number of (x,y) points. :type num_points: :class:`int` :returns: a dictionary mapping name and parameters to a tuple of: [x, y, [fiducial_x, fiducial_y, coeff_a, coeff_b, theta_0]] :rtype: :class:`dict` """ # process names: if names==None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params1==None: params_temp_1 = total_paramnames_list else: params_temp_1 = [ i for i in fu.make_list(params1) if i in total_paramnames_list ] if params2==None: params_temp_2 = total_paramnames_list else: params_temp_2 = [ i for i in fu.make_list(params2) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient( confidence_level ) # get the distributions: gaussian_distro = {} for par1 in params_temp_1: dict_names_1 = {} for par2 in params_temp_2: dict_names_2 = {} for mat,name in zip(fisher_temp_list,names_temp): # get the index of the parameter: try: index_1 = mat.get_param_index(par1) index_2 = mat.get_param_index(par2) except: dict_names_2[name] = [np.array([0.0]), np.array([0.0]), [0.0, 0.0, 0.0, 0.0, 0.0]] continue # get sigmas: sigma_x = mat.get_fisher_inverse()[index_1,index_1] sigma_y = mat.get_fisher_inverse()[index_2,index_2] sigma_xy = mat.get_fisher_inverse()[index_1,index_2] # get fiducial: fiducial_x = mat.get_fiducial(par1) fiducial_y = mat.get_fiducial(par2) # compute the ellipse coefficients: coeff_a = confidence_coefficient*math.sqrt((sigma_x + sigma_y)/2.0 + math.sqrt( (sigma_x - sigma_y)**2/4.0 + sigma_xy**2 )) coeff_b = confidence_coefficient*math.sqrt((sigma_x + sigma_y)/2.0 - math.sqrt( (sigma_x - sigma_y)**2/4.0 + sigma_xy**2 )) theta_0 = math.atan2( (2.0*sigma_xy), (sigma_x - sigma_y) )/2.0 # generate the ellipses angles = np.linspace( 0, 2.0*math.pi, num_points ) x_points = np.array( [+coeff_a*math.cos(theta)*math.cos(theta_0) -coeff_b*math.sin(theta)*math.sin(theta_0) + fiducial_x for theta in angles ] ) y_points = np.array( [+coeff_a*math.cos(theta)*math.sin(theta_0) +coeff_b*math.sin(theta)*math.cos(theta_0) + fiducial_y for theta in angles ] ) # save the result: dict_names_2[name] = [x_points, y_points, [fiducial_x, fiducial_y, coeff_a, coeff_b, theta_0]] dict_names_1[par2] = dict_names_2 gaussian_distro[par1] = dict_names_1 return gaussian_distro # ----------------------------------------------------------------------------------- # ***************************************************************************************
def compute_gaussian( self, params=None, confidence_level=0.68, names=None, num_points=100, normalized=False, nice_bounds=True ): """ Function that computes the (1D) gaussian distribution of a given parameter. Returns a dictionary with all the meaningul information about the gaussian. :param params: name of the parameter or list of names of parameters. :type params: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param num_points: number of (x,y) points. :type num_points: :class:`int` :param normalized: wether the distribution is normalized or not. :type normalized: :class:`bool` :param nice_bounds: wether the x range is properly rounded to be nice or not. :type nice_bounds: :class:`bool` :returns: a dictionary mapping name and parameter to a tuple of: [x, y, [fiducial,sigma]] :rtype: :class:`dict` """ # process names: if names==None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params==None: params_temp = total_paramnames_list else: params_temp = [ i for i in fu.make_list(params) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient( confidence_level ) # get the plot ranges: plot_ranges = self.compute_plot_range( params=params_temp, confidence_level=confidence_level, names=names_temp, nice=nice_bounds ) # get the distributions: gaussian_distro = {} for par1 in params_temp: dict_names = {} for mat,name in zip(fisher_temp_list,names_temp): # get the index of the parameter: try: index = mat.get_param_index(par1) except: dict_names[name] = [np.array([0.0]), np.array([0.0]), [0.0,0.0]] continue # get sigma and fiducial: sigma = math.sqrt( mat.get_fisher_inverse()[index,index] ) fiducial = mat.get_fiducial(par1) # get optimal x: if nice_bounds: lower_bound = plot_ranges[par1][0] upper_bound = plot_ranges[par1][1] else: lower_bound = fiducial -confidence_coefficient*sigma upper_bound = fiducial +confidence_coefficient*sigma x_points = np.linspace( lower_bound, upper_bound, num_points ) # get y: if normalized: y_points = np.array([ np.exp( -( x-fiducial )**2/(2.0*sigma**2) )/( sigma*np.sqrt(2.0*math.pi) ) for x in x_points ]) else: y_points = np.array([ np.exp( -( x-fiducial )**2/(2.0*sigma**2) ) for x in x_points ]) dict_names[name] = [x_points, y_points, [fiducial,sigma]] gaussian_distro[par1] = dict_names return gaussian_distro
def compute_plot_range(self, params=None, confidence_level=0.68, names=None, nice=True ): """ Function that computes a meaningfull plot range for the plots involving the specified parameters and the specified Fisher names. :param params: name of the parameter or list of names of parameters. :type params: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param nice: wether the number is properly rounded to be nice. :type nice: :class:`bool` :returns: a dictionary of name and bounds :rtype: :class:`dict` """ # process names: if names==None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params==None: params_temp = total_paramnames_list else: params_temp = [ i for i in fu.make_list(params) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient( confidence_level ) # get the ranges: range = [] for i in params_temp: lower_bound = [] upper_bound = [] for j in fisher_temp_list: # get the index of the parameter: try: index = j.get_param_index(i) except: continue # get sigma and fiducial: sigma = j.get_fisher_inverse()[index,index] sigma = math.sqrt( sigma ) fiducial = j.get_fiducial(i) # apply a coefficient to safeguard: if not nice: sigma = confidence_coefficient*sigma # store the values: if nice: lower_bound.append(fu.significant_digits( (fiducial-confidence_coefficient*sigma, sigma), mode=2 ) ) upper_bound.append(fu.significant_digits( (fiducial+confidence_coefficient*sigma, sigma), mode=0 ) ) else: lower_bound.append(fiducial-sigma) upper_bound.append(fiducial+sigma) # decide what to use: upper_bound = np.array(upper_bound) lower_bound = np.array(lower_bound) range.append([ float(str(np.amin(lower_bound))), float(str(np.amax(upper_bound))) ]) dict = {} for i,j in zip(params_temp,xrange(len(params_temp))): dict[i] = range[j] return dict
def compute_ellipse(self, params1=None, params2=None, confidence_level=0.68, names=None, num_points=100): """ Function that computes the (2D) ellipses for a given parameters combination. Returns a dictionary with all the meaningul information about the ellipses. :param params1: name of the first parameter or list of names of parameters. :type params1: a :class:`string` or a :class:`list` of :class:`string` :param params2: name of the second parameter or list of names of parameters. :type params3: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param num_points: number of (x,y) points. :type num_points: :class:`int` :returns: a dictionary mapping name and parameters to a tuple of: [x, y, [fiducial_x, fiducial_y, coeff_a, coeff_b, theta_0]] :rtype: :class:`dict` """ # process names: if names == None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params1 == None: params_temp_1 = total_paramnames_list else: params_temp_1 = [ i for i in fu.make_list(params1) if i in total_paramnames_list ] if params2 == None: params_temp_2 = total_paramnames_list else: params_temp_2 = [ i for i in fu.make_list(params2) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient(confidence_level) # get the distributions: gaussian_distro = {} for par1 in params_temp_1: dict_names_1 = {} for par2 in params_temp_2: dict_names_2 = {} for mat, name in zip(fisher_temp_list, names_temp): # get the index of the parameter: try: index_1 = mat.get_param_index(par1) index_2 = mat.get_param_index(par2) except: dict_names_2[name] = [ np.array([0.0]), np.array([0.0]), [0.0, 0.0, 0.0, 0.0, 0.0] ] continue # get sigmas: sigma_x = mat.get_fisher_inverse()[index_1, index_1] sigma_y = mat.get_fisher_inverse()[index_2, index_2] sigma_xy = mat.get_fisher_inverse()[index_1, index_2] # get fiducial: fiducial_x = mat.get_fiducial(par1) fiducial_y = mat.get_fiducial(par2) # compute the ellipse coefficients: coeff_a = confidence_coefficient * math.sqrt( (sigma_x + sigma_y) / 2.0 + math.sqrt((sigma_x - sigma_y)**2 / 4.0 + sigma_xy**2)) coeff_b = confidence_coefficient * math.sqrt( (sigma_x + sigma_y) / 2.0 - math.sqrt((sigma_x - sigma_y)**2 / 4.0 + sigma_xy**2)) theta_0 = math.atan2((2.0 * sigma_xy), (sigma_x - sigma_y)) / 2.0 # generate the ellipses angles = np.linspace(0, 2.0 * math.pi, num_points) x_points = np.array([ +coeff_a * math.cos(theta) * math.cos(theta_0) - coeff_b * math.sin(theta) * math.sin(theta_0) + fiducial_x for theta in angles ]) y_points = np.array([ +coeff_a * math.cos(theta) * math.sin(theta_0) + coeff_b * math.sin(theta) * math.cos(theta_0) + fiducial_y for theta in angles ]) # save the result: dict_names_2[name] = [ x_points, y_points, [fiducial_x, fiducial_y, coeff_a, coeff_b, theta_0] ] dict_names_1[par2] = dict_names_2 gaussian_distro[par1] = dict_names_1 return gaussian_distro # ----------------------------------------------------------------------------------- # ***************************************************************************************
def compute_gaussian(self, params=None, confidence_level=0.68, names=None, num_points=100, normalized=False, nice_bounds=True): """ Function that computes the (1D) gaussian distribution of a given parameter. Returns a dictionary with all the meaningul information about the gaussian. :param params: name of the parameter or list of names of parameters. :type params: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param num_points: number of (x,y) points. :type num_points: :class:`int` :param normalized: wether the distribution is normalized or not. :type normalized: :class:`bool` :param nice_bounds: wether the x range is properly rounded to be nice or not. :type nice_bounds: :class:`bool` :returns: a dictionary mapping name and parameter to a tuple of: [x, y, [fiducial,sigma]] :rtype: :class:`dict` """ # process names: if names == None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params == None: params_temp = total_paramnames_list else: params_temp = [ i for i in fu.make_list(params) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient(confidence_level) # get the plot ranges: plot_ranges = self.compute_plot_range( params=params_temp, confidence_level=confidence_level, names=names_temp, nice=nice_bounds) # get the distributions: gaussian_distro = {} for par1 in params_temp: dict_names = {} for mat, name in zip(fisher_temp_list, names_temp): # get the index of the parameter: try: index = mat.get_param_index(par1) except: dict_names[name] = [ np.array([0.0]), np.array([0.0]), [0.0, 0.0] ] continue # get sigma and fiducial: sigma = math.sqrt(mat.get_fisher_inverse()[index, index]) fiducial = mat.get_fiducial(par1) # get optimal x: if nice_bounds: lower_bound = plot_ranges[par1][0] upper_bound = plot_ranges[par1][1] else: lower_bound = fiducial - confidence_coefficient * sigma upper_bound = fiducial + confidence_coefficient * sigma x_points = np.linspace(lower_bound, upper_bound, num_points) # get y: if normalized: y_points = np.array([ np.exp(-(x - fiducial)**2 / (2.0 * sigma**2)) / (sigma * np.sqrt(2.0 * math.pi)) for x in x_points ]) else: y_points = np.array([ np.exp(-(x - fiducial)**2 / (2.0 * sigma**2)) for x in x_points ]) dict_names[name] = [x_points, y_points, [fiducial, sigma]] gaussian_distro[par1] = dict_names return gaussian_distro
def compute_plot_range(self, params=None, confidence_level=0.68, names=None, nice=True): """ Function that computes a meaningfull plot range for the plots involving the specified parameters and the specified Fisher names. :param params: name of the parameter or list of names of parameters. :type params: a :class:`string` or a :class:`list` of :class:`string` :param confidence_level: (optional) Confidence Level of the bounds. Default 68%. :type confidence_level: :class:`float` :param names: names of the Fisher matrices. :type names: a :class:`string` or a :class:`list` of :class:`string` :param nice: wether the number is properly rounded to be nice. :type nice: :class:`bool` :returns: a dictionary of name and bounds :rtype: :class:`dict` """ # process names: if names == None: names_temp = self.fisher_name_list else: names_temp = [ i for i in fu.make_list(names) if i in self.fisher_name_list ] # process parameters: total_paramnames_list = self.get_parameter_list(names_temp) if params == None: params_temp = total_paramnames_list else: params_temp = [ i for i in fu.make_list(params) if i in total_paramnames_list ] # get the fishers: fisher_temp_list = self.get_fisher_matrix(names_temp) # compute the confidence coefficient: confidence_coefficient = fu.confidence_coefficient(confidence_level) # get the ranges: range = [] for i in params_temp: lower_bound = [] upper_bound = [] for j in fisher_temp_list: # get the index of the parameter: try: index = j.get_param_index(i) except: continue # get sigma and fiducial: sigma = j.get_fisher_inverse()[index, index] sigma = math.sqrt(sigma) fiducial = j.get_fiducial(i) # apply a coefficient to safeguard: if not nice: sigma = confidence_coefficient * sigma # store the values: if nice: lower_bound.append( fu.significant_digits( (fiducial - confidence_coefficient * sigma, sigma), mode=2)) upper_bound.append( fu.significant_digits( (fiducial + confidence_coefficient * sigma, sigma), mode=0)) else: lower_bound.append(fiducial - sigma) upper_bound.append(fiducial + sigma) # decide what to use: upper_bound = np.array(upper_bound) lower_bound = np.array(lower_bound) range.append([ float(str(np.amin(lower_bound))), float(str(np.amax(upper_bound))) ]) dict = {} for i, j in zip(params_temp, xrange(len(params_temp))): dict[i] = range[j] return dict