def trunc_norm_prob(center): """ get probability mass """ return (truncnorm.cdf(center + radius, a=(low - mean) / radius, b=(high - mean) / radius, loc=mean, scale=radius) - truncnorm.cdf(center - radius, a=(low - mean) / radius, b=(high - mean) / radius, loc=mean, scale=radius))
def get_mfd(self, slip, area, shear_modulus=30.0): ''' Calculates activity rate on the fault :param float slip: Slip rate in mm/yr :param fault_width: Width of the fault (km) :param float disp_length_ratio: Displacement to length ratio (dimensionless) :param float shear_modulus: Shear modulus of the fault (GPa) :returns: * Minimum Magnitude (float) * Bin width (float) * Occurrence Rates (numpy.ndarray) ''' # Working in Nm so convert: shear_modulus - GPa -> Nm # area - km ** 2. -> m ** 2. # slip - mm/yr -> m/yr moment_rate = (shear_modulus * 1.E9) * (area * 1.E6) * (slip / 1000.) moment_mag = _scale_moment(self.mmax, in_nm=True) characteristic_rate = moment_rate / moment_mag if self.sigma and (fabs(self.sigma) > 1E-5): self.mmin = self.mmax + (self.lower_bound * self.sigma) mag_upper = self.mmax + (self.upper_bound * self.sigma) mag_range = np.arange(self.mmin, mag_upper + self.bin_width, self.bin_width) self.occurrence_rate = characteristic_rate * (truncnorm.cdf( mag_range + (self.bin_width / 2.), self.lower_bound, self.upper_bound, loc=self.mmax, scale=self.sigma) - truncnorm.cdf(mag_range - (self.bin_width / 2.), self.lower_bound, self.upper_bound, loc=self.mmax, scale=self.sigma)) else: # Returns only a single rate self.mmin = self.mmax self.occurrence_rate = np.array([characteristic_rate], dtype=float) return self.mmin, self.bin_width, self.occurrence_rate
def fit(self, model, num_samples, data, truncated_lower=0.0, truncated_upper=2.0, threshold=0.01, **kwargs): start = time.time() samples = self.sampler.sample(model, ut.random_normal, num_samples, data, ut.mae_loss, **kwargs) """ The standard form of this distribution is a standard normal truncated to the range [a, b] — notice that a and b are defined over the domain of the standard normal. To convert clip values for a specific mean and standard deviation, use: a, b = (myclip_a - my_mean) / my_std, (myclip_b - my_mean) / my_std """ mean = np.mean(samples) std = np.std(samples) a = (truncated_lower - mean) / std b = (truncated_upper - mean) / std p_threshold = truncnorm.cdf(threshold, a, b, loc=mean, scale=std) log_p = np.log(p_threshold) sampling_time = time.time() - start return { 'p': p_threshold, 'log_p': log_p, 'mean': mean, 'std': std, 'sampling_time': sampling_time, 'samples': samples }
def cdf(self, x) -> float: """ Calculate the Normal cumulative distribution value at position `x`. :param x: value where the cumulative distribution function is evaluated. :return: value of the cumulative distribution function. """ if self.hard_clip_min is not None and (x < self.hard_clip_min): return 0. if self.hard_clip_max is not None and (x > self.hard_clip_max): return 1. if self.hard_clip_min is not None or self.hard_clip_max is not None: a = -np.inf b = np.inf if self.hard_clip_min is not None: a = (self.hard_clip_min - self.mean) / self.std if self.hard_clip_max is not None: b = (self.hard_clip_max - self.mean) / self.std return truncnorm.cdf(x, a=a, b=b, loc=self.mean, scale=self.std) return norm.cdf(x, loc=self.mean, scale=self.std)
def relative_seg(self, roi): lower, upper = 0.33, 0.60 mu, std = 0.42, 0.06 a, b = (lower - mu) / std, (upper - mu) / std return truncnorm.cdf(roi / np.max(roi), a, b, loc=mu, scale=std)
def cdf(self, x): cdfs = truncnorm.cdf(x, self.a, self.b, loc=self.means, scale=self.sigmas) return np.sum(np.dot(cdfs, self.coeff))
def cdf(self, x: Tuple[float]): """Find the CDF for a certain x value. Args: x (float): The value for which the CDF is needed. Returns: float: The CDF value at point x. """ x_a, x_b = (self.x_lower_bound - self.x_mean) / self.x_std, ( self.x_upper_bound - self.x_mean) / self.x_std y_a, y_b = (self.y_lower_bound - self.y_mean) / self.y_std, ( self.y_upper_bound - self.y_mean) / self.y_std return truncnorm.cdf(x[0], x_a, x_b, self.x_mean, self.x_std) * truncnorm.cdf( x[1], y_a, y_b, self.y_mean, self.y_std)
def CDF_func(self, t): return truncnorm.cdf( t, self.__low_bound, self.__up_bound, loc=self.mu, scale=self.sigma)
def absolute_seg(self, roi): lower, upper = 2.0, 4.0 mu, std = 2.5, 0.5 a, b = (lower - mu) / std, (upper - mu) / std return truncnorm.cdf(roi, a, b, loc=mu, scale=std)
def get_mfd(self, slip, area, shear_modulus=30.0): ''' Calculates activity rate on the fault :param float slip: Slip rate in mm/yr :param fault_width: Width of the fault (km) :param float disp_length_ratio: Displacement to length ratio (dimensionless) :param float shear_modulus: Shear modulus of the fault (GPa) :returns: * Minimum Magnitude (float) * Bin width (float) * Occurrence Rates (numpy.ndarray) ''' # Working in Nm so convert: shear_modulus - GPa -> Nm # area - km ** 2. -> m ** 2. # slip - mm/yr -> m/yr moment_rate = (shear_modulus * 1.E9) * (area * 1.E6) * (slip / 1000.) moment_mag = _scale_moment(self.mmax, in_nm=True) characteristic_rate = moment_rate / moment_mag if self.sigma and (fabs(self.sigma) > 1E-5): self.mmin = self.mmax + (self.lower_bound * self.sigma) mag_upper = self.mmax + (self.upper_bound * self.sigma) mag_range = np.arange(self.mmin, mag_upper + self.bin_width, self.bin_width) self.occurrence_rate = characteristic_rate * ( truncnorm.cdf(mag_range + (self.bin_width / 2.), self.lower_bound, self.upper_bound, loc=self.mmax, scale=self.sigma) - truncnorm.cdf(mag_range - (self.bin_width / 2.), self.lower_bound, self.upper_bound, loc=self.mmax, scale=self.sigma)) else: # Returns only a single rate self.mmin = self.mmax self.occurrence_rate = np.array([characteristic_rate], dtype=float) return self.mmin, self.bin_width, self.occurrence_rate
def pretty_print(self): a,b = (0-self.constraint.mean)/self.constraint.std,(1e6-self.constraint.mean)/self.constraint.std ub_survival = truncnorm.sf(self.allocated_ub, a,b,loc=self.constraint.mean, scale=self.constraint.std) lb_mass = truncnorm.cdf(self.allocated_lb, a,b,loc=self.constraint.mean, scale=self.constraint.std) print(self.constraint.name + ": [" + str(self.allocated_lb) + "," + str( self.allocated_ub) + "] (Risk: " + str(lb_mass+ub_survival) + ")")
def trunc_visualization(parameters): [mu, sig, min, max] = parameters a, b, = (min - mu) / sig, (max - mu) / sig x_range = np.linspace(0, 1, 1000) fig, ax = plt.subplots() sns.lineplot(x_range, truncnorm.pdf(x_range, a, b, loc=mu, scale=sig), label='pdf') sns.lineplot(x_range, truncnorm.cdf(x_range, a, b, loc=mu, scale=sig), label='cdf') ax.legend() return ax
def cdf(self, x: float): """Find the CDF for a certain x value. Args: x (float): The value for which the CDF is needed. """ a, b = (self.lower_bound - self.mean) / self.std, ( self.upper_bound - self.mean) / self.std return truncnorm.cdf(x, a, b, self.mean, self.std)
def absolute_seg(self, roi): # lower, upper = 2.0, 4.0 # # mu, std = 2.5, 0.5 # mu, std = 3.0, 0.5 lower, upper = self.tvals_probs['absolute']['lower'], self.tvals_probs[ 'absolute']['upper'] mu, std = self.tvals_probs['absolute']['mu'], self.tvals_probs[ 'absolute']['std'] a, b = (lower - mu) / std, (upper - mu) / std return truncnorm.cdf(roi, a, b, loc=mu, scale=std)
def get_mfd(self, slip, shear_modulus, area): '''Calculates activity rate''' self.mfd_params['mmin'] = self.mfd_params['mmax'] + ( self.mfd_params['Lower'] * self.mfd_params['Sigma']) moment_rate = (shear_modulus * 1.E9) * (area * 1.E6) * (slip / 1000.) mag_upper = self.mfd_params['mmax'] + (self.mfd_params['Upper'] * self.mfd_params['Sigma']) mag_range = np.arange(self.mfd_params['mmin'], mag_upper + self.bin_width + 1E-7, self.bin_width) #moment_mag = 10. ** (1.5 * mag_range + 9.05) moment_mag = 10. ** (1.5 * self.mfd_params['mmax'] + 9.05) characteristic_rate = moment_rate / moment_mag self.occurrence_rate = characteristic_rate * (truncnorm.cdf( mag_range + (self.bin_width / 2.), self.mfd_params['Lower'], self.mfd_params['Upper'], loc=self.mfd_params['mmax'], scale=self.mfd_params['Sigma']) - truncnorm.cdf( mag_range - (self.bin_width / 2.), self.mfd_params['Lower'], self.mfd_params['Upper'], loc=self.mfd_params['mmax'], scale=self.mfd_params['Sigma']))
def relative_seg(self, roi): # lower, upper = 0.33, 0.60 # mu, std = 0.42, 0.06 lower, upper = self.tvals_probs['relative']['lower'], self.tvals_probs[ 'relative']['upper'] mu, std = self.tvals_probs['relative']['mu'], self.tvals_probs[ 'relative']['std'] a, b = (lower - mu) / std, (upper - mu) / std return truncnorm.cdf(roi / np.max(roi), a, b, loc=mu, scale=std)
def get_ci(self, stat, eta, l_thres, u_thres, alpha): """Calculation of one two-sided confidence interval""" sigma = np.dot(eta, np.dot(self.cov, eta)) scale = np.sqrt(sigma) pivot = lambda mu: truncnorm.cdf(stat, (l_thres - mu) / scale, (u_thres - mu) / scale, loc=mu, scale=scale) lb = stat - 20. * scale # lower bound ub = stat + 20. * scale # upper bound ci_l = helper.find_root(pivot, 1 - alpha / 2, lb, ub) ci_u = helper.find_root(pivot, alpha / 2, lb, ub) return np.array([ci_l, ci_u])
def usrf(status, x, needF, neF, F, needG, neG, G, cu, iu, ru): """ ================================================================== Computes the nonlinear objective and constraint terms for the problem. ================================================================== """ # print('called usrfun with ' + str(len(G)) + ' non-linear variables') if (needF[0] != 0): # the second last row is for chance constraint F[neF[0] - 2] = 0 if cc_var > 0: F[neF[0] - 2] += x[cc_var] for idx in range(0, int(len(G) / 2)): mean = prob_means[idx] sigma = prob_stds[idx] lb_var = prob_vars[2 * idx] ub_var = prob_vars[2 * idx + 1] # print("Mean: " + str(mean) + " / Sigma: " + str(sigma)) a, b = (0 - mean) / sigma, (1e6 - mean) / sigma ub_survival = truncnorm.sf(x[ub_var], a, b, loc=mean, scale=sigma) lb_mass = truncnorm.cdf(x[lb_var], a, b, loc=mean, scale=sigma) F[neF[0] - 2] += ub_survival + lb_mass # print('Updating F['+str(neF[0] - 2)+']: ' + str(x[lb_var]) + '-' + str(x[ub_var]) + ': ' + str(lb_mass) + "+" +str(ub_survival) + "="+str(F[neF[0] - 2])) if (needG[0] != 0): # Compute the partial derivatives of the chance constraint # over the lower and upper bounds of the # probabilistic durations for idx in range(0, int(len(G) / 2)): mean = prob_means[idx] sigma = prob_stds[idx] lb_var = prob_vars[2 * idx] ub_var = prob_vars[2 * idx + 1] a, b = (0 - mean) / sigma, (1e6 - mean) / sigma # For the lower bound, the derivative is the Gaussian pdf G[2 * idx] = truncnorm.pdf(x[lb_var], a, b, loc=mean, scale=sigma) # For the upper bound, it is the negation of the Gaussian pdf G[2 * idx + 1] = -1 * truncnorm.pdf(x[ub_var], a, b, loc=mean, scale=sigma)
def usrf(status, x, needF, neF, F, needG, neG, G, cu, iu, ru): """ ================================================================== Computes the nonlinear objective and constraint terms for the problem. ================================================================== """ # print('called usrfun with ' + str(len(G)) + ' non-linear variables') if (needF[0] != 0): # the second last row is for chance constraint F[neF[0] - 2] = 0 if cc_var > 0: F[neF[0] - 2] += x[cc_var] for idx in range(0, int(len(G)/ 2)): mean = prob_means[idx] sigma = prob_stds[idx] lb_var = prob_vars[2 * idx] ub_var = prob_vars[2 * idx+1] # print("Mean: " + str(mean) + " / Sigma: " + str(sigma)) a, b = (0 - mean) / sigma, (1e6 - mean) / sigma ub_survival = truncnorm.sf(x[ub_var],a,b, loc=mean, scale=sigma) lb_mass = truncnorm.cdf(x[lb_var],a,b, loc=mean, scale=sigma) F[neF[0] - 2] += ub_survival + lb_mass # print('Updating F['+str(neF[0] - 2)+']: ' + str(x[lb_var]) + '-' + str(x[ub_var]) + ': ' + str(lb_mass) + "+" +str(ub_survival) + "="+str(F[neF[0] - 2])) if (needG[0] != 0): # Compute the partial derivatives of the chance constraint # over the lower and upper bounds of the # probabilistic durations for idx in range(0, int(len(G) / 2)): mean = prob_means[idx] sigma = prob_stds[idx] lb_var = prob_vars[2 * idx] ub_var = prob_vars[2 * idx + 1] a, b = (0 - mean) / sigma, (1e6 - mean) / sigma # For the lower bound, the derivative is the Gaussian pdf G[2 * idx] = truncnorm.pdf(x[lb_var], a,b, loc=mean, scale=sigma) # For the upper bound, it is the negation of the Gaussian pdf G[2 * idx + 1] = -1 * truncnorm.pdf(x[ub_var], a,b, loc=mean, scale=sigma)
def cdf(self,dat): ''' Evaluates the cumulative distribution function on the data points in dat. :param dat: Data points for which the c.d.f. will be computed. :type dat: natter.DataModule.Data :returns: A numpy array containing the probabilities. :rtype: numpy.array ''' #print dat.X a,b = (self.param['a']-self.param['mu'])/self.param['sigma'],(self.param['b']-self.param['mu'])/self.param['sigma'] return squeeze(truncnorm.cdf(dat.X,a,b,loc=self.param['mu'],scale=self.param['sigma']))
def beliefs_loglike_binary(responses, signals, sm, wp, noise_type, noise): belief_matrix = fwd.calc_belief_matrix(sm, wp) probs = np.empty(len(signals)) for k in range(len(signals)): bayes_s0 = belief_matrix[0][signals[k]] given_s0 = responses[k] #probs[k] = prob_noisy(given_s0, bayes_s0, noise_type, noise[k]) probs0 = truncnorm.cdf(.5, -bayes_s0 / noise, (1-bayes_s0)/scale, loc=bayes_s0, scale=noise) #assuming truncnorm, write own func. if responses[k] == 0: probs[k] = probs0 else: probs[k] = 1 - probs0 loglike = np.sum(np.log(probs)) return loglike
def MLE_X_trunc(self,low_support,high_support,threshold,x2nd,x_v,w_v): ''' I do not know this MLE est I just realized that I can genreate the conditional chain rule to calculate the MLE (Because I calculate the probability!!!) ''' self.setup_para(0) low_support = low_support.reshape(self.N,1) high_support = high_support.reshape(self.N,1) low_support[-2]=low_support[-2]-0.05 high_support[-2]=high_support[-2]+0.05 x_flag1 = x_v >= low_support x_flag2 = x_v <= high_support check_flag_v1=np.prod(x_flag1, axis=0) check_flag_v2=np.prod(x_flag2, axis=0) check_flag_v1=check_flag_v1*check_flag_v2 nominator = np.sum(check_flag_v1*w_v) denominator = np.sum(w_v) mu=self.MU[-2] sigma=self.SIGMA2[-2,-2]**0.5 density_2nd = truncnorm.pdf((x2nd-mu)/sigma,(threshold[-2]-mu)/sigma,10) prob_1st = 1 - truncnorm.cdf((low_support[-1]-mu)/sigma,(threshold[-1]-mu)/sigma,10) with np.errstate(divide='raise'): try: log_Prob = density_2nd + prob_1st+ np.log(nominator)-np.log(denominator) except Exception as e: print('-----------------------------------------------') print('0 in log at {} bidders with {} reserve price'.format(self.N,threshold[0])) print(low_support.flatten()) print(high_support.flatten()) print("density_2d: {0:.4}\t| prob_1st: {0:.4}\t| nominator: {0:.4}\t| denominator: {0:.4}\t| ".format(density_2nd,prob_1st,nominator,denominator)) log_Prob = np.nan log_Prob = np.log(nominator)-np.log(denominator) + np.log(density_2nd) + np.log(prob_1st) return log_Prob
def pretty_print(self): a, b = (0 - self.constraint.mean) / self.constraint.std, ( 1e6 - self.constraint.mean) / self.constraint.std ub_survival = truncnorm.sf(self.allocated_ub, a, b, loc=self.constraint.mean, scale=self.constraint.std) lb_mass = truncnorm.cdf(self.allocated_lb, a, b, loc=self.constraint.mean, scale=self.constraint.std) print(self.constraint.name + ": [" + str(self.allocated_lb) + "," + str(self.allocated_ub) + "] (Risk: " + str(lb_mass + ub_survival) + ")")
def fit(self, model, num_samples, data, truncated_lower=0.0, truncated_upper=2.0, threshold=0.01, **kwargs): start = time.time() samples, _ = self.sampler.sample(model, ut.random_normal, num_samples, data, 'mae', **kwargs) """ The standard form of this distribution is a standard normal truncated to the range [a, b] — notice that a and b are defined over the domain of the standard normal. To convert clip values for a specific mean and standard deviation, use: a, b = (myclip_a - my_mean) / my_std, (myclip_b - my_mean) / my_std """ mean = np.mean(samples) std = np.std(samples) a = (truncated_lower - mean) / std b = (truncated_upper - mean) / std p_threshold = truncnorm.cdf(threshold, a, b, loc=mean, scale=std) if p_threshold == 0: # log_p = np.finfo(float).min # Some software, e.g., mipego, have trouble dealing with long floats... log_p = np.log(1e-300) else: log_p = np.log(p_threshold) sampling_time = time.time() - start return { 'p': p_threshold, 'log_p': log_p, 'mean': mean, 'std': std, 'sampling_time': sampling_time, 'samples': samples }
def fit(self, model, num_samples, x_df, y_df, truncated_lower=0.0, truncated_upper=2.0, threshold=0.01, **kwargs): samples = self.sampler.sample(model, ut.random_normal, num_samples, x_df, y_df, ut.mae_loss, **kwargs) """ The standard form of this distribution is a standard normal truncated to the range [a, b] — notice that a and b are defined over the domain of the standard normal. To convert clip values for a specific mean and standard deviation, use: a, b = (myclip_a - my_mean) / my_std, (myclip_b - my_mean) / my_std """ mean = np.mean(samples) std = np.std(samples) a = (truncated_lower - mean) / std b = (truncated_upper - mean) / std p_threshold = truncnorm.cdf(threshold, a, b, loc=mean, scale=std) log_p = np.log(p_threshold) return {'p': p_threshold, 'log_p': log_p, 'mean': mean, 'std': std, 'samples': samples}
def prob_distribution(self, task): x_axis = np.arange(0, task.expiry_ + self.time_unit, self.time_unit) a = task.deadline_ b = task.expiry_ probability = truncnorm.pdf(x_axis, -b, b, loc=a * self.mean_, scale=self.sigma_) cdf = truncnorm.cdf(x_axis, -b, b, loc=a * self.mean_, scale=self.sigma_) probability = probability / ((cdf[-1] - cdf[0])) cdf = (cdf - cdf[0]) / ((cdf[-1] - cdf[0])) return probability, cdf, x_axis
def get_probabilities(self): if self.probabilities is None: avg, std = self._get_mean_std_percentage() if self.model_std is not None: std = (self.model_std + std) / 2 if self.flat_uncertainty is not None: std += self.flat_uncertainty self.properties['Average interest'] = avg self.properties['Std interest'] = std if self.limit_std is not None: std = self.limit_std_dev(std) self.properties['Limited std'] = std if self.prop_domain is not None: a, b = (self.prop_domain[0] - avg) / std, (self.prop_domain[1] - avg) / std self.probabilities = truncnorm.cdf([0, 1], a=a, b=b, loc=avg, scale=std) else: self.probabilities = norm(avg, std).cdf([0, 1]) return self.probabilities
def log_prob(self, value): if self._validate_args: self._validate_sample(value) return super(TruncatedNormal, self).log_prob( self._to_std_rv(value)) - self._log_scale if __name__ == '__main__': from scipy.stats import truncnorm loc, scale, a, b = 1., 2., 1., 2. tn_pt = TruncatedNormal(loc, scale, a, b) mean_pt, var_pt = tn_pt.mean.item(), tn_pt.variance.item() alpha, beta = (a - loc) / scale, (b - loc) / scale mean_sp, var_sp = truncnorm.stats(alpha, beta, loc=loc, scale=scale, moments='mv') print('mean', mean_pt, mean_sp) print('var', var_pt, var_sp) print('cdf', tn_pt.cdf(1.4).item(), truncnorm.cdf(1.4, alpha, beta, loc=loc, scale=scale)) print('icdf', tn_pt.icdf(0.333).item(), truncnorm.ppf(0.333, alpha, beta, loc=loc, scale=scale)) print('logpdf', tn_pt.log_prob(1.5).item(), truncnorm.logpdf(1.5, alpha, beta, loc=loc, scale=scale)) print('entropy', tn_pt.entropy.item(), truncnorm.entropy(alpha, beta, loc=loc, scale=scale))
def _cdf(self, x, a, b, mu, sigma): return truncnorm.cdf(x, a, b, loc=mu, scale=sigma)
""" from scipy.stats import truncnorm import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) a, b = 0, np.inf mean, var, skew, kurt = truncnorm.stats(a, b, moments='mvsk') x = np.linspace(truncnorm.ppf(0, a, b), truncnorm.ppf(0.99, a, b), 100) ax.plot(x, truncnorm.pdf(x, a, b), 'r-', lw=5, alpha=1, label='truncnorm pdf') mean = 2 rv = truncnorm(a, b) ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf') vals = truncnorm.ppf([0.1, 0.1, b], a, b) np.allclose([0.0001, 1.5, 2], truncnorm.cdf(vals, a, b)) r = truncnorm.rvs(a, b, size=1000) ax.hist(r, density=True, histtype='stepfilled', alpha=1) ax.legend(loc='best', frameon=False) plt.show() plt.plot(r) mu, sigma = 10, 0.1 s = np.random.normal(mu, 0, 1000)
def get_truncated_lognormal_example_exact_quantities(lb, ub, mu, sigma): f = lambda x: np.exp(x).T #lb,ub passed to truncnorm_rv are defined for standard normal. #Adjust for mu and sigma using alpha, beta = (lb - mu) / sigma, (ub - mu) / sigma denom = normal_rv.cdf(beta) - normal_rv.cdf(alpha) #truncated_normal_cdf = lambda x: ( # normal_rv.cdf((x-mu)/sigma)-normal_rv.cdf(alpha))/denom truncated_normal_cdf = lambda x: truncnorm_rv.cdf( x, alpha, beta, loc=mu, scale=sigma) truncated_normal_pdf = lambda x: truncnorm_rv.pdf( x, alpha, beta, loc=mu, scale=sigma) truncated_normal_ppf = lambda p: truncnorm_rv.ppf( p, alpha, beta, loc=mu, scale=sigma) # CDF of output variable (log truncated normal PDF) def f_cdf(y): vals = np.zeros_like(y) II = np.where((y > np.exp(lb)) & (y < np.exp(ub)))[0] vals[II] = truncated_normal_cdf(np.log(y[II])) JJ = np.where((y >= np.exp(ub)))[0] vals[JJ] = 1. return vals # PDF of output variable (log truncated normal PDF) def f_pdf(y): vals = np.zeros_like(y) II = np.where((y > np.exp(lb)) & (y < np.exp(ub)))[0] vals[II] = truncated_normal_pdf(np.log(y[II])) / y[II] return vals # Analytic VaR of model output VaR = lambda p: np.exp(truncated_normal_ppf(p)) const = np.exp(mu + sigma**2 / 2) # Analytic VaR of model output CVaR = lambda p: -0.5 / denom * const / (1 - p) * (erf( (mu + sigma**2 - ub) / (np.sqrt(2) * sigma)) - erf( (mu + sigma**2 - np.log(VaR(p))) / (np.sqrt(2) * sigma))) def cond_exp_le_eta(y): vals = np.zeros_like(y) II = np.where((y > np.exp(lb)) & (y < np.exp(ub)))[0] vals[II] = -0.5 / denom * const * (erf( (mu + sigma**2 - np.log(y[II])) / (np.sqrt(2) * sigma)) - erf( (mu + sigma**2 - lb) / (np.sqrt(2) * sigma))) / f_cdf(y[II]) JJ = np.where((y >= np.exp(ub)))[0] vals[JJ] = mean return vals ssd = lambda y: f_cdf(y) * (y - cond_exp_le_eta(y)) mean = CVaR(np.zeros(1)) def cond_exp_y_ge_eta(y): vals = np.ones_like(y) * mean II = np.where((y > np.exp(lb)) & (y < np.exp(ub)))[0] vals[II] = -0.5 / denom * const * (erf( (mu + sigma**2 - ub) / (np.sqrt(2) * sigma)) - erf( (mu + sigma**2 - np.log(y[II])) / (np.sqrt(2) * sigma))) / (1 - f_cdf(y[II])) JJ = np.where((y > np.exp(ub)))[0] vals[JJ] = 0 return vals ssd_disutil = lambda eta: (1 - f_cdf(-eta)) * (eta + cond_exp_y_ge_eta(-eta )) return f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil
# Plots # plt.figure(1) # plt.plot(x,truncnorm.pdf(x, a, b, loc=mu, scale=sigma),'b',label='normpdf') # plt.legend() # plt.figure(2) # plt.plot(x,Weightedpdf(x,mu,sigma,a,b),'r',label='pdf/x**2') # plt.legend() # plt.figure(3) # plt.plot(x,awPDFDistribution(x,mu,sigma,interval,a,b),'r',label='awPDF') # plt.legend() plt.figure(4) plt.plot(x, truncnorm.cdf(x, a, b, loc=mu, scale=sigma), 'b-', label='Normal Distribution') plt.plot(x, Phi(x, mu, sigma, x, interval, a, b), 'b--', label='Area Weighted Normal Distribution') # ''' subplots f, (ax1, ax2) = plt.subplots(1, 2) ax1.plot(x, truncnorm.cdf(x, a, b, loc=mu, scale=sigma), 'b-', label='ND of (20,8)') ax1.plot(x, Phi(x, mu, sigma, x, interval, a, b),
for i in range(ndim): arr_1[:, i] = sampler._rvs[str(i)].flatten() arr_2[:, i] = samplerEnsemble._rvs[str(i)].flatten() colors = ["black", "red", "blue", "green", "orange"] plt.figure(figsize=(10, 8)) for i in range(ndim): s = np.sqrt(cov[i][i]) ### get sorted samples (for the current dimension) x_1 = arr_1[:, i][np.argsort(arr_1[:, i])] x_2 = arr_2[:, i][np.argsort(arr_2[:, i])] ### plot true cdf plt.plot(x_1, truncnorm.cdf(x_1, llim, rlim, mu[i], s), label="True CDF", color=colors[i], linewidth=0.5) # NOTE: old mcsampler stores L, mcsamplerEnsemble stores lnL L = sampler._rvs["integrand"] p = sampler._rvs["joint_prior"] ps = sampler._rvs["joint_s_prior"] ### compute weights of samples weights_1 = (L * p / ps)[np.argsort(arr_1[:, i])] L = samplerEnsemble._rvs["integrand"] p = samplerEnsemble._rvs["joint_prior"] ps = samplerEnsemble._rvs["joint_s_prior"] ### compute weights of samples weights_2 = (L * p / ps)[np.argsort(arr_2[:, i])] y_1 = np.cumsum(weights_1)
def MLE_X_new_omega(self,low_support,high_support,threshold,x2nd): ''' this is old version that use the probability of Prob(Xi in [xi_low, xi_up] | Omega_it xj in [xj_low,xj_up]) ''' self.setup_para(0) mu=self.MU[-2] sigma=self.SIGMA2[-2,-2]**0.5 low_support = low_support.reshape(self.N,1) high_support = high_support.reshape(self.N,1) density_2nd = truncnorm.pdf((x2nd-mu)/sigma,(threshold[-2]-mu)/sigma,10) prob_1st = 1 - truncnorm.cdf((low_support[-1]-mu)/sigma,(threshold[-1]-mu)/sigma,10) with np.errstate(divide='raise'): try: log_Prob = np.log(density_2nd) + np.log(prob_1st) except Exception as e: print('-----------------------------------------------') print('0 in log at {} bidders with {} reserve price'.format(self.N,threshold[0])) print(low_support.flatten()) print(high_support.flatten()) print("density_2d: {} | prob_1st: {}".format(density_2nd[0],prob_1st[0])) log_Prob = np.nan return log_Prob if self.N>2: for i in range(self.N-2): temp_low =low_support[i+1:] temp_high =high_support[i+1:] temp_low =np.append(temp_low,threshold[i]) temp_high =np.append(temp_high,10) [x_v,w_v]=self.GHK_simulator(i,temp_low,temp_high,2) # last column is what we need # x_flag1 = x_v[0] >= low_support[i] x_flag2 = x_v[0] <= high_support[i] check_flag_v1 = x_flag1*x_flag2*1 # calculate the prob nominator = np.sum(check_flag_v1*w_v) denominator = np.sum(w_v) with np.errstate(divide='raise'): try: log_Prob = log_Prob + np.log(nominator)-np.log(denominator) except Exception as e: print('-----------------------------------------------') print(e) print('0 in log at {} bidders with {} reserve price for bidder {}'.format(self.N,threshold[0],i)) print(low_support.flatten()) print(high_support.flatten()) print("density_2d: {} \t| prob_1st: {} \t| nominator: {} \t| denominator: {} \t| ".format(density_2nd[0],prob_1st[0],nominator,denominator)) log_Prob = np.nan return log_Prob
def MLE_X_new_karl(self,low_support,high_support,threshold): ''' In Karl's suggestion, conditional each Omgea_i, I can get conditional distribution for each bidder i. Then I can calculate the probability that xi is under the lower and upper bound Prob_Xi (Xi in [X_low, X_up] | Xi > gamma) Prob_xi( xi_low < xi < xi_up | Omega_it) ignore the second highest bid first For each xi I don't even need the truncated GHK simulator Here I am doing miniziation to estimate the prob that outside the support ''' self.setup_para(0) mu=self.MU sigma=np.diag(self.SIGMA2)**0.5 old_low=np.copy(low_support) old_high=np.copy(high_support) flag=low_support[:-2]>high_support[:-2] high_support[:-2]=(1-flag)*high_support[:-2]+flag*high_support[-2] flag=high_support[:-2]>high_support[-2] high_support[:-2]=(1-flag)*high_support[:-2]+flag*high_support[-2] low_support = low_support.flatten() high_support = high_support.flatten() # Notice that P_Xi (Xi in [X_low, X_up] | Xi > gamma) # from i=1, 3,4,.... # minimize ignore the second highest norm_threshold = (threshold[-1]-mu[-1])/sigma[-1] norm_support = (low_support[-1]-mu[-1])/sigma[-1] prob_1st=truncnorm.cdf(norm_support,norm_threshold,15) with np.errstate(divide='raise'): try: log_Prob = np.log(1+prob_1st) except Exception as e: print('-----------------------------------------------') print('0 in log at {} bidders with {} reserve price'.format(self.N,threshold[0])) print(low_support.flatten()) print(high_support.flatten()) print("density_2d: {} ".format(prob_1st[0])) log_Prob = np.nan return log_Prob if self.N > 2: for i in range(0,self.N-2): norm_threshold = (threshold[i]-mu[i])/sigma[i] norm_low_supp = (low_support[i]-mu[i])/sigma[i] norm_high_supp = (high_support[i]-mu[i])/sigma[i] Prob_temp1 = truncnorm.cdf(norm_low_supp,norm_threshold,15,mu[i],sigma[i]) Prob_temp2 = 1 - truncnorm.cdf(norm_high_supp,norm_threshold,15,mu[i],sigma[i]) with np.errstate(divide='raise'): try: log_Prob = log_Prob + np.log(1+Prob_temp1) + np.log(1+Prob_temp2) except Exception as e: print('-----------------------------------------------') print(e) print('0 in log at {} bidders with {} reserve price for bidder {}'.format(self.N,threshold[0],i)) print(low_support.flatten()) print(high_support.flatten()) print("prob_1st: {} \t| low: {} \t | upp: {} \t ".format(prob_1st,Prob_temp1,Prob_temp2)) log_Prob = np.nan return log_Prob
def normal_truncated_cdf(self, xvalue): return truncnorm.cdf( xvalue, (self.lower_limit - self.prior_estimate) / self.spread, (self.upper_limit - self.prior_estimate) / self.spread, loc=self.prior_estimate, scale=self.spread)