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 __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 """ ## evaluate the function val = self._value_(x, y) # x = VE(x) y = VE(y) # x_plain = x.cov2() <= 0 or iszero(x.cov2()) y_plain = y.cov2() <= 0 or iszero(y.cov2()) # if x_plain and y_plain: return VE(val, 0) # ## here we need to calculate the uncertainties # cov2 = 0.0 # fx = self.dFdX(x, y.value()) if not x_plain else 0 fy = self.dFdY(x.value(), y) if not y_plain else 0 # if not x_plain: cov2 += fx * fx * x.cov2() if not y_plain: cov2 += fy * fy * y.cov2() # if not x_plain and not y_plain: ## adjust the correlation coefficient: cxy = min(max(-1, cxy), 1) if not iszero(cxy): cov2 += 2 * cxy * fx * fy * x.error() * y.error() return VE(val, cov2)
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
>>> 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) funcs = [