def __call__(self, x, *args): """Evaluate the function taking into account uncertainty in the argument >>> import math >>> x = VE(1,0.1**2) >>> sin1 = EvalVE( math.sin , lambda s : math.cos(s) ) >>> print 'sin1(x) = %s ' % sin1(x) >>> sin2 = EvalVE( math.sin ) >>> print 'sin2(x) = %s ' % sin2(x) """ # ## evaluate the function val = self._value_(x, *args) # ## no uncertainties? if isinstance(x, (float, int, long)): return VE(val, 0) # ignore small or invalid uncertanties elif 0 >= x.cov2() or iszero(x.cov2()): return VE(val, 0) # evaluate the derivative d = self._deriv(float(x), *args) ## calculate the variance cov2 = d * d * x.cov2() ## get a final result return VE(val, cov2)
def __call__ ( self , *x ) : n = self.__N assert len ( x ) == n , 'Invalid argument size' xve = [ VE(i) for i in x ] ## force everything to be VE xv = [ i.value() for i in xve ] ## get only the values xv = tuple ( xv ) ## value of the function value = self.__func ( *xv ) ## calculate the covariance cov2 = 0 for i in range ( n ) : c2 = xve[i].cov2() if c2 <= 0 or iszero ( c2 ) : continue ## calculate the gradient df = self.partial[i] ( *xv ) if iszero ( df ) : continue cov2 += c2 * df**2 return VE ( value , cov2 )
def gauss_cdf ( x , mu = 0.0 , sigma = 1.0 ) : """Standard gaussian CDF: >>> x,mu, sigma = .... >>> cdf = gauss_cdf ( x , mu , sigma ) """ y = VE ( x ) return _gauss_cdf_ ( y if 0 < y.cov2() else y.value () , mu , sigma )
def __call__ ( self , args , cor = None ) : """Calcualte the value of the scalar function of N arguments with uncertainties and correlations >>> fun2 = lambda x , y : ... >>> fun2e = EvalNVEcor ( fun2 , 2 ) >>> cor = ... # 2x2 symmetric correlation matrix >>> x = ... >>> y = ... >>> result = fun2e ( (x,y) , cor ) ## """ n = self.N assert len ( args ) == n , 'Invalid argument size' ## get value of the function val = self.func ( *args ) c2 = 0 x = n * [ 0 ] ## argument g = n * [ 0 ] ## gradient for i in range ( n ) : xi = VE ( args[i] ) x [i] = x ci = xi.cov2() if ci < 0 or iszero ( ci ) : continue di = self.partial[i] ( *args ) if iszero ( di ) : continue ei = xi.error() g [i] = di e [i] = ei ## diagonal correlation coefficients are assumed to be 1 and ignored! c2 += ci * di * di for j in range ( i ) : xj = x [ j ] cj = xj.cov2 () if cj < 0 or iszero ( cj ) : continue dj = d [ j ] if iszero ( dj ) : continue ej = e [ j ] rij = self.__corr ( cor , i , j ) if cor else 0 assert -1 <= rij <= 1 or isequal ( abs ( rij ) , 1 ) ,\ 'Invalid correlaation coefficient (%d,%d)=%s ' % ( i , j , rij ) c2 += 2.0 * di * dj * rij * ei * ej return VE ( val , c2 )
def test_ve(): from ostap.math.ve import VE a = VE(100, 100) b = VE(400, 400) assert ((a + b).value() == 500) assert ((b - a).value() == 300) assert ((a + b).error() == (a - b).error())
def complex_histo_draw(file_name, val_1_col, err_1_col, val_2_col, err_2_col, val_3_col, err_3_col, val_4_col, err_4_col): #from csv to numpy-array data = numpy.genfromtxt(file_name, delimiter=',') #binning y_bins = [2.25, 2.75, 3.25, 3.75, 4.25] pt_bins = [3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20] length_x = numpy.size(data, 0) #histogram for all bins hist_os = h2_axes(y_bins, pt_bins) #histograms with ratios & yeilds hist_y1 = h1_axis(pt_bins) hist_y2 = h1_axis(pt_bins) hist_y3 = h1_axis(pt_bins) hist_y4 = h1_axis(pt_bins) hist_array = [hist_y1, hist_y2, hist_y3, hist_y4] #filling loop pt_bin = 1 y_bin = 1 for j in range(length_x - 1): if pt_bin == len(pt_bins): y_bin += 1 pt_bin = 1 bin_VE_1 = VE(data[j + 1, val_1_col], data[j + 1, err_1_col]**2) bin_VE_2 = VE(data[j + 1, val_2_col], data[j + 1, err_2_col]**2) bin_VE_3 = VE(data[j + 1, val_3_col], data[j + 1, err_3_col]**2) bin_VE_4 = VE(data[j + 1, val_4_col], data[j + 1, err_4_col]**2) #fill histogram with bins values bin_val = bin_VE_2 * bin_VE_4 / (bin_VE_1 * bin_VE_3) #1. uncomment if one need to non-round-values hist_os.SetBinContent(y_bin, pt_bin, bin_val.value()) hist_os.SetBinError(y_bin, pt_bin, bin_val.error()) #2. uncomment if one need to round-values #hist_os.SetBinContent(y_bin, pt_bin, round(bin_val.value())) #hist_os.SetBinError(y_bin, pt_bin, round(bin_val.error())) #stuff for changing bin's colors which determine by Z axis range in 2d hist #hist_os.SetMinimum(0.) #hist_os.SetMaximum(0.08) #fill histogram with R-values hist_array[y_bin - 1].SetBinContent(pt_bin, 100 * (bin_val.value())) hist_array[y_bin - 1].SetBinError(pt_bin, 100 * (bin_val.error())) pt_bin += 1 return hist_os, hist_array[0], hist_array[1], hist_array[2], hist_array[3]
def fma(x, y, z, cxy=0, cxz=0, cyz=0): """ Evaluate fma(x,y,z)=x*y+z with uncertainties >>> x = ... >>> y = ... >>> z = ... >>> print fma ( x , y , z ) """ _x = VE(x) _y = VE(y) _z = VE(z) return _fma_(_x, _y, _z, cxy, cxz, cyz)
def pretty_ve ( value , width = 8 , precision = 6 , parentheses = True ) : """Nice printout of the ValueWithError object ( string + exponent) - return nice stirng and the separate exponent >>> s , n = pretty_ve ( number ) """ from ostap.math.ve import VE value = VE ( value ) fmt , fmtv , fmte , n = fmt_pretty_ve ( value , width , precision , parentheses ) v = value.value () e = max ( 0 , value.error () ) return fmt % ( v / 10**n , e / 10**n ) , n
def __call__(self, func, x, h, args=(), kwargs={}): """The main method: evaluate the numerical derivative - func the function with signature `func(x,*args,**kwargs)` - x point where derivative is evaluated - h step size - args addtional positional arguments - kwargs addtional keyword arguments """ if not self.with_error: return self.derivatives(False, func, x, h, args=args, kwargs=kwargs) ## estimate the uncertainty, if needed d1, dJ = self.derivatives(True, fun, x, h, args=args, kwargs=kwargs) ## get the function value at the given point f0 = fun(x, *args, **kwargs) i = self.__I j = self.__J c_j = self.table2[1] d_j = self.table2[2] e = j * c_j / (d_j * (j - 1)) a = j * epsilon + abs(f0) + abs(x * d1) e2 = e * e * (a**(2 - 2. / j)) * (abs(dJ)**(2.0 / j)) return VE(d1, 4 * e2)
def derivative(self, fun, x, h=0, args=(), kwargs={}): """Get the value of the 1st derivative using the adaptive rule with the optimal step """ ## get the optimal step and value f(x) hopt, f0 = self.optimal_step(fun, x, h, args=args, kwargs=kwargs) ## adjust it if needed hopt = self.adjust_step(x, hopt) if not self.with_error: return self.derivatives(False, fun, x, hopt, args=args, kwargs=kwargs) ## estimate the uncertainty, if needed d1, dJ = self.derivatives(True, fun, x, hopt, args=args, kwargs=kwargs) i = self.__I j = self.__J c_j = self.table2[1] d_j = self.table2[2] e = j * c_j / (d_j * (j - 1)) a = j * epsilon + abs(f0) + abs(x * d1) e2 = e * e * (a**(2 - 2. / j)) * (abs(dJ)**(2.0 / j)) return VE(d1, 4 * e2)
def __call__ ( self , x , y , z , error = False ) : """Get the efficiency >>> dataset = ... >>> eff = ... >>> eff.fitTo ( dataset ) >>> x = 0.15 >>> y = 90 >>> z = 15 >>> value = eff(x,y,z) """ from ostap.fitting.roofit import SETVAR from ostap.math.ve import VE xx = float ( x ) yy = float ( y ) zz = float ( z ) if xx in self.xvar and yy in self.yvar and zz in self.zvar : with SETVAR ( self.xvar ) : with SETVAR ( self.yvar ) : with SETVAR ( self.zvar ) : self.xvar.setVal ( xx ) self.yvar.setVal ( yy ) self.zvar.setVal ( zz ) if error and self.fit_result : e = self.eff_fun.getPropagatedError ( self.fit_result ) if 0<= e : return VE ( v , e * e ) return v logger.error ('Invalid efficiency, return -1 ') return -1
def __call__(self, func, *args): ## additional arguments args = args if args else self.args # ## define integration rules # if hasattr(func, 'integral'): _integral_ = lambda f, low, high: f.integral(low, high, *args) else: from ostap.math.integral import integral _integral_ = lambda f, low, high: integral(f, low, high, *args) # ## xmin/max # xmin, xmax = self.xmin, self.xmax # ## calculate x0 as "mean"-value # x0 = self.x0 if x0 is None: if hasattr(func, 'mean'): x0 = func.mean() else: m = Mean(xmin, xmax, False) x0 = m(func, *args) # ## check validity of x0 # if not xmin <= x0 <= xmax: raise AttributeError("Invalid x0 value %s<=%s<=%s" % (xmin, x0, xmax)) # ## get the normalization # norm = _integral_(func, xmin, xmax) if 0 >= norm: raise AttributeError("Normalization integral is not positive %s" % norm) # ## Equation: ifun(x) \equiv \int_{x0-x}^{x0+x}f(t)dt - N*prob = 0 # yval = self.prob * norm def ifun(x): if 0 >= x: return -yval return _integral_(func, max(xmin, x0 - x), min(xmax, x0 + x)) - yval from ostap.math.rootfinder import findroot s = findroot(ifun, 0, max(xmax - x0, x0 - xmin)) from ostap.math.ve import VE return VE(x0, s * s)
def gradient ( self , *x ) : n = self.__N assert len ( x ) == n , 'Invalid argument size' xx = [ VE(i).value() for i in x ] gr = [ self.partial[i](*xx) for i in range ( n ) ] return tuple ( gr )
def __call__(self, x, y, cxy=0): """Evaluate the function >>> func2 = lambda x,y : x*x + y*y >>> eval2 = Eval2VE ( func2 ) >>> x = VE(1,0.1**2) >>> y = VE(2,0.1**2) >>> print eval2(x,y) ## treat x,y as uncorrelated >>> print eval2(x,y, 0) ## ditto >>> print eval2(x,y,+1) ## treat x,y as 100% correlated >>> print eval2(x,y,-1) ## treat x,y as 100% anti-correlated """ assert isinstance ( cxy , num_types ) and \ ( abs ( cxy ) <= 1 or isequal ( abs ( cxy ) , 1 ) ) , \ 'Invalid correlation coefficient %s' % cxy x = VE(x) y = VE(y) xv = x.value() yv = y.value() val = self.func(xv, yv) xc2 = x.cov2() yc2 = y.cov2() x_plain = xc2 <= 0 or iszero(xc2) y_plain = yc2 <= 0 or iszero(yc2) # if x_plain and y_plain: return VE(val, 0) # ## here we need to calculate the uncertainties # dx = self.partial[0](xv, yv) if not x_plain else 0 dy = self.partial[1](xv, yv) if not y_plain else 0 # cov2 = dx * dx * xc2 + dy * dy * yc2 if cxy and xc2 and yc2: cov2 += 2 * cxy * dx * dy * math.sqrt(xc2 * yc2) return VE(val, cov2)
def complex_histo_draw(file_name, val_1_col, err_1_col, val_2_col, err_2_col, corr_1_val): #from csv to numpy-array data = numpy.genfromtxt(file_name, delimiter = ',') #binning #for statistic y_bins_1 = [2.25, 2.75, 3.25, 3.75, 4.25] pt_bins_1 = [ 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20 ] #for systematic y_bins_2 = [2.25, 2.75, 3.25, 3.75, 4.25] pt_bins_2 = [ 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20 ] length_x = numpy.size(data, 0) #histograms with ratios & yeilds #stat hist_array_1 = [h1_axis(pt_bins_1), h1_axis(pt_bins_1), h1_axis(pt_bins_1), h1_axis(pt_bins_1)] #syst hist_array_2 = [h1_axis(pt_bins_2), h1_axis(pt_bins_2), h1_axis(pt_bins_2), h1_axis(pt_bins_2)] #filling loop pt_bin = 1 y_bin = 1 for j in range(length_x - 1): if pt_bin == len(pt_bins_1): y_bin += 1 pt_bin = 1 bin_VE_1 = VE(data[j + 1, val_1_col]*data[j+1, corr_1_val], (data[j + 1, val_1_col]*data[j + 1, err_1_col])**2) #R + syst bin_VE_2 = VE(data[j + 1, val_2_col]*data[j+1, corr_1_val], (data[j + 1, val_2_col]*data[j + 1, err_2_col])**2) #R + stat #fill histogram with bins values #syst bin_val_1 = bin_VE_1 #stat bin_val_2 = bin_VE_2 #fill histogram with R-values hist_array_1[y_bin - 1].SetBinContent(pt_bin, bin_val_1.value()) hist_array_1[y_bin - 1].SetBinError(pt_bin, bin_val_1.error()) hist_array_2[y_bin - 1].SetBinContent(pt_bin, bin_val_2.value()) hist_array_2[y_bin - 1].SetBinError(pt_bin, bin_val_2.error()) pt_bin += 1 return hist_array_1[0], hist_array_2[0]
def gauss_cdf(x, mu=0.0, sigma=1.0): """Standard gaussian CDF >>> x,mu, sigma = .... >>> cdf = gauss_cdf ( x , mu , sigma ) """ m = float(mu) s = abs(float(sigma)) y = (VE(x) - m) / s ## return _gauss_cdf_(y) if 0 < y.cov2() else _gauss_cdf_(y.value())
def integral(fun, x0, x, err=False, **kwargs): """Calculate the integral for the 1D-function using scipy >>> func = lambda x : x * x >>> v = integral(func,0,1) """ func = lambda x: float(fun(x)) import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") result = integrate.quad(func, x0, x, **kwargs) return VE(result[0], result[1] * result[1]) if err else result[0]
def _fit_getitem_(self, par): """Getitem for fit-result-object >>> r = h1.Fit(....) ## >>> print r[0] ## print 0th parameter """ ## convert parameter into integer ipar = _fit_parnum_(self, par) if not 0 <= ipar: raise IndexError("TFitResult:illegal index %s" % par) # _p = self.Parameter(ipar) _e = self.Error(ipar) # return VE(_p, _e * _e)
def pochhammer(x, n): """ calculate Pochhammer's symbol \f[ (x)^n = x ( x + 1) ( x + 1 ) ... ( x + n - 1 ) = \Pi^{k-1}_{k=0} (x + k) \f] @see https://en.wikipedia.org/wiki/Falling_and_rising_factorials """ assert is_integer ( n ) and 0<= n < 2**16, \ "pochhammer: invalid n=%s" % n fun = getattr(x, '__pochhammer__', None) if fun: return fun() _x = x if isinstance(x, num_types) else VE(x) return _pochhammer(_x, n)
def derivative(fun, x, h=0, I=2, err=False): """Calculate the first derivative for the function # @code # >>> fun = lambda x : x*x # >>> print derivative ( fun , x = 1 ) - see R. De Levie, ``An improved numerical approximation for the first derivative'' - see https://link.springer.com/article/10.1007/s12039-009-0111-y - see http://www.ias.ac.in/chemsci/Pdf-Sep2009/935.pdf """ func = lambda x: float(fun(x)) ## get the function value at the given point f0 = func(x) ## adjust the rule I = min(max(I, 1), 8) J = 2 * I + 1 _dfun_ = _funcs_[I] delta = _delta_(x) ## if the intial step is too small, choose another one if abs(h) < _numbers_[I][3] or abs(h) < delta: if iszero(x): h = _numbers_[0][I] else: h = abs(x) * _numbers_[I][3] h = max(h, 2 * delta) ## 1) find the estimate for first and "J"th the derivative with the given step d1, dJ = _dfun_(func, x, h, True) ## find the optimal step if iszero(dJ) or (iszero(f0) and iszero(x * d1)): if iszero(x): hopt = _numbers_[0][I] else: hopt = abs(x) * _numbers_[I][3] else: hopt = _numbers_[I][2] * ((abs(f0) + abs(x * d1)) / abs(dJ))**(1.0 / J) ## finally get the derivative if not err: return _dfun_(func, x, hopt, False) ## estimate the uncertainty, if needed d1, dJ = _dfun_(func, x, hopt, True) e = _numbers_[I][1] / _numbers_[I][2] * J / (J - 1) e2 = e * e * (J * _eps_ + abs(f0) + abs(x * d1))**(2 - 2. / J) * abs(dJ)**(2. / J) return VE(d1, 4 * e2)
def test_basic_2D () : logger.info ( 'Test for very basic operations with 2D-histograms') h2 = h2_axes ( [1,2,3,4,5,6,7] , [1,2,3,4,5] ) h2 += lambda x,y: VE(1,1)+VE(x*x+2*y*y,x*x+2*y*y) ## access the content logger.info ( "h[%1d, %1d]=%s" % ( 2 , 3 , h2[2,3] ) ) logger.info ( "h[%1d][%1d]=%s" % ( 2 , 3 , h2[2][3] ) ) logger.info ( "h[%1d](%.2f)=%s" % ( 2 , 3.01 , h2[2](3.01 ) ) ) logger.info ( "h(%.2f,%.2f)=%s" % ( 2.01 , 3.01 , h2(2.01,3.01 ) ) ) ## get the 1st X-slice hx = h2.sliceX ( 1 ) ## get the slice in 1,4,5 X-bins hx = h2.sliceX ( [1,4,5] ) ## get the 2nd Y-slice hy = h2.sliceY ( 2 ) ## get the slice in 1,3,5 Y-bins hy = h2.sliceY ( [1,3,4] ) ## projection in X hx = h2.projX() ## projection in Y hy = h2.projY() logger.info ( ' minmax %20s' % str( h2. minmax() ) ) logger.info ( 'x-minmax %20s' % str( h2.xminmax() ) ) logger.info ( 'y-minmax %20s' % str( h2.yminmax() ) ) logger.info ( 'z-minmax %20s' % str( h2.zminmax() ) )
def _fit_repr_(self): """Representaion of TFitResult object >>> fit_result = hiisto.Fit( func , 'S' , ... ) >>> print fit_result """ _r = '' _r += "\n Status = %s " % self.Status() _r += "\n Chi2/nDoF = %s/%s " % (self.Chi2(), self.Ndf()) _r += "\n Probability = %s " % self.Prob() _p = self.Parameters() _e = self.Errors() for i in range(0, len(_p)): v = _p[i] e = _e[i] a = VE(v, e * e) _r += " \n %s " % a return _r
def derivative(fun, x, h=0, I=2, err=False): """Calculate the first derivative for the function # @code # >>> fun = lambda x : x*x # >>> print derivative ( fun , x = 1 ) """ func = lambda x: float(fun(x)) ## get the function value at the given point f0 = func(x) ## adjust the rule I = min(max(I, 1), 8) J = 2 * I + 1 _dfun_ = _funcs_[I] delta = _delta_(x) ## if the intial step is too small, choose another one if abs(h) < _numbers_[I][3] or abs(h) < delta: if iszero(x): h = _numbers_[0][I] else: h = abs(x) * _numbers_[I][3] h = max(h, 2 * delta) ## 1) find the estimate for first and "J"th the derivative with the given step d1, dJ = _dfun_(func, x, h, True) ## find the optimal step if iszero(dJ) or (iszero(f0) and iszero(x * d1)): if iszero(x): hopt = _numbers_[0][I] else: hopt = abs(x) * _numbers_[I][3] else: hopt = _numbers_[I][2] * ((abs(f0) + abs(x * d1)) / abs(dJ))**(1.0 / J) ## finally get the derivative if not err: return _dfun_(func, x, hopt, False) ## estimate the uncertainty, if needed d1, dJ = _dfun_(func, x, hopt, True) e = _numbers_[I][1] / _numbers_[I][2] * J / (J - 1) e2 = e * e * (J * _eps_ + abs(f0) + abs(x * d1))**(2 - 2. / J) * abs(dJ)**(2. / J) return VE(d1, 4 * e2)
def __call__ ( self , args , cov2 = None ) : """Calcualte the value of the scalar function of N (scalar) arguments with the given NxN covariance matrix >>> fun2 = lambda x , y : ... >>> fun2e = EvalNVEcov ( fun2 , 2 ) >>> cov2 = ... # 2x2 symmetric covariance matrix >>> result = fun2e ( (1,5) , cov2 ) ## """ n = self.N assert len ( args ) == n , 'Invalid argument size' ## get value of the function val = float ( self.func ( *args ) ) ## no covariance matrix is specified ? if not cov2 : return val c2 = 0 g = n * [ 0 ] ## gradient for i in range ( n ) : di = self.partial[i] ( *args ) if iszero ( di ) : continue g [i] = di cii = self.__cov2 ( cov2 , i , i ) c2 += di * di * cii for j in range ( i ) : dj = g [ j ] if iszero ( dj ) : continue cij = self.__cov2 ( cov2 , i , j ) c2 += 2 * di * dj * cij return VE ( val , c2 )
def _ve_pdg_(ve): """Make a rounding according to PDG prescription @see http://pdg.lbl.gov/2010/reviews/rpp2010-rev-rpp-intro.pdf @see section 5.3 of doi:10.1088/0954-3899/33/1/001 Quote: The basic rule states that if the three highest order digits of the error lie between 100 and 354, we round to two significant digits. If they lie between 355 and 949, we round to one significant digit. Finally, if they lie between 950 and 999, we round up to 1000 and keep two significant digits. In all cases, the central value is given with a precision that matches that of the error. >>> ve = VE( ... >>> vr = ve.pdg() >>> print ' Rounded value with error is %s ' % vr """ # v, e = pdg_round(ve.value(), ve.error()) # return VE(v, e * e)
def __call__ ( self , x , error = False ) : """Get the efficiency >>> dataset = ... >>> eff = Efficiency1D( ... ) >>> eff.fitTo ( dataset ) >>> x = 0.15 >>> value = eff(x) """ from ostap.fitting.roofit import SETVAR from ostap.math.ve import VE xx = float ( x ) if xx in self.xvar : with SETVAR ( self.xvar ) : self.xvar.setVal ( xx ) v = self.eff_fun.getVal () if error and self.fit_result : e = self.eff_fun.getPropagatedError ( self.fit_result ) if 0<= e : return VE ( v , e * e ) return v logger.error ('Invalid efficiency, return -1 ') return -1
def h2(file_name, xvar, x_bins, yvar, y_bins, zvar): "Create 2d histo" h2 = h2_axes(x_bins, y_bins) print("\nCreating 2D-histo:") print("FILE : " + file_name) print("HEADER : " + header(file_name)) print(" x_var : " + xvar) print(" y_var : " + yvar) print(" z_var : " + zvar) xidx, yidx, zidx = find_vars(file_name, xvar, yvar, zvar) with open(file_name, "r") as f: for line in f: if line[0:2] == " |": wl = line[1:-1].split("|") for w in wl: x_min = float(wl[xidx].split(",")[0]) y_min = float(wl[yidx].split(",")[0]) z_val = float(wl[zidx].split("+-")[0]) z_err = float(wl[zidx].split("+-")[1]) h2[get_2d_bin(x_min, x_bins, y_min, y_bins)] = VE(z_val, z_err**2) return h2
# -*- coding: utf-8 -*- # ============================================================================= # Copyright Ostap developers # ============================================================================= ## @file examples/math/math_ex001_functions.py # Example of basic operations with VE objects and functions # ============================================================================= """Example of basic operations with VE objects and functions """ # ============================================================================= from __future__ import print_function import math from ostap.math.ve import VE from ostap.math.math_ve import * ## get functions a = VE ( 2 , 0.2**2 ) b = VE ( 3 , 0.3**2 ) print ( 'a,b : %s %s' % ( a , b ) ) print ( 'a+b : %s ' % ( a + b ) ) print ( 'a-b : %s ' % ( a - b ) ) print ( 'a*b : %s ' % ( a * b ) ) print ( 'a/b : %s ' % ( a / b ) ) print ( 'a**b : %s ' % ( a ** b ) ) print ( 'a+2 : %s ' % ( a + 2 ) ) print ( 'a-2 : %s ' % ( a - 2 ) ) print ( 'a*2 : %s ' % ( a * 2 ) ) print ( 'a/2 : %s ' % ( a / 2 ) ) print ( 'a**2 : %s ' % ( a ** 2 ) )
def hypot(x, y, c=0): """ evaluate hypot(x,y)=sqrt{x*x+y*y} witn uncertainties """ _x = VE(x) _y = VE(y) return _hypot_(_x, _y, c)
def gauss_cdf(x, mu=0.0, sigma=1.0): """Standard gaussian CDF >>> x,mu, sigma = .... >>> cdf = gauss_cdf ( x , mu , sigma ) """ m = float(mu) s = abs(float(sigma)) y = (VE(x) - m) / s ## return _gauss_cdf_(y) if 0 < y.cov2() else _gauss_cdf_(y.value()) # ============================================================================= ## FIX # @see https://sft.its.cern.ch/jira/browse/ROOT-6627' _a = VE(1, 1) _b = VE(_a) if isequal(_a.error(), _b.error()): pass else: jira = 'https://sft.its.cern.ch/jira/browse/ROOT-6627' vers = ROOT.gROOT.GetVersion() logger.warning('The problem %s is not solved yet ( ROOT %s) ' % (jira, vers)) logger.warning('Temporarily disable cast of VE to float') del VE.__float__ # ============================================================================= if '__main__' == __name__: from ostap.utils.docme import docme docme(__name__, logger=logger)